@parlor/agent-host 0.0.0-stage → 0.2.0
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/LICENSE +21 -0
- package/README.md +16 -2
- package/dist/acp.d.ts +165 -0
- package/dist/acp.d.ts.map +1 -0
- package/dist/acp.js +626 -0
- package/dist/acp.js.map +1 -0
- package/dist/adapter-launch.d.ts +7 -0
- package/dist/adapter-launch.d.ts.map +1 -0
- package/dist/adapter-launch.js +35 -0
- package/dist/adapter-launch.js.map +1 -0
- package/dist/agents.d.ts +32 -0
- package/dist/agents.d.ts.map +1 -0
- package/dist/agents.js +132 -0
- package/dist/agents.js.map +1 -0
- package/dist/assertion.d.ts +9 -0
- package/dist/assertion.d.ts.map +1 -0
- package/dist/assertion.js +22 -0
- package/dist/assertion.js.map +1 -0
- package/dist/control.d.ts +106 -0
- package/dist/control.d.ts.map +1 -0
- package/dist/control.js +32 -0
- package/dist/control.js.map +1 -0
- package/dist/daemon.d.ts +50 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +543 -0
- package/dist/daemon.js.map +1 -0
- package/dist/dev-host.d.ts +5 -0
- package/dist/dev-host.d.ts.map +1 -0
- package/dist/dev-host.js +29 -0
- package/dist/dev-host.js.map +1 -0
- package/dist/device-list.d.ts +6 -0
- package/dist/device-list.d.ts.map +1 -0
- package/dist/device-list.js +30 -0
- package/dist/device-list.js.map +1 -0
- package/dist/embedded.d.ts +6 -0
- package/dist/embedded.d.ts.map +1 -0
- package/dist/embedded.js +3 -0
- package/dist/embedded.js.map +1 -0
- package/dist/fold.d.ts +38 -0
- package/dist/fold.d.ts.map +1 -0
- package/dist/fold.js +165 -0
- package/dist/fold.js.map +1 -0
- package/dist/grants.d.ts +54 -0
- package/dist/grants.d.ts.map +1 -0
- package/dist/grants.js +157 -0
- package/dist/grants.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/json-file.d.ts +6 -0
- package/dist/json-file.d.ts.map +1 -0
- package/dist/json-file.js +35 -0
- package/dist/json-file.js.map +1 -0
- package/dist/lines.d.ts +5 -0
- package/dist/lines.d.ts.map +1 -0
- package/dist/lines.js +9 -0
- package/dist/lines.js.map +1 -0
- package/dist/link-device.d.ts +28 -0
- package/dist/link-device.d.ts.map +1 -0
- package/dist/link-device.js +40 -0
- package/dist/link-device.js.map +1 -0
- package/dist/link.d.ts +52 -0
- package/dist/link.d.ts.map +1 -0
- package/dist/link.js +277 -0
- package/dist/link.js.map +1 -0
- package/dist/lock.d.ts +7 -0
- package/dist/lock.d.ts.map +1 -0
- package/dist/lock.js +105 -0
- package/dist/lock.js.map +1 -0
- package/dist/log.d.ts +3 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +18 -0
- package/dist/log.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +520 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp-proxy.d.ts +33 -0
- package/dist/mcp-proxy.d.ts.map +1 -0
- package/dist/mcp-proxy.js +317 -0
- package/dist/mcp-proxy.js.map +1 -0
- package/dist/naming.d.ts +7 -0
- package/dist/naming.d.ts.map +1 -0
- package/dist/naming.js +42 -0
- package/dist/naming.js.map +1 -0
- package/dist/pairing.d.ts +68 -0
- package/dist/pairing.d.ts.map +1 -0
- package/dist/pairing.js +312 -0
- package/dist/pairing.js.map +1 -0
- package/dist/paths.d.ts +19 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +23 -0
- package/dist/paths.js.map +1 -0
- package/dist/policy.d.ts +37 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +60 -0
- package/dist/policy.js.map +1 -0
- package/dist/pool.d.ts +34 -0
- package/dist/pool.d.ts.map +1 -0
- package/dist/pool.js +112 -0
- package/dist/pool.js.map +1 -0
- package/dist/prompter.d.ts +33 -0
- package/dist/prompter.d.ts.map +1 -0
- package/dist/prompter.js +98 -0
- package/dist/prompter.js.map +1 -0
- package/dist/release-main.d.ts +2 -0
- package/dist/release-main.d.ts.map +1 -0
- package/dist/release-main.js +50 -0
- package/dist/release-main.js.map +1 -0
- package/dist/release.d.ts +22 -0
- package/dist/release.d.ts.map +1 -0
- package/dist/release.js +81 -0
- package/dist/release.js.map +1 -0
- package/dist/revoke.d.ts +10 -0
- package/dist/revoke.d.ts.map +1 -0
- package/dist/revoke.js +23 -0
- package/dist/revoke.js.map +1 -0
- package/dist/self.d.ts +7 -0
- package/dist/self.d.ts.map +1 -0
- package/dist/self.js +10 -0
- package/dist/self.js.map +1 -0
- package/dist/service.d.ts +97 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +205 -0
- package/dist/service.js.map +1 -0
- package/dist/shell-path.d.ts +10 -0
- package/dist/shell-path.d.ts.map +1 -0
- package/dist/shell-path.js +64 -0
- package/dist/shell-path.js.map +1 -0
- package/dist/skeleton-kit.d.ts +8 -0
- package/dist/skeleton-kit.d.ts.map +1 -0
- package/dist/skeleton-kit.js +143 -0
- package/dist/skeleton-kit.js.map +1 -0
- package/dist/spec-kit.d.ts +102 -0
- package/dist/spec-kit.d.ts.map +1 -0
- package/dist/spec-kit.js +372 -0
- package/dist/spec-kit.js.map +1 -0
- package/dist/testing/fake-agent.d.ts +65 -0
- package/dist/testing/fake-agent.d.ts.map +1 -0
- package/dist/testing/fake-agent.js +238 -0
- package/dist/testing/fake-agent.js.map +1 -0
- package/dist/trust.d.ts +20 -0
- package/dist/trust.d.ts.map +1 -0
- package/dist/trust.js +27 -0
- package/dist/trust.js.map +1 -0
- package/dist/turn.d.ts +32 -0
- package/dist/turn.d.ts.map +1 -0
- package/dist/turn.js +650 -0
- package/dist/turn.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +6 -0
- package/dist/version.js.map +1 -0
- package/package.json +57 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n chmod,\n mkdir,\n readlink,\n realpath,\n rm,\n symlink,\n writeFile,\n} from \"node:fs/promises\";\nimport { createServer, type Server, type Socket } from \"node:net\";\nimport { basename, delimiter, dirname, join } from \"node:path\";\n\nimport type { LocalHostStatus } from \"@parlor/capabilities\";\nimport {\n type AgentInfo,\n type ClaimedTurn,\n HOST_PROTOCOL,\n type HostWelcome,\n} from \"@parlor/chat\";\nimport { ActionError, asId, DEV_USER_ID } from \"@parlor/core\";\n\nimport type { AgentLauncher } from \"./acp.js\";\nimport { type AgentProfile, detectAgents, loadProfiles } from \"./agents.js\";\nimport { connectControl, type ControlRequest } from \"./control.js\";\nimport { requestDevHostToken } from \"./dev-host.js\";\nimport { type AppGrant, devHostKeys, type GrantStore, type HostKeys } from \"./grants.js\";\nimport { onLines } from \"./lines.js\";\nimport { type AppLink, createAppLink } from \"./link.js\";\nimport { withInheritedLock } from \"./lock.js\";\nimport { logEvent, openHostLog } from \"./log.js\";\nimport type { McpProxy } from \"./mcp-proxy.js\";\nimport { computerName, platformName, workspaceOf } from \"./naming.js\";\nimport {\n type LocalPairing,\n pairingDeviceOf,\n startLocalPairing,\n UnrevokedGrant,\n} from \"./pairing.js\";\nimport type { HostPaths } from \"./paths.js\";\nimport { DEV_POLICY, loadPolicy, presenceDueAt, type RemotePolicy } from \"./policy.js\";\nimport type { SessionPool } from \"./pool.js\";\nimport { type LocalPrompter, printable } from \"./prompter.js\";\nimport { compareVersions, RELEASE_KEY, signedRelease } from \"./release.js\";\nimport { revokeGrant } from \"./revoke.js\";\nimport { selfEntry } from \"./self.js\";\nimport { type HostRelease, installLoginItem, installRelease } from \"./service.js\";\nimport type { TrustStore } from \"./trust.js\";\nimport { runTurn } from \"./turn.js\";\n\nexport interface DaemonDeps {\n readonly release: HostRelease;\n readonly paths: HostPaths;\n readonly grants: GrantStore;\n readonly keys: HostKeys;\n readonly trust: TrustStore;\n readonly pool: SessionPool;\n readonly proxy: McpProxy;\n readonly launcher: AgentLauncher;\n readonly prompter: LocalPrompter;\n readonly policy: RemotePolicy;\n /** The `service.lock` token of the `ensureService` that spawned this daemon, which holds the lock for it. */\n readonly lockToken?: string | undefined;\n}\n\n/**\n * One per user per computer, for every app: an `AppLink` per grant, the session pool,\n * the proxy socket and the control socket. Started only through `ensureService`.\n */\nexport interface HostDaemon {\n start(): Promise<void>;\n connect(appOrigin: string): Promise<void>;\n disconnect(appOrigin: string): Promise<void>;\n /** Hands links over to a newer release; running turns finish here first. */\n handover(): Promise<void>;\n stop(): Promise<void>;\n}\n\nconst CONNECT_TIMEOUT_MS = 15_000;\nconst OFFLINE_REPORT_MS = 1_000;\nfunction incompatibleMessage(\n grant: AppGrant,\n welcome: Extract<HostWelcome, { readonly accepted: false }>,\n): string {\n return welcome.reason === \"host_too_old\"\n ? `Update Parlor Host to use ${grant.appName}: it speaks host protocol ${HOST_PROTOCOL}, and ${grant.appName} needs ${welcome.protocols.min}.`\n : `${grant.appName} is older than this Parlor Host: it speaks host protocol ${welcome.protocols.max}, and this computer needs ${HOST_PROTOCOL}.`;\n}\n\nconst shellQuote = (value: string) => `'${value.replaceAll(\"'\", `'\\\\''`)}'`;\n\n/**\n * Agents start `parlor-host mcp-proxy` by name. An entry named otherwise, such as the\n * published `dist/main.js` that `parlor dev` runs with node, gets a shim instead of a link.\n */\nexport async function putHostCommandFirstOnPath(\n root: string,\n entry: string | undefined = selfEntry(),\n): Promise<void> {\n if (!entry) return;\n const bin = join(root, \"bin\");\n const link = join(bin, \"parlor-host\");\n await mkdir(bin, { recursive: true, mode: 0o700 });\n const target = await realpath(entry);\n if (basename(entry).startsWith(\"parlor-host\")) {\n if ((await readlink(link).catch(() => undefined)) !== target) {\n await rm(link, { force: true });\n await symlink(target, link);\n }\n } else {\n await rm(link, { force: true });\n await writeFile(\n link,\n `#!/bin/sh\\nexec ${shellQuote(process.execPath)} ${shellQuote(target)} \"$@\"\\n`,\n { mode: 0o700 },\n );\n }\n const path = (process.env.PATH ?? \"\").split(delimiter).filter((dir) => dir !== bin);\n process.env.PATH = [bin, ...path].join(delimiter);\n}\n\ninterface LinkState {\n readonly link: AppLink;\n readonly keys: HostKeys;\n claiming: Promise<void> | undefined;\n again: boolean;\n incompatible: string | undefined;\n turns: number;\n}\n\n/** The daemon a service runs: once it handed over, `drained` settles after its last turn. */\nexport interface ServiceDaemon extends HostDaemon {\n readonly drained: Promise<void>;\n}\n\nexport class HostAlreadyRunning extends Error {\n override readonly name = \"HostAlreadyRunning\";\n constructor() {\n super(\"Parlor Host is already running on this computer.\");\n }\n}\n\nexport function createHostDaemon(deps: DaemonDeps): ServiceDaemon {\n const { paths } = deps;\n const links = new Map<string, LinkState>();\n const devTokens = new Map<string, string>();\n const name = computerName();\n const platform = platformName();\n let profiles: readonly AgentProfile[] = [];\n let agents: AgentInfo[] = [];\n let control: Server | undefined;\n let startup: Promise<void> = Promise.resolve();\n const clients = new Set<Socket>();\n\n const claim = async (link: AppLink): Promise<ClaimedTurn | undefined> => {\n try {\n return await link.api.calls.call(\"hostClaim\", {});\n } catch (error) {\n if (!(error instanceof ActionError && error.code === \"not_found\")) {\n logEvent(\"claim_failed\", {\n appOrigin: link.grant.appOrigin,\n error: String(error),\n });\n }\n return undefined;\n }\n };\n\n const running = new Set<Promise<void>>();\n let handedOver = false;\n let finishing = false;\n let finishHandover: () => void = () => undefined;\n const drained = new Promise<void>((resolve) => (finishHandover = resolve));\n\n const run = (state: LinkState, claimed: ClaimedTurn) => {\n const { link } = state;\n logEvent(\"turn_claimed\", { appOrigin: link.grant.appOrigin, turnId: claimed.turnId });\n state.turns += 1;\n const turn = (\n link.grant.dev ? Promise.resolve(DEV_POLICY) : loadPolicy(paths.policy, deps.policy)\n )\n .then((policy) =>\n runTurn(claimed, {\n link,\n profiles,\n launcher: deps.launcher,\n pool: deps.pool,\n proxy: deps.proxy,\n trust: {\n ...deps.trust,\n pin: async (appOrigin, device) => {\n await deps.trust.pin(appOrigin, device);\n void report(state).catch(() => undefined);\n },\n forget: async (appOrigin, deviceId) => {\n await deps.trust.forget(appOrigin, deviceId);\n void report(state).catch(() => undefined);\n },\n },\n policy,\n prompter: deps.prompter,\n now: Date.now,\n pairing: {\n secret: async () =>\n (await deps.grants.get(link.grant.appOrigin))?.pairingSecret,\n forget: async () => {\n const saved = await deps.grants.get(link.grant.appOrigin);\n if (!saved?.pairingSecret) return;\n const { pairingSecret: _used, ...rest } = saved;\n await deps.grants.save(rest);\n },\n },\n }),\n )\n .then(\n (outcome) => logEvent(\"turn_finished\", { turnId: claimed.turnId, outcome }),\n (error: unknown) =>\n logEvent(\"turn_finished\", { turnId: claimed.turnId, error: String(error) }),\n )\n .finally(() => {\n state.turns -= 1;\n running.delete(turn);\n settleHandover();\n });\n running.add(turn);\n };\n\n const claimLoop = async (state: LinkState) => {\n do {\n state.again = false;\n for (\n let claimed = await claim(state.link);\n claimed;\n claimed = state.link.mode === \"serving\" ? await claim(state.link) : undefined\n ) {\n run(state, claimed);\n }\n } while (state.again && state.link.mode === \"serving\");\n };\n\n const wake = (state: LinkState) => {\n if (state.link.mode !== \"serving\") return;\n if (state.claiming) {\n state.again = true;\n return;\n }\n state.claiming = claimLoop(state).finally(() => {\n state.claiming = undefined;\n });\n };\n\n const closeLink = async (origin: string, reason: string) => {\n const state = links.get(origin);\n links.delete(origin);\n await state?.link.stop();\n await deps.pool.drop(origin);\n if (state) logEvent(\"link_closed\", { appOrigin: origin, reason });\n };\n\n const forget = async (grant: AppGrant) => {\n devTokens.delete(grant.appOrigin);\n await deps.grants.remove(grant.appOrigin);\n await deps.keys.remove(grant.appOrigin);\n await deps.trust.forget(grant.appOrigin);\n await deps.pool.forget(grant);\n };\n\n const open = (grant: AppGrant, keys: HostKeys): LinkState => {\n const origin = grant.appOrigin;\n let state: LinkState;\n const link = createAppLink(grant, {\n keys,\n hostVersion: deps.release.version,\n hostName: name,\n platform,\n fetch: (input, init) => fetch(input, init),\n onWake: () => wake(state),\n busy: () => state.turns > 0,\n onRevoked: () => {\n if (links.get(origin) !== state) return;\n if (grant.dev) void reattach(grant);\n else void closeLink(origin, \"revoked\").then(() => forget(grant));\n },\n onIncompatible: (refused, welcome) => {\n state.incompatible = incompatibleMessage(refused, welcome);\n process.stderr.write(`${printable(state.incompatible)}\\n`);\n },\n });\n state = {\n link,\n keys,\n claiming: undefined,\n again: false,\n incompatible: undefined,\n turns: 0,\n };\n links.set(origin, state);\n link.start();\n return state;\n };\n\n const pinnedDevices = async (state: LinkState) => {\n if (state.link.grant.dev) return {};\n const [pinned, policy] = await Promise.all([\n deps.trust.list(state.link.grant.appOrigin),\n loadPolicy(paths.policy, deps.policy),\n ]);\n const presenceDue: Record<string, number> = {};\n for (const device of pinned) {\n const due = presenceDueAt(policy, device);\n if (due !== undefined) presenceDue[device.deviceId] = due;\n }\n return { devices: pinned.map((device) => device.deviceId), presenceDue };\n };\n\n const report = async (state: LinkState) => {\n const reported = state.link.api.calls.call(\"hostReport\", {\n online: true,\n agents,\n ...(await pinnedDevices(state)),\n });\n const timeout = new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new Error(\"The app did not answer in time.\")),\n CONNECT_TIMEOUT_MS,\n ),\n );\n try {\n await Promise.race([reported, timeout]);\n } catch (error) {\n throw new Error(\n state.incompatible ?? (error instanceof Error ? error.message : String(error)),\n { cause: error },\n );\n }\n };\n\n const devGrant = async (origin: string): Promise<AppGrant> => {\n const manifest = await fetch(`${origin}/_parlor/manifest`)\n .then((response) => response.json() as Promise<{ app?: { name?: string } }>)\n .catch(() => undefined);\n return {\n appOrigin: origin,\n appName: manifest?.app?.name ?? new URL(origin).host,\n grantId: asId(\"grant\", \"dev\"),\n hostId: asId(\"host\", \"dev\"),\n account: { userId: DEV_USER_ID, name: \"Developer\" },\n workspace: workspaceOf(paths.workspaces, origin),\n createdAt: Date.now(),\n dev: true,\n };\n };\n\n const attach = async (origin: string, hostToken: string) => {\n await closeLink(origin, \"replaced\");\n devTokens.set(origin, hostToken);\n await report(open(await devGrant(origin), devHostKeys(hostToken)));\n };\n\n const reattach = async (grant: AppGrant) => {\n await closeLink(grant.appOrigin, \"dev_server_restarted\");\n if (!devTokens.has(grant.appOrigin)) return;\n try {\n const token = await requestDevHostToken(grant.appOrigin);\n if (devTokens.has(grant.appOrigin)) await attach(grant.appOrigin, token);\n } catch (error) {\n logEvent(\"dev_attach_failed\", { appOrigin: grant.appOrigin, error: String(error) });\n }\n };\n\n const status = (): LocalHostStatus => ({\n state: \"running\",\n version: deps.release.version,\n apps: [...links.keys()],\n });\n\n const grantsOf = () =>\n [...links.values()].map(({ link: { grant } }) => ({\n appOrigin: grant.appOrigin,\n appName: grant.appName,\n grantId: grant.grantId,\n }));\n\n const daemon: ServiceDaemon = {\n drained,\n async start() {\n let finishStartup!: () => void;\n let failStartup!: (error: unknown) => void;\n startup = new Promise<void>((resolve, reject) => {\n finishStartup = resolve;\n failStartup = reject;\n });\n startup.catch(() => undefined);\n try {\n await mkdir(paths.root, { recursive: true, mode: 0o700 });\n await withInheritedLock(paths.lock, deps.lockToken, async () => {\n const answering = await connectControl(paths.control);\n if (answering) {\n answering.close();\n throw new HostAlreadyRunning();\n }\n await mkdir(dirname(paths.control), { recursive: true, mode: 0o700 });\n control = createServer(serve);\n await rm(paths.control, { force: true });\n await new Promise<void>((resolve, reject) => {\n control!.once(\"error\", reject);\n control!.listen(paths.control, () => resolve());\n });\n await chmod(paths.control, 0o600);\n });\n openHostLog(join(paths.root, \"logs\", \"daemon.log\"));\n await putHostCommandFirstOnPath(paths.root);\n await deps.proxy.listen(paths.proxy);\n profiles = await loadProfiles(paths.agents);\n agents = await detectAgents(profiles);\n finishStartup();\n } catch (error) {\n failStartup(error);\n throw error;\n }\n logEvent(\"daemon_started\", {\n version: deps.release.version,\n agents: agents.map((a) => a.id),\n });\n for (const grant of await deps.grants.list()) {\n if (grant.declined) continue;\n void report(open(grant, deps.keys)).catch((error: unknown) =>\n logEvent(\"link_failed\", { appOrigin: grant.appOrigin, error: String(error) }),\n );\n }\n },\n async connect(appOrigin) {\n const grant = await deps.grants.get(appOrigin);\n if (!grant || grant.declined) {\n throw new Error(`This computer is not connected to ${appOrigin}.`);\n }\n const current = links.get(appOrigin);\n if (current?.link.grant.grantId === grant.grantId) {\n await report(current);\n return;\n }\n await closeLink(appOrigin, \"replaced\");\n if (current) await deps.pool.forget(current.link.grant);\n await report(open(grant, deps.keys));\n },\n async disconnect(appOrigin) {\n const state = links.get(appOrigin);\n const grant = state?.link.grant ?? (await deps.grants.get(appOrigin));\n if (!grant) throw new Error(`This computer is not connected to ${appOrigin}.`);\n if (state) {\n await state.link.stop({ revoke: true });\n } else {\n await revokeGrant({\n appOrigin,\n appName: grant.appName,\n assert: (request) => deps.keys.assert(appOrigin, request),\n });\n }\n await closeLink(appOrigin, \"disconnected\");\n await forget(grant);\n },\n async handover() {\n if (handedOver) return;\n handedOver = true;\n for (const state of links.values()) state.link.drain();\n await Promise.all([...links.values()].map((state) => state.claiming));\n const closing = control;\n control = undefined;\n closing?.close();\n await Promise.all([rm(paths.control, { force: true }), deps.proxy.stopListening()]);\n logEvent(\"handover_started\", { version: deps.release.version });\n },\n async stop() {\n if (!handedOver) {\n await Promise.all(\n [...links.values()].map((state) =>\n Promise.race([\n state.link.api.calls.call(\"hostReport\", { online: false, agents }),\n new Promise((resolve) => setTimeout(resolve, OFFLINE_REPORT_MS)),\n ]).catch(() => undefined),\n ),\n );\n }\n for (const origin of [...links.keys()]) await closeLink(origin, \"stopped\");\n for (const socket of clients) socket.destroy();\n const closing = control;\n control = undefined;\n if (closing) await new Promise<void>((resolve) => closing.close(() => resolve()));\n if (!handedOver) await rm(paths.control, { force: true });\n await deps.proxy.close();\n },\n };\n\n const settleHandover = () => {\n if (!handedOver || running.size > 0 || finishing) return;\n finishing = true;\n void (async () => {\n for (const origin of [...links.keys()]) await closeLink(origin, \"handed_over\");\n await Promise.all(\n [...clients].map(\n (socket) =>\n new Promise<void>((resolve) => {\n socket.end(() => resolve());\n setTimeout(resolve, OFFLINE_REPORT_MS).unref();\n }),\n ),\n );\n logEvent(\"handover_finished\", { version: deps.release.version });\n finishHandover();\n })();\n };\n\n const handOverTo = async (binary: string, signature: string): Promise<unknown> => {\n const release = await signedRelease(binary, signature, RELEASE_KEY);\n if (!release) return { ok: false, error: \"unsigned\" };\n if (compareVersions(release.version, deps.release.version) <= 0) {\n return { ok: false, error: \"downgrade\" };\n }\n if (!(await installRelease(paths, { binary, signature }, release))) {\n return { ok: false, error: \"unsigned\" };\n }\n await installLoginItem(paths);\n await daemon.handover();\n setImmediate(settleHandover);\n return { ok: true };\n };\n\n const pairings = new Map<string, LocalPairing>();\n\n const pendingPairing = (appOrigin: string) => {\n const origin = new URL(appOrigin).origin;\n return { origin, pairing: pairings.get(origin) };\n };\n\n const confirmPairing = async (\n request: Extract<ControlRequest, { readonly op: \"confirm_local_pairing\" }>,\n ): Promise<unknown> => {\n const { origin, pairing } = pendingPairing(request.appOrigin);\n if (!pairing) return { ok: false, error: \"No pairing was started for this app.\" };\n pairings.delete(origin);\n let outcome: Awaited<ReturnType<LocalPairing[\"confirm\"]>>;\n try {\n outcome = await pairing.confirm(request.connect);\n } catch (error) {\n if (!(error instanceof UnrevokedGrant)) throw error;\n await deps.grants.save(error.grant);\n return { ok: false, error: \"declined_locally\" };\n }\n if (!outcome.paired) return { ok: false, error: outcome.reason };\n const { grant } = outcome;\n await deps.grants.save(grant);\n const device = pairingDeviceOf(request.device);\n if (device) {\n await deps.trust.pin(grant.appOrigin, {\n deviceId: asId(\"device\", device.deviceId),\n signingKey: device.signingKey,\n presenceKey: device.presenceKey,\n name: device.name,\n platform: device.platform,\n approvedAt: Date.now(),\n via: \"pairing\",\n });\n }\n await daemon.connect(grant.appOrigin);\n return { ok: true };\n };\n\n const handle = async (request: ControlRequest): Promise<unknown> => {\n if (request.op !== \"hello\") await startup;\n switch (request.op) {\n case \"hello\":\n return { ok: true, release: deps.release };\n case \"handover\":\n return handOverTo(request.binary, request.signature);\n case \"status\":\n return { ok: true, status: status(), grants: grantsOf() };\n case \"begin_local_pairing\": {\n const { origin } = pendingPairing(request.appOrigin);\n const existing = await deps.grants.get(origin);\n if (existing && !existing.declined) {\n return {\n ok: false,\n error: `This computer is already connected to ${existing.appName}.`,\n };\n }\n const pairing = startLocalPairing({\n appOrigin: origin,\n hostName: name,\n platform,\n keys: deps.keys,\n workspaceRoot: paths.workspaces,\n });\n pairings.set(origin, pairing);\n const begun = await pairing.pairing;\n logEvent(\"local_pairing_begun\", {\n appOrigin: origin,\n matchingCode: begun.matchingCode,\n });\n return { ok: true, pairing: begun };\n }\n case \"finish_local_pairing\": {\n const { pairing } = pendingPairing(request.appOrigin);\n if (!pairing) return { ok: false, error: \"No pairing was started for this app.\" };\n return { ok: true, ...(await pairing.finish(request.code)) };\n }\n case \"confirm_local_pairing\":\n return confirmPairing(request);\n case \"connect\":\n await daemon.connect(request.appOrigin);\n return { ok: true };\n case \"disconnect\":\n await daemon.disconnect(request.appOrigin);\n return { ok: true };\n case \"dev_attach\":\n await attach(request.appOrigin, request.hostToken);\n return { ok: true };\n case \"dev_detach\":\n devTokens.delete(request.appOrigin);\n await closeLink(request.appOrigin, \"detached\");\n return { ok: true };\n }\n };\n\n function serve(socket: Socket) {\n clients.add(socket);\n socket.on(\"close\", () => clients.delete(socket));\n socket.on(\"error\", () => socket.destroy());\n onLines(socket, (line) => {\n let request: ControlRequest;\n try {\n request = JSON.parse(line) as ControlRequest;\n } catch {\n socket.write(`${JSON.stringify({ ok: false, error: \"Not JSON.\" })}\\n`);\n return;\n }\n void handle(request)\n .catch((error: unknown) => ({\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n }))\n .then((reply) => {\n if (!socket.destroyed)\n socket.write(\n `${JSON.stringify(reply ?? { ok: false, error: \"Unknown op.\" })}\\n`,\n );\n });\n });\n }\n\n return daemon;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-host.d.ts","sourceRoot":"","sources":["../src/dev-host.ts"],"names":[],"mappings":"AAOA,qBAAa,SAAU,SAAQ,KAAK;IAClC,SAAkB,IAAI,eAAe;CACtC;AAED,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,CAAC,CAkBjB"}
|
package/dist/dev-host.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
2
|
+
import { DEV_AUTH_PLUGIN, DEV_HOST_PATH } from "@parlor/server";
|
|
3
|
+
const RETRY_MS = 250;
|
|
4
|
+
const RETRY_MAX_MS = 2_000;
|
|
5
|
+
export class NoDevAuth extends Error {
|
|
6
|
+
name = "NoDevAuth";
|
|
7
|
+
}
|
|
8
|
+
export async function requestDevHostToken(serverOrigin, signal) {
|
|
9
|
+
const url = `${serverOrigin}/_parlor/${DEV_AUTH_PLUGIN}${DEV_HOST_PATH}`;
|
|
10
|
+
for (let attempt = 0;; attempt += 1) {
|
|
11
|
+
signal?.throwIfAborted();
|
|
12
|
+
let response;
|
|
13
|
+
try {
|
|
14
|
+
response = await fetch(url, { method: "POST", ...(signal ? { signal } : {}) });
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
response = undefined;
|
|
18
|
+
}
|
|
19
|
+
if (response?.ok)
|
|
20
|
+
return (await response.json()).token;
|
|
21
|
+
if (response?.status === 404)
|
|
22
|
+
throw new NoDevAuth(`${serverOrigin} uses its own sign-in.`);
|
|
23
|
+
if (response && response.status !== 502 && response.status !== 503) {
|
|
24
|
+
throw new Error(`${url} answered HTTP ${response.status}.`);
|
|
25
|
+
}
|
|
26
|
+
await sleep(Math.min(RETRY_MS * 2 ** attempt, RETRY_MAX_MS), undefined, { signal });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=dev-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-host.js","sourceRoot":"","sources":["../src/dev-host.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEhE,MAAM,QAAQ,GAAG,GAAG,CAAC;AACrB,MAAM,YAAY,GAAG,KAAK,CAAC;AAE3B,MAAM,OAAO,SAAU,SAAQ,KAAK;IAChB,IAAI,GAAG,WAAW,CAAC;CACtC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,YAAoB,EACpB,MAAoB;IAEpB,MAAM,GAAG,GAAG,GAAG,YAAY,YAAY,eAAe,GAAG,aAAa,EAAE,CAAC;IACzE,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,IAAI,CAAC,EAAE,CAAC;QACrC,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,IAAI,QAA8B,CAAC;QACnC,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACjF,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,GAAG,SAAS,CAAC;QACvB,CAAC;QACD,IAAI,QAAQ,EAAE,EAAE;YAAE,OAAQ,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuB,CAAC,KAAK,CAAC;QAC9E,IAAI,QAAQ,EAAE,MAAM,KAAK,GAAG;YAC1B,MAAM,IAAI,SAAS,CAAC,GAAG,YAAY,wBAAwB,CAAC,CAAC;QAC/D,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACnE,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,kBAAkB,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,IAAI,OAAO,EAAE,YAAY,CAAC,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACtF,CAAC;AACH,CAAC","sourcesContent":["import { setTimeout as sleep } from \"node:timers/promises\";\n\nimport { DEV_AUTH_PLUGIN, DEV_HOST_PATH } from \"@parlor/server\";\n\nconst RETRY_MS = 250;\nconst RETRY_MAX_MS = 2_000;\n\nexport class NoDevAuth extends Error {\n override readonly name = \"NoDevAuth\";\n}\n\nexport async function requestDevHostToken(\n serverOrigin: string,\n signal?: AbortSignal,\n): Promise<string> {\n const url = `${serverOrigin}/_parlor/${DEV_AUTH_PLUGIN}${DEV_HOST_PATH}`;\n for (let attempt = 0; ; attempt += 1) {\n signal?.throwIfAborted();\n let response: Response | undefined;\n try {\n response = await fetch(url, { method: \"POST\", ...(signal ? { signal } : {}) });\n } catch {\n response = undefined;\n }\n if (response?.ok) return ((await response.json()) as { token: string }).token;\n if (response?.status === 404)\n throw new NoDevAuth(`${serverOrigin} uses its own sign-in.`);\n if (response && response.status !== 502 && response.status !== 503) {\n throw new Error(`${url} answered HTTP ${response.status}.`);\n }\n await sleep(Math.min(RETRY_MS * 2 ** attempt, RETRY_MAX_MS), undefined, { signal });\n }\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { TrustedDevice, TrustStore } from "./trust.js";
|
|
2
|
+
/** The devices that can use this computer's agents for one app, one per line. */
|
|
3
|
+
export declare function describeDevices(appName: string, devices: readonly TrustedDevice[]): string;
|
|
4
|
+
/** Unlinks a device from this computer's agents; it must be linked again to use them. */
|
|
5
|
+
export declare function removeDevice(trust: TrustStore, appOrigin: string, deviceId: string): Promise<TrustedDevice>;
|
|
6
|
+
//# sourceMappingURL=device-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-list.d.ts","sourceRoot":"","sources":["../src/device-list.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAW5D,iFAAiF;AACjF,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,SAAS,aAAa,EAAE,GAChC,MAAM,CAWR;AAED,yFAAyF;AACzF,wBAAsB,YAAY,CAChC,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,CAAC,CASxB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { printable } from "./prompter.js";
|
|
2
|
+
const day = (at) => new Date(at).toLocaleDateString("en-CA");
|
|
3
|
+
function how(device, all) {
|
|
4
|
+
if (device.via === "pairing")
|
|
5
|
+
return "approved connect on this computer";
|
|
6
|
+
if (device.via === "local")
|
|
7
|
+
return "linked on this computer";
|
|
8
|
+
const voucher = all.find((candidate) => candidate.deviceId === device.voucher);
|
|
9
|
+
return `linked from ${voucher ? printable(voucher.name) : "a removed device"}`;
|
|
10
|
+
}
|
|
11
|
+
/** The devices that can use this computer's agents for one app, one per line. */
|
|
12
|
+
export function describeDevices(appName, devices) {
|
|
13
|
+
if (devices.length === 0) {
|
|
14
|
+
return `No device can use your agents for ${printable(appName)} yet. Open the app's Agent sidebar on one to link it.\n`;
|
|
15
|
+
}
|
|
16
|
+
const lines = [...devices]
|
|
17
|
+
.sort((a, b) => a.approvedAt - b.approvedAt)
|
|
18
|
+
.map((device) => ` ${device.deviceId} ${printable(device.name)}, ${day(device.approvedAt)}, ${how(device, devices)}`);
|
|
19
|
+
return `Devices that can use your agents for ${printable(appName)}:\n${lines.join("\n")}\n`;
|
|
20
|
+
}
|
|
21
|
+
/** Unlinks a device from this computer's agents; it must be linked again to use them. */
|
|
22
|
+
export async function removeDevice(trust, appOrigin, deviceId) {
|
|
23
|
+
const device = await trust.get(appOrigin, deviceId);
|
|
24
|
+
if (!device) {
|
|
25
|
+
throw new Error(`No linked device ${deviceId}. Run \`npx @parlor/agent-host devices ${appOrigin}\` to list them.`);
|
|
26
|
+
}
|
|
27
|
+
await trust.forget(appOrigin, deviceId);
|
|
28
|
+
return device;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=device-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-list.js","sourceRoot":"","sources":["../src/device-list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAG1C,MAAM,GAAG,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAErE,SAAS,GAAG,CAAC,MAAqB,EAAE,GAA6B;IAC/D,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS;QAAE,OAAO,mCAAmC,CAAC;IACzE,IAAI,MAAM,CAAC,GAAG,KAAK,OAAO;QAAE,OAAO,yBAAyB,CAAC;IAC7D,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/E,OAAO,eAAe,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC;AACjF,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,eAAe,CAC7B,OAAe,EACf,OAAiC;IAEjC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,qCAAqC,SAAS,CAAC,OAAO,CAAC,yDAAyD,CAAC;IAC1H,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC;SACvB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC;SAC3C,GAAG,CACF,CAAC,MAAM,EAAE,EAAE,CACT,KAAK,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CACxG,CAAC;IACJ,OAAO,wCAAwC,SAAS,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AAC9F,CAAC;AAED,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAiB,EACjB,SAAiB,EACjB,QAAgB;IAEhB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACpD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,oBAAoB,QAAQ,0CAA0C,SAAS,kBAAkB,CAClG,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACxC,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { printable } from \"./prompter.js\";\nimport type { TrustedDevice, TrustStore } from \"./trust.js\";\n\nconst day = (at: number) => new Date(at).toLocaleDateString(\"en-CA\");\n\nfunction how(device: TrustedDevice, all: readonly TrustedDevice[]): string {\n if (device.via === \"pairing\") return \"approved connect on this computer\";\n if (device.via === \"local\") return \"linked on this computer\";\n const voucher = all.find((candidate) => candidate.deviceId === device.voucher);\n return `linked from ${voucher ? printable(voucher.name) : \"a removed device\"}`;\n}\n\n/** The devices that can use this computer's agents for one app, one per line. */\nexport function describeDevices(\n appName: string,\n devices: readonly TrustedDevice[],\n): string {\n if (devices.length === 0) {\n return `No device can use your agents for ${printable(appName)} yet. Open the app's Agent sidebar on one to link it.\\n`;\n }\n const lines = [...devices]\n .sort((a, b) => a.approvedAt - b.approvedAt)\n .map(\n (device) =>\n ` ${device.deviceId} ${printable(device.name)}, ${day(device.approvedAt)}, ${how(device, devices)}`,\n );\n return `Devices that can use your agents for ${printable(appName)}:\\n${lines.join(\"\\n\")}\\n`;\n}\n\n/** Unlinks a device from this computer's agents; it must be linked again to use them. */\nexport async function removeDevice(\n trust: TrustStore,\n appOrigin: string,\n deviceId: string,\n): Promise<TrustedDevice> {\n const device = await trust.get(appOrigin, deviceId);\n if (!device) {\n throw new Error(\n `No linked device ${deviceId}. Run \\`npx @parlor/agent-host devices ${appOrigin}\\` to list them.`,\n );\n }\n await trust.forget(appOrigin, deviceId);\n return device;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedded.d.ts","sourceRoot":"","sources":["../src/embedded.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,qBAA4B,CAAC;AAE1D,eAAO,MAAM,UAAU,WAAY;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,WAA0C,CAAC"}
|
package/dist/embedded.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedded.js","sourceRoot":"","sources":["../src/embedded.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAkB,CAAC;AAE1D,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAG1B,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC","sourcesContent":["export const embeddedAdapters = new Map<string, string>();\n\nexport const adapterKey = (launch: {\n readonly package: string;\n readonly version: string;\n}) => `${launch.package}@${launch.version}`;\n"]}
|
package/dist/fold.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { HostFrame, HostItemDraft } from "@parlor/chat";
|
|
2
|
+
import { type TurnId } from "@parlor/core";
|
|
3
|
+
import type { AgentUpdate } from "./acp.js";
|
|
4
|
+
interface OpenText {
|
|
5
|
+
readonly id: string;
|
|
6
|
+
readonly kind: "reply" | "reasoning";
|
|
7
|
+
readonly text: string;
|
|
8
|
+
}
|
|
9
|
+
interface OpenTool {
|
|
10
|
+
readonly id: string;
|
|
11
|
+
readonly title: string;
|
|
12
|
+
readonly app: boolean;
|
|
13
|
+
readonly name: string;
|
|
14
|
+
}
|
|
15
|
+
export interface TurnFold {
|
|
16
|
+
readonly turnId: TurnId;
|
|
17
|
+
readonly open: OpenText | undefined;
|
|
18
|
+
readonly tools: ReadonlyMap<string, OpenTool>;
|
|
19
|
+
readonly plan: Extract<AgentUpdate, {
|
|
20
|
+
kind: "plan";
|
|
21
|
+
}>["entries"] | undefined;
|
|
22
|
+
readonly nextId: number;
|
|
23
|
+
}
|
|
24
|
+
export interface FoldStep {
|
|
25
|
+
readonly fold: TurnFold;
|
|
26
|
+
/** Ephemeral, streamed now. */
|
|
27
|
+
readonly frames: readonly HostFrame[];
|
|
28
|
+
/** Finished, appended durably. */
|
|
29
|
+
readonly closed: readonly HostItemDraft[];
|
|
30
|
+
}
|
|
31
|
+
/** Pure: knows no ACP, HTTP or time. Item ids are `<turnId>.<n>`. */
|
|
32
|
+
export declare function startFold(turnId: TurnId): TurnFold;
|
|
33
|
+
/** `appServer` is the MCP server name the host gave the agent for this app. */
|
|
34
|
+
export declare function foldUpdate(fold: TurnFold, update: AgentUpdate, appServer: string): FoldStep;
|
|
35
|
+
/** Closes what is open; `interrupted` marks the last reply when the user stopped the turn. */
|
|
36
|
+
export declare function finishFold(fold: TurnFold, interrupted: boolean): FoldStep;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=fold.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAqB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAE9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,UAAU,QAAQ;IAChB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,QAAQ;IAChB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC9C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IAC7E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;CAC3C;AA+ID,qEAAqE;AACrE,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAElD;AAED,+EAA+E;AAC/E,wBAAgB,UAAU,CACxB,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,GAChB,QAAQ,CA4BV;AAED,8FAA8F;AAC9F,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,GAAG,QAAQ,CAazE"}
|
package/dist/fold.js
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { asId } from "@parlor/core";
|
|
2
|
+
const MAX_DETAIL_CHARS = 4_000;
|
|
3
|
+
const itemId = (id) => asId("item", id);
|
|
4
|
+
const entriesOf = (entries) => entries.map((entry) => ({ ...entry }));
|
|
5
|
+
const unchanged = (fold) => ({ fold, frames: [], closed: [] });
|
|
6
|
+
const planItemOf = (fold) => itemId(`${fold.turnId}.0`);
|
|
7
|
+
function allocate(fold) {
|
|
8
|
+
return {
|
|
9
|
+
id: `${fold.turnId}.${fold.nextId}`,
|
|
10
|
+
fold: { ...fold, nextId: fold.nextId + 1 },
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function closeText(fold, interrupted = false) {
|
|
14
|
+
const open = fold.open;
|
|
15
|
+
if (!open)
|
|
16
|
+
return unchanged(fold);
|
|
17
|
+
const closed = open.kind === "reply"
|
|
18
|
+
? {
|
|
19
|
+
id: itemId(open.id),
|
|
20
|
+
kind: "reply",
|
|
21
|
+
body: {
|
|
22
|
+
text: open.text,
|
|
23
|
+
...(interrupted ? { interrupted: true } : {}),
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
: { id: itemId(open.id), kind: "reasoning", body: { text: open.text } };
|
|
27
|
+
return { fold: { ...fold, open: undefined }, frames: [], closed: [closed] };
|
|
28
|
+
}
|
|
29
|
+
function toolFrame(tool, status) {
|
|
30
|
+
return {
|
|
31
|
+
type: "item",
|
|
32
|
+
item: { id: itemId(tool.id), kind: "tool", title: tool.title, status },
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function toolDraft(tool, status, detail) {
|
|
36
|
+
return {
|
|
37
|
+
id: itemId(tool.id),
|
|
38
|
+
kind: "tool",
|
|
39
|
+
body: {
|
|
40
|
+
title: tool.title,
|
|
41
|
+
tool: { kind: tool.app ? "app" : "local", name: tool.name },
|
|
42
|
+
status,
|
|
43
|
+
...(detail ? { detail: detail.slice(0, MAX_DETAIL_CHARS) } : {}),
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function withTool(fold, toolCallId, tool) {
|
|
48
|
+
const tools = new Map(fold.tools);
|
|
49
|
+
if (tool)
|
|
50
|
+
tools.set(toolCallId, tool);
|
|
51
|
+
else
|
|
52
|
+
tools.delete(toolCallId);
|
|
53
|
+
return { ...fold, tools };
|
|
54
|
+
}
|
|
55
|
+
function appendText(fold, kind, text) {
|
|
56
|
+
if (text === "")
|
|
57
|
+
return unchanged(fold);
|
|
58
|
+
const switched = fold.open && fold.open.kind !== kind ? closeText(fold) : unchanged(fold);
|
|
59
|
+
let current = switched.fold;
|
|
60
|
+
let open = current.open;
|
|
61
|
+
if (!open) {
|
|
62
|
+
const next = allocate(current);
|
|
63
|
+
current = next.fold;
|
|
64
|
+
open = { id: next.id, kind, text: "" };
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
fold: { ...current, open: { ...open, text: open.text + text } },
|
|
68
|
+
frames: [
|
|
69
|
+
{ type: "delta", itemId: itemId(open.id), kind, offset: open.text.length, text },
|
|
70
|
+
],
|
|
71
|
+
closed: switched.closed,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function startTool(fold, update, appServer) {
|
|
75
|
+
const known = fold.tools.get(update.toolCallId);
|
|
76
|
+
if (known) {
|
|
77
|
+
const tool = { ...known, title: update.title || known.title };
|
|
78
|
+
return {
|
|
79
|
+
fold: withTool(fold, update.toolCallId, tool),
|
|
80
|
+
frames: [toolFrame(tool, "pending")],
|
|
81
|
+
closed: [],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const text = closeText(fold);
|
|
85
|
+
const next = allocate(text.fold);
|
|
86
|
+
const tool = {
|
|
87
|
+
id: next.id,
|
|
88
|
+
title: update.title,
|
|
89
|
+
app: update.mcp !== undefined && update.mcp.server === appServer,
|
|
90
|
+
name: update.mcp?.tool ?? update.toolKind,
|
|
91
|
+
};
|
|
92
|
+
return {
|
|
93
|
+
fold: withTool(next.fold, update.toolCallId, tool),
|
|
94
|
+
frames: [toolFrame(tool, "pending")],
|
|
95
|
+
closed: text.closed,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function updateTool(fold, update) {
|
|
99
|
+
const known = fold.tools.get(update.toolCallId);
|
|
100
|
+
if (!known)
|
|
101
|
+
return unchanged(fold);
|
|
102
|
+
const tool = { ...known, title: update.title || known.title };
|
|
103
|
+
if (update.status === "completed" || update.status === "failed") {
|
|
104
|
+
return {
|
|
105
|
+
fold: withTool(fold, update.toolCallId, undefined),
|
|
106
|
+
frames: [],
|
|
107
|
+
closed: [
|
|
108
|
+
toolDraft(tool, update.status === "completed" ? "done" : "failed", update.detail),
|
|
109
|
+
],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
fold: withTool(fold, update.toolCallId, tool),
|
|
114
|
+
frames: [toolFrame(tool, update.status === "in_progress" ? "running" : "pending")],
|
|
115
|
+
closed: [],
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/** Pure: knows no ACP, HTTP or time. Item ids are `<turnId>.<n>`. */
|
|
119
|
+
export function startFold(turnId) {
|
|
120
|
+
return { turnId, open: undefined, tools: new Map(), plan: undefined, nextId: 1 };
|
|
121
|
+
}
|
|
122
|
+
/** `appServer` is the MCP server name the host gave the agent for this app. */
|
|
123
|
+
export function foldUpdate(fold, update, appServer) {
|
|
124
|
+
switch (update.kind) {
|
|
125
|
+
case "text":
|
|
126
|
+
return appendText(fold, "reply", update.text);
|
|
127
|
+
case "thought":
|
|
128
|
+
return appendText(fold, "reasoning", update.text);
|
|
129
|
+
case "tool_start":
|
|
130
|
+
return startTool(fold, update, appServer);
|
|
131
|
+
case "tool_update":
|
|
132
|
+
return updateTool(fold, update);
|
|
133
|
+
case "plan":
|
|
134
|
+
return {
|
|
135
|
+
fold: { ...fold, plan: update.entries },
|
|
136
|
+
frames: [
|
|
137
|
+
{
|
|
138
|
+
type: "item",
|
|
139
|
+
item: {
|
|
140
|
+
id: planItemOf(fold),
|
|
141
|
+
kind: "plan",
|
|
142
|
+
entries: entriesOf(update.entries),
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
closed: [],
|
|
147
|
+
};
|
|
148
|
+
case "mode":
|
|
149
|
+
return unchanged(fold);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/** Closes what is open; `interrupted` marks the last reply when the user stopped the turn. */
|
|
153
|
+
export function finishFold(fold, interrupted) {
|
|
154
|
+
const text = closeText(fold, interrupted);
|
|
155
|
+
const tools = [...fold.tools.values()].map((tool) => toolDraft(tool, interrupted ? "cancelled" : "done", undefined));
|
|
156
|
+
const plan = fold.plan
|
|
157
|
+
? [{ id: planItemOf(fold), kind: "plan", body: { entries: entriesOf(fold.plan) } }]
|
|
158
|
+
: [];
|
|
159
|
+
return {
|
|
160
|
+
fold: { ...text.fold, tools: new Map(), plan: undefined },
|
|
161
|
+
frames: [],
|
|
162
|
+
closed: [...text.closed, ...tools, ...plan],
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=fold.js.map
|
package/dist/fold.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fold.js","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAA4B,MAAM,cAAc,CAAC;AAiC9D,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAI/B,MAAM,MAAM,GAAG,CAAC,EAAU,EAAU,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAExD,MAAM,SAAS,GAAG,CAChB,OAA0D,EACzB,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;AAE7E,MAAM,SAAS,GAAG,CAAC,IAAc,EAAY,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;AAEnF,MAAM,UAAU,GAAG,CAAC,IAAc,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;AAElE,SAAS,QAAQ,CAAC,IAAc;IAC9B,OAAO;QACL,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE;QACnC,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;KAC3C,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,IAAc,EAAE,WAAW,GAAG,KAAK;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACvB,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,MAAM,GACV,IAAI,CAAC,IAAI,KAAK,OAAO;QACnB,CAAC,CAAC;YACE,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACnB,IAAI,EAAE,OAAO;YACb,IAAI,EAAE;gBACJ,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACvD;SACF;QACH,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;IAC5E,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;AAC9E,CAAC;AAED,SAAS,SAAS,CAAC,IAAc,EAAE,MAAuB;IACxD,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE;KACvE,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAChB,IAAc,EACd,MAAsC,EACtC,MAA0B;IAE1B,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE;YACJ,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;YAC3D,MAAM;YACN,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjE;KACF,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,IAAc,EAAE,UAAkB,EAAE,IAA0B;IAC9E,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,IAAI;QAAE,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;;QACjC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC9B,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,UAAU,CAAC,IAAc,EAAE,IAAsB,EAAE,IAAY;IACtE,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,QAAQ,GACZ,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC3E,IAAI,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC;IAC5B,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IACxB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC/B,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC;QACpB,IAAI,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IACzC,CAAC;IACD,OAAO;QACL,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,IAAI,EAAE,EAAE;QAC/D,MAAM,EAAE;YACN,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE;SACjF;QACD,MAAM,EAAE,QAAQ,CAAC,MAAM;KACxB,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAChB,IAAc,EACd,MAAoD,EACpD,SAAiB;IAEjB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,IAAI,GAAG,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC9D,OAAO;YACL,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC;YAC7C,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YACpC,MAAM,EAAE,EAAE;SACX,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,IAAI,GAAa;QACrB,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,GAAG,EAAE,MAAM,CAAC,GAAG,KAAK,SAAS,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS;QAChE,IAAI,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,IAAI,MAAM,CAAC,QAAQ;KAC1C,CAAC;IACF,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC;QAClD,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACpC,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CACjB,IAAc,EACd,MAAqD;IAErD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;IAC9D,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAChE,OAAO;YACL,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC;YAClD,MAAM,EAAE,EAAE;YACV,MAAM,EAAE;gBACN,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC;aAClF;SACF,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC;QAC7C,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAClF,MAAM,EAAE,EAAE;KACX,CAAC;AACJ,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;AACnF,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,UAAU,CACxB,IAAc,EACd,MAAmB,EACnB,SAAiB;IAEjB,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,MAAM;YACT,OAAO,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QAChD,KAAK,SAAS;YACZ,OAAO,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QACpD,KAAK,YAAY;YACf,OAAO,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QAC5C,KAAK,aAAa;YAChB,OAAO,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAClC,KAAK,MAAM;YACT,OAAO;gBACL,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE;gBACvC,MAAM,EAAE;oBACN;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;4BACJ,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC;4BACpB,IAAI,EAAE,MAAM;4BACZ,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC;yBACnC;qBACF;iBACF;gBACD,MAAM,EAAE,EAAE;aACX,CAAC;QACJ,KAAK,MAAM;YACT,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,UAAU,CAAC,IAAc,EAAE,WAAoB;IAC7D,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAClD,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAC/D,CAAC;IACF,MAAM,IAAI,GAAoB,IAAI,CAAC,IAAI;QACrC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACnF,CAAC,CAAC,EAAE,CAAC;IACP,OAAO;QACL,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QACzD,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC;KAC5C,CAAC;AACJ,CAAC","sourcesContent":["import type { ChatItemBody, HostFrame, HostItemDraft } from \"@parlor/chat\";\nimport { asId, type ItemId, type TurnId } from \"@parlor/core\";\n\nimport type { AgentUpdate } from \"./acp.js\";\n\ninterface OpenText {\n readonly id: string;\n readonly kind: \"reply\" | \"reasoning\";\n readonly text: string;\n}\n\ninterface OpenTool {\n readonly id: string;\n readonly title: string;\n readonly app: boolean;\n readonly name: string;\n}\n\nexport interface TurnFold {\n readonly turnId: TurnId;\n readonly open: OpenText | undefined;\n readonly tools: ReadonlyMap<string, OpenTool>;\n readonly plan: Extract<AgentUpdate, { kind: \"plan\" }>[\"entries\"] | undefined;\n readonly nextId: number;\n}\n\nexport interface FoldStep {\n readonly fold: TurnFold;\n /** Ephemeral, streamed now. */\n readonly frames: readonly HostFrame[];\n /** Finished, appended durably. */\n readonly closed: readonly HostItemDraft[];\n}\n\nconst MAX_DETAIL_CHARS = 4_000;\n\ntype ToolFrameStatus = \"pending\" | \"running\";\n\nconst itemId = (id: string): ItemId => asId(\"item\", id);\n\nconst entriesOf = (\n entries: Extract<AgentUpdate, { kind: \"plan\" }>[\"entries\"],\n): ChatItemBody<\"plan\">[\"entries\"] => entries.map((entry) => ({ ...entry }));\n\nconst unchanged = (fold: TurnFold): FoldStep => ({ fold, frames: [], closed: [] });\n\nconst planItemOf = (fold: TurnFold) => itemId(`${fold.turnId}.0`);\n\nfunction allocate(fold: TurnFold): { readonly id: string; readonly fold: TurnFold } {\n return {\n id: `${fold.turnId}.${fold.nextId}`,\n fold: { ...fold, nextId: fold.nextId + 1 },\n };\n}\n\nfunction closeText(fold: TurnFold, interrupted = false): FoldStep {\n const open = fold.open;\n if (!open) return unchanged(fold);\n const closed: HostItemDraft =\n open.kind === \"reply\"\n ? {\n id: itemId(open.id),\n kind: \"reply\",\n body: {\n text: open.text,\n ...(interrupted ? { interrupted: true as const } : {}),\n },\n }\n : { id: itemId(open.id), kind: \"reasoning\", body: { text: open.text } };\n return { fold: { ...fold, open: undefined }, frames: [], closed: [closed] };\n}\n\nfunction toolFrame(tool: OpenTool, status: ToolFrameStatus): HostFrame {\n return {\n type: \"item\",\n item: { id: itemId(tool.id), kind: \"tool\", title: tool.title, status },\n };\n}\n\nfunction toolDraft(\n tool: OpenTool,\n status: ChatItemBody<\"tool\">[\"status\"],\n detail: string | undefined,\n): HostItemDraft {\n return {\n id: itemId(tool.id),\n kind: \"tool\",\n body: {\n title: tool.title,\n tool: { kind: tool.app ? \"app\" : \"local\", name: tool.name },\n status,\n ...(detail ? { detail: detail.slice(0, MAX_DETAIL_CHARS) } : {}),\n },\n };\n}\n\nfunction withTool(fold: TurnFold, toolCallId: string, tool: OpenTool | undefined) {\n const tools = new Map(fold.tools);\n if (tool) tools.set(toolCallId, tool);\n else tools.delete(toolCallId);\n return { ...fold, tools };\n}\n\nfunction appendText(fold: TurnFold, kind: OpenText[\"kind\"], text: string): FoldStep {\n if (text === \"\") return unchanged(fold);\n const switched =\n fold.open && fold.open.kind !== kind ? closeText(fold) : unchanged(fold);\n let current = switched.fold;\n let open = current.open;\n if (!open) {\n const next = allocate(current);\n current = next.fold;\n open = { id: next.id, kind, text: \"\" };\n }\n return {\n fold: { ...current, open: { ...open, text: open.text + text } },\n frames: [\n { type: \"delta\", itemId: itemId(open.id), kind, offset: open.text.length, text },\n ],\n closed: switched.closed,\n };\n}\n\nfunction startTool(\n fold: TurnFold,\n update: Extract<AgentUpdate, { kind: \"tool_start\" }>,\n appServer: string,\n): FoldStep {\n const known = fold.tools.get(update.toolCallId);\n if (known) {\n const tool = { ...known, title: update.title || known.title };\n return {\n fold: withTool(fold, update.toolCallId, tool),\n frames: [toolFrame(tool, \"pending\")],\n closed: [],\n };\n }\n const text = closeText(fold);\n const next = allocate(text.fold);\n const tool: OpenTool = {\n id: next.id,\n title: update.title,\n app: update.mcp !== undefined && update.mcp.server === appServer,\n name: update.mcp?.tool ?? update.toolKind,\n };\n return {\n fold: withTool(next.fold, update.toolCallId, tool),\n frames: [toolFrame(tool, \"pending\")],\n closed: text.closed,\n };\n}\n\nfunction updateTool(\n fold: TurnFold,\n update: Extract<AgentUpdate, { kind: \"tool_update\" }>,\n): FoldStep {\n const known = fold.tools.get(update.toolCallId);\n if (!known) return unchanged(fold);\n const tool = { ...known, title: update.title || known.title };\n if (update.status === \"completed\" || update.status === \"failed\") {\n return {\n fold: withTool(fold, update.toolCallId, undefined),\n frames: [],\n closed: [\n toolDraft(tool, update.status === \"completed\" ? \"done\" : \"failed\", update.detail),\n ],\n };\n }\n return {\n fold: withTool(fold, update.toolCallId, tool),\n frames: [toolFrame(tool, update.status === \"in_progress\" ? \"running\" : \"pending\")],\n closed: [],\n };\n}\n\n/** Pure: knows no ACP, HTTP or time. Item ids are `<turnId>.<n>`. */\nexport function startFold(turnId: TurnId): TurnFold {\n return { turnId, open: undefined, tools: new Map(), plan: undefined, nextId: 1 };\n}\n\n/** `appServer` is the MCP server name the host gave the agent for this app. */\nexport function foldUpdate(\n fold: TurnFold,\n update: AgentUpdate,\n appServer: string,\n): FoldStep {\n switch (update.kind) {\n case \"text\":\n return appendText(fold, \"reply\", update.text);\n case \"thought\":\n return appendText(fold, \"reasoning\", update.text);\n case \"tool_start\":\n return startTool(fold, update, appServer);\n case \"tool_update\":\n return updateTool(fold, update);\n case \"plan\":\n return {\n fold: { ...fold, plan: update.entries },\n frames: [\n {\n type: \"item\",\n item: {\n id: planItemOf(fold),\n kind: \"plan\",\n entries: entriesOf(update.entries),\n },\n },\n ],\n closed: [],\n };\n case \"mode\":\n return unchanged(fold);\n }\n}\n\n/** Closes what is open; `interrupted` marks the last reply when the user stopped the turn. */\nexport function finishFold(fold: TurnFold, interrupted: boolean): FoldStep {\n const text = closeText(fold, interrupted);\n const tools = [...fold.tools.values()].map((tool) =>\n toolDraft(tool, interrupted ? \"cancelled\" : \"done\", undefined),\n );\n const plan: HostItemDraft[] = fold.plan\n ? [{ id: planItemOf(fold), kind: \"plan\", body: { entries: entriesOf(fold.plan) } }]\n : [];\n return {\n fold: { ...text.fold, tools: new Map(), plan: undefined },\n frames: [],\n closed: [...text.closed, ...tools, ...plan],\n };\n}\n"]}
|
package/dist/grants.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { AccountSummary } from "@parlor/auth";
|
|
2
|
+
import type { GrantId, HostId } from "@parlor/core";
|
|
3
|
+
/** One app this computer is connected to. Its key lives in `HostKeys`, never here. */
|
|
4
|
+
export interface AppGrant {
|
|
5
|
+
readonly appOrigin: string;
|
|
6
|
+
readonly appName: string;
|
|
7
|
+
readonly grantId: GrantId;
|
|
8
|
+
readonly hostId: HostId;
|
|
9
|
+
readonly account: AccountSummary;
|
|
10
|
+
/** The agents' working directory for this app; only the user changes it, here. */
|
|
11
|
+
readonly workspace: string;
|
|
12
|
+
readonly createdAt: number;
|
|
13
|
+
/** A `parlor dev` grant: in memory only. */
|
|
14
|
+
readonly dev?: true | undefined;
|
|
15
|
+
/** Refused here but not yet revoked by the app: kept only to retry the revoke, never served. */
|
|
16
|
+
readonly declined?: true | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Handed only to the browser that approved `connect`, through the loopback redirect; that
|
|
19
|
+
* browser proves it on its first prompt and is trusted without asking, then this is dropped.
|
|
20
|
+
*/
|
|
21
|
+
readonly pairingSecret?: string | undefined;
|
|
22
|
+
}
|
|
23
|
+
/** One key per app grant in the OS keychain; the server holds only its public half. */
|
|
24
|
+
export interface HostKeys {
|
|
25
|
+
/** A pairing's new key pair, kept only once the pairing completes. */
|
|
26
|
+
create(appOrigin: string): Promise<HostKeyPair>;
|
|
27
|
+
/** A fresh `ParlorHost` assertion for one request. */
|
|
28
|
+
assert(appOrigin: string, request: {
|
|
29
|
+
readonly method: "GET" | "POST";
|
|
30
|
+
readonly url: string;
|
|
31
|
+
}): Promise<string>;
|
|
32
|
+
remove(appOrigin: string): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
export interface HostKeyPair {
|
|
35
|
+
readonly publicKey: JsonWebKey;
|
|
36
|
+
/** RFC 7638, the assertion's `kid`. */
|
|
37
|
+
readonly thumbprint: string;
|
|
38
|
+
sign(payload: Uint8Array): Promise<string>;
|
|
39
|
+
/** Binds the key to the grant the pairing produced and stores it. */
|
|
40
|
+
keep(grantId: GrantId): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
export interface GrantStore {
|
|
43
|
+
list(): Promise<readonly AppGrant[]>;
|
|
44
|
+
get(appOrigin: string): Promise<AppGrant | undefined>;
|
|
45
|
+
save(grant: AppGrant): Promise<void>;
|
|
46
|
+
remove(appOrigin: string): Promise<void>;
|
|
47
|
+
}
|
|
48
|
+
/** `~/.parlor/host/grants.json`, 0600, written atomically. */
|
|
49
|
+
export declare function fileGrantStore(file: string): GrantStore;
|
|
50
|
+
/** The macOS Keychain; other platforms are refused before pairing (`unsupportedHostPlatform`). */
|
|
51
|
+
export declare function keychainHostKeys(service: string): HostKeys;
|
|
52
|
+
/** For `parlor-host dev`: one dev host token for every request, nothing on disk. */
|
|
53
|
+
export declare function devHostKeys(hostToken: string): HostKeys;
|
|
54
|
+
//# sourceMappingURL=grants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grants.d.ts","sourceRoot":"","sources":["../src/grants.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAKpD,sFAAsF;AACtF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,kFAAkF;IAClF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,4CAA4C;IAC5C,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IAChC,gGAAgG;IAChG,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7C;AAED,uFAAuF;AACvF,MAAM,WAAW,QAAQ;IACvB,sEAAsE;IACtE,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAChD,sDAAsD;IACtD,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GACjE,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAC/B,uCAAuC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,qEAAqE;IACrE,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,IAAI,OAAO,CAAC,SAAS,QAAQ,EAAE,CAAC,CAAC;IACrC,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,8DAA8D;AAC9D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAcvD;AA0JD,kGAAkG;AAClG,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAE1D;AAED,oFAAoF;AACpF,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAMvD"}
|