Skip to content
This repository was archived by the owner on Jun 7, 2026. It is now read-only.

feat(gateway): use native --json-schema for structured output - #68

Merged
matthew-petty merged 3 commits into
mainfrom
feat/66-json-schema-flag
Dec 27, 2025
Merged

feat(gateway): use native --json-schema for structured output#68
matthew-petty merged 3 commits into
mainfrom
feat/66-json-schema-flag

Conversation

@matthew-petty

Copy link
Copy Markdown
Member

Summary

Replaces the prompt injection approach for structured JSON output with Claude CLI's native --json-schema flag for constrained decoding. This provides model-level enforcement of valid JSON output.

Main Feature (Issue #66)

  • Add jsonSchema option to ClaudeCliOptions, passed as --json-schema CLI flag
  • Handle structured_output field in CLI response (used when --json-schema is provided)
  • Simplify /generate-object route by removing prompt injection logic

Code Quality Improvements

  • Add warning log when jsonSchema provided but structured_output missing (helps detect CLI version mismatches)
  • Soften "guarantee" language in comments (the guarantee is external to our code)
  • Remove legacy CLI output format support (pre-1.0.17 total_tokens_in/out fields that were never needed)

Type Design Improvements

  • Extract CliUsageInfo interface for shared CLI usage type (was defined inline in 3 places)
  • Add createUsageInfo() function for consistent CLI→API usage conversion (eliminates duplication)
  • Extract baseRequestSchema to reduce request schema duplication
  • Add .int().nonnegative() refinements to UsageInfo schema with totalTokens consistency check
  • Remove unused outputFormat field from ClaudeCliOptions (always hardcoded to "json")
  • Make rawOutput non-nullable in ClaudeCliResult (we throw on parse failure, never return null)
  • Document unused maxTokens field (CLI doesn't support --max-tokens)

Test Coverage

  • Add tests for structured_output code path (5 new tests in cli.test.ts)
  • Add E2E tests for /generate-object with structured_output response (2 new tests)

Test plan

  • All 113 tests pass
  • Lint passes
  • TypeScript type checking passes
  • Manual testing with SDK examples (TypeScript and Python)

Closes #66

Remove backwards compatibility for pre-1.0.17 Claude CLI output format.
The project has always used modern Claude CLI versions, so the legacy
`total_tokens_in/out` fields were never needed.

- Remove `total_tokens_in/out` from ClaudeCliOutput interface
- Update cli.ts to only use `usage.input_tokens/output_tokens`
- Update stream.ts to use `usage` object format
- Update all test fixtures to use new format
Replace prompt injection approach with Claude CLI's native --json-schema
flag for constrained JSON decoding. This provides model-level guarantees
of valid JSON output.

Changes:
- Add jsonSchema option to ClaudeCliOptions, pass as --json-schema flag
- Handle structured_output field in CLI response (used by --json-schema)
- Add warning log when jsonSchema provided but structured_output missing
- Simplify /generate-object route by removing prompt injection
- Soften "guarantee" language in comments (external to our code)

Type design improvements:
- Extract CliUsageInfo interface for shared CLI usage type
- Add createUsageInfo() for consistent CLI→API usage conversion
- Extract baseRequestSchema to reduce request schema duplication
- Add int().nonnegative() refinements to UsageInfo schema
- Remove unused outputFormat field from ClaudeCliOptions
- Make rawOutput non-nullable in ClaudeCliResult (we throw on failure)
- Document unused maxTokens field (CLI doesn't support it)

Closes #66
@codecov

codecov Bot commented Dec 27, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.05882% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
packages/gateway/src/cli.ts 96.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@matthew-petty
matthew-petty merged commit 1e14a82 into main Dec 27, 2025
3 checks passed
@matthew-petty
matthew-petty deleted the feat/66-json-schema-flag branch December 27, 2025 02:44
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(gateway): use native --json-schema flag instead of prompt injection

1 participant