Skip to content

feat(appkit): shared agent types and LLM adapter implementations#301

Open
MarioCadenas wants to merge 1 commit intomainfrom
agent/v2/1-types-adapters
Open

feat(appkit): shared agent types and LLM adapter implementations#301
MarioCadenas wants to merge 1 commit intomainfrom
agent/v2/1-types-adapters

Conversation

@MarioCadenas
Copy link
Copy Markdown
Collaborator

@MarioCadenas MarioCadenas commented Apr 21, 2026

Foundation layer for the agents feature. Adds the portable type surface
that every downstream layer builds on, plus three LLM adapter
implementations so the agents plugin (later PR) can target whatever the
user has.

Shared agent types

packages/shared/src/agent.ts — no behavior, just the type vocabulary:
AgentAdapter, AgentEvent, AgentInput, AgentRunContext,
AgentToolDefinition, Message, Thread, ThreadStore, ToolAnnotations,
ToolCall, ToolProvider, ResponseStreamEvent. Exported from the
shared barrel.

Adapters

  • packages/appkit/src/agents/databricks.tsDatabricksAdapter:
    streams OpenAI-compatible completions against a Databricks Model
    Serving endpoint (raw fetch + SSE, no vendor SDKs).
  • packages/appkit/src/agents/vercel-ai.tsVercelAIAdapter:
    wraps any Vercel AI SDK streamText call. Maps Vercel SDK events to
    AppKit AgentEvents and tool calls.
  • packages/appkit/src/agents/langchain.tsLangChainAdapter:
    wraps any LangChain Runnable (AgentExecutor, compiled LangGraph,
    etc.). Subscribes to streamEvents(v2) and maps to AgentEvents.

Each adapter is self-contained and independently testable.

Package plumbing

  • Subpath exports @databricks/appkit/agents/{databricks,vercel-ai,langchain}
    so consumers pick only the adapter they want.
  • @langchain/core and ai declared as optional peer dependencies.
  • @ai-sdk/openai, @langchain/core, ai added as devDeps for tests.
  • tsdown.config.ts emits the three adapter entry points alongside the
    main bundle.

Test plan

  • 24 adapter tests (Databricks: 16, Vercel AI: 4, LangChain: 4) passing
  • Full appkit vitest suite: 1154 tests passing

PR Stack

  1. Shared agent types + LLM adapters (this PR)
  2. Tool primitives + ToolProvider surfaces — feat(appkit): tool primitives and ToolProvider surfaces on core plugins #302
  3. Plugin infrastructure (attachContext + PluginContext) — feat(appkit): plugin infrastructure — attachContext + PluginContext mediator #303
  4. agents() plugin + createAgent(def) + markdown-driven agents — feat(appkit): agents() plugin, createAgent(def), and markdown-driven agents #304
  5. fromPlugin() DX + runAgent plugins arg + toolkit-resolver — feat(appkit): fromPlugin() DX, runAgent plugins arg, shared toolkit-resolver #305
  6. Reference app + dev-playground + docs — feat(appkit): reference agent-app, dev-playground chat UI, docs, and template #306

This 6-PR stack is a redesign of the earlier 13-PR stack (#282-#286, #293-#300), reorganized to eliminate mid-stack API churn. Reviewers never see code in this stack that later PRs delete. The old 13 PRs have been closed with references back here.

This was referenced Apr 21, 2026
@MarioCadenas MarioCadenas force-pushed the agent/v2/1-types-adapters branch from bb4efff to 5d060a6 Compare April 21, 2026 20:41
@MarioCadenas MarioCadenas force-pushed the agent/v2/1-types-adapters branch 2 times, most recently from 3523a03 to 021cf0a Compare April 22, 2026 15:49
Foundation layer for the agents feature. Adds the portable type surface
that every downstream layer builds on, plus three LLM adapter
implementations so the agents plugin (later PR) can target whatever the
user has.

### Shared agent types

`packages/shared/src/agent.ts` — no behavior, just the type vocabulary:
`AgentAdapter`, `AgentEvent`, `AgentInput`, `AgentRunContext`,
`AgentToolDefinition`, `Message`, `Thread`, `ThreadStore`, `ToolAnnotations`,
`ToolCall`, `ToolProvider`, `ResponseStreamEvent`. Exported from the
shared barrel.

### Adapters

- `packages/appkit/src/agents/databricks.ts` — `DatabricksAdapter`:
  streams OpenAI-compatible completions against a Databricks Model
  Serving endpoint (raw fetch + SSE, no vendor SDKs).
- `packages/appkit/src/agents/vercel-ai.ts` — `VercelAIAdapter`:
  wraps any Vercel AI SDK `streamText` call. Maps Vercel SDK events to
  AppKit `AgentEvent`s and tool calls.
- `packages/appkit/src/agents/langchain.ts` — `LangChainAdapter`:
  wraps any LangChain `Runnable` (AgentExecutor, compiled LangGraph,
  etc.). Subscribes to `streamEvents(v2)` and maps to `AgentEvent`s.

Each adapter is self-contained and independently testable.

### Package plumbing

- Subpath exports `@databricks/appkit/agents/{databricks,vercel-ai,langchain}`
  so consumers pick only the adapter they want.
- `@langchain/core` and `ai` declared as optional peer dependencies.
- `@ai-sdk/openai`, `@langchain/core`, `ai` added as devDeps for tests.
- `tsdown.config.ts` emits the three adapter entry points alongside the
  main bundle.

### Test plan

- 24 adapter tests (Databricks: 16, Vercel AI: 4, LangChain: 4) passing
- Full appkit vitest suite: 1154 tests passing
- Typecheck clean
- Build clean, publint clean

Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>

### MVP polish

- **LangChain adapter `callId` correlation fix.** The previous
  implementation emitted `tool_call` with the LLM-provided
  `tc.id ?? tc.name` and `tool_result` with LangChain's internal
  `event.run_id` — these never matched, breaking every Responses-API
  client that pairs calls by `call_id`. The adapter now records a
  `run_id → callId` mapping at `on_tool_start` (matching the
  accumulated tool_call by name) and resolves it at `on_tool_end`. A
  deterministic `lc_<name>_<idx>_<counter>` fallback id prevents
  collisions when the same tool is called multiple times in one turn
  without a model-provided id. Adds three regression tests covering
  happy-path correlation, duplicate-name disambiguation, and the
  no-accumulator-match fallback.

- **Adapter docstring cleanup.** The four `@example` blocks in
  `databricks.ts`, `langchain.ts`, and `vercel-ai.ts` referenced a
  fictional `appkit.agent.registerAgent("assistant", adapter)` API
  that has never existed. Replaced with real usage via
  `createApp({ plugins: [agents({ agents: { assistant: createAgent(
  { model: adapter }) } })] })`.

Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
@MarioCadenas MarioCadenas force-pushed the agent/v2/1-types-adapters branch from 021cf0a to a4d0130 Compare April 22, 2026 16:19
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