Skip to content

fix(core): apply agent request body and headers - #55051

Closed
lazyayuan wants to merge 2 commits into
anomalyco:devfrom
lazyayuan:agent-request-options
Closed

lazyayuan wants to merge 2 commits into
anomalyco:devfrom
lazyayuan:agent-request-options

Conversation

@lazyayuan

@lazyayuan lazyayuan commented Oct 13, 2026 •

Copy link
Copy Markdown

Issue for this PR

Related to #49550. This PR addresses body and header overlays only; agent-level request.settings remains unimplemented.

#55009 reports the same omission and has been identified as a duplicate of #49550.

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Agent config populated request.body and request.headers, but Session request preparation received only the agent ID. The configured values never reached model requests.

Pass the selected agent's request overlays into primary, compaction, generate, and title request preparation. Body is passed through http.body, matching provider/model/variant raw JSON overlays. Provider field names such as top_p and service_tier are preserved, and agent body no longer changes the internal computed output budget. Headers matching runtime-owned names are filtered case-insensitively before merging; model.request hooks can still override headers.

Update the Agents documentation to describe the implemented behavior. Agent request settings such as transport and timeouts remain outside this change.

How did you verify your code works?

Using Bun 1.4.2, from packages/core:

  • bun test test/session-model-request-hooks.test.ts test/session-model-request.test.ts test/session-native-compaction.test.ts: 18 tests passed.
  • bun typecheck: passed.
  • The new regression fails against the original request builder and passes with the fix. It checks all four request kinds, raw JSON transport overlays (temperature, top_p, service_tier), nested body merging, preserved internal output limits, and case-insensitive runtime header protection.
  • git diff --check: passed.
  • Local full-repository pre-push checks were interrupted due to resource pressure. Focused tests and Core typechecking passed; full validation is left to CI.

No live provider request was made.

Screenshots / recordings

Not applicable; this changes request construction, not UI.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes. Agent headers and generation keys such as temperature now reach model requests, but agent body works differently from the model/variant/provider body it is documented alongside.

How I checked: on the base, nothing passes the agent's request into SessionModelRequest (from reading the code). With this PR I ran a throwaway test that sent agent body { temperature: 0.1, top_p: 0.9, service_tier: "flex", maxTokens: 5 } through requests.primary and encoded it with OpenAIChat.fromRequest. temperature and maxTokens reached the request; top_p and service_tier were silently dropped, and maxTokens: 5 replaced the computed output limit. The three test files you listed pass (18 tests), and bun run typecheck in packages/core passes.

Public API: unchanged in code. The config key agents.*.request.body/headers already existed in the schema and now takes effect. Existing configs whose agent body uses names the provider expects (e.g. top_p) will still be ignored, without any warning.

Main concern: model, variant and provider body are raw JSON fields merged into the request the provider receives (the http.body overlay, see models.mdx/providers.mdx). This PR puts agent body into Session options instead, so only keys with the internal option names (temperature, topP, maxTokens, …) are sent. Keys like top_p, service_tier or reasoning_effort go to providerOptions and are dropped. The same block that works on a model does nothing on an agent. The new docs text also says agent values override model and variant defaults; because model body is merged in last, a model's temperature would most likely still win (I didn't test this combination). Passing agent body through http.body, the way model body is passed, would give the same rules and the intended precedence. Details are inline.

Related: #49550, #55009

kind === "primary" || kind === "compaction"
? { maxTokens: outputLimit(model.limit, kind, input.inputTokens) }
: {},
? { maxTokens: outputLimit(model.limit, kind, input.inputTokens), ...input.agentRequest?.body }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes agent body a set of Session options rather than a JSON body overlay like model/variant/provider body. In a quick check, { top_p: 0.9, service_tier: "flex" } ended up in providerOptions and was missing from the encoded OpenAI Chat request. Only keys with the internal names (temperature, topP) were sent. Also, spreading the agent body after maxTokens lets an agent maxTokens replace the computed output limit for primary/compaction. Could agent body go through http.body instead (merged like the model's body), so the same config works on agents and models?

model: model.model,
http: {
headers: {
...input.agentRequest?.headers,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Headers are spread as an object, so an agent header that differs from a runtime header only in case (e.g. X-Session-Affinity) survives next to the lowercase runtime key. I saw both in the prepared headers. If session identity should never be replaced by agent config, drop the agent headers that match runtime-owned names case-insensitively before merging.

<Callout type="warning">
The V2 session runner preserves these values but does not yet send them with model requests. Configure active request
settings on the provider, model, or model variant instead.
Agent request values override model and variant defaults. Session hooks may override the agent body options, and

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Agent request values override model and variant defaults" doesn't seem to hold for body. Model/variant body is merged into the request the provider receives after encoding, so a model temperature would most likely win over the agent's. Body keys written the way the provider expects them (top_p, service_tier) are dropped entirely. The docs should match whichever behaviour is kept.

@lazyayuan

Copy link
Copy Markdown
Author

Addressed in a7f1fca. Agent body now uses http.body rather than Session generation options. The regression checks the transport JSON for temperature, top_p and service_tier, nested overlay precedence, and that maxTokens in raw body does not replace the internal output budget. Runtime-owned agent headers are filtered case-insensitively. Documentation now describes raw overlay semantics and explicitly notes request.settings remains unsupported. The 18 focused tests and Core typecheck pass with Bun 1.4.2; no live provider call or full local check was run.

@opencode-agent opencode-agent Bot mentioned this pull request Oct 23, 2026
3 of 6 tasks
@github-actions

Copy link
Copy Markdown
Contributor

Automated PR Cleanup

Thank you for contributing to opencode.

Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions.

This PR was closed because it matched the following cleanup criteria:

  • The PR was created more than 1 month ago
  • The PR had fewer than 2 positive reactions
  • Positive reactions are counted as thumbs-up, heart, celebration, or rocket reactions on the PR

PRs created within the last month are not affected by this cleanup.

If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate.

Thanks again for taking the time to contribute.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant