Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

README.md

D6 reference snapshots

D6 is disabled by default. Set D6_ENABLED=true on the showcase-harness Railway service to enable. The other env vars below (D6_MODE, LGP_BASE_URL, etc.) only matter once D6_ENABLED is true. Without the flag the driver short-circuits with an aggregate green "D6 disabled" signal on every tick and emits no per-feature rows.

Per-feature ParitySnapshot JSON files captured against the LangGraph-Python (LGP) showcase — the reference implementation the D6 probe compares every other showcase against.

What lives here

One JSON file per D5FeatureType:

fixtures/d6-reference/
  agentic-chat.json
  tool-rendering.json
  shared-state-read.json
  shared-state-write.json
  hitl-approve-deny.json
  hitl-text-input.json
  gen-ui-headless.json
  gen-ui-custom.json
  mcp-apps.json
  subagents.json

Each file conforms to the ParitySnapshot schema in src/probes/helpers/parity-compare.ts:

  • domElements — flat list of relevant chat-content DOM elements (sorted by testId, tag, classes).
  • toolCalls — ordered list of tool-call names emitted on the SSE stream (concatenated across turns).
  • streamProfile{ ttft_ms, p50_chunk_ms, total_chunks } aggregated across the conversation's turns.
  • contractShape — field path → JS-type string for the union of every SSE payload observed.

The files are NOT shipped in git in this commit — the .gitkeep reserves the directory and the helper writes snapshots at runtime when the LGP showcase is online.

When to refresh

  • Weekly cron — the showcase-harness scheduler runs the capture job once a week to pick up upstream LGP runtime/agent drift.
  • Manual trigger — operators can re-capture on demand:
    • after an LGP showcase redeploy (especially LGP runtime / agent changes),
    • after a D5 fixture update (fixtures/d5/*.json) — fixtures drive what the model says, which changes tool calls and contract shape,
    • after a parity-tolerances change in parity-compare.ts — re-baseline so previous captures' timing aren't unfairly compared against new bounds,
    • after an ag-ui protocol bump that changes wire-level event names.

If you're unsure whether the snapshots are stale, run the D6 probe — captured-vs-reference drift on the timing axes is a clean signal that the reference is older than the deployment.

How to invoke

The everyday operator path is the CLI script — it wires all deps (Playwright launcher, SSE interceptor, conversation runner, DOM serializer, file writer) for you:

# From showcase/harness/:
LGP_BASE_URL=https://langgraph-python.up.railway.app \
  npx tsx scripts/d6-capture-references.ts

The script (showcase/harness/scripts/d6-capture-references.ts) accepts:

  • --integration <slug> — default langgraph-python.
  • --base-url <url> — else falls back to the LGP_BASE_URL env.
  • --feature <type> — optional, target a single featureType.

It exits 0 when every result is captured or skipped, and 1 when any result is failed. Production wiring (driver + scheduler) is integrated with B13.

For programmatic / test callers, the helper lives at src/probes/helpers/reference-capture.ts and exposes two entry points:

import {
  captureReferenceForFeature,
  captureAllReferences,
  serializeRelevantDom,
  defaultWriteSnapshot,
} from "../../src/probes/helpers/reference-capture.js";
import { attachSseInterceptor } from "../../src/probes/helpers/sse-interceptor.js";
import { runConversation } from "../../src/probes/helpers/conversation-runner.js";

// Production callers compose their own `launchBrowser` (real Playwright) and
// pass the helper's defaults for the remaining slots. Tests inject scripted
// fakes for ALL deps — there is no "default" launcher exported from the
// helper module today; the CLI script above contains the canonical wiring.
const results = await captureAllReferences(
  {
    baseUrl: "https://langgraph-python.up.railway.app",
    integrationSlug: "langgraph-python",
    outputDir: path.resolve(__dirname, "../../fixtures/d6-reference"),
  },
  {
    launchBrowser: yourLauncher,
    attachSseInterceptor,
    runConversation,
    serializeDom: serializeRelevantDom,
    writeSnapshot: defaultWriteSnapshot,
  },
);

yourLauncher is a placeholder — production callers compose a real Playwright launcher. See scripts/d6-capture-references.ts for the canonical wiring (browser launch, page setup, teardown).

What to verify after capture

  1. Every featureType in D5_REGISTRY produced a file (no failed results in the return array).
  2. streamProfile.total_chunks > 0 on every captured snapshot — a zero-chunk profile means the SSE interceptor missed the stream and the snapshot is unusable.
  3. toolCalls matches the D5 fixture's expected sequence — if not, either the fixture or the capture is wrong; check fixtures/d5/<feature>.json first.
  4. Open the JSON file diff — keys should be sorted, domElements sorted by (testId, tag, classes), toolCalls in arrival order. Diff-stable output is non-negotiable: a noisy diff on re-capture means either non-determinism in the LGP run or a regression in the helper's normalization.

Failure modes

The helper is fail-closed: any failure (browser launch, navigation, conversation failure_turn, DOM serialization, write) returns { status: "failed", reason } WITHOUT writing a partial file. An absent reference is correctly handled by the D6 driver (skips the comparison with a "no reference" note); a corrupt one would silently invalidate the parity verdict for that featureType.

If the capture run reports failed for a featureType, do NOT delete the older snapshot in place — leave it until a successful run replaces it atomically.