Skip to content

Commit c97f4da

Browse files
authored
chore: sync fantasy fork with upstream v0.40.0 and openai-go with v3.50.0 (#27981)
Our fantasy fork had drifted far behind upstream charmbracelet/fantasy (base v0.31.0 vs current v0.40.0). This PR updates the pinned forks after reconciling which fork hacks upstream has fixed and which we still need, and adapts this repo to the new APIs. ## Fork updates - `charm.land/fantasy` -> [coder/fantasy#51](coder/fantasy#51) (merged): `coder_2_33` synced with upstream v0.40.0, pinned at the merge commit `bb10946892ef`. - `github.com/openai/openai-go/v3` -> [coder/openai-go#10](coder/openai-go#10) (merged): `coder/pinned` rebased from v3.16.0 onto upstream v3.50.0 (required by upstream fantasy), pinned at the merge commit `92b5addb22d2`. - `coder/anthropic-sdk-go` pin unchanged; the fantasy fork now tracks the same revision this repo ships. ## Hack reconciliation summary Dropped from our fantasy diff (upstream now has equivalents, often stricter): truncated-stream fail-closed detection, Anthropic EffortXHigh / computer use / thinking effort / thinking display, replay fidelity for signed reasoning and web_search errors, PDF and text documents with sanitized filename titles, refusal finish-reason mapping (upstream also maps Bedrock `content_filtered`/`guardrail_intervened`), gpt-5.5/5.6 Responses routing, the Go 1.25 downgrade, and the openai-go SSE decoder and appendCompact patches. Still fork-only and preserved: OpenAI computer use, OpenAI Responses replay continuity validation, Anthropic pre-4.6 budget-thinking conversion plus explicit thinking disable for effort none, Anthropic RefusalMetadata parsing, Bedrock cross-region inference profile region mirroring, and openai-go deferred body serialization with the WithJSONSet fix. Picked up new upstream features: stream transport retry with in-band SSE error classification, Bedrock expired-credential refresh, per-message cache markers for OpenAI-compatible models, tool panic recovery, extra usage fields in provider metadata, and ClientMetadata on tool results. ## Changes in this repo - `aibridge/intercept/responses`: `ResponseOutputItemUnion.Arguments` became a union type in openai-go v3.50; read function-call arguments via `.OfString` (plus test literal updates). - `coderd/x/chatd/chatdebug`: register the new fantasy `Call.Headers`, `ObjectCall.Headers`, and `ToolResultPart.ClientMetadata` fields in the normalization coverage map (all skipped). - `aibridge/internal/integrationtest`: make the RST test listener drain the request before resetting the connection. The new SDK's write path exposed the previous 1-byte-read race as sporadic `use of closed network connection` failures; the fix holds over 40 consecutive runs. - `go.mod`: rewrite the fork provenance comments to describe the post-sync state. ## Validation - `go build ./...` and `go vet ./...` clean (vet findings identical to base). - Fresh (`-count=1`) runs of `./coderd/x/chatd/...`, `./aibridge/...`, `./coderd/aibridged/...`, `./coderd/database/db2sdk/`: 37 packages pass. - `TestClientAndConnectionError` stress-tested 40x clean. - Both fork PRs have green CI. > Mux acted on Mike's behalf to create this PR.
1 parent b3acf7f commit c97f4da

6 files changed

Lines changed: 186 additions & 199 deletions

File tree

aibridge/intercept/responses/base.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,9 @@ func (i *responsesInterceptionBase) recordNonInjectedToolUsage(ctx context.Conte
264264
// have no uniform argument representation.
265265
switch item.Type {
266266
case string(constant.ValueOf[constant.FunctionCall]()):
267-
args = i.parseFunctionCallJSONArgs(ctx, item.Arguments)
267+
// Arguments is a union since openai-go v3.50; function_call
268+
// arguments are always the JSON string variant.
269+
args = i.parseFunctionCallJSONArgs(ctx, item.Arguments.OfString)
268270
case string(constant.ValueOf[constant.CustomToolCall]()):
269271
args = item.Input
270272
case string(constant.ValueOf[constant.WebSearchCall]()),

aibridge/intercept/responses/base_internal_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func TestRecordToolUsage(t *testing.T) {
114114
Type: "function_call",
115115
CallID: "call_abc",
116116
Name: "get_weather",
117-
Arguments: "",
117+
Arguments: oairesponses.ResponseOutputItemUnionArguments{OfString: ""},
118118
},
119119
},
120120
},
@@ -138,13 +138,13 @@ func TestRecordToolUsage(t *testing.T) {
138138
Type: "function_call",
139139
CallID: "call_1",
140140
Name: "get_weather",
141-
Arguments: `{"location": "NYC"}`,
141+
Arguments: oairesponses.ResponseOutputItemUnionArguments{OfString: `{"location": "NYC"}`},
142142
},
143143
{
144144
Type: "function_call",
145145
CallID: "call_2",
146146
Name: "bad_json_args",
147-
Arguments: `{"bad": args`,
147+
Arguments: oairesponses.ResponseOutputItemUnionArguments{OfString: `{"bad": args`},
148148
},
149149
{
150150
Type: "message",
@@ -161,7 +161,7 @@ func TestRecordToolUsage(t *testing.T) {
161161
Type: "function_call",
162162
CallID: "call_4",
163163
Name: "calculate",
164-
Arguments: `{"a": 1, "b": 2}`,
164+
Arguments: oairesponses.ResponseOutputItemUnionArguments{OfString: `{"a": 1, "b": 2}`},
165165
},
166166
},
167167
},
@@ -211,7 +211,7 @@ func TestRecordToolUsage(t *testing.T) {
211211
ID: "fc_item_1",
212212
CallID: "call_both",
213213
Name: "get_weather",
214-
Arguments: `{"location": "NYC"}`,
214+
Arguments: oairesponses.ResponseOutputItemUnionArguments{OfString: `{"location": "NYC"}`},
215215
},
216216
},
217217
},

