Files
Michał Pierzchała 801734d433 feat(ai-sdk): add agent-device/ai-sdk tool set and document the MCP zero-code path (#1804)
* feat(ai-sdk): add agent-device/ai-sdk tool set and document the MCP zero-code path

Adds `createAgentDeviceTools()` under a new `agent-device/ai-sdk` subpath,
built from the same command registry the MCP server uses so both stay in
lockstep without a hand-maintained tool list. Introduces a `frameworkTier`
descriptor facet ('core' | 'extended') so the factory can default to a
curated perceive/act loop instead of handing a model dozens of tools.

`ai` is wired as an optional peer dependency, imported lazily inside the
factory rather than at module scope, so importing the subpath itself never
requires `ai` to be installed - only calling it does. The package's own
publishing gate (scripts/lib/shipped-imports.ts) is extended to recognize
peerDependencies as a valid resolution source, since this is the first
optional peer this package has shipped.

Also restructures the AI SDK doc around three tiers (zero-code via
@ai-sdk/mcp, the new typed tool set, hand-written tools) and fixes a stale
`needsApproval` reference in favor of the current `toolApproval` API.

* fix(layering): classify src/ai-sdk as a rank-4 zone

The layering guard requires every src/<folder>/ to be explicitly ranked or
unranked; the new src/ai-sdk/ subpath (added in the prior commit) was left
unclassified, failing CI's Layering Guard job. It sits at the same tier as
client/compat/daemon-server/metro/remote/sdk - a public integration surface
consuming mcp (3) and core (2), imported by nothing else in the tree.

* fix(ci): cover, exempt, and pack the new ai-sdk subpath

Fixes the remaining CI failures on the ai-sdk subpath commit:

- Coverage: src/ai-sdk/index.ts had no dedicated unit test (only manual/
  integration verification), so changed-line coverage sat at 6.9% against
  the 70% gate. Adds src/ai-sdk/__tests__/index.test.ts (core vs 'all' tool
  filtering, session/platform pinning and schema hiding, error
  normalization, toolApproval passthrough) with createCommandToolExecutor
  and createAgentDeviceClient mocked the same way command-tools.test.ts
  does, plus a dedicated missing-peer-dependency.test.ts that mocks `ai`
  itself to throw, isolated to its own file so it doesn't affect the other
  tests' use of the real, installed `ai` package. Changed-line coverage is
  now 29/29 (100%).
- Fallow Code Quality: src/ai-sdk/index.ts and examples/sdk/ai-sdk-tools.ts
  are entry points with no in-repo importer (reached only via package.json
  exports / run directly), and the new subpath's exports are unused
  internally by design - both need the same treatment src/sdk/*.ts and its
  examples already have in .fallowrc.json.
- Integration Tests: test/integration/installed-package-metro.test.ts and
  src/__tests__/package-exports.test.ts each hand-list every published
  subpath and smoke-check it from a real packed install; added ./ai-sdk to
  both so the new subpath is actually exercised, not just silently passing.

* fix(ai-sdk): hide MCP transport/config fields from the model too

createAgentDeviceTools() only removed session and mcpOutputFormat from tool
schemas. stateDir was still model-visible and reached the shared executor
as client configuration, letting a tool call redirect into a different
daemon state directory - defeating the "one pinned session" guarantee the
factory exists to provide. includeCost and responseLevel are MCP
tool-config knobs in the same category, irrelevant to this adapter.

Widens the hidden-field set to session/stateDir/mcpOutputFormat/
includeCost/responseLevel, and now strips them from the runtime input
inside execute() too (not just the schema), so the guarantee holds even if
a caller bypasses schema validation. The schema-properties filter and the
input filter now share one omitHidden() helper instead of two near-
duplicate implementations.

Addresses the P1 review comment on #1804.
2026-08-18 11:57:34 +02:00

2.4 KiB

Examples

Runnable, typechecked Node.js examples for the agent-device SDK surface exposed to Node consumers. Source of truth for the API itself is Node.js API. Two guards keep these files in sync with that doc: src/__tests__/client-api-examples-drift.test.ts checks the doc's subpath API manifest against what these examples import, and test/integration/client-api-doc-snippets.test.ts compiles every fenced TypeScript code block in the doc itself against the real agent-device/* sources.

sdk/

Standalone scripts under sdk/ exercise the published agent-device export map — agent-device, agent-device/metro, agent-device/contracts, agent-device/batch, and agent-device/ai-sdk — the same way a Node consumer or the agent-device-cloud bridge would. Each file:

  • has a top comment stating what it demonstrates and its prerequisites (daemon running, device/simulator available);
  • typechecks without live hardware — pnpm typecheck resolves the agent-device/... imports against src/sdk/ via examples/sdk/tsconfig.json's paths, so CI checks them without a build or publish step;
  • imports the package by name (agent-device/...), not a relative src/ path, so it exercises the same surface a real consumer sees;
  • is runnable on its own with node --experimental-strip-types (repo Node is >=22.12) once the package is built (pnpm build) — running for real resolves agent-device as a self-referencing package, the same way an installed consumer would.
Example Subpath Demonstrates
client-session.ts agent-device createAgentDeviceClient → open → snapshot/tap → close, with typed error handling
metro-runtime.ts agent-device/metro normalizeBaseUrl, resolveRuntimeTransport
contracts-result.ts agent-device/contracts typed result consumption via centerOfRect
batch-orchestration.ts agent-device/batch runBatch for a custom transport
ai-sdk-tools.ts agent-device/ai-sdk createAgentDeviceTools driven by a ToolLoopAgent

test-app/

test-app/ is the Expo dogfood fixture used for agent-device experiments (see its own README) — it is a test fixture, not an SDK usage example.