Skip to content

Generate the public client types from the schema - #549

Merged
SaladDay merged 1 commit into
mainfrom
refactor/generated-public-ts
Oct 8, 2026
Merged

SaladDay merged 1 commit into
mainfrom
refactor/generated-public-ts

Conversation

@SaladDay

@SaladDay SaladDay commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Generates the TypeScript client's /v1 types, enum values and field names from the same public schema that already produces Core's Go types, and deletes the hand-written copies.

Generator. scripts/generate-public-api.py gains a 72-line emitter (ts_module) that writes packages/agents-client/src/generated/public-api.ts: each schema's type, enums as xValues plus a union, objects as xFields (and xRequired when some fields are optional), and discriminated unions as {tag: variantFields}. make openapi writes it and make check-openapi fails when it is stale. No new dependency. The emitter takes any parsed schema dict (OpenAPI 3.1 or Swagger 2.0), so the /core/v1 types can follow from core.openapi.yaml.

Client. types.ts aliases the generated types, and every /v1 field set and enum in client.ts and the projection files reads the generated one (66 hand-written sets in client.ts down to 13 that are client-defined or /core/v1). The strict validators stay. Where a hand-written set disagreed with the schema, the schema wins:

  • snapshot events carry no session_id;
  • Item events have no item_id and require output_index;
  • terminal Turn events require usage;
  • turn.waiting passes through as an unknown event;
  • function_call_output has no duration_ms;
  • message and web_search_call Items have no failed status;
  • web search actions are checked per variant;
  • the Environment error is exactly {code, type, message};
  • Turn errors accept the full code enum;
  • user messages accept input_image;
  • SessionError.code may be null.

Required fields Core always sends are now required. The client no longer re-checks limits Core enforces: batch and idempotency-key sizes, list ranges, and upload and name bounds. The two known differences between the schema and the service, null File expires_at/status_details and null first_id/last_id on empty File pages, keep their recorded allowance (coverage ledger).

Core, to match the pinned schema.

  • Environment events always carry turn_id, null when no Turn is linked.
  • command_execution Items always carry nullable cwd, output, exit_code and duration_ms.
  • The stream interruption frame carries param: null.

Docs. The client README, the contract index (en/zh) and the Session events rules (en/zh).

Net: hand-written non-test code −514 lines; generated +1,970; tests −105.

Checks:

  • make openapi (idempotent) and make check-openapi, including a stale-file probe;
  • generator tests (14);
  • client tsc and vitest (711);
  • Web tsc and vitest (382);
  • example tsc and tests;
  • go build ./... and go vet;
  • Go tests for contracts/agents-api/v1, api, items, sessionpg, execution and tests/integration. One environment test expected four event fields; it now expects turn_id: null.
  • check-names.py, check-docs and the translation test.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@blacksmith-sh

This comment has been minimized.

@SaladDay
SaladDay force-pushed the refactor/generated-public-ts branch from 4bb3623 to 084ed90 Compare October 8, 2026 07:38
make openapi now projects the public schema onto
packages/agents-client/src/generated/public-api.ts: each schema's
TypeScript type, each enum's values and each object's field names, with
required lists and per-union field maps. make check-openapi rejects a
stale copy. The emitter takes a parsed schema dict and accepts the
Swagger 2.0 forms of the Core document (x-nullable, allOf, any ref
prefix), so the /core/v1 projection can reuse it.

The client aliases the generated types and validates responses with the
generated field sets and enums instead of hand-written copies. Where the
schema and the validators disagreed, the schema wins: snapshot events
carry no session_id, Item events require output_index, terminal Turn
events require usage, list envelopes are complete, input_image is
accepted in user messages, and older-Core allowances are gone. The
client no longer re-checks limits Core enforces.

Core now sends turn_id null on Environment events, null cwd, output,
exit_code and duration_ms on command_execution Items, and param null on
the stream interruption error, as the pinned schema requires.
@SaladDay
SaladDay merged commit 0ea327b into main Oct 8, 2026
25 checks passed
@SaladDay
SaladDay deleted the refactor/generated-public-ts branch October 8, 2026 07:44
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