aibridge/internal/integrationtest/responses_internal_test.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package integrationtest
22

33
import (
4+
"bufio"
45
"context"
56
"encoding/json"
67
"fmt"
@@ -1158,10 +1159,12 @@ func startRejectingListener(t *testing.T) (addr string) {
11581159
return
11591160
}
11601161

1161-
// Read at least 1 byte so the client has started writing
1162-
// before we RST, ensuring a consistent "connection reset by peer".
1163-
buf := make([]byte, 1)
1164-
_, _ = c.Read(buf)
1162+
// Drain the request before the RST so the client observes a
1163+
// read-side reset rather than a racy body-write failure.
1164+
if req, err := http.ReadRequest(bufio.NewReader(c)); err == nil {
1165+
_, _ = io.Copy(io.Discard, req.Body)
1166+
_ = req.Body.Close()
1167+
}
11651168
if tc, ok := c.(*net.TCPConn); ok {
11661169
_ = tc.SetLinger(0)
11671170
}

coderd/x/chatd/chatdebug/model_coverage_internal_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ func TestNormalizationFieldCoverage(t *testing.T) {
5858
"Tools": "normalized",
5959
"ToolChoice": "normalized",
6060
"UserAgent": "skipped: internal transport header, not useful for debug panel",
61+
"Headers": "skipped: transport headers, may carry credentials",
6162
"ProviderOptions": "skipped: opaque provider data, only count preserved",
6263
},
6364
},
@@ -76,6 +77,7 @@ func TestNormalizationFieldCoverage(t *testing.T) {
7677
"PresencePenalty": "normalized",
7778
"FrequencyPenalty": "normalized",
7879
"UserAgent": "skipped: internal transport header, not useful for debug panel",
80+
"Headers": "skipped: transport headers, may carry credentials",
7981
"ProviderOptions": "skipped: opaque provider data, only count preserved",
8082
"RepairText": "skipped: function value, not serializable",
8183
},
@@ -196,6 +198,7 @@ func TestNormalizationFieldCoverage(t *testing.T) {
196198
"Output": "normalized: text extracted via normalizeToolResultOutput",
197199
"ProviderExecuted": "skipped: provider vs client distinction not needed for debug panel",
198200
"ProviderOptions": "skipped: opaque provider-specific options",
201+
"ClientMetadata": "skipped: client execution metadata not needed for debug panel",
199202
},
200203
},
201204

0 commit comments

Comments
 (0)