Skip to content

Type the source that served a run - #46

Open
kev1n wants to merge 1 commit into
mainfrom
typed-served-source
Open

kev1n wants to merge 1 commit into
mainfrom
typed-served-source

Conversation

@kev1n

@kev1n kev1n commented Sep 16, 2026

Copy link
Copy Markdown
Member

What

The gateway added an optional source to the POST /v1/run/{slug} success envelope in anyapi#1133 (in production since 2026-09-16). Neither SDK declared it, so a caller could read costUsd and replayed off a run but not which source served it - and therefore could not feed that id back as the source input, or into ignoreSources, on the next call.

source is the same customer-safe object discovery already publishes under lanes[].source ({ id, name, kind, artworkKey }), so both SDKs reuse their existing DiscoverySource type rather than declaring a second one. The internal routing provider slug is never part of it and provider stays the literal "AnyAPI".

Changed

  • SPEC.md 2.3: source?: DiscoverySource on the RunResult<T> declaration, added to the "Run-envelope field presence" erratum's optional set, and a new "Served source" erratum. Mirrored in the 3.3 Python sketch.
  • packages/typescript/src/core/types.ts: source?: DiscoverySource on RunResult<T> and BareRunResult<T>.
  • packages/python/src/getanyapi/types.py: source: DiscoverySource | None = None on RunResult and BareRunResult.
  • Tests in both languages: a served source parses and round-trips at the wire alias (artworkKey / artwork_key), and is absent when the run names no resolvable lane.

The Go tag carries omitempty, so source is optional exactly like resultId and jqError. The synthetic fixtures are unchanged for the same reason they omit resultId: a fixture models the success path, and the generator was not touched.

Proof

Removing the two field declarations fails the new coverage: tsc --noEmit reports Property 'source' does not exist on type 'RunResult<AmazonReviewsData>' at both new assertions, and pytest fails test_served_source_parses_as_a_discovery_source and test_source_defaults_to_none_when_no_lane_is_named.

Full gate green on the final tree: pnpm check (dash guard, release tests, no regen drift, 162 generator tests, 481 TypeScript tests, tsup, consumer-typecheck), pyright, mypy --strict, pytest 508 passed.

No version bump and no workflow dispatch: the blocked catalog-refresh release is a separate call.

The gateway's run envelope now carries an optional `source`: the
customer-safe identity of the lane that actually served the call, in the
same shape discovery already publishes under `lanes[].source`. Both SDKs
dropped it on the floor, so a caller could not read which source served a
run and feed that id back as `source` (or into `ignoreSources`) next time.

Declare it on `RunResult` and `BareRunResult` in both languages, reusing
the existing `DiscoverySource` type rather than declaring a second one,
and record it in SPEC 2.3 beside the run-envelope field-presence erratum:
the Go tag carries `omitempty`, so `source` is optional exactly like
`resultId` and `jqError`. The synthetic fixtures are unchanged for the
same reason they omit `resultId` - they model the success path.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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