The onPayload hook contract (README, docs/extensions.md) is that a non-undefined
return replaces the provider request payload, and every provider except these
three implements it (anthropic, openai-responses family, google, ollama — see
the earlier fix for the responses providers). openai-completions, amazon-bedrock
and cursor invoked the hook fire-and-forget and sent the original payload, so
extensions hooking before_provider_request could never transform the wire body
on these providers.
- openai-completions: await the hook and apply a non-undefined replacement to
the params used for the request body, raw request dump and error-path
fallback state
- amazon-bedrock: same for the ConverseStream command input
- cursor: await the hook for the AgentRunRequest; buildGrpcRequest becomes
async and is exported for direct testing (transport is HTTP/2)
- devin-agent intentionally unchanged: it does not fire the hook at all (its
payload is a protobuf object), which is a feature gap rather than a dropped
replacement; documented in README/docs instead
- regression tests: captured wire body reflects async/sync replacement, and an
undefined return keeps the original payload (completions + bedrock over a
mocked fetch; cursor by decoding the serialized run request)