@parlor/agent-host 0.4.4 → 0.4.6
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/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +24 -1
- package/dist/daemon.js.map +1 -1
- package/dist/link.d.ts +2 -0
- package/dist/link.d.ts.map +1 -1
- package/dist/link.js +16 -1
- package/dist/link.js.map +1 -1
- package/dist/mcp-proxy.d.ts +2 -0
- package/dist/mcp-proxy.d.ts.map +1 -1
- package/dist/mcp-proxy.js +42 -6
- package/dist/mcp-proxy.js.map +1 -1
- package/dist/pool.d.ts +10 -0
- package/dist/pool.d.ts.map +1 -1
- package/dist/pool.js +52 -0
- package/dist/pool.js.map +1 -1
- package/dist/testing/fake-agent.d.ts.map +1 -1
- package/dist/testing/fake-agent.js +4 -1
- package/dist/testing/fake-agent.js.map +1 -1
- package/dist/turn.d.ts.map +1 -1
- package/dist/turn.js +22 -21
- package/dist/turn.js.map +1 -1
- package/dist/warm.d.ts +29 -0
- package/dist/warm.d.ts.map +1 -0
- package/dist/warm.js +68 -0
- package/dist/warm.js.map +1 -0
- package/package.json +9 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fake-agent.js","sourceRoot":"","sources":["../../src/testing/fake-agent.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ChildProcessWithoutNullStreams, spawn } from \"node:child_process\";\nimport { createInterface } from \"node:readline\";\n\nimport type { AgentOption, AgentUsage } from \"@parlor/chat\";\n\nimport {\n type AcpStdio,\n type AgentAsk,\n type AgentAskAnswer,\n type AgentModes,\n type AgentUpdate,\n type PromptBlock,\n serveAcpAgent,\n type StdioMcpServer,\n type StopReason,\n type ToolKind,\n} from \"../acp.js\";\nimport type { AgentProfile } from \"../agents.js\";\n\n/**\n * A scripted agent on the real ACP transport (through `serveAcpAgent`), so the adapter,\n * fold, permission, cancel and MCP proxy paths are tested as Claude Code and Codex drive\n * them. A prompt's text names the step list to play: the whole text, or its last line when\n * the host put its context block first. Every reply chunk goes out prefixed with\n * `[t:<epoch ms>]`, the time it was written.\n */\nexport interface FakeAgentScript {\n readonly advertise?:\n | {\n readonly resume?: boolean | undefined;\n readonly close?: boolean | undefined;\n readonly mcpHttp?: boolean | undefined;\n readonly modes?: AgentModes | undefined;\n readonly options?: readonly AgentOption[] | undefined;\n }\n | undefined;\n readonly steps: Readonly<Record<string, readonly FakeStep[]>>;\n /** For a prompt no step names: reply with it. */\n readonly fallback?: \"echo\" | undefined;\n}\n\nexport type FakeStep =\n | {\n readonly kind: \"reply\";\n readonly chunks: readonly string[];\n readonly perSecond?: number;\n }\n | { readonly kind: \"thought\"; readonly text: string }\n /** The agent moving itself to another mode, as Claude does off a model without `auto`. */\n | { readonly kind: \"mode\"; readonly modeId: string }\n /** A rate limit report, as Claude Code sends it on a `usage_update`. */\n | { readonly kind: \"usage\"; readonly usage: AgentUsage }\n | {\n readonly kind: \"tool\";\n readonly title: string;\n readonly toolKind: ToolKind;\n readonly mcp?: { readonly server: string; readonly tool: string } | undefined;\n readonly askPermission: boolean;\n /** The permission request's own title, when it differs from the call's. */\n readonly askTitle?: string | undefined;\n }\n /** Calls an app tool through the MCP server the host passed in `session/new`. */\n | { readonly kind: \"call_app\"; readonly tool: string; readonly input: unknown }\n | { readonly kind: \"plan\"; readonly entries: readonly string[] }\n | {\n readonly kind: \"question\";\n readonly message: string;\n readonly schema: Readonly<Record<string, unknown>>;\n }\n | { readonly kind: \"wait_for_cancel\" }\n | { readonly kind: \"exit\"; readonly code: number }\n | { readonly kind: \"stop\"; readonly reason: Exclude<StopReason, \"cancelled\"> };\n\ninterface Peer {\n update(update: AgentUpdate): Promise<void>;\n ask(ask: AgentAsk): Promise<AgentAskAnswer>;\n readonly cancelled: AbortSignal;\n}\n\nconst ALLOW = \"allow\";\nconst REJECT = \"reject\";\n\nconst PERMISSION_OPTIONS = [\n { id: ALLOW, label: \"Allow\", effect: \"allow_once\" },\n { id: REJECT, label: \"Reject\", effect: \"reject_once\" },\n] as const;\n\nfunction sleep(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n if (signal.aborted) return resolve();\n const timer = setTimeout(resolve, ms);\n signal.addEventListener(\n \"abort\",\n () => {\n clearTimeout(timer);\n resolve();\n },\n { once: true },\n );\n });\n}\n\nfunction stepsFor(script: FakeAgentScript, text: string): readonly FakeStep[] {\n const trimmed = text.trim();\n const lastLine = trimmed.split(\"\\n\").at(-1)?.trim() ?? \"\";\n const named = script.steps[trimmed] ?? script.steps[lastLine];\n if (named) return named;\n return [\n {\n kind: \"reply\",\n chunks: [\n script.fallback === \"echo\" ? text : `No step list is named \"${lastLine}\".`,\n ],\n },\n ];\n}\n\nclass McpStdioClient {\n readonly #child: ChildProcessWithoutNullStreams;\n readonly #pending = new Map<number, (message: Record<string, unknown>) => void>();\n readonly #ready: Promise<void>;\n #nextId = 1;\n\n constructor(server: StdioMcpServer) {\n this.#child = spawn(server.command, [...server.args], {\n env: { ...process.env, ...server.env },\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n createInterface({ input: this.#child.stdout }).on(\"line\", (line) => {\n let message: Record<string, unknown>;\n try {\n message = JSON.parse(line) as Record<string, unknown>;\n } catch {\n return;\n }\n if (typeof message.id === \"number\") this.#pending.get(message.id)?.(message);\n });\n this.#ready = this.request(\"initialize\", {\n protocolVersion: \"2025-06-18\",\n capabilities: {},\n clientInfo: { name: \"fake-agent\", version: \"0.0.0\" },\n }).then(() => this.#send({ jsonrpc: \"2.0\", method: \"notifications/initialized\" }));\n }\n\n #send(message: unknown) {\n this.#child.stdin.write(`${JSON.stringify(message)}\\n`);\n }\n\n request(method: string, params: unknown): Promise<Record<string, unknown>> {\n const id = this.#nextId++;\n return new Promise((resolve) => {\n this.#pending.set(id, (message) => {\n this.#pending.delete(id);\n resolve(message);\n });\n this.#send({ jsonrpc: \"2.0\", id, method, params });\n });\n }\n\n async callTool(name: string, input: unknown): Promise<Record<string, unknown>> {\n await this.#ready;\n return this.request(\"tools/call\", { name, arguments: input });\n }\n\n close() {\n this.#child.kill();\n }\n}\n\nfunction resultText(message: Record<string, unknown>): { text: string; failed: boolean } {\n const error = message.error as { message?: string } | undefined;\n if (error) return { text: error.message ?? \"error\", failed: true };\n const result = message.result as\n | { content?: { type: string; text?: string }[]; isError?: boolean }\n | undefined;\n const text = (result?.content ?? [])\n .flatMap((content) => (content.type === \"text\" && content.text ? [content.text] : []))\n .join(\"\\n\");\n return { text, failed: result?.isError === true };\n}\n\n/** The fixture's entry point: serves `script` on `io` (the process's stdio). */\nexport function serveFakeAgent(script: FakeAgentScript, io: AcpStdio): Promise<void> {\n const sessions = new Map<string, readonly StdioMcpServer[]>();\n const clients = new Map<string, McpStdioClient>();\n let tools = 0;\n\n const permit = async (\n peer: Peer,\n toolCallId: string,\n title: string,\n step: {\n readonly toolKind: ToolKind;\n readonly mcp?: { readonly server: string; readonly tool: string } | undefined;\n },\n ) => {\n const answer = await peer.ask({\n kind: \"permission\",\n toolCallId,\n title,\n toolKind: step.toolKind,\n mcp: step.mcp,\n options: PERMISSION_OPTIONS,\n });\n return answer.kind === \"selected\" && answer.optionId === ALLOW;\n };\n\n const play = async (\n sessionId: string,\n step: FakeStep,\n peer: Peer,\n ): Promise<StopReason | undefined> => {\n switch (step.kind) {\n case \"reply\":\n for (const chunk of step.chunks) {\n if (peer.cancelled.aborted) return \"cancelled\";\n await peer.update({ kind: \"text\", text: `[t:${Date.now()}]${chunk}` });\n if (step.perSecond) await sleep(1000 / step.perSecond, peer.cancelled);\n }\n return undefined;\n case \"thought\":\n await peer.update({ kind: \"thought\", text: step.text });\n return undefined;\n case \"mode\":\n await peer.update({ kind: \"mode\", modeId: step.modeId });\n return undefined;\n case \"usage\":\n await peer.update({ kind: \"usage\", usage: step.usage });\n return undefined;\n case \"tool\": {\n const toolCallId = `tool-${++tools}`;\n await peer.update({\n kind: \"tool_start\",\n toolCallId,\n title: step.title,\n toolKind: step.toolKind,\n mcp: step.mcp,\n });\n const allowed =\n !step.askPermission ||\n (await permit(peer, toolCallId, step.askTitle ?? step.title, step));\n await peer.update({\n kind: \"tool_update\",\n toolCallId,\n status: allowed ? \"completed\" : \"failed\",\n ...(allowed ? {} : { detail: \"denied\" }),\n });\n return undefined;\n }\n case \"call_app\": {\n const server = sessions.get(sessionId)?.[0];\n if (!server) throw new Error(\"The host gave this session no MCP server.\");\n const toolCallId = `tool-${++tools}`;\n const mcp = { server: server.name, tool: step.tool };\n await peer.update({\n kind: \"tool_start\",\n toolCallId,\n title: step.tool,\n toolKind: \"other\",\n mcp,\n });\n if (!(await permit(peer, toolCallId, step.tool, { toolKind: \"other\", mcp }))) {\n await peer.update({\n kind: \"tool_update\",\n toolCallId,\n status: \"failed\",\n detail: \"denied\",\n });\n return undefined;\n }\n let client = clients.get(sessionId);\n if (!client) {\n client = new McpStdioClient(server);\n clients.set(sessionId, client);\n }\n const { text, failed } = resultText(await client.callTool(step.tool, step.input));\n await peer.update({\n kind: \"tool_update\",\n toolCallId,\n status: failed ? \"failed\" : \"completed\",\n detail: text,\n });\n return undefined;\n }\n case \"plan\":\n await peer.update({\n kind: \"plan\",\n entries: step.entries.map((content) => ({ content, status: \"pending\" })),\n });\n return undefined;\n case \"question\":\n await peer.ask({ kind: \"question\", message: step.message, schema: step.schema });\n return undefined;\n case \"wait_for_cancel\":\n await new Promise<void>((resolve) => {\n if (peer.cancelled.aborted) return resolve();\n peer.cancelled.addEventListener(\"abort\", () => resolve(), { once: true });\n });\n return \"cancelled\";\n case \"exit\":\n return process.exit(step.code);\n case \"stop\":\n return step.reason;\n }\n };\n\n const served = serveAcpAgent(\n {\n capabilities: {\n resume: script.advertise?.resume === true,\n close: script.advertise?.close === true,\n mcpHttp: script.advertise?.mcpHttp === true,\n },\n newSession: async (input) => {\n const id = `fake-session-${sessions.size + 1}`;\n sessions.set(id, input.mcpServers);\n return {\n id,\n modes: script.advertise?.modes,\n options: script.advertise?.options,\n };\n },\n prompt: async (sessionId, blocks: readonly PromptBlock[], peer) => {\n const text = blocks.map((block) => block.text).join(\"\\n\");\n for (const step of stepsFor(script, text)) {\n if (peer.cancelled.aborted) return \"cancelled\";\n const stop = await play(sessionId, step, peer);\n if (stop) return stop;\n }\n return peer.cancelled.aborted ? \"cancelled\" : \"end_turn\";\n },\n },\n io,\n );\n return served.finally(() => {\n for (const client of clients.values()) client.close();\n });\n}\n\n/** A profile that launches the fixture at `entry` with `scriptFile`. */\nexport function fakeAgentProfile(entry: string, scriptFile: string): AgentProfile {\n return {\n id: \"fake\",\n name: \"Fake agent\",\n launch: { kind: \"native\", command: \"node\", args: [entry, scriptFile] },\n binary: \"node\",\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fake-agent.js","sourceRoot":"","sources":["../../src/testing/fake-agent.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ChildProcessWithoutNullStreams, spawn } from \"node:child_process\";\nimport { createInterface } from \"node:readline\";\n\nimport type { AgentOption, AgentUsage } from \"@parlor/chat\";\n\nimport {\n type AcpStdio,\n type AgentAsk,\n type AgentAskAnswer,\n type AgentModes,\n type AgentUpdate,\n type PromptBlock,\n serveAcpAgent,\n type StdioMcpServer,\n type StopReason,\n type ToolKind,\n} from \"../acp.js\";\nimport type { AgentProfile } from \"../agents.js\";\n\n/**\n * A scripted agent on the real ACP transport (through `serveAcpAgent`), so the adapter,\n * fold, permission, cancel and MCP proxy paths are tested as Claude Code and Codex drive\n * them. A prompt's text names the step list to play: the whole text, or its last line when\n * the host put its context block first. Every reply chunk goes out prefixed with\n * `[t:<epoch ms>]`, the time it was written.\n */\nexport interface FakeAgentScript {\n readonly advertise?:\n | {\n readonly resume?: boolean | undefined;\n readonly close?: boolean | undefined;\n readonly mcpHttp?: boolean | undefined;\n readonly modes?: AgentModes | undefined;\n readonly options?: readonly AgentOption[] | undefined;\n }\n | undefined;\n readonly steps: Readonly<Record<string, readonly FakeStep[]>>;\n /** For a prompt no step names: reply with it. */\n readonly fallback?: \"echo\" | undefined;\n}\n\nexport type FakeStep =\n | {\n readonly kind: \"reply\";\n readonly chunks: readonly string[];\n readonly perSecond?: number;\n }\n | { readonly kind: \"thought\"; readonly text: string }\n /** The agent moving itself to another mode, as Claude does off a model without `auto`. */\n | { readonly kind: \"mode\"; readonly modeId: string }\n /** A rate limit report, as Claude Code sends it on a `usage_update`. */\n | { readonly kind: \"usage\"; readonly usage: AgentUsage }\n | {\n readonly kind: \"tool\";\n readonly title: string;\n readonly toolKind: ToolKind;\n readonly mcp?: { readonly server: string; readonly tool: string } | undefined;\n readonly askPermission: boolean;\n /** The permission request's own title, when it differs from the call's. */\n readonly askTitle?: string | undefined;\n }\n /** Calls an app tool through the MCP server the host passed in `session/new`. */\n | { readonly kind: \"call_app\"; readonly tool: string; readonly input: unknown }\n | { readonly kind: \"plan\"; readonly entries: readonly string[] }\n | {\n readonly kind: \"question\";\n readonly message: string;\n readonly schema: Readonly<Record<string, unknown>>;\n }\n | { readonly kind: \"wait_for_cancel\" }\n | { readonly kind: \"exit\"; readonly code: number }\n | { readonly kind: \"stop\"; readonly reason: Exclude<StopReason, \"cancelled\"> };\n\ninterface Peer {\n update(update: AgentUpdate): Promise<void>;\n ask(ask: AgentAsk): Promise<AgentAskAnswer>;\n readonly cancelled: AbortSignal;\n}\n\nconst ALLOW = \"allow\";\nconst REJECT = \"reject\";\n\nconst PERMISSION_OPTIONS = [\n { id: ALLOW, label: \"Allow\", effect: \"allow_once\" },\n { id: REJECT, label: \"Reject\", effect: \"reject_once\" },\n] as const;\n\nfunction sleep(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n if (signal.aborted) return resolve();\n const timer = setTimeout(resolve, ms);\n signal.addEventListener(\n \"abort\",\n () => {\n clearTimeout(timer);\n resolve();\n },\n { once: true },\n );\n });\n}\n\nfunction stepsFor(script: FakeAgentScript, text: string): readonly FakeStep[] {\n const trimmed = text.trim();\n const lastLine = trimmed.split(\"\\n\").at(-1)?.trim() ?? \"\";\n const named = script.steps[trimmed] ?? script.steps[lastLine];\n if (named) return named;\n return [\n {\n kind: \"reply\",\n chunks: [\n script.fallback === \"echo\" ? text : `No step list is named \"${lastLine}\".`,\n ],\n },\n ];\n}\n\nclass McpStdioClient {\n readonly #child: ChildProcessWithoutNullStreams;\n readonly #pending = new Map<number, (message: Record<string, unknown>) => void>();\n readonly #ready: Promise<void>;\n #nextId = 1;\n\n constructor(server: StdioMcpServer) {\n this.#child = spawn(server.command, [...server.args], {\n env: { ...process.env, ...server.env },\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n createInterface({ input: this.#child.stdout }).on(\"line\", (line) => {\n let message: Record<string, unknown>;\n try {\n message = JSON.parse(line) as Record<string, unknown>;\n } catch {\n return;\n }\n if (typeof message.id === \"number\") this.#pending.get(message.id)?.(message);\n });\n this.#ready = this.request(\"initialize\", {\n protocolVersion: \"2025-06-18\",\n capabilities: {},\n clientInfo: { name: \"fake-agent\", version: \"0.0.0\" },\n })\n .then(() => this.#send({ jsonrpc: \"2.0\", method: \"notifications/initialized\" }))\n .then(() => this.request(\"tools/list\", {}))\n .then(() => undefined);\n }\n\n #send(message: unknown) {\n this.#child.stdin.write(`${JSON.stringify(message)}\\n`);\n }\n\n request(method: string, params: unknown): Promise<Record<string, unknown>> {\n const id = this.#nextId++;\n return new Promise((resolve) => {\n this.#pending.set(id, (message) => {\n this.#pending.delete(id);\n resolve(message);\n });\n this.#send({ jsonrpc: \"2.0\", id, method, params });\n });\n }\n\n async callTool(name: string, input: unknown): Promise<Record<string, unknown>> {\n await this.#ready;\n return this.request(\"tools/call\", { name, arguments: input });\n }\n\n close() {\n this.#child.kill();\n }\n}\n\nfunction resultText(message: Record<string, unknown>): { text: string; failed: boolean } {\n const error = message.error as { message?: string } | undefined;\n if (error) return { text: error.message ?? \"error\", failed: true };\n const result = message.result as\n | { content?: { type: string; text?: string }[]; isError?: boolean }\n | undefined;\n const text = (result?.content ?? [])\n .flatMap((content) => (content.type === \"text\" && content.text ? [content.text] : []))\n .join(\"\\n\");\n return { text, failed: result?.isError === true };\n}\n\n/** The fixture's entry point: serves `script` on `io` (the process's stdio). */\nexport function serveFakeAgent(script: FakeAgentScript, io: AcpStdio): Promise<void> {\n const sessions = new Map<string, readonly StdioMcpServer[]>();\n const clients = new Map<string, McpStdioClient>();\n let tools = 0;\n\n const permit = async (\n peer: Peer,\n toolCallId: string,\n title: string,\n step: {\n readonly toolKind: ToolKind;\n readonly mcp?: { readonly server: string; readonly tool: string } | undefined;\n },\n ) => {\n const answer = await peer.ask({\n kind: \"permission\",\n toolCallId,\n title,\n toolKind: step.toolKind,\n mcp: step.mcp,\n options: PERMISSION_OPTIONS,\n });\n return answer.kind === \"selected\" && answer.optionId === ALLOW;\n };\n\n const play = async (\n sessionId: string,\n step: FakeStep,\n peer: Peer,\n ): Promise<StopReason | undefined> => {\n switch (step.kind) {\n case \"reply\":\n for (const chunk of step.chunks) {\n if (peer.cancelled.aborted) return \"cancelled\";\n await peer.update({ kind: \"text\", text: `[t:${Date.now()}]${chunk}` });\n if (step.perSecond) await sleep(1000 / step.perSecond, peer.cancelled);\n }\n return undefined;\n case \"thought\":\n await peer.update({ kind: \"thought\", text: step.text });\n return undefined;\n case \"mode\":\n await peer.update({ kind: \"mode\", modeId: step.modeId });\n return undefined;\n case \"usage\":\n await peer.update({ kind: \"usage\", usage: step.usage });\n return undefined;\n case \"tool\": {\n const toolCallId = `tool-${++tools}`;\n await peer.update({\n kind: \"tool_start\",\n toolCallId,\n title: step.title,\n toolKind: step.toolKind,\n mcp: step.mcp,\n });\n const allowed =\n !step.askPermission ||\n (await permit(peer, toolCallId, step.askTitle ?? step.title, step));\n await peer.update({\n kind: \"tool_update\",\n toolCallId,\n status: allowed ? \"completed\" : \"failed\",\n ...(allowed ? {} : { detail: \"denied\" }),\n });\n return undefined;\n }\n case \"call_app\": {\n const server = sessions.get(sessionId)?.[0];\n if (!server) throw new Error(\"The host gave this session no MCP server.\");\n const toolCallId = `tool-${++tools}`;\n const mcp = { server: server.name, tool: step.tool };\n await peer.update({\n kind: \"tool_start\",\n toolCallId,\n title: step.tool,\n toolKind: \"other\",\n mcp,\n });\n if (!(await permit(peer, toolCallId, step.tool, { toolKind: \"other\", mcp }))) {\n await peer.update({\n kind: \"tool_update\",\n toolCallId,\n status: \"failed\",\n detail: \"denied\",\n });\n return undefined;\n }\n let client = clients.get(sessionId);\n if (!client) {\n client = new McpStdioClient(server);\n clients.set(sessionId, client);\n }\n const { text, failed } = resultText(await client.callTool(step.tool, step.input));\n await peer.update({\n kind: \"tool_update\",\n toolCallId,\n status: failed ? \"failed\" : \"completed\",\n detail: text,\n });\n return undefined;\n }\n case \"plan\":\n await peer.update({\n kind: \"plan\",\n entries: step.entries.map((content) => ({ content, status: \"pending\" })),\n });\n return undefined;\n case \"question\":\n await peer.ask({ kind: \"question\", message: step.message, schema: step.schema });\n return undefined;\n case \"wait_for_cancel\":\n await new Promise<void>((resolve) => {\n if (peer.cancelled.aborted) return resolve();\n peer.cancelled.addEventListener(\"abort\", () => resolve(), { once: true });\n });\n return \"cancelled\";\n case \"exit\":\n return process.exit(step.code);\n case \"stop\":\n return step.reason;\n }\n };\n\n const served = serveAcpAgent(\n {\n capabilities: {\n resume: script.advertise?.resume === true,\n close: script.advertise?.close === true,\n mcpHttp: script.advertise?.mcpHttp === true,\n },\n newSession: async (input) => {\n const id = `fake-session-${sessions.size + 1}`;\n sessions.set(id, input.mcpServers);\n return {\n id,\n modes: script.advertise?.modes,\n options: script.advertise?.options,\n };\n },\n prompt: async (sessionId, blocks: readonly PromptBlock[], peer) => {\n const text = blocks.map((block) => block.text).join(\"\\n\");\n for (const step of stepsFor(script, text)) {\n if (peer.cancelled.aborted) return \"cancelled\";\n const stop = await play(sessionId, step, peer);\n if (stop) return stop;\n }\n return peer.cancelled.aborted ? \"cancelled\" : \"end_turn\";\n },\n },\n io,\n );\n return served.finally(() => {\n for (const client of clients.values()) client.close();\n });\n}\n\n/** A profile that launches the fixture at `entry` with `scriptFile`. */\nexport function fakeAgentProfile(entry: string, scriptFile: string): AgentProfile {\n return {\n id: \"fake\",\n name: \"Fake agent\",\n launch: { kind: \"native\", command: \"node\", args: [entry, scriptFile] },\n binary: \"node\",\n };\n}\n"]}
|
package/dist/turn.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"turn.d.ts","sourceRoot":"","sources":["../src/turn.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"turn.d.ts","sourceRoot":"","sources":["../src/turn.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EAGV,WAAW,EAIX,WAAW,EAEZ,MAAM,cAAc,CAAC;AAItB,OAAO,EAKL,KAAK,aAAa,EAInB,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,QAAQ,EAAgB,MAAM,gBAAgB,CAAC;AAE7D,OAAO,EAAyC,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACvF,OAAO,KAAK,EAAe,WAAW,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAiB,UAAU,EAAE,MAAM,YAAY,CAAC;AAG5D,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAC;IAC3B,4FAA4F;IAC5F,QAAQ,CAAC,OAAO,CAAC,EAAE;QACjB,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;QACtC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;KACzB,CAAC;IACF,qGAAqG;IACrG,QAAQ,CAAC,OAAO,CAAC,EAAE,CACjB,OAAO,EAAE,MAAM,EACf,OAAO,EACH;QAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAA;KAAE,GAC5C;QAAE,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;KAAE,KAC/B,IAAI,CAAC;CACX;AAED,eAAO,MAAM,iBAAiB,QAAc,CAAC;AA0G7C;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,WAAW,CAAC,CAupBtB"}
|
package/dist/turn.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { mkdir } from "node:fs/promises";
|
|
2
1
|
import { answerStatement, checkPairingProof, deviceCommitment, vouchStatement, signedPrompt, statementBytes, verifyStatement, } from "@parlor/auth";
|
|
3
2
|
import { canonicalBytes, encodeBase64url } from "@parlor/capabilities/encoding";
|
|
4
3
|
import { ActionError, asId } from "@parlor/core";
|
|
@@ -8,7 +7,7 @@ import { finishFold, foldUpdate, startFold } from "./fold.js";
|
|
|
8
7
|
import { logEvent } from "./log.js";
|
|
9
8
|
import { appServerOf, computerName } from "./naming.js";
|
|
10
9
|
import { approvalFor, isAppTool, presenceDueAt } from "./policy.js";
|
|
11
|
-
import {
|
|
10
|
+
import { launchAgent, sessionFit, sessionInput } from "./warm.js";
|
|
12
11
|
export const PROMPT_MAX_AGE_MS = 10 * 60_000;
|
|
13
12
|
/** A vouch is bound to one device's keys, so it may wait for that device's first prompt. */
|
|
14
13
|
const VOUCH_MAX_AGE_MS = 30 * 24 * 60 * 60_000;
|
|
@@ -357,26 +356,28 @@ export async function runTurn(claimed, deps) {
|
|
|
357
356
|
if (switched)
|
|
358
357
|
await event("agent_switched", profile.name);
|
|
359
358
|
try {
|
|
360
|
-
connection = await pool.
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
autoMode: deps.policy.agentMode !== "ask",
|
|
377
|
-
});
|
|
378
|
-
live = { session, proxy };
|
|
359
|
+
connection = await launchAgent(pool, deps.launcher, profile, grant);
|
|
360
|
+
const resume = await pool.resumable(grant, threadId, agentId);
|
|
361
|
+
const warm = resume === undefined
|
|
362
|
+
? pool.takeWarm(grant, agentId, sessionFit(grant, deps.policy))
|
|
363
|
+
: undefined;
|
|
364
|
+
if (warm) {
|
|
365
|
+
proxy = warm.proxy;
|
|
366
|
+
proxy.begin(claimed.token);
|
|
367
|
+
live = warm;
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
proxy = deps.proxy.open(appServer, origin);
|
|
371
|
+
proxy.begin(claimed.token);
|
|
372
|
+
const session = await connection.openSession(sessionInput(grant, deps.policy, proxy, resume));
|
|
373
|
+
live = { session, proxy };
|
|
374
|
+
}
|
|
379
375
|
pool.remember(grant, threadId, agentId, live);
|
|
376
|
+
logEvent("session_opened", {
|
|
377
|
+
appOrigin: origin,
|
|
378
|
+
agentId,
|
|
379
|
+
warm: warm !== undefined,
|
|
380
|
+
});
|
|
380
381
|
}
|
|
381
382
|
catch (error) {
|
|
382
383
|
proxy?.dispose();
|
package/dist/turn.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"turn.js","sourceRoot":"","sources":["../src/turn.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdir } from \"node:fs/promises\";\n\nimport {\n answerStatement,\n checkPairingProof,\n deviceCommitment,\n vouchStatement,\n type PinnedDevice,\n signedPrompt,\n statementBytes,\n verifyStatement,\n type VerifyOutcome,\n} from \"@parlor/auth\";\nimport type { PresenceSignature } from \"@parlor/capabilities\";\nimport { canonicalBytes, encodeBase64url } from \"@parlor/capabilities/encoding\";\nimport type {\n AgentOption,\n AgentUsage,\n ChatEvent,\n ChatItemBody,\n ClaimedTurn,\n HostItemDraft,\n LoggedItem,\n TurnFailure,\n TurnOutcome,\n TurnSignals,\n} from \"@parlor/chat\";\nimport { ActionError, asId, type ItemId } from \"@parlor/core\";\nimport type { DeviceKeys } from \"@parlor/server\";\n\nimport {\n type AgentAsk,\n type AgentAskAnswer,\n type AgentConnection,\n type AgentExit,\n type AgentLauncher,\n type AgentSession,\n SessionRefused,\n type StopReason,\n} from \"./acp.js\";\nimport { optionChanges } from \"./agent-options.js\";\nimport type { AgentProfile } from \"./agents.js\";\nimport { finishFold, foldUpdate, startFold, type TurnFold } from \"./fold.js\";\nimport type { AppLink } from \"./link.js\";\nimport { logEvent } from \"./log.js\";\nimport type { McpProxy, ProxySession } from \"./mcp-proxy.js\";\nimport { appServerOf, computerName } from \"./naming.js\";\nimport { approvalFor, isAppTool, presenceDueAt, type RemotePolicy } from \"./policy.js\";\nimport type { LiveSession, SessionPool } from \"./pool.js\";\nimport type { LocalPrompter } from \"./prompter.js\";\nimport { agentEnvironment } from \"./shell-path.js\";\nimport type { TrustedDevice, TrustStore } from \"./trust.js\";\n\nexport interface TurnDeps {\n readonly link: AppLink;\n readonly profiles: readonly AgentProfile[];\n readonly launcher: AgentLauncher;\n readonly pool: SessionPool;\n readonly proxy: McpProxy;\n readonly trust: TrustStore;\n readonly policy: RemotePolicy;\n readonly prompter: LocalPrompter;\n readonly now: () => number;\n /** The secret the browser that approved this grant's `connect` proves, until it is used. */\n readonly pairing?: {\n secret(): Promise<string | undefined>;\n forget(): Promise<void>;\n };\n /** What the agent said about itself: the options a prompt may choose, or the account's allowance. */\n readonly learned?: (\n agentId: string,\n learned:\n | { readonly options: readonly AgentOption[] }\n | { readonly usage: AgentUsage },\n ) => void;\n}\n\nexport const PROMPT_MAX_AGE_MS = 10 * 60_000;\n/** A vouch is bound to one device's keys, so it may wait for that device's first prompt. */\nconst VOUCH_MAX_AGE_MS = 30 * 24 * 60 * 60_000;\n\nconst SIGNAL_POLL_MS = 500;\nconst MAX_APPEND_ITEMS = 64;\nconst APPEND_RETRY_BASE_MS = 250;\nconst APPEND_RETRY_MAX_MS = 4_000;\nconst MIN_LEASE_MS = 1_000;\nconst CANCEL_SETTLE_MS = 5_000;\nconst QUESTION_CHOICES = [\n { id: \"accept\", label: \"Submit\", effect: \"allow_once\" },\n { id: \"decline\", label: \"Decline\", effect: \"reject_once\" },\n] as const;\n\nclass AgentExited extends Error {\n override readonly name = \"AgentExited\";\n constructor(readonly exit: AgentExit) {\n super(\"The agent exited.\");\n }\n}\n\ninterface Pending {\n readonly ask: AgentAsk;\n readonly approval: ChatItemBody<\"ask\">[\"approval\"];\n readonly dialog: AbortController;\n readonly resolve: (answer: AgentAskAnswer) => void;\n}\n\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nclass LeaseLapsed extends Error {\n override readonly name = \"LeaseLapsed\";\n}\n\nfunction lapseAfter(ms: number) {\n let timer: NodeJS.Timeout | undefined;\n const lapsed = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new LeaseLapsed(\"The turn's lease lapsed.\")), ms);\n });\n lapsed.catch(() => undefined);\n return { lapsed, cancel: () => clearTimeout(timer) };\n}\n\nasync function settlesWithin(work: Promise<unknown>, ms: number): Promise<boolean> {\n let timer: NodeJS.Timeout | undefined;\n const late = new Promise<false>((resolve) => {\n timer = setTimeout(() => resolve(false), ms);\n });\n try {\n return await Promise.race([work.then(() => true as const), late]);\n } finally {\n clearTimeout(timer);\n }\n}\n\nfunction promptMaxAgeMs(): number {\n const lowered = Number(process.env.PARLOR_HOST_PROMPT_MAX_AGE_MS);\n return lowered > 0 ? Math.min(lowered, PROMPT_MAX_AGE_MS) : PROMPT_MAX_AGE_MS;\n}\n\nconst hex = async (bytes: Uint8Array) =>\n [...new Uint8Array(await crypto.subtle.digest(\"SHA-256\", new Uint8Array(bytes)))]\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n\nconst fingerprint = (device: Pick<PinnedDevice, \"signingKey\" | \"presenceKey\">) =>\n encodeBase64url(\n canonicalBytes({ signing: device.signingKey, presence: device.presenceKey ?? null }),\n );\n\nfunction exitDetail(exit: AgentExit): string {\n if (exit.kind === \"killed\") return \"stopped by this computer\";\n const last = exit.stderrTail.trim().split(\"\\n\").at(-1)?.slice(0, 300);\n return [`exit code ${exit.code ?? \"none\"}`, last].filter(Boolean).join(\": \");\n}\n\nfunction askBody(ask: AgentAsk, approval: ChatItemBody<\"ask\">[\"approval\"]) {\n const body: ChatItemBody<\"ask\"> =\n ask.kind === \"permission\"\n ? {\n question: ask.title,\n choices: ask.options.map((option) => ({ ...option })),\n }\n : {\n question: ask.message,\n choices: QUESTION_CHOICES.map((choice) => ({ ...choice })),\n form: { ...ask.schema },\n };\n return approval ? { ...body, approval } : body;\n}\n\nfunction answerOf(\n pending: Pending,\n body: Extract<TurnSignals[\"items\"][number], { kind: \"answer\" }>[\"body\"],\n): AgentAskAnswer | undefined {\n if (pending.ask.kind === \"question\") {\n if (body.choice === \"accept\") return { kind: \"values\", values: { ...body.values } };\n return { kind: \"declined\" };\n }\n if (body.choice === \"declined\") return { kind: \"declined\" };\n return pending.ask.options.some((option) => option.id === body.choice)\n ? { kind: \"selected\", optionId: body.choice }\n : undefined;\n}\n\n/**\n * Runs one claimed turn to its outcome and reports it with `hostFinish`: where the\n * claimed prompt, the agent's updates, the user's answers and stop, and the local policy meet.\n */\nexport async function runTurn(\n claimed: ClaimedTurn,\n deps: TurnDeps,\n): Promise<TurnOutcome> {\n const { link, pool } = deps;\n const { calls } = link.api;\n const grant = link.grant;\n const origin = grant.appOrigin;\n const appServer = appServerOf(grant.appName);\n const agentId = claimed.agent.agentId;\n const threadId = claimed.id;\n const turnId = claimed.turnId;\n\n let fold: TurnFold = startFold(turnId);\n let proxy: ProxySession | undefined;\n let lost = false;\n const lostOver = new AbortController();\n const markLost = () => {\n lost = true;\n lostOver.abort();\n };\n const lostPromise = new Promise<\"lost\">((resolve) =>\n lostOver.signal.addEventListener(\"abort\", () => resolve(\"lost\"), { once: true }),\n );\n const leaseMs = Math.max(MIN_LEASE_MS, claimed.leaseUntil - deps.now());\n let cancelled = false;\n let lastWrite = deps.now();\n let appending: Promise<void> = Promise.resolve();\n const pending = new Map<ItemId, Pending>();\n\n const settle = (id: ItemId, answer: AgentAskAnswer) => {\n const waiting = pending.get(id);\n if (!waiting) return;\n pending.delete(id);\n waiting.dialog.abort();\n waiting.resolve(answer);\n };\n const settleAll = () => {\n for (const id of [...pending.keys()]) settle(id, { kind: \"cancelled\" });\n };\n\n const nextId = (): ItemId => {\n const id = asId(\"item\", `${turnId}.${fold.nextId}`);\n fold = { ...fold, nextId: fold.nextId + 1 };\n return id;\n };\n\n const untilLeaseLapses = async <T>(call: () => Promise<T>): Promise<T> => {\n const lease = lapseAfter(leaseMs);\n try {\n for (let attempt = 0; ; attempt += 1) {\n try {\n return await Promise.race([call(), lease.lapsed]);\n } catch (error) {\n if (error instanceof ActionError || error instanceof LeaseLapsed) throw error;\n await Promise.race([\n sleep(Math.min(APPEND_RETRY_BASE_MS * 2 ** attempt, APPEND_RETRY_MAX_MS)),\n lease.lapsed,\n ]);\n }\n }\n } finally {\n lease.cancel();\n }\n };\n\n const send = async (items: HostItemDraft[]) => {\n const renewed = await untilLeaseLapses(() =>\n calls.call(\"hostAppend\", { turnId, items }),\n );\n lastWrite = deps.now();\n proxy?.renew(renewed.token);\n logEvent(\"host_append\", { turnId, itemIds: items.map((item) => item.id) });\n };\n\n const write = (items: readonly HostItemDraft[]) => {\n const batch = [...items];\n appending = appending.then(async () => {\n if (lost) return;\n try {\n if (batch.length === 0) {\n await send([]);\n return;\n }\n for (let at = 0; at < batch.length; at += MAX_APPEND_ITEMS) {\n await send(batch.slice(at, at + MAX_APPEND_ITEMS));\n }\n } catch {\n markLost();\n }\n });\n return appending;\n };\n\n const event = (name: ChatEvent, detail?: string, itemId?: ItemId) =>\n write([\n {\n id: nextId(),\n kind: \"event\",\n body: {\n event: name,\n ...(detail ? { detail: detail.slice(0, 500) } : {}),\n ...(itemId ? { itemId } : {}),\n },\n },\n ]);\n\n const finish = async (outcome: TurnOutcome): Promise<TurnOutcome> => {\n await appending;\n proxy?.end();\n if (lost) return { state: \"failed\", reason: \"host_lost\" };\n try {\n await untilLeaseLapses(() => calls.call(\"hostFinish\", { turnId, outcome }));\n } catch (error) {\n if (error instanceof LeaseLapsed) return { state: \"failed\", reason: \"host_lost\" };\n if (!(error instanceof ActionError && error.code === \"forbidden\")) throw error;\n }\n return outcome;\n };\n\n const fail = async (reason: TurnFailure, name: ChatEvent, detail?: string) => {\n await event(name, detail);\n return finish({ state: \"failed\", reason });\n };\n\n const verifyPrompt = async (\n signed: NonNullable<Awaited<ReturnType<typeof signedPrompt>>>,\n pinned: PinnedDevice,\n requirePresence: boolean,\n ): Promise<VerifyOutcome> => {\n const outcome = await verifyStatement(signed, pinned, {\n requirePresence,\n now: deps.now(),\n maxAgeMs: promptMaxAgeMs(),\n });\n logEvent(\"statement_verified\", {\n kind: \"prompt\",\n deviceId: pinned.deviceId,\n outcome,\n sha256: await hex(statementBytes(signed.statement)),\n });\n return outcome;\n };\n\n type Admission = { readonly device: TrustedDevice } | { readonly outcome: TurnOutcome };\n\n const refuse = async (\n reason: TurnFailure,\n name: ChatEvent,\n detail?: string,\n ): Promise<Admission> => ({ outcome: await fail(reason, name, detail) });\n\n /** A vouch counts when a device pinned here signed it with presence, for exactly these keys. */\n const vouchedFor = async (keys: DeviceKeys): Promise<TrustedDevice | undefined> => {\n if (!keys.vouches?.length) return undefined;\n const commitment = await deviceCommitment(\n origin,\n keys.id,\n keys.signingKey,\n keys.presenceKey?.publicKey,\n );\n for (const vouch of keys.vouches) {\n if (vouch.commitment !== commitment) continue;\n const voucher = await deps.trust.get(origin, vouch.voucher);\n if (!voucher?.presenceKey) continue;\n const outcome = await verifyStatement(\n {\n statement: vouchStatement(origin, vouch.voucher, keys.id, commitment, vouch.at),\n deviceId: voucher.deviceId,\n signature: vouch.signature as PresenceSignature,\n },\n voucher,\n { requirePresence: true, now: deps.now(), maxAgeMs: VOUCH_MAX_AGE_MS },\n );\n logEvent(\"vouch_verified\", { deviceId: keys.id, voucher: vouch.voucher, outcome });\n if (outcome !== \"valid\") continue;\n return {\n deviceId: keys.id,\n signingKey: keys.signingKey,\n presenceKey: keys.presenceKey,\n name: keys.name,\n platform: keys.platform,\n approvedAt: deps.now(),\n via: \"vouched\",\n voucher: vouch.voucher,\n };\n }\n return undefined;\n };\n\n const pinVouched = async (device: TrustedDevice) => {\n await deps.trust.pin(origin, device);\n logEvent(\"device_trusted\", { deviceId: device.deviceId, via: \"vouched\" });\n deps.prompter.deviceLinked?.({\n appName: grant.appName,\n device: device.name ?? \"A device\",\n });\n };\n\n /** Moves the device's last presence check forward; reported so its devices know when the next is due. */\n const confirmedPresence = async (device: TrustedDevice, at: number) => {\n if (at <= (device.presenceAt ?? device.approvedAt)) return;\n await deps.trust.pin(origin, { ...device, presenceAt: at });\n };\n\n const unlinked = `Link this device to use your agents on ${computerName()}: open the Agent sidebar on it.`;\n\n const admit = async (): Promise<Admission> => {\n const signed = await signedPrompt(origin, claimed.prompt);\n if (!signed) {\n return refuse(\n \"device_rejected\",\n \"turn_failed\",\n `Update ${grant.appName} to send messages to ${computerName()}: this version does not sign them.`,\n );\n }\n const known = await deps.trust.get(origin, signed.deviceId);\n const keys = claimed.device;\n if (known && !keys) {\n await deps.trust.forget(origin, known.deviceId);\n return refuse(\n \"device_rejected\",\n \"device_rejected\",\n \"This device is no longer registered.\",\n );\n }\n if (!keys || keys.id !== signed.deviceId) {\n return refuse(\n \"signature_invalid\",\n \"turn_failed\",\n \"The account has no such device.\",\n );\n }\n if (known && fingerprint(known) !== fingerprint(keys)) {\n return refuse(\"signature_invalid\", \"turn_failed\", \"This device's keys changed.\");\n }\n const pinned: PinnedDevice = known ?? {\n deviceId: keys.id,\n signingKey: keys.signingKey,\n presenceKey: keys.presenceKey,\n };\n const due = known && presenceDueAt(deps.policy, known);\n const outcome = await verifyPrompt(\n signed,\n pinned,\n due !== undefined && signed.statement.at > due,\n );\n if (outcome === \"stale\") {\n return { outcome: await finish({ state: \"failed\", reason: \"prompt_expired\" }) };\n }\n if (outcome === \"presence_required\") {\n return refuse(\n \"device_rejected\",\n \"turn_failed\",\n `Confirm it's you to keep using your agents on ${computerName()} from this device: send again and use Face ID or Touch ID.`,\n );\n }\n if (outcome !== \"valid\") {\n return refuse(\n \"signature_invalid\",\n \"turn_failed\",\n \"This prompt's signature did not check out.\",\n );\n }\n if (known) {\n if (signed.signature.presence === \"user\") {\n await confirmedPresence(known, signed.statement.at);\n }\n return { device: known };\n }\n const proof = claimed.prompt.body.signed?.pairing;\n const secret = proof ? await deps.pairing?.secret() : undefined;\n if (\n proof &&\n secret &&\n (await checkPairingProof(secret, proof, keys.id, keys.signingKey))\n ) {\n const device: TrustedDevice = {\n ...pinned,\n name: keys.name,\n platform: keys.platform,\n approvedAt: deps.now(),\n via: \"pairing\",\n };\n await deps.trust.pin(origin, device);\n await deps.pairing?.forget();\n logEvent(\"device_trusted\", { deviceId: keys.id, via: \"pairing\" });\n return { device };\n }\n const vouched = await vouchedFor(keys);\n if (vouched) {\n await pinVouched(vouched);\n return { device: vouched };\n }\n return refuse(\"device_rejected\", \"device_rejected\", unlinked);\n };\n\n const proceed = async (device: TrustedDevice | undefined): Promise<TurnOutcome> => {\n const profile = deps.profiles.find((candidate) => candidate.id === agentId);\n if (!profile) {\n return fail(\n \"agent_unavailable\",\n \"turn_failed\",\n `This computer has no agent \"${agentId}\".`,\n );\n }\n\n let live: LiveSession | undefined = pool.session(grant, threadId, agentId);\n let connection: AgentConnection | undefined = pool.process(origin, agentId);\n const fresh = live === undefined;\n if (live) {\n proxy = live.proxy;\n proxy.begin(claimed.token);\n } else {\n const switched = deps.profiles.some(\n (other) =>\n other.id !== agentId && pool.session(grant, threadId, other.id) !== undefined,\n );\n if (switched) await event(\"agent_switched\", profile.name);\n try {\n connection = await pool.launch(origin, agentId, async (signal) => {\n await mkdir(grant.workspace, { recursive: true, mode: 0o700 });\n return deps.launcher.launch(profile, {\n cwd: grant.workspace,\n env: await agentEnvironment(),\n signal,\n });\n });\n proxy = deps.proxy.open(appServer, origin);\n proxy.begin(claimed.token);\n const session: AgentSession = await connection.openSession({\n cwd: grant.workspace,\n mcpServers: [proxy.server],\n resume: await pool.resumable(grant, threadId, agentId),\n pinAskMode: true,\n strictAsk: deps.policy.answers !== \"off\",\n autoMode: deps.policy.agentMode !== \"ask\",\n });\n live = { session, proxy };\n pool.remember(grant, threadId, agentId, live);\n } catch (error) {\n proxy?.dispose();\n proxy = undefined;\n if (error instanceof SessionRefused && error.leftOpen) {\n await pool.drop(origin, agentId);\n }\n const message = error instanceof Error ? error.message : String(error);\n return fail(\"agent_unavailable\", \"turn_failed\", message);\n }\n }\n\n const { session } = live;\n deps.learned?.(agentId, { options: session.options });\n for (const change of optionChanges(session.options, claimed.prompt.body.options)) {\n await session.setOption(change.id, change.value).catch((error: unknown) => {\n logEvent(\"option_refused\", { agentId, option: change.id, error: String(error) });\n });\n }\n const exited = connection!.exited.then((exit) => {\n throw new AgentExited(exit);\n });\n exited.catch(() => undefined);\n\n const text = claimed.prompt.body.text;\n const blocks = [\n {\n kind: \"text\" as const,\n text: fresh && !session.resumed ? `${claimed.context}\\n\\n${text}` : text,\n },\n ];\n const fromThisComputer = grant.dev === true || device?.via === \"pairing\";\n if (!fromThisComputer) {\n deps.prompter.turnStarted({\n appName: grant.appName,\n device: device?.name ?? claimed.device?.name ?? \"the app\",\n agent: profile.name,\n preview: text.slice(0, 80),\n });\n }\n\n const turnOver = new AbortController();\n const cancel = () => {\n if (cancelled) return;\n cancelled = true;\n void session.cancel();\n settleAll();\n turnOver.abort();\n };\n\n const ask = async (question: AgentAsk): Promise<AgentAskAnswer> => {\n if (cancelled) return { kind: \"cancelled\" };\n if (question.kind === \"permission\" && isAppTool(question, appServer)) {\n const allow = question.options.find((option) => option.effect === \"allow_once\");\n if (allow) return { kind: \"selected\", optionId: allow.id };\n }\n const approval = approvalFor(deps.policy, question, device);\n const id = nextId();\n const dialog = new AbortController();\n const answered = new Promise<AgentAskAnswer>((resolve) =>\n pending.set(id, { ask: question, approval, dialog, resolve }),\n );\n await write([{ id, kind: \"ask\", body: askBody(question, approval) }]);\n if (approval === \"computer\") {\n const choices =\n question.kind === \"permission\" ? question.options : QUESTION_CHOICES;\n void deps.prompter\n .answerHere({\n appName: grant.appName,\n agent: profile.name,\n question: question.kind === \"permission\" ? question.title : question.message,\n choices,\n signal: dialog.signal,\n })\n .then((choice) => {\n const waiting = pending.get(id);\n if (!waiting) return;\n const answer =\n choice === undefined ? undefined : answerOf(waiting, { askId: id, choice });\n if (choice !== undefined && answer) {\n void write([\n {\n id: nextId(),\n kind: \"event\",\n body: { event: \"answered_on_computer\", itemId: id, choice },\n },\n ]);\n }\n settle(id, answer ?? { kind: \"cancelled\" });\n });\n }\n return answered;\n };\n\n type Decided =\n | { readonly kind: \"accepted\" }\n | { readonly kind: \"rejected\"; readonly reason: string };\n type AnswerVerdict =\n | Decided\n | { readonly kind: \"unpinned\"; readonly device: DeviceKeys };\n\n const rejected = (reason: string): Decided => ({ kind: \"rejected\", reason });\n\n const verdictOf = async (\n waiting: Pending,\n item: LoggedItem<\"answer\">,\n devices: readonly DeviceKeys[],\n ): Promise<AnswerVerdict> => {\n if (waiting.approval === \"computer\") {\n return rejected(\"This question is answered on the computer.\");\n }\n if (\n waiting.approval === \"device\" &&\n item.body.signed?.deviceId !== device?.deviceId\n ) {\n return rejected(\"This question is answered on the device that asked it.\");\n }\n if (deps.policy.deviceApproval !== \"local\" && waiting.approval === undefined) {\n return { kind: \"accepted\" };\n }\n const { signed, askId, choice, values } = item.body;\n const pinned = signed ? await deps.trust.get(origin, signed.deviceId) : undefined;\n const listed = signed\n ? devices.find((keys) => keys.id === signed.deviceId)\n : undefined;\n const known: PinnedDevice | undefined =\n pinned ??\n (listed && {\n deviceId: listed.id,\n signingKey: listed.signingKey,\n presenceKey: listed.presenceKey,\n });\n if (!signed || !known) {\n logEvent(\"statement_verified\", {\n kind: \"answer\",\n deviceId: signed?.deviceId,\n outcome: \"invalid\",\n });\n return rejected(\"This device cannot answer here.\");\n }\n const statement = await answerStatement(\n origin,\n { threadId: item.threadId, askId, choice, ...(values ? { values } : {}) },\n signed.at,\n );\n const outcome = await verifyStatement(\n { statement, deviceId: signed.deviceId, signature: signed.signature },\n known,\n {\n requirePresence: waiting.approval === \"presence\",\n now: deps.now(),\n maxAgeMs: PROMPT_MAX_AGE_MS,\n },\n );\n logEvent(\"statement_verified\", {\n kind: \"answer\",\n deviceId: signed.deviceId,\n outcome,\n sha256: await hex(statementBytes(statement)),\n });\n if (outcome === \"presence_required\") {\n return rejected(\"This answer needs a presence check.\");\n }\n if (outcome !== \"valid\")\n return rejected(\"This answer's signature did not check out.\");\n if (pinned && signed.signature.presence === \"user\") {\n await confirmedPresence(pinned, signed.at);\n }\n return pinned || !listed\n ? { kind: \"accepted\" }\n : { kind: \"unpinned\", device: listed };\n };\n\n const deliver = (waiting: Pending, item: LoggedItem<\"answer\">, verdict: Decided) => {\n const answer =\n verdict.kind === \"accepted\" ? answerOf(waiting, item.body) : undefined;\n if (!answer) {\n void event(\n \"answer_rejected\",\n verdict.kind === \"rejected\"\n ? verdict.reason\n : \"That is not one of the choices.\",\n item.id,\n );\n return;\n }\n settle(item.body.askId, answer);\n };\n\n const admitAnswer = async (\n waiting: Pending,\n item: LoggedItem<\"answer\">,\n devices: readonly DeviceKeys[],\n ) => {\n const verdict = await verdictOf(waiting, item, devices);\n if (verdict.kind !== \"unpinned\") {\n deliver(waiting, item, verdict);\n return;\n }\n const vouched = await vouchedFor(verdict.device);\n if (!vouched) {\n deliver(waiting, item, rejected(unlinked));\n return;\n }\n await pinVouched(vouched);\n deliver(waiting, item, { kind: \"accepted\" });\n };\n\n let afterSeq = claimed.prompt.seq;\n const signalsOver = new AbortController();\n const signalsEnded = new Promise<\"ended\">((resolve) =>\n signalsOver.signal.addEventListener(\"abort\", () => resolve(\"ended\"), {\n once: true,\n }),\n );\n const signals = async () => {\n for (;;) {\n if ((await Promise.race([sleep(SIGNAL_POLL_MS), signalsEnded])) === \"ended\")\n return;\n let batches: TurnSignals[];\n try {\n const fetched = await Promise.race([\n calls.call(\"hostSignals\", { turns: [{ turnId, afterSeq }] }),\n signalsEnded,\n ]);\n if (fetched === \"ended\") return;\n batches = fetched;\n } catch {\n continue;\n }\n for (const batch of batches) {\n for (const item of batch.items) {\n if (signalsOver.signal.aborted) return;\n afterSeq = Math.max(afterSeq, item.seq);\n if (item.kind === \"cancel\") {\n cancel();\n continue;\n }\n const waiting = pending.get(item.body.askId);\n if (waiting) await admitAnswer(waiting, item, batch.devices ?? []);\n }\n }\n }\n };\n\n let stop: StopReason | \"lost\" | undefined;\n let failure: AgentExited | Error | undefined;\n const prompted = session.prompt(blocks, {\n update: (update) => {\n if (update.kind === \"usage\") deps.learned?.(agentId, { usage: update.usage });\n const step = foldUpdate(fold, update, appServer);\n fold = step.fold;\n if (step.frames.length > 0) link.api.stream({ turnId, frames: step.frames });\n if (step.closed.length > 0) void write(step.closed);\n },\n ask,\n });\n prompted.catch(() => undefined);\n const signalsRan = signals().catch(() => undefined);\n try {\n stop = await Promise.race([prompted, exited, lostPromise]);\n if (stop === \"lost\") {\n signalsOver.abort();\n proxy?.end();\n const settled = await settlesWithin(\n Promise.allSettled([session.cancel(), prompted]),\n CANCEL_SETTLE_MS,\n );\n if (!settled) await pool.drop(origin, agentId);\n }\n } catch (error) {\n failure =\n error instanceof AgentExited\n ? error\n : await Promise.race([\n exited.catch((exit: unknown) => exit as AgentExited),\n sleep(1_000).then(() =>\n error instanceof Error ? error : new Error(String(error)),\n ),\n ]);\n } finally {\n signalsOver.abort();\n settleAll();\n turnOver.abort();\n }\n await signalsRan;\n\n const stopped = failure !== undefined || cancelled || stop === \"cancelled\";\n const final = finishFold(fold, stopped);\n fold = final.fold;\n void write(final.closed);\n\n if (failure) {\n await pool.drop(origin, agentId);\n const detail =\n failure instanceof AgentExited ? exitDetail(failure.exit) : failure.message;\n return fail(\"agent_exited\", \"agent_exited\", detail);\n }\n if (lost) {\n proxy?.end();\n return { state: \"failed\", reason: \"host_lost\" };\n }\n return finish(\n stopped\n ? { state: \"cancelled\" }\n : { state: \"done\", stopReason: stop as StopReason },\n );\n };\n\n const renewEveryMs = Math.max(1_000, (claimed.leaseUntil - deps.now()) / 2);\n const renewal = setInterval(() => {\n if (deps.now() - lastWrite >= renewEveryMs) void write([]);\n }, renewEveryMs / 4);\n try {\n if (deps.policy.deviceApproval === \"local\") {\n const admission = await admit();\n if (\"outcome\" in admission) return admission.outcome;\n return await proceed(admission.device);\n }\n return await proceed(undefined);\n } finally {\n clearInterval(renewal);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"turn.js","sourceRoot":"","sources":["../src/turn.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n answerStatement,\n checkPairingProof,\n deviceCommitment,\n vouchStatement,\n type PinnedDevice,\n signedPrompt,\n statementBytes,\n verifyStatement,\n type VerifyOutcome,\n} from \"@parlor/auth\";\nimport type { PresenceSignature } from \"@parlor/capabilities\";\nimport { canonicalBytes, encodeBase64url } from \"@parlor/capabilities/encoding\";\nimport type {\n AgentOption,\n AgentUsage,\n ChatEvent,\n ChatItemBody,\n ClaimedTurn,\n HostItemDraft,\n LoggedItem,\n TurnFailure,\n TurnOutcome,\n TurnSignals,\n} from \"@parlor/chat\";\nimport { ActionError, asId, type ItemId } from \"@parlor/core\";\nimport type { DeviceKeys } from \"@parlor/server\";\n\nimport {\n type AgentAsk,\n type AgentAskAnswer,\n type AgentConnection,\n type AgentExit,\n type AgentLauncher,\n type AgentSession,\n SessionRefused,\n type StopReason,\n} from \"./acp.js\";\nimport { optionChanges } from \"./agent-options.js\";\nimport type { AgentProfile } from \"./agents.js\";\nimport { finishFold, foldUpdate, startFold, type TurnFold } from \"./fold.js\";\nimport type { AppLink } from \"./link.js\";\nimport { logEvent } from \"./log.js\";\nimport type { McpProxy, ProxySession } from \"./mcp-proxy.js\";\nimport { appServerOf, computerName } from \"./naming.js\";\nimport { approvalFor, isAppTool, presenceDueAt, type RemotePolicy } from \"./policy.js\";\nimport type { LiveSession, SessionPool } from \"./pool.js\";\nimport type { LocalPrompter } from \"./prompter.js\";\nimport type { TrustedDevice, TrustStore } from \"./trust.js\";\nimport { launchAgent, sessionFit, sessionInput } from \"./warm.js\";\n\nexport interface TurnDeps {\n readonly link: AppLink;\n readonly profiles: readonly AgentProfile[];\n readonly launcher: AgentLauncher;\n readonly pool: SessionPool;\n readonly proxy: McpProxy;\n readonly trust: TrustStore;\n readonly policy: RemotePolicy;\n readonly prompter: LocalPrompter;\n readonly now: () => number;\n /** The secret the browser that approved this grant's `connect` proves, until it is used. */\n readonly pairing?: {\n secret(): Promise<string | undefined>;\n forget(): Promise<void>;\n };\n /** What the agent said about itself: the options a prompt may choose, or the account's allowance. */\n readonly learned?: (\n agentId: string,\n learned:\n | { readonly options: readonly AgentOption[] }\n | { readonly usage: AgentUsage },\n ) => void;\n}\n\nexport const PROMPT_MAX_AGE_MS = 10 * 60_000;\n/** A vouch is bound to one device's keys, so it may wait for that device's first prompt. */\nconst VOUCH_MAX_AGE_MS = 30 * 24 * 60 * 60_000;\n\nconst SIGNAL_POLL_MS = 500;\nconst MAX_APPEND_ITEMS = 64;\nconst APPEND_RETRY_BASE_MS = 250;\nconst APPEND_RETRY_MAX_MS = 4_000;\nconst MIN_LEASE_MS = 1_000;\nconst CANCEL_SETTLE_MS = 5_000;\nconst QUESTION_CHOICES = [\n { id: \"accept\", label: \"Submit\", effect: \"allow_once\" },\n { id: \"decline\", label: \"Decline\", effect: \"reject_once\" },\n] as const;\n\nclass AgentExited extends Error {\n override readonly name = \"AgentExited\";\n constructor(readonly exit: AgentExit) {\n super(\"The agent exited.\");\n }\n}\n\ninterface Pending {\n readonly ask: AgentAsk;\n readonly approval: ChatItemBody<\"ask\">[\"approval\"];\n readonly dialog: AbortController;\n readonly resolve: (answer: AgentAskAnswer) => void;\n}\n\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nclass LeaseLapsed extends Error {\n override readonly name = \"LeaseLapsed\";\n}\n\nfunction lapseAfter(ms: number) {\n let timer: NodeJS.Timeout | undefined;\n const lapsed = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new LeaseLapsed(\"The turn's lease lapsed.\")), ms);\n });\n lapsed.catch(() => undefined);\n return { lapsed, cancel: () => clearTimeout(timer) };\n}\n\nasync function settlesWithin(work: Promise<unknown>, ms: number): Promise<boolean> {\n let timer: NodeJS.Timeout | undefined;\n const late = new Promise<false>((resolve) => {\n timer = setTimeout(() => resolve(false), ms);\n });\n try {\n return await Promise.race([work.then(() => true as const), late]);\n } finally {\n clearTimeout(timer);\n }\n}\n\nfunction promptMaxAgeMs(): number {\n const lowered = Number(process.env.PARLOR_HOST_PROMPT_MAX_AGE_MS);\n return lowered > 0 ? Math.min(lowered, PROMPT_MAX_AGE_MS) : PROMPT_MAX_AGE_MS;\n}\n\nconst hex = async (bytes: Uint8Array) =>\n [...new Uint8Array(await crypto.subtle.digest(\"SHA-256\", new Uint8Array(bytes)))]\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n\nconst fingerprint = (device: Pick<PinnedDevice, \"signingKey\" | \"presenceKey\">) =>\n encodeBase64url(\n canonicalBytes({ signing: device.signingKey, presence: device.presenceKey ?? null }),\n );\n\nfunction exitDetail(exit: AgentExit): string {\n if (exit.kind === \"killed\") return \"stopped by this computer\";\n const last = exit.stderrTail.trim().split(\"\\n\").at(-1)?.slice(0, 300);\n return [`exit code ${exit.code ?? \"none\"}`, last].filter(Boolean).join(\": \");\n}\n\nfunction askBody(ask: AgentAsk, approval: ChatItemBody<\"ask\">[\"approval\"]) {\n const body: ChatItemBody<\"ask\"> =\n ask.kind === \"permission\"\n ? {\n question: ask.title,\n choices: ask.options.map((option) => ({ ...option })),\n }\n : {\n question: ask.message,\n choices: QUESTION_CHOICES.map((choice) => ({ ...choice })),\n form: { ...ask.schema },\n };\n return approval ? { ...body, approval } : body;\n}\n\nfunction answerOf(\n pending: Pending,\n body: Extract<TurnSignals[\"items\"][number], { kind: \"answer\" }>[\"body\"],\n): AgentAskAnswer | undefined {\n if (pending.ask.kind === \"question\") {\n if (body.choice === \"accept\") return { kind: \"values\", values: { ...body.values } };\n return { kind: \"declined\" };\n }\n if (body.choice === \"declined\") return { kind: \"declined\" };\n return pending.ask.options.some((option) => option.id === body.choice)\n ? { kind: \"selected\", optionId: body.choice }\n : undefined;\n}\n\n/**\n * Runs one claimed turn to its outcome and reports it with `hostFinish`: where the\n * claimed prompt, the agent's updates, the user's answers and stop, and the local policy meet.\n */\nexport async function runTurn(\n claimed: ClaimedTurn,\n deps: TurnDeps,\n): Promise<TurnOutcome> {\n const { link, pool } = deps;\n const { calls } = link.api;\n const grant = link.grant;\n const origin = grant.appOrigin;\n const appServer = appServerOf(grant.appName);\n const agentId = claimed.agent.agentId;\n const threadId = claimed.id;\n const turnId = claimed.turnId;\n\n let fold: TurnFold = startFold(turnId);\n let proxy: ProxySession | undefined;\n let lost = false;\n const lostOver = new AbortController();\n const markLost = () => {\n lost = true;\n lostOver.abort();\n };\n const lostPromise = new Promise<\"lost\">((resolve) =>\n lostOver.signal.addEventListener(\"abort\", () => resolve(\"lost\"), { once: true }),\n );\n const leaseMs = Math.max(MIN_LEASE_MS, claimed.leaseUntil - deps.now());\n let cancelled = false;\n let lastWrite = deps.now();\n let appending: Promise<void> = Promise.resolve();\n const pending = new Map<ItemId, Pending>();\n\n const settle = (id: ItemId, answer: AgentAskAnswer) => {\n const waiting = pending.get(id);\n if (!waiting) return;\n pending.delete(id);\n waiting.dialog.abort();\n waiting.resolve(answer);\n };\n const settleAll = () => {\n for (const id of [...pending.keys()]) settle(id, { kind: \"cancelled\" });\n };\n\n const nextId = (): ItemId => {\n const id = asId(\"item\", `${turnId}.${fold.nextId}`);\n fold = { ...fold, nextId: fold.nextId + 1 };\n return id;\n };\n\n const untilLeaseLapses = async <T>(call: () => Promise<T>): Promise<T> => {\n const lease = lapseAfter(leaseMs);\n try {\n for (let attempt = 0; ; attempt += 1) {\n try {\n return await Promise.race([call(), lease.lapsed]);\n } catch (error) {\n if (error instanceof ActionError || error instanceof LeaseLapsed) throw error;\n await Promise.race([\n sleep(Math.min(APPEND_RETRY_BASE_MS * 2 ** attempt, APPEND_RETRY_MAX_MS)),\n lease.lapsed,\n ]);\n }\n }\n } finally {\n lease.cancel();\n }\n };\n\n const send = async (items: HostItemDraft[]) => {\n const renewed = await untilLeaseLapses(() =>\n calls.call(\"hostAppend\", { turnId, items }),\n );\n lastWrite = deps.now();\n proxy?.renew(renewed.token);\n logEvent(\"host_append\", { turnId, itemIds: items.map((item) => item.id) });\n };\n\n const write = (items: readonly HostItemDraft[]) => {\n const batch = [...items];\n appending = appending.then(async () => {\n if (lost) return;\n try {\n if (batch.length === 0) {\n await send([]);\n return;\n }\n for (let at = 0; at < batch.length; at += MAX_APPEND_ITEMS) {\n await send(batch.slice(at, at + MAX_APPEND_ITEMS));\n }\n } catch {\n markLost();\n }\n });\n return appending;\n };\n\n const event = (name: ChatEvent, detail?: string, itemId?: ItemId) =>\n write([\n {\n id: nextId(),\n kind: \"event\",\n body: {\n event: name,\n ...(detail ? { detail: detail.slice(0, 500) } : {}),\n ...(itemId ? { itemId } : {}),\n },\n },\n ]);\n\n const finish = async (outcome: TurnOutcome): Promise<TurnOutcome> => {\n await appending;\n proxy?.end();\n if (lost) return { state: \"failed\", reason: \"host_lost\" };\n try {\n await untilLeaseLapses(() => calls.call(\"hostFinish\", { turnId, outcome }));\n } catch (error) {\n if (error instanceof LeaseLapsed) return { state: \"failed\", reason: \"host_lost\" };\n if (!(error instanceof ActionError && error.code === \"forbidden\")) throw error;\n }\n return outcome;\n };\n\n const fail = async (reason: TurnFailure, name: ChatEvent, detail?: string) => {\n await event(name, detail);\n return finish({ state: \"failed\", reason });\n };\n\n const verifyPrompt = async (\n signed: NonNullable<Awaited<ReturnType<typeof signedPrompt>>>,\n pinned: PinnedDevice,\n requirePresence: boolean,\n ): Promise<VerifyOutcome> => {\n const outcome = await verifyStatement(signed, pinned, {\n requirePresence,\n now: deps.now(),\n maxAgeMs: promptMaxAgeMs(),\n });\n logEvent(\"statement_verified\", {\n kind: \"prompt\",\n deviceId: pinned.deviceId,\n outcome,\n sha256: await hex(statementBytes(signed.statement)),\n });\n return outcome;\n };\n\n type Admission = { readonly device: TrustedDevice } | { readonly outcome: TurnOutcome };\n\n const refuse = async (\n reason: TurnFailure,\n name: ChatEvent,\n detail?: string,\n ): Promise<Admission> => ({ outcome: await fail(reason, name, detail) });\n\n /** A vouch counts when a device pinned here signed it with presence, for exactly these keys. */\n const vouchedFor = async (keys: DeviceKeys): Promise<TrustedDevice | undefined> => {\n if (!keys.vouches?.length) return undefined;\n const commitment = await deviceCommitment(\n origin,\n keys.id,\n keys.signingKey,\n keys.presenceKey?.publicKey,\n );\n for (const vouch of keys.vouches) {\n if (vouch.commitment !== commitment) continue;\n const voucher = await deps.trust.get(origin, vouch.voucher);\n if (!voucher?.presenceKey) continue;\n const outcome = await verifyStatement(\n {\n statement: vouchStatement(origin, vouch.voucher, keys.id, commitment, vouch.at),\n deviceId: voucher.deviceId,\n signature: vouch.signature as PresenceSignature,\n },\n voucher,\n { requirePresence: true, now: deps.now(), maxAgeMs: VOUCH_MAX_AGE_MS },\n );\n logEvent(\"vouch_verified\", { deviceId: keys.id, voucher: vouch.voucher, outcome });\n if (outcome !== \"valid\") continue;\n return {\n deviceId: keys.id,\n signingKey: keys.signingKey,\n presenceKey: keys.presenceKey,\n name: keys.name,\n platform: keys.platform,\n approvedAt: deps.now(),\n via: \"vouched\",\n voucher: vouch.voucher,\n };\n }\n return undefined;\n };\n\n const pinVouched = async (device: TrustedDevice) => {\n await deps.trust.pin(origin, device);\n logEvent(\"device_trusted\", { deviceId: device.deviceId, via: \"vouched\" });\n deps.prompter.deviceLinked?.({\n appName: grant.appName,\n device: device.name ?? \"A device\",\n });\n };\n\n /** Moves the device's last presence check forward; reported so its devices know when the next is due. */\n const confirmedPresence = async (device: TrustedDevice, at: number) => {\n if (at <= (device.presenceAt ?? device.approvedAt)) return;\n await deps.trust.pin(origin, { ...device, presenceAt: at });\n };\n\n const unlinked = `Link this device to use your agents on ${computerName()}: open the Agent sidebar on it.`;\n\n const admit = async (): Promise<Admission> => {\n const signed = await signedPrompt(origin, claimed.prompt);\n if (!signed) {\n return refuse(\n \"device_rejected\",\n \"turn_failed\",\n `Update ${grant.appName} to send messages to ${computerName()}: this version does not sign them.`,\n );\n }\n const known = await deps.trust.get(origin, signed.deviceId);\n const keys = claimed.device;\n if (known && !keys) {\n await deps.trust.forget(origin, known.deviceId);\n return refuse(\n \"device_rejected\",\n \"device_rejected\",\n \"This device is no longer registered.\",\n );\n }\n if (!keys || keys.id !== signed.deviceId) {\n return refuse(\n \"signature_invalid\",\n \"turn_failed\",\n \"The account has no such device.\",\n );\n }\n if (known && fingerprint(known) !== fingerprint(keys)) {\n return refuse(\"signature_invalid\", \"turn_failed\", \"This device's keys changed.\");\n }\n const pinned: PinnedDevice = known ?? {\n deviceId: keys.id,\n signingKey: keys.signingKey,\n presenceKey: keys.presenceKey,\n };\n const due = known && presenceDueAt(deps.policy, known);\n const outcome = await verifyPrompt(\n signed,\n pinned,\n due !== undefined && signed.statement.at > due,\n );\n if (outcome === \"stale\") {\n return { outcome: await finish({ state: \"failed\", reason: \"prompt_expired\" }) };\n }\n if (outcome === \"presence_required\") {\n return refuse(\n \"device_rejected\",\n \"turn_failed\",\n `Confirm it's you to keep using your agents on ${computerName()} from this device: send again and use Face ID or Touch ID.`,\n );\n }\n if (outcome !== \"valid\") {\n return refuse(\n \"signature_invalid\",\n \"turn_failed\",\n \"This prompt's signature did not check out.\",\n );\n }\n if (known) {\n if (signed.signature.presence === \"user\") {\n await confirmedPresence(known, signed.statement.at);\n }\n return { device: known };\n }\n const proof = claimed.prompt.body.signed?.pairing;\n const secret = proof ? await deps.pairing?.secret() : undefined;\n if (\n proof &&\n secret &&\n (await checkPairingProof(secret, proof, keys.id, keys.signingKey))\n ) {\n const device: TrustedDevice = {\n ...pinned,\n name: keys.name,\n platform: keys.platform,\n approvedAt: deps.now(),\n via: \"pairing\",\n };\n await deps.trust.pin(origin, device);\n await deps.pairing?.forget();\n logEvent(\"device_trusted\", { deviceId: keys.id, via: \"pairing\" });\n return { device };\n }\n const vouched = await vouchedFor(keys);\n if (vouched) {\n await pinVouched(vouched);\n return { device: vouched };\n }\n return refuse(\"device_rejected\", \"device_rejected\", unlinked);\n };\n\n const proceed = async (device: TrustedDevice | undefined): Promise<TurnOutcome> => {\n const profile = deps.profiles.find((candidate) => candidate.id === agentId);\n if (!profile) {\n return fail(\n \"agent_unavailable\",\n \"turn_failed\",\n `This computer has no agent \"${agentId}\".`,\n );\n }\n\n let live: LiveSession | undefined = pool.session(grant, threadId, agentId);\n let connection: AgentConnection | undefined = pool.process(origin, agentId);\n const fresh = live === undefined;\n if (live) {\n proxy = live.proxy;\n proxy.begin(claimed.token);\n } else {\n const switched = deps.profiles.some(\n (other) =>\n other.id !== agentId && pool.session(grant, threadId, other.id) !== undefined,\n );\n if (switched) await event(\"agent_switched\", profile.name);\n try {\n connection = await launchAgent(pool, deps.launcher, profile, grant);\n const resume = await pool.resumable(grant, threadId, agentId);\n const warm =\n resume === undefined\n ? pool.takeWarm(grant, agentId, sessionFit(grant, deps.policy))\n : undefined;\n if (warm) {\n proxy = warm.proxy;\n proxy.begin(claimed.token);\n live = warm;\n } else {\n proxy = deps.proxy.open(appServer, origin);\n proxy.begin(claimed.token);\n const session: AgentSession = await connection.openSession(\n sessionInput(grant, deps.policy, proxy, resume),\n );\n live = { session, proxy };\n }\n pool.remember(grant, threadId, agentId, live);\n logEvent(\"session_opened\", {\n appOrigin: origin,\n agentId,\n warm: warm !== undefined,\n });\n } catch (error) {\n proxy?.dispose();\n proxy = undefined;\n if (error instanceof SessionRefused && error.leftOpen) {\n await pool.drop(origin, agentId);\n }\n const message = error instanceof Error ? error.message : String(error);\n return fail(\"agent_unavailable\", \"turn_failed\", message);\n }\n }\n\n const { session } = live;\n deps.learned?.(agentId, { options: session.options });\n for (const change of optionChanges(session.options, claimed.prompt.body.options)) {\n await session.setOption(change.id, change.value).catch((error: unknown) => {\n logEvent(\"option_refused\", { agentId, option: change.id, error: String(error) });\n });\n }\n const exited = connection!.exited.then((exit) => {\n throw new AgentExited(exit);\n });\n exited.catch(() => undefined);\n\n const text = claimed.prompt.body.text;\n const blocks = [\n {\n kind: \"text\" as const,\n text: fresh && !session.resumed ? `${claimed.context}\\n\\n${text}` : text,\n },\n ];\n const fromThisComputer = grant.dev === true || device?.via === \"pairing\";\n if (!fromThisComputer) {\n deps.prompter.turnStarted({\n appName: grant.appName,\n device: device?.name ?? claimed.device?.name ?? \"the app\",\n agent: profile.name,\n preview: text.slice(0, 80),\n });\n }\n\n const turnOver = new AbortController();\n const cancel = () => {\n if (cancelled) return;\n cancelled = true;\n void session.cancel();\n settleAll();\n turnOver.abort();\n };\n\n const ask = async (question: AgentAsk): Promise<AgentAskAnswer> => {\n if (cancelled) return { kind: \"cancelled\" };\n if (question.kind === \"permission\" && isAppTool(question, appServer)) {\n const allow = question.options.find((option) => option.effect === \"allow_once\");\n if (allow) return { kind: \"selected\", optionId: allow.id };\n }\n const approval = approvalFor(deps.policy, question, device);\n const id = nextId();\n const dialog = new AbortController();\n const answered = new Promise<AgentAskAnswer>((resolve) =>\n pending.set(id, { ask: question, approval, dialog, resolve }),\n );\n await write([{ id, kind: \"ask\", body: askBody(question, approval) }]);\n if (approval === \"computer\") {\n const choices =\n question.kind === \"permission\" ? question.options : QUESTION_CHOICES;\n void deps.prompter\n .answerHere({\n appName: grant.appName,\n agent: profile.name,\n question: question.kind === \"permission\" ? question.title : question.message,\n choices,\n signal: dialog.signal,\n })\n .then((choice) => {\n const waiting = pending.get(id);\n if (!waiting) return;\n const answer =\n choice === undefined ? undefined : answerOf(waiting, { askId: id, choice });\n if (choice !== undefined && answer) {\n void write([\n {\n id: nextId(),\n kind: \"event\",\n body: { event: \"answered_on_computer\", itemId: id, choice },\n },\n ]);\n }\n settle(id, answer ?? { kind: \"cancelled\" });\n });\n }\n return answered;\n };\n\n type Decided =\n | { readonly kind: \"accepted\" }\n | { readonly kind: \"rejected\"; readonly reason: string };\n type AnswerVerdict =\n | Decided\n | { readonly kind: \"unpinned\"; readonly device: DeviceKeys };\n\n const rejected = (reason: string): Decided => ({ kind: \"rejected\", reason });\n\n const verdictOf = async (\n waiting: Pending,\n item: LoggedItem<\"answer\">,\n devices: readonly DeviceKeys[],\n ): Promise<AnswerVerdict> => {\n if (waiting.approval === \"computer\") {\n return rejected(\"This question is answered on the computer.\");\n }\n if (\n waiting.approval === \"device\" &&\n item.body.signed?.deviceId !== device?.deviceId\n ) {\n return rejected(\"This question is answered on the device that asked it.\");\n }\n if (deps.policy.deviceApproval !== \"local\" && waiting.approval === undefined) {\n return { kind: \"accepted\" };\n }\n const { signed, askId, choice, values } = item.body;\n const pinned = signed ? await deps.trust.get(origin, signed.deviceId) : undefined;\n const listed = signed\n ? devices.find((keys) => keys.id === signed.deviceId)\n : undefined;\n const known: PinnedDevice | undefined =\n pinned ??\n (listed && {\n deviceId: listed.id,\n signingKey: listed.signingKey,\n presenceKey: listed.presenceKey,\n });\n if (!signed || !known) {\n logEvent(\"statement_verified\", {\n kind: \"answer\",\n deviceId: signed?.deviceId,\n outcome: \"invalid\",\n });\n return rejected(\"This device cannot answer here.\");\n }\n const statement = await answerStatement(\n origin,\n { threadId: item.threadId, askId, choice, ...(values ? { values } : {}) },\n signed.at,\n );\n const outcome = await verifyStatement(\n { statement, deviceId: signed.deviceId, signature: signed.signature },\n known,\n {\n requirePresence: waiting.approval === \"presence\",\n now: deps.now(),\n maxAgeMs: PROMPT_MAX_AGE_MS,\n },\n );\n logEvent(\"statement_verified\", {\n kind: \"answer\",\n deviceId: signed.deviceId,\n outcome,\n sha256: await hex(statementBytes(statement)),\n });\n if (outcome === \"presence_required\") {\n return rejected(\"This answer needs a presence check.\");\n }\n if (outcome !== \"valid\")\n return rejected(\"This answer's signature did not check out.\");\n if (pinned && signed.signature.presence === \"user\") {\n await confirmedPresence(pinned, signed.at);\n }\n return pinned || !listed\n ? { kind: \"accepted\" }\n : { kind: \"unpinned\", device: listed };\n };\n\n const deliver = (waiting: Pending, item: LoggedItem<\"answer\">, verdict: Decided) => {\n const answer =\n verdict.kind === \"accepted\" ? answerOf(waiting, item.body) : undefined;\n if (!answer) {\n void event(\n \"answer_rejected\",\n verdict.kind === \"rejected\"\n ? verdict.reason\n : \"That is not one of the choices.\",\n item.id,\n );\n return;\n }\n settle(item.body.askId, answer);\n };\n\n const admitAnswer = async (\n waiting: Pending,\n item: LoggedItem<\"answer\">,\n devices: readonly DeviceKeys[],\n ) => {\n const verdict = await verdictOf(waiting, item, devices);\n if (verdict.kind !== \"unpinned\") {\n deliver(waiting, item, verdict);\n return;\n }\n const vouched = await vouchedFor(verdict.device);\n if (!vouched) {\n deliver(waiting, item, rejected(unlinked));\n return;\n }\n await pinVouched(vouched);\n deliver(waiting, item, { kind: \"accepted\" });\n };\n\n let afterSeq = claimed.prompt.seq;\n const signalsOver = new AbortController();\n const signalsEnded = new Promise<\"ended\">((resolve) =>\n signalsOver.signal.addEventListener(\"abort\", () => resolve(\"ended\"), {\n once: true,\n }),\n );\n const signals = async () => {\n for (;;) {\n if ((await Promise.race([sleep(SIGNAL_POLL_MS), signalsEnded])) === \"ended\")\n return;\n let batches: TurnSignals[];\n try {\n const fetched = await Promise.race([\n calls.call(\"hostSignals\", { turns: [{ turnId, afterSeq }] }),\n signalsEnded,\n ]);\n if (fetched === \"ended\") return;\n batches = fetched;\n } catch {\n continue;\n }\n for (const batch of batches) {\n for (const item of batch.items) {\n if (signalsOver.signal.aborted) return;\n afterSeq = Math.max(afterSeq, item.seq);\n if (item.kind === \"cancel\") {\n cancel();\n continue;\n }\n const waiting = pending.get(item.body.askId);\n if (waiting) await admitAnswer(waiting, item, batch.devices ?? []);\n }\n }\n }\n };\n\n let stop: StopReason | \"lost\" | undefined;\n let failure: AgentExited | Error | undefined;\n const prompted = session.prompt(blocks, {\n update: (update) => {\n if (update.kind === \"usage\") deps.learned?.(agentId, { usage: update.usage });\n const step = foldUpdate(fold, update, appServer);\n fold = step.fold;\n if (step.frames.length > 0) link.api.stream({ turnId, frames: step.frames });\n if (step.closed.length > 0) void write(step.closed);\n },\n ask,\n });\n prompted.catch(() => undefined);\n const signalsRan = signals().catch(() => undefined);\n try {\n stop = await Promise.race([prompted, exited, lostPromise]);\n if (stop === \"lost\") {\n signalsOver.abort();\n proxy?.end();\n const settled = await settlesWithin(\n Promise.allSettled([session.cancel(), prompted]),\n CANCEL_SETTLE_MS,\n );\n if (!settled) await pool.drop(origin, agentId);\n }\n } catch (error) {\n failure =\n error instanceof AgentExited\n ? error\n : await Promise.race([\n exited.catch((exit: unknown) => exit as AgentExited),\n sleep(1_000).then(() =>\n error instanceof Error ? error : new Error(String(error)),\n ),\n ]);\n } finally {\n signalsOver.abort();\n settleAll();\n turnOver.abort();\n }\n await signalsRan;\n\n const stopped = failure !== undefined || cancelled || stop === \"cancelled\";\n const final = finishFold(fold, stopped);\n fold = final.fold;\n void write(final.closed);\n\n if (failure) {\n await pool.drop(origin, agentId);\n const detail =\n failure instanceof AgentExited ? exitDetail(failure.exit) : failure.message;\n return fail(\"agent_exited\", \"agent_exited\", detail);\n }\n if (lost) {\n proxy?.end();\n return { state: \"failed\", reason: \"host_lost\" };\n }\n return finish(\n stopped\n ? { state: \"cancelled\" }\n : { state: \"done\", stopReason: stop as StopReason },\n );\n };\n\n const renewEveryMs = Math.max(1_000, (claimed.leaseUntil - deps.now()) / 2);\n const renewal = setInterval(() => {\n if (deps.now() - lastWrite >= renewEveryMs) void write([]);\n }, renewEveryMs / 4);\n try {\n if (deps.policy.deviceApproval === \"local\") {\n const admission = await admit();\n if (\"outcome\" in admission) return admission.outcome;\n return await proceed(admission.device);\n }\n return await proceed(undefined);\n } finally {\n clearInterval(renewal);\n }\n}\n"]}
|
package/dist/warm.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type AgentConnection, type AgentLauncher, type OpenSessionInput } from "./acp.js";
|
|
2
|
+
import type { AgentProfile } from "./agents.js";
|
|
3
|
+
import type { AppGrant } from "./grants.js";
|
|
4
|
+
import type { AppLink } from "./link.js";
|
|
5
|
+
import type { McpProxy, ProxySession } from "./mcp-proxy.js";
|
|
6
|
+
import type { RemotePolicy } from "./policy.js";
|
|
7
|
+
import type { SessionPool } from "./pool.js";
|
|
8
|
+
export declare const WARM_IDLE_MS: number;
|
|
9
|
+
/** The app's agent process: the running one, or one started in the grant's workspace. */
|
|
10
|
+
export declare function launchAgent(pool: SessionPool, launcher: AgentLauncher, profile: AgentProfile, grant: AppGrant): Promise<AgentConnection>;
|
|
11
|
+
export declare function sessionInput(grant: AppGrant, policy: RemotePolicy, proxy: ProxySession, resume: string | undefined): OpenSessionInput;
|
|
12
|
+
/** What a session is opened under; a warm one opened under another is never a turn's. */
|
|
13
|
+
export declare function sessionFit(grant: AppGrant, policy: RemotePolicy): string;
|
|
14
|
+
export interface WarmDeps {
|
|
15
|
+
readonly link: AppLink;
|
|
16
|
+
readonly profiles: readonly AgentProfile[];
|
|
17
|
+
readonly launcher: AgentLauncher;
|
|
18
|
+
readonly pool: SessionPool;
|
|
19
|
+
readonly proxy: McpProxy;
|
|
20
|
+
readonly policy: RemotePolicy;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* `kept`: a warm session waited and waits on. `launched`: the agent runs, but no session
|
|
24
|
+
* opens before the app first answered a turn's handshake, which a warm session replays.
|
|
25
|
+
*/
|
|
26
|
+
export type WarmOutcome = "kept" | "warmed" | "launched" | "unknown_agent" | "failed";
|
|
27
|
+
/** Starts the agent and opens a session for the app's next new thread, before its prompt. */
|
|
28
|
+
export declare function warmAgent(agentId: string, deps: WarmDeps): Promise<WarmOutcome>;
|
|
29
|
+
//# sourceMappingURL=warm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"warm.d.ts","sourceRoot":"","sources":["../src/warm.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EAEtB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAG7C,eAAO,MAAM,YAAY,QAAc,CAAC;AAExC,yFAAyF;AACzF,wBAAgB,WAAW,CACzB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,QAAQ,GACd,OAAO,CAAC,eAAe,CAAC,CAS1B;AAOD,wBAAgB,YAAY,CAC1B,KAAK,EAAE,QAAQ,EACf,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,gBAAgB,CAQlB;AAED,yFAAyF;AACzF,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAGxE;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B;AAED;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,eAAe,GAAG,QAAQ,CAAC;AAEtF,6FAA6F;AAC7F,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CA4BrF"}
|
package/dist/warm.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { mkdir } from "node:fs/promises";
|
|
2
|
+
import { SessionRefused, } from "./acp.js";
|
|
3
|
+
import { logEvent } from "./log.js";
|
|
4
|
+
import { appServerOf } from "./naming.js";
|
|
5
|
+
import { agentEnvironment } from "./shell-path.js";
|
|
6
|
+
export const WARM_IDLE_MS = 10 * 60_000;
|
|
7
|
+
/** The app's agent process: the running one, or one started in the grant's workspace. */
|
|
8
|
+
export function launchAgent(pool, launcher, profile, grant) {
|
|
9
|
+
return pool.launch(grant.appOrigin, profile.id, async (signal) => {
|
|
10
|
+
await mkdir(grant.workspace, { recursive: true, mode: 0o700 });
|
|
11
|
+
return launcher.launch(profile, {
|
|
12
|
+
cwd: grant.workspace,
|
|
13
|
+
env: await agentEnvironment(),
|
|
14
|
+
signal,
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
const askModes = (policy) => ({
|
|
19
|
+
strictAsk: policy.answers !== "off",
|
|
20
|
+
autoMode: policy.agentMode !== "ask",
|
|
21
|
+
});
|
|
22
|
+
export function sessionInput(grant, policy, proxy, resume) {
|
|
23
|
+
return {
|
|
24
|
+
cwd: grant.workspace,
|
|
25
|
+
mcpServers: [proxy.server],
|
|
26
|
+
resume,
|
|
27
|
+
pinAskMode: true,
|
|
28
|
+
...askModes(policy),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** What a session is opened under; a warm one opened under another is never a turn's. */
|
|
32
|
+
export function sessionFit(grant, policy) {
|
|
33
|
+
const { strictAsk, autoMode } = askModes(policy);
|
|
34
|
+
return JSON.stringify([grant.workspace, strictAsk, autoMode]);
|
|
35
|
+
}
|
|
36
|
+
/** Starts the agent and opens a session for the app's next new thread, before its prompt. */
|
|
37
|
+
export async function warmAgent(agentId, deps) {
|
|
38
|
+
const grant = deps.link.grant;
|
|
39
|
+
const profile = deps.profiles.find((candidate) => candidate.id === agentId);
|
|
40
|
+
if (!profile)
|
|
41
|
+
return "unknown_agent";
|
|
42
|
+
const fit = sessionFit(grant, deps.policy);
|
|
43
|
+
if (deps.pool.warm(grant, agentId, fit, WARM_IDLE_MS))
|
|
44
|
+
return "kept";
|
|
45
|
+
let proxy;
|
|
46
|
+
try {
|
|
47
|
+
const connection = await launchAgent(deps.pool, deps.launcher, profile, grant);
|
|
48
|
+
if (!deps.proxy.knowsHandshake(grant.appOrigin))
|
|
49
|
+
return "launched";
|
|
50
|
+
proxy = deps.proxy.open(appServerOf(grant.appName), grant.appOrigin);
|
|
51
|
+
const session = await connection.openSession(sessionInput(grant, deps.policy, proxy, undefined));
|
|
52
|
+
deps.pool.keepWarm(grant, agentId, { session, proxy }, fit, WARM_IDLE_MS);
|
|
53
|
+
return "warmed";
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
proxy?.dispose();
|
|
57
|
+
if (error instanceof SessionRefused && error.leftOpen) {
|
|
58
|
+
await deps.pool.drop(grant.appOrigin, agentId);
|
|
59
|
+
}
|
|
60
|
+
logEvent("warm_failed", {
|
|
61
|
+
appOrigin: grant.appOrigin,
|
|
62
|
+
agentId,
|
|
63
|
+
error: error instanceof Error ? error.message : String(error),
|
|
64
|
+
});
|
|
65
|
+
return "failed";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=warm.js.map
|
package/dist/warm.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"warm.js","sourceRoot":"","sources":["../src/warm.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdir } from \"node:fs/promises\";\n\nimport {\n type AgentConnection,\n type AgentLauncher,\n type OpenSessionInput,\n SessionRefused,\n} from \"./acp.js\";\nimport type { AgentProfile } from \"./agents.js\";\nimport type { AppGrant } from \"./grants.js\";\nimport type { AppLink } from \"./link.js\";\nimport { logEvent } from \"./log.js\";\nimport type { McpProxy, ProxySession } from \"./mcp-proxy.js\";\nimport { appServerOf } from \"./naming.js\";\nimport type { RemotePolicy } from \"./policy.js\";\nimport type { SessionPool } from \"./pool.js\";\nimport { agentEnvironment } from \"./shell-path.js\";\n\nexport const WARM_IDLE_MS = 10 * 60_000;\n\n/** The app's agent process: the running one, or one started in the grant's workspace. */\nexport function launchAgent(\n pool: SessionPool,\n launcher: AgentLauncher,\n profile: AgentProfile,\n grant: AppGrant,\n): Promise<AgentConnection> {\n return pool.launch(grant.appOrigin, profile.id, async (signal) => {\n await mkdir(grant.workspace, { recursive: true, mode: 0o700 });\n return launcher.launch(profile, {\n cwd: grant.workspace,\n env: await agentEnvironment(),\n signal,\n });\n });\n}\n\nconst askModes = (policy: RemotePolicy) => ({\n strictAsk: policy.answers !== \"off\",\n autoMode: policy.agentMode !== \"ask\",\n});\n\nexport function sessionInput(\n grant: AppGrant,\n policy: RemotePolicy,\n proxy: ProxySession,\n resume: string | undefined,\n): OpenSessionInput {\n return {\n cwd: grant.workspace,\n mcpServers: [proxy.server],\n resume,\n pinAskMode: true,\n ...askModes(policy),\n };\n}\n\n/** What a session is opened under; a warm one opened under another is never a turn's. */\nexport function sessionFit(grant: AppGrant, policy: RemotePolicy): string {\n const { strictAsk, autoMode } = askModes(policy);\n return JSON.stringify([grant.workspace, strictAsk, autoMode]);\n}\n\nexport interface WarmDeps {\n readonly link: AppLink;\n readonly profiles: readonly AgentProfile[];\n readonly launcher: AgentLauncher;\n readonly pool: SessionPool;\n readonly proxy: McpProxy;\n readonly policy: RemotePolicy;\n}\n\n/**\n * `kept`: a warm session waited and waits on. `launched`: the agent runs, but no session\n * opens before the app first answered a turn's handshake, which a warm session replays.\n */\nexport type WarmOutcome = \"kept\" | \"warmed\" | \"launched\" | \"unknown_agent\" | \"failed\";\n\n/** Starts the agent and opens a session for the app's next new thread, before its prompt. */\nexport async function warmAgent(agentId: string, deps: WarmDeps): Promise<WarmOutcome> {\n const grant = deps.link.grant;\n const profile = deps.profiles.find((candidate) => candidate.id === agentId);\n if (!profile) return \"unknown_agent\";\n const fit = sessionFit(grant, deps.policy);\n if (deps.pool.warm(grant, agentId, fit, WARM_IDLE_MS)) return \"kept\";\n let proxy: ProxySession | undefined;\n try {\n const connection = await launchAgent(deps.pool, deps.launcher, profile, grant);\n if (!deps.proxy.knowsHandshake(grant.appOrigin)) return \"launched\";\n proxy = deps.proxy.open(appServerOf(grant.appName), grant.appOrigin);\n const session = await connection.openSession(\n sessionInput(grant, deps.policy, proxy, undefined),\n );\n deps.pool.keepWarm(grant, agentId, { session, proxy }, fit, WARM_IDLE_MS);\n return \"warmed\";\n } catch (error) {\n proxy?.dispose();\n if (error instanceof SessionRefused && error.leftOpen) {\n await deps.pool.drop(grant.appOrigin, agentId);\n }\n logEvent(\"warm_failed\", {\n appOrigin: grant.appOrigin,\n agentId,\n error: error instanceof Error ? error.message : String(error),\n });\n return \"failed\";\n }\n}\n"]}
|