diff --git a/internal/llmclient/client.go b/internal/llmclient/client.go index 3745e4a..7b21b84 100644 --- a/internal/llmclient/client.go +++ b/internal/llmclient/client.go @@ -107,11 +107,14 @@ type ResponseFormat struct { JSONSchema JSONSchema `json:"json_schema"` } -// JSONSchema is the strict structured-output schema. +// JSONSchema is the strict structured-output schema. Schema is raw JSON so the +// caller controls property ORDER: OpenAI emits fields in schema order, and a +// reasoning-first schema must not be re-sorted alphabetically (as a Go map +// would be). type JSONSchema struct { - Name string `json:"name"` - Strict bool `json:"strict"` - Schema map[string]any `json:"schema"` + Name string `json:"name"` + Strict bool `json:"strict"` + Schema json.RawMessage `json:"schema"` } // Response is the slice of a chat-completions response we read. diff --git a/internal/llmclient/client_test.go b/internal/llmclient/client_test.go index a9ccb68..b4bac25 100644 --- a/internal/llmclient/client_test.go +++ b/internal/llmclient/client_test.go @@ -49,7 +49,7 @@ func TestChatCompletionRequestShapeAndParse(t *testing.T) { JSONSchema: JSONSchema{ Name: "ranked_actions", Strict: true, - Schema: map[string]any{"type": "object"}, + Schema: json.RawMessage(`{"type":"object"}`), }, }, })