feat(kosong): support structured response formats#1397
Conversation
🦋 Changeset detectedLatest commit: 1fa7b33 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f2b73f1a80
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| createParams['instructions'] = systemPrompt; | ||
| } | ||
| if (options?.responseFormat !== undefined) { | ||
| createParams['text'] = responseFormatToResponsesText(options.responseFormat); |
There was a problem hiding this comment.
Preserve existing Responses text options
When a caller has already configured Responses-specific text options via withGenerationKwargs (for example text: { verbosity: 'low' }), this assignment replaces the whole text object after ...kwargs has been applied. Adding responseFormat therefore silently drops those existing options even though text.format can coexist with them; merge the new format into the prior text config instead of overwriting it.
Useful? React with 👍 / 👎.
| if (format === undefined) return; | ||
| config['responseMimeType'] = 'application/json'; | ||
| if (format.type === 'json_schema') { | ||
| config['responseJsonSchema'] = format.jsonSchema.schema; |
There was a problem hiding this comment.
Remove conflicting Gemini schema config
If a Google provider was configured with the native responseSchema in withGenerationKwargs, using the new responseFormat: { type: 'json_schema' } leaves that existing responseSchema in config and adds responseJsonSchema here. Gemini's generateContent config treats those schema fields as mutually exclusive, so that combination turns a previously valid provider config into a rejected request; clear or replace the old schema field when applying the common format.
Useful? React with 👍 / 👎.
Signed-off-by: _Kerman <kermanx@qq.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1fa7b33236
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| createParams['instructions'] = systemPrompt; | ||
| } | ||
| if (options?.responseFormat !== undefined) { | ||
| createParams['text'] = responseFormatToResponsesText(options.responseFormat); |
There was a problem hiding this comment.
Preserve existing Responses text options
When callers have already configured other OpenAI Responses text settings through withGenerationKwargs (for example text: { verbosity: 'low' }), this assignment runs after ...kwargs and replaces the entire text object with only the structured-output format. That silently drops those text settings on every structured-output request; merge the new format into the existing text object instead.
Useful? React with 👍 / 👎.
| @@ -0,0 +1,5 @@ | |||
| --- | |||
| "@moonshot-ai/kosong": patch | |||
There was a problem hiding this comment.
Add the CLI package to this changeset
This changeset lists only the internal @moonshot-ai/kosong package, but the repository's changeset rules require internal package source changes that enter the CLI bundle to manually list @moonshot-ai/kimi-code. As written, the private/internal package can be versioned without bumping the published CLI artifact, so this provider-layer behavior may not ship in the next CLI release/changelog.
Useful? React with 👍 / 👎.
Related Issue
No linked issue. This addresses the provider-layer gap for passing native structured output / JSON schema response format options through
@moonshot-ai/kosong.Problem
GenerateOptionsdid not expose a common response-format constraint, so provider callers could not request native JSON object mode or JSON-schema structured outputs through the sharedkosongabstraction.What changed
ResponseFormatoption forjson_objectandjson_schemaoutput constraints.response_formattext.formatoutput_config.formatfor JSON schema, with an explicit error for schema-less JSON object moderesponseMimeTypeandresponseJsonSchema@moonshot-ai/kosongand the bundled CLI package.Protocol checks were made against the locked SDK/API type definitions used by this package and the public provider documentation for structured output fields.
Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.Validation:
./node_modules/.bin/vitest run packages/kosong/test/anthropic.test.ts packages/kosong/test/kimi.test.ts packages/kosong/test/openai-legacy.test.ts packages/kosong/test/openai-responses.test.ts packages/kosong/test/google-genai.test.ts./node_modules/.bin/tsc -p packages/kosong/tsconfig.json --noEmit./node_modules/.bin/oxlint --type-aware packages/kosong/src/provider.ts packages/kosong/src/providers/anthropic.ts packages/kosong/src/providers/google-genai.ts packages/kosong/src/providers/kimi.ts packages/kosong/src/providers/openai-legacy.ts packages/kosong/src/providers/openai-responses.ts packages/kosong/test/anthropic.test.ts packages/kosong/test/google-genai.test.ts packages/kosong/test/kimi.test.ts packages/kosong/test/openai-legacy.test.ts packages/kosong/test/openai-responses.test.tsgit diff --check