@parlor/client 0.3.0 → 0.3.1

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.
@@ -1,4 +1,4 @@
1
- import { ActionError, type ActionInput, type ActionMap, type ActionOutput, type Tag } from "@parlor/core";
1
+ import { ActionError, type ActionInput, type ActionMap, type ActionOutput, type ReadRequest, type RefreshedRead, type Tag } from "@parlor/core";
2
2
  export declare function generateClientId(): string;
3
3
  export type HeadersProvider = HeadersInit | (() => HeadersInit | Promise<HeadersInit>);
4
4
  export interface ActionClientOptions {
@@ -10,12 +10,18 @@ export interface ActionClientOptions {
10
10
  }
11
11
  export interface CallOptions {
12
12
  readonly signal?: AbortSignal | undefined;
13
+ /** For a write: the reads the page shows, to answer with fresh the ones it changed. */
14
+ readonly refresh?: readonly ReadRequest[] | undefined;
13
15
  }
14
16
  export interface ActionEnvelope<T> {
15
17
  readonly data: T;
16
18
  readonly tags: readonly Tag[];
17
19
  /** The sync cursor a read's data reflects, when the server tracks it. */
18
20
  readonly cursor?: string | undefined;
21
+ /** For a call with `refresh`, when the server knows it: what the write changed. */
22
+ readonly writes?: readonly Tag[] | undefined;
23
+ /** For a call with `refresh`, when the server knows it: each read named, in order. */
24
+ readonly refreshed?: readonly RefreshedRead[] | undefined;
19
25
  }
20
26
  export interface ActionClient<T extends ActionMap> {
21
27
  readonly clientId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"action-client.d.ts","sourceRoot":"","sources":["../src/action-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"action-client.d.ts","sourceRoot":"","sources":["../src/action-client.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { ActionError, SHELL_ORIGINS, } from "@parlor/core";
1
+ import { ActionError, encodeReadRequests, REFRESH_HEADER, SHELL_ORIGINS, } from "@parlor/core";
2
2
  const DEFAULT_BASE_PATH = "/_parlor";
3
3
  const SOURCE_HEADER = "x-parlor-source";
4
4
  const CLIENT_HEADER = "x-parlor-client";
@@ -26,7 +26,12 @@ export async function toActionError(response, options = {}) {
26
26
  export async function invokeAt(request, path, input, options = {}) {
27
27
  const response = await request(path, {
28
28
  method: "POST",
29
- headers: { "content-type": "application/json" },
29
+ headers: {
30
+ "content-type": "application/json",
31
+ ...(options.refresh?.length
32
+ ? { [REFRESH_HEADER]: encodeReadRequests(options.refresh) }
33
+ : {}),
34
+ },
30
35
  body: JSON.stringify(input ?? {}),
31
36
  signal: options.signal ?? null,
32
37
  });
@@ -38,6 +43,9 @@ export async function invokeAt(request, path, input, options = {}) {
38
43
  data: body.data,
39
44
  tags: body.tags ?? [],
40
45
  ...(typeof body.cursor === "string" ? { cursor: body.cursor } : {}),
46
+ ...(Array.isArray(body.writes) && Array.isArray(body.refreshed)
47
+ ? { writes: body.writes, refreshed: body.refreshed }
48
+ : {}),
41
49
  };
42
50
  }
43
51
  export function resolveServerOrigin() {
@@ -1 +1 @@
1
- {"version":3,"file":"action-client.js","sourceRoot":"","sources":["../src/action-client.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ActionError,\n type ActionInput,\n type ActionMap,\n type ActionOutput,\n SHELL_ORIGINS,\n type Tag,\n} from \"@parlor/core\";\n\nconst DEFAULT_BASE_PATH = \"/_parlor\";\nconst SOURCE_HEADER = \"x-parlor-source\";\nconst CLIENT_HEADER = \"x-parlor-client\";\n\nfunction injectedServerUrl(): string {\n const env = (import.meta as { env?: { PARLOR_SERVER_URL?: string } }).env;\n return env?.PARLOR_SERVER_URL ?? \"\";\n}\n\nexport function generateClientId(): string {\n return globalThis.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2);\n}\n\nexport type HeadersProvider = HeadersInit | (() => HeadersInit | Promise<HeadersInit>);\n\nexport interface ActionClientOptions {\n readonly baseUrl?: string | undefined;\n readonly basePath?: string | undefined;\n readonly fetch?: typeof fetch | undefined;\n readonly headers?: HeadersProvider | undefined;\n readonly clientId?: string | undefined;\n}\n\nexport interface CallOptions {\n readonly signal?: AbortSignal | undefined;\n}\n\nexport interface ActionEnvelope<T> {\n readonly data: T;\n readonly tags: readonly Tag[];\n /** The sync cursor a read's data reflects, when the server tracks it. */\n readonly cursor?: string | undefined;\n}\n\nexport interface ActionClient<T extends ActionMap> {\n readonly clientId: string;\n readonly basePath: string;\n call<K extends keyof T & string>(\n name: K,\n input: ActionInput<T[K]>,\n options?: CallOptions,\n ): Promise<ActionOutput<T[K]>>;\n invoke<K extends keyof T & string>(\n name: K,\n input: ActionInput<T[K]>,\n options?: CallOptions,\n ): Promise<ActionEnvelope<ActionOutput<T[K]>>>;\n request(path: string, init?: RequestInit): Promise<Response>;\n}\n\nasync function resolveHeaders(\n provider: HeadersProvider | undefined,\n clientId: string,\n extra?: HeadersInit,\n): Promise<Headers> {\n const headers = new Headers(\n typeof provider === \"function\" ? await provider() : provider,\n );\n new Headers(extra).forEach((value, key) => headers.set(key, value));\n headers.set(SOURCE_HEADER, \"ui\");\n headers.set(CLIENT_HEADER, clientId);\n return headers;\n}\n\nexport async function toActionError(\n response: Response,\n options: { readonly missingIsNotFound?: boolean } = {},\n): Promise<ActionError> {\n const body: unknown = await response.json().catch(() => undefined);\n if (ActionError.isBody(body)) return ActionError.fromBody(body);\n const code =\n options.missingIsNotFound && response.status === 404 ? \"not_found\" : \"internal\";\n return new ActionError(code, `Action request failed with HTTP ${response.status}`);\n}\n\nexport async function invokeAt<T extends ActionMap, K extends keyof T & string>(\n request: ActionClient<ActionMap>[\"request\"],\n path: string,\n input: ActionInput<T[K]>,\n options: CallOptions & { readonly missingIsNotFound?: boolean } = {},\n): Promise<ActionEnvelope<ActionOutput<T[K]>>> {\n const response = await request(path, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(input ?? {}),\n signal: options.signal ?? null,\n });\n if (!response.ok) {\n throw await toActionError(\n response,\n options.missingIsNotFound ? { missingIsNotFound: true } : {},\n );\n }\n const body = (await response.json()) as {\n data: ActionOutput<T[K]>;\n tags?: Tag[];\n cursor?: string;\n };\n return {\n data: body.data,\n tags: body.tags ?? [],\n ...(typeof body.cursor === \"string\" ? { cursor: body.cursor } : {}),\n };\n}\n\nexport function resolveServerOrigin(): string {\n return injectedServerUrl() || globalThis.location?.origin || \"\";\n}\n\nfunction injectedAppOrigin(): string {\n const env = (import.meta as { env?: { PARLOR_APP_ORIGIN?: string } }).env;\n return env?.PARLOR_APP_ORIGIN ?? \"\";\n}\n\n/**\n * The one name of this app's backend on every surface: the page's own origin when it is\n * served over http(s) and is not a shell's webview origin, else the shell's `server.url`.\n * `parlor dev` running several targets names the web target's origin for all of them.\n * Statements are signed for it and the host is paired with it.\n */\nexport function appOrigin(\n serverUrl: string = resolveServerOrigin(),\n injected: string = injectedAppOrigin(),\n): string {\n if (injected) return new URL(injected).origin;\n const page = globalThis.location?.origin ?? \"\";\n if (/^https?:\\/\\//.test(page) && !SHELL_ORIGINS.includes(page)) return page;\n try {\n return new URL(serverUrl).origin;\n } catch {\n return serverUrl;\n }\n}\n\nexport function createActionClient<T extends ActionMap>(\n options: ActionClientOptions = {},\n): ActionClient<T> {\n const {\n baseUrl = injectedServerUrl(),\n basePath = DEFAULT_BASE_PATH,\n headers,\n } = options;\n // Drawn on first use: workerd allows no random values while a module loads.\n let clientId = options.clientId;\n const ownId = () => (clientId ??= generateClientId());\n const fetchImpl = options.fetch ?? globalThis.fetch;\n\n const request = async (path: string, init: RequestInit = {}) =>\n fetchImpl(`${baseUrl}${path}`, {\n ...init,\n headers: await resolveHeaders(headers, ownId(), init.headers),\n });\n\n const invoke = async <K extends keyof T & string>(\n name: K,\n input: ActionInput<T[K]>,\n callOptions: CallOptions = {},\n ): Promise<ActionEnvelope<ActionOutput<T[K]>>> => {\n return invokeAt<T, K>(request, `${basePath}/actions/${name}`, input, callOptions);\n };\n\n return {\n get clientId() {\n return ownId();\n },\n basePath,\n request,\n invoke,\n call: async (name, input, callOptions) =>\n (await invoke(name, input, callOptions)).data,\n };\n}\n"]}
1
+ {"version":3,"file":"action-client.js","sourceRoot":"","sources":["../src/action-client.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ActionError,\n type ActionInput,\n type ActionMap,\n type ActionOutput,\n encodeReadRequests,\n type ReadRequest,\n REFRESH_HEADER,\n type RefreshedRead,\n SHELL_ORIGINS,\n type Tag,\n} from \"@parlor/core\";\n\nconst DEFAULT_BASE_PATH = \"/_parlor\";\nconst SOURCE_HEADER = \"x-parlor-source\";\nconst CLIENT_HEADER = \"x-parlor-client\";\n\nfunction injectedServerUrl(): string {\n const env = (import.meta as { env?: { PARLOR_SERVER_URL?: string } }).env;\n return env?.PARLOR_SERVER_URL ?? \"\";\n}\n\nexport function generateClientId(): string {\n return globalThis.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2);\n}\n\nexport type HeadersProvider = HeadersInit | (() => HeadersInit | Promise<HeadersInit>);\n\nexport interface ActionClientOptions {\n readonly baseUrl?: string | undefined;\n readonly basePath?: string | undefined;\n readonly fetch?: typeof fetch | undefined;\n readonly headers?: HeadersProvider | undefined;\n readonly clientId?: string | undefined;\n}\n\nexport interface CallOptions {\n readonly signal?: AbortSignal | undefined;\n /** For a write: the reads the page shows, to answer with fresh the ones it changed. */\n readonly refresh?: readonly ReadRequest[] | undefined;\n}\n\nexport interface ActionEnvelope<T> {\n readonly data: T;\n readonly tags: readonly Tag[];\n /** The sync cursor a read's data reflects, when the server tracks it. */\n readonly cursor?: string | undefined;\n /** For a call with `refresh`, when the server knows it: what the write changed. */\n readonly writes?: readonly Tag[] | undefined;\n /** For a call with `refresh`, when the server knows it: each read named, in order. */\n readonly refreshed?: readonly RefreshedRead[] | undefined;\n}\n\nexport interface ActionClient<T extends ActionMap> {\n readonly clientId: string;\n readonly basePath: string;\n call<K extends keyof T & string>(\n name: K,\n input: ActionInput<T[K]>,\n options?: CallOptions,\n ): Promise<ActionOutput<T[K]>>;\n invoke<K extends keyof T & string>(\n name: K,\n input: ActionInput<T[K]>,\n options?: CallOptions,\n ): Promise<ActionEnvelope<ActionOutput<T[K]>>>;\n request(path: string, init?: RequestInit): Promise<Response>;\n}\n\nasync function resolveHeaders(\n provider: HeadersProvider | undefined,\n clientId: string,\n extra?: HeadersInit,\n): Promise<Headers> {\n const headers = new Headers(\n typeof provider === \"function\" ? await provider() : provider,\n );\n new Headers(extra).forEach((value, key) => headers.set(key, value));\n headers.set(SOURCE_HEADER, \"ui\");\n headers.set(CLIENT_HEADER, clientId);\n return headers;\n}\n\nexport async function toActionError(\n response: Response,\n options: { readonly missingIsNotFound?: boolean } = {},\n): Promise<ActionError> {\n const body: unknown = await response.json().catch(() => undefined);\n if (ActionError.isBody(body)) return ActionError.fromBody(body);\n const code =\n options.missingIsNotFound && response.status === 404 ? \"not_found\" : \"internal\";\n return new ActionError(code, `Action request failed with HTTP ${response.status}`);\n}\n\nexport async function invokeAt<T extends ActionMap, K extends keyof T & string>(\n request: ActionClient<ActionMap>[\"request\"],\n path: string,\n input: ActionInput<T[K]>,\n options: CallOptions & { readonly missingIsNotFound?: boolean } = {},\n): Promise<ActionEnvelope<ActionOutput<T[K]>>> {\n const response = await request(path, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n ...(options.refresh?.length\n ? { [REFRESH_HEADER]: encodeReadRequests(options.refresh) }\n : {}),\n },\n body: JSON.stringify(input ?? {}),\n signal: options.signal ?? null,\n });\n if (!response.ok) {\n throw await toActionError(\n response,\n options.missingIsNotFound ? { missingIsNotFound: true } : {},\n );\n }\n const body = (await response.json()) as {\n data: ActionOutput<T[K]>;\n tags?: Tag[];\n cursor?: string;\n writes?: Tag[];\n refreshed?: RefreshedRead[];\n };\n return {\n data: body.data,\n tags: body.tags ?? [],\n ...(typeof body.cursor === \"string\" ? { cursor: body.cursor } : {}),\n ...(Array.isArray(body.writes) && Array.isArray(body.refreshed)\n ? { writes: body.writes, refreshed: body.refreshed }\n : {}),\n };\n}\n\nexport function resolveServerOrigin(): string {\n return injectedServerUrl() || globalThis.location?.origin || \"\";\n}\n\nfunction injectedAppOrigin(): string {\n const env = (import.meta as { env?: { PARLOR_APP_ORIGIN?: string } }).env;\n return env?.PARLOR_APP_ORIGIN ?? \"\";\n}\n\n/**\n * The one name of this app's backend on every surface: the page's own origin when it is\n * served over http(s) and is not a shell's webview origin, else the shell's `server.url`.\n * `parlor dev` running several targets names the web target's origin for all of them.\n * Statements are signed for it and the host is paired with it.\n */\nexport function appOrigin(\n serverUrl: string = resolveServerOrigin(),\n injected: string = injectedAppOrigin(),\n): string {\n if (injected) return new URL(injected).origin;\n const page = globalThis.location?.origin ?? \"\";\n if (/^https?:\\/\\//.test(page) && !SHELL_ORIGINS.includes(page)) return page;\n try {\n return new URL(serverUrl).origin;\n } catch {\n return serverUrl;\n }\n}\n\nexport function createActionClient<T extends ActionMap>(\n options: ActionClientOptions = {},\n): ActionClient<T> {\n const {\n baseUrl = injectedServerUrl(),\n basePath = DEFAULT_BASE_PATH,\n headers,\n } = options;\n // Drawn on first use: workerd allows no random values while a module loads.\n let clientId = options.clientId;\n const ownId = () => (clientId ??= generateClientId());\n const fetchImpl = options.fetch ?? globalThis.fetch;\n\n const request = async (path: string, init: RequestInit = {}) =>\n fetchImpl(`${baseUrl}${path}`, {\n ...init,\n headers: await resolveHeaders(headers, ownId(), init.headers),\n });\n\n const invoke = async <K extends keyof T & string>(\n name: K,\n input: ActionInput<T[K]>,\n callOptions: CallOptions = {},\n ): Promise<ActionEnvelope<ActionOutput<T[K]>>> => {\n return invokeAt<T, K>(request, `${basePath}/actions/${name}`, input, callOptions);\n };\n\n return {\n get clientId() {\n return ownId();\n },\n basePath,\n request,\n invoke,\n call: async (name, input, callOptions) =>\n (await invoke(name, input, callOptions)).data,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/react/chat/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/react/chat/runtime.ts"],"names":[],"mappings":"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"}
@@ -67,6 +67,8 @@ export function createChatRuntime(deps) {
67
67
  let optionChoices = readOptionChoices();
68
68
  let sending = false;
69
69
  let pendingSend;
70
+ /** The prompt in flight, shown in its thread until the server's copy arrives. */
71
+ let shownSend;
70
72
  let startedNew = false;
71
73
  let connect = {
72
74
  kind: "command",
@@ -185,6 +187,27 @@ export function createChatRuntime(deps) {
185
187
  hosts.some((host) => host.id === turn.agent.hostId && !host.online));
186
188
  return offline && waitOn("offline", offline.agent.hostId);
187
189
  };
190
+ const withShownSend = (folded) => {
191
+ if (shownSend && items.has(shownSend.itemId))
192
+ shownSend = undefined;
193
+ const shown = shownSend;
194
+ if (!shown || (threadId !== shown.openedIn && threadId !== shown.threadId)) {
195
+ return folded;
196
+ }
197
+ const [hostId, agentId] = shown.agent.split("/");
198
+ const row = {
199
+ kind: "prompt",
200
+ id: shown.itemId,
201
+ turnId: shown.turnId,
202
+ text: shown.text,
203
+ agent: { hostId: asId("host", hostId), agentId },
204
+ state: "queued",
205
+ failure: undefined,
206
+ mine: true,
207
+ sending: true,
208
+ };
209
+ return [...folded, row];
210
+ };
188
211
  const compute = () => {
189
212
  const agents = choices();
190
213
  const wanted = chosen ??
@@ -217,13 +240,15 @@ export function createChatRuntime(deps) {
217
240
  moreThreads,
218
241
  hasOlder,
219
242
  loadingOlder,
220
- items: foldThread({
243
+ items: withShownSend(foldThread({
221
244
  items: [...items.values()].sort(bySeq),
222
245
  open: [...open.turns.values()],
223
246
  turns,
224
- confirmations: agentUi.confirmations.get().filter((c) => c.threadId === threadId),
247
+ confirmations: agentUi.confirmations
248
+ .get()
249
+ .filter((c) => c.threadId === threadId),
225
250
  deviceId: device?.id,
226
- }),
251
+ })),
227
252
  hosts,
228
253
  agents,
229
254
  agent,
@@ -541,6 +566,7 @@ export function createChatRuntime(deps) {
541
566
  open = NO_OPEN_TURNS;
542
567
  beforeLoad = [];
543
568
  pendingSend = undefined;
569
+ shownSend = undefined;
544
570
  stopIds.clear();
545
571
  answerIds.clear();
546
572
  dirty = false;
@@ -586,11 +612,26 @@ export function createChatRuntime(deps) {
586
612
  turnId: mint("turn"),
587
613
  itemId: mint("item"),
588
614
  });
589
- await whenSetUp(() => submit(attempt, target.key, () => {
590
- pendingSend = undefined;
615
+ await whenSetUp(async () => {
616
+ let delivered = false;
617
+ shownSend = attempt;
591
618
  if (draft.trim() === prompt)
592
619
  draft = "";
593
- }));
620
+ emit();
621
+ try {
622
+ await submit(attempt, target.key, () => {
623
+ delivered = true;
624
+ pendingSend = undefined;
625
+ });
626
+ }
627
+ finally {
628
+ if (!delivered && shownSend === attempt) {
629
+ shownSend = undefined;
630
+ draft = draft.trim() === "" ? attempt.text : `${attempt.text}\n\n${draft}`;
631
+ emit();
632
+ }
633
+ }
634
+ });
594
635
  },
595
636
  async loadOlder() {
596
637
  const target = threadId;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/react/chat/runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentConfirmation, AgentUiClient } from \"@parlor/agent-ui/client\";\nimport type { CapabilityHandle, LocalAgentHost } from \"@parlor/capabilities\";\nimport {\n type AgentOption,\n type AgentUsage,\n CHAT_CHANNEL,\n CHAT_TAG,\n type ChatFrame,\n type AnswerToSign,\n type ChatItem,\n foldThread,\n type HostSummary,\n HOSTS_TAG,\n isPromptTooLong,\n type ItemSignature,\n type LoggedItem,\n parseChatFrame,\n PROMPT_LIMIT_MESSAGE,\n type PromptToSign,\n type ThreadSummary,\n type TurnStatus,\n} from \"@parlor/chat\";\nimport type { ChatUserActionMap } from \"@parlor/chat/server\";\nimport {\n ActionError,\n asId,\n type ItemId,\n type Tag,\n tagsOverlap,\n type ThreadId,\n type TurnId,\n} from \"@parlor/core\";\nimport type { ClientChannel } from \"@parlor/sync\";\n\nimport { generateClientId } from \"../../action-client.js\";\nimport type { PluginClient } from \"../../plugin-client.js\";\nimport type {\n ComputerDisconnector,\n DeviceLinker,\n DeviceSource,\n HostAuthorizer,\n SessionDevice,\n} from \"../../session.js\";\nimport {\n applyFrame,\n mergeSnapshot,\n NO_OPEN_TURNS,\n type OpenTurns,\n pruneOpen,\n} from \"./open-turns.js\";\n\n/** One agent the user can talk to; `key` is `<hostId>/<agentId>`. */\nexport interface AgentChoice {\n readonly key: string;\n readonly name: string;\n readonly hostName: string;\n readonly online: boolean;\n readonly ready: boolean;\n readonly problem: string | undefined;\n /** What a prompt to this agent may choose, such as its model; empty until it has said. */\n readonly options: readonly AgentChoiceOption[];\n /** The account's allowance, as the agent last reported it. */\n readonly usage: AgentUsage | undefined;\n /** The name this agent knows the app by outside the sidebar, when the user let it use the app there. */\n readonly outsideName: string | undefined;\n}\n\nexport interface AgentChoiceOption extends AgentOption {\n /** The value the next prompt runs with: this device's choice, or the agent's own. */\n readonly selected: string;\n}\n\n/** How this client adds a computer, decided by the `localAgentHost` capability. */\nexport type ConnectOption =\n | { readonly kind: \"command\"; readonly command: string }\n | { readonly kind: \"here\"; start(): Promise<void> };\n\n/**\n * `waiting`: a prompt waits for a computer, which `ChatState.wait` names: one that must\n * still approve this device, or one that is offline while the prompt queues.\n * `unavailable`: this backend has no chat, this user may not use it, or the first read\n * failed and is being retried; `ChatState.unavailable` says which.\n */\nexport type ChatStatus =\n | \"loading\"\n | \"idle\"\n | \"sending\"\n | \"waiting\"\n | \"running\"\n | \"unavailable\";\n\n/**\n * Why chat is `unavailable`: `forbidden` when the app's chat `access` refuses this user,\n * so the agent should not show at all; `not_found` when the server has no chat;\n * `unauthenticated` when nobody is signed in; `error` while a failed read is retried.\n */\nexport interface ChatUnavailable {\n readonly reason: \"forbidden\" | \"not_found\" | \"unauthenticated\" | \"error\";\n}\n\nexport interface ChatWait {\n readonly reason: \"offline\" | \"approval\";\n readonly hostId: string;\n readonly hostName: string;\n}\n\n/**\n * Whether this device may send: `linked` (or nothing to link), `checking` until it knows, or\n * `unlinked` with the code it shows once `startLink` made one. A device links once, from a\n * device already linked or from the computer.\n */\nexport type LinkState =\n | { readonly status: \"linked\" | \"checking\" }\n | {\n readonly status: \"unlinked\";\n readonly hostName: string;\n readonly code?: string | undefined;\n /** What a linked phone's camera opens to link this device: `<app>/link#d=…&c=…`. */\n readonly qr?: string | undefined;\n /** What to run on the computer to link this device there instead, while `code` is shown. */\n readonly command?: string | undefined;\n readonly expiresAt?: string | undefined;\n /** The code shown last ran out; `startLink` shows a new one. */\n readonly expired: boolean;\n /** No other device is linked yet to link this one, so only the computer can, with `command`. */\n readonly onlyComputer: boolean;\n readonly busy: boolean;\n readonly error?: string | undefined;\n };\n\n/**\n * Set while an action waits for this device to be set up: on a browser, the first prompt\n * would otherwise open a passkey prompt with no warning. `explain` until the user picks,\n * `passkey` while the browser asks, `cancelled` once they dismissed it.\n */\nexport interface DeviceSetup {\n readonly step: \"explain\" | \"passkey\" | \"cancelled\";\n}\n\nexport interface ChatState {\n readonly status: ChatStatus;\n /** Set exactly while `status` is `waiting`; approval wins when both reasons hold. */\n readonly wait: ChatWait | undefined;\n /** Set exactly while `status` is `unavailable`. */\n readonly unavailable: ChatUnavailable | undefined;\n readonly thread: ThreadSummary | undefined;\n readonly threads: readonly ThreadSummary[];\n /** Older threads exist past `threads`; `loadMoreThreads` reads them. */\n readonly moreThreads: boolean;\n readonly items: readonly ChatItem<AgentConfirmation>[];\n /** The thread has items before the first one shown; `loadOlder` reads them. */\n readonly hasOlder: boolean;\n /** Set while `loadOlder` or `loadMoreThreads` reads. */\n readonly loadingOlder: boolean;\n readonly hosts: readonly HostSummary[];\n readonly agents: readonly AgentChoice[];\n readonly agent: AgentChoice | undefined;\n readonly connect: ConnectOption;\n readonly draft: string;\n /** Why the last send, stop or answer failed; cleared by the next one that succeeds. */\n readonly error: string | undefined;\n readonly setup: DeviceSetup | undefined;\n readonly link: LinkState;\n /**\n * The chosen agent's computer wants this device to confirm it is the user again, so\n * sending asks for Face ID or Touch ID first.\n */\n readonly presenceDue: boolean;\n}\n\nexport interface ChatCommands {\n setDraft(text: string): void;\n /** Signs the draft (or `text`) and sends it to the chosen agent; idempotent per call. */\n send(text?: string): Promise<void>;\n stop(): Promise<void>;\n /** Sends a prompt again as a new turn in its thread, signed anew. */\n resend(promptItemId: string): Promise<void>;\n /** Reads the thread's next earlier page while `hasOlder`. */\n loadOlder(): Promise<void>;\n /** Reads the next older threads while `moreThreads`. */\n loadMoreThreads(): Promise<void>;\n /** A `presence` ask triggers the OS prompt first; a `computer` ask refuses. */\n answer(\n askId: string,\n choice: string,\n values?: Readonly<Record<string, string | number | boolean>>,\n ): Promise<void>;\n choose(agentKey: string): void;\n /** Chooses a value of the chosen agent's option for this device's next prompts to it. */\n setOption(optionId: string, value: string): void;\n /** Disconnects a computer: its agents leave the sidebar and stop using the app outside it. */\n disconnect(hostId: string): Promise<void>;\n /** `undefined` opens the most recent thread, if there is one. */\n openThread(threadId: string | undefined): void;\n /** Starts a blank thread; it exists on the server once the first prompt is sent. */\n newThread(): void;\n /** Shows this device's link code, after Face ID or Touch ID unless `presence` is false. */\n startLink(options?: { readonly presence?: boolean }): Promise<void>;\n}\n\nexport interface DeviceSetupCommands {\n /** Sets this device up, with a passkey or without one, then runs what waited for it. */\n setUpDevice(options: { readonly passkey: boolean }): Promise<void>;\n /** Drops what waited for the setup; the draft stays. */\n dismissSetup(): void;\n}\n\nexport interface ChatRuntime extends ChatCommands, DeviceSetupCommands {\n subscribe(listener: () => void): () => void;\n get(): ChatState;\n start(): () => void;\n /**\n * Called by a UI that explains the device setup, until it unmounts. Without one, the first\n * prompt enrolls the device directly, as before.\n */\n explainSetup(): () => void;\n}\n\nexport interface ChatRuntimeDeps {\n readonly calls: PluginClient<ChatUserActionMap>;\n readonly clientId: string;\n readonly appOrigin: string;\n readonly agentUi: AgentUiClient;\n readonly addChannel: (channel: ClientChannel) => () => void;\n readonly onSyncTags: (listener: (tags: readonly Tag[]) => void) => () => void;\n readonly onResume: (listener: () => void) => () => void;\n /** What the server negotiated for sync; `undefined` until it has. */\n readonly transport: () => \"sse\" | \"poll\" | undefined;\n readonly onNegotiated: (listener: (transport: \"sse\" | \"poll\") => void) => () => void;\n readonly isHidden?: (() => boolean) | undefined;\n readonly auth:\n | Partial<DeviceSource & HostAuthorizer & DeviceLinker & ComputerDisconnector>\n | undefined;\n readonly localHost: Promise<CapabilityHandle<LocalAgentHost>>;\n readonly threadId: string | undefined;\n}\n\nexport const HOST_GRANTS_TAG = \"parlor_auth_hosts\";\nexport const DEVICES_TAG = \"parlor_auth_devices\";\n\nconst LINKED: LinkState = { status: \"linked\" };\nconst CHECKING: LinkState = { status: \"checking\" };\n\nconst READ_RETRY_BASE_MS = 1_000;\nconst READ_RETRY_MAX_MS = 30_000;\nconst ACTIVITY_PING_MS = 60_000;\nconst UNFIXABLE_BY_RETRY: ReadonlySet<string> = new Set([\n \"not_found\",\n \"unauthenticated\",\n \"forbidden\",\n]);\n\nconst retryable = (error: unknown) =>\n !(error instanceof ActionError && UNFIXABLE_BY_RETRY.has(error.code));\n\nconst unavailableBecause = (error: unknown): ChatUnavailable[\"reason\"] =>\n error instanceof ActionError &&\n (error.code === \"forbidden\" ||\n error.code === \"not_found\" ||\n error.code === \"unauthenticated\")\n ? error.code\n : \"error\";\n\ntype StaleRead = \"lists\" | \"hosts\";\n\ninterface PendingSend {\n readonly text: string;\n readonly agent: string;\n readonly openedIn: ThreadId | undefined;\n readonly threadId: ThreadId;\n readonly turnId: TurnId;\n readonly itemId: ItemId;\n}\n\nconst mint = <K extends \"thread\" | \"turn\" | \"item\">(kind: K) =>\n asId(kind, generateClientId());\n\nconst isActive = (turn: TurnStatus) =>\n turn.state === \"queued\" || turn.state === \"running\";\n\nconst exceedsPromptLimit = (error: ActionError): boolean =>\n error.issues?.some(\n (issue) => issue.code === \"too_big\" && issue.path.join(\".\") === \"prompt.text\",\n ) ?? false;\n\nclass NeedsDevice extends Error {\n override readonly name = \"NeedsDevice\";\n}\n\n/** Prompts are signed with presence this long before the computer's deadline, for clock skew. */\nconst PRESENCE_MARGIN_MS = 10 * 60_000;\nconst LONGEST_TIMEOUT_MS = 2 ** 31 - 1;\n\nconst readable = (error: unknown): string => {\n if (error instanceof NeedsDevice) return error.message;\n if (error instanceof Error && error.name === \"NotAllowedError\") {\n return \"Face ID or Touch ID was cancelled.\";\n }\n if (!(error instanceof ActionError)) return \"Could not reach the server.\";\n if (error.issues === undefined) return error.message;\n return exceedsPromptLimit(error)\n ? PROMPT_LIMIT_MESSAGE\n : \"That message could not be sent. Try again.\";\n};\n\nconst bySeq = (a: LoggedItem, b: LoggedItem) => a.seq - b.seq;\n\nexport function createChatRuntime(deps: ChatRuntimeDeps): ChatRuntime {\n const { calls, agentUi } = deps;\n const listeners = new Set<() => void>();\n\n let threadId = deps.threadId === undefined ? undefined : asId(\"thread\", deps.threadId);\n let loaded: \"no\" | \"yes\" | \"failed\" = \"no\";\n let thread: ThreadSummary | undefined;\n let threads: readonly ThreadSummary[] = [];\n let olderThreads: readonly ThreadSummary[] = [];\n let moreThreads = false;\n let hasOlder = false;\n let loadingOlder = false;\n let hosts: readonly HostSummary[] = [];\n let items = new Map<string, LoggedItem>();\n let turns: readonly TurnStatus[] = [];\n let open: OpenTurns = NO_OPEN_TURNS;\n let beforeLoad: ChatFrame[] = [];\n let draft = \"\";\n let failure: string | undefined;\n let chosen: string | undefined;\n let optionChoices = readOptionChoices();\n let sending = false;\n let pendingSend: PendingSend | undefined;\n let startedNew = false;\n let connect: ConnectOption = {\n kind: \"command\",\n command: `npx @parlor/agent-host connect ${deps.appOrigin}`,\n };\n let stopWatching: (() => void) | undefined;\n let watched: ThreadId | undefined;\n let running = false;\n let channelOpen = false;\n let staleAfterLoad = false;\n let dirty = false;\n const staleReads = new Set<StaleRead>();\n let unfixable = false;\n let unavailable: ChatUnavailable | undefined;\n let retryTimer: ReturnType<typeof setTimeout> | undefined;\n let retryDelay = READ_RETRY_BASE_MS;\n let lastPing: number | undefined;\n let pingRefused = false;\n let generation = 0;\n let device: SessionDevice | undefined;\n let linkInfo: Awaited<ReturnType<DeviceLinker[\"linkState\"]>> | undefined;\n let linking:\n | {\n readonly deviceId: string;\n readonly code: string;\n readonly qr: string;\n readonly expiresAt: string;\n }\n | undefined;\n let linkBusy = false;\n let linkError: string | undefined;\n let linkExpired = false;\n let linkTimer: ReturnType<typeof setTimeout> | undefined;\n let presenceTimer: ReturnType<typeof setTimeout> | undefined;\n let setup: DeviceSetup | undefined;\n let afterSetup: (() => Promise<void>) | undefined;\n let explainers = 0;\n const resends = new Map<ItemId, PendingSend>();\n const answerIds = new Map<string, ItemId>();\n const stopIds = new Map<TurnId, ItemId>();\n\n const refusedLast = (hostId: string, deviceId: string): boolean => {\n const last = [...turns].reverse().find((turn) => turn.agent.hostId === hostId);\n if (last?.failure !== \"device_rejected\") return false;\n return [...items.values()].some(\n (item) =>\n item.turnId === last.turnId &&\n item.kind === \"prompt\" &&\n item.body.signed?.deviceId === deviceId,\n );\n };\n\n /**\n * When the computer behind `agentKey` wants this device's next prompt signed with presence:\n * by its report, or now if it refused this device's last prompt, whatever the clocks say.\n */\n const presenceDueAt = (agentKey: string): number | undefined => {\n const deviceId = device?.id ?? linkInfo?.deviceId;\n if (deviceId === undefined) return undefined;\n const hostId = agentKey.split(\"/\")[0]!;\n const due = hosts.find((host) => host.id === hostId)?.presenceDue?.[deviceId];\n if (due === undefined) return undefined;\n return refusedLast(hostId, deviceId) ? 0 : due - PRESENCE_MARGIN_MS;\n };\n\n /** This device's choices for `agentKey` that its agent still offers. */\n const chosenOptions = (\n agentKey: string,\n options: readonly AgentOption[],\n ): Record<string, string> =>\n Object.fromEntries(\n Object.entries(optionChoices[agentKey] ?? {}).filter(([id, value]) =>\n options.some(\n (option) =>\n option.id === id && option.values.some((candidate) => candidate.id === value),\n ),\n ),\n );\n\n const choices = (): AgentChoice[] =>\n hosts.flatMap((host) =>\n host.agents.map((agent) => {\n const key = `${host.id}/${agent.id}`;\n const offered = agent.options ?? [];\n const picked = chosenOptions(key, offered);\n return {\n key,\n name: agent.name,\n hostName: host.name,\n online: host.online,\n ready: agent.ready,\n problem: agent.problem,\n options: offered.map((option) => ({\n ...option,\n selected: picked[option.id] ?? option.current,\n })),\n usage: agent.usage,\n outsideName: agent.outsideName,\n };\n }),\n );\n\n const waitOn = (reason: ChatWait[\"reason\"], hostId: string): ChatWait => ({\n reason,\n hostId,\n hostName: hosts.find((host) => host.id === hostId)?.name ?? \"your computer\",\n });\n\n const linkOf = (): LinkState => {\n if (!deps.auth?.linkState) return LINKED;\n const reporting = hosts.filter((host) => host.online && host.devices !== undefined);\n if (reporting.length === 0) return LINKED;\n if (!linkInfo) return CHECKING;\n const { deviceId } = linkInfo;\n if (\n linkInfo.pairing ||\n linkInfo.vouched ||\n (deviceId !== undefined &&\n reporting.some((host) => host.devices?.includes(deviceId)))\n ) {\n return LINKED;\n }\n const listing = hosts.filter((host) => host.devices !== undefined);\n return {\n status: \"unlinked\",\n hostName: reporting[0]!.name,\n code: linking?.code,\n qr: linking?.qr,\n command: linking && `npx @parlor/agent-host link ${deps.appOrigin} ${linking.code}`,\n expiresAt: linking?.expiresAt,\n expired: linkExpired,\n onlyComputer: listing.every((host) => host.devices!.every((id) => id === deviceId)),\n busy: linkBusy,\n error: linkError,\n };\n };\n\n const waitOf = (): ChatWait | undefined => {\n const approving = turns.find(awaitsApproval);\n if (approving) return waitOn(\"approval\", approving.agent.hostId);\n const offline = turns.find(\n (turn) =>\n turn.state === \"queued\" &&\n hosts.some((host) => host.id === turn.agent.hostId && !host.online),\n );\n return offline && waitOn(\"offline\", offline.agent.hostId);\n };\n\n const compute = (): ChatState => {\n const agents = choices();\n const wanted =\n chosen ??\n (thread?.agent ? `${thread.agent.hostId}/${thread.agent.agentId}` : undefined);\n const agent =\n agents.find((choice) => choice.key === wanted) ??\n agents.find((choice) => choice.online && choice.ready) ??\n agents[0];\n const wait = loaded === \"yes\" && !sending ? waitOf() : undefined;\n const due = agent && presenceDueAt(agent.key);\n const status: ChatStatus =\n loaded === \"failed\"\n ? \"unavailable\"\n : loaded === \"no\"\n ? \"loading\"\n : sending\n ? \"sending\"\n : wait\n ? \"waiting\"\n : turns.some(isActive) || open.turns.size > 0\n ? \"running\"\n : \"idle\";\n return {\n status,\n wait,\n unavailable: loaded === \"failed\" ? unavailable : undefined,\n thread,\n threads: [\n ...threads,\n ...olderThreads.filter(\n (older) => !threads.some((shown) => shown.id === older.id),\n ),\n ],\n moreThreads,\n hasOlder,\n loadingOlder,\n items: foldThread({\n items: [...items.values()].sort(bySeq),\n open: [...open.turns.values()],\n turns,\n confirmations: agentUi.confirmations.get().filter((c) => c.threadId === threadId),\n deviceId: device?.id,\n }),\n hosts,\n agents,\n agent,\n connect,\n draft,\n error: failure,\n setup,\n link: linkOf(),\n presenceDue: due !== undefined && Date.now() >= due,\n };\n };\n\n /** Re-emits once the chosen computer's presence deadline arrives, so the hint shows unprompted. */\n const watchPresence = () => {\n clearTimeout(presenceTimer);\n presenceTimer = undefined;\n const due = running && state.agent ? presenceDueAt(state.agent.key) : undefined;\n if (due === undefined || state.presenceDue) return;\n presenceTimer = setTimeout(emit, Math.min(due - Date.now(), LONGEST_TIMEOUT_MS));\n };\n\n let state = compute();\n const emit = () => {\n state = compute();\n watchPresence();\n for (const listener of [...listeners]) listener();\n };\n\n const watch = () => {\n if (watched === threadId) return;\n stopWatching?.();\n watched = threadId;\n stopWatching = threadId === undefined ? undefined : agentUi.watch(threadId);\n };\n\n const absorb = (page: {\n readonly items: readonly LoggedItem[];\n readonly turns?: readonly TurnStatus[] | undefined;\n }) => {\n items = new Map(items);\n for (const item of page.items) items.set(item.id, item);\n if (page.turns) {\n const fresh = new Map(page.turns.map((turn) => [turn.turnId, turn]));\n turns = [...turns.filter((turn) => !fresh.has(turn.turnId)), ...page.turns];\n }\n open = pruneOpen(open, items, turns);\n };\n\n const oldestSeq = (): number | undefined =>\n items.size === 0\n ? undefined\n : Math.min(...[...items.values()].map((item) => item.seq));\n\n const takeThreads = (snapshot: {\n readonly threads: readonly ThreadSummary[];\n readonly moreThreads?: boolean | undefined;\n }) => {\n threads = snapshot.threads;\n if (olderThreads.length === 0) moreThreads = snapshot.moreThreads === true;\n };\n\n const load = async (target: ThreadId | undefined) => {\n const epoch = generation;\n const snapshot = await calls.call(\"open\", target ? { threadId: target } : {});\n if (epoch !== generation) return;\n staleReads.clear();\n takeThreads(snapshot);\n hosts = snapshot.hosts;\n const page = startedNew && target === undefined ? undefined : snapshot.page;\n thread = page?.thread;\n threadId = page?.thread?.id ?? target;\n if (page) {\n const oldest = oldestSeq();\n absorb(page);\n const first = page.items[0];\n if (oldest === undefined || (first !== undefined && first.seq <= oldest)) {\n hasOlder = page.hasMore;\n }\n }\n open = mergeSnapshot(open, channelOpen && page ? page.open : []);\n const replay = beforeLoad;\n beforeLoad = [];\n loaded = \"yes\";\n retryDelay = READ_RETRY_BASE_MS;\n for (const frame of replay) {\n if (frame.threadId === threadId) open = applyFrame(open, frame);\n }\n open = pruneOpen(open, items, turns);\n watch();\n };\n\n const refreshLists = async () => {\n const epoch = generation;\n const fresh = await calls.call(\"open\", {});\n if (epoch !== generation || threadId !== undefined) return;\n takeThreads(fresh);\n hosts = fresh.hosts;\n emit();\n };\n\n const refreshHosts = async () => {\n const fresh = await calls.call(\"hosts\", {});\n hosts = fresh;\n emit();\n };\n\n const readLists = async () => {\n if (threadId === undefined && !startedNew && draft.trim() === \"\") {\n await load(undefined);\n emit();\n } else await refreshLists();\n };\n\n const staleReaders: Record<StaleRead, () => Promise<void>> = {\n lists: readLists,\n hosts: refreshHosts,\n };\n\n const cancelRetry = () => {\n if (retryTimer !== undefined) globalThis.clearTimeout(retryTimer);\n retryTimer = undefined;\n };\n\n const clearRetry = () => {\n cancelRetry();\n retryDelay = READ_RETRY_BASE_MS;\n };\n\n const scheduleRetry = () => {\n if (!running || retryTimer !== undefined) return;\n const wait = retryDelay;\n retryDelay = Math.min(retryDelay * 2, READ_RETRY_MAX_MS);\n retryTimer = globalThis.setTimeout(() => {\n retryTimer = undefined;\n void mend();\n }, wait);\n };\n\n const settled = () => {\n if (!dirty && staleReads.size === 0) clearRetry();\n };\n\n const rereadStale = async (kind: StaleRead) => {\n const epoch = generation;\n try {\n await staleReaders[kind]();\n staleReads.delete(kind);\n settled();\n } catch (error) {\n if (epoch !== generation) return;\n staleReads.add(kind);\n if (retryable(error)) scheduleRetry();\n }\n };\n\n let refreshing = false;\n let refreshAgain = false;\n const refresh = async () => {\n if (refreshing) {\n refreshAgain = true;\n return;\n }\n refreshing = true;\n try {\n do {\n refreshAgain = false;\n if (loaded !== \"yes\" || threadId === undefined) break;\n const epoch = generation;\n const target = threadId;\n if (turns.some(isActive)) {\n await load(target);\n } else {\n const lastSeq = Math.max(0, ...[...items.values()].map((item) => item.seq));\n const fresh = await calls.call(\"items\", {\n threadId: target,\n afterSeq: lastSeq,\n });\n if (epoch !== generation) break;\n absorb({ items: fresh });\n const known = new Set(turns.map((turn) => turn.turnId));\n if (fresh.some((item) => !known.has(item.turnId))) await load(target);\n }\n dirty = false;\n settled();\n emit();\n } while (refreshAgain);\n } catch (error) {\n refreshAgain = false;\n dirty = true;\n if (retryable(error)) scheduleRetry();\n } finally {\n refreshing = false;\n }\n };\n\n const reporting = async (command: () => Promise<void>) => {\n try {\n await command();\n } catch (error) {\n failure = readable(error);\n emit();\n throw error;\n }\n if (failure !== undefined) {\n failure = undefined;\n emit();\n }\n };\n\n const awaitsApproval = (turn: TurnStatus): boolean => {\n if (!isActive(turn)) return false;\n let waiting = false;\n for (const item of [...items.values()].sort(bySeq)) {\n if (item.turnId !== turn.turnId) continue;\n if (item.kind === \"event\" && item.body.event === \"device_pending\") waiting = true;\n else if (item.author !== \"user\") waiting = false;\n }\n return waiting;\n };\n\n const deviceOf = async (): Promise<SessionDevice | undefined> => {\n const found = await deps.auth?.device?.();\n device = found ?? device;\n return found;\n };\n\n const refreshLink = async () => {\n if (!deps.auth?.linkState) return;\n try {\n linkInfo = await deps.auth.linkState();\n } catch {\n return;\n }\n if (linking && linking.deviceId !== linkInfo.deviceId) linking = undefined;\n emit();\n };\n\n const whenSetUp = async (action: () => Promise<void>): Promise<void> => {\n if (\n explainers > 0 &&\n device === undefined &&\n (await deps.auth?.deviceSetup?.()) === \"needed\"\n ) {\n afterSetup = action;\n setup = { step: \"explain\" };\n emit();\n return;\n }\n await action();\n };\n\n const signPrompt = async (prompt: PromptToSign): Promise<ItemSignature | undefined> => {\n const own = await deviceOf();\n if (!own) return undefined;\n const due = presenceDueAt(`${prompt.agent.hostId}/${prompt.agent.agentId}`);\n return due !== undefined && Date.now() >= due\n ? own.signPrompt(prompt, { presence: true })\n : own.signPrompt(prompt);\n };\n\n const submit = async (\n attempt: PendingSend,\n agentKey: string,\n settle: () => void,\n ): Promise<void> => {\n const [hostId, agentId] = agentKey.split(\"/\") as [string, string];\n const epoch = generation;\n sending = true;\n emit();\n try {\n await reporting(async () => {\n const agent = { hostId: asId(\"host\", hostId), agentId };\n const offered = hosts\n .find((host) => host.id === hostId)\n ?.agents.find((candidate) => candidate.id === agentId)?.options;\n const options = chosenOptions(agentKey, offered ?? []);\n const signed = deps.auth?.device\n ? await signPrompt({\n threadId: attempt.threadId,\n turnId: attempt.turnId,\n agent,\n text: attempt.text,\n })\n : undefined;\n await calls.call(\"send\", {\n threadId: attempt.threadId,\n turnId: attempt.turnId,\n itemId: attempt.itemId,\n clientId: deps.clientId,\n prompt: {\n text: attempt.text,\n agent,\n ...(signed ? { signed } : {}),\n ...(Object.keys(options).length > 0 ? { options } : {}),\n },\n });\n settle();\n if (epoch !== generation) return;\n startedNew = false;\n threadId = attempt.threadId;\n watch();\n await load(threadId);\n });\n } finally {\n sending = false;\n emit();\n }\n };\n\n const activeTurn = (): TurnStatus | undefined => [...turns].reverse().find(isActive);\n\n const switchTo = (target: ThreadId | undefined, blank: boolean) => {\n generation += 1;\n threadId = target;\n startedNew = blank;\n thread = undefined;\n items = new Map();\n turns = [];\n hasOlder = false;\n open = NO_OPEN_TURNS;\n beforeLoad = [];\n pendingSend = undefined;\n stopIds.clear();\n answerIds.clear();\n dirty = false;\n staleReads.clear();\n clearRetry();\n watch();\n if (blank && loaded === \"yes\") {\n emit();\n return;\n }\n loaded = \"no\";\n emit();\n void loadFirst().then(emit);\n };\n\n const runtime: ChatRuntime = {\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n get: () => state,\n setDraft(text) {\n draft = text;\n emit();\n announceActivity();\n },\n async send(text = draft) {\n announceActivity();\n const prompt = text.trim();\n const target = state.agent;\n if (!prompt || isPromptTooLong(prompt) || !target || sending || loaded !== \"yes\") {\n return;\n }\n const retrying =\n pendingSend?.text === prompt &&\n pendingSend.agent === target.key &&\n pendingSend.openedIn === threadId;\n const attempt =\n retrying && pendingSend\n ? pendingSend\n : (pendingSend = {\n text: prompt,\n agent: target.key,\n openedIn: threadId,\n threadId: threadId ?? mint(\"thread\"),\n turnId: mint(\"turn\"),\n itemId: mint(\"item\"),\n });\n await whenSetUp(() =>\n submit(attempt, target.key, () => {\n pendingSend = undefined;\n if (draft.trim() === prompt) draft = \"\";\n }),\n );\n },\n async loadOlder() {\n const target = threadId;\n const before = oldestSeq();\n if (target === undefined || before === undefined || !hasOlder || loadingOlder)\n return;\n const epoch = generation;\n loadingOlder = true;\n emit();\n try {\n await reporting(async () => {\n const older = await calls.call(\"history\", {\n threadId: target,\n beforeSeq: before,\n });\n if (epoch !== generation) return;\n absorb(older);\n hasOlder = older.hasMore;\n });\n } finally {\n loadingOlder = false;\n emit();\n }\n },\n async loadMoreThreads() {\n const last = olderThreads.at(-1) ?? threads.at(-1);\n if (!last || !moreThreads || loadingOlder) return;\n loadingOlder = true;\n emit();\n try {\n await reporting(async () => {\n const next = await calls.call(\"threadsBefore\", {\n before: { updatedAt: last.updatedAt, id: last.id },\n });\n olderThreads = [...olderThreads, ...next.threads];\n moreThreads = next.hasMore;\n });\n } finally {\n loadingOlder = false;\n emit();\n }\n },\n async resend(promptItemId) {\n const prompt = state.items.find(\n (item) => item.kind === \"prompt\" && item.id === promptItemId,\n );\n if (prompt?.kind !== \"prompt\" || sending || loaded !== \"yes\" || !threadId) return;\n const key = `${prompt.agent.hostId}/${prompt.agent.agentId}`;\n let attempt = resends.get(prompt.id);\n if (!attempt) {\n attempt = {\n text: prompt.text,\n agent: key,\n openedIn: threadId,\n threadId,\n turnId: mint(\"turn\"),\n itemId: mint(\"item\"),\n };\n resends.set(prompt.id, attempt);\n }\n await whenSetUp(() => submit(attempt, key, () => resends.delete(prompt.id)));\n },\n async stop() {\n const turn = activeTurn();\n if (!turn || threadId === undefined) return;\n const itemId = stopIds.get(turn.turnId) ?? mint(\"item\");\n stopIds.set(turn.turnId, itemId);\n const target = threadId;\n await reporting(async () => {\n await calls.call(\"cancel\", { threadId: target, turnId: turn.turnId, itemId });\n await refresh();\n });\n },\n async answer(askId, choice, values) {\n const ask = state.items.find((item) => item.kind === \"ask\" && item.id === askId);\n if (!ask || ask.kind !== \"ask\" || ask.answer.state !== \"open\" || !threadId) return;\n if (ask.approval === \"computer\") {\n throw new Error(\"This question is answered on your computer.\");\n }\n const itemId = answerIds.get(askId) ?? mint(\"item\");\n answerIds.set(askId, itemId);\n const target = threadId;\n const toSign: AnswerToSign = {\n threadId: target,\n askId: ask.id,\n choice,\n ...(values ? { values } : {}),\n };\n await whenSetUp(() =>\n reporting(async () => {\n const found = deps.auth?.device ? await deviceOf() : undefined;\n if ((ask.approval === \"presence\" || ask.approval === \"device\") && !found) {\n throw new NeedsDevice(\n \"This question needs a device that can confirm it is you.\",\n );\n }\n const signed = await found?.signAnswer(toSign, {\n presence: ask.approval === \"presence\",\n });\n await calls.call(\"answer\", {\n threadId: target,\n turnId: ask.turnId,\n itemId,\n answer: {\n askId: ask.id,\n choice,\n ...(values ? { values } : {}),\n ...(signed ? { signed } : {}),\n },\n });\n answerIds.delete(askId);\n await refresh();\n }),\n );\n },\n async setUpDevice({ passkey }) {\n if (setup === undefined || setup.step === \"passkey\") return;\n setup = { step: \"passkey\" };\n emit();\n try {\n device = (await deps.auth?.device?.({ presence: passkey })) ?? device;\n } catch (error) {\n if (error instanceof Error && error.name === \"PresenceSetupCancelled\") {\n setup = { step: \"cancelled\" };\n emit();\n return;\n }\n setup = undefined;\n afterSetup = undefined;\n failure = readable(error);\n emit();\n return;\n }\n const waiting = afterSetup;\n setup = undefined;\n afterSetup = undefined;\n emit();\n await waiting?.();\n },\n dismissSetup() {\n setup = undefined;\n afterSetup = undefined;\n emit();\n },\n async startLink(options) {\n if (!deps.auth?.startLink || linkBusy) return;\n linkBusy = true;\n linkError = undefined;\n emit();\n try {\n const started = await deps.auth.startLink(options);\n linking = {\n deviceId: started.deviceId,\n code: started.code,\n qr: `${deps.appOrigin}/link#${new URLSearchParams({ d: started.deviceId, c: started.commitment })}`,\n expiresAt: started.expiresAt,\n };\n linkExpired = false;\n clearTimeout(linkTimer);\n linkTimer = setTimeout(\n () => {\n linking = undefined;\n linkExpired = true;\n emit();\n },\n Math.min(\n Math.max(0, Date.parse(started.expiresAt) - Date.now()),\n LONGEST_TIMEOUT_MS,\n ),\n );\n linkInfo = {\n vouched: false,\n pairing: false,\n ...linkInfo,\n deviceId: started.deviceId,\n };\n } catch (error) {\n linkError =\n error instanceof Error && error.name === \"PresenceSetupCancelled\"\n ? \"Face ID or Touch ID was cancelled. Try again, or link without it.\"\n : readable(error);\n } finally {\n linkBusy = false;\n emit();\n }\n },\n explainSetup() {\n explainers += 1;\n return () => {\n explainers -= 1;\n if (explainers === 0 && setup !== undefined) runtime.dismissSetup();\n };\n },\n choose(agentKey) {\n chosen = agentKey;\n emit();\n },\n async disconnect(hostId) {\n if (!deps.auth?.disconnectComputer) {\n throw new Error(\"This app cannot disconnect computers.\");\n }\n await deps.auth.disconnectComputer(hostId);\n await refreshHosts();\n emit();\n },\n setOption(optionId, value) {\n const agentKey = state.agent?.key;\n if (agentKey === undefined) return;\n optionChoices = {\n ...optionChoices,\n [agentKey]: { ...optionChoices[agentKey], [optionId]: value },\n };\n writeOptionChoices(optionChoices);\n emit();\n },\n openThread(target) {\n switchTo(target === undefined ? undefined : asId(\"thread\", target), false);\n },\n newThread() {\n switchTo(undefined, true);\n },\n start() {\n running = true;\n const detachChannel = deps.addChannel({\n event: CHAT_CHANNEL,\n opened: () => {\n channelOpen = true;\n if (loaded === \"yes\" && turns.some(isActive) && !refreshing) void refresh();\n },\n receive(data) {\n const frame = parseChatFrame(data);\n if (!frame) return;\n if (loaded === \"no\") {\n beforeLoad.push(frame);\n return;\n }\n if (loaded !== \"yes\" || frame.threadId !== threadId) return;\n open = applyFrame(open, frame);\n emit();\n },\n closed: () => {\n channelOpen = false;\n },\n });\n const offTags = deps.onSyncTags((tags) => {\n const mine = tags.some((tag) =>\n tagsOverlap(tag, threadId === undefined ? [CHAT_TAG] : [CHAT_TAG, threadId]),\n );\n const computers = tags.some(\n (tag) => tagsOverlap(tag, [HOSTS_TAG]) || tagsOverlap(tag, [HOST_GRANTS_TAG]),\n );\n if (tags.some((tag) => tagsOverlap(tag, [DEVICES_TAG]))) void refreshLink();\n if (loaded === \"failed\" && (mine || computers)) {\n cancelRetry();\n void loadFirst().then(emit);\n } else if (loaded === \"no\") {\n if (mine || computers) staleAfterLoad = true;\n } else {\n if (mine && threadId !== undefined) void refresh();\n else if (mine) void rereadStale(\"lists\");\n if (computers) void rereadStale(\"hosts\");\n }\n });\n const offResume = deps.onResume(() => {\n if (loaded === \"failed\") {\n if (!unfixable) {\n cancelRetry();\n void loadFirst().then(emit);\n }\n } else if (loaded === \"no\") staleAfterLoad = true;\n else void refresh();\n });\n const offNegotiated = deps.onNegotiated((transport) => {\n if (transport === \"poll\") announceActivity();\n });\n const offConfirmations = agentUi.confirmations.subscribe(emit);\n const offLink = deps.auth?.subscribeLink?.(() => void refreshLink());\n emit();\n announceActivity();\n void initial();\n return () => {\n running = false;\n channelOpen = false;\n generation += 1;\n clearRetry();\n clearTimeout(presenceTimer);\n presenceTimer = undefined;\n clearTimeout(linkTimer);\n linkTimer = undefined;\n detachChannel();\n offTags();\n offResume();\n offNegotiated();\n offConfirmations();\n offLink?.();\n stopWatching?.();\n stopWatching = undefined;\n watched = undefined;\n };\n },\n };\n\n async function mend() {\n if (loaded === \"failed\") await loadFirst();\n else if (loaded === \"yes\") {\n if (dirty) await refresh();\n for (const kind of [...staleReads]) await rereadStale(kind);\n }\n emit();\n }\n\n function announceActivity() {\n if (!running || pingRefused || deps.transport() !== \"poll\") return;\n if (deps.isHidden?.() === true) return;\n const now = Date.now();\n if (lastPing !== undefined && now - lastPing < ACTIVITY_PING_MS) return;\n lastPing = now;\n calls.call(\"userActive\", {}).catch((error: unknown) => {\n if (\n error instanceof ActionError &&\n (error.code === \"not_found\" || error.code === \"forbidden\")\n ) {\n pingRefused = true;\n }\n });\n }\n\n async function loadFirst() {\n try {\n await load(threadId);\n unfixable = false;\n } catch (error) {\n if (running) {\n loaded = \"failed\";\n unavailable = { reason: unavailableBecause(error) };\n unfixable = !retryable(error);\n if (!unfixable) scheduleRetry();\n }\n return;\n }\n if (staleAfterLoad) {\n staleAfterLoad = false;\n await refresh();\n }\n }\n\n async function initial() {\n void deps.localHost.then((handle) => {\n const authorizeHost = deps.auth?.authorizeHost;\n if (!handle.available || !authorizeHost || !running) return;\n connect = {\n kind: \"here\",\n start: async () => {\n const own = await deps.auth?.device?.();\n const outcome = await handle.api.connect({\n appOrigin: deps.appOrigin,\n authorize: authorizeHost,\n ...(own ? { device: own.keys } : {}),\n });\n if (!outcome.connected) throw new Error(`Connecting failed: ${outcome.reason}`);\n await refreshHosts();\n await refreshLink();\n },\n };\n emit();\n });\n void refreshLink();\n await loadFirst();\n announceActivity();\n emit();\n }\n\n return runtime;\n}\n\nconst OPTION_CHOICES_KEY = \"parlor:agent-options\";\n\ntype OptionChoices = Readonly<Record<string, Readonly<Record<string, string>>>>;\n\nfunction readOptionChoices(): OptionChoices {\n try {\n const stored: unknown = JSON.parse(\n globalThis.localStorage?.getItem(OPTION_CHOICES_KEY) ?? \"{}\",\n );\n return stored && typeof stored === \"object\" ? (stored as OptionChoices) : {};\n } catch {\n return {};\n }\n}\n\nfunction writeOptionChoices(choices: OptionChoices): void {\n try {\n globalThis.localStorage?.setItem(OPTION_CHOICES_KEY, JSON.stringify(choices));\n } catch {}\n}\n"]}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/react/chat/runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentConfirmation, AgentUiClient } from \"@parlor/agent-ui/client\";\nimport type { CapabilityHandle, LocalAgentHost } from \"@parlor/capabilities\";\nimport {\n type AgentOption,\n type AgentUsage,\n CHAT_CHANNEL,\n CHAT_TAG,\n type ChatFrame,\n type AnswerToSign,\n type ChatItem,\n foldThread,\n type HostSummary,\n HOSTS_TAG,\n isPromptTooLong,\n type ItemSignature,\n type LoggedItem,\n parseChatFrame,\n PROMPT_LIMIT_MESSAGE,\n type PromptToSign,\n type ThreadSummary,\n type TurnStatus,\n} from \"@parlor/chat\";\nimport type { ChatUserActionMap } from \"@parlor/chat/server\";\nimport {\n ActionError,\n asId,\n type ItemId,\n type Tag,\n tagsOverlap,\n type ThreadId,\n type TurnId,\n} from \"@parlor/core\";\nimport type { ClientChannel } from \"@parlor/sync\";\n\nimport { generateClientId } from \"../../action-client.js\";\nimport type { PluginClient } from \"../../plugin-client.js\";\nimport type {\n ComputerDisconnector,\n DeviceLinker,\n DeviceSource,\n HostAuthorizer,\n SessionDevice,\n} from \"../../session.js\";\nimport {\n applyFrame,\n mergeSnapshot,\n NO_OPEN_TURNS,\n type OpenTurns,\n pruneOpen,\n} from \"./open-turns.js\";\n\n/** One agent the user can talk to; `key` is `<hostId>/<agentId>`. */\nexport interface AgentChoice {\n readonly key: string;\n readonly name: string;\n readonly hostName: string;\n readonly online: boolean;\n readonly ready: boolean;\n readonly problem: string | undefined;\n /** What a prompt to this agent may choose, such as its model; empty until it has said. */\n readonly options: readonly AgentChoiceOption[];\n /** The account's allowance, as the agent last reported it. */\n readonly usage: AgentUsage | undefined;\n /** The name this agent knows the app by outside the sidebar, when the user let it use the app there. */\n readonly outsideName: string | undefined;\n}\n\nexport interface AgentChoiceOption extends AgentOption {\n /** The value the next prompt runs with: this device's choice, or the agent's own. */\n readonly selected: string;\n}\n\n/** How this client adds a computer, decided by the `localAgentHost` capability. */\nexport type ConnectOption =\n | { readonly kind: \"command\"; readonly command: string }\n | { readonly kind: \"here\"; start(): Promise<void> };\n\n/**\n * `waiting`: a prompt waits for a computer, which `ChatState.wait` names: one that must\n * still approve this device, or one that is offline while the prompt queues.\n * `unavailable`: this backend has no chat, this user may not use it, or the first read\n * failed and is being retried; `ChatState.unavailable` says which.\n */\nexport type ChatStatus =\n | \"loading\"\n | \"idle\"\n | \"sending\"\n | \"waiting\"\n | \"running\"\n | \"unavailable\";\n\n/**\n * Why chat is `unavailable`: `forbidden` when the app's chat `access` refuses this user,\n * so the agent should not show at all; `not_found` when the server has no chat;\n * `unauthenticated` when nobody is signed in; `error` while a failed read is retried.\n */\nexport interface ChatUnavailable {\n readonly reason: \"forbidden\" | \"not_found\" | \"unauthenticated\" | \"error\";\n}\n\nexport interface ChatWait {\n readonly reason: \"offline\" | \"approval\";\n readonly hostId: string;\n readonly hostName: string;\n}\n\n/**\n * Whether this device may send: `linked` (or nothing to link), `checking` until it knows, or\n * `unlinked` with the code it shows once `startLink` made one. A device links once, from a\n * device already linked or from the computer.\n */\nexport type LinkState =\n | { readonly status: \"linked\" | \"checking\" }\n | {\n readonly status: \"unlinked\";\n readonly hostName: string;\n readonly code?: string | undefined;\n /** What a linked phone's camera opens to link this device: `<app>/link#d=…&c=…`. */\n readonly qr?: string | undefined;\n /** What to run on the computer to link this device there instead, while `code` is shown. */\n readonly command?: string | undefined;\n readonly expiresAt?: string | undefined;\n /** The code shown last ran out; `startLink` shows a new one. */\n readonly expired: boolean;\n /** No other device is linked yet to link this one, so only the computer can, with `command`. */\n readonly onlyComputer: boolean;\n readonly busy: boolean;\n readonly error?: string | undefined;\n };\n\n/**\n * Set while an action waits for this device to be set up: on a browser, the first prompt\n * would otherwise open a passkey prompt with no warning. `explain` until the user picks,\n * `passkey` while the browser asks, `cancelled` once they dismissed it.\n */\nexport interface DeviceSetup {\n readonly step: \"explain\" | \"passkey\" | \"cancelled\";\n}\n\nexport interface ChatState {\n readonly status: ChatStatus;\n /** Set exactly while `status` is `waiting`; approval wins when both reasons hold. */\n readonly wait: ChatWait | undefined;\n /** Set exactly while `status` is `unavailable`. */\n readonly unavailable: ChatUnavailable | undefined;\n readonly thread: ThreadSummary | undefined;\n readonly threads: readonly ThreadSummary[];\n /** Older threads exist past `threads`; `loadMoreThreads` reads them. */\n readonly moreThreads: boolean;\n readonly items: readonly ChatItem<AgentConfirmation>[];\n /** The thread has items before the first one shown; `loadOlder` reads them. */\n readonly hasOlder: boolean;\n /** Set while `loadOlder` or `loadMoreThreads` reads. */\n readonly loadingOlder: boolean;\n readonly hosts: readonly HostSummary[];\n readonly agents: readonly AgentChoice[];\n readonly agent: AgentChoice | undefined;\n readonly connect: ConnectOption;\n readonly draft: string;\n /** Why the last send, stop or answer failed; cleared by the next one that succeeds. */\n readonly error: string | undefined;\n readonly setup: DeviceSetup | undefined;\n readonly link: LinkState;\n /**\n * The chosen agent's computer wants this device to confirm it is the user again, so\n * sending asks for Face ID or Touch ID first.\n */\n readonly presenceDue: boolean;\n}\n\nexport interface ChatCommands {\n setDraft(text: string): void;\n /** Signs the draft (or `text`) and sends it to the chosen agent; idempotent per call. */\n send(text?: string): Promise<void>;\n stop(): Promise<void>;\n /** Sends a prompt again as a new turn in its thread, signed anew. */\n resend(promptItemId: string): Promise<void>;\n /** Reads the thread's next earlier page while `hasOlder`. */\n loadOlder(): Promise<void>;\n /** Reads the next older threads while `moreThreads`. */\n loadMoreThreads(): Promise<void>;\n /** A `presence` ask triggers the OS prompt first; a `computer` ask refuses. */\n answer(\n askId: string,\n choice: string,\n values?: Readonly<Record<string, string | number | boolean>>,\n ): Promise<void>;\n choose(agentKey: string): void;\n /** Chooses a value of the chosen agent's option for this device's next prompts to it. */\n setOption(optionId: string, value: string): void;\n /** Disconnects a computer: its agents leave the sidebar and stop using the app outside it. */\n disconnect(hostId: string): Promise<void>;\n /** `undefined` opens the most recent thread, if there is one. */\n openThread(threadId: string | undefined): void;\n /** Starts a blank thread; it exists on the server once the first prompt is sent. */\n newThread(): void;\n /** Shows this device's link code, after Face ID or Touch ID unless `presence` is false. */\n startLink(options?: { readonly presence?: boolean }): Promise<void>;\n}\n\nexport interface DeviceSetupCommands {\n /** Sets this device up, with a passkey or without one, then runs what waited for it. */\n setUpDevice(options: { readonly passkey: boolean }): Promise<void>;\n /** Drops what waited for the setup; the draft stays. */\n dismissSetup(): void;\n}\n\nexport interface ChatRuntime extends ChatCommands, DeviceSetupCommands {\n subscribe(listener: () => void): () => void;\n get(): ChatState;\n start(): () => void;\n /**\n * Called by a UI that explains the device setup, until it unmounts. Without one, the first\n * prompt enrolls the device directly, as before.\n */\n explainSetup(): () => void;\n}\n\nexport interface ChatRuntimeDeps {\n readonly calls: PluginClient<ChatUserActionMap>;\n readonly clientId: string;\n readonly appOrigin: string;\n readonly agentUi: AgentUiClient;\n readonly addChannel: (channel: ClientChannel) => () => void;\n readonly onSyncTags: (listener: (tags: readonly Tag[]) => void) => () => void;\n readonly onResume: (listener: () => void) => () => void;\n /** What the server negotiated for sync; `undefined` until it has. */\n readonly transport: () => \"sse\" | \"poll\" | undefined;\n readonly onNegotiated: (listener: (transport: \"sse\" | \"poll\") => void) => () => void;\n readonly isHidden?: (() => boolean) | undefined;\n readonly auth:\n | Partial<DeviceSource & HostAuthorizer & DeviceLinker & ComputerDisconnector>\n | undefined;\n readonly localHost: Promise<CapabilityHandle<LocalAgentHost>>;\n readonly threadId: string | undefined;\n}\n\nexport const HOST_GRANTS_TAG = \"parlor_auth_hosts\";\nexport const DEVICES_TAG = \"parlor_auth_devices\";\n\nconst LINKED: LinkState = { status: \"linked\" };\nconst CHECKING: LinkState = { status: \"checking\" };\n\nconst READ_RETRY_BASE_MS = 1_000;\nconst READ_RETRY_MAX_MS = 30_000;\nconst ACTIVITY_PING_MS = 60_000;\nconst UNFIXABLE_BY_RETRY: ReadonlySet<string> = new Set([\n \"not_found\",\n \"unauthenticated\",\n \"forbidden\",\n]);\n\nconst retryable = (error: unknown) =>\n !(error instanceof ActionError && UNFIXABLE_BY_RETRY.has(error.code));\n\nconst unavailableBecause = (error: unknown): ChatUnavailable[\"reason\"] =>\n error instanceof ActionError &&\n (error.code === \"forbidden\" ||\n error.code === \"not_found\" ||\n error.code === \"unauthenticated\")\n ? error.code\n : \"error\";\n\ntype StaleRead = \"lists\" | \"hosts\";\n\ninterface PendingSend {\n readonly text: string;\n readonly agent: string;\n readonly openedIn: ThreadId | undefined;\n readonly threadId: ThreadId;\n readonly turnId: TurnId;\n readonly itemId: ItemId;\n}\n\nconst mint = <K extends \"thread\" | \"turn\" | \"item\">(kind: K) =>\n asId(kind, generateClientId());\n\nconst isActive = (turn: TurnStatus) =>\n turn.state === \"queued\" || turn.state === \"running\";\n\nconst exceedsPromptLimit = (error: ActionError): boolean =>\n error.issues?.some(\n (issue) => issue.code === \"too_big\" && issue.path.join(\".\") === \"prompt.text\",\n ) ?? false;\n\nclass NeedsDevice extends Error {\n override readonly name = \"NeedsDevice\";\n}\n\n/** Prompts are signed with presence this long before the computer's deadline, for clock skew. */\nconst PRESENCE_MARGIN_MS = 10 * 60_000;\nconst LONGEST_TIMEOUT_MS = 2 ** 31 - 1;\n\nconst readable = (error: unknown): string => {\n if (error instanceof NeedsDevice) return error.message;\n if (error instanceof Error && error.name === \"NotAllowedError\") {\n return \"Face ID or Touch ID was cancelled.\";\n }\n if (!(error instanceof ActionError)) return \"Could not reach the server.\";\n if (error.issues === undefined) return error.message;\n return exceedsPromptLimit(error)\n ? PROMPT_LIMIT_MESSAGE\n : \"That message could not be sent. Try again.\";\n};\n\nconst bySeq = (a: LoggedItem, b: LoggedItem) => a.seq - b.seq;\n\nexport function createChatRuntime(deps: ChatRuntimeDeps): ChatRuntime {\n const { calls, agentUi } = deps;\n const listeners = new Set<() => void>();\n\n let threadId = deps.threadId === undefined ? undefined : asId(\"thread\", deps.threadId);\n let loaded: \"no\" | \"yes\" | \"failed\" = \"no\";\n let thread: ThreadSummary | undefined;\n let threads: readonly ThreadSummary[] = [];\n let olderThreads: readonly ThreadSummary[] = [];\n let moreThreads = false;\n let hasOlder = false;\n let loadingOlder = false;\n let hosts: readonly HostSummary[] = [];\n let items = new Map<string, LoggedItem>();\n let turns: readonly TurnStatus[] = [];\n let open: OpenTurns = NO_OPEN_TURNS;\n let beforeLoad: ChatFrame[] = [];\n let draft = \"\";\n let failure: string | undefined;\n let chosen: string | undefined;\n let optionChoices = readOptionChoices();\n let sending = false;\n let pendingSend: PendingSend | undefined;\n /** The prompt in flight, shown in its thread until the server's copy arrives. */\n let shownSend: PendingSend | undefined;\n let startedNew = false;\n let connect: ConnectOption = {\n kind: \"command\",\n command: `npx @parlor/agent-host connect ${deps.appOrigin}`,\n };\n let stopWatching: (() => void) | undefined;\n let watched: ThreadId | undefined;\n let running = false;\n let channelOpen = false;\n let staleAfterLoad = false;\n let dirty = false;\n const staleReads = new Set<StaleRead>();\n let unfixable = false;\n let unavailable: ChatUnavailable | undefined;\n let retryTimer: ReturnType<typeof setTimeout> | undefined;\n let retryDelay = READ_RETRY_BASE_MS;\n let lastPing: number | undefined;\n let pingRefused = false;\n let generation = 0;\n let device: SessionDevice | undefined;\n let linkInfo: Awaited<ReturnType<DeviceLinker[\"linkState\"]>> | undefined;\n let linking:\n | {\n readonly deviceId: string;\n readonly code: string;\n readonly qr: string;\n readonly expiresAt: string;\n }\n | undefined;\n let linkBusy = false;\n let linkError: string | undefined;\n let linkExpired = false;\n let linkTimer: ReturnType<typeof setTimeout> | undefined;\n let presenceTimer: ReturnType<typeof setTimeout> | undefined;\n let setup: DeviceSetup | undefined;\n let afterSetup: (() => Promise<void>) | undefined;\n let explainers = 0;\n const resends = new Map<ItemId, PendingSend>();\n const answerIds = new Map<string, ItemId>();\n const stopIds = new Map<TurnId, ItemId>();\n\n const refusedLast = (hostId: string, deviceId: string): boolean => {\n const last = [...turns].reverse().find((turn) => turn.agent.hostId === hostId);\n if (last?.failure !== \"device_rejected\") return false;\n return [...items.values()].some(\n (item) =>\n item.turnId === last.turnId &&\n item.kind === \"prompt\" &&\n item.body.signed?.deviceId === deviceId,\n );\n };\n\n /**\n * When the computer behind `agentKey` wants this device's next prompt signed with presence:\n * by its report, or now if it refused this device's last prompt, whatever the clocks say.\n */\n const presenceDueAt = (agentKey: string): number | undefined => {\n const deviceId = device?.id ?? linkInfo?.deviceId;\n if (deviceId === undefined) return undefined;\n const hostId = agentKey.split(\"/\")[0]!;\n const due = hosts.find((host) => host.id === hostId)?.presenceDue?.[deviceId];\n if (due === undefined) return undefined;\n return refusedLast(hostId, deviceId) ? 0 : due - PRESENCE_MARGIN_MS;\n };\n\n /** This device's choices for `agentKey` that its agent still offers. */\n const chosenOptions = (\n agentKey: string,\n options: readonly AgentOption[],\n ): Record<string, string> =>\n Object.fromEntries(\n Object.entries(optionChoices[agentKey] ?? {}).filter(([id, value]) =>\n options.some(\n (option) =>\n option.id === id && option.values.some((candidate) => candidate.id === value),\n ),\n ),\n );\n\n const choices = (): AgentChoice[] =>\n hosts.flatMap((host) =>\n host.agents.map((agent) => {\n const key = `${host.id}/${agent.id}`;\n const offered = agent.options ?? [];\n const picked = chosenOptions(key, offered);\n return {\n key,\n name: agent.name,\n hostName: host.name,\n online: host.online,\n ready: agent.ready,\n problem: agent.problem,\n options: offered.map((option) => ({\n ...option,\n selected: picked[option.id] ?? option.current,\n })),\n usage: agent.usage,\n outsideName: agent.outsideName,\n };\n }),\n );\n\n const waitOn = (reason: ChatWait[\"reason\"], hostId: string): ChatWait => ({\n reason,\n hostId,\n hostName: hosts.find((host) => host.id === hostId)?.name ?? \"your computer\",\n });\n\n const linkOf = (): LinkState => {\n if (!deps.auth?.linkState) return LINKED;\n const reporting = hosts.filter((host) => host.online && host.devices !== undefined);\n if (reporting.length === 0) return LINKED;\n if (!linkInfo) return CHECKING;\n const { deviceId } = linkInfo;\n if (\n linkInfo.pairing ||\n linkInfo.vouched ||\n (deviceId !== undefined &&\n reporting.some((host) => host.devices?.includes(deviceId)))\n ) {\n return LINKED;\n }\n const listing = hosts.filter((host) => host.devices !== undefined);\n return {\n status: \"unlinked\",\n hostName: reporting[0]!.name,\n code: linking?.code,\n qr: linking?.qr,\n command: linking && `npx @parlor/agent-host link ${deps.appOrigin} ${linking.code}`,\n expiresAt: linking?.expiresAt,\n expired: linkExpired,\n onlyComputer: listing.every((host) => host.devices!.every((id) => id === deviceId)),\n busy: linkBusy,\n error: linkError,\n };\n };\n\n const waitOf = (): ChatWait | undefined => {\n const approving = turns.find(awaitsApproval);\n if (approving) return waitOn(\"approval\", approving.agent.hostId);\n const offline = turns.find(\n (turn) =>\n turn.state === \"queued\" &&\n hosts.some((host) => host.id === turn.agent.hostId && !host.online),\n );\n return offline && waitOn(\"offline\", offline.agent.hostId);\n };\n\n const withShownSend = (folded: readonly ChatItem<AgentConfirmation>[]) => {\n if (shownSend && items.has(shownSend.itemId)) shownSend = undefined;\n const shown = shownSend;\n if (!shown || (threadId !== shown.openedIn && threadId !== shown.threadId)) {\n return folded;\n }\n const [hostId, agentId] = shown.agent.split(\"/\") as [string, string];\n const row: ChatItem<AgentConfirmation> = {\n kind: \"prompt\",\n id: shown.itemId,\n turnId: shown.turnId,\n text: shown.text,\n agent: { hostId: asId(\"host\", hostId), agentId },\n state: \"queued\",\n failure: undefined,\n mine: true,\n sending: true,\n };\n return [...folded, row];\n };\n\n const compute = (): ChatState => {\n const agents = choices();\n const wanted =\n chosen ??\n (thread?.agent ? `${thread.agent.hostId}/${thread.agent.agentId}` : undefined);\n const agent =\n agents.find((choice) => choice.key === wanted) ??\n agents.find((choice) => choice.online && choice.ready) ??\n agents[0];\n const wait = loaded === \"yes\" && !sending ? waitOf() : undefined;\n const due = agent && presenceDueAt(agent.key);\n const status: ChatStatus =\n loaded === \"failed\"\n ? \"unavailable\"\n : loaded === \"no\"\n ? \"loading\"\n : sending\n ? \"sending\"\n : wait\n ? \"waiting\"\n : turns.some(isActive) || open.turns.size > 0\n ? \"running\"\n : \"idle\";\n return {\n status,\n wait,\n unavailable: loaded === \"failed\" ? unavailable : undefined,\n thread,\n threads: [\n ...threads,\n ...olderThreads.filter(\n (older) => !threads.some((shown) => shown.id === older.id),\n ),\n ],\n moreThreads,\n hasOlder,\n loadingOlder,\n items: withShownSend(\n foldThread({\n items: [...items.values()].sort(bySeq),\n open: [...open.turns.values()],\n turns,\n confirmations: agentUi.confirmations\n .get()\n .filter((c) => c.threadId === threadId),\n deviceId: device?.id,\n }),\n ),\n hosts,\n agents,\n agent,\n connect,\n draft,\n error: failure,\n setup,\n link: linkOf(),\n presenceDue: due !== undefined && Date.now() >= due,\n };\n };\n\n /** Re-emits once the chosen computer's presence deadline arrives, so the hint shows unprompted. */\n const watchPresence = () => {\n clearTimeout(presenceTimer);\n presenceTimer = undefined;\n const due = running && state.agent ? presenceDueAt(state.agent.key) : undefined;\n if (due === undefined || state.presenceDue) return;\n presenceTimer = setTimeout(emit, Math.min(due - Date.now(), LONGEST_TIMEOUT_MS));\n };\n\n let state = compute();\n const emit = () => {\n state = compute();\n watchPresence();\n for (const listener of [...listeners]) listener();\n };\n\n const watch = () => {\n if (watched === threadId) return;\n stopWatching?.();\n watched = threadId;\n stopWatching = threadId === undefined ? undefined : agentUi.watch(threadId);\n };\n\n const absorb = (page: {\n readonly items: readonly LoggedItem[];\n readonly turns?: readonly TurnStatus[] | undefined;\n }) => {\n items = new Map(items);\n for (const item of page.items) items.set(item.id, item);\n if (page.turns) {\n const fresh = new Map(page.turns.map((turn) => [turn.turnId, turn]));\n turns = [...turns.filter((turn) => !fresh.has(turn.turnId)), ...page.turns];\n }\n open = pruneOpen(open, items, turns);\n };\n\n const oldestSeq = (): number | undefined =>\n items.size === 0\n ? undefined\n : Math.min(...[...items.values()].map((item) => item.seq));\n\n const takeThreads = (snapshot: {\n readonly threads: readonly ThreadSummary[];\n readonly moreThreads?: boolean | undefined;\n }) => {\n threads = snapshot.threads;\n if (olderThreads.length === 0) moreThreads = snapshot.moreThreads === true;\n };\n\n const load = async (target: ThreadId | undefined) => {\n const epoch = generation;\n const snapshot = await calls.call(\"open\", target ? { threadId: target } : {});\n if (epoch !== generation) return;\n staleReads.clear();\n takeThreads(snapshot);\n hosts = snapshot.hosts;\n const page = startedNew && target === undefined ? undefined : snapshot.page;\n thread = page?.thread;\n threadId = page?.thread?.id ?? target;\n if (page) {\n const oldest = oldestSeq();\n absorb(page);\n const first = page.items[0];\n if (oldest === undefined || (first !== undefined && first.seq <= oldest)) {\n hasOlder = page.hasMore;\n }\n }\n open = mergeSnapshot(open, channelOpen && page ? page.open : []);\n const replay = beforeLoad;\n beforeLoad = [];\n loaded = \"yes\";\n retryDelay = READ_RETRY_BASE_MS;\n for (const frame of replay) {\n if (frame.threadId === threadId) open = applyFrame(open, frame);\n }\n open = pruneOpen(open, items, turns);\n watch();\n };\n\n const refreshLists = async () => {\n const epoch = generation;\n const fresh = await calls.call(\"open\", {});\n if (epoch !== generation || threadId !== undefined) return;\n takeThreads(fresh);\n hosts = fresh.hosts;\n emit();\n };\n\n const refreshHosts = async () => {\n const fresh = await calls.call(\"hosts\", {});\n hosts = fresh;\n emit();\n };\n\n const readLists = async () => {\n if (threadId === undefined && !startedNew && draft.trim() === \"\") {\n await load(undefined);\n emit();\n } else await refreshLists();\n };\n\n const staleReaders: Record<StaleRead, () => Promise<void>> = {\n lists: readLists,\n hosts: refreshHosts,\n };\n\n const cancelRetry = () => {\n if (retryTimer !== undefined) globalThis.clearTimeout(retryTimer);\n retryTimer = undefined;\n };\n\n const clearRetry = () => {\n cancelRetry();\n retryDelay = READ_RETRY_BASE_MS;\n };\n\n const scheduleRetry = () => {\n if (!running || retryTimer !== undefined) return;\n const wait = retryDelay;\n retryDelay = Math.min(retryDelay * 2, READ_RETRY_MAX_MS);\n retryTimer = globalThis.setTimeout(() => {\n retryTimer = undefined;\n void mend();\n }, wait);\n };\n\n const settled = () => {\n if (!dirty && staleReads.size === 0) clearRetry();\n };\n\n const rereadStale = async (kind: StaleRead) => {\n const epoch = generation;\n try {\n await staleReaders[kind]();\n staleReads.delete(kind);\n settled();\n } catch (error) {\n if (epoch !== generation) return;\n staleReads.add(kind);\n if (retryable(error)) scheduleRetry();\n }\n };\n\n let refreshing = false;\n let refreshAgain = false;\n const refresh = async () => {\n if (refreshing) {\n refreshAgain = true;\n return;\n }\n refreshing = true;\n try {\n do {\n refreshAgain = false;\n if (loaded !== \"yes\" || threadId === undefined) break;\n const epoch = generation;\n const target = threadId;\n if (turns.some(isActive)) {\n await load(target);\n } else {\n const lastSeq = Math.max(0, ...[...items.values()].map((item) => item.seq));\n const fresh = await calls.call(\"items\", {\n threadId: target,\n afterSeq: lastSeq,\n });\n if (epoch !== generation) break;\n absorb({ items: fresh });\n const known = new Set(turns.map((turn) => turn.turnId));\n if (fresh.some((item) => !known.has(item.turnId))) await load(target);\n }\n dirty = false;\n settled();\n emit();\n } while (refreshAgain);\n } catch (error) {\n refreshAgain = false;\n dirty = true;\n if (retryable(error)) scheduleRetry();\n } finally {\n refreshing = false;\n }\n };\n\n const reporting = async (command: () => Promise<void>) => {\n try {\n await command();\n } catch (error) {\n failure = readable(error);\n emit();\n throw error;\n }\n if (failure !== undefined) {\n failure = undefined;\n emit();\n }\n };\n\n const awaitsApproval = (turn: TurnStatus): boolean => {\n if (!isActive(turn)) return false;\n let waiting = false;\n for (const item of [...items.values()].sort(bySeq)) {\n if (item.turnId !== turn.turnId) continue;\n if (item.kind === \"event\" && item.body.event === \"device_pending\") waiting = true;\n else if (item.author !== \"user\") waiting = false;\n }\n return waiting;\n };\n\n const deviceOf = async (): Promise<SessionDevice | undefined> => {\n const found = await deps.auth?.device?.();\n device = found ?? device;\n return found;\n };\n\n const refreshLink = async () => {\n if (!deps.auth?.linkState) return;\n try {\n linkInfo = await deps.auth.linkState();\n } catch {\n return;\n }\n if (linking && linking.deviceId !== linkInfo.deviceId) linking = undefined;\n emit();\n };\n\n const whenSetUp = async (action: () => Promise<void>): Promise<void> => {\n if (\n explainers > 0 &&\n device === undefined &&\n (await deps.auth?.deviceSetup?.()) === \"needed\"\n ) {\n afterSetup = action;\n setup = { step: \"explain\" };\n emit();\n return;\n }\n await action();\n };\n\n const signPrompt = async (prompt: PromptToSign): Promise<ItemSignature | undefined> => {\n const own = await deviceOf();\n if (!own) return undefined;\n const due = presenceDueAt(`${prompt.agent.hostId}/${prompt.agent.agentId}`);\n return due !== undefined && Date.now() >= due\n ? own.signPrompt(prompt, { presence: true })\n : own.signPrompt(prompt);\n };\n\n const submit = async (\n attempt: PendingSend,\n agentKey: string,\n settle: () => void,\n ): Promise<void> => {\n const [hostId, agentId] = agentKey.split(\"/\") as [string, string];\n const epoch = generation;\n sending = true;\n emit();\n try {\n await reporting(async () => {\n const agent = { hostId: asId(\"host\", hostId), agentId };\n const offered = hosts\n .find((host) => host.id === hostId)\n ?.agents.find((candidate) => candidate.id === agentId)?.options;\n const options = chosenOptions(agentKey, offered ?? []);\n const signed = deps.auth?.device\n ? await signPrompt({\n threadId: attempt.threadId,\n turnId: attempt.turnId,\n agent,\n text: attempt.text,\n })\n : undefined;\n await calls.call(\"send\", {\n threadId: attempt.threadId,\n turnId: attempt.turnId,\n itemId: attempt.itemId,\n clientId: deps.clientId,\n prompt: {\n text: attempt.text,\n agent,\n ...(signed ? { signed } : {}),\n ...(Object.keys(options).length > 0 ? { options } : {}),\n },\n });\n settle();\n if (epoch !== generation) return;\n startedNew = false;\n threadId = attempt.threadId;\n watch();\n await load(threadId);\n });\n } finally {\n sending = false;\n emit();\n }\n };\n\n const activeTurn = (): TurnStatus | undefined => [...turns].reverse().find(isActive);\n\n const switchTo = (target: ThreadId | undefined, blank: boolean) => {\n generation += 1;\n threadId = target;\n startedNew = blank;\n thread = undefined;\n items = new Map();\n turns = [];\n hasOlder = false;\n open = NO_OPEN_TURNS;\n beforeLoad = [];\n pendingSend = undefined;\n shownSend = undefined;\n stopIds.clear();\n answerIds.clear();\n dirty = false;\n staleReads.clear();\n clearRetry();\n watch();\n if (blank && loaded === \"yes\") {\n emit();\n return;\n }\n loaded = \"no\";\n emit();\n void loadFirst().then(emit);\n };\n\n const runtime: ChatRuntime = {\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n get: () => state,\n setDraft(text) {\n draft = text;\n emit();\n announceActivity();\n },\n async send(text = draft) {\n announceActivity();\n const prompt = text.trim();\n const target = state.agent;\n if (!prompt || isPromptTooLong(prompt) || !target || sending || loaded !== \"yes\") {\n return;\n }\n const retrying =\n pendingSend?.text === prompt &&\n pendingSend.agent === target.key &&\n pendingSend.openedIn === threadId;\n const attempt =\n retrying && pendingSend\n ? pendingSend\n : (pendingSend = {\n text: prompt,\n agent: target.key,\n openedIn: threadId,\n threadId: threadId ?? mint(\"thread\"),\n turnId: mint(\"turn\"),\n itemId: mint(\"item\"),\n });\n await whenSetUp(async () => {\n let delivered = false;\n shownSend = attempt;\n if (draft.trim() === prompt) draft = \"\";\n emit();\n try {\n await submit(attempt, target.key, () => {\n delivered = true;\n pendingSend = undefined;\n });\n } finally {\n if (!delivered && shownSend === attempt) {\n shownSend = undefined;\n draft = draft.trim() === \"\" ? attempt.text : `${attempt.text}\\n\\n${draft}`;\n emit();\n }\n }\n });\n },\n async loadOlder() {\n const target = threadId;\n const before = oldestSeq();\n if (target === undefined || before === undefined || !hasOlder || loadingOlder)\n return;\n const epoch = generation;\n loadingOlder = true;\n emit();\n try {\n await reporting(async () => {\n const older = await calls.call(\"history\", {\n threadId: target,\n beforeSeq: before,\n });\n if (epoch !== generation) return;\n absorb(older);\n hasOlder = older.hasMore;\n });\n } finally {\n loadingOlder = false;\n emit();\n }\n },\n async loadMoreThreads() {\n const last = olderThreads.at(-1) ?? threads.at(-1);\n if (!last || !moreThreads || loadingOlder) return;\n loadingOlder = true;\n emit();\n try {\n await reporting(async () => {\n const next = await calls.call(\"threadsBefore\", {\n before: { updatedAt: last.updatedAt, id: last.id },\n });\n olderThreads = [...olderThreads, ...next.threads];\n moreThreads = next.hasMore;\n });\n } finally {\n loadingOlder = false;\n emit();\n }\n },\n async resend(promptItemId) {\n const prompt = state.items.find(\n (item) => item.kind === \"prompt\" && item.id === promptItemId,\n );\n if (prompt?.kind !== \"prompt\" || sending || loaded !== \"yes\" || !threadId) return;\n const key = `${prompt.agent.hostId}/${prompt.agent.agentId}`;\n let attempt = resends.get(prompt.id);\n if (!attempt) {\n attempt = {\n text: prompt.text,\n agent: key,\n openedIn: threadId,\n threadId,\n turnId: mint(\"turn\"),\n itemId: mint(\"item\"),\n };\n resends.set(prompt.id, attempt);\n }\n await whenSetUp(() => submit(attempt, key, () => resends.delete(prompt.id)));\n },\n async stop() {\n const turn = activeTurn();\n if (!turn || threadId === undefined) return;\n const itemId = stopIds.get(turn.turnId) ?? mint(\"item\");\n stopIds.set(turn.turnId, itemId);\n const target = threadId;\n await reporting(async () => {\n await calls.call(\"cancel\", { threadId: target, turnId: turn.turnId, itemId });\n await refresh();\n });\n },\n async answer(askId, choice, values) {\n const ask = state.items.find((item) => item.kind === \"ask\" && item.id === askId);\n if (!ask || ask.kind !== \"ask\" || ask.answer.state !== \"open\" || !threadId) return;\n if (ask.approval === \"computer\") {\n throw new Error(\"This question is answered on your computer.\");\n }\n const itemId = answerIds.get(askId) ?? mint(\"item\");\n answerIds.set(askId, itemId);\n const target = threadId;\n const toSign: AnswerToSign = {\n threadId: target,\n askId: ask.id,\n choice,\n ...(values ? { values } : {}),\n };\n await whenSetUp(() =>\n reporting(async () => {\n const found = deps.auth?.device ? await deviceOf() : undefined;\n if ((ask.approval === \"presence\" || ask.approval === \"device\") && !found) {\n throw new NeedsDevice(\n \"This question needs a device that can confirm it is you.\",\n );\n }\n const signed = await found?.signAnswer(toSign, {\n presence: ask.approval === \"presence\",\n });\n await calls.call(\"answer\", {\n threadId: target,\n turnId: ask.turnId,\n itemId,\n answer: {\n askId: ask.id,\n choice,\n ...(values ? { values } : {}),\n ...(signed ? { signed } : {}),\n },\n });\n answerIds.delete(askId);\n await refresh();\n }),\n );\n },\n async setUpDevice({ passkey }) {\n if (setup === undefined || setup.step === \"passkey\") return;\n setup = { step: \"passkey\" };\n emit();\n try {\n device = (await deps.auth?.device?.({ presence: passkey })) ?? device;\n } catch (error) {\n if (error instanceof Error && error.name === \"PresenceSetupCancelled\") {\n setup = { step: \"cancelled\" };\n emit();\n return;\n }\n setup = undefined;\n afterSetup = undefined;\n failure = readable(error);\n emit();\n return;\n }\n const waiting = afterSetup;\n setup = undefined;\n afterSetup = undefined;\n emit();\n await waiting?.();\n },\n dismissSetup() {\n setup = undefined;\n afterSetup = undefined;\n emit();\n },\n async startLink(options) {\n if (!deps.auth?.startLink || linkBusy) return;\n linkBusy = true;\n linkError = undefined;\n emit();\n try {\n const started = await deps.auth.startLink(options);\n linking = {\n deviceId: started.deviceId,\n code: started.code,\n qr: `${deps.appOrigin}/link#${new URLSearchParams({ d: started.deviceId, c: started.commitment })}`,\n expiresAt: started.expiresAt,\n };\n linkExpired = false;\n clearTimeout(linkTimer);\n linkTimer = setTimeout(\n () => {\n linking = undefined;\n linkExpired = true;\n emit();\n },\n Math.min(\n Math.max(0, Date.parse(started.expiresAt) - Date.now()),\n LONGEST_TIMEOUT_MS,\n ),\n );\n linkInfo = {\n vouched: false,\n pairing: false,\n ...linkInfo,\n deviceId: started.deviceId,\n };\n } catch (error) {\n linkError =\n error instanceof Error && error.name === \"PresenceSetupCancelled\"\n ? \"Face ID or Touch ID was cancelled. Try again, or link without it.\"\n : readable(error);\n } finally {\n linkBusy = false;\n emit();\n }\n },\n explainSetup() {\n explainers += 1;\n return () => {\n explainers -= 1;\n if (explainers === 0 && setup !== undefined) runtime.dismissSetup();\n };\n },\n choose(agentKey) {\n chosen = agentKey;\n emit();\n },\n async disconnect(hostId) {\n if (!deps.auth?.disconnectComputer) {\n throw new Error(\"This app cannot disconnect computers.\");\n }\n await deps.auth.disconnectComputer(hostId);\n await refreshHosts();\n emit();\n },\n setOption(optionId, value) {\n const agentKey = state.agent?.key;\n if (agentKey === undefined) return;\n optionChoices = {\n ...optionChoices,\n [agentKey]: { ...optionChoices[agentKey], [optionId]: value },\n };\n writeOptionChoices(optionChoices);\n emit();\n },\n openThread(target) {\n switchTo(target === undefined ? undefined : asId(\"thread\", target), false);\n },\n newThread() {\n switchTo(undefined, true);\n },\n start() {\n running = true;\n const detachChannel = deps.addChannel({\n event: CHAT_CHANNEL,\n opened: () => {\n channelOpen = true;\n if (loaded === \"yes\" && turns.some(isActive) && !refreshing) void refresh();\n },\n receive(data) {\n const frame = parseChatFrame(data);\n if (!frame) return;\n if (loaded === \"no\") {\n beforeLoad.push(frame);\n return;\n }\n if (loaded !== \"yes\" || frame.threadId !== threadId) return;\n open = applyFrame(open, frame);\n emit();\n },\n closed: () => {\n channelOpen = false;\n },\n });\n const offTags = deps.onSyncTags((tags) => {\n const mine = tags.some((tag) =>\n tagsOverlap(tag, threadId === undefined ? [CHAT_TAG] : [CHAT_TAG, threadId]),\n );\n const computers = tags.some(\n (tag) => tagsOverlap(tag, [HOSTS_TAG]) || tagsOverlap(tag, [HOST_GRANTS_TAG]),\n );\n if (tags.some((tag) => tagsOverlap(tag, [DEVICES_TAG]))) void refreshLink();\n if (loaded === \"failed\" && (mine || computers)) {\n cancelRetry();\n void loadFirst().then(emit);\n } else if (loaded === \"no\") {\n if (mine || computers) staleAfterLoad = true;\n } else {\n if (mine && threadId !== undefined) void refresh();\n else if (mine) void rereadStale(\"lists\");\n if (computers) void rereadStale(\"hosts\");\n }\n });\n const offResume = deps.onResume(() => {\n if (loaded === \"failed\") {\n if (!unfixable) {\n cancelRetry();\n void loadFirst().then(emit);\n }\n } else if (loaded === \"no\") staleAfterLoad = true;\n else void refresh();\n });\n const offNegotiated = deps.onNegotiated((transport) => {\n if (transport === \"poll\") announceActivity();\n });\n const offConfirmations = agentUi.confirmations.subscribe(emit);\n const offLink = deps.auth?.subscribeLink?.(() => void refreshLink());\n emit();\n announceActivity();\n void initial();\n return () => {\n running = false;\n channelOpen = false;\n generation += 1;\n clearRetry();\n clearTimeout(presenceTimer);\n presenceTimer = undefined;\n clearTimeout(linkTimer);\n linkTimer = undefined;\n detachChannel();\n offTags();\n offResume();\n offNegotiated();\n offConfirmations();\n offLink?.();\n stopWatching?.();\n stopWatching = undefined;\n watched = undefined;\n };\n },\n };\n\n async function mend() {\n if (loaded === \"failed\") await loadFirst();\n else if (loaded === \"yes\") {\n if (dirty) await refresh();\n for (const kind of [...staleReads]) await rereadStale(kind);\n }\n emit();\n }\n\n function announceActivity() {\n if (!running || pingRefused || deps.transport() !== \"poll\") return;\n if (deps.isHidden?.() === true) return;\n const now = Date.now();\n if (lastPing !== undefined && now - lastPing < ACTIVITY_PING_MS) return;\n lastPing = now;\n calls.call(\"userActive\", {}).catch((error: unknown) => {\n if (\n error instanceof ActionError &&\n (error.code === \"not_found\" || error.code === \"forbidden\")\n ) {\n pingRefused = true;\n }\n });\n }\n\n async function loadFirst() {\n try {\n await load(threadId);\n unfixable = false;\n } catch (error) {\n if (running) {\n loaded = \"failed\";\n unavailable = { reason: unavailableBecause(error) };\n unfixable = !retryable(error);\n if (!unfixable) scheduleRetry();\n }\n return;\n }\n if (staleAfterLoad) {\n staleAfterLoad = false;\n await refresh();\n }\n }\n\n async function initial() {\n void deps.localHost.then((handle) => {\n const authorizeHost = deps.auth?.authorizeHost;\n if (!handle.available || !authorizeHost || !running) return;\n connect = {\n kind: \"here\",\n start: async () => {\n const own = await deps.auth?.device?.();\n const outcome = await handle.api.connect({\n appOrigin: deps.appOrigin,\n authorize: authorizeHost,\n ...(own ? { device: own.keys } : {}),\n });\n if (!outcome.connected) throw new Error(`Connecting failed: ${outcome.reason}`);\n await refreshHosts();\n await refreshLink();\n },\n };\n emit();\n });\n void refreshLink();\n await loadFirst();\n announceActivity();\n emit();\n }\n\n return runtime;\n}\n\nconst OPTION_CHOICES_KEY = \"parlor:agent-options\";\n\ntype OptionChoices = Readonly<Record<string, Readonly<Record<string, string>>>>;\n\nfunction readOptionChoices(): OptionChoices {\n try {\n const stored: unknown = JSON.parse(\n globalThis.localStorage?.getItem(OPTION_CHOICES_KEY) ?? \"{}\",\n );\n return stored && typeof stored === \"object\" ? (stored as OptionChoices) : {};\n } catch {\n return {};\n }\n}\n\nfunction writeOptionChoices(choices: OptionChoices): void {\n try {\n globalThis.localStorage?.setItem(OPTION_CHOICES_KEY, JSON.stringify(choices));\n } catch {}\n}\n"]}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * A streaming reply's text, revealed at the pace it arrives instead of a batch at a time:
3
+ * what came in is spread over the time until the next batch is expected, and the rest
4
+ * shows within a moment once `streaming` ends. Text there at mount shows at once.
5
+ */
6
+ export declare function useStreamingText(text: string, streaming: boolean): string;
7
+ //# sourceMappingURL=use-streaming-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-streaming-text.d.ts","sourceRoot":"","sources":["../../../src/react/chat/use-streaming-text.ts"],"names":[],"mappings":"AAgBA;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,CA2CzE"}
@@ -0,0 +1,59 @@
1
+ import { useEffect, useRef, useState } from "react";
2
+ const FRAME_MS = 32;
3
+ const FIRST_GAP_MS = 250;
4
+ const MIN_GAP_MS = 60;
5
+ const MAX_GAP_MS = 1_000;
6
+ const SETTLE_MS = 180;
7
+ const clamp = (value) => Math.min(MAX_GAP_MS, Math.max(MIN_GAP_MS, value));
8
+ /** Never ends inside a surrogate pair, so an emoji is shown whole or not at all. */
9
+ function boundary(text, at) {
10
+ const code = text.charCodeAt(at - 1);
11
+ return code >= 0xd800 && code <= 0xdbff ? at + 1 : at;
12
+ }
13
+ /**
14
+ * A streaming reply's text, revealed at the pace it arrives instead of a batch at a time:
15
+ * what came in is spread over the time until the next batch is expected, and the rest
16
+ * shows within a moment once `streaming` ends. Text there at mount shows at once.
17
+ */
18
+ export function useStreamingText(text, streaming) {
19
+ const [shown, setShown] = useState(text.length);
20
+ const shownNow = useRef(shown);
21
+ const pace = useRef({
22
+ text,
23
+ arrivedAt: undefined,
24
+ gap: FIRST_GAP_MS,
25
+ rate: 0,
26
+ });
27
+ useEffect(() => {
28
+ shownNow.current = shown;
29
+ }, [shown]);
30
+ useEffect(() => {
31
+ const p = pace.current;
32
+ const previous = p.text;
33
+ p.text = text;
34
+ if (!text.startsWith(previous.slice(0, shownNow.current))) {
35
+ setShown(text.length);
36
+ return;
37
+ }
38
+ if (text.length > previous.length) {
39
+ const now = performance.now();
40
+ if (p.arrivedAt !== undefined)
41
+ p.gap = clamp(0.7 * p.gap + 0.3 * (now - p.arrivedAt));
42
+ p.arrivedAt = now;
43
+ }
44
+ p.rate = (text.length - shownNow.current) / (streaming ? p.gap : SETTLE_MS);
45
+ }, [text, streaming]);
46
+ useEffect(() => {
47
+ if (shown >= text.length)
48
+ return;
49
+ const timer = setTimeout(() => {
50
+ setShown((current) => {
51
+ const step = Math.max(1, Math.round(pace.current.rate * FRAME_MS));
52
+ return Math.min(text.length, boundary(text, current + step));
53
+ });
54
+ }, FRAME_MS);
55
+ return () => clearTimeout(timer);
56
+ }, [shown, text]);
57
+ return shown >= text.length ? text : text.slice(0, shown);
58
+ }
59
+ //# sourceMappingURL=use-streaming-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-streaming-text.js","sourceRoot":"","sources":["../../../src/react/chat/use-streaming-text.ts"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useRef, useState } from \"react\";\n\nconst FRAME_MS = 32;\nconst FIRST_GAP_MS = 250;\nconst MIN_GAP_MS = 60;\nconst MAX_GAP_MS = 1_000;\nconst SETTLE_MS = 180;\n\nconst clamp = (value: number) => Math.min(MAX_GAP_MS, Math.max(MIN_GAP_MS, value));\n\n/** Never ends inside a surrogate pair, so an emoji is shown whole or not at all. */\nfunction boundary(text: string, at: number): number {\n const code = text.charCodeAt(at - 1);\n return code >= 0xd800 && code <= 0xdbff ? at + 1 : at;\n}\n\n/**\n * A streaming reply's text, revealed at the pace it arrives instead of a batch at a time:\n * what came in is spread over the time until the next batch is expected, and the rest\n * shows within a moment once `streaming` ends. Text there at mount shows at once.\n */\nexport function useStreamingText(text: string, streaming: boolean): string {\n const [shown, setShown] = useState(text.length);\n const shownNow = useRef(shown);\n const pace = useRef({\n text,\n arrivedAt: undefined as number | undefined,\n gap: FIRST_GAP_MS,\n rate: 0,\n });\n\n useEffect(() => {\n shownNow.current = shown;\n }, [shown]);\n\n useEffect(() => {\n const p = pace.current;\n const previous = p.text;\n p.text = text;\n if (!text.startsWith(previous.slice(0, shownNow.current))) {\n setShown(text.length);\n return;\n }\n if (text.length > previous.length) {\n const now = performance.now();\n if (p.arrivedAt !== undefined)\n p.gap = clamp(0.7 * p.gap + 0.3 * (now - p.arrivedAt));\n p.arrivedAt = now;\n }\n p.rate = (text.length - shownNow.current) / (streaming ? p.gap : SETTLE_MS);\n }, [text, streaming]);\n\n useEffect(() => {\n if (shown >= text.length) return;\n const timer = setTimeout(() => {\n setShown((current) => {\n const step = Math.max(1, Math.round(pace.current.rate * FRAME_MS));\n return Math.min(text.length, boundary(text, current + step));\n });\n }, FRAME_MS);\n return () => clearTimeout(timer);\n }, [shown, text]);\n\n return shown >= text.length ? text : text.slice(0, shown);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/react/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAK5B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAIxD,KAAK,OAAO,GAAG,iBAAiB,CAAC;AACjC,KAAK,IAAI,GAAG,MAAM,OAAO,GAAG,MAAM,CAAC;AAEnC,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,IAAI,IAAI,IAAI,CACnD,eAAe,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,EACtD,UAAU,GAAG,SAAS,CACvB,CAAC;AAEF,wBAAgB,cAAc,CAAC,CAAC,SAAS,IAAI,EAC3C,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAC9B,OAAO,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC9B,cAAc,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAKvD;AAED,MAAM,MAAM,0BAA0B,CAAC,CAAC,SAAS,IAAI,IAAI,IAAI,CAC3D,uBAAuB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,EAC9D,UAAU,GAAG,SAAS,CACvB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,IAAI,EACnD,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAC9B,OAAO,CAAC,EAAE,0BAA0B,CAAC,CAAC,CAAC,GACtC,sBAAsB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAK/D;AAMD,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,IAAI,IAAI,IAAI,CACtD,kBAAkB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAClF,YAAY,CACb,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,IAAI,EAC9C,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,qBAAqB,CAAC,CAAC,CAAC,GACjC,iBAAiB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAWnF"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/react/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAK5B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAKxD,KAAK,OAAO,GAAG,iBAAiB,CAAC;AACjC,KAAK,IAAI,GAAG,MAAM,OAAO,GAAG,MAAM,CAAC;AAEnC,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,IAAI,IAAI,IAAI,CACnD,eAAe,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,EACtD,UAAU,GAAG,SAAS,CACvB,CAAC;AAEF,wBAAgB,cAAc,CAAC,CAAC,SAAS,IAAI,EAC3C,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAC9B,OAAO,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC9B,cAAc,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAKvD;AAED,MAAM,MAAM,0BAA0B,CAAC,CAAC,SAAS,IAAI,IAAI,IAAI,CAC3D,uBAAuB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,EAC9D,UAAU,GAAG,SAAS,CACvB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,IAAI,EACnD,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAC9B,OAAO,CAAC,EAAE,0BAA0B,CAAC,CAAC,CAAC,GACtC,sBAAsB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAK/D;AAMD,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,IAAI,IAAI,IAAI,CACtD,kBAAkB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAClF,YAAY,CACb,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,IAAI,EAC9C,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,qBAAqB,CAAC,CAAC,CAAC,GACjC,iBAAiB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAQnF"}
@@ -1,7 +1,7 @@
1
1
  import { useMutation, useQuery, useQueryClient, useSuspenseQuery, } from "@tanstack/react-query";
2
- import { ACTION_QUERY_PREFIX } from "../query-keys.js";
3
2
  import { actionQueryOptions } from "./action-query.js";
4
3
  import { useFramework } from "./provider.js";
4
+ import { callAndRefresh } from "./write-refresh.js";
5
5
  export function useActionQuery(name, input, options) {
6
6
  return useQuery({
7
7
  ...actionQueryOptions(useActionQueryContext(), name, input),
@@ -26,11 +26,8 @@ export function useActionMutation(name, options) {
26
26
  const queryClient = useQueryClient();
27
27
  return useMutation({
28
28
  ...options,
29
- mutationFn: (input) => client.call(name, input),
30
- onSuccess: async (data, variables, onMutateResult, context) => {
31
- await queryClient.invalidateQueries({ queryKey: ACTION_QUERY_PREFIX });
32
- await options?.onSuccess?.(data, variables, onMutateResult, context);
33
- },
29
+ // The page is fresh, with what the write changed, before `onSuccess` runs.
30
+ mutationFn: (input) => callAndRefresh({ client, queryClient }, name, input),
34
31
  });
35
32
  }
36
33
  //# sourceMappingURL=hooks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/react/hooks.ts"],"names":[],"mappings":"AACA,OAAO,EAOL,WAAW,EACX,QAAQ,EACR,cAAc,EACd,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAA2B,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAU7C,MAAM,UAAU,cAAc,CAC5B,IAAO,EACP,KAA8B,EAC9B,OAA+B;IAE/B,OAAO,QAAQ,CAAC;QACd,GAAG,kBAAkB,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC;QAC3D,GAAG,OAAO;KACX,CAAC,CAAC;AACL,CAAC;AAOD;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAAO,EACP,KAA8B,EAC9B,OAAuC;IAEvC,OAAO,gBAAgB,CAAC;QACtB,GAAG,kBAAkB,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC;QAC3D,GAAG,OAAO;KACX,CAAC,CAAC;AACL,CAAC;AAED,SAAS,qBAAqB;IAC5B,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,EAAE,CAAC;AAC1E,CAAC;AAOD,MAAM,UAAU,iBAAiB,CAC/B,IAAO,EACP,OAAkC;IAElC,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IAClC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,WAAW,CAAC;QACjB,GAAG,OAAO;QACV,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC;QAC/C,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,EAAE;YAC5D,MAAM,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACvE,MAAM,OAAO,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;QACvE,CAAC;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { ActionError, ActionInput, ActionOutput } from \"@parlor/core\";\nimport {\n type UseMutationOptions,\n type UseMutationResult,\n type UseQueryOptions,\n type UseQueryResult,\n type UseSuspenseQueryOptions,\n type UseSuspenseQueryResult,\n useMutation,\n useQuery,\n useQueryClient,\n useSuspenseQuery,\n} from \"@tanstack/react-query\";\n\nimport { ACTION_QUERY_PREFIX } from \"../query-keys.js\";\nimport type { RegisteredActions } from \"../register.js\";\nimport { type ActionQueryContext, actionQueryOptions } from \"./action-query.js\";\nimport { useFramework } from \"./provider.js\";\n\ntype Actions = RegisteredActions;\ntype Name = keyof Actions & string;\n\nexport type ActionQueryOptions<K extends Name> = Omit<\n UseQueryOptions<ActionOutput<Actions[K]>, ActionError>,\n \"queryKey\" | \"queryFn\"\n>;\n\nexport function useActionQuery<K extends Name>(\n name: K,\n input: ActionInput<Actions[K]>,\n options?: ActionQueryOptions<K>,\n): UseQueryResult<ActionOutput<Actions[K]>, ActionError> {\n return useQuery({\n ...actionQueryOptions(useActionQueryContext(), name, input),\n ...options,\n });\n}\n\nexport type ActionSuspenseQueryOptions<K extends Name> = Omit<\n UseSuspenseQueryOptions<ActionOutput<Actions[K]>, ActionError>,\n \"queryKey\" | \"queryFn\"\n>;\n\n/**\n * `useActionQuery` as a TanStack Query `useSuspenseQuery`: `data` is always there. It suspends\n * until the action answers, unless a route `loader` already ran `ensureActionQueryData`.\n */\nexport function useActionSuspenseQuery<K extends Name>(\n name: K,\n input: ActionInput<Actions[K]>,\n options?: ActionSuspenseQueryOptions<K>,\n): UseSuspenseQueryResult<ActionOutput<Actions[K]>, ActionError> {\n return useSuspenseQuery({\n ...actionQueryOptions(useActionQueryContext(), name, input),\n ...options,\n });\n}\n\nfunction useActionQueryContext(): ActionQueryContext {\n return { client: useFramework().client, queryClient: useQueryClient() };\n}\n\nexport type ActionMutationOptions<K extends Name> = Omit<\n UseMutationOptions<ActionOutput<Actions[K]>, ActionError, ActionInput<Actions[K]>>,\n \"mutationFn\"\n>;\n\nexport function useActionMutation<K extends Name>(\n name: K,\n options?: ActionMutationOptions<K>,\n): UseMutationResult<ActionOutput<Actions[K]>, ActionError, ActionInput<Actions[K]>> {\n const { client } = useFramework();\n const queryClient = useQueryClient();\n return useMutation({\n ...options,\n mutationFn: (input) => client.call(name, input),\n onSuccess: async (data, variables, onMutateResult, context) => {\n await queryClient.invalidateQueries({ queryKey: ACTION_QUERY_PREFIX });\n await options?.onSuccess?.(data, variables, onMutateResult, context);\n },\n });\n}\n"]}
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/react/hooks.ts"],"names":[],"mappings":"AACA,OAAO,EAOL,WAAW,EACX,QAAQ,EACR,cAAc,EACd,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAA2B,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAUpD,MAAM,UAAU,cAAc,CAC5B,IAAO,EACP,KAA8B,EAC9B,OAA+B;IAE/B,OAAO,QAAQ,CAAC;QACd,GAAG,kBAAkB,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC;QAC3D,GAAG,OAAO;KACX,CAAC,CAAC;AACL,CAAC;AAOD;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAAO,EACP,KAA8B,EAC9B,OAAuC;IAEvC,OAAO,gBAAgB,CAAC;QACtB,GAAG,kBAAkB,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC;QAC3D,GAAG,OAAO;KACX,CAAC,CAAC;AACL,CAAC;AAED,SAAS,qBAAqB;IAC5B,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,EAAE,CAAC;AAC1E,CAAC;AAOD,MAAM,UAAU,iBAAiB,CAC/B,IAAO,EACP,OAAkC;IAElC,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IAClC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,WAAW,CAAC;QACjB,GAAG,OAAO;QACV,2EAA2E;QAC3E,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC;KAC5E,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { ActionError, ActionInput, ActionOutput } from \"@parlor/core\";\nimport {\n type UseMutationOptions,\n type UseMutationResult,\n type UseQueryOptions,\n type UseQueryResult,\n type UseSuspenseQueryOptions,\n type UseSuspenseQueryResult,\n useMutation,\n useQuery,\n useQueryClient,\n useSuspenseQuery,\n} from \"@tanstack/react-query\";\n\nimport type { RegisteredActions } from \"../register.js\";\nimport { type ActionQueryContext, actionQueryOptions } from \"./action-query.js\";\nimport { useFramework } from \"./provider.js\";\nimport { callAndRefresh } from \"./write-refresh.js\";\n\ntype Actions = RegisteredActions;\ntype Name = keyof Actions & string;\n\nexport type ActionQueryOptions<K extends Name> = Omit<\n UseQueryOptions<ActionOutput<Actions[K]>, ActionError>,\n \"queryKey\" | \"queryFn\"\n>;\n\nexport function useActionQuery<K extends Name>(\n name: K,\n input: ActionInput<Actions[K]>,\n options?: ActionQueryOptions<K>,\n): UseQueryResult<ActionOutput<Actions[K]>, ActionError> {\n return useQuery({\n ...actionQueryOptions(useActionQueryContext(), name, input),\n ...options,\n });\n}\n\nexport type ActionSuspenseQueryOptions<K extends Name> = Omit<\n UseSuspenseQueryOptions<ActionOutput<Actions[K]>, ActionError>,\n \"queryKey\" | \"queryFn\"\n>;\n\n/**\n * `useActionQuery` as a TanStack Query `useSuspenseQuery`: `data` is always there. It suspends\n * until the action answers, unless a route `loader` already ran `ensureActionQueryData`.\n */\nexport function useActionSuspenseQuery<K extends Name>(\n name: K,\n input: ActionInput<Actions[K]>,\n options?: ActionSuspenseQueryOptions<K>,\n): UseSuspenseQueryResult<ActionOutput<Actions[K]>, ActionError> {\n return useSuspenseQuery({\n ...actionQueryOptions(useActionQueryContext(), name, input),\n ...options,\n });\n}\n\nfunction useActionQueryContext(): ActionQueryContext {\n return { client: useFramework().client, queryClient: useQueryClient() };\n}\n\nexport type ActionMutationOptions<K extends Name> = Omit<\n UseMutationOptions<ActionOutput<Actions[K]>, ActionError, ActionInput<Actions[K]>>,\n \"mutationFn\"\n>;\n\nexport function useActionMutation<K extends Name>(\n name: K,\n options?: ActionMutationOptions<K>,\n): UseMutationResult<ActionOutput<Actions[K]>, ActionError, ActionInput<Actions[K]>> {\n const { client } = useFramework();\n const queryClient = useQueryClient();\n return useMutation({\n ...options,\n // The page is fresh, with what the write changed, before `onSuccess` runs.\n mutationFn: (input) => callAndRefresh({ client, queryClient }, name, input),\n });\n}\n"]}
@@ -6,6 +6,7 @@ export type { ChatRootProps } from "./chat/chat-root.js";
6
6
  export type { ChatThreadProps } from "./chat/chat-thread.js";
7
7
  export type { AgentChoice, AgentChoiceOption, ChatCommands, ChatState, ChatStatus, ChatUnavailable, ChatWait, ConnectOption, DeviceSetup, DeviceSetupCommands, LinkState, } from "./chat/runtime.js";
8
8
  export { useChat } from "./chat/use-chat.js";
9
+ export { useStreamingText } from "./chat/use-streaming-text.js";
9
10
  export { useDeviceSetup } from "./chat/use-device-setup.js";
10
11
  export { type RemoveDeviceState, useDevices } from "./use-devices.js";
11
12
  export { type LinkDeviceState, useLinkDevice } from "./use-link-device.js";
@@ -14,6 +15,7 @@ export { useAgentActivity } from "./agent-ui/use-agent-activity.js";
14
15
  export { useAgentConfirmations } from "./agent-ui/use-agent-confirmations.js";
15
16
  export { type AgentViewHandle, useAgentView } from "./agent-ui/use-agent-view.js";
16
17
  export { type ActionQueryContext, actionQueryOptions, ensureActionQueryData, } from "./action-query.js";
18
+ export { callAndRefresh } from "./write-refresh.js";
17
19
  export { type ActionMutationOptions, type ActionQueryOptions, type ActionSuspenseQueryOptions, useActionMutation, useActionQuery, useActionSuspenseQuery, } from "./hooks.js";
18
20
  export { FrameworkProvider, type FrameworkProviderProps, useActionClient, useSession, } from "./provider.js";
19
21
  export { type CapabilityState, useCapability } from "./use-capability.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,IAAI,MAAM,oBAAoB,CAAC;AAC3C,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,GACb,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,YAAY,EACV,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,UAAU,EACV,eAAe,EACf,QAAQ,EACR,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,SAAS,GACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,KAAK,iBAAiB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,KAAK,eAAe,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC3E,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,KAAK,eAAe,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAClF,OAAO,EACL,KAAK,kBAAkB,EACvB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,iBAAiB,EACjB,cAAc,EACd,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,KAAK,sBAAsB,EAC3B,eAAe,EACf,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,KAAK,eAAe,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,IAAI,MAAM,oBAAoB,CAAC;AAC3C,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,GACb,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,YAAY,EACV,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,UAAU,EACV,eAAe,EACf,QAAQ,EACR,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,SAAS,GACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,KAAK,iBAAiB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,KAAK,eAAe,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC3E,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,KAAK,eAAe,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAClF,OAAO,EACL,KAAK,kBAAkB,EACvB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,iBAAiB,EACjB,cAAc,EACd,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,KAAK,sBAAsB,EAC3B,eAAe,EACf,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,KAAK,eAAe,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export * as Chat from "./agent-ui/chat.js";
2
2
  export { useChat } from "./chat/use-chat.js";
3
+ export { useStreamingText } from "./chat/use-streaming-text.js";
3
4
  export { useDeviceSetup } from "./chat/use-device-setup.js";
4
5
  export { useDevices } from "./use-devices.js";
5
6
  export { useLinkDevice } from "./use-link-device.js";
@@ -7,6 +8,7 @@ export { useAgentActivity } from "./agent-ui/use-agent-activity.js";
7
8
  export { useAgentConfirmations } from "./agent-ui/use-agent-confirmations.js";
8
9
  export { useAgentView } from "./agent-ui/use-agent-view.js";
9
10
  export { actionQueryOptions, ensureActionQueryData, } from "./action-query.js";
11
+ export { callAndRefresh } from "./write-refresh.js";
10
12
  export { useActionMutation, useActionQuery, useActionSuspenseQuery, } from "./hooks.js";
11
13
  export { FrameworkProvider, useActionClient, useSession, } from "./provider.js";
12
14
  export { useCapability } from "./use-capability.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,IAAI,MAAM,oBAAoB,CAAC;AAqB3C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAA0B,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAwB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAwB,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAClF,OAAO,EAEL,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAIL,iBAAiB,EACjB,cAAc,EACd,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EAEjB,eAAe,EACf,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAwB,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC","sourcesContent":["export type {\n AgentActivity,\n AgentActivityKind,\n AgentOutcome,\n AgentConfirmation,\n} from \"@parlor/agent-ui/client\";\nexport type { AgentActivityState } from \"./agent-ui/activity-state.js\";\nexport * as Chat from \"./agent-ui/chat.js\";\nexport type {\n ChatAskChoiceProps,\n ChatAskFormProps,\n ChatAskProps,\n} from \"./chat/chat-ask.js\";\nexport type { ChatRootProps } from \"./chat/chat-root.js\";\nexport type { ChatThreadProps } from \"./chat/chat-thread.js\";\nexport type {\n AgentChoice,\n AgentChoiceOption,\n ChatCommands,\n ChatState,\n ChatStatus,\n ChatUnavailable,\n ChatWait,\n ConnectOption,\n DeviceSetup,\n DeviceSetupCommands,\n LinkState,\n} from \"./chat/runtime.js\";\nexport { useChat } from \"./chat/use-chat.js\";\nexport { useDeviceSetup } from \"./chat/use-device-setup.js\";\nexport { type RemoveDeviceState, useDevices } from \"./use-devices.js\";\nexport { type LinkDeviceState, useLinkDevice } from \"./use-link-device.js\";\nexport type { ChatItem } from \"@parlor/chat\";\nexport { useAgentActivity } from \"./agent-ui/use-agent-activity.js\";\nexport { useAgentConfirmations } from \"./agent-ui/use-agent-confirmations.js\";\nexport { type AgentViewHandle, useAgentView } from \"./agent-ui/use-agent-view.js\";\nexport {\n type ActionQueryContext,\n actionQueryOptions,\n ensureActionQueryData,\n} from \"./action-query.js\";\nexport {\n type ActionMutationOptions,\n type ActionQueryOptions,\n type ActionSuspenseQueryOptions,\n useActionMutation,\n useActionQuery,\n useActionSuspenseQuery,\n} from \"./hooks.js\";\nexport {\n FrameworkProvider,\n type FrameworkProviderProps,\n useActionClient,\n useSession,\n} from \"./provider.js\";\nexport { type CapabilityState, useCapability } from \"./use-capability.js\";\nexport { invalidateForEvents, ReadTagRegistry } from \"./sync.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,IAAI,MAAM,oBAAoB,CAAC;AAqB3C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAA0B,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAwB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAwB,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAClF,OAAO,EAEL,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAIL,iBAAiB,EACjB,cAAc,EACd,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EAEjB,eAAe,EACf,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAwB,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC","sourcesContent":["export type {\n AgentActivity,\n AgentActivityKind,\n AgentOutcome,\n AgentConfirmation,\n} from \"@parlor/agent-ui/client\";\nexport type { AgentActivityState } from \"./agent-ui/activity-state.js\";\nexport * as Chat from \"./agent-ui/chat.js\";\nexport type {\n ChatAskChoiceProps,\n ChatAskFormProps,\n ChatAskProps,\n} from \"./chat/chat-ask.js\";\nexport type { ChatRootProps } from \"./chat/chat-root.js\";\nexport type { ChatThreadProps } from \"./chat/chat-thread.js\";\nexport type {\n AgentChoice,\n AgentChoiceOption,\n ChatCommands,\n ChatState,\n ChatStatus,\n ChatUnavailable,\n ChatWait,\n ConnectOption,\n DeviceSetup,\n DeviceSetupCommands,\n LinkState,\n} from \"./chat/runtime.js\";\nexport { useChat } from \"./chat/use-chat.js\";\nexport { useStreamingText } from \"./chat/use-streaming-text.js\";\nexport { useDeviceSetup } from \"./chat/use-device-setup.js\";\nexport { type RemoveDeviceState, useDevices } from \"./use-devices.js\";\nexport { type LinkDeviceState, useLinkDevice } from \"./use-link-device.js\";\nexport type { ChatItem } from \"@parlor/chat\";\nexport { useAgentActivity } from \"./agent-ui/use-agent-activity.js\";\nexport { useAgentConfirmations } from \"./agent-ui/use-agent-confirmations.js\";\nexport { type AgentViewHandle, useAgentView } from \"./agent-ui/use-agent-view.js\";\nexport {\n type ActionQueryContext,\n actionQueryOptions,\n ensureActionQueryData,\n} from \"./action-query.js\";\nexport { callAndRefresh } from \"./write-refresh.js\";\nexport {\n type ActionMutationOptions,\n type ActionQueryOptions,\n type ActionSuspenseQueryOptions,\n useActionMutation,\n useActionQuery,\n useActionSuspenseQuery,\n} from \"./hooks.js\";\nexport {\n FrameworkProvider,\n type FrameworkProviderProps,\n useActionClient,\n useSession,\n} from \"./provider.js\";\nexport { type CapabilityState, useCapability } from \"./use-capability.js\";\nexport { invalidateForEvents, ReadTagRegistry } from \"./sync.js\";\n"]}
@@ -0,0 +1,27 @@
1
+ import { type ActionInput, type ActionOutput, type ReadRequest } from "@parlor/core";
2
+ import type { Query, QueryClient } from "@tanstack/react-query";
3
+ import type { ActionEnvelope, CallOptions } from "../action-client.js";
4
+ import type { RegisteredActions } from "../register.js";
5
+ import type { ActionQueryContext } from "./action-query.js";
6
+ export interface ShownRead {
7
+ readonly query: Query;
8
+ readonly request: ReadRequest;
9
+ }
10
+ /** The action queries the page shows, to name on a write so it answers with them fresh. */
11
+ export declare function shownReads(queryClient: QueryClient): ShownRead[];
12
+ /**
13
+ * Brings the cache up to date after a write. The reads the server ran again go straight in;
14
+ * a shown read it could not run, or one whose reads are unknown here, is fetched again, and
15
+ * this waits for it; data nothing shows that the write changed is marked out of date. A
16
+ * server that did not say what the write changed gets every action query fetched again.
17
+ */
18
+ export declare function applyWrite(queryClient: QueryClient, shown: readonly ShownRead[], envelope: ActionEnvelope<unknown>): Promise<void>;
19
+ type Name = keyof RegisteredActions & string;
20
+ /**
21
+ * Calls an action and brings the page up to date with what it changed, in the same round
22
+ * trip: the write answers with the reads the page shows that it touched. What
23
+ * `useActionMutation` runs; for a flow of several calls behind one button, call each with it.
24
+ */
25
+ export declare function callAndRefresh<K extends Name>({ client, queryClient }: ActionQueryContext, name: K, input: ActionInput<RegisteredActions[K]>, options?: Omit<CallOptions, "refresh">): Promise<ActionOutput<RegisteredActions[K]>>;
26
+ export {};
27
+ //# sourceMappingURL=write-refresh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-refresh.d.ts","sourceRoot":"","sources":["../../src/react/write-refresh.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,YAAY,EAEjB,KAAK,WAAW,EAEjB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEhE,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG5D,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;CAC/B;AAED,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,WAAW,EAAE,WAAW,GAAG,SAAS,EAAE,CAMhE;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC,CAsDf;AAED,KAAK,IAAI,GAAG,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAE7C;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,CAAC,SAAS,IAAI,EACjD,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,kBAAkB,EAC3C,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,WAAW,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EACxC,OAAO,GAAE,IAAI,CAAC,WAAW,EAAE,SAAS,CAAM,GACzC,OAAO,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAU7C"}
@@ -0,0 +1,80 @@
1
+ import { MAX_REFRESHED_READS, tagsOverlap, } from "@parlor/core";
2
+ import { ACTION_QUERY_PREFIX } from "../query-keys.js";
3
+ import { readTagsOf } from "./sync.js";
4
+ /** The action queries the page shows, to name on a write so it answers with them fresh. */
5
+ export function shownReads(queryClient) {
6
+ return queryClient
7
+ .getQueryCache()
8
+ .findAll({ queryKey: ACTION_QUERY_PREFIX, type: "active" })
9
+ .slice(0, MAX_REFRESHED_READS)
10
+ .map((query) => ({ query, request: [String(query.queryKey[2]), query.queryKey[3]] }));
11
+ }
12
+ /**
13
+ * Brings the cache up to date after a write. The reads the server ran again go straight in;
14
+ * a shown read it could not run, or one whose reads are unknown here, is fetched again, and
15
+ * this waits for it; data nothing shows that the write changed is marked out of date. A
16
+ * server that did not say what the write changed gets every action query fetched again.
17
+ */
18
+ export async function applyWrite(queryClient, shown, envelope) {
19
+ const { writes, refreshed } = envelope;
20
+ if (!writes || !refreshed) {
21
+ await queryClient.invalidateQueries({ queryKey: ACTION_QUERY_PREFIX });
22
+ return;
23
+ }
24
+ const registry = readTagsOf(queryClient);
25
+ const changed = (query) => {
26
+ const tags = registry.tagsFor(query.queryHash);
27
+ return (tags === undefined ||
28
+ tags.some((read) => writes.some((write) => tagsOverlap(read, write))));
29
+ };
30
+ const refetch = [];
31
+ await Promise.all(shown.map(async ({ query }, index) => {
32
+ const fresh = refreshed[index];
33
+ // The server judged it untouched by the write.
34
+ if (fresh === null)
35
+ return;
36
+ if (fresh === undefined) {
37
+ if (changed(query))
38
+ refetch.push(query);
39
+ return;
40
+ }
41
+ if ("error" in fresh) {
42
+ refetch.push(query);
43
+ return;
44
+ }
45
+ // A fetch that started before the write would land older data over it.
46
+ if (query.state.fetchStatus === "fetching") {
47
+ await queryClient.cancelQueries({ queryKey: query.queryKey, exact: true });
48
+ }
49
+ registry.record(query.queryHash, fresh.tags, fresh.cursor);
50
+ queryClient.setQueryData(query.queryKey, fresh.data);
51
+ }));
52
+ const named = new Set(shown.map(({ query }) => query.queryHash));
53
+ for (const query of queryClient
54
+ .getQueryCache()
55
+ .findAll({ queryKey: ACTION_QUERY_PREFIX })) {
56
+ if (named.has(query.queryHash) || !changed(query))
57
+ continue;
58
+ void queryClient.invalidateQueries({
59
+ queryKey: query.queryKey,
60
+ exact: true,
61
+ refetchType: "none",
62
+ });
63
+ }
64
+ await Promise.all(refetch.map((query) => queryClient.invalidateQueries({ queryKey: query.queryKey, exact: true })));
65
+ }
66
+ /**
67
+ * Calls an action and brings the page up to date with what it changed, in the same round
68
+ * trip: the write answers with the reads the page shows that it touched. What
69
+ * `useActionMutation` runs; for a flow of several calls behind one button, call each with it.
70
+ */
71
+ export async function callAndRefresh({ client, queryClient }, name, input, options = {}) {
72
+ const shown = shownReads(queryClient);
73
+ const envelope = await client.invoke(name, input, {
74
+ ...options,
75
+ refresh: shown.map(({ request }) => request),
76
+ });
77
+ await applyWrite(queryClient, shown, envelope).catch(() => queryClient.invalidateQueries({ queryKey: ACTION_QUERY_PREFIX }));
78
+ return envelope.data;
79
+ }
80
+ //# sourceMappingURL=write-refresh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-refresh.js","sourceRoot":"","sources":["../../src/react/write-refresh.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type ActionInput,\n type ActionOutput,\n MAX_REFRESHED_READS,\n type ReadRequest,\n tagsOverlap,\n} from \"@parlor/core\";\nimport type { Query, QueryClient } from \"@tanstack/react-query\";\n\nimport type { ActionEnvelope, CallOptions } from \"../action-client.js\";\nimport { ACTION_QUERY_PREFIX } from \"../query-keys.js\";\nimport type { RegisteredActions } from \"../register.js\";\nimport type { ActionQueryContext } from \"./action-query.js\";\nimport { readTagsOf } from \"./sync.js\";\n\nexport interface ShownRead {\n readonly query: Query;\n readonly request: ReadRequest;\n}\n\n/** The action queries the page shows, to name on a write so it answers with them fresh. */\nexport function shownReads(queryClient: QueryClient): ShownRead[] {\n return queryClient\n .getQueryCache()\n .findAll({ queryKey: ACTION_QUERY_PREFIX, type: \"active\" })\n .slice(0, MAX_REFRESHED_READS)\n .map((query) => ({ query, request: [String(query.queryKey[2]), query.queryKey[3]] }));\n}\n\n/**\n * Brings the cache up to date after a write. The reads the server ran again go straight in;\n * a shown read it could not run, or one whose reads are unknown here, is fetched again, and\n * this waits for it; data nothing shows that the write changed is marked out of date. A\n * server that did not say what the write changed gets every action query fetched again.\n */\nexport async function applyWrite(\n queryClient: QueryClient,\n shown: readonly ShownRead[],\n envelope: ActionEnvelope<unknown>,\n): Promise<void> {\n const { writes, refreshed } = envelope;\n if (!writes || !refreshed) {\n await queryClient.invalidateQueries({ queryKey: ACTION_QUERY_PREFIX });\n return;\n }\n const registry = readTagsOf(queryClient);\n const changed = (query: Query) => {\n const tags = registry.tagsFor(query.queryHash);\n return (\n tags === undefined ||\n tags.some((read) => writes.some((write) => tagsOverlap(read, write)))\n );\n };\n\n const refetch: Query[] = [];\n await Promise.all(\n shown.map(async ({ query }, index) => {\n const fresh = refreshed[index];\n // The server judged it untouched by the write.\n if (fresh === null) return;\n if (fresh === undefined) {\n if (changed(query)) refetch.push(query);\n return;\n }\n if (\"error\" in fresh) {\n refetch.push(query);\n return;\n }\n // A fetch that started before the write would land older data over it.\n if (query.state.fetchStatus === \"fetching\") {\n await queryClient.cancelQueries({ queryKey: query.queryKey, exact: true });\n }\n registry.record(query.queryHash, fresh.tags, fresh.cursor);\n queryClient.setQueryData(query.queryKey, fresh.data);\n }),\n );\n\n const named = new Set(shown.map(({ query }) => query.queryHash));\n for (const query of queryClient\n .getQueryCache()\n .findAll({ queryKey: ACTION_QUERY_PREFIX })) {\n if (named.has(query.queryHash) || !changed(query)) continue;\n void queryClient.invalidateQueries({\n queryKey: query.queryKey,\n exact: true,\n refetchType: \"none\",\n });\n }\n await Promise.all(\n refetch.map((query) =>\n queryClient.invalidateQueries({ queryKey: query.queryKey, exact: true }),\n ),\n );\n}\n\ntype Name = keyof RegisteredActions & string;\n\n/**\n * Calls an action and brings the page up to date with what it changed, in the same round\n * trip: the write answers with the reads the page shows that it touched. What\n * `useActionMutation` runs; for a flow of several calls behind one button, call each with it.\n */\nexport async function callAndRefresh<K extends Name>(\n { client, queryClient }: ActionQueryContext,\n name: K,\n input: ActionInput<RegisteredActions[K]>,\n options: Omit<CallOptions, \"refresh\"> = {},\n): Promise<ActionOutput<RegisteredActions[K]>> {\n const shown = shownReads(queryClient);\n const envelope = await client.invoke(name, input, {\n ...options,\n refresh: shown.map(({ request }) => request),\n });\n await applyWrite(queryClient, shown, envelope).catch(() =>\n queryClient.invalidateQueries({ queryKey: ACTION_QUERY_PREFIX }),\n );\n return envelope.data;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parlor/client",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "homepage": "https://cychien.github.io/parlor",
5
5
  "bugs": "https://github.com/cychien/parlor/issues",
6
6
  "license": "MIT",
@@ -33,11 +33,11 @@
33
33
  }
34
34
  },
35
35
  "dependencies": {
36
- "@parlor/agent-ui": "0.3.0",
37
- "@parlor/core": "0.3.0",
38
- "@parlor/chat": "0.3.0",
39
- "@parlor/sync": "0.3.0",
40
- "@parlor/capabilities": "0.3.0"
36
+ "@parlor/core": "0.3.1",
37
+ "@parlor/chat": "0.3.1",
38
+ "@parlor/sync": "0.3.1",
39
+ "@parlor/agent-ui": "0.3.1",
40
+ "@parlor/capabilities": "0.3.1"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@tanstack/react-query": "^5.104.1",