@agentproto/adapter-mastra-agent 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,7 +11,7 @@ models, no third-party CLI.
11
11
  agentproto-mastra acp --model anthropic/claude-opus-4-8
12
12
 
13
13
  # Or let the agentproto daemon spawn it like any other arm:
14
- # start_agent_session({ adapter: "mastra-agent", model: "openrouter/z-ai/glm-5.2" })
14
+ # agent_start({ adapter: "mastra-agent", model: "openrouter/z-ai/glm-5.2" })
15
15
  ```
16
16
 
17
17
  ## How it works
@@ -47,6 +47,11 @@ cwd** (path-traversal guarded):
47
47
  | `edit_file` | Replace a unique substring. |
48
48
  | `run_command` | Run a shell command (cwd-scoped, timeout). |
49
49
 
50
+ > **Note:** `read_file` and `write_file` here are Mastra-native workspace tools
51
+ > scoped to this adapter's session cwd. They are distinct from the runtime MCP
52
+ > filesystem tools (`file_read`, `file_write`) registered on the daemon's `/mcp`
53
+ > endpoint.
54
+
50
55
  `run_command` is on by default; set `AGENTPROTO_MASTRA_NO_EXEC=1` to withhold it.
51
56
 
52
57
  ## Memory
@@ -277,8 +277,8 @@ function toolKindFor(toolName) {
277
277
  }
278
278
  function toolCallTitle(toolName, args) {
279
279
  if (args && typeof args === "object") {
280
- const a = args;
281
- const hint = typeof a.command === "string" && a.command || typeof a.path === "string" && a.path || typeof a.file === "string" && a.file || "";
280
+ const { command, path, file } = args;
281
+ const hint = typeof command === "string" && command || typeof path === "string" && path || typeof file === "string" && file || "";
282
282
  if (hint) return `${toolName}: ${hint}`;
283
283
  }
284
284
  return toolName;
@@ -294,26 +294,27 @@ function chunkToSessionUpdate(chunk) {
294
294
  };
295
295
  }
296
296
  case "tool-call": {
297
- const p = chunk.payload;
298
- if (!p?.toolCallId) return null;
299
- const toolName = p.toolName ?? "tool";
297
+ const toolCallId = chunk.payload?.toolCallId;
298
+ if (!toolCallId) return null;
299
+ const toolName = chunk.payload?.toolName ?? "tool";
300
+ const args = chunk.payload?.args;
300
301
  return {
301
302
  sessionUpdate: "tool_call",
302
- toolCallId: p.toolCallId,
303
- title: toolCallTitle(toolName, p.args),
303
+ toolCallId,
304
+ title: toolCallTitle(toolName, args),
304
305
  kind: toolKindFor(toolName),
305
306
  status: "in_progress",
306
- rawInput: p.args
307
+ rawInput: args
307
308
  };
308
309
  }
309
310
  case "tool-result": {
310
- const p = chunk.payload;
311
- if (!p?.toolCallId) return null;
311
+ const toolCallId = chunk.payload?.toolCallId;
312
+ if (!toolCallId) return null;
312
313
  return {
313
314
  sessionUpdate: "tool_call_update",
314
- toolCallId: p.toolCallId,
315
- status: p.isError ? "failed" : "completed",
316
- rawOutput: p.result
315
+ toolCallId,
316
+ status: chunk.payload?.isError ? "failed" : "completed",
317
+ rawOutput: chunk.payload?.result
317
318
  };
318
319
  }
319
320
  default:
@@ -365,7 +366,8 @@ var MastraAcpAgent = class {
365
366
  const agent = await this.#ensureAgent();
366
367
  const result = await agent.stream(text, {
367
368
  abortSignal: ac.signal,
368
- memory: { thread: params.sessionId, resource: this.#resource }
369
+ memory: { thread: params.sessionId, resource: this.#resource },
370
+ maxSteps: 200
369
371
  });
370
372
  if (result.fullStream) {
371
373
  await this.#pumpFullStream(params.sessionId, result.fullStream, ac);
@@ -472,5 +474,5 @@ function runAcpOverStdio(buildAgent) {
472
474
  }
473
475
 
474
476
  export { DEFAULT_MODEL, DEFAULT_TOOL_IDS, MastraAcpAgent, buildSqliteMemory, chunkToSessionUpdate, defaultAgentManifest, makeAgentFactory, makeWorkspaceTools, modelRefToString, promptText, providerOf, resolveInCwd, resolveMastraModel, resolveMemoryDbPath, runAcpOverStdio, toolCallTitle, toolKindFor };
475
- //# sourceMappingURL=chunk-7SWAWNDG.mjs.map
476
- //# sourceMappingURL=chunk-7SWAWNDG.mjs.map
477
+ //# sourceMappingURL=chunk-5G4U3UGM.mjs.map
478
+ //# sourceMappingURL=chunk-5G4U3UGM.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/memory.ts","../src/model-resolver.ts","../src/workspace-tools.ts","../src/default-agent.ts","../src/tool-call-map.ts","../src/acp-host.ts","../src/run.ts"],"names":["fs"],"mappings":"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","file":"chunk-5G4U3UGM.mjs","sourcesContent":["/**\n * SQLite-backed memory for the agent, via Mastra's LibSQL store.\n *\n * Each ACP session is a memory *thread* (see acp-host.ts), so the agent recalls\n * earlier turns within a session. The db is a single SQLite file (LibSQL is a\n * SQLite fork) under `~/.agentproto/mastra-agent/` by default — persistent\n * across spawns — overridable with `AGENTPROTO_MASTRA_MEMORY_DB`.\n */\n\nimport { mkdirSync } from \"node:fs\"\nimport { homedir } from \"node:os\"\nimport { join } from \"node:path\"\nimport { LibSQLStore } from \"@mastra/libsql\"\nimport { Memory } from \"@mastra/memory\"\nimport type { MemoryConfig } from \"@agentproto/agent\"\n\n/** A built Mastra memory — structural, matching `@agentproto/mastra`'s\n * `MastraMemoryLike` expectation without importing the exact type. */\nexport type MastraMemoryLike = Memory\n\n/** Resolve the SQLite file path, creating the parent dir. `AGENTPROTO_MASTRA_MEMORY_DB`\n * wins; otherwise `~/.agentproto/mastra-agent/memory.db`. */\nexport function resolveMemoryDbPath(\n env: Record<string, string | undefined> = process.env,\n): string {\n const override = env.AGENTPROTO_MASTRA_MEMORY_DB\n if (override) return override\n const dir = join(homedir(), \".agentproto\", \"mastra-agent\")\n mkdirSync(dir, { recursive: true })\n return join(dir, \"memory.db\")\n}\n\n/**\n * Build a Mastra `Memory` from an AIP-42 `memory:` config. Returns `undefined`\n * when memory is disabled (`scope: \"none\"`) so `buildMastraAgent` attaches none.\n *\n * - `retention_turns` → `options.lastMessages` (how many recent messages to\n * replay into context). Defaults to 20.\n * - Semantic recall is left off (it needs an embedder + vector index) — this is\n * conversation-history memory, the SQLite ask.\n */\nexport function buildSqliteMemory(\n config?: MemoryConfig,\n env: Record<string, string | undefined> = process.env,\n): MastraMemoryLike | undefined {\n if (config?.scope === \"none\") return undefined\n const dbPath = resolveMemoryDbPath(env)\n const lastMessages =\n typeof config?.retention_turns === \"number\" && config.retention_turns > 0\n ? config.retention_turns\n : 20\n return new Memory({\n storage: new LibSQLStore({ id: \"mastra-agent-memory\", url: `file:${dbPath}` }),\n options: {\n lastMessages,\n semanticRecall: false,\n workingMemory: { enabled: false },\n },\n })\n}\n","/**\n * WP1 — AIP-42 `model:` ref -> a model Mastra's `Agent` can run.\n *\n * Mastra 1.x ships a model router (`models.dev` gateway) that accepts a bare\n * `provider/model` string (e.g. `anthropic/claude-opus-4-8`,\n * `openrouter/z-ai/glm-5.2`) and resolves it to a live ai-sdk model, reading\n * the provider's key from the environment. So the resolver is a thin,\n * *validated* pass-through: extract the ref string, sanity-check the shape,\n * surface a friendly error when the obvious provider key is missing, and hand\n * the string to Mastra. No bespoke provider wiring, no extra ai-sdk deps.\n */\n\nimport type { ModelRef } from \"@agentproto/agent\"\n\n/** Best-effort provider -> env var map, used only for a friendly preflight\n * error. Mastra's gateway is the source of truth; this list just turns the\n * common \"forgot the key\" case into a clear message instead of a deep ai-sdk\n * stack trace. Providers not listed here skip the preflight check. */\nconst PROVIDER_ENV: Record<string, string> = {\n openai: \"OPENAI_API_KEY\",\n anthropic: \"ANTHROPIC_API_KEY\",\n openrouter: \"OPENROUTER_API_KEY\",\n google: \"GOOGLE_GENERATIVE_AI_API_KEY\",\n groq: \"GROQ_API_KEY\",\n xai: \"XAI_API_KEY\",\n mistral: \"MISTRAL_API_KEY\",\n deepseek: \"DEEPSEEK_API_KEY\",\n}\n\n/** Pull the model id string out of an AIP-42 `ModelRef` (string | { ref }). */\nexport function modelRefToString(ref: ModelRef): string {\n if (typeof ref === \"string\") return ref.trim()\n if (ref && typeof ref === \"object\" && typeof ref.ref === \"string\") {\n return ref.ref.trim()\n }\n throw new Error(\n \"mastra-agent: AGENT.md `model` must be a `provider/model` string \" +\n \"(or { ref }); inline model objects are not supported by this adapter.\",\n )\n}\n\n/** The provider segment is everything before the first `/`. */\nexport function providerOf(modelId: string): string {\n const slash = modelId.indexOf(\"/\")\n return slash > 0 ? modelId.slice(0, slash) : modelId\n}\n\n/**\n * Resolve an AIP-42 model ref to the value Mastra's `Agent` constructor takes.\n * Returns the `provider/model` string — Mastra routes it. `env` defaults to\n * `process.env`; injectable for tests.\n */\nexport function resolveMastraModel(\n ref: ModelRef,\n env: Record<string, string | undefined> = process.env,\n): string {\n const modelId = modelRefToString(ref)\n if (!modelId) {\n throw new Error(\"mastra-agent: empty `model` ref.\")\n }\n const provider = providerOf(modelId)\n const envKey = PROVIDER_ENV[provider]\n if (envKey && !env[envKey]) {\n throw new Error(\n `mastra-agent: model '${modelId}' needs ${envKey} in the environment ` +\n `(provider '${provider}'). Set it on the spawn env or export it.`,\n )\n }\n return modelId\n}\n","/**\n * Workspace toolset — gives the Mastra agent the ability to inspect, edit, and\n * run commands inside its session working directory, like a coding agent.\n *\n * SAFETY: every file path is resolved against the session `cwd` and rejected if\n * it escapes (no `../` traversal, no absolute paths outside cwd). Command\n * execution runs with `cwd` and a timeout, and is gated by `allowExec` (the CLI\n * sets it from `AGENTPROTO_MASTRA_NO_EXEC`). The agent only ever touches the\n * directory the daemon spawned it in.\n */\n\nimport { exec } from \"node:child_process\"\nimport { promises as fs } from \"node:fs\"\nimport { isAbsolute, relative, resolve, sep } from \"node:path\"\nimport { promisify } from \"node:util\"\nimport { createTool } from \"@mastra/core/tools\"\nimport { z } from \"zod\"\n\nconst execAsync = promisify(exec)\n\n/** A Mastra tool (structural — avoids coupling to a @mastra/core type name). */\nexport interface WorkspaceTool {\n id: string\n}\n\nexport interface WorkspaceToolsOptions {\n /** Absolute path the agent is confined to (the spawn cwd). */\n cwd: string\n /** When false, `run_command` is omitted from the toolset. Default true. */\n allowExec?: boolean\n /** Per-command timeout (ms). Default 120_000. */\n execTimeoutMs?: number\n}\n\n/** Resolve `p` against `cwd`, throwing if the result escapes the workspace. */\nexport function resolveInCwd(cwd: string, p: string): string {\n const base = resolve(cwd)\n const target = isAbsolute(p) ? resolve(p) : resolve(base, p)\n const rel = relative(base, target)\n if (rel === \"\" ) return target // the workspace root itself\n if (rel.startsWith(\"..\") || (isAbsolute(rel) && !target.startsWith(base + sep))) {\n throw new Error(\n `path '${p}' escapes the workspace (resolved to '${target}', outside '${base}').`,\n )\n }\n return target\n}\n\n/**\n * Build the workspace toolset, all confined to `cwd`. Returns a record keyed by\n * tool id (also the AGENT.md tool ref the resolver matches).\n */\nexport function makeWorkspaceTools(\n opts: WorkspaceToolsOptions,\n): Record<string, ReturnType<typeof createTool>> {\n const cwd = resolve(opts.cwd)\n const allowExec = opts.allowExec ?? true\n const execTimeoutMs = opts.execTimeoutMs ?? 120_000\n\n const list_dir = createTool({\n id: \"list_dir\",\n description:\n \"List the entries of a directory in the workspace. Returns names with a trailing '/' for directories. Path is relative to the workspace root (default '.').\",\n inputSchema: z.object({\n path: z.string().default(\".\").describe(\"Directory path, relative to the workspace root.\"),\n }),\n outputSchema: z.object({ entries: z.array(z.string()) }),\n execute: async (input: { path?: string }) => {\n const dir = resolveInCwd(cwd, input.path ?? \".\")\n const dirents = await fs.readdir(dir, { withFileTypes: true })\n return {\n entries: dirents.map((d) => (d.isDirectory() ? `${d.name}/` : d.name)).sort(),\n }\n },\n })\n\n const read_file = createTool({\n id: \"read_file\",\n description:\n \"Read a UTF-8 text file from the workspace. Path is relative to the workspace root.\",\n inputSchema: z.object({\n path: z.string().describe(\"File path, relative to the workspace root.\"),\n }),\n outputSchema: z.object({ content: z.string() }),\n execute: async (input: { path: string }) => {\n const file = resolveInCwd(cwd, input.path)\n return { content: await fs.readFile(file, \"utf8\") }\n },\n })\n\n const write_file = createTool({\n id: \"write_file\",\n description:\n \"Write (creating or overwriting) a UTF-8 text file in the workspace. Creates parent directories as needed. Path is relative to the workspace root.\",\n inputSchema: z.object({\n path: z.string().describe(\"File path, relative to the workspace root.\"),\n content: z.string().describe(\"Full file contents to write.\"),\n }),\n outputSchema: z.object({ path: z.string(), bytes: z.number() }),\n execute: async (input: { path: string; content: string }) => {\n const file = resolveInCwd(cwd, input.path)\n await fs.mkdir(resolve(file, \"..\"), { recursive: true })\n await fs.writeFile(file, input.content, \"utf8\")\n return { path: input.path, bytes: Buffer.byteLength(input.content, \"utf8\") }\n },\n })\n\n const edit_file = createTool({\n id: \"edit_file\",\n description:\n \"Replace an exact substring in a workspace file. `old_string` must occur exactly once. Use for targeted edits instead of rewriting the whole file.\",\n inputSchema: z.object({\n path: z.string().describe(\"File path, relative to the workspace root.\"),\n old_string: z.string().describe(\"Exact text to replace (must be unique in the file).\"),\n new_string: z.string().describe(\"Replacement text.\"),\n }),\n outputSchema: z.object({ path: z.string(), replaced: z.boolean() }),\n execute: async (input: { path: string; old_string: string; new_string: string }) => {\n const file = resolveInCwd(cwd, input.path)\n const current = await fs.readFile(file, \"utf8\")\n const count = current.split(input.old_string).length - 1\n if (count === 0) throw new Error(`old_string not found in '${input.path}'.`)\n if (count > 1) {\n throw new Error(`old_string occurs ${count}× in '${input.path}' — make it unique.`)\n }\n await fs.writeFile(file, current.replace(input.old_string, input.new_string), \"utf8\")\n return { path: input.path, replaced: true }\n },\n })\n\n const tools: Record<string, ReturnType<typeof createTool>> = {\n list_dir,\n read_file,\n write_file,\n edit_file,\n }\n\n if (allowExec) {\n tools.run_command = createTool({\n id: \"run_command\",\n description:\n \"Run a shell command in the workspace directory and return its stdout/stderr/exit code. Runs with a timeout; use for builds, tests, git, etc.\",\n inputSchema: z.object({\n command: z.string().describe(\"The shell command to run (executed in the workspace root).\"),\n }),\n outputSchema: z.object({\n stdout: z.string(),\n stderr: z.string(),\n exitCode: z.number(),\n }),\n execute: async (input: { command: string }) => {\n try {\n const { stdout, stderr } = await execAsync(input.command, {\n cwd,\n timeout: execTimeoutMs,\n maxBuffer: 10 * 1024 * 1024,\n })\n return { stdout, stderr, exitCode: 0 }\n } catch (err) {\n const e = err as { stdout?: string; stderr?: string; code?: number; message?: string }\n return {\n stdout: e.stdout ?? \"\",\n stderr: e.stderr ?? e.message ?? String(err),\n exitCode: typeof e.code === \"number\" ? e.code : 1,\n }\n }\n },\n })\n }\n\n return tools\n}\n","/**\n * Builds a runnable Mastra agent from an AIP-42 AGENT.md — either a caller's\n * file or a zero-config built-in default — wiring the model, the markdown body\n * as instructions, the SQLite memory, and the workspace toolset.\n */\n\nimport { readFile } from \"node:fs/promises\"\nimport { agentFromManifest, parseAgentManifest } from \"@agentproto/agent\"\nimport { buildMastraAgent } from \"@agentproto/mastra\"\nimport type { MastraLike } from \"./acp-host.js\"\nimport { buildSqliteMemory } from \"./memory.js\"\nimport { resolveMastraModel } from \"./model-resolver.js\"\nimport { makeWorkspaceTools } from \"./workspace-tools.js\"\n\n/** Cheap OpenRouter coder by default — this is the budget first-party arm,\n * same rationale as the hermes default. Override with --model / env. */\nexport const DEFAULT_MODEL = \"openrouter/z-ai/glm-5.2\"\n\n/** Tool ids the built-in default agent is granted (the workspace toolset). */\nexport const DEFAULT_TOOL_IDS = [\n \"list_dir\",\n \"read_file\",\n \"write_file\",\n \"edit_file\",\n \"run_command\",\n] as const\n\nexport interface AgentSourceOptions {\n /** Path to an AGENT.md. When omitted, the built-in default agent is used. */\n agentFile?: string\n /** Model id for the default agent (ignored when agentFile carries a model). */\n model?: string\n /** Workspace dir the tools are confined to. Defaults to `process.cwd()`. */\n cwd?: string\n /** When false, the `run_command` tool is withheld. Default true. */\n allowExec?: boolean\n}\n\n/** The built-in AGENT.md used when no file is supplied. */\nexport function defaultAgentManifest(model: string): string {\n return [\n \"---\",\n \"schema: agent/v1\",\n \"id: mastra-agent\",\n \"description: A first-party agentproto agent powered by Mastra.\",\n `model: ${model}`,\n \"version: 0.1.0\",\n \"tools:\",\n ...DEFAULT_TOOL_IDS.map((id) => ` - ${id}`),\n \"memory:\",\n \" scope: per-conversation\",\n \" retention_turns: 20\",\n \"---\",\n \"\",\n \"You are a capable, concise coding agent operating inside a workspace \",\n \"directory. You can list, read, write, and edit files and run shell \",\n \"commands there using your tools. Do exactly what the user asks — when \",\n \"asked to reply with an exact string, reply with only that string.\",\n \"\",\n ].join(\"\\n\")\n}\n\n/** Pull the id string out of an AIP-42 tool ref (string | { ref }). */\nfunction toolRefId(ref: unknown): string | undefined {\n if (typeof ref === \"string\") return ref\n if (ref && typeof ref === \"object\" && typeof (ref as { ref?: unknown }).ref === \"string\") {\n return (ref as { ref: string }).ref\n }\n return undefined\n}\n\n/** Resolve the AGENT.md source for these options (file or built-in default). */\nexport async function resolveAgentSource(\n opts: AgentSourceOptions = {},\n): Promise<string> {\n if (opts.agentFile) return readFile(opts.agentFile, \"utf8\")\n return defaultAgentManifest(opts.model ?? DEFAULT_MODEL)\n}\n\n/**\n * A lazy factory: parses the AGENT.md, builds the Mastra agent with the model\n * resolver, SQLite memory, the markdown body as instructions, and the\n * workspace toolset (matched by tool id), then returns it as the structural\n * `MastraLike` the ACP host needs.\n */\nexport function makeAgentFactory(\n opts: AgentSourceOptions = {},\n): () => Promise<MastraLike> {\n return async () => {\n const source = await resolveAgentSource(opts)\n const { frontmatter, body } = parseAgentManifest(source)\n const handle = agentFromManifest({ frontmatter, body })\n\n const cwd = opts.cwd ?? process.cwd()\n const workspaceTools = makeWorkspaceTools({ cwd, allowExec: opts.allowExec })\n\n const { agent } = await buildMastraAgent(handle, {\n resolveModel: (ref) => resolveMastraModel(ref),\n // Match each declared tool ref against the workspace toolset by id.\n resolveTool: (ref) => {\n const id = toolRefId(ref)\n const tool = id ? workspaceTools[id] : undefined\n return tool ? { name: id as string, tool } : undefined\n },\n buildMemory: (config) => buildSqliteMemory(config),\n // The markdown body is the agent's primary system prompt (AIP-42).\n body,\n })\n return agent as unknown as MastraLike\n }\n}\n","/**\n * Pure mapping from Mastra `fullStream` chunks to AIP-44 ACP `session/update`\n * payloads. Kept dependency-light (no SDK import beyond types) and side-effect\n * free so it is straightforward to unit-test; the ACP host (acp-host.ts) owns\n * the wire/IO and just forwards whatever this returns.\n *\n * Mastra emits a typed chunk union on `agent.stream(...).fullStream`. We care\n * about three kinds:\n * - `text-delta` → ACP `agent_message_chunk` (assistant prose)\n * - `tool-call` → ACP `tool_call` (a tool started, status in_progress)\n * - `tool-result` → ACP `tool_call_update` (that tool finished/failed)\n * Everything else (reasoning, step boundaries, finish, …) is not surfaced.\n */\n\nimport type { SessionUpdate, ToolKind } from \"@agentclientprotocol/sdk\"\n\n/** The narrow slice of a Mastra fullStream chunk we read. Typed structurally\n * so we don't couple to a specific @mastra/core version.\n * Mastra 1.45 wraps all chunk data in a `payload` field. */\nexport type MastraStreamChunk =\n | { type: \"text-delta\"; payload?: { text?: string } }\n | { type: \"tool-call\"; payload?: { toolCallId?: string; toolName?: string; args?: unknown } }\n | { type: \"tool-result\"; payload?: { toolCallId?: string; result?: unknown; isError?: boolean } }\n\n/** Map a workspace tool id to the ACP {@link ToolKind} that drives client\n * icon/UI treatment. Unknown ids fall back to \"other\". */\nexport function toolKindFor(toolName: string): ToolKind {\n switch (toolName) {\n case \"read_file\":\n case \"list_dir\":\n return \"read\"\n case \"write_file\":\n case \"edit_file\":\n return \"edit\"\n case \"run_command\":\n return \"execute\"\n default:\n return \"other\"\n }\n}\n\n/** A short, human-readable title for a tool call, e.g. `run_command: ls -la`\n * or `read_file: src/index.ts`. Falls back to the bare tool name. */\nexport function toolCallTitle(toolName: string, args: unknown): string {\n if (args && typeof args === \"object\") {\n const { command, path, file } = args as Record<string, unknown>\n const hint =\n (typeof command === \"string\" && command) ||\n (typeof path === \"string\" && path) ||\n (typeof file === \"string\" && file) ||\n \"\"\n if (hint) return `${toolName}: ${hint}`\n }\n return toolName\n}\n\n/**\n * Translate one Mastra chunk into an ACP `session/update` payload, or `null`\n * when the chunk has no ACP surface (or is missing the ids we need). The ACP\n * host wraps the result with the `sessionId`.\n */\nexport function chunkToSessionUpdate(\n chunk: MastraStreamChunk,\n): SessionUpdate | null {\n switch (chunk.type) {\n case \"text-delta\": {\n const text = chunk.payload?.text\n if (!text) return null\n return {\n sessionUpdate: \"agent_message_chunk\",\n content: { type: \"text\", text },\n }\n }\n case \"tool-call\": {\n const toolCallId = chunk.payload?.toolCallId\n if (!toolCallId) return null\n const toolName = chunk.payload?.toolName ?? \"tool\"\n const args = chunk.payload?.args\n return {\n sessionUpdate: \"tool_call\",\n toolCallId,\n title: toolCallTitle(toolName, args),\n kind: toolKindFor(toolName),\n status: \"in_progress\",\n rawInput: args,\n }\n }\n case \"tool-result\": {\n const toolCallId = chunk.payload?.toolCallId\n if (!toolCallId) return null\n return {\n sessionUpdate: \"tool_call_update\",\n toolCallId,\n status: chunk.payload?.isError ? \"failed\" : \"completed\",\n rawOutput: chunk.payload?.result,\n }\n }\n default:\n return null\n }\n}\n","/**\n * WP2 — the agent side of AIP-44 ACP, backed by a live Mastra agent.\n *\n * Implements the `@agentclientprotocol/sdk` `Agent` interface: handles the\n * session lifecycle and, on `session/prompt`, drives a Mastra agent's\n * `stream()` — relaying each text delta as an `agent_message_chunk`\n * `session/update`, exactly as an IDE/host expects from codex or claude-code.\n *\n * No Mastra-specific protocol knowledge leaks past this file; everything above\n * is the standard ACP wire, so the daemon spawns this like any other arm.\n */\n\nimport type {\n AgentSideConnection,\n Agent as AcpAgent,\n AuthenticateRequest,\n CancelNotification,\n InitializeRequest,\n InitializeResponse,\n NewSessionRequest,\n NewSessionResponse,\n PromptRequest,\n PromptResponse,\n SetSessionConfigOptionRequest,\n SetSessionConfigOptionResponse,\n SetSessionModeRequest,\n} from \"@agentclientprotocol/sdk\"\nimport { PROTOCOL_VERSION } from \"@agentclientprotocol/sdk\"\nimport { type MastraStreamChunk, chunkToSessionUpdate } from \"./tool-call-map.js\"\n\n/** A built Mastra agent — only the surface we need (its `stream`). Typed\n * structurally so we don't couple to a specific @mastra/core version.\n *\n * We read `fullStream` (the typed chunk union: text deltas AND tool-call /\n * tool-result events) so tool activity surfaces as ACP `tool_call` updates,\n * not only the final prose. `textStream` is kept as an optional fallback for\n * a stripped agent that exposes only text. */\nexport interface MastraLike {\n stream(\n input: string,\n options?: {\n abortSignal?: AbortSignal\n /** Memory threading — `thread` scopes recall to one ACP session. */\n memory?: { thread?: string; resource?: string }\n /** Max agentic loop steps (tool-call → execute → continue). Default 1 = no loop. */\n maxSteps?: number\n },\n ): Promise<{\n fullStream?: ReadableStream<unknown>\n textStream?: ReadableStream<string>\n text?: Promise<string>\n }>\n}\n\n/** Lazily builds the Mastra agent (so model/key errors surface on the first\n * prompt with a clear message, not at process spawn). */\nexport type AgentFactory = () => Promise<MastraLike>\n\ninterface SessionState {\n prompt: AbortController | null\n}\n\n/** Pull the user's text out of an ACP prompt (its `text` content blocks). */\nexport function promptText(params: PromptRequest): string {\n const blocks = Array.isArray(params.prompt) ? params.prompt : []\n return blocks\n .filter((b): b is { type: \"text\"; text: string } =>\n Boolean(b) && (b as { type?: string }).type === \"text\" &&\n typeof (b as { text?: unknown }).text === \"string\",\n )\n .map((b) => b.text)\n .join(\"\")\n .trim()\n}\n\nexport class MastraAcpAgent implements AcpAgent {\n readonly #conn: AgentSideConnection\n readonly #buildAgent: AgentFactory\n readonly #resource: string\n readonly #sessions = new Map<string, SessionState>()\n #agent: MastraLike | null = null\n\n constructor(\n conn: AgentSideConnection,\n buildAgent: AgentFactory,\n resource = \"mastra-agent\",\n ) {\n this.#conn = conn\n this.#buildAgent = buildAgent\n // `resource` groups a user's threads in Mastra memory; one per agent here.\n this.#resource = resource\n }\n\n async initialize(_params: InitializeRequest): Promise<InitializeResponse> {\n return {\n protocolVersion: PROTOCOL_VERSION,\n agentCapabilities: {\n // Stateless per-prompt for now; no resume/replay surface.\n loadSession: false,\n },\n }\n }\n\n async authenticate(\n _params: AuthenticateRequest,\n ): Promise<Record<string, never>> {\n // The provider key is read from the spawn env by the model gateway — no\n // ACP-level auth handshake needed.\n return {}\n }\n\n async newSession(_params: NewSessionRequest): Promise<NewSessionResponse> {\n const sessionId = randomId()\n this.#sessions.set(sessionId, { prompt: null })\n return { sessionId }\n }\n\n async prompt(params: PromptRequest): Promise<PromptResponse> {\n const session = this.#sessions.get(params.sessionId)\n if (!session) throw new Error(`unknown session ${params.sessionId}`)\n\n // Cancel any in-flight turn for this session before starting a new one.\n session.prompt?.abort()\n const ac = new AbortController()\n session.prompt = ac\n\n const text = promptText(params)\n try {\n const agent = await this.#ensureAgent()\n // Thread = ACP session id → recall is scoped to this session's history.\n const result = await agent.stream(text, {\n abortSignal: ac.signal,\n memory: { thread: params.sessionId, resource: this.#resource },\n maxSteps: 200,\n })\n if (result.fullStream) {\n // Preferred path: the typed chunk stream carries text deltas AND\n // tool-call / tool-result events, so tool activity surfaces live.\n await this.#pumpFullStream(params.sessionId, result.fullStream, ac)\n } else if (result.textStream) {\n // Fallback: a text-only agent — relay prose deltas, no tool surface.\n await this.#pumpTextStream(params.sessionId, result.textStream, ac)\n }\n } catch (err) {\n if (ac.signal.aborted) return { stopReason: \"cancelled\" }\n // Surface the failure to the client as a message chunk, then end the\n // turn — better UX than a bare JSON-RPC error the host may swallow.\n await this.#conn.sessionUpdate({\n sessionId: params.sessionId,\n update: {\n sessionUpdate: \"agent_message_chunk\",\n content: {\n type: \"text\",\n text: `\\n[mastra-agent error] ${(err as Error).message}\\n`,\n },\n },\n })\n session.prompt = null\n return { stopReason: \"refusal\" }\n }\n\n const cancelled = ac.signal.aborted\n session.prompt = null\n return { stopReason: cancelled ? \"cancelled\" : \"end_turn\" }\n }\n\n async cancel(params: CancelNotification): Promise<void> {\n this.#sessions.get(params.sessionId)?.prompt?.abort()\n }\n\n /**\n * The host applies the `model` (and other operator options) as a `--model`\n * spawn arg via the manifest `bin_args_template`, then ALSO calls this ACP\n * config hook (the daemon's default \"config\" apply path). The model is\n * already in effect, so this is a no-op that just reports our (empty) set of\n * runtime-configurable options. Without it the spawn fails with\n * \"Method not found: session/set_config_option\".\n */\n async setSessionConfigOption(\n _params: SetSessionConfigOptionRequest,\n ): Promise<SetSessionConfigOptionResponse> {\n return { configOptions: [] }\n }\n\n /** No agent-specific modes; accept and ignore so a host that sets one\n * doesn't error. */\n async setSessionMode(\n _params: SetSessionModeRequest,\n ): Promise<Record<string, never>> {\n return {}\n }\n\n /** Drain Mastra's typed `fullStream`, mapping each chunk to an ACP\n * `session/update` (text deltas + tool_call / tool_call_update). */\n async #pumpFullStream(\n sessionId: string,\n stream: ReadableStream<unknown>,\n ac: AbortController,\n ): Promise<void> {\n const reader = stream.getReader()\n try {\n for (;;) {\n const { value, done } = await reader.read()\n if (done || ac.signal.aborted) break\n if (!value) continue\n // Single boundary cast: raw Mastra chunks include many event types\n // beyond what MastraStreamChunk models; chunkToSessionUpdate returns\n // null for anything it doesn't recognise.\n const update = chunkToSessionUpdate(value as MastraStreamChunk)\n if (update) await this.#conn.sessionUpdate({ sessionId, update })\n }\n } finally {\n reader.releaseLock()\n }\n }\n\n /** Fallback drain for an agent exposing only a plain text stream. */\n async #pumpTextStream(\n sessionId: string,\n stream: ReadableStream<string>,\n ac: AbortController,\n ): Promise<void> {\n const reader = stream.getReader()\n try {\n for (;;) {\n const { value, done } = await reader.read()\n if (done || ac.signal.aborted) break\n if (value) {\n await this.#conn.sessionUpdate({\n sessionId,\n update: {\n sessionUpdate: \"agent_message_chunk\",\n content: { type: \"text\", text: value },\n },\n })\n }\n }\n } finally {\n reader.releaseLock()\n }\n }\n\n async #ensureAgent(): Promise<MastraLike> {\n if (!this.#agent) this.#agent = await this.#buildAgent()\n return this.#agent\n }\n}\n\n/** 16 random bytes as hex — matches the SDK example's session id shape. */\nfunction randomId(): string {\n const bytes = new Uint8Array(16)\n crypto.getRandomValues(bytes)\n return Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\")\n}\n","/**\n * Boots the ACP server over stdio — the standard wiring for a spawned ACP\n * agent (mirrors the @agentclientprotocol/sdk agent example): the agent writes\n * JSON-RPC to stdout and reads from stdin.\n */\n\nimport { Readable, Writable } from \"node:stream\"\nimport { AgentSideConnection, ndJsonStream } from \"@agentclientprotocol/sdk\"\nimport { MastraAcpAgent, type AgentFactory } from \"./acp-host.js\"\n\nexport function runAcpOverStdio(buildAgent: AgentFactory): AgentSideConnection {\n // ndJsonStream(writable, readable): outgoing bytes -> stdout, incoming <- stdin.\n const toClient = Writable.toWeb(process.stdout) as WritableStream<Uint8Array>\n const fromClient = Readable.toWeb(\n process.stdin,\n ) as unknown as ReadableStream<Uint8Array>\n const stream = ndJsonStream(toClient, fromClient)\n return new AgentSideConnection(\n (conn) => new MastraAcpAgent(conn, buildAgent),\n stream,\n )\n}\n"]}
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { runAcpOverStdio, makeAgentFactory } from './chunk-7SWAWNDG.mjs';
2
+ import { runAcpOverStdio, makeAgentFactory } from './chunk-5G4U3UGM.mjs';
3
3
 
4
4
  /**
5
5
  * @agentproto/adapter-mastra-agent v0.1.0-alpha
package/dist/index.d.ts CHANGED
@@ -1,63 +1,10 @@
1
1
  import { AgentCliHandle, AgentCliRuntime } from '@agentproto/driver-agent-cli';
2
2
  export { AgentCliHandle, AgentCliRuntime } from '@agentproto/driver-agent-cli';
3
- import { SessionUpdate, ToolKind, Agent, AgentSideConnection, InitializeRequest, InitializeResponse, AuthenticateRequest, NewSessionRequest, NewSessionResponse, PromptRequest, PromptResponse, CancelNotification, SetSessionConfigOptionRequest, SetSessionConfigOptionResponse, SetSessionModeRequest } from '@agentclientprotocol/sdk';
3
+ import { Agent, AgentSideConnection, InitializeRequest, InitializeResponse, AuthenticateRequest, NewSessionRequest, NewSessionResponse, PromptRequest, PromptResponse, CancelNotification, SetSessionConfigOptionRequest, SetSessionConfigOptionResponse, SetSessionModeRequest, SessionUpdate, ToolKind } from '@agentclientprotocol/sdk';
4
4
  import { ModelRef, MemoryConfig } from '@agentproto/agent';
5
5
  import { createTool } from '@mastra/core/tools';
6
6
  import { Memory } from '@mastra/memory';
7
7
 
8
- /**
9
- * Pure mapping from Mastra `fullStream` chunks to AIP-44 ACP `session/update`
10
- * payloads. Kept dependency-light (no SDK import beyond types) and side-effect
11
- * free so it is straightforward to unit-test; the ACP host (acp-host.ts) owns
12
- * the wire/IO and just forwards whatever this returns.
13
- *
14
- * Mastra emits a typed chunk union on `agent.stream(...).fullStream`. We care
15
- * about three kinds:
16
- * - `text-delta` → ACP `agent_message_chunk` (assistant prose)
17
- * - `tool-call` → ACP `tool_call` (a tool started, status in_progress)
18
- * - `tool-result` → ACP `tool_call_update` (that tool finished/failed)
19
- * Everything else (reasoning, step boundaries, finish, …) is not surfaced.
20
- */
21
-
22
- /** The narrow slice of a Mastra fullStream chunk we read. Typed structurally
23
- * so we don't couple to a specific @mastra/core version. */
24
- type MastraStreamChunk = {
25
- type: "text-delta";
26
- payload?: {
27
- text?: string;
28
- };
29
- } | {
30
- type: "tool-call";
31
- payload?: {
32
- toolCallId?: string;
33
- toolName?: string;
34
- args?: unknown;
35
- };
36
- } | {
37
- type: "tool-result";
38
- payload?: {
39
- toolCallId?: string;
40
- toolName?: string;
41
- result?: unknown;
42
- isError?: boolean;
43
- };
44
- } | {
45
- type: string;
46
- payload?: unknown;
47
- };
48
- /** Map a workspace tool id to the ACP {@link ToolKind} that drives client
49
- * icon/UI treatment. Unknown ids fall back to "other". */
50
- declare function toolKindFor(toolName: string): ToolKind;
51
- /** A short, human-readable title for a tool call, e.g. `run_command: ls -la`
52
- * or `read_file: src/index.ts`. Falls back to the bare tool name. */
53
- declare function toolCallTitle(toolName: string, args: unknown): string;
54
- /**
55
- * Translate one Mastra chunk into an ACP `session/update` payload, or `null`
56
- * when the chunk has no ACP surface (or is missing the ids we need). The ACP
57
- * host wraps the result with the `sessionId`.
58
- */
59
- declare function chunkToSessionUpdate(chunk: MastraStreamChunk): SessionUpdate | null;
60
-
61
8
  /**
62
9
  * WP2 — the agent side of AIP-44 ACP, backed by a live Mastra agent.
63
10
  *
@@ -85,8 +32,10 @@ interface MastraLike {
85
32
  thread?: string;
86
33
  resource?: string;
87
34
  };
35
+ /** Max agentic loop steps (tool-call → execute → continue). Default 1 = no loop. */
36
+ maxSteps?: number;
88
37
  }): Promise<{
89
- fullStream?: ReadableStream<MastraStreamChunk>;
38
+ fullStream?: ReadableStream<unknown>;
90
39
  textStream?: ReadableStream<string>;
91
40
  text?: Promise<string>;
92
41
  }>;
