Skip to content

chore(schema): bump @typra/emitter to 0.4.21 and regenerate - #453

Open
Seth Juarez (sethjuarez) wants to merge 3 commits into
mainfrom
sethjuarez/bump-typra-0.4.21
Open

chore(schema): bump @typra/emitter to 0.4.21 and regenerate#453
Seth Juarez (sethjuarez) wants to merge 3 commits into
mainfrom
sethjuarez/bump-typra-0.4.21

Conversation

@sethjuarez

Copy link
Copy Markdown
Member

Supersedes #448, which pinned 0.4.20.

0.4.21 ships the #59 fix — C#, Python and TypeScript now absorb unknown discriminators on abstract open polymorphic bases via a concrete UnknownX carrier, matching what Rust and Go already did. That completes the reject-before-the-open-fallback family across four backends (typra #37, #38, #54, #59).

Regeneration delta is small, and that is expected

On main's current schema the #59 fix is a no-op for Connection, whose kind is still the closed ConnectionType alias — so no Unknown carrier is emitted here. The defect is latent on main and becomes live on wip/connection-open-discriminator, which changes kind to a bare string.

The only substantive delta is the privateprotected widening of the raw-payload machinery on Property, which the carrier subclass needs to reach:

``diff

  • private Dictionary<string, object?> _raw = new();
  • protected Dictionary<string, object?> _raw = new();
  • private raw: Record<string, unknown> = {};
  • protected raw: Record<string, unknown> = {};
    ``

Measurements

Against published 0.4.21, measured on wip/connection-open-discriminator where the open discriminator is actually live:

Runtime Result
Go go test ./... 1 failure
Rust cargo test 293 passed / 3 failed
TypeScript vitest run 1510 passed / 12 failed / 17 skipped

tests/connection-roundtrip-vectors.test.ts went from 2 failed / 1 passed → 0 failed / 3 passed.

Every remaining failure is attributed, and none of them is an emitter defect

Failures Cause Issue
1 Go + 1 TS ReferenceTurnRunner skips tool_result on the permission-denied path #449
7 TS schema declares model, approvalMode, items required; vectors and fixtures omit them #450
4 TS stale generated custom-connection.test.ts for a type removed from the schema #451
3 Rust handwritten unit tests omit schema-required connection / context #452

Attributions were confirmed by experiment rather than by reading: flipping the three schema declarations in #450 took spec-vectors.test.ts from 2 failures to 0 and loader.test.ts from 5 to 4; adding items to structured.prompty took loader.test.ts from 5 to 1. Both changes were reverted.

Not verified

  • prompty's Python package does not build, so the Python side of the Prompty documentation link is broken #59 fix is verified against typra fixtures and by direct execution of generated code — not against this repo.
  • prompty has no C# runtime committed, so the C# side is verified by compilation only.
  • I did not run the vscode or non-core TypeScript workspaces.

Note for reviewers regenerating locally

Run npm install in runtime/typescript before npm run generate. Without it prettier does not resolve and regeneration emits a spurious ~276-file, ~3900-line reformatting diff that is pure line-wrapping.

0.4.20 is the first release cut from typra's `main` since 0.4.2. Versions
0.4.3 through 0.4.18 were published from an unmerged branch, so this pin moves
from 0.4.2 straight to the current `latest`.

Regeneration follows in the next commit.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Pure regeneration - `npm run generate` in `schema/`, no handwritten edits.

This pulls in every emitter fix that accumulated behind typra's unmerged PR
stack, plus the defects found and fixed while landing it.

Measured effect on this repository's suites:

  go test ./...                58 failed -> 2 failed
  TypeScript (4 workspaces)    63 failed -> 10 failed

Zero generated-test failures remain in either backend. All 12 remaining
failures are in handwritten tests and are unrelated to code generation:

  Go (2)
    TestReferenceTurnRunnerMatchesSharedGoldenReplayVectors and its
    permission_denied subtest, package prompty/model.

  TypeScript (10)
    tests/harness/turn-runner.test.ts  (1) golden replay journal vectors
    tests/loader.test.ts               (5) allowedFileRoots, structured output
    tests/models.test.ts               (2) Azure modalities, OpenAI enrichment
    tests/spec-vectors.test.ts         (2) empty_frontmatter_body_only,
                                           tools_mcp_load

Emitter fixes included, by typra issue:

  #37  non-abstract polymorphic bases absorb unclaimed discriminator values
  #38  open discriminators are no longer pre-validated ahead of dispatch
  #39  Go numeric coercions bridge encoding/json float64 and yaml.v3 int
  #46  named-collection round-trips, including duplicate and unnamed entries
  #47  diagnostic paths carry array element indices, e.g. messages[3].role
  #53  generated tests synthesize required complex fields from nested samples
  #54  Go abstract-open discriminators absorb unknown kinds into the base
  #56  TypeScript dictionary-load tests use the built example payload
  #64  TypeScript never emits a generated test file with no test cases

