From 0ead53757c8c393d75c074598a04e7c830090f1a Mon Sep 17 00:00:00 2001 From: PJ Date: Mon, 13 Jul 2026 07:23:21 +0530 Subject: [PATCH] refactor(llmclient): make JSONSchema.Schema raw json for pinned field order --- internal/llmclient/client.go | 11 +++++++---- internal/llmclient/client_test.go | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) 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"}`), }, }, })