Skip to content

ai-anthropic: modelOptions.context_management is forwarded to the wire but the required beta header is never sent #1074

Description

@mathiasrscom

Summary

AnthropicTextAdapter accepts modelOptions.context_management, forwards it onto the request body, and never sends the beta header that Anthropic requires for it. The option is typed, accepted, transmitted — and cannot work.

Detail

mapCommonOptionsToAnthropic lists context_management in its validKeys whitelist and copies it into requestParams (dist/esm/adapters/text.js, validKeys around line 195):

const validKeys = [
  "container",
  "context_management",
  "effort",
  ...
]

But computeAnthropicBetas (dist/esm/adapters/text.js:53-63) only ever unions four values:

function computeAnthropicBetas(tools, modelOptions) {
  const betas = new Set();
  if (modelOptions?.thinking?.type === "enabled" && ...) betas.add("interleaved-thinking-2025-05-14");
  const codeExecTool = tools?.find((t) => t.name === "code_execution");
  if (codeExecTool) {
    const cfgType = readCodeExecutionConfig(codeExecTool)?.type;
    betas.add(cfgType === "code_execution_20250522" ? "code-execution-2025-05-22" : "code-execution-2025-08-25");
  }
  if (tools?.some((t) => t.name === "code_execution" && (readCodeExecutionSkills(t)?.length ?? 0) > 0)) betas.add("skills-2025-10-02");
  return betas.size > 0 ? Array.from(betas) : void 0;
}

Context editing requires anthropic-beta: context-management-2025-06-27 (docs). The string context-management does not appear anywhere in dist/.

There is also no caller-facing escape hatch: betas is computed internally from tools and modelOptions, so a consumer cannot add the header themselves.

Why it is easy to miss

AnthropicContextManagementOptions appears in the provider-options type of every model in model-meta.d.ts, so this typechecks cleanly and looks supported:

modelOptions: {
  context_management: { edits: [{ type: 'clear_tool_uses_20250919' }] },
}

Suggested fix

Add the beta when the option is present, in the same shape as the existing interleaved-thinking rule:

if (modelOptions?.context_management) betas.add("context-management-2025-06-27");

Environment

@tanstack/ai-anthropic@0.16.4. I could not find an existing report.

Metadata

Metadata

Assignees

No one assigned

    Labels

    has-prAn open PR references this issuewaiting-on: maintainerThe ball is in the maintainers’ court

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions