Skip to content

feat(kosong): support structured response formats#1397

Open
kermanx wants to merge 3 commits into
mainfrom
xtr/structured-outputs-kosong
Open

feat(kosong): support structured response formats#1397
kermanx wants to merge 3 commits into
mainfrom
xtr/structured-outputs-kosong

Conversation

@kermanx

@kermanx kermanx commented Jul 5, 2026

Copy link
Copy Markdown
Collaborator

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

GenerateOptions did not expose a common response-format constraint, so provider callers could not request native JSON object mode or JSON-schema structured outputs through the shared kosong abstraction.

What changed

  • Added a provider-level ResponseFormat option for json_object and json_schema output constraints.
  • Mapped the option to each provider's native protocol shape:
    • Kimi and OpenAI Chat Completions: response_format
    • OpenAI Responses: text.format
    • Anthropic Messages: output_config.format for JSON schema, with an explicit error for schema-less JSON object mode
    • Google GenAI SDK: responseMimeType and responseJsonSchema
  • Added provider request-shape tests for the supported mappings.
  • Added a patch changeset for @moonshot-ai/kosong and 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

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, 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.ts
  • git diff --check

@changeset-bot

changeset-bot Bot commented Jul 5, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 1fa7b33

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kosong Patch

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

@pkg-pr-new

pkg-pr-new Bot commented Jul 5, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@1fa7b33
npx https://pkg.pr.new/@moonshot-ai/kimi-code@1fa7b33

commit: 1fa7b33

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 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);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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 👍 / 👎.

@kermanx

kermanx commented Jul 5, 2026

Copy link
Copy Markdown
Collaborator Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 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);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge 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 👍 / 👎.

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.

1 participant