Skip to content

fix(sdk/go): rewrite max_tokens to max_completion_tokens for newer OpenAI models#724

Open
7vignesh wants to merge 2 commits into
Agent-Field:mainfrom
7vignesh:fix/441-max-tokens-rewrite
Open

fix(sdk/go): rewrite max_tokens to max_completion_tokens for newer OpenAI models#724
7vignesh wants to merge 2 commits into
Agent-Field:mainfrom
7vignesh:fix/441-max-tokens-rewrite

Conversation

@7vignesh

@7vignesh 7vignesh commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Summary

The Go SDK always emits max_tokens in API requests, but newer OpenAI models (o1, o3, gpt-4o, gpt-4.x) only accept max_completion_tokens and silently ignore max_tokens. This causes Go agents to lose their output-length
cap with no error. This PR adds a model-aware serialization pass that rewrites the parameter for affected models.

Closes #441

Type of Change

  • Bug fix

Test Plan

  • cd sdk/go && go test ./ai/ -v -run "TestNeedsMaxCompletion|TestMarshalRequest"
  • cd sdk/go && go build ./...
  • cd sdk/go && CGO_ENABLED=0 GOOS=linux go build ./...
  • golangci-lint run ./ai/... no new issues

Test Coverage

  • I ran tests for the surface(s) I changed locally.
  • New code paths are covered by tests in this PR (no bare additions).
  • If I removed code, I updated coverage-baseline.json in this PR only if
    the removal caused a legitimate regression and I called it out in the
    summary above.
  • The coverage gate check is green in CI before requesting review.

Checklist

Related Issues / PRs

Fixes #441

…enAI models (Agent-Field#441)

Newer OpenAI models (o1, o3, gpt-4o, gpt-4.x) dropped support for the
legacy max_tokens parameter in favor of max_completion_tokens. The Go
SDK was always emitting max_tokens, causing the output-length cap to be
silently ignored.

Changes:
- Add model-aware marshalRequest() that detects newer OpenAI models and
  rewrites max_tokens → max_completion_tokens at serialization time
- Detection uses model prefix matching (o1, o3, o4, gpt-4o, gpt-4.)
- Preserves backward compatibility: legacy models still use max_tokens
- Request-level model override takes precedence over client default
- Add 6 focused tests covering new models, legacy models, nil handling,
  and request-level model override

Closes Agent-Field#441
Copilot AI review requested due to automatic review settings July 6, 2026 18:27
@7vignesh 7vignesh requested review from a team and AbirAbbas as code owners July 6, 2026 18:27
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Performance

SDK Memory Δ Latency Δ Tests Status
Go 235 B -16% 0.65 µs -35%

✓ No regressions detected

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the Go SDK’s request serialization to avoid OpenAI silently ignoring max_tokens for newer model families by rewriting it to max_completion_tokens when applicable.

Changes:

  • Added model detection logic to decide when max_tokens must be rewritten to max_completion_tokens.
  • Routed request serialization in Client through a new rewrite-aware marshalRequest method.
  • Added unit tests covering model detection and JSON marshaling behavior for rewritten vs legacy models.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

File Description
sdk/go/ai/model_params.go Adds model/base-URL detection and rewrite-aware request marshaling to emit max_completion_tokens for newer OpenAI model families.
sdk/go/ai/model_params_test.go Adds tests validating model detection and ensuring marshaled JSON uses the correct token field.
sdk/go/ai/client.go Switches request serialization to c.marshalRequest(req) for both non-streaming and streaming calls.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread sdk/go/ai/model_params.go
cfg.APIKey = "test-key"
cfg.Model = "gpt-4o"

client, _ := NewClient(cfg)
cfg.APIKey = "test-key"
cfg.Model = "gpt-3.5-turbo"

client, _ := NewClient(cfg)
cfg.APIKey = "test-key"
cfg.Model = "o1-mini"

client, _ := NewClient(cfg)
cfg.APIKey = "test-key"
cfg.Model = "gpt-4o"

client, _ := NewClient(cfg)
cfg.APIKey = "test-key"
cfg.Model = "gpt-3.5-turbo" // client default is legacy

client, _ := NewClient(cfg)
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

📊 Coverage gate

Thresholds from .coverage-gate.toml: per-surface ≥ 84%, aggregate ≥ 85%, max per-surface regression ≤ 1.0 pp, max aggregate regression ≤ 0.50 pp.

Surface Current Baseline Δ
control-plane 86.90% 87.40% ↓ -0.50 pp 🟡
sdk-go 91.90% 92.00% ↓ -0.10 pp 🟢
sdk-python 93.76% 93.73% ↑ +0.03 pp 🟢
sdk-typescript 90.09% 90.42% ↓ -0.33 pp 🟢
web-ui 84.76% 84.79% ↓ -0.03 pp 🟡
aggregate 85.55% 85.75% ↓ -0.20 pp 🟡

✅ Gate passed

No surface regressed past the allowed threshold and the aggregate stayed above the floor.

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

📐 Patch coverage gate

Threshold: 80% on lines this PR touches vs origin/main (from .coverage-gate.toml:thresholds.min_patch).

Surface Touched lines Patch coverage Status
control-plane 0 ➖ no changes
sdk-go 61 90.00%
sdk-python 0 ➖ no changes
sdk-typescript 0 ➖ no changes
web-ui 0 ➖ no changes

✅ Patch gate passed

Every surface whose lines were touched by this PR has patch coverage at or above the threshold.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
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.

[Go SDK] max_tokens not rewritten to max_completion_tokens for newer OpenAI models

2 participants