Not verified: this repository's Rust, C# and Python suites were not run for
this bump. Python does not build (typra#43).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
0.4.21 ships the #59 fix: C#, Python and TypeScript now absorb unknown
discriminators on abstract open bases via a concrete UnknownX carrier,
completing the reject-before-the-open-fallback family (typra #37, #38,
#54, #59).

On main's current schema the fix is a no-op for Connection, whose `kind`
is still the closed `ConnectionType` alias, so no Unknown carrier is
emitted. The only substantive regeneration delta is the private -> protected
widening of the raw-payload machinery on Property, which the carrier needs
to reach from a subclass.

Measured against 0.4.21 (branch wip/connection-open-discriminator, where the
open discriminator is live):
  Go    go test ./...  1 failure  (#449)
  Rust  cargo test     293 passed / 3 failed  (#452)
  TS    vitest run     1510 passed / 12 failed
                       (#449, #450, #451)

Every remaining failure is attributed to a filed prompty-side issue.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b31c70d1-3bf8-4b6d-80a9-db836f2a4166
Copilot AI lite review requested due to automatic review settings August 5, 2026 20:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@@ -23,6 +23,9 @@ type AiResourceInfo struct {

// LoadAiResourceInfo creates a AiResourceInfo from a map[string]interface{}
func LoadAiResourceInfo(data interface{}, ctx *LoadContext) (AiResourceInfo, error) {
if ctx == nil {
ctx = NewLoadContext()
@@ -20,6 +20,9 @@ type AnthropicImageSource struct {

// LoadAnthropicImageSource creates a AnthropicImageSource from a map[string]interface{}
func LoadAnthropicImageSource(data interface{}, ctx *LoadContext) (AnthropicImageSource, error) {
if ctx == nil {
ctx = NewLoadContext()
@@ -19,6 +19,9 @@ type AnthropicTextBlock struct {

// LoadAnthropicTextBlock creates a AnthropicTextBlock from a map[string]interface{}
func LoadAnthropicTextBlock(data interface{}, ctx *LoadContext) (AnthropicTextBlock, error) {
if ctx == nil {
ctx = NewLoadContext()
@@ -22,6 +22,9 @@ type AnthropicToolDefinition struct {

// LoadAnthropicToolDefinition creates a AnthropicToolDefinition from a map[string]interface{}
func LoadAnthropicToolDefinition(data interface{}, ctx *LoadContext) (AnthropicToolDefinition, error) {
if ctx == nil {
ctx = NewLoadContext()
@@ -20,6 +20,9 @@ type AnthropicToolResultBlock struct {

// LoadAnthropicToolResultBlock creates a AnthropicToolResultBlock from a map[string]interface{}
func LoadAnthropicToolResultBlock(data interface{}, ctx *LoadContext) (AnthropicToolResultBlock, error) {
if ctx == nil {
ctx = NewLoadContext()
@@ -19,6 +19,9 @@ type AnthropicUsage struct {

// LoadAnthropicUsage creates a AnthropicUsage from a map[string]interface{}
func LoadAnthropicUsage(data interface{}, ctx *LoadContext) (AnthropicUsage, error) {
if ctx == nil {
ctx = NewLoadContext()
@@ -21,6 +21,9 @@ type AnthropicWireMessage struct {

// LoadAnthropicWireMessage creates a AnthropicWireMessage from a map[string]interface{}
func LoadAnthropicWireMessage(data interface{}, ctx *LoadContext) (AnthropicWireMessage, error) {
if ctx == nil {
ctx = NewLoadContext()
@@ -22,6 +22,9 @@ type AnthropicToolUseBlock struct {

// LoadAnthropicToolUseBlock creates a AnthropicToolUseBlock from a map[string]interface{}
func LoadAnthropicToolUseBlock(data interface{}, ctx *LoadContext) (AnthropicToolUseBlock, error) {
if ctx == nil {
ctx = NewLoadContext()
@@ -19,6 +19,9 @@ type AuthorizationCodeFlow struct {

// LoadAuthorizationCodeFlow creates a AuthorizationCodeFlow from a map[string]interface{}
func LoadAuthorizationCodeFlow(data interface{}, ctx *LoadContext) (AuthorizationCodeFlow, error) {
if ctx == nil {
ctx = NewLoadContext()
@@ -20,6 +20,9 @@ type CompactionCompletePayload struct {

// LoadCompactionCompletePayload creates a CompactionCompletePayload from a map[string]interface{}
func LoadCompactionCompletePayload(data interface{}, ctx *LoadContext) (CompactionCompletePayload, error) {
if ctx == nil {
ctx = NewLoadContext()
@sethjuarez

Copy link
Copy Markdown
Member Author

@typra/emitter@0.4.22 is now published and is npm latest. This PR should bump to 0.4.22 rather than 0.4.21 before merging.

0.4.22 adds the fix for sethjuarez/typra#73 (PR sethjuarez/typra#74): the Rust backend no longer loses the primitive kind of an immediate integer scalar or the precision of an immediate float scalar.

Verified against the published package — pinned schema/package.json to 0.4.22, npm install, npm run generate:

cargo test --no-fail-fast --test property_scalar_coercion_vectors
  0.4.21   0 passed / 1 failed
  0.4.22   1 passed / 0 failed

Full Rust suite 869 passed / 39 failed -> 870 passed / 38 failed — a single flip, in the intended direction, no other test changing state. Regeneration touches five lines in one file, runtime/rust/prompty/src/model/core/property.rs:

-if let Some(value) = value.as_f64().map(|value| value as f32) { ... "float" ... }
-if let Some(value) = value.as_i64() { ... "integer" ... }
+if let Some(value) = value.as_i64() { ... "integer" ... }
+if let Some(value) = value.as_f64() { ... "float" ... }

Go and TypeScript output is byte-identical to 0.4.21 — the emitter diff was confined to the Rust backend.

@sethjuarez

Copy link
Copy Markdown
Member Author

Superseded — flagging rather than closing, since the landing decision isn't mine to make.

This PR pins @typra/emitter@0.4.21. 0.4.22 is published and is npm latest; it fixes the Rust immediate-scalar coercion defect (typra #73 / #72). Branch wip/typra-0.4.20-regen carries that bump plus every prompty-owned fix found while validating all five runtimes.

Why the newer pin matters

The 0.4.21 → 0.4.22 regeneration delta is exactly one file plus a version stamp: runtime/rust/prompty/src/model/core/property.rs (5 lines — as_i64() now precedes as_f64(), as_str() moved up, the as f32 narrowing removed) and the export-surfaces.json version. Every other backend's generated output is byte-identical, so this is a strict improvement with no cross-backend risk — that's proof from the generated diff, not structural inference.

Effect: cargo test --no-fail-fast --test property_scalar_coercion_vectors goes 0 passed / 1 failed → 1 passed / 0 failed, and Rust's total goes 3 → 2 failures. One flip, intended direction, nothing else changed state. I revert-checked it with a controlled single-file stash to confirm the delta was real.

What wip/typra-0.4.20-regen contains beyond this PR

The 0.4.21 bump (equivalent to this PR's content) plus 15 further commits fixing prompty-owned defects across all five runtimes — the denied-tool_result harness seam in Go/TypeScript/Python/C#, optional Prompty.model and McpTool.approvalMode in the schema with regeneration, the bare-string template rejection in Rust, the enrichment-vector modalities in Python, the flat parameters form in C#, an orphaned generated test, and the named-collection form in the tool vectors.

Measured state on that branch, every number run personally

runtime result attribution
Go 0 failures
TypeScript 1518 passed / 0 failed
Python 1468 passed / 1 failed typra #71
Rust 2 failed typra #46
C# 1292 passed / 49 failed typra #53 ×48, #71 ×1

Progression across the effort: Go 62→0, TypeScript 67→0, Rust 39→2, Python 10→1, C# 53→49. 52 failures remain across all five runtimes and all 52 are emitter-side — zero prompty-owned defects left. 48 of the 52 are typra #53 alone.

Two measurement notes, since they produced wrong numbers for me

  • cargo test fail-fast stops at the first failing target. Every "293 passed / 3 failed" figure quoted earlier in this effort was lib-only; the true figure was 39. Always --no-fail-fast. Likewise go test ./... serves cached results — always -count=1 after regeneration.
  • Run npm install in runtime/typescript before npm run generate, or prettier won't resolve and regeneration emits a spurious ~276-file / ~3900-line diff that is pure line-wrapping and reads exactly like a semantic regression.

Suggestion

Either rebase this PR onto the 0.4.22 pin, or close it in favour of wip/typra-0.4.20-regen. As it stands, merging it would land a pin that's already stale and reintroduce a Rust failure that's fixed on the newer branch.

@sethjuarez

Copy link
Copy Markdown
Member Author

Superseded by #456, which takes the model layer to @typra/emitter 0.4.26 and includes this bump in its lineage.

The 0.4.21 pin here is necessary but not sufficient — it clears the #59 carrier failures and leaves the named-collection entry shorthand (0.4.23), the optional variant declaration (0.4.25) and the Rust scalar coercion (0.4.22) outstanding. Measured on that branch:

pin Rust workspace
0.4.20 869 passed / 39 failed
0.4.26 1145 passed / 0 failed

#456 also carries live-provider validation (OpenAI + Anthropic) across four runtimes. Closing this in favour of it is safe once #456 is reviewed.

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.

2 participants