@@ -225,6 +174,56 @@ declare function resolveMemoryDbPath(env?: Record<string, string | undefined>):
225
174
  */
226
175
  declare function buildSqliteMemory(config?: MemoryConfig, env?: Record<string, string | undefined>): MastraMemoryLike | undefined;
227
176
 
177
+ /**
178
+ * Pure mapping from Mastra `fullStream` chunks to AIP-44 ACP `session/update`
179
+ * payloads. Kept dependency-light (no SDK import beyond types) and side-effect
180
+ * free so it is straightforward to unit-test; the ACP host (acp-host.ts) owns
181
+ * the wire/IO and just forwards whatever this returns.
182
+ *
183
+ * Mastra emits a typed chunk union on `agent.stream(...).fullStream`. We care
184
+ * about three kinds:
185
+ * - `text-delta` → ACP `agent_message_chunk` (assistant prose)
186
+ * - `tool-call` → ACP `tool_call` (a tool started, status in_progress)
187
+ * - `tool-result` → ACP `tool_call_update` (that tool finished/failed)
188
+ * Everything else (reasoning, step boundaries, finish, …) is not surfaced.
189
+ */
190
+
191
+ /** The narrow slice of a Mastra fullStream chunk we read. Typed structurally
192
+ * so we don't couple to a specific @mastra/core version.
193
+ * Mastra 1.45 wraps all chunk data in a `payload` field. */
194
+ type MastraStreamChunk = {
195
+ type: "text-delta";
196
+ payload?: {
197
+ text?: string;
198
+ };
199
+ } | {
200
+ type: "tool-call";
201
+ payload?: {
202
+ toolCallId?: string;
203
+ toolName?: string;
204
+ args?: unknown;
205
+ };
206
+ } | {
207
+ type: "tool-result";
208
+ payload?: {
209
+ toolCallId?: string;
210
+ result?: unknown;
211
+ isError?: boolean;
212
+ };
213
+ };
214
+ /** Map a workspace tool id to the ACP {@link ToolKind} that drives client
215
+ * icon/UI treatment. Unknown ids fall back to "other". */
216
+ declare function toolKindFor(toolName: string): ToolKind;
217
+ /** A short, human-readable title for a tool call, e.g. `run_command: ls -la`
218
+ * or `read_file: src/index.ts`. Falls back to the bare tool name. */
219
+ declare function toolCallTitle(toolName: string, args: unknown): string;
220
+ /**
221
+ * Translate one Mastra chunk into an ACP `session/update` payload, or `null`
222
+ * when the chunk has no ACP surface (or is missing the ids we need). The ACP
223
+ * host wraps the result with the `sessionId`.
224
+ */
225
+ declare function chunkToSessionUpdate(chunk: MastraStreamChunk): SessionUpdate | null;
226
+
228
227
  /**
229
228
  * Boots the ACP server over stdio — the standard wiring for a spawned ACP
230
229
  * agent (mirrors the @agentclientprotocol/sdk agent example): the agent writes
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { DEFAULT_MODEL, DEFAULT_TOOL_IDS, MastraAcpAgent, buildSqliteMemory, chunkToSessionUpdate, defaultAgentManifest, makeAgentFactory, makeWorkspaceTools, modelRefToString, promptText, providerOf, resolveInCwd, resolveMastraModel, resolveMemoryDbPath, runAcpOverStdio, toolCallTitle, toolKindFor } from './chunk-7SWAWNDG.mjs';
1
+ export { DEFAULT_MODEL, DEFAULT_TOOL_IDS, MastraAcpAgent, buildSqliteMemory, chunkToSessionUpdate, defaultAgentManifest, makeAgentFactory, makeWorkspaceTools, modelRefToString, promptText, providerOf, resolveInCwd, resolveMastraModel, resolveMemoryDbPath, runAcpOverStdio, toolCallTitle, toolKindFor } from './chunk-5G4U3UGM.mjs';
2
2
  import { fileURLToPath } from 'url';
3
3
  import { defineAgentCli, createAgentCliRuntime } from '@agentproto/driver-agent-cli';
4
4
 
@@ -47,12 +47,13 @@ var mastraAgent = defineAgentCli({
47
47
  },
48
48
  models: {
49
49
  // Cheap OpenRouter coder by default — this is the budget first-party arm.
50
+ // Anthropic models are not advertised here (this arm shouldn't be steered
51
+ // onto premium Anthropic spend); the free-form `model` option still
52
+ // accepts any Mastra-routable id.
50
53
  default: "openrouter/z-ai/glm-5.2",
51
54
  allowed: [
52
55
  "openrouter/z-ai/glm-5.2",
53
56
  "openrouter/deepseek/deepseek-v4-pro",
54
- "anthropic/claude-opus-4-8",
55
- "anthropic/claude-sonnet-4-6",
56
57
  "openai/gpt-5"
57
58
  ],
58
59
  env: {
@@ -80,7 +81,7 @@ var mastraAgent = defineAgentCli({
80
81
  // string (not enum) so any Mastra-routable `provider/model` id works
81
82
  // without a code change. Applied as a `--model <id>` spawn arg.
82
83
  type: "string",
83
- description: "Model id routed via Mastra's model gateway (e.g. 'anthropic/claude-opus-4-8', 'openrouter/z-ai/glm-5.2'). Applied as a `--model` arg at spawn. Omit for the default.",
84
+ description: "Model id routed via Mastra's model gateway (e.g. 'openrouter/z-ai/glm-5.2', 'openrouter/deepseek/deepseek-v4-pro'). Applied as a `--model` arg at spawn. Omit for the default.",
84
85
  bin_args_template: ["--model", "{value}"]
85
86
  }
86
87
  ],
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;AAwBA,IAAM,WAAW,aAAA,CAAc,IAAI,IAAI,WAAA,EAAa,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA;AAE7D,IAAM,cAA8B,cAAA,CAAe;AAAA,EACxD,IAAA,EAAM,cAAA;AAAA,EACN,EAAA,EAAI,cAAA;AAAA,EACJ,WAAA,EACE,mUAAA;AAAA,EACF,OAAA,EAAS,OAAA;AAAA,EACT,GAAA,EAAK,MAAA;AAAA,EACL,QAAA,EAAU,CAAC,QAAA,EAAU,KAAK,CAAA;AAAA,EAC1B,OAAA,EAAS;AAAA,IACP;AAAA,MACE,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS,kCAAA;AAAA,MACT,MAAA,EAAQ;AAAA;AACV,GACF;AAAA;AAAA;AAAA,EAGA,aAAA,EAAe;AAAA,IACb,GAAA,EAAK,gBAAA;AAAA,IACL,KAAA,EAAO,sBAAA;AAAA,IACP,KAAA,EAAO,UAAA;AAAA,IACP,UAAA,EAAY;AAAA,GACd;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK,uBAAA;AAAA;AAAA;AAAA,IAGL,KAAA,EAAO;AAAA,MACL,GAAA,EAAK,CAAC,oBAAA,EAAsB,mBAAA,EAAqB,gBAAgB;AAAA;AACnE,GACF;AAAA,EACA,OAAA,EACE,2IAAA;AAAA,EACF,QAAA,EAAU,KAAA;AAAA,EACV,GAAA,EAAK,uBAAA;AAAA,EACL,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,YAAA;AAAA,IACN,eAAA,EAAiB,IAAA;AAAA,IACjB,iBAAA,EAAmB;AAAA,GACrB;AAAA,EACA,MAAA,EAAQ;AAAA;AAAA,IAEN,OAAA,EAAS,yBAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,yBAAA;AAAA,MACA,qCAAA;AAAA,MACA,2BAAA;AAAA,MACA,6BAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,GAAA,EAAK;AAAA,MACH,SAAA,EAAW,mBAAA;AAAA,MACX,UAAA,EAAY,oBAAA;AAAA,MACZ,MAAA,EAAQ;AAAA;AACV,GACF;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,SAAA,EAAW,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAKX,UAAA,EAAY,IAAA;AAAA,IACZ,UAAA,EAAY,KAAA;AAAA,IACZ,OAAA,EAAS,KAAA;AAAA,IACT,UAAA,EAAY,KAAA;AAAA,IACZ,SAAA,EAAW,KAAA;AAAA,IACX,aAAA,EAAe;AAAA,GACjB;AAAA,EACA,OAAA,EAAS;AAAA,IACP;AAAA,MACE,EAAA,EAAI,OAAA;AAAA;AAAA;AAAA,MAGJ,IAAA,EAAM,QAAA;AAAA,MACN,WAAA,EACE,sKAAA;AAAA,MAGF,iBAAA,EAAmB,CAAC,SAAA,EAAW,SAAS;AAAA;AAC1C,GACF;AAAA,EACA,MAAM,CAAC,QAAA,EAAU,YAAA,EAAc,KAAA,EAAO,iBAAiB,aAAa;AACtE,CAAC;AAEM,SAAS,kBAAA,GAAsC;AACpD,EAAA,OAAO,sBAAsB,WAAW,CAAA;AAC1C","file":"index.mjs","sourcesContent":["/**\n * @agentproto/adapter-mastra-agent — the first-party agentproto agent.\n *\n * Unlike the codex/hermes/claude-code adapters (which wrap an external agent\n * CLI), this adapter IS the agent: an AIP-42 AGENT.md is run as a live Mastra\n * agent behind an AIP-44 ACP server (see ./acp-host.ts), shipped as a CLI bin\n * (`agentproto-mastra acp`). The daemon spawns it like any other arm; a user\n * can launch it standalone. Our loop, our models — no external CLI.\n *\n * import { mastraAgent, mastraAgentRuntime } from \"@agentproto/adapter-mastra-agent\"\n */\n\nimport { fileURLToPath } from \"node:url\"\nimport {\n createAgentCliRuntime,\n defineAgentCli,\n type AgentCliHandle,\n type AgentCliRuntime,\n} from \"@agentproto/driver-agent-cli\"\n\n// Self-locating: the built handle spawns `node <this-dist>/cli.mjs acp`.\n// import.meta.url resolves into dist/ at runtime, where cli.mjs sits next to\n// index.mjs — so the same build works whether the daemon spawns it (resolved\n// from node_modules) or a user runs the published bin.\nconst cliEntry = fileURLToPath(new URL(\"./cli.mjs\", import.meta.url))\n\nexport const mastraAgent: AgentCliHandle = defineAgentCli({\n name: \"mastra-agent\",\n id: \"mastra-agent\",\n description:\n \"First-party agentproto agent — an AIP-42 AGENT.md run as a live Mastra agent behind an AIP-44 ACP server. No external agent CLI: our own loop, our own models (routed via Mastra's model gateway from the spawn env). Spawned as `node cli.mjs acp` over stdio JSON-RPC, or launched standalone via `agentproto-mastra acp`.\",\n version: \"0.1.0\",\n bin: \"node\",\n bin_args: [cliEntry, \"acp\"],\n install: [\n {\n method: \"npm\",\n package: \"@agentproto/adapter-mastra-agent\",\n global: true,\n },\n ],\n // No external runtime to probe — the agent runs in the spawned node process.\n // A node version gate is enough to mark the arm ready.\n version_check: {\n cmd: \"node --version\",\n parse: \"(\\\\d+\\\\.\\\\d+\\\\.\\\\d+)\",\n range: \">=20.9.0\",\n timeout_ms: 5000,\n },\n auth: {\n ref: \"./mastra-agent.ACP.md\",\n // The chosen model's provider key is read from the spawn env by Mastra's\n // model gateway. Any one of these covers the common providers.\n state: {\n env: [\"OPENROUTER_API_KEY\", \"ANTHROPIC_API_KEY\", \"OPENAI_API_KEY\"],\n },\n },\n sandbox:\n \"In-process: the agent runs inside the spawned node process. Tool-level sandboxing is the responsibility of the tools the AGENT.md grants.\",\n protocol: \"acp\",\n acp: \"./mastra-agent.ACP.md\",\n session: {\n mode: \"persistent\",\n idle_timeout_ms: 1_800_000,\n context_carryover: true,\n },\n models: {\n // Cheap OpenRouter coder by default — this is the budget first-party arm.\n default: \"openrouter/z-ai/glm-5.2\",\n allowed: [\n \"openrouter/z-ai/glm-5.2\",\n \"openrouter/deepseek/deepseek-v4-pro\",\n \"anthropic/claude-opus-4-8\",\n \"anthropic/claude-sonnet-4-6\",\n \"openai/gpt-5\",\n ],\n env: {\n anthropic: \"ANTHROPIC_API_KEY\",\n openrouter: \"OPENROUTER_API_KEY\",\n openai: \"OPENAI_API_KEY\",\n },\n },\n capabilities: {\n streaming: true,\n // Tool calls run inside Mastra and are relayed to the host as ACP\n // tool_call / tool_call_update session updates (see acp-host.ts +\n // tool-call-map.ts). The built-in default agent ships the workspace\n // toolset (read/edit/run), so this is on.\n tool_calls: true,\n sub_agents: false,\n file_io: false,\n multimodal: false,\n resumable: false,\n bidirectional: true,\n },\n options: [\n {\n id: \"model\",\n // string (not enum) so any Mastra-routable `provider/model` id works\n // without a code change. Applied as a `--model <id>` spawn arg.\n type: \"string\" as const,\n description:\n \"Model id routed via Mastra's model gateway (e.g. \" +\n \"'anthropic/claude-opus-4-8', 'openrouter/z-ai/glm-5.2'). \" +\n \"Applied as a `--model` arg at spawn. Omit for the default.\",\n bin_args_template: [\"--model\", \"{value}\"],\n },\n ],\n tags: [\"mastra\", \"agentproto\", \"acp\", \"agent-runtime\", \"first-party\"],\n})\n\nexport function mastraAgentRuntime(): AgentCliRuntime {\n return createAgentCliRuntime(mastraAgent)\n}\n\nexport {\n makeAgentFactory,\n defaultAgentManifest,\n DEFAULT_MODEL,\n DEFAULT_TOOL_IDS,\n} from \"./default-agent.js\"\nexport { MastraAcpAgent, promptText, type MastraLike } from \"./acp-host.js\"\nexport { resolveMastraModel, modelRefToString, providerOf } from \"./model-resolver.js\"\nexport { makeWorkspaceTools, resolveInCwd } from \"./workspace-tools.js\"\nexport { buildSqliteMemory, resolveMemoryDbPath } from \"./memory.js\"\nexport {\n chunkToSessionUpdate,\n toolKindFor,\n toolCallTitle,\n type MastraStreamChunk,\n} from \"./tool-call-map.js\"\nexport { runAcpOverStdio } from \"./run.js\"\nexport type { AgentCliHandle, AgentCliRuntime }\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;AAwBA,IAAM,WAAW,aAAA,CAAc,IAAI,IAAI,WAAA,EAAa,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA;AAE7D,IAAM,cAA8B,cAAA,CAAe;AAAA,EACxD,IAAA,EAAM,cAAA;AAAA,EACN,EAAA,EAAI,cAAA;AAAA,EACJ,WAAA,EACE,mUAAA;AAAA,EACF,OAAA,EAAS,OAAA;AAAA,EACT,GAAA,EAAK,MAAA;AAAA,EACL,QAAA,EAAU,CAAC,QAAA,EAAU,KAAK,CAAA;AAAA,EAC1B,OAAA,EAAS;AAAA,IACP;AAAA,MACE,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS,kCAAA;AAAA,MACT,MAAA,EAAQ;AAAA;AACV,GACF;AAAA;AAAA;AAAA,EAGA,aAAA,EAAe;AAAA,IACb,GAAA,EAAK,gBAAA;AAAA,IACL,KAAA,EAAO,sBAAA;AAAA,IACP,KAAA,EAAO,UAAA;AAAA,IACP,UAAA,EAAY;AAAA,GACd;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK,uBAAA;AAAA;AAAA;AAAA,IAGL,KAAA,EAAO;AAAA,MACL,GAAA,EAAK,CAAC,oBAAA,EAAsB,mBAAA,EAAqB,gBAAgB;AAAA;AACnE,GACF;AAAA,EACA,OAAA,EACE,2IAAA;AAAA,EACF,QAAA,EAAU,KAAA;AAAA,EACV,GAAA,EAAK,uBAAA;AAAA,EACL,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,YAAA;AAAA,IACN,eAAA,EAAiB,IAAA;AAAA,IACjB,iBAAA,EAAmB;AAAA,GACrB;AAAA,EACA,MAAA,EAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,IAKN,OAAA,EAAS,yBAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,yBAAA;AAAA,MACA,qCAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,GAAA,EAAK;AAAA,MACH,SAAA,EAAW,mBAAA;AAAA,MACX,UAAA,EAAY,oBAAA;AAAA,MACZ,MAAA,EAAQ;AAAA;AACV,GACF;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,SAAA,EAAW,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAKX,UAAA,EAAY,IAAA;AAAA,IACZ,UAAA,EAAY,KAAA;AAAA,IACZ,OAAA,EAAS,KAAA;AAAA,IACT,UAAA,EAAY,KAAA;AAAA,IACZ,SAAA,EAAW,KAAA;AAAA,IACX,aAAA,EAAe;AAAA,GACjB;AAAA,EACA,OAAA,EAAS;AAAA,IACP;AAAA,MACE,EAAA,EAAI,OAAA;AAAA;AAAA;AAAA,MAGJ,IAAA,EAAM,QAAA;AAAA,MACN,WAAA,EACE,gLAAA;AAAA,MAGF,iBAAA,EAAmB,CAAC,SAAA,EAAW,SAAS;AAAA;AAC1C,GACF;AAAA,EACA,MAAM,CAAC,QAAA,EAAU,YAAA,EAAc,KAAA,EAAO,iBAAiB,aAAa;AACtE,CAAC;AAEM,SAAS,kBAAA,GAAsC;AACpD,EAAA,OAAO,sBAAsB,WAAW,CAAA;AAC1C","file":"index.mjs","sourcesContent":["/**\n * @agentproto/adapter-mastra-agent — the first-party agentproto agent.\n *\n * Unlike the codex/hermes/claude-code adapters (which wrap an external agent\n * CLI), this adapter IS the agent: an AIP-42 AGENT.md is run as a live Mastra\n * agent behind an AIP-44 ACP server (see ./acp-host.ts), shipped as a CLI bin\n * (`agentproto-mastra acp`). The daemon spawns it like any other arm; a user\n * can launch it standalone. Our loop, our models — no external CLI.\n *\n * import { mastraAgent, mastraAgentRuntime } from \"@agentproto/adapter-mastra-agent\"\n */\n\nimport { fileURLToPath } from \"node:url\"\nimport {\n createAgentCliRuntime,\n defineAgentCli,\n type AgentCliHandle,\n type AgentCliRuntime,\n} from \"@agentproto/driver-agent-cli\"\n\n// Self-locating: the built handle spawns `node <this-dist>/cli.mjs acp`.\n// import.meta.url resolves into dist/ at runtime, where cli.mjs sits next to\n// index.mjs — so the same build works whether the daemon spawns it (resolved\n// from node_modules) or a user runs the published bin.\nconst cliEntry = fileURLToPath(new URL(\"./cli.mjs\", import.meta.url))\n\nexport const mastraAgent: AgentCliHandle = defineAgentCli({\n name: \"mastra-agent\",\n id: \"mastra-agent\",\n description:\n \"First-party agentproto agent — an AIP-42 AGENT.md run as a live Mastra agent behind an AIP-44 ACP server. No external agent CLI: our own loop, our own models (routed via Mastra's model gateway from the spawn env). Spawned as `node cli.mjs acp` over stdio JSON-RPC, or launched standalone via `agentproto-mastra acp`.\",\n version: \"0.1.0\",\n bin: \"node\",\n bin_args: [cliEntry, \"acp\"],\n install: [\n {\n method: \"npm\",\n package: \"@agentproto/adapter-mastra-agent\",\n global: true,\n },\n ],\n // No external runtime to probe — the agent runs in the spawned node process.\n // A node version gate is enough to mark the arm ready.\n version_check: {\n cmd: \"node --version\",\n parse: \"(\\\\d+\\\\.\\\\d+\\\\.\\\\d+)\",\n range: \">=20.9.0\",\n timeout_ms: 5000,\n },\n auth: {\n ref: \"./mastra-agent.ACP.md\",\n // The chosen model's provider key is read from the spawn env by Mastra's\n // model gateway. Any one of these covers the common providers.\n state: {\n env: [\"OPENROUTER_API_KEY\", \"ANTHROPIC_API_KEY\", \"OPENAI_API_KEY\"],\n },\n },\n sandbox:\n \"In-process: the agent runs inside the spawned node process. Tool-level sandboxing is the responsibility of the tools the AGENT.md grants.\",\n protocol: \"acp\",\n acp: \"./mastra-agent.ACP.md\",\n session: {\n mode: \"persistent\",\n idle_timeout_ms: 1_800_000,\n context_carryover: true,\n },\n models: {\n // Cheap OpenRouter coder by default — this is the budget first-party arm.\n // Anthropic models are not advertised here (this arm shouldn't be steered\n // onto premium Anthropic spend); the free-form `model` option still\n // accepts any Mastra-routable id.\n default: \"openrouter/z-ai/glm-5.2\",\n allowed: [\n \"openrouter/z-ai/glm-5.2\",\n \"openrouter/deepseek/deepseek-v4-pro\",\n \"openai/gpt-5\",\n ],\n env: {\n anthropic: \"ANTHROPIC_API_KEY\",\n openrouter: \"OPENROUTER_API_KEY\",\n openai: \"OPENAI_API_KEY\",\n },\n },\n capabilities: {\n streaming: true,\n // Tool calls run inside Mastra and are relayed to the host as ACP\n // tool_call / tool_call_update session updates (see acp-host.ts +\n // tool-call-map.ts). The built-in default agent ships the workspace\n // toolset (read/edit/run), so this is on.\n tool_calls: true,\n sub_agents: false,\n file_io: false,\n multimodal: false,\n resumable: false,\n bidirectional: true,\n },\n options: [\n {\n id: \"model\",\n // string (not enum) so any Mastra-routable `provider/model` id works\n // without a code change. Applied as a `--model <id>` spawn arg.\n type: \"string\" as const,\n description:\n \"Model id routed via Mastra's model gateway (e.g. \" +\n \"'openrouter/z-ai/glm-5.2', 'openrouter/deepseek/deepseek-v4-pro'). \" +\n \"Applied as a `--model` arg at spawn. Omit for the default.\",\n bin_args_template: [\"--model\", \"{value}\"],\n },\n ],\n tags: [\"mastra\", \"agentproto\", \"acp\", \"agent-runtime\", \"first-party\"],\n})\n\nexport function mastraAgentRuntime(): AgentCliRuntime {\n return createAgentCliRuntime(mastraAgent)\n}\n\nexport {\n makeAgentFactory,\n defaultAgentManifest,\n DEFAULT_MODEL,\n DEFAULT_TOOL_IDS,\n} from \"./default-agent.js\"\nexport { MastraAcpAgent, promptText, type MastraLike } from \"./acp-host.js\"\nexport { resolveMastraModel, modelRefToString, providerOf } from \"./model-resolver.js\"\nexport { makeWorkspaceTools, resolveInCwd } from \"./workspace-tools.js\"\nexport { buildSqliteMemory, resolveMemoryDbPath } from \"./memory.js\"\nexport {\n chunkToSessionUpdate,\n toolKindFor,\n toolCallTitle,\n type MastraStreamChunk,\n} from \"./tool-call-map.js\"\nexport { runAcpOverStdio } from \"./run.js\"\nexport type { AgentCliHandle, AgentCliRuntime }\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentproto/adapter-mastra-agent",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "@agentproto/adapter-mastra-agent — first-party agentproto agent. An AIP-42 AGENT.md run as a live Mastra agent behind an AIP-44 ACP server, spawnable by the daemon like any other AGENT-CLI arm AND launchable standalone via `agentproto-mastra acp`. Our own loop, our own models — no external CLI.",
5
5
  "keywords": [
6
6
  "agentproto",
@@ -53,8 +53,8 @@
53
53
  "@mastra/libsql": "~1.10.0",
54
54
  "zod": "^4.4.3",
55
55
  "@agentproto/agent": "0.2.0",
56
- "@agentproto/driver-agent-cli": "0.2.0",
57
- "@agentproto/mastra": "0.2.0"
56
+ "@agentproto/driver-agent-cli": "0.4.0",
57
+ "@agentproto/mastra": "0.2.1"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@types/node": "^25.6.2",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/memory.ts","../src/model-resolver.ts","../src/workspace-tools.ts","../src/default-agent.ts","../src/tool-call-map.ts","../src/acp-host.ts","../src/run.ts"],"names":["fs"],"mappings":"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","file":"chunk-7SWAWNDG.mjs","sourcesContent":["/**\n * SQLite-backed memory for the agent, via Mastra's LibSQL store.\n *\n * Each ACP session is a memory *thread* (see acp-host.ts), so the agent recalls\n * earlier turns within a session. The db is a single SQLite file (LibSQL is a\n * SQLite fork) under `~/.agentproto/mastra-agent/` by default — persistent\n * across spawns — overridable with `AGENTPROTO_MASTRA_MEMORY_DB`.\n */\n\nimport { mkdirSync } from \"node:fs\"\nimport { homedir } from \"node:os\"\nimport { join } from \"node:path\"\nimport { LibSQLStore } from \"@mastra/libsql\"\nimport { Memory } from \"@mastra/memory\"\nimport type { MemoryConfig } from \"@agentproto/agent\"\n\n/** A built Mastra memory — structural, matching `@agentproto/mastra`'s\n * `MastraMemoryLike` expectation without importing the exact type. */\nexport type MastraMemoryLike = Memory\n\n/** Resolve the SQLite file path, creating the parent dir. `AGENTPROTO_MASTRA_MEMORY_DB`\n * wins; otherwise `~/.agentproto/mastra-agent/memory.db`. */\nexport function resolveMemoryDbPath(\n env: Record<string, string | undefined> = process.env,\n): string {\n const override = env.AGENTPROTO_MASTRA_MEMORY_DB\n if (override) return override\n const dir = join(homedir(), \".agentproto\", \"mastra-agent\")\n mkdirSync(dir, { recursive: true })\n return join(dir, \"memory.db\")\n}\n\n/**\n * Build a Mastra `Memory` from an AIP-42 `memory:` config. Returns `undefined`\n * when memory is disabled (`scope: \"none\"`) so `buildMastraAgent` attaches none.\n *\n * - `retention_turns` → `options.lastMessages` (how many recent messages to\n * replay into context). Defaults to 20.\n * - Semantic recall is left off (it needs an embedder + vector index) — this is\n * conversation-history memory, the SQLite ask.\n */\nexport function buildSqliteMemory(\n config?: MemoryConfig,\n env: Record<string, string | undefined> = process.env,\n): MastraMemoryLike | undefined {\n if (config?.scope === \"none\") return undefined\n const dbPath = resolveMemoryDbPath(env)\n const lastMessages =\n typeof config?.retention_turns === \"number\" && config.retention_turns > 0\n ? config.retention_turns\n : 20\n return new Memory({\n storage: new LibSQLStore({ id: \"mastra-agent-memory\", url: `file:${dbPath}` }),\n options: {\n lastMessages,\n semanticRecall: false,\n workingMemory: { enabled: false },\n },\n })\n}\n","/**\n * WP1 — AIP-42 `model:` ref -> a model Mastra's `Agent` can run.\n *\n * Mastra 1.x ships a model router (`models.dev` gateway) that accepts a bare\n * `provider/model` string (e.g. `anthropic/claude-opus-4-8`,\n * `openrouter/z-ai/glm-5.2`) and resolves it to a live ai-sdk model, reading\n * the provider's key from the environment. So the resolver is a thin,\n * *validated* pass-through: extract the ref string, sanity-check the shape,\n * surface a friendly error when the obvious provider key is missing, and hand\n * the string to Mastra. No bespoke provider wiring, no extra ai-sdk deps.\n */\n\nimport type { ModelRef } from \"@agentproto/agent\"\n\n/** Best-effort provider -> env var map, used only for a friendly preflight\n * error. Mastra's gateway is the source of truth; this list just turns the\n * common \"forgot the key\" case into a clear message instead of a deep ai-sdk\n * stack trace. Providers not listed here skip the preflight check. */\nconst PROVIDER_ENV: Record<string, string> = {\n openai: \"OPENAI_API_KEY\",\n anthropic: \"ANTHROPIC_API_KEY\",\n openrouter: \"OPENROUTER_API_KEY\",\n google: \"GOOGLE_GENERATIVE_AI_API_KEY\",\n groq: \"GROQ_API_KEY\",\n xai: \"XAI_API_KEY\",\n mistral: \"MISTRAL_API_KEY\",\n deepseek: \"DEEPSEEK_API_KEY\",\n}\n\n/** Pull the model id string out of an AIP-42 `ModelRef` (string | { ref }). */\nexport function modelRefToString(ref: ModelRef): string {\n if (typeof ref === \"string\") return ref.trim()\n if (ref && typeof ref === \"object\" && typeof ref.ref === \"string\") {\n return ref.ref.trim()\n }\n throw new Error(\n \"mastra-agent: AGENT.md `model` must be a `provider/model` string \" +\n \"(or { ref }); inline model objects are not supported by this adapter.\",\n )\n}\n\n/** The provider segment is everything before the first `/`. */\nexport function providerOf(modelId: string): string {\n const slash = modelId.indexOf(\"/\")\n return slash > 0 ? modelId.slice(0, slash) : modelId\n}\n\n/**\n * Resolve an AIP-42 model ref to the value Mastra's `Agent` constructor takes.\n * Returns the `provider/model` string — Mastra routes it. `env` defaults to\n * `process.env`; injectable for tests.\n */\nexport function resolveMastraModel(\n ref: ModelRef,\n env: Record<string, string | undefined> = process.env,\n): string {\n const modelId = modelRefToString(ref)\n if (!modelId) {\n throw new Error(\"mastra-agent: empty `model` ref.\")\n }\n const provider = providerOf(modelId)\n const envKey = PROVIDER_ENV[provider]\n if (envKey && !env[envKey]) {\n throw new Error(\n `mastra-agent: model '${modelId}' needs ${envKey} in the environment ` +\n `(provider '${provider}'). Set it on the spawn env or export it.`,\n )\n }\n return modelId\n}\n","/**\n * Workspace toolset — gives the Mastra agent the ability to inspect, edit, and\n * run commands inside its session working directory, like a coding agent.\n *\n * SAFETY: every file path is resolved against the session `cwd` and rejected if\n * it escapes (no `../` traversal, no absolute paths outside cwd). Command\n * execution runs with `cwd` and a timeout, and is gated by `allowExec` (the CLI\n * sets it from `AGENTPROTO_MASTRA_NO_EXEC`). The agent only ever touches the\n * directory the daemon spawned it in.\n */\n\nimport { exec } from \"node:child_process\"\nimport { promises as fs } from \"node:fs\"\nimport { isAbsolute, relative, resolve, sep } from \"node:path\"\nimport { promisify } from \"node:util\"\nimport { createTool } from \"@mastra/core/tools\"\nimport { z } from \"zod\"\n\nconst execAsync = promisify(exec)\n\n/** A Mastra tool (structural — avoids coupling to a @mastra/core type name). */\nexport interface WorkspaceTool {\n id: string\n}\n\nexport interface WorkspaceToolsOptions {\n /** Absolute path the agent is confined to (the spawn cwd). */\n cwd: string\n /** When false, `run_command` is omitted from the toolset. Default true. */\n allowExec?: boolean\n /** Per-command timeout (ms). Default 120_000. */\n execTimeoutMs?: number\n}\n\n/** Resolve `p` against `cwd`, throwing if the result escapes the workspace. */\nexport function resolveInCwd(cwd: string, p: string): string {\n const base = resolve(cwd)\n const target = isAbsolute(p) ? resolve(p) : resolve(base, p)\n const rel = relative(base, target)\n if (rel === \"\" ) return target // the workspace root itself\n if (rel.startsWith(\"..\") || (isAbsolute(rel) && !target.startsWith(base + sep))) {\n throw new Error(\n `path '${p}' escapes the workspace (resolved to '${target}', outside '${base}').`,\n )\n }\n return target\n}\n\n/**\n * Build the workspace toolset, all confined to `cwd`. Returns a record keyed by\n * tool id (also the AGENT.md tool ref the resolver matches).\n */\nexport function makeWorkspaceTools(\n opts: WorkspaceToolsOptions,\n): Record<string, ReturnType<typeof createTool>> {\n const cwd = resolve(opts.cwd)\n const allowExec = opts.allowExec ?? true\n const execTimeoutMs = opts.execTimeoutMs ?? 120_000\n\n const list_dir = createTool({\n id: \"list_dir\",\n description:\n \"List the entries of a directory in the workspace. Returns names with a trailing '/' for directories. Path is relative to the workspace root (default '.').\",\n inputSchema: z.object({\n path: z.string().default(\".\").describe(\"Directory path, relative to the workspace root.\"),\n }),\n outputSchema: z.object({ entries: z.array(z.string()) }),\n execute: async (input: { path?: string }) => {\n const dir = resolveInCwd(cwd, input.path ?? \".\")\n const dirents = await fs.readdir(dir, { withFileTypes: true })\n return {\n entries: dirents.map((d) => (d.isDirectory() ? `${d.name}/` : d.name)).sort(),\n }\n },\n })\n\n const read_file = createTool({\n id: \"read_file\",\n description:\n \"Read a UTF-8 text file from the workspace. Path is relative to the workspace root.\",\n inputSchema: z.object({\n path: z.string().describe(\"File path, relative to the workspace root.\"),\n }),\n outputSchema: z.object({ content: z.string() }),\n execute: async (input: { path: string }) => {\n const file = resolveInCwd(cwd, input.path)\n return { content: await fs.readFile(file, \"utf8\") }\n },\n })\n\n const write_file = createTool({\n id: \"write_file\",\n description:\n \"Write (creating or overwriting) a UTF-8 text file in the workspace. Creates parent directories as needed. Path is relative to the workspace root.\",\n inputSchema: z.object({\n path: z.string().describe(\"File path, relative to the workspace root.\"),\n content: z.string().describe(\"Full file contents to write.\"),\n }),\n outputSchema: z.object({ path: z.string(), bytes: z.number() }),\n execute: async (input: { path: string; content: string }) => {\n const file = resolveInCwd(cwd, input.path)\n await fs.mkdir(resolve(file, \"..\"), { recursive: true })\n await fs.writeFile(file, input.content, \"utf8\")\n return { path: input.path, bytes: Buffer.byteLength(input.content, \"utf8\") }\n },\n })\n\n const edit_file = createTool({\n id: \"edit_file\",\n description:\n \"Replace an exact substring in a workspace file. `old_string` must occur exactly once. Use for targeted edits instead of rewriting the whole file.\",\n inputSchema: z.object({\n path: z.string().describe(\"File path, relative to the workspace root.\"),\n old_string: z.string().describe(\"Exact text to replace (must be unique in the file).\"),\n new_string: z.string().describe(\"Replacement text.\"),\n }),\n outputSchema: z.object({ path: z.string(), replaced: z.boolean() }),\n execute: async (input: { path: string; old_string: string; new_string: string }) => {\n const file = resolveInCwd(cwd, input.path)\n const current = await fs.readFile(file, \"utf8\")\n const count = current.split(input.old_string).length - 1\n if (count === 0) throw new Error(`old_string not found in '${input.path}'.`)\n if (count > 1) {\n throw new Error(`old_string occurs ${count}× in '${input.path}' — make it unique.`)\n }\n await fs.writeFile(file, current.replace(input.old_string, input.new_string), \"utf8\")\n return { path: input.path, replaced: true }\n },\n })\n\n const tools: Record<string, ReturnType<typeof createTool>> = {\n list_dir,\n read_file,\n write_file,\n edit_file,\n }\n\n if (allowExec) {\n tools.run_command = createTool({\n id: \"run_command\",\n description:\n \"Run a shell command in the workspace directory and return its stdout/stderr/exit code. Runs with a timeout; use for builds, tests, git, etc.\",\n inputSchema: z.object({\n command: z.string().describe(\"The shell command to run (executed in the workspace root).\"),\n }),\n outputSchema: z.object({\n stdout: z.string(),\n stderr: z.string(),\n exitCode: z.number(),\n }),\n execute: async (input: { command: string }) => {\n try {\n const { stdout, stderr } = await execAsync(input.command, {\n cwd,\n timeout: execTimeoutMs,\n maxBuffer: 10 * 1024 * 1024,\n })\n return { stdout, stderr, exitCode: 0 }\n } catch (err) {\n const e = err as { stdout?: string; stderr?: string; code?: number; message?: string }\n return {\n stdout: e.stdout ?? \"\",\n stderr: e.stderr ?? e.message ?? String(err),\n exitCode: typeof e.code === \"number\" ? e.code : 1,\n }\n }\n },\n })\n }\n\n return tools\n}\n","/**\n * Builds a runnable Mastra agent from an AIP-42 AGENT.md — either a caller's\n * file or a zero-config built-in default — wiring the model, the markdown body\n * as instructions, the SQLite memory, and the workspace toolset.\n */\n\nimport { readFile } from \"node:fs/promises\"\nimport { agentFromManifest, parseAgentManifest } from \"@agentproto/agent\"\nimport { buildMastraAgent } from \"@agentproto/mastra\"\nimport type { MastraLike } from \"./acp-host.js\"\nimport { buildSqliteMemory } from \"./memory.js\"\nimport { resolveMastraModel } from \"./model-resolver.js\"\nimport { makeWorkspaceTools } from \"./workspace-tools.js\"\n\n/** Cheap OpenRouter coder by default — this is the budget first-party arm,\n * same rationale as the hermes default. Override with --model / env. */\nexport const DEFAULT_MODEL = \"openrouter/z-ai/glm-5.2\"\n\n/** Tool ids the built-in default agent is granted (the workspace toolset). */\nexport const DEFAULT_TOOL_IDS = [\n \"list_dir\",\n \"read_file\",\n \"write_file\",\n \"edit_file\",\n \"run_command\",\n] as const\n\nexport interface AgentSourceOptions {\n /** Path to an AGENT.md. When omitted, the built-in default agent is used. */\n agentFile?: string\n /** Model id for the default agent (ignored when agentFile carries a model). */\n model?: string\n /** Workspace dir the tools are confined to. Defaults to `process.cwd()`. */\n cwd?: string\n /** When false, the `run_command` tool is withheld. Default true. */\n allowExec?: boolean\n}\n\n/** The built-in AGENT.md used when no file is supplied. */\nexport function defaultAgentManifest(model: string): string {\n return [\n \"---\",\n \"schema: agent/v1\",\n \"id: mastra-agent\",\n \"description: A first-party agentproto agent powered by Mastra.\",\n `model: ${model}`,\n \"version: 0.1.0\",\n \"tools:\",\n ...DEFAULT_TOOL_IDS.map((id) => ` - ${id}`),\n \"memory:\",\n \" scope: per-conversation\",\n \" retention_turns: 20\",\n \"---\",\n \"\",\n \"You are a capable, concise coding agent operating inside a workspace \",\n \"directory. You can list, read, write, and edit files and run shell \",\n \"commands there using your tools. Do exactly what the user asks — when \",\n \"asked to reply with an exact string, reply with only that string.\",\n \"\",\n ].join(\"\\n\")\n}\n\n/** Pull the id string out of an AIP-42 tool ref (string | { ref }). */\nfunction toolRefId(ref: unknown): string | undefined {\n if (typeof ref === \"string\") return ref\n if (ref && typeof ref === \"object\" && typeof (ref as { ref?: unknown }).ref === \"string\") {\n return (ref as { ref: string }).ref\n }\n return undefined\n}\n\n/** Resolve the AGENT.md source for these options (file or built-in default). */\nexport async function resolveAgentSource(\n opts: AgentSourceOptions = {},\n): Promise<string> {\n if (opts.agentFile) return readFile(opts.agentFile, \"utf8\")\n return defaultAgentManifest(opts.model ?? DEFAULT_MODEL)\n}\n\n/**\n * A lazy factory: parses the AGENT.md, builds the Mastra agent with the model\n * resolver, SQLite memory, the markdown body as instructions, and the\n * workspace toolset (matched by tool id), then returns it as the structural\n * `MastraLike` the ACP host needs.\n */\nexport function makeAgentFactory(\n opts: AgentSourceOptions = {},\n): () => Promise<MastraLike> {\n return async () => {\n const source = await resolveAgentSource(opts)\n const { frontmatter, body } = parseAgentManifest(source)\n const handle = agentFromManifest({ frontmatter, body })\n\n const cwd = opts.cwd ?? process.cwd()\n const workspaceTools = makeWorkspaceTools({ cwd, allowExec: opts.allowExec })\n\n const { agent } = await buildMastraAgent(handle, {\n resolveModel: (ref) => resolveMastraModel(ref),\n // Match each declared tool ref against the workspace toolset by id.\n resolveTool: (ref) => {\n const id = toolRefId(ref)\n const tool = id ? workspaceTools[id] : undefined\n return tool ? { name: id as string, tool } : undefined\n },\n buildMemory: (config) => buildSqliteMemory(config),\n // The markdown body is the agent's primary system prompt (AIP-42).\n body,\n })\n return agent as unknown as MastraLike\n }\n}\n","/**\n * Pure mapping from Mastra `fullStream` chunks to AIP-44 ACP `session/update`\n * payloads. Kept dependency-light (no SDK import beyond types) and side-effect\n * free so it is straightforward to unit-test; the ACP host (acp-host.ts) owns\n * the wire/IO and just forwards whatever this returns.\n *\n * Mastra emits a typed chunk union on `agent.stream(...).fullStream`. We care\n * about three kinds:\n * - `text-delta` → ACP `agent_message_chunk` (assistant prose)\n * - `tool-call` → ACP `tool_call` (a tool started, status in_progress)\n * - `tool-result` → ACP `tool_call_update` (that tool finished/failed)\n * Everything else (reasoning, step boundaries, finish, …) is not surfaced.\n */\n\nimport type { SessionUpdate, ToolKind } from \"@agentclientprotocol/sdk\"\n\n/** The narrow slice of a Mastra fullStream chunk we read. Typed structurally\n * so we don't couple to a specific @mastra/core version. */\nexport type MastraStreamChunk =\n | { type: \"text-delta\"; payload?: { text?: string } }\n | {\n type: \"tool-call\"\n payload?: { toolCallId?: string; toolName?: string; args?: unknown }\n }\n | {\n type: \"tool-result\"\n payload?: {\n toolCallId?: string\n toolName?: string\n result?: unknown\n isError?: boolean\n }\n }\n | { type: string; payload?: unknown }\n\n/** Map a workspace tool id to the ACP {@link ToolKind} that drives client\n * icon/UI treatment. Unknown ids fall back to \"other\". */\nexport function toolKindFor(toolName: string): ToolKind {\n switch (toolName) {\n case \"read_file\":\n case \"list_dir\":\n return \"read\"\n case \"write_file\":\n case \"edit_file\":\n return \"edit\"\n case \"run_command\":\n return \"execute\"\n default:\n return \"other\"\n }\n}\n\n/** A short, human-readable title for a tool call, e.g. `run_command: ls -la`\n * or `read_file: src/index.ts`. Falls back to the bare tool name. */\nexport function toolCallTitle(toolName: string, args: unknown): string {\n if (args && typeof args === \"object\") {\n const a = args as Record<string, unknown>\n const hint =\n (typeof a.command === \"string\" && a.command) ||\n (typeof a.path === \"string\" && a.path) ||\n (typeof a.file === \"string\" && a.file) ||\n \"\"\n if (hint) return `${toolName}: ${hint}`\n }\n return toolName\n}\n\n/**\n * Translate one Mastra chunk into an ACP `session/update` payload, or `null`\n * when the chunk has no ACP surface (or is missing the ids we need). The ACP\n * host wraps the result with the `sessionId`.\n */\nexport function chunkToSessionUpdate(\n chunk: MastraStreamChunk,\n): SessionUpdate | null {\n switch (chunk.type) {\n case \"text-delta\": {\n const text = (chunk.payload as { text?: string } | undefined)?.text\n if (!text) return null\n return {\n sessionUpdate: \"agent_message_chunk\",\n content: { type: \"text\", text },\n }\n }\n case \"tool-call\": {\n const p = chunk.payload as\n | { toolCallId?: string; toolName?: string; args?: unknown }\n | undefined\n if (!p?.toolCallId) return null\n const toolName = p.toolName ?? \"tool\"\n return {\n sessionUpdate: \"tool_call\",\n toolCallId: p.toolCallId,\n title: toolCallTitle(toolName, p.args),\n kind: toolKindFor(toolName),\n status: \"in_progress\",\n rawInput: p.args,\n }\n }\n case \"tool-result\": {\n const p = chunk.payload as\n | { toolCallId?: string; result?: unknown; isError?: boolean }\n | undefined\n if (!p?.toolCallId) return null\n return {\n sessionUpdate: \"tool_call_update\",\n toolCallId: p.toolCallId,\n status: p.isError ? \"failed\" : \"completed\",\n rawOutput: p.result,\n }\n }\n default:\n return null\n }\n}\n","/**\n * WP2 — the agent side of AIP-44 ACP, backed by a live Mastra agent.\n *\n * Implements the `@agentclientprotocol/sdk` `Agent` interface: handles the\n * session lifecycle and, on `session/prompt`, drives a Mastra agent's\n * `stream()` — relaying each text delta as an `agent_message_chunk`\n * `session/update`, exactly as an IDE/host expects from codex or claude-code.\n *\n * No Mastra-specific protocol knowledge leaks past this file; everything above\n * is the standard ACP wire, so the daemon spawns this like any other arm.\n */\n\nimport type {\n AgentSideConnection,\n Agent as AcpAgent,\n AuthenticateRequest,\n CancelNotification,\n InitializeRequest,\n InitializeResponse,\n NewSessionRequest,\n NewSessionResponse,\n PromptRequest,\n PromptResponse,\n SetSessionConfigOptionRequest,\n SetSessionConfigOptionResponse,\n SetSessionModeRequest,\n} from \"@agentclientprotocol/sdk\"\nimport { PROTOCOL_VERSION } from \"@agentclientprotocol/sdk\"\nimport { type MastraStreamChunk, chunkToSessionUpdate } from \"./tool-call-map.js\"\n\n/** A built Mastra agent — only the surface we need (its `stream`). Typed\n * structurally so we don't couple to a specific @mastra/core version.\n *\n * We read `fullStream` (the typed chunk union: text deltas AND tool-call /\n * tool-result events) so tool activity surfaces as ACP `tool_call` updates,\n * not only the final prose. `textStream` is kept as an optional fallback for\n * a stripped agent that exposes only text. */\nexport interface MastraLike {\n stream(\n input: string,\n options?: {\n abortSignal?: AbortSignal\n /** Memory threading — `thread` scopes recall to one ACP session. */\n memory?: { thread?: string; resource?: string }\n },\n ): Promise<{\n fullStream?: ReadableStream<MastraStreamChunk>\n textStream?: ReadableStream<string>\n text?: Promise<string>\n }>\n}\n\n/** Lazily builds the Mastra agent (so model/key errors surface on the first\n * prompt with a clear message, not at process spawn). */\nexport type AgentFactory = () => Promise<MastraLike>\n\ninterface SessionState {\n prompt: AbortController | null\n}\n\n/** Pull the user's text out of an ACP prompt (its `text` content blocks). */\nexport function promptText(params: PromptRequest): string {\n const blocks = Array.isArray(params.prompt) ? params.prompt : []\n return blocks\n .filter((b): b is { type: \"text\"; text: string } =>\n Boolean(b) && (b as { type?: string }).type === \"text\" &&\n typeof (b as { text?: unknown }).text === \"string\",\n )\n .map((b) => b.text)\n .join(\"\")\n .trim()\n}\n\nexport class MastraAcpAgent implements AcpAgent {\n readonly #conn: AgentSideConnection\n readonly #buildAgent: AgentFactory\n readonly #resource: string\n readonly #sessions = new Map<string, SessionState>()\n #agent: MastraLike | null = null\n\n constructor(\n conn: AgentSideConnection,\n buildAgent: AgentFactory,\n resource = \"mastra-agent\",\n ) {\n this.#conn = conn\n this.#buildAgent = buildAgent\n // `resource` groups a user's threads in Mastra memory; one per agent here.\n this.#resource = resource\n }\n\n async initialize(_params: InitializeRequest): Promise<InitializeResponse> {\n return {\n protocolVersion: PROTOCOL_VERSION,\n agentCapabilities: {\n // Stateless per-prompt for now; no resume/replay surface.\n loadSession: false,\n },\n }\n }\n\n async authenticate(\n _params: AuthenticateRequest,\n ): Promise<Record<string, never>> {\n // The provider key is read from the spawn env by the model gateway — no\n // ACP-level auth handshake needed.\n return {}\n }\n\n async newSession(_params: NewSessionRequest): Promise<NewSessionResponse> {\n const sessionId = randomId()\n this.#sessions.set(sessionId, { prompt: null })\n return { sessionId }\n }\n\n async prompt(params: PromptRequest): Promise<PromptResponse> {\n const session = this.#sessions.get(params.sessionId)\n if (!session) throw new Error(`unknown session ${params.sessionId}`)\n\n // Cancel any in-flight turn for this session before starting a new one.\n session.prompt?.abort()\n const ac = new AbortController()\n session.prompt = ac\n\n const text = promptText(params)\n try {\n const agent = await this.#ensureAgent()\n // Thread = ACP session id → recall is scoped to this session's history.\n const result = await agent.stream(text, {\n abortSignal: ac.signal,\n memory: { thread: params.sessionId, resource: this.#resource },\n })\n if (result.fullStream) {\n // Preferred path: the typed chunk stream carries text deltas AND\n // tool-call / tool-result events, so tool activity surfaces live.\n await this.#pumpFullStream(params.sessionId, result.fullStream, ac)\n } else if (result.textStream) {\n // Fallback: a text-only agent — relay prose deltas, no tool surface.\n await this.#pumpTextStream(params.sessionId, result.textStream, ac)\n }\n } catch (err) {\n if (ac.signal.aborted) return { stopReason: \"cancelled\" }\n // Surface the failure to the client as a message chunk, then end the\n // turn — better UX than a bare JSON-RPC error the host may swallow.\n await this.#conn.sessionUpdate({\n sessionId: params.sessionId,\n update: {\n sessionUpdate: \"agent_message_chunk\",\n content: {\n type: \"text\",\n text: `\\n[mastra-agent error] ${(err as Error).message}\\n`,\n },\n },\n })\n session.prompt = null\n return { stopReason: \"refusal\" }\n }\n\n const cancelled = ac.signal.aborted\n session.prompt = null\n return { stopReason: cancelled ? \"cancelled\" : \"end_turn\" }\n }\n\n async cancel(params: CancelNotification): Promise<void> {\n this.#sessions.get(params.sessionId)?.prompt?.abort()\n }\n\n /**\n * The host applies the `model` (and other operator options) as a `--model`\n * spawn arg via the manifest `bin_args_template`, then ALSO calls this ACP\n * config hook (the daemon's default \"config\" apply path). The model is\n * already in effect, so this is a no-op that just reports our (empty) set of\n * runtime-configurable options. Without it the spawn fails with\n * \"Method not found: session/set_config_option\".\n */\n async setSessionConfigOption(\n _params: SetSessionConfigOptionRequest,\n ): Promise<SetSessionConfigOptionResponse> {\n return { configOptions: [] }\n }\n\n /** No agent-specific modes; accept and ignore so a host that sets one\n * doesn't error. */\n async setSessionMode(\n _params: SetSessionModeRequest,\n ): Promise<Record<string, never>> {\n return {}\n }\n\n /** Drain Mastra's typed `fullStream`, mapping each chunk to an ACP\n * `session/update` (text deltas + tool_call / tool_call_update). */\n async #pumpFullStream(\n sessionId: string,\n stream: ReadableStream<MastraStreamChunk>,\n ac: AbortController,\n ): Promise<void> {\n const reader = stream.getReader()\n try {\n for (;;) {\n const { value, done } = await reader.read()\n if (done || ac.signal.aborted) break\n if (!value) continue\n const update = chunkToSessionUpdate(value)\n if (update) await this.#conn.sessionUpdate({ sessionId, update })\n }\n } finally {\n reader.releaseLock()\n }\n }\n\n /** Fallback drain for an agent exposing only a plain text stream. */\n async #pumpTextStream(\n sessionId: string,\n stream: ReadableStream<string>,\n ac: AbortController,\n ): Promise<void> {\n const reader = stream.getReader()\n try {\n for (;;) {\n const { value, done } = await reader.read()\n if (done || ac.signal.aborted) break\n if (value) {\n await this.#conn.sessionUpdate({\n sessionId,\n update: {\n sessionUpdate: \"agent_message_chunk\",\n content: { type: \"text\", text: value },\n },\n })\n }\n }\n } finally {\n reader.releaseLock()\n }\n }\n\n async #ensureAgent(): Promise<MastraLike> {\n if (!this.#agent) this.#agent = await this.#buildAgent()\n return this.#agent\n }\n}\n\n/** 16 random bytes as hex — matches the SDK example's session id shape. */\nfunction randomId(): string {\n const bytes = new Uint8Array(16)\n crypto.getRandomValues(bytes)\n return Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\")\n}\n","/**\n * Boots the ACP server over stdio — the standard wiring for a spawned ACP\n * agent (mirrors the @agentclientprotocol/sdk agent example): the agent writes\n * JSON-RPC to stdout and reads from stdin.\n */\n\nimport { Readable, Writable } from \"node:stream\"\nimport { AgentSideConnection, ndJsonStream } from \"@agentclientprotocol/sdk\"\nimport { MastraAcpAgent, type AgentFactory } from \"./acp-host.js\"\n\nexport function runAcpOverStdio(buildAgent: AgentFactory): AgentSideConnection {\n // ndJsonStream(writable, readable): outgoing bytes -> stdout, incoming <- stdin.\n const toClient = Writable.toWeb(process.stdout) as WritableStream<Uint8Array>\n const fromClient = Readable.toWeb(\n process.stdin,\n ) as unknown as ReadableStream<Uint8Array>\n const stream = ndJsonStream(toClient, fromClient)\n return new AgentSideConnection(\n (conn) => new MastraAcpAgent(conn, buildAgent),\n stream,\n )\n}\n"]}