diff --git a/README.md b/README.md index d5bb3ac..e4d97b8 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,12 @@ Run the sample CI regression gate: bun run --filter './examples/ci-regression-gate' dev ``` +Run mocked ecosystem adapter examples: + +```bash +bun run --filter './examples/ecosystem-adapters' dev +``` + Run the alpha dogfood document-assistant experiment: ```bash diff --git a/bun.lock b/bun.lock index ded9729..e032b8c 100644 --- a/bun.lock +++ b/bun.lock @@ -62,6 +62,20 @@ "@ignitionai/agent-trainer-preset-rag": "workspace:*", }, }, + "examples/ecosystem-adapters": { + "name": "ecosystem-adapters", + "version": "0.0.0", + "dependencies": { + "@ignitionai/agent-trainer-adapter-langchain": "workspace:*", + "@ignitionai/agent-trainer-adapter-langgraph": "workspace:*", + "@ignitionai/agent-trainer-adapter-mastra": "workspace:*", + "@ignitionai/agent-trainer-adapter-vercel-ai": "workspace:*", + "@ignitionai/agent-trainer-core": "workspace:*", + "@ignitionai/agent-trainer-evals": "workspace:*", + "@ignitionai/agent-trainer-experiments": "workspace:*", + "vitest": "latest", + }, + }, "examples/ignitionrag-evaluation-bridge": { "name": "ignitionrag-evaluation-bridge", "version": "0.0.0", @@ -576,6 +590,8 @@ "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + "ecosystem-adapters": ["ecosystem-adapters@workspace:examples/ecosystem-adapters"], + "es-module-lexer": ["es-module-lexer@2.1.0", "", {}, "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ=="], "esbuild": ["esbuild@0.27.7", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.7", "@esbuild/android-arm": "0.27.7", "@esbuild/android-arm64": "0.27.7", "@esbuild/android-x64": "0.27.7", "@esbuild/darwin-arm64": "0.27.7", "@esbuild/darwin-x64": "0.27.7", "@esbuild/freebsd-arm64": "0.27.7", "@esbuild/freebsd-x64": "0.27.7", "@esbuild/linux-arm": "0.27.7", "@esbuild/linux-arm64": "0.27.7", "@esbuild/linux-ia32": "0.27.7", "@esbuild/linux-loong64": "0.27.7", "@esbuild/linux-mips64el": "0.27.7", "@esbuild/linux-ppc64": "0.27.7", "@esbuild/linux-riscv64": "0.27.7", "@esbuild/linux-s390x": "0.27.7", "@esbuild/linux-x64": "0.27.7", "@esbuild/netbsd-arm64": "0.27.7", "@esbuild/netbsd-x64": "0.27.7", "@esbuild/openbsd-arm64": "0.27.7", "@esbuild/openbsd-x64": "0.27.7", "@esbuild/openharmony-arm64": "0.27.7", "@esbuild/sunos-x64": "0.27.7", "@esbuild/win32-arm64": "0.27.7", "@esbuild/win32-ia32": "0.27.7", "@esbuild/win32-x64": "0.27.7" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w=="], diff --git a/docs/ALPHA_READINESS.md b/docs/ALPHA_READINESS.md index 03a09d1..2c8ffb5 100644 --- a/docs/ALPHA_READINESS.md +++ b/docs/ALPHA_READINESS.md @@ -23,10 +23,10 @@ All packages declare `license: MIT`, matching the root `LICENSE` file. |---|---|---|---|---|---|---| | `@ignitionai/agent-trainer-adapter-callable` | ready | ready | ready | ready | ready | Generic callable adapter has docs, tests and an example. | | `@ignitionai/agent-trainer-adapter-ignitionrag` | ready | ready | ready | ready | partial | Type-level contract only; no runtime IgnitionRAG integration. | -| `@ignitionai/agent-trainer-adapter-langchain` | ready | ready | ready | ready | partial | Structural adapter only; no dedicated example or deep framework coverage. | -| `@ignitionai/agent-trainer-adapter-langgraph` | ready | ready | ready | ready | partial | Structural adapter only; no persistence, streaming or graph internals. | -| `@ignitionai/agent-trainer-adapter-mastra` | ready | ready | ready | ready | partial | Structural adapter only; no memory, tool or full Mastra coverage. | -| `@ignitionai/agent-trainer-adapter-vercel-ai` | ready | ready | ready | ready | partial | Structural adapter only; no streaming, tools or live provider calls. | +| `@ignitionai/agent-trainer-adapter-langchain` | ready | ready | ready | ready | partial | Structural adapter with mocked example coverage; no deep LangChain internals. | +| `@ignitionai/agent-trainer-adapter-langgraph` | ready | ready | ready | ready | partial | Structural adapter with mocked example coverage; no persistence, streaming or graph internals. | +| `@ignitionai/agent-trainer-adapter-mastra` | ready | ready | ready | ready | partial | Structural adapter with mocked example coverage; no memory, tool or full Mastra coverage. | +| `@ignitionai/agent-trainer-adapter-vercel-ai` | ready | ready | ready | ready | partial | Structural adapter with mocked example coverage; no streaming, tools or live provider calls. | | `@ignitionai/agent-trainer-cli` | ready | ready | ready | ready | partial | Runs typed experiments, writes reports/bundles, records local history, selects baselines and runs regression checks; no watch mode or remote execution. | | `@ignitionai/agent-trainer-core` | ready | ready | ready | ready | partial | Foundational helpers have dedicated tests; runtime schema validation remains outside the current helper surface. | | `@ignitionai/agent-trainer-environment` | ready | ready | ready | ready | partial | Tested episode runner with safety guards and a deterministic RAG episode example; no production runtime or optimization loop. | @@ -55,7 +55,6 @@ All packages declare `license: MIT`, matching the root `LICENSE` file. ## Known Work After Internal Alpha -- Add deeper mocked examples for ecosystem adapters. - Dogfood the alpha inside IgnitionRAG and collect trajectory/reward evidence. - Add a lightweight policy optimization loop after real dogfood produces trajectory data. - Decide any next-step publishing automation policy before a future public release workflow. diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md index a14dbf3..5db2e5b 100644 --- a/docs/BACKLOG.md +++ b/docs/BACKLOG.md @@ -2850,7 +2850,7 @@ Next PR: Status: -- current +- completed Branch: @@ -2912,7 +2912,7 @@ Next PR: Status: -- planned +- current Branch: diff --git a/docs/PROJECT_AUDIT.md b/docs/PROJECT_AUDIT.md index efaa40a..0c53bc1 100644 --- a/docs/PROJECT_AUDIT.md +++ b/docs/PROJECT_AUDIT.md @@ -43,7 +43,7 @@ If a package exists but is intentionally narrow, minimal or untested, it is part - Main exports: `createLangChainAdapter`, `langChainAdapter`, `LangChainRunnableLike`. - Stability level: partial. - Tests present: yes. -- Example present: no dedicated example. +- Example present: yes, `examples/ecosystem-adapters`. - Known limitations: does not require or inspect LangChain internals, does not stream, does not call providers, and only expects `invoke()`. ### `@ignitionai/agent-trainer-adapter-langgraph` @@ -52,7 +52,7 @@ If a package exists but is intentionally narrow, minimal or untested, it is part - Main exports: `createLangGraphAdapter`, `langGraphAdapter`, `LangGraphLike`. - Stability level: partial. - Tests present: yes. -- Example present: no dedicated example. +- Example present: yes, `examples/ecosystem-adapters`. - Known limitations: does not persist graph state, stream events, inspect graph internals or call providers. ### `@ignitionai/agent-trainer-adapter-mastra` @@ -61,7 +61,7 @@ If a package exists but is intentionally narrow, minimal or untested, it is part - Main exports: `createMastraAdapter`, `mastraAdapter`, `MastraAgentLike`. - Stability level: partial. - Tests present: yes. -- Example present: no dedicated example. +- Example present: yes, `examples/ecosystem-adapters`. - Known limitations: only supports `generate()` or `run()` style objects, no tools, memory, persistence or full Mastra API coverage. ### `@ignitionai/agent-trainer-adapter-vercel-ai` @@ -70,7 +70,7 @@ If a package exists but is intentionally narrow, minimal or untested, it is part - Main exports: `createVercelAiAdapter`, `vercelAiAdapter`, `VercelAiGenerateLike`. - Stability level: partial. - Tests present: yes. -- Example present: no dedicated example. +- Example present: yes, `examples/ecosystem-adapters`. - Known limitations: no real provider calls, no auth, no streaming, no tool integration and no prompt generation. ### `@ignitionai/agent-trainer-cli` @@ -187,6 +187,14 @@ If a package exists but is intentionally narrow, minimal or untested, it is part - Mocked or live: mocked. - Product concept: context engineering strategy comparison and CLI-ready typed experiments. +### `examples/ecosystem-adapters` + +- Demonstrates: LangChain, LangGraph, Mastra and Vercel AI SDK-style adapters wired into `createExperiment()`. +- Command: `bun run --filter './examples/ecosystem-adapters' dev`. +- Test command: `bun test examples/ecosystem-adapters/src/example.test.ts`. +- Mocked or live: deterministic mocked framework objects. +- Product concept: adapter portability with trace, usage and metadata preserved through standard experiment results. + ### `examples/ci-regression-gate` - Demonstrates: comparing a current experiment result against a committed baseline in CI. @@ -221,7 +229,7 @@ If a package exists but is intentionally narrow, minimal or untested, it is part | Capability | Status | Package/File | Stable? | Notes | |---|---|---|---|---| -| core primitives | partial | `packages/core` | No | Core types and helpers exist, but package lacks dedicated tests. | +| core primitives | partial | `packages/core` | No | Core types and helpers have dedicated tests; runtime schema validation remains out of scope. | | IgnitionRAG adapter contract | partial | `packages/adapter-ignitionrag` | No | Type-level contract only; no runtime IgnitionRAG integration. | | evals/rewards | partial | `packages/evals` | No | Tests and README exist, but reward set is intentionally small. | | RAG presets | partial | `packages/preset-rag` | No | Deterministic presets compose text, citation, latency, cost and tool-use rewards. | @@ -232,15 +240,15 @@ If a package exists but is intentionally narrow, minimal or untested, it is part | context engineering example | done | `examples/context-engineering` | Yes | Mocked strategy comparison plus CLI module. | | exporters | done | `packages/exporters` | Yes | Stable JSON/Markdown export shape and local report bundle writer. | | typed experiment definitions | done | `packages/experiments/src/definition.ts` | Yes | Used by the CLI example. | -| CLI runner | partial | `packages/cli` | Yes | Current command works; history, baselines and regression gates are not CLI flags yet. | +| CLI runner | partial | `packages/cli` | Yes | Runs experiments, reports, bundles, local history, baseline selection and regression checks. | | regression gates | done | `packages/experiments/src/regression-gates.ts` | Yes | Tested comparison helpers plus a copyable CI example. | | alpha dogfood workflow | done | `examples/alpha-dogfood` | Yes | Deterministic IgnitionRAG-style document assistant evaluation with report exports and a regression gate. | -| ecosystem adapters | partial | `packages/adapter-*` | No | Structural adapters exist with tests/docs, but dedicated examples and deeper framework coverage are missing. | +| ecosystem adapters | partial | `packages/adapter-*` | No | Structural adapters exist with tests/docs and a grouped mocked example; deeper framework internals remain out of scope. | | simple search optimization | done | `packages/trainer/src/search.ts` | Yes | Deterministic grid search over manual parameter grids. | | IgnitionRAG design | done | `docs/10-ignitionrag-integration-design.md` | Yes | Design-only; no IgnitionRAG runtime integration. | | IgnitionRAG Evaluation Center checklist | done | `docs/IGNITIONRAG_EVALUATION_CENTER_CHECKLIST.md` | Yes | Actionable checklist only; no IgnitionRAG app code, migrations or frontend. | | IgnitionRAG evaluation bridge prototype | prototype | `examples/ignitionrag-evaluation-bridge` | No | Deterministic record mapping only; no database, hosted worker, auth or real provider calls. | -| file-based history | done | `packages/experiments/src/history.ts` | Yes | JSONL local history helpers, no CLI flag yet. | +| file-based history | done | `packages/experiments/src/history.ts` and `packages/cli` | Yes | JSONL local history helpers plus CLI list/show/record workflows. | | policy abstraction | partial | `packages/rl/src/policy.ts` | No | Deterministic static and score-based selection only; no training loop. | | environment episodes | partial | `packages/environment` | No | Tested episode runner with max-step safety, seed forwarding, final state and metadata. | | trajectory recorder | partial | `packages/rl/src/trajectory.ts` | No | Local state/action/reward/outcome records with deterministic summaries. | diff --git a/examples/ecosystem-adapters/README.md b/examples/ecosystem-adapters/README.md new file mode 100644 index 0000000..076d68d --- /dev/null +++ b/examples/ecosystem-adapters/README.md @@ -0,0 +1,24 @@ +# Ecosystem Adapter Examples + +This example runs deterministic mocked adapters for: + +- LangChain Runnable-like objects, +- LangGraph graph-like objects, +- Mastra agent-like objects, +- Vercel AI SDK-style generate functions. + +Each adapter plugs into `createExperiment()` as an `AgentVariant`. The mocks return trace, usage and metadata so the example can validate adapter observability without provider credentials or network calls. + +Run it: + +```bash +bun run --filter './examples/ecosystem-adapters' dev +``` + +Run the example test: + +```bash +bun test examples/ecosystem-adapters/src/example.test.ts +``` + +This is not deep framework coverage. It proves the adapter contracts work with public package APIs and documents the shape each adapter expects. diff --git a/examples/ecosystem-adapters/package.json b/examples/ecosystem-adapters/package.json new file mode 100644 index 0000000..162004f --- /dev/null +++ b/examples/ecosystem-adapters/package.json @@ -0,0 +1,20 @@ +{ + "name": "ecosystem-adapters", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "bun src/index.ts", + "test": "vitest run" + }, + "dependencies": { + "@ignitionai/agent-trainer-adapter-langchain": "workspace:*", + "@ignitionai/agent-trainer-adapter-langgraph": "workspace:*", + "@ignitionai/agent-trainer-adapter-mastra": "workspace:*", + "@ignitionai/agent-trainer-adapter-vercel-ai": "workspace:*", + "@ignitionai/agent-trainer-core": "workspace:*", + "@ignitionai/agent-trainer-evals": "workspace:*", + "@ignitionai/agent-trainer-experiments": "workspace:*", + "vitest": "latest" + } +} diff --git a/examples/ecosystem-adapters/src/example.test.ts b/examples/ecosystem-adapters/src/example.test.ts new file mode 100644 index 0000000..8daa1fe --- /dev/null +++ b/examples/ecosystem-adapters/src/example.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, it } from "vitest"; +import { dataset, runEcosystemAdapterExperiment, variants } from "./example"; + +describe("ecosystem adapter example", () => { + it("runs mocked ecosystem adapters through createExperiment with trace, usage and metadata", async () => { + const result = await runEcosystemAdapterExperiment(); + + expect(result.name).toBe("ecosystem-adapter-comparison"); + expect(result.failedCases).toEqual([]); + expect(result.leaderboard.map((row) => row.variantId).sort()).toEqual( + variants.map((variant) => variant.id).sort(), + ); + expect(result.cases).toHaveLength(dataset.items.length * variants.length); + + for (const caseResult of result.cases) { + expect(caseResult.score).toBeGreaterThan(0.8); + expect(caseResult.trace.steps.length).toBeGreaterThan(0); + expect(caseResult.usage?.latencyMs).toBeGreaterThan(0); + expect(caseResult.usage?.costUsd).toBeGreaterThan(0); + expect(caseResult.metadata?.framework).toBeDefined(); + } + + expect(result.cases.map((caseResult) => caseResult.metadata?.framework).sort()).toEqual([ + "langchain", + "langchain", + "langgraph", + "langgraph", + "mastra", + "mastra", + "vercel-ai", + "vercel-ai", + ]); + }); +}); diff --git a/examples/ecosystem-adapters/src/example.ts b/examples/ecosystem-adapters/src/example.ts new file mode 100644 index 0000000..8a53184 --- /dev/null +++ b/examples/ecosystem-adapters/src/example.ts @@ -0,0 +1,219 @@ +import { langChainAdapter } from "@ignitionai/agent-trainer-adapter-langchain"; +import { langGraphAdapter } from "@ignitionai/agent-trainer-adapter-langgraph"; +import { mastraAdapter } from "@ignitionai/agent-trainer-adapter-mastra"; +import { vercelAiAdapter } from "@ignitionai/agent-trainer-adapter-vercel-ai"; +import { + createDataset, + type DatasetItem, + type RunResult, + type UsageMetrics, +} from "@ignitionai/agent-trainer-core"; +import { containsAll, costPenalty, latencyPenalty } from "@ignitionai/agent-trainer-evals"; +import { createExperiment } from "@ignitionai/agent-trainer-experiments"; + +type FrameworkName = "langchain" | "langgraph" | "mastra" | "vercel-ai"; + +interface MockFrameworkResult { + text: string; + retrieved: string; + model: string; + mode: string; + usage: UsageMetrics; + metadata: { + framework: FrameworkName; + mockProvider: true; + model: string; + }; +} + +export const dataset = createDataset({ + name: "ecosystem-adapter-observability", + description: "Checks that ecosystem adapters preserve output, trace, usage and metadata.", + items: [ + { + id: "adapter-observability", + input: "Show that adapter results keep trace, usage and metadata.", + expected: { + contains: ["trace", "usage", "metadata"], + }, + }, + { + id: "adapter-portability", + input: "Show that a mocked provider shape can run through createExperiment.", + expected: { + contains: ["createExperiment", "mocked", "provider"], + }, + }, + ], +}); + +export const variants = [ + langChainAdapter({ + id: "langchain-runnable", + name: "LangChain Runnable", + runnable: { + invoke(input) { + return frameworkResult("langchain", toCaseId(input), 420, 0.0014); + }, + }, + mapInput: adapterInput, + mapOutput: (raw, input) => mapMockFrameworkResult("langchain", raw, input.item.id), + metadata: { adapterFamily: "langchain" }, + }), + langGraphAdapter({ + id: "langgraph-graph", + name: "LangGraph Graph", + graph: { + invoke(input) { + return frameworkResult("langgraph", toCaseId(input), 510, 0.0018); + }, + }, + mapInput: adapterInput, + mapOutput: (raw, input) => mapMockFrameworkResult("langgraph", raw, input.item.id), + metadata: { adapterFamily: "langgraph" }, + }), + mastraAdapter({ + id: "mastra-agent", + name: "Mastra Agent", + agent: { + generate(input) { + return frameworkResult("mastra", toCaseId(input), 470, 0.0016); + }, + }, + mapInput: adapterInput, + mapOutput: (raw, input) => mapMockFrameworkResult("mastra", raw, input.item.id), + metadata: { adapterFamily: "mastra" }, + }), + vercelAiAdapter({ + id: "vercel-ai-generate", + name: "Vercel AI Generate", + generate(input) { + const caseId = typeof input.caseId === "string" ? input.caseId : "adapter-observability"; + const result = frameworkResult("vercel-ai", caseId, 390, 0.0012); + return { + text: result.text, + usage: result.usage, + metadata: result.metadata, + }; + }, + mapInput: (item) => ({ + prompt: item.input, + caseId: item.id, + model: "mock-vercel-ai-model", + }), + metadata: { adapterFamily: "vercel-ai" }, + }), +]; + +export function createEcosystemAdapterExperiment() { + return createExperiment({ + name: "ecosystem-adapter-comparison", + dataset, + variants, + rewards: [ + containsAll({ weight: 0.7 }), + latencyPenalty({ maxLatencyMs: 1000, weight: 0.15 }), + costPenalty({ maxCostUsd: 0.005, weight: 0.15 }), + ], + options: { + concurrency: 4, + }, + metadata: { + providerCalls: "mocked", + }, + }); +} + +export async function runEcosystemAdapterExperiment() { + return createEcosystemAdapterExperiment().run(); +} + +function adapterInput(item: DatasetItem): { prompt: string; caseId: string } { + return { + prompt: item.input, + caseId: item.id, + }; +} + +function mapMockFrameworkResult(framework: FrameworkName, raw: unknown, caseId: string): RunResult { + const result = assertMockFrameworkResult(raw, framework); + return { + output: result.text, + trace: { + steps: [ + { + type: "tool_call", + name: `${framework}.mock_retrieve`, + input: { caseId }, + output: result.retrieved, + }, + { + type: "custom", + name: `${framework}.mock_response`, + payload: { + model: result.model, + mode: result.mode, + }, + }, + ], + }, + usage: result.usage, + metadata: { + framework, + model: result.model, + mode: result.mode, + }, + }; +} + +function frameworkResult( + framework: FrameworkName, + caseId: string, + latencyMs: number, + costUsd: number, +): MockFrameworkResult { + const model = `mock-${framework}-model`; + return { + text: frameworkAnswer(framework, caseId), + retrieved: `${framework}-docs#${caseId}`, + model, + mode: "deterministic-example", + usage: { + inputTokens: 120, + outputTokens: 42, + totalTokens: 162, + latencyMs, + costUsd, + }, + metadata: { + framework, + mockProvider: true, + model, + }, + }; +} + +function frameworkAnswer(framework: FrameworkName, caseId: string): string { + if (caseId === "adapter-portability") { + return `${framework} uses a mocked provider shape that plugs into createExperiment without network calls.`; + } + + return `${framework} preserves trace, usage and metadata from the adapter result.`; +} + +function toCaseId(input: unknown): string { + if (isRecord(input) && typeof input.caseId === "string") return input.caseId; + return "adapter-observability"; +} + +function assertMockFrameworkResult(raw: unknown, framework: FrameworkName): MockFrameworkResult { + if (!isRecord(raw) || typeof raw.text !== "string" || !isRecord(raw.usage)) { + throw new Error(`Invalid mocked ${framework} result.`); + } + + return raw as unknown as MockFrameworkResult; +} + +function isRecord(value: unknown): value is Record { + return typeof value === "object" && value !== null && !Array.isArray(value); +} diff --git a/examples/ecosystem-adapters/src/index.ts b/examples/ecosystem-adapters/src/index.ts new file mode 100644 index 0000000..e75cbe4 --- /dev/null +++ b/examples/ecosystem-adapters/src/index.ts @@ -0,0 +1,27 @@ +import { dataset, runEcosystemAdapterExperiment, variants } from "./example"; + +const result = await runEcosystemAdapterExperiment(); + +console.log(`Experiment: ${result.name}`); +console.log(`Dataset items: ${dataset.items.length}`); +console.log(`Variants: ${variants.map((variant) => variant.name).join(", ")}`); +console.log(""); +console.log("Leaderboard:"); +for (const [index, row] of result.leaderboard.entries()) { + console.log( + `${index + 1}. ${row.name} - ${row.score.toFixed(2)} (${row.averageLatencyMs?.toFixed( + 0, + )}ms avg)`, + ); +} + +console.log(""); +console.log("Adapter evidence:"); +for (const row of result.leaderboard) { + const firstCase = result.cases.find((caseResult) => caseResult.variantId === row.variantId); + console.log( + `- ${row.name}: trace steps ${firstCase?.trace.steps.length ?? 0}, latency ${ + firstCase?.usage?.latencyMs ?? "n/a" + }ms, metadata framework ${String(firstCase?.metadata?.framework ?? "n/a")}`, + ); +} diff --git a/packages/adapter-langchain/README.md b/packages/adapter-langchain/README.md index 3f36c54..a19be47 100644 --- a/packages/adapter-langchain/README.md +++ b/packages/adapter-langchain/README.md @@ -31,6 +31,10 @@ const variant = langChainAdapter({ The adapter uses `@ignitionai/agent-trainer-adapter-callable` internally, so thrown runnable errors flow through the standard experiment failure path. +## Example + +See `examples/ecosystem-adapters` for a runnable mocked LangChain adapter wired into `createExperiment()` with trace, usage and metadata mapping. + ## Mapping Customize input and output conversion with `mapInput` and `mapOutput`: diff --git a/packages/adapter-langgraph/README.md b/packages/adapter-langgraph/README.md index 6253f72..c5ce7c6 100644 --- a/packages/adapter-langgraph/README.md +++ b/packages/adapter-langgraph/README.md @@ -39,6 +39,10 @@ The default input shape is message-oriented: Customize input and output conversion with `mapInput` and `mapOutput`. +## Example + +See `examples/ecosystem-adapters` for a runnable mocked LangGraph adapter wired into `createExperiment()` with trace, usage and metadata mapping. + ## Non-goals This adapter does not persist graph state, stream events, call real providers, inspect graph internals or adapt LangChain/Mastra/Vercel AI SDK behavior. diff --git a/packages/adapter-mastra/README.md b/packages/adapter-mastra/README.md index 4e4be3d..325a0c5 100644 --- a/packages/adapter-mastra/README.md +++ b/packages/adapter-mastra/README.md @@ -31,6 +31,10 @@ const variant = mastraAdapter({ The adapter uses `@ignitionai/agent-trainer-adapter-callable` internally, so thrown agent errors flow through the standard experiment failure path. +## Example + +See `examples/ecosystem-adapters` for a runnable mocked Mastra adapter wired into `createExperiment()` with trace, usage and metadata mapping. + ## Mapping Customize input and output conversion with `mapInput` and `mapOutput`: diff --git a/packages/adapter-vercel-ai/README.md b/packages/adapter-vercel-ai/README.md index 11bfea0..d024e36 100644 --- a/packages/adapter-vercel-ai/README.md +++ b/packages/adapter-vercel-ai/README.md @@ -37,6 +37,10 @@ const generate = async ({ prompt }) => ({ }); ``` +## Example + +See `examples/ecosystem-adapters` for a runnable mocked Vercel AI SDK-style adapter wired into `createExperiment()` with trace, usage and metadata mapping. + ## Mapping Customize input and output conversion with `baseOptions`, `mapInput` and `mapOutput`.