Skip to content

feat(sdk): adapter conformance testkit (@ratel-ai/sdk/testkit)#116

Merged
rstagi merged 4 commits into
feat/sdk-adapter-spifrom
feat/adapter-testkit
Jul 20, 2026
Merged

feat(sdk): adapter conformance testkit (@ratel-ai/sdk/testkit)#116
rstagi merged 4 commits into
feat/sdk-adapter-spifrom
feat/adapter-testkit

Conversation

@rstagi

@rstagi rstagi commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Stacked on #111 (feat/sdk-adapter-spi, base of this PR). GitHub auto-retargets this to main when #111 merges.

Ships the adapter conformance testkit (OSI-14) — a runner-agnostic battery every framework adapter must pass, so an AI SDK / Mastra / community RatelAdapter can prove it satisfies the ADR-0013 SPI contract before it ships.

Surface (@ratel-ai/sdk/testkit)

  • adapterConformanceCases(options) → named cases { name, area, skipped?, run() }; assertions via node:assert (no test-runner leaks into shipped types), each case builds its own fresh ratel() core + adapted view, BM25 only (deterministic, model-free).
  • describeAdapterConformance(options, { describe, it }) → registers the battery as first-class tests; structurally typed runner (Vitest/Jest/node:test all fit), it.skip with a name-suffix fallback.
  • AdapterConformanceOptions hooks: required adapter(), makeExecutableTool, callExposedTool, validateRecallPair; optional makePassthroughTool (absent → the 4 passthrough cases emit as skipped) and validateExposedTool.
  • referenceAdapter / referenceConformanceOptions — the worked example a real adapter's options copy; ratel.test.ts now imports it instead of an inline fake.

Battery (21 cases across 6 areas)

ingest-expose · reserved-ids · recall-topk · passthrough · recall-pair · guards. Expected recall + call ids are computed by the testkit from the pure core.recall(query) and the deterministic counter (recall_0, recall_1).

Discrimination

9 build-excluded broken-adapter variants (lossyIngest, inertIngest, passthroughAlways/Never, rawExpose, fixedCallId, droppedResult, shadowingExtend, namelessAdapter) each fail exactly their targeted cases while unrelated cases stay green — proving the battery actually catches defects, not just passes the reference.

Packaging

@ratel-ai/sdk/testkit subpath — an exports map whose . is byte-identical to today's main/types (default, not import-only, so the CJS require in verify-install keeps working), plus ./testkit and ./package.json. Zero new deps, no new release unit. conformance.test.ts + test-support/ stay build-excluded; typedoc gains the testkit entry point.

Verification

  • src/sdk/ts: build · typecheck · lint (biome + typedoc docs:check) · test211 tests green.
  • Workspace pnpm -r build/typecheck/lint/test — green.
  • Subpath resolves via both ESM import and CJS require, running a real case through the native binding; . entry intact.

@rstagi
rstagi force-pushed the feat/adapter-testkit branch 2 times, most recently from 316cb7e to 3750d7b Compare July 20, 2026 16:46
@rstagi
rstagi force-pushed the feat/adapter-testkit branch from 3750d7b to ec6f7e6 Compare July 20, 2026 18:13
@rstagi
rstagi merged commit 591758d into feat/sdk-adapter-spi Jul 20, 2026
7 of 9 checks passed
@rstagi
rstagi deleted the feat/adapter-testkit branch July 20, 2026 18:17
rstagi added a commit that referenced this pull request Jul 20, 2026
* refactor(sdk): extract reference adapter to testkit/reference-adapter

* feat(sdk): testkit types, case builder skeleton, runner helper

* feat(sdk): conformance battery cases, discrimination tests, green path

* feat(sdk): package testkit as @ratel-ai/sdk/testkit subpath

exports map (. byte-identical to main/types, ./testkit, ./package.json),
typedoc second entry point, CHANGELOG + README testkit section.
rstagi added a commit that referenced this pull request Jul 20, 2026
* refactor(sdk): extract reference adapter to testkit/reference-adapter

* feat(sdk): testkit types, case builder skeleton, runner helper

* feat(sdk): conformance battery cases, discrimination tests, green path

* feat(sdk): package testkit as @ratel-ai/sdk/testkit subpath

exports map (. byte-identical to main/types, ./testkit, ./package.json),
typedoc second entry point, CHANGELOG + README testkit section.
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