Skip to content

Stream OpenAI OAuth structured helpers - #100

Open
k2v7n24cbf-cyber wants to merge 1 commit into
sandydasari:mainfrom
k2v7n24cbf-cyber:agent/openai-oauth-stream-structured
Open

Stream OpenAI OAuth structured helpers#100
k2v7n24cbf-cyber wants to merge 1 commit into
sandydasari:mainfrom
k2v7n24cbf-cyber:agent/openai-oauth-stream-structured

Conversation

@k2v7n24cbf-cyber

Copy link
Copy Markdown

Summary

This PR changes structured helper calls to use streaming when the parent model is openai with oauth auth.

The existing structured-helper path uses generateObject() for all providers. For ChatGPT OAuth, that sends a non-streaming Responses request. In local deployment debug logs, those calls reached the ChatGPT OAuth backend but were rejected with:

400 Bad Request: Stream must be set to true

The fix keeps the existing generateObject() path for other providers/auth modes, and only routes OpenAI OAuth structured helpers through streamObject(). The helper still exposes the same one-shot result contract to callers by draining the SDK stream internally before returning the final object and usage metadata.

Root cause

OpenAcme structured helper jobs, such as session title generation and memory selection, currently share one implementation in runStructured(). That implementation uses AI SDK generateObject(), which is non-streaming.

The ChatGPT OAuth/Codex backend expects these Responses calls to be streamed. Non-streaming structured helper calls therefore fail even though normal interactive turns can continue to work, because the main chat path already streams.

Why this is costly

This is not just a cosmetic helper failure. In a real deployment, the failure was observed repeatedly across deployed agents during normal sessions. Each failed helper call is still a model round trip that carries prompt input and returns no useful work.

That cost compounds because these helpers run around common workflows:

  • title generation can run when a session starts or needs a title;
  • memory selection can run before turns to decide which persisted context to surface;
  • repeated failures leave the system doing fallback behavior while still paying for failed requests.

Prompt caching can reduce reprocessing work, but it does not make failed turns free: each call still sends input, consumes latency, and adds operational noise. A repeating 400 on helper paths is therefore token-expensive relative to the value produced, because the marginal information returned by each failed call is zero.

Change

  • Use streamObject() for structured helper calls only when the resolved helper model is openai + oauth.
  • Drain result.fullStream so result.object and result.usage resolve reliably while preserving the existing synchronous helper API.
  • Leave API-key OpenAI, Anthropic, OpenRouter, Google, custom, and local model paths on the current generateObject() behavior.
  • Add a regression test proving OpenAI OAuth structured helpers call doStream instead of doGenerate.

Validation

Focused validation:

pnpm --filter @openacme/agent-core... build
pnpm --filter @openacme/agent-core test -- subagent.test.ts

Commit/push hooks also ran successfully:

pnpm check-types
pnpm test
pnpm build
pnpm test:e2e

@k2v7n24cbf-cyber
k2v7n24cbf-cyber marked this pull request as ready for review July 20, 2026 08:35
k2v7n24cbf-cyber added a commit to k2v7n24cbf-cyber/openacme that referenced this pull request Jul 22, 2026
Merge staged copy of sandydasari#100 into local-stage.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant