@parlor/chat 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/model.d.ts +5 -0
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js.map +1 -1
- package/dist/server/actions.d.ts +8 -0
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/actions.js +10 -2
- package/dist/server/actions.js.map +1 -1
- package/dist/server/migrations.d.ts.map +1 -1
- package/dist/server/migrations.js +4 -0
- package/dist/server/migrations.js.map +1 -1
- package/dist/server/store.d.ts +2 -0
- package/dist/server/store.d.ts.map +1 -1
- package/dist/server/store.js +7 -3
- package/dist/server/store.js.map +1 -1
- package/dist/tags.d.ts +2 -0
- package/dist/tags.d.ts.map +1 -1
- package/dist/tags.js +2 -0
- package/dist/tags.js.map +1 -1
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,6 @@ export { type AppliedFrame, applyFrame } from "./open-turns.js";
|
|
|
4
4
|
export { isPromptTooLong, MAX_PROMPT_CHARS, PROMPT_LIMIT_MESSAGE } from "./limits.js";
|
|
5
5
|
export type { AgentInfo, AgentOption, AgentOptionValue, AgentRef, AgentUsage, AgentUsageWindow, AnswerToSign, ChatOwner, ChatSnapshot, ClaimedDevice, ClaimedTurn, HostSummary, OpenItem, OpenTurn, PromptToSign, ThreadHistory, ThreadList, ThreadPage, ThreadSummary, TurnFailure, TurnOutcome, TurnSignals, TurnState, TurnStatus, } from "./model.js";
|
|
6
6
|
export { CHAT_CHANNEL, CHAT_PLUGIN, type ChatFrame, HOST_PROTOCOL, type HostFrame, type HostHello, type HostStreamBatch, type HostWelcome, parseChatFrame, PUSHED_TURNS_PROTOCOL, type PushedTurn, type ProtocolRange, type StreamingKind, } from "./protocol.js";
|
|
7
|
-
export { CHAT_ACTIVITY_TAG, CHAT_TAG, HOSTS_TAG } from "./tags.js";
|
|
7
|
+
export { CHAT_ACTIVITY_TAG, CHAT_AGENTS_CHECK_TAG, CHAT_TAG, HOSTS_TAG } from "./tags.js";
|
|
8
8
|
export { type AskState, type ChatItem, type FoldedKind, type FoldInput, foldThread, type ItemFolders, type ThreadConfirmation, } from "./view.js";
|
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAC1D,YAAY,EACV,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,EACb,UAAU,EACV,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACtF,YAAY,EACV,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,UAAU,EACV,UAAU,EACV,aAAa,EACb,WAAW,EACX,WAAW,EACX,WAAW,EACX,SAAS,EACT,UAAU,GACX,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,YAAY,EACZ,WAAW,EACX,KAAK,SAAS,EACd,aAAa,EACb,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,cAAc,EACd,qBAAqB,EACrB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAC1D,YAAY,EACV,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,EACb,UAAU,EACV,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACtF,YAAY,EACV,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,UAAU,EACV,UAAU,EACV,aAAa,EACb,WAAW,EACX,WAAW,EACX,WAAW,EACX,SAAS,EACT,UAAU,GACX,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,YAAY,EACZ,WAAW,EACX,KAAK,SAAS,EACd,aAAa,EACb,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,cAAc,EACd,qBAAqB,EACrB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC1F,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,SAAS,EACd,UAAU,EACV,KAAK,WAAW,EAChB,KAAK,kBAAkB,GACxB,MAAM,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,6 @@ export { CHAT_EVENTS } from "./events.js";
|
|
|
2
2
|
export { applyFrame } from "./open-turns.js";
|
|
3
3
|
export { isPromptTooLong, MAX_PROMPT_CHARS, PROMPT_LIMIT_MESSAGE } from "./limits.js";
|
|
4
4
|
export { CHAT_CHANNEL, CHAT_PLUGIN, HOST_PROTOCOL, parseChatFrame, PUSHED_TURNS_PROTOCOL, } from "./protocol.js";
|
|
5
|
-
export { CHAT_ACTIVITY_TAG, CHAT_TAG, HOSTS_TAG } from "./tags.js";
|
|
5
|
+
export { CHAT_ACTIVITY_TAG, CHAT_AGENTS_CHECK_TAG, CHAT_TAG, HOSTS_TAG } from "./tags.js";
|
|
6
6
|
export { foldThread, } from "./view.js";
|
|
7
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,aAAa,CAAC;AAY1D,OAAO,EAAqB,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AA2BtF,OAAO,EACL,YAAY,EACZ,WAAW,EAEX,aAAa,EAKb,cAAc,EACd,qBAAqB,GAItB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,aAAa,CAAC;AAY1D,OAAO,EAAqB,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AA2BtF,OAAO,EACL,YAAY,EACZ,WAAW,EAEX,aAAa,EAKb,cAAc,EACd,qBAAqB,GAItB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC1F,OAAO,EAKL,UAAU,GAGX,MAAM,WAAW,CAAC","sourcesContent":["export { CHAT_EVENTS, type ChatEvent } from \"./events.js\";\nexport type {\n Author,\n AuthorOf,\n ChatItemBody,\n ChatItemKind,\n HostItemDraft,\n HostItemKind,\n ItemSignature,\n LoggedItem,\n UserItemKind,\n} from \"./items.js\";\nexport { type AppliedFrame, applyFrame } from \"./open-turns.js\";\nexport { isPromptTooLong, MAX_PROMPT_CHARS, PROMPT_LIMIT_MESSAGE } from \"./limits.js\";\nexport type {\n AgentInfo,\n AgentOption,\n AgentOptionValue,\n AgentRef,\n AgentUsage,\n AgentUsageWindow,\n AnswerToSign,\n ChatOwner,\n ChatSnapshot,\n ClaimedDevice,\n ClaimedTurn,\n HostSummary,\n OpenItem,\n OpenTurn,\n PromptToSign,\n ThreadHistory,\n ThreadList,\n ThreadPage,\n ThreadSummary,\n TurnFailure,\n TurnOutcome,\n TurnSignals,\n TurnState,\n TurnStatus,\n} from \"./model.js\";\nexport {\n CHAT_CHANNEL,\n CHAT_PLUGIN,\n type ChatFrame,\n HOST_PROTOCOL,\n type HostFrame,\n type HostHello,\n type HostStreamBatch,\n type HostWelcome,\n parseChatFrame,\n PUSHED_TURNS_PROTOCOL,\n type PushedTurn,\n type ProtocolRange,\n type StreamingKind,\n} from \"./protocol.js\";\nexport { CHAT_ACTIVITY_TAG, CHAT_AGENTS_CHECK_TAG, CHAT_TAG, HOSTS_TAG } from \"./tags.js\";\nexport {\n type AskState,\n type ChatItem,\n type FoldedKind,\n type FoldInput,\n foldThread,\n type ItemFolders,\n type ThreadConfirmation,\n} from \"./view.js\";\n"]}
|
package/dist/model.d.ts
CHANGED
|
@@ -27,6 +27,11 @@ export interface HostSummary {
|
|
|
27
27
|
* (epoch ms); a device it never asks is missing.
|
|
28
28
|
*/
|
|
29
29
|
readonly presenceDue?: Readonly<Record<string, number>> | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* When this computer last looked for the agents installed on it, by the server's clock;
|
|
32
|
+
* absent on a computer too old to look again when asked.
|
|
33
|
+
*/
|
|
34
|
+
readonly agentsCheckedAt?: number | undefined;
|
|
30
35
|
}
|
|
31
36
|
export interface AgentInfo {
|
|
32
37
|
readonly id: string;
|
package/dist/model.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE7D,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEzE,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,qFAAqF;IACrF,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IACjD;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
|
package/dist/model.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"","sourcesContent":["import type { HostId, ItemId, ThreadId, TurnId, UserId } from \"@parlor/core\";\nimport type { Delegation, DeviceKeys } from \"@parlor/server\";\n\nimport type { ChatItemBody, LoggedItem, UserItemKind } from \"./items.js\";\n\nexport interface AgentRef {\n readonly hostId: HostId;\n /** A profile id on that host (`claude`, `codex`), not an entity. */\n readonly agentId: string;\n}\n\n/**\n * Whose chat a row is. Every thread, turn and host row carries both and every chat query\n * filters by both, so members of one organization scope never see each other's chats.\n */\nexport interface ChatOwner {\n readonly scope: string;\n readonly userId: UserId;\n}\n\nexport interface HostSummary {\n readonly id: HostId;\n readonly name: string;\n readonly platform: string;\n readonly online: boolean;\n readonly agents: readonly AgentInfo[];\n /** The devices this computer runs prompts from; absent when it is too old to say. */\n readonly devices?: readonly string[] | undefined;\n /**\n * When each of those devices must sign its next prompt with Face ID or Touch ID again\n * (epoch ms); a device it never asks is missing.\n */\n readonly presenceDue?: Readonly<Record<string, number>> | undefined;\n}\n\nexport interface AgentInfo {\n readonly id: string;\n readonly name: string;\n readonly version?: string | undefined;\n readonly ready: boolean;\n /** Why a not-ready agent cannot run yet (\"run `claude` to log in\"). */\n readonly problem?: string | undefined;\n /** What a prompt may choose for its turn, as the agent last offered it; absent until it has. */\n readonly options?: readonly AgentOption[] | undefined;\n /** The account's allowance, as the agent last reported it; absent until it has. */\n readonly usage?: AgentUsage | undefined;\n /**\n * The name this agent knows the app by outside the sidebar, when the user let it use the\n * app there: \"use coursekit to ...\" in Claude Code.\n */\n readonly outsideName?: string | undefined;\n}\n\n/**\n * One setting a prompt may choose, such as the model or how hard it thinks. Never the\n * permission mode: that is the computer's to set.\n */\nexport interface AgentOption {\n readonly id: string;\n readonly name: string;\n /** `model` and `thought_level` as the agent tags them; any other the agent names. */\n readonly category?: string | undefined;\n /** The agent's own default, the value a prompt that chooses nothing runs with. */\n readonly current: string;\n readonly values: readonly AgentOptionValue[];\n}\n\nexport interface AgentOptionValue {\n readonly id: string;\n readonly name: string;\n readonly description?: string | undefined;\n}\n\nexport interface AgentUsage {\n /** Account-wide windows first, each set shortest first. */\n readonly windows: readonly AgentUsageWindow[];\n /** When the agent reported it (epoch ms). */\n readonly at: number;\n}\n\nexport interface AgentUsageWindow {\n /** The vendor's name for it: `five_hour`, `seven_day`, `seven_day_opus`. */\n readonly id: string;\n readonly minutes: number;\n /** Share of the window used, 0 to 1. */\n readonly used: number;\n /** When the window rolls over (epoch ms). */\n readonly resetsAt?: number | undefined;\n}\n\nexport interface ThreadSummary {\n readonly id: ThreadId;\n readonly title: string;\n readonly agent: AgentRef | undefined;\n readonly updatedAt: number;\n readonly lastSeq: number;\n}\n\nexport type TurnState = \"queued\" | \"running\" | \"done\" | \"failed\" | \"cancelled\";\n\nexport type TurnFailure =\n | \"agent_exited\"\n | \"agent_unavailable\"\n | \"device_rejected\"\n | \"signature_invalid\"\n | \"prompt_expired\"\n | \"host_lost\";\n\nexport type TurnOutcome =\n | { readonly state: \"done\"; readonly stopReason: string }\n | { readonly state: \"cancelled\" }\n | { readonly state: \"failed\"; readonly reason: TurnFailure };\n\n/** Still being produced: only in memory, on the instance the host posts to. */\nexport type OpenItem =\n | { readonly id: ItemId; readonly kind: \"reply\" | \"reasoning\"; readonly text: string }\n | {\n readonly id: ItemId;\n readonly kind: \"tool\";\n readonly title: string;\n readonly status: \"pending\" | \"running\";\n }\n | {\n readonly id: ItemId;\n readonly kind: \"plan\";\n readonly entries: ChatItemBody<\"plan\">[\"entries\"];\n };\n\nexport interface OpenTurn {\n readonly turnId: TurnId;\n readonly threadId: ThreadId;\n readonly items: readonly OpenItem[];\n}\n\nexport interface TurnStatus {\n readonly turnId: TurnId;\n readonly state: TurnState;\n readonly agent: AgentRef;\n readonly failure?: TurnFailure | undefined;\n}\n\nexport interface ThreadPage {\n readonly thread: ThreadSummary | undefined;\n readonly items: readonly LoggedItem[];\n readonly open: readonly OpenTurn[];\n readonly turns: readonly TurnStatus[];\n readonly hasMore: boolean;\n}\n\nexport interface ChatSnapshot {\n readonly threads: readonly ThreadSummary[];\n /** `threads` was cut at its limit; `threadsBefore` reads on from its last one. */\n readonly moreThreads?: boolean | undefined;\n readonly hosts: readonly HostSummary[];\n readonly page: ThreadPage;\n}\n\n/** What `history` returns: earlier items of a thread, oldest first, with their turns. */\nexport interface ThreadHistory {\n readonly items: readonly LoggedItem[];\n readonly turns: readonly TurnStatus[];\n readonly hasMore: boolean;\n}\n\n/** What `threadsBefore` returns: the next older threads, newest first. */\nexport interface ThreadList {\n readonly threads: readonly ThreadSummary[];\n readonly hasMore: boolean;\n}\n\n/** The device's keys as the account has them; the host compares them with its own pins. */\nexport type ClaimedDevice = DeviceKeys;\n\nexport interface ClaimedTurn {\n /** The thread id; every chat write returns it as `id`, which becomes its sync tag. */\n readonly id: ThreadId;\n readonly turnId: TurnId;\n readonly agent: AgentRef;\n /** The client the prompt came from; the turn token binds `ui_*` to it. */\n readonly clientId: string;\n readonly prompt: LoggedItem<\"prompt\">;\n readonly device: ClaimedDevice | undefined;\n /** The `<parlor-context>` block for a fresh agent session. */\n readonly context: string;\n readonly token: Delegation;\n readonly leaseUntil: number;\n}\n\nexport interface TurnSignals {\n readonly turnId: TurnId;\n readonly items: readonly LoggedItem<Exclude<UserItemKind, \"prompt\">>[];\n /** The keys of each device that answered, as the account lists them; revoked ones are left out. */\n readonly devices?: readonly DeviceKeys[];\n}\n\n/** What a device signs for a prompt; the host rebuilds the same statement from the item. */\nexport interface PromptToSign {\n readonly threadId: ThreadId;\n readonly turnId: TurnId;\n readonly agent: AgentRef;\n readonly text: string;\n}\n\nexport interface AnswerToSign {\n readonly threadId: ThreadId;\n readonly askId: ItemId;\n readonly choice: string;\n readonly values?: ChatItemBody<\"answer\">[\"values\"];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"","sourcesContent":["import type { HostId, ItemId, ThreadId, TurnId, UserId } from \"@parlor/core\";\nimport type { Delegation, DeviceKeys } from \"@parlor/server\";\n\nimport type { ChatItemBody, LoggedItem, UserItemKind } from \"./items.js\";\n\nexport interface AgentRef {\n readonly hostId: HostId;\n /** A profile id on that host (`claude`, `codex`), not an entity. */\n readonly agentId: string;\n}\n\n/**\n * Whose chat a row is. Every thread, turn and host row carries both and every chat query\n * filters by both, so members of one organization scope never see each other's chats.\n */\nexport interface ChatOwner {\n readonly scope: string;\n readonly userId: UserId;\n}\n\nexport interface HostSummary {\n readonly id: HostId;\n readonly name: string;\n readonly platform: string;\n readonly online: boolean;\n readonly agents: readonly AgentInfo[];\n /** The devices this computer runs prompts from; absent when it is too old to say. */\n readonly devices?: readonly string[] | undefined;\n /**\n * When each of those devices must sign its next prompt with Face ID or Touch ID again\n * (epoch ms); a device it never asks is missing.\n */\n readonly presenceDue?: Readonly<Record<string, number>> | undefined;\n /**\n * When this computer last looked for the agents installed on it, by the server's clock;\n * absent on a computer too old to look again when asked.\n */\n readonly agentsCheckedAt?: number | undefined;\n}\n\nexport interface AgentInfo {\n readonly id: string;\n readonly name: string;\n readonly version?: string | undefined;\n readonly ready: boolean;\n /** Why a not-ready agent cannot run yet (\"run `claude` to log in\"). */\n readonly problem?: string | undefined;\n /** What a prompt may choose for its turn, as the agent last offered it; absent until it has. */\n readonly options?: readonly AgentOption[] | undefined;\n /** The account's allowance, as the agent last reported it; absent until it has. */\n readonly usage?: AgentUsage | undefined;\n /**\n * The name this agent knows the app by outside the sidebar, when the user let it use the\n * app there: \"use coursekit to ...\" in Claude Code.\n */\n readonly outsideName?: string | undefined;\n}\n\n/**\n * One setting a prompt may choose, such as the model or how hard it thinks. Never the\n * permission mode: that is the computer's to set.\n */\nexport interface AgentOption {\n readonly id: string;\n readonly name: string;\n /** `model` and `thought_level` as the agent tags them; any other the agent names. */\n readonly category?: string | undefined;\n /** The agent's own default, the value a prompt that chooses nothing runs with. */\n readonly current: string;\n readonly values: readonly AgentOptionValue[];\n}\n\nexport interface AgentOptionValue {\n readonly id: string;\n readonly name: string;\n readonly description?: string | undefined;\n}\n\nexport interface AgentUsage {\n /** Account-wide windows first, each set shortest first. */\n readonly windows: readonly AgentUsageWindow[];\n /** When the agent reported it (epoch ms). */\n readonly at: number;\n}\n\nexport interface AgentUsageWindow {\n /** The vendor's name for it: `five_hour`, `seven_day`, `seven_day_opus`. */\n readonly id: string;\n readonly minutes: number;\n /** Share of the window used, 0 to 1. */\n readonly used: number;\n /** When the window rolls over (epoch ms). */\n readonly resetsAt?: number | undefined;\n}\n\nexport interface ThreadSummary {\n readonly id: ThreadId;\n readonly title: string;\n readonly agent: AgentRef | undefined;\n readonly updatedAt: number;\n readonly lastSeq: number;\n}\n\nexport type TurnState = \"queued\" | \"running\" | \"done\" | \"failed\" | \"cancelled\";\n\nexport type TurnFailure =\n | \"agent_exited\"\n | \"agent_unavailable\"\n | \"device_rejected\"\n | \"signature_invalid\"\n | \"prompt_expired\"\n | \"host_lost\";\n\nexport type TurnOutcome =\n | { readonly state: \"done\"; readonly stopReason: string }\n | { readonly state: \"cancelled\" }\n | { readonly state: \"failed\"; readonly reason: TurnFailure };\n\n/** Still being produced: only in memory, on the instance the host posts to. */\nexport type OpenItem =\n | { readonly id: ItemId; readonly kind: \"reply\" | \"reasoning\"; readonly text: string }\n | {\n readonly id: ItemId;\n readonly kind: \"tool\";\n readonly title: string;\n readonly status: \"pending\" | \"running\";\n }\n | {\n readonly id: ItemId;\n readonly kind: \"plan\";\n readonly entries: ChatItemBody<\"plan\">[\"entries\"];\n };\n\nexport interface OpenTurn {\n readonly turnId: TurnId;\n readonly threadId: ThreadId;\n readonly items: readonly OpenItem[];\n}\n\nexport interface TurnStatus {\n readonly turnId: TurnId;\n readonly state: TurnState;\n readonly agent: AgentRef;\n readonly failure?: TurnFailure | undefined;\n}\n\nexport interface ThreadPage {\n readonly thread: ThreadSummary | undefined;\n readonly items: readonly LoggedItem[];\n readonly open: readonly OpenTurn[];\n readonly turns: readonly TurnStatus[];\n readonly hasMore: boolean;\n}\n\nexport interface ChatSnapshot {\n readonly threads: readonly ThreadSummary[];\n /** `threads` was cut at its limit; `threadsBefore` reads on from its last one. */\n readonly moreThreads?: boolean | undefined;\n readonly hosts: readonly HostSummary[];\n readonly page: ThreadPage;\n}\n\n/** What `history` returns: earlier items of a thread, oldest first, with their turns. */\nexport interface ThreadHistory {\n readonly items: readonly LoggedItem[];\n readonly turns: readonly TurnStatus[];\n readonly hasMore: boolean;\n}\n\n/** What `threadsBefore` returns: the next older threads, newest first. */\nexport interface ThreadList {\n readonly threads: readonly ThreadSummary[];\n readonly hasMore: boolean;\n}\n\n/** The device's keys as the account has them; the host compares them with its own pins. */\nexport type ClaimedDevice = DeviceKeys;\n\nexport interface ClaimedTurn {\n /** The thread id; every chat write returns it as `id`, which becomes its sync tag. */\n readonly id: ThreadId;\n readonly turnId: TurnId;\n readonly agent: AgentRef;\n /** The client the prompt came from; the turn token binds `ui_*` to it. */\n readonly clientId: string;\n readonly prompt: LoggedItem<\"prompt\">;\n readonly device: ClaimedDevice | undefined;\n /** The `<parlor-context>` block for a fresh agent session. */\n readonly context: string;\n readonly token: Delegation;\n readonly leaseUntil: number;\n}\n\nexport interface TurnSignals {\n readonly turnId: TurnId;\n readonly items: readonly LoggedItem<Exclude<UserItemKind, \"prompt\">>[];\n /** The keys of each device that answered, as the account lists them; revoked ones are left out. */\n readonly devices?: readonly DeviceKeys[];\n}\n\n/** What a device signs for a prompt; the host rebuilds the same statement from the item. */\nexport interface PromptToSign {\n readonly threadId: ThreadId;\n readonly turnId: TurnId;\n readonly agent: AgentRef;\n readonly text: string;\n}\n\nexport interface AnswerToSign {\n readonly threadId: ThreadId;\n readonly askId: ItemId;\n readonly choice: string;\n readonly values?: ChatItemBody<\"answer\">[\"values\"];\n}\n"]}
|
package/dist/server/actions.d.ts
CHANGED
|
@@ -140,6 +140,9 @@ export declare function userChatActions(deps: ChatActionDeps): {
|
|
|
140
140
|
userActive: import("@parlor/core").ActionDefinition<z.ZodObject<{}, z.core.$strip>, {
|
|
141
141
|
readonly ok: true;
|
|
142
142
|
}>;
|
|
143
|
+
checkAgents: import("@parlor/core").ActionDefinition<z.ZodObject<{}, z.core.$strip>, {
|
|
144
|
+
readonly askedAt: number;
|
|
145
|
+
}>;
|
|
143
146
|
};
|
|
144
147
|
/**
|
|
145
148
|
* What the server keeps about the computers it serves: which said hello, their agents'
|
|
@@ -236,6 +239,7 @@ export declare function hostChatActions(deps: ChatActionDeps, session?: HostSess
|
|
|
236
239
|
}, z.core.$strip>>;
|
|
237
240
|
devices: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
238
241
|
presenceDue: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
242
|
+
agentsChecked: z.ZodOptional<z.ZodLiteral<true>>;
|
|
239
243
|
}, z.core.$strip>, {
|
|
240
244
|
readonly id: string;
|
|
241
245
|
readonly onlineUntil: number;
|
|
@@ -469,6 +473,9 @@ export declare function chatActions(deps: ChatActionDeps, session?: HostSession)
|
|
|
469
473
|
userActive: import("@parlor/core").ActionDefinition<z.ZodObject<{}, z.core.$strip>, {
|
|
470
474
|
readonly ok: true;
|
|
471
475
|
}>;
|
|
476
|
+
checkAgents: import("@parlor/core").ActionDefinition<z.ZodObject<{}, z.core.$strip>, {
|
|
477
|
+
readonly askedAt: number;
|
|
478
|
+
}>;
|
|
472
479
|
hostHello: import("@parlor/core").ActionDefinition<z.ZodObject<{
|
|
473
480
|
protocols: z.ZodObject<{
|
|
474
481
|
min: z.ZodNumber;
|
|
@@ -542,6 +549,7 @@ export declare function chatActions(deps: ChatActionDeps, session?: HostSession)
|
|
|
542
549
|
}, z.core.$strip>>;
|
|
543
550
|
devices: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
544
551
|
presenceDue: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
552
|
+
agentsChecked: z.ZodOptional<z.ZodLiteral<true>>;
|
|
545
553
|
}, z.core.$strip>, {
|
|
546
554
|
readonly id: string;
|
|
547
555
|
readonly onlineUntil: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/server/actions.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,MAAM,EACZ,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,SAAS,EAAkB,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAiC,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,KAAK,EACV,SAAS,EACT,SAAS,EACT,YAAY,EACZ,aAAa,EACb,UAAU,EACV,WAAW,EACX,WAAW,EACX,WAAW,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAiB,KAAK,WAAW,EAAyB,MAAM,gBAAgB,CAAC;AACxF,OAAO,
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/server/actions.ts"],"names":[],"mappings":"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"}
|
package/dist/server/actions.js
CHANGED
|
@@ -5,7 +5,7 @@ import { z } from "zod";
|
|
|
5
5
|
import { idSchema } from "../id-schemas.js";
|
|
6
6
|
import { chatItemBodies, hostItemDraft } from "../items.js";
|
|
7
7
|
import { HOST_PROTOCOL, PUSHED_TURNS_PROTOCOL } from "../protocol.js";
|
|
8
|
-
import { CHAT_ACTIVITY_TAG, CHAT_TAG, HOSTS_TAG } from "../tags.js";
|
|
8
|
+
import { CHAT_ACTIVITY_TAG, CHAT_AGENTS_CHECK_TAG, CHAT_TAG, HOSTS_TAG, } from "../tags.js";
|
|
9
9
|
import { turnContext } from "./context.js";
|
|
10
10
|
import { chatAction } from "./party.js";
|
|
11
11
|
import { agentInfoSchema, TURN_FAILURES } from "./rows.js";
|
|
@@ -193,6 +193,12 @@ export function userChatActions(deps) {
|
|
|
193
193
|
writes: [CHAT_ACTIVITY_TAG],
|
|
194
194
|
run: () => ({ ok: true }),
|
|
195
195
|
}),
|
|
196
|
+
checkAgents: chatAction("user", enforcing, {
|
|
197
|
+
description: "Ask the user's computers to look again for the coding agents installed on them; each reports what it found, stamped `agentsCheckedAt`. Answers when it asked, by the same clock.",
|
|
198
|
+
input: z.object({}),
|
|
199
|
+
writes: [CHAT_AGENTS_CHECK_TAG],
|
|
200
|
+
run: () => ({ askedAt: Date.now() }),
|
|
201
|
+
}),
|
|
196
202
|
};
|
|
197
203
|
}
|
|
198
204
|
/**
|
|
@@ -351,12 +357,13 @@ export function hostChatActions(deps, session = hostSession(deps)) {
|
|
|
351
357
|
},
|
|
352
358
|
}),
|
|
353
359
|
hostReport: chatAction("host", enforcing, {
|
|
354
|
-
description: "This computer went offline
|
|
360
|
+
description: "This computer went offline, changed its agents, or looked for them again (`agentsChecked`).",
|
|
355
361
|
input: z.object({
|
|
356
362
|
online: z.boolean(),
|
|
357
363
|
agents: z.array(agentInfoSchema).max(32),
|
|
358
364
|
devices: z.array(z.string().min(1).max(64)).max(256).optional(),
|
|
359
365
|
presenceDue: presenceDueSchema.optional(),
|
|
366
|
+
agentsChecked: z.literal(true).optional(),
|
|
360
367
|
}),
|
|
361
368
|
writes: [HOSTS_TAG],
|
|
362
369
|
run: async (input, host, ctx) => {
|
|
@@ -369,6 +376,7 @@ export function hostChatActions(deps, session = hostSession(deps)) {
|
|
|
369
376
|
agents: input.agents,
|
|
370
377
|
devices: input.devices,
|
|
371
378
|
presenceDue: input.presenceDue,
|
|
379
|
+
agentsCheckedAt: input.agentsChecked ? Date.now() : undefined,
|
|
372
380
|
online: input.online,
|
|
373
381
|
ttlMs: 2 * deps.heartbeatMs,
|
|
374
382
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/server/actions.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,GAIZ,MAAM,cAAc,CAAC;AACtB,OAAO,EAAkB,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAsC,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,aAAa,EAAmB,MAAM,aAAa,CAAC;AAW7E,OAAO,EAAE,aAAa,EAAoB,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAiB,UAAU,EAAE,MAAM,YAAY,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE3D,MAAM,iBAAiB,GAAG,CAAC;KACxB,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;KACjE,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,GAAG,EAAE,sBAAsB,CAAC,CAAC;AAC3E,OAAO,EAIL,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;AAoCnE,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACpC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;AAChC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;AAChC,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAEzC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAClC,6EAA6E;AAC7E,MAAM,kBAAkB,GAAG,EAAE,GAAG,MAAM,CAAC;AACvC,MAAM,QAAQ,GAAwB,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;AAE/E,MAAM,IAAI,GAAG,CAAC,GAAkB,EAAE,EAAE,CAAC,GAAG,CAAC,EAAY,CAAC;AAEtD,KAAK,UAAU,WAAW,CACxB,IAAoB,EACpB,EAAU,EACV,KAAgB;IAEhB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IACpD,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;IACjC,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAC9B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAC9D,CAAC;IACF,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IACvD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,CAAC,UAAU,CACnB,KAAK,EACL,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAC5B,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,SAAS,GAAG,CAAC,EACjB,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,SAAS,EACnB,GAAG,OAAO,EACC,EAAe,EAAE,CAAC,OAAO,CAAC;AAEvC,MAAM,UAAU,eAAe,CAAC,IAAoB;IAClD,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAC3B,OAAO;QACL,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;YAClC,WAAW,EACT,kHAAkH;YACpH,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;gBACd,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE;gBAC7B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;aACrD,CAAC;YACF,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;gBAChB,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACvD,CAAC,SAAS,CAAC;gBACX,CAAC,eAAe,CAAC;aAClB;YACD,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAyB,EAAE;gBACrD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;gBACrB,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;oBAC/C,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE,IAAI,CAAC;oBAChC,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC;oBAC3B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC;iBAC3D,CAAC,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;gBAC3B,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;oBACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC;oBAChF,MAAM,KAAK,GAAG,KAAK,KAAK,SAAS,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;oBACzD,IAAI,KAAK;wBAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;oBAC/D,OAAO,CAAC,KAAK,CAAC;gBAChB,CAAC,CAAC,CAAC;gBACH,OAAO;oBACL,OAAO;oBACP,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,iBAAiB,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACrE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;oBAC3B,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE;iBACnC,CAAC;YACJ,CAAC;SACF,CAAC;QACF,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;YACnC,WAAW,EAAE,2CAA2C;YACxD,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;YACvC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC9C,GAAG,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAyB,EAAE,CAC/C,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC;SAC7E,CAAC;QACF,OAAO,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;YACrC,WAAW,EACT,6GAA6G;YAC/G,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;gBACd,QAAQ;gBACR,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;gBAClC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;aACrD,CAAC;YACF,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC9C,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAA0B,EAAE;gBACtD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC1D,IAAI,CAAC,IAAI;oBACP,MAAM,IAAI,WAAW,CAAC,WAAW,EAAE,mCAAmC,CAAC,CAAC;gBAC1E,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YAC7E,CAAC;SACF,CAAC;QACF,aAAa,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;YAC3C,WAAW,EACT,iGAAiG;YACnG,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;gBACd,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;gBACtE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;aACrD,CAAC;YACF,KAAK,EAAE,CAAC,QAAQ,CAAC;YACjB,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAuB,EAAE;gBACnD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC5D,IAAI,CAAC,IAAI;oBACP,MAAM,IAAI,WAAW,CAAC,WAAW,EAAE,mCAAmC,CAAC,CAAC;gBAC1E,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1D,CAAC;SACF,CAAC;QACF,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;YACnC,WAAW,EAAE,8CAA8C;YAC3D,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;YACnB,KAAK,EAAE,CAAC,SAAS,EAAE,eAAe,CAAC;YACnC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAA0B,EAAE,CACvD,CAAC,MAAM,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC;SAC5D,CAAC;QACF,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;YAClC,WAAW,EAAE,2DAA2D;YACxE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;gBACd,QAAQ;gBACR,MAAM;gBACN,MAAM;gBACN,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;gBACpC,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,IAAI;aACnC,CAAC;YACF,GAAG,EAAE,KAAK,EACR,KAAK,EACL,IAAI,EACJ,GAAG,EACwD,EAAE;gBAC7D,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;gBACvD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CACrB,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAC1D,CAAC;gBACF,IAAI,CAAC,IAAI;oBAAE,MAAM,IAAI,WAAW,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;gBACpE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;oBAClD,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,EAAE,IAAI,EAAE;wBACzC,QAAQ,EAAE,KAAK,CAAC,QAAQ;wBACxB,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;wBACjE,IAAI,EAAE;4BACJ,MAAM,EAAE,KAAK,CAAC,MAAM;4BACpB,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK;4BACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;4BACxB,QAAQ,EAAE,IAAI,CAAC,QAAQ;4BACvB,SAAS,EAAE,IAAI,CAAC,SAAS;yBAC1B;qBACF,CAAC,CAAC;oBACH,OAAO;wBACL,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;wBACpD,QAAQ,EAAE,KAAK,CAAC,QAAQ;qBACzB,CAAC;gBACJ,CAAC,CAAC,CAAC;gBACH,IAAI,IAAI,CAAC,QAAQ,IAAI,qBAAqB;oBAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC9E,OAAO,IAAI,CAAC;YACd,CAAC;SACF,CAAC;QACF,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;YACpC,WAAW,EAAE,mDAAmD;YAChE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACjF,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAoC,EAAE;gBAC3D,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC;gBAChC,IAAI,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;oBACpE,IAAI,CAAC,MAAM,EAAE,CAAC;wBACZ,MAAM,IAAI,WAAW,CAAC,WAAW,EAAE,4BAA4B,CAAC,CAAC;oBACnE,CAAC;gBACH,CAAC;gBACD,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;oBACtC,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,EAAE,IAAI,EAAE;wBACzC,QAAQ,EAAE,KAAK,CAAC,QAAQ;wBACxB,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;qBAClE,CAAC,CAAC;oBACH,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACtE,CAAC,CAAC,CAAC;YACL,CAAC;SACF,CAAC;QACF,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;YACpC,WAAW,EAAE,6DAA6D;YAC1E,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YAC7C,MAAM,EAAE,CAAC,QAAQ,CAAC;YAClB,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAoC,EAAE;gBAChE,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;oBAChD,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;iBACxD,CAAC,CAAC;gBACH,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;YAChC,CAAC;SACF,CAAC;QACF,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;YACxC,WAAW,EACT,qHAAqH;YACvH,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;YACnB,MAAM,EAAE,CAAC,iBAAiB,CAAC;YAC3B,GAAG,EAAE,GAA0B,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;SACjD,CAAC;KACH,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,IAAoB;IAC9C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,MAAM,OAAO,GAAG,KAAK,EAAE,IAAc,EAAE,EAAU,EAAE,EAAE;QACnD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3E,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,WAAW,CAAC,WAAW,EAAE,iCAAiC,CAAC,CAAC;QAClF,IAAI,KAAK,CAAC,QAAQ,GAAG,iBAAiB,EAAE,CAAC;YACvC,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;YACxC,MAAM,IAAI,WAAW,CAAC,WAAW,EAAE,iCAAiC,CAAC,CAAC;QACxE,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IACF,MAAM,cAAc,GAAG,KAAK,EAAE,IAAc,EAAE,EAAU,EAAE,EAAE;QAC1D,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,MAAM,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC/D,CAAC,CAAC;IACF,MAAM,UAAU,GAAG,IAAI,GAAG,EAAuC,CAAC;IAClE,MAAM,WAAW,GAAG,CAAC,MAAc,EAAE,MAA4B,EAAE,EAAE;QACnE,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACjF,CAAC,CAAC;IACF,MAAM,WAAW,GAAG,KAAK,EAAE,IAAc,EAAE,EAAU,EAAE,OAAe,EAAE,EAAE;QACxE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CACvD,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CACjD,CAAC;YACF,IAAI,KAAK;gBAAE,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC;IACnE,CAAC,CAAC;IACF,MAAM,IAAI,GAAG,KAAK,EAChB,IAAc,EACd,EAAU,EACV,IAA+E,EAC/E,EAAE;QACF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACxB,MAAM,IAAI,WAAW,CAAC,UAAU,EAAE,4CAA4C,CAAC,CAAC;QAClF,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE;YACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,KAAK,EAAE,MAAM,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC;YAChD,KAAK,EAAE,IAAI,CAAC,OAAO;SACpB,CAAC,CAAC;IACL,CAAC,CAAC;IACF,8GAA8G;IAC9G,MAAM,KAAK,GAAG,KAAK,EAAE,IAAc,EAAE,EAAU,EAAoC,EAAE;QACnF,MAAM,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC/B,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC3B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;YACrD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAC5E,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAChD,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC;YACtD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACvD,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE;oBACb,QAAQ,EAAE,OAAO,CAAC,EAAE;oBACpB,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO;iBAC/B,CAAC;gBACF,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS;gBAChE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;gBAChC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,qBAAqB,CAAC;aACjE,CAAC,CAAC;YACH,MAAM,OAAO,GAAG,WAAW,CAAC;gBAC1B,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE;gBAC3B,OAAO;gBACP,MAAM;gBACN,YAAY,EAAE,IAAI,CAAC,YAAY;gBAC/B,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;aACpE,CAAC,CAAC;YACH,OAAO,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;YACnE,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC;IACF,oFAAoF;IACpF,MAAM,OAAO,GAAG,CAAC,IAAc,EAAE,MAAgB,EAAE,IAAY,EAAE,EAAE,CACjE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;QAC/B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAChD,CAAC,CAAC,CAAC;IACL,OAAO;QACL,OAAO;QACP,cAAc;QACd,WAAW;QACX,WAAW;QACX,IAAI;QACJ,KAAK;QACL,OAAO;QACP,QAAQ;KACT,CAAC;AACJ,CAAC;AAID,uEAAuE;AACvE,MAAM,UAAU,eAAe,CAC7B,IAAoB,EACpB,OAAO,GAAgB,WAAW,CAAC,IAAI,CAAC;IAExC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IACzE,OAAO;QACL,SAAS,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;YACvC,WAAW,EACT,kGAAkG;YACpG,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;gBACd,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC;oBAClB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC5B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;iBAC7B,CAAC;gBACF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;gBAC/D,WAAW,EAAE,iBAAiB,CAAC,QAAQ,EAAE;aAC1C,CAAC;YACF,MAAM,EAAE,CAAC,SAAS,CAAC;YACnB,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAkD,EAAE;gBAC9E,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC5B,MAAM,SAAS,GAAG,EAAE,GAAG,EAAE,iBAAiB,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC;gBACjE,MAAM,MAAM,GAAG,KAAK,EAAE,MAAsC,EAAE,EAAE;oBAC9D,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;oBACpB,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;oBACnD,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAc,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;gBAC7D,CAAC,CAAC;gBACF,IAAI,KAAK,CAAC,SAAS,CAAC,GAAG,GAAG,SAAS,CAAC,GAAG;oBAAE,OAAO,MAAM,CAAC,cAAc,CAAC,CAAC;gBACvE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;gBAC9D,IAAI,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG;oBAAE,OAAO,MAAM,CAAC,aAAa,CAAC,CAAC;gBACjE,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;oBACtD,QAAQ;oBACR,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,MAAM,EAAE,IAAI;oBACZ,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW;iBAC5B,CAAC,CAAC;gBACH,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC9B,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACjB,OAAO;oBACL,EAAE;oBACF,QAAQ,EAAE,IAAI;oBACd,QAAQ;oBACR,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,WAAW,EAAE,IAAI,CAAC,WAAW;oBAC7B,YAAY,EAAE,IAAI;iBACnB,CAAC;YACJ,CAAC;SACF,CAAC;QACF,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;YACxC,WAAW,EAAE,mDAAmD;YAChE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;gBACd,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;gBACnB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;gBAC/D,WAAW,EAAE,iBAAiB,CAAC,QAAQ,EAAE;aAC1C,CAAC;YACF,MAAM,EAAE,CAAC,SAAS,CAAC;YACnB,GAAG,EAAE,KAAK,EACR,KAAK,EACL,IAAI,EACJ,GAAG,EAC6D,EAAE;gBAClE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;gBACrB,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACtC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;oBACvE,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW;iBAC5B,CAAC,CAAC;gBACH,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC5C,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;YAC/C,CAAC;SACF,CAAC;QACF,cAAc,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;YAC5C,WAAW,EACT,2JAA2J;YAC7J,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACtD,GAAG,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,EAAuB,EAAE;gBACvD,MAAM,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBACtC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;oBAC7B,MAAM,IAAI,WAAW,CACnB,WAAW,EACX,4CAA4C,CAC7C,CAAC;gBACJ,CAAC;gBACD,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAClF,CAAC;SACF,CAAC;QACF,SAAS,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;YACvC,WAAW,EACT,+FAA+F;YACjG,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;YACnB,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAwB,EAAE;gBACrD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBACrD,IAAI,CAAC,OAAO;oBAAE,MAAM,IAAI,WAAW,CAAC,WAAW,EAAE,qBAAqB,CAAC,CAAC;gBACxE,OAAO,OAAO,CAAC;YACjB,CAAC;SACF,CAAC;QACF,WAAW,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;YACzC,WAAW,EAAE,6DAA6D;YAC1E,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAC3E,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAA0B,EAAE;gBACtD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK;oBAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAClE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;gBACrB,MAAM,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC/B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;gBAC/E,OAAO,OAAO,CAAC,GAAG,CAChB,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAwB,EAAE;oBAChD,MAAM,SAAS,GAAG,IAAI,GAAG,CACvB,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAC3B,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM;wBACxC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;wBAC7B,CAAC,CAAC,EAAE,CACP,CACF,CAAC;oBACF,MAAM,OAAO,GAAG,CACd,MAAM,OAAO,CAAC,GAAG,CACf,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC9B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAC1C,CACF,CACF,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;oBAC3C,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;gBAC5D,CAAC,CAAC,CACH,CAAC;YACJ,CAAC;SACF,CAAC;QACF,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;YACxC,WAAW,EACT,wFAAwF;YAC1F,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAClE,GAAG,EAAE,KAAK,EACR,KAAK,EACL,IAAI,EACJ,GAAG,EAKF,EAAE;gBACH,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACnC,MAAM,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBACtC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;oBACtD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAC7C,EAAE,EACF,IAAI,EACJ,IAAI,CAAC,IAAI,EACT,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,KAAK,EACX,IAAI,CAAC,OAAO,CACb,CAAC;oBACF,OAAO;wBACL,MAAM;wBACN,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;qBAC/D,CAAC;gBACJ,CAAC,CAAC,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;gBACjF,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC;YAC3E,CAAC;SACF,CAAC;QACF,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;YACxC,WAAW,EAAE,mBAAmB;YAChC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;gBACd,MAAM;gBACN,OAAO,EAAE,CAAC,CAAC,kBAAkB,CAAC,OAAO,EAAE;oBACrC,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;oBAC9D,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;oBAC3C,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;iBACxE,CAAC;aACH,CAAC;YACF,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAoC,EAAE;gBAChE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACnC,MAAM,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBACtC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;oBACtD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CACxC,EAAE,EACF,IAAI,EACJ,IAAI,CAAC,IAAI,EACT,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,OAAO,CACd,CAAC;oBACF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAC/C,CAAC,CAAC,CAAC;gBACH,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;gBACzD,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACnC,CAAC;SACF,CAAC;KACH,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CACzB,IAAoB,EACpB,OAAO,GAAgB,WAAW,CAAC,IAAI,CAAC;IAExC,OAAO,cAAc,CAAC,EAAE,GAAG,eAAe,CAAC,IAAI,CAAC,EAAE,GAAG,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;AACzF,CAAC","sourcesContent":["import {\n type ActionContext,\n ActionError,\n type HostId,\n type ThreadId,\n type TurnId,\n} from \"@parlor/core\";\nimport { type ActionsOf, createRegistry } from \"@parlor/core/registry\";\nimport { type AuthProvider, type Delegation, HOST_GRANTS_TAG } from \"@parlor/server\";\nimport { z } from \"zod\";\n\nimport { idSchema } from \"../id-schemas.js\";\nimport { chatItemBodies, hostItemDraft, type LoggedItem } from \"../items.js\";\nimport type {\n AgentInfo,\n ChatOwner,\n ChatSnapshot,\n ThreadHistory,\n ThreadList,\n ClaimedTurn,\n HostSummary,\n TurnSignals,\n} from \"../model.js\";\nimport { HOST_PROTOCOL, type HostWelcome, PUSHED_TURNS_PROTOCOL } from \"../protocol.js\";\nimport { CHAT_ACTIVITY_TAG, CHAT_TAG, HOSTS_TAG } from \"../tags.js\";\nimport { turnContext } from \"./context.js\";\nimport type { LiveRelay } from \"./live.js\";\nimport { type ChatHost, chatAction } from \"./party.js\";\nimport type { TurnPush } from \"./push.js\";\nimport { agentInfoSchema, TURN_FAILURES } from \"./rows.js\";\n\nconst presenceDueSchema = z\n .record(z.string().min(1).max(64), z.number().int().nonnegative())\n .refine((due) => Object.keys(due).length <= 256, \"At most 256 devices.\");\nimport {\n type ChatDb,\n type ChatStore,\n type StoredHost,\n THREAD_LIST_LIMIT,\n} from \"./store.js\";\n\nexport { CHAT_ACTIVITY_TAG, CHAT_TAG, HOSTS_TAG, HOST_GRANTS_TAG };\n\nexport interface Written<T> {\n readonly result: T;\n readonly threadId: ThreadId | undefined;\n}\n\nexport interface ChatActionDeps {\n readonly enforcing: boolean;\n /**\n * Runs `work` in one transaction with the thread's sync event. Actions that call the auth\n * provider do so outside it, because a provider may read through another connection\n * (PGlite has one, and the transaction holds it).\n */\n /** Runs `work` in one transaction and wakes only `owner`'s tabs and computers. */\n readonly transact: <T>(\n owner: ChatOwner,\n work: (tx: ChatDb) => Promise<Written<T>>,\n ) => Promise<T>;\n /** Commits the lapsed leases and liveness of `owner`, with the sync events they owe. */\n readonly reconcile: (owner: ChatOwner) => Promise<void>;\n /** Drops the owner's computer rows whose grant is gone; best effort, never fails a read. */\n readonly pruneHosts: (owner: ChatOwner, hostIds: readonly HostId[]) => Promise<void>;\n readonly auth: AuthProvider;\n readonly store: ChatStore;\n readonly relay: LiveRelay;\n readonly leaseMs: number;\n readonly heartbeatMs: number;\n readonly maxQueued: number;\n readonly instructions: string | undefined;\n readonly appName: string;\n readonly appOrigin: () => string;\n /** Hands a queued turn straight to its computer; without it computers only claim. */\n readonly pushed?: TurnPush | undefined;\n}\n\nconst threadId = idSchema(\"thread\");\nconst turnId = idSchema(\"turn\");\nconst itemId = idSchema(\"item\");\nconst afterSeq = z.number().int().min(0);\n\nconst MIN_HOST_PROTOCOL = 2;\nconst CONTEXT_HISTORY_ITEMS = 200;\n/** An agent outside a turn asks again well inside the revocation horizon. */\nconst AGENT_TOKEN_TTL_MS = 10 * 60_000;\nconst TERMINAL: ReadonlySet<string> = new Set([\"done\", \"failed\", \"cancelled\"]);\n\nconst dbOf = (ctx: ActionContext) => ctx.db as ChatDb;\n\nasync function activeHosts(\n deps: ChatActionDeps,\n db: ChatDb,\n owner: ChatOwner,\n): Promise<StoredHost[]> {\n const hosts = await deps.store.listHosts(db, owner);\n const { hostActive } = deps.auth;\n if (!hostActive) return hosts;\n const holding = await Promise.all(\n hosts.map((host) => hostActive.call(deps.auth, host.grantId)),\n );\n const gone = hosts.filter((_host, at) => !holding[at]);\n if (gone.length > 0) {\n await deps.pruneHosts(\n owner,\n gone.map((host) => host.id),\n );\n }\n return hosts.filter((_host, at) => holding[at]);\n}\n\nconst summaryOf = ({\n grantId: _grantId,\n protocol: _protocol,\n ...summary\n}: StoredHost): HostSummary => summary;\n\nexport function userChatActions(deps: ChatActionDeps) {\n const { enforcing } = deps;\n return {\n open: chatAction(\"user\", enforcing, {\n description:\n \"The sidebar's first paint in one round trip: threads, computers, and a thread's last page with what streams now.\",\n input: z.object({\n threadId: threadId.optional(),\n limit: z.number().int().min(1).max(500).default(200),\n }),\n reads: (input) => [\n [CHAT_TAG, ...(input.threadId ? [input.threadId] : [])],\n [HOSTS_TAG],\n [HOST_GRANTS_TAG],\n ],\n run: async (input, user, ctx): Promise<ChatSnapshot> => {\n const db = dbOf(ctx);\n const [threads, hosts, page] = await Promise.all([\n deps.store.listThreads(db, user),\n activeHosts(deps, db, user),\n deps.store.readPage(db, user, input.threadId, input.limit),\n ]);\n const thread = page.thread;\n const open = thread ? deps.relay.open(user, thread.id) : [];\n const streaming = open.filter((turn) => {\n const state = page.turns.find((status) => status.turnId === turn.turnId)?.state;\n const ended = state !== undefined && TERMINAL.has(state);\n if (ended) deps.relay.settle(user, turn.threadId, turn.turnId);\n return !ended;\n });\n return {\n threads,\n ...(threads.length >= THREAD_LIST_LIMIT ? { moreThreads: true } : {}),\n hosts: hosts.map(summaryOf),\n page: { ...page, open: streaming },\n };\n },\n }),\n items: chatAction(\"user\", enforcing, {\n description: \"A thread's items after a sequence number.\",\n input: z.object({ threadId, afterSeq }),\n reads: (input) => [[CHAT_TAG, input.threadId]],\n run: (input, user, ctx): Promise<LoggedItem[]> =>\n deps.store.readItemsAfter(dbOf(ctx), user, input.threadId, input.afterSeq),\n }),\n history: chatAction(\"user\", enforcing, {\n description:\n \"A thread's items before a sequence number, oldest first, with their turns; hasMore while older ones remain.\",\n input: z.object({\n threadId,\n beforeSeq: z.number().int().min(1),\n limit: z.number().int().min(1).max(500).default(200),\n }),\n reads: (input) => [[CHAT_TAG, input.threadId]],\n run: async (input, user, ctx): Promise<ThreadHistory> => {\n const read = deps.store.readItemsBefore?.bind(deps.store);\n if (!read)\n throw new ActionError(\"not_found\", \"This chat store keeps no history.\");\n return read(dbOf(ctx), user, input.threadId, input.beforeSeq, input.limit);\n },\n }),\n threadsBefore: chatAction(\"user\", enforcing, {\n description:\n \"The user's threads updated before a thread, newest first, for the list past what open returned.\",\n input: z.object({\n before: z.object({ updatedAt: z.number().int().min(0), id: threadId }),\n limit: z.number().int().min(1).max(500).default(200),\n }),\n reads: [CHAT_TAG],\n run: async (input, user, ctx): Promise<ThreadList> => {\n const list = deps.store.listThreadsBefore?.bind(deps.store);\n if (!list)\n throw new ActionError(\"not_found\", \"This chat store keeps no history.\");\n return list(dbOf(ctx), user, input.before, input.limit);\n },\n }),\n hosts: chatAction(\"user\", enforcing, {\n description: \"The user's computers and the agents on them.\",\n input: z.object({}),\n reads: [HOSTS_TAG, HOST_GRANTS_TAG],\n run: async (_input, user, ctx): Promise<HostSummary[]> =>\n (await activeHosts(deps, dbOf(ctx), user)).map(summaryOf),\n }),\n send: chatAction(\"user\", enforcing, {\n description: \"Send a prompt to an agent on one of the user's computers.\",\n input: z.object({\n threadId,\n turnId,\n itemId,\n clientId: z.string().min(1).max(128),\n prompt: chatItemBodies.prompt.body,\n }),\n run: async (\n input,\n user,\n ctx,\n ): Promise<{ readonly id: string; readonly turnId: string }> => {\n const hosts = await activeHosts(deps, dbOf(ctx), user);\n const host = hosts.find(\n (candidate) => candidate.id === input.prompt.agent.hostId,\n );\n if (!host) throw new ActionError(\"not_found\", \"Computer not found\");\n const sent = await deps.transact(user, async (tx) => {\n await deps.store.appendUserItems(tx, user, {\n threadId: input.threadId,\n turnId: input.turnId,\n items: [{ id: input.itemId, kind: \"prompt\", body: input.prompt }],\n turn: {\n turnId: input.turnId,\n agent: input.prompt.agent,\n clientId: input.clientId,\n deviceId: user.deviceId,\n maxQueued: deps.maxQueued,\n },\n });\n return {\n result: { id: input.threadId, turnId: input.turnId },\n threadId: input.threadId,\n };\n });\n if (host.protocol >= PUSHED_TURNS_PROTOCOL) deps.pushed?.offer(user, host.id);\n return sent;\n },\n }),\n answer: chatAction(\"user\", enforcing, {\n description: \"Answer the agent's permission prompt or question.\",\n input: z.object({ threadId, turnId, itemId, answer: chatItemBodies.answer.body }),\n run: async (input, user): Promise<{ readonly id: string }> => {\n const { signed } = input.answer;\n if (signed && deps.auth.device) {\n const device = await deps.auth.device(user.userId, signed.deviceId);\n if (!device) {\n throw new ActionError(\"forbidden\", \"This device cannot answer.\");\n }\n }\n return deps.transact(user, async (tx) => {\n await deps.store.appendUserItems(tx, user, {\n threadId: input.threadId,\n turnId: input.turnId,\n items: [{ id: input.itemId, kind: \"answer\", body: input.answer }],\n });\n return { result: { id: input.threadId }, threadId: input.threadId };\n });\n },\n }),\n cancel: chatAction(\"user\", enforcing, {\n description: \"Stop the running turn; what the agent already said is kept.\",\n input: z.object({ threadId, turnId, itemId }),\n writes: [CHAT_TAG],\n run: async (input, user, ctx): Promise<{ readonly id: string }> => {\n await deps.store.appendUserItems(dbOf(ctx), user, {\n threadId: input.threadId,\n turnId: input.turnId,\n items: [{ id: input.itemId, kind: \"cancel\", body: {} }],\n });\n return { id: input.threadId };\n },\n }),\n userActive: chatAction(\"user\", enforcing, {\n description:\n \"Tell the user's computers a tab is in use, so a polling computer speeds up; carries no content and writes no table.\",\n input: z.object({}),\n writes: [CHAT_ACTIVITY_TAG],\n run: (): { readonly ok: true } => ({ ok: true }),\n }),\n };\n}\n\n/**\n * What the server keeps about the computers it serves: which said hello, their agents'\n * names, and how a turn is claimed for one, by `hostClaim` or pushed to it.\n */\nexport function hostSession(deps: ChatActionDeps) {\n const welcomed = new Set<HostId>();\n const welcome = async (host: ChatHost, db: ChatDb) => {\n const hosts = await deps.store.listHosts(db, host);\n const known = hosts.find((candidate) => candidate.id === host.host.hostId);\n if (!known) throw new ActionError(\"forbidden\", \"Say hello before anything else.\");\n if (known.protocol < MIN_HOST_PROTOCOL) {\n await deps.pruneHosts(host, [known.id]);\n throw new ActionError(\"forbidden\", \"Say hello before anything else.\");\n }\n welcomed.add(known.id);\n return known;\n };\n const requireWelcome = async (host: ChatHost, db: ChatDb) => {\n if (!welcomed.has(host.host.hostId)) await welcome(host, db);\n };\n const agentNames = new Map<HostId, ReadonlyMap<string, string>>();\n const learnAgents = (hostId: HostId, agents: readonly AgentInfo[]) => {\n agentNames.set(hostId, new Map(agents.map((agent) => [agent.id, agent.name])));\n };\n const agentNameOf = async (host: ChatHost, db: ChatDb, agentId: string) => {\n if (!agentNames.has(host.host.hostId)) {\n const known = (await deps.store.listHosts(db, host)).find(\n (candidate) => candidate.id === host.host.hostId,\n );\n if (known) learnAgents(known.id, known.agents);\n }\n return agentNames.get(host.host.hostId)?.get(agentId) ?? agentId;\n };\n const mint = async (\n host: ChatHost,\n db: ChatDb,\n turn: { threadId: ThreadId; turnId: TurnId; clientId: string; agentId: string },\n ) => {\n if (!deps.auth.delegate) {\n throw new ActionError(\"internal\", \"The auth provider cannot mint turn tokens.\");\n }\n return deps.auth.delegate(host.host, {\n threadId: turn.threadId,\n turnId: turn.turnId,\n clientId: turn.clientId,\n agent: await agentNameOf(host, db, turn.agentId),\n ttlMs: deps.leaseMs,\n });\n };\n /** The next turn waiting for `host`, claimed for it with its token and context; undefined when none waits. */\n const claim = async (host: ChatHost, db: ChatDb): Promise<ClaimedTurn | undefined> => {\n await requireWelcome(host, db);\n await deps.reconcile(host);\n const claimed = await deps.transact(host, async (tx) => {\n const taken = await deps.store.claimTurn(tx, host, host.host, deps.leaseMs);\n return { result: taken, threadId: taken?.id };\n });\n if (!claimed) return undefined;\n try {\n const deviceId = claimed.prompt.body.signed?.deviceId;\n const [token, device, account, page] = await Promise.all([\n mint(host, db, {\n threadId: claimed.id,\n turnId: claimed.turnId,\n clientId: claimed.clientId,\n agentId: claimed.agent.agentId,\n }),\n deviceId ? deps.auth.device?.(host.userId, deviceId) : undefined,\n deps.auth.account?.(host.userId),\n deps.store.readPage(db, host, claimed.id, CONTEXT_HISTORY_ITEMS),\n ]);\n const context = turnContext({\n appName: deps.appName,\n appOrigin: deps.appOrigin(),\n account,\n device,\n instructions: deps.instructions,\n history: page.items.filter((item) => item.seq < claimed.prompt.seq),\n });\n return { ...claimed, device, context, token };\n } catch (error) {\n await release(host, claimed.id, claimed.turnId).catch(() => false);\n throw error;\n }\n };\n /** Puts a claimed turn back in the queue, waking the computer to claim it again. */\n const release = (host: ChatHost, thread: ThreadId, turn: TurnId) =>\n deps.transact(host, async (tx) => {\n const released = await deps.store.releaseClaim(tx, host, host.host, turn);\n return { result: released, threadId: thread };\n });\n return {\n welcome,\n requireWelcome,\n learnAgents,\n agentNameOf,\n mint,\n claim,\n release,\n welcomed,\n };\n}\n\nexport type HostSession = ReturnType<typeof hostSession>;\n\n/** What the user's computers call; `hostHello` first on every link. */\nexport function hostChatActions(\n deps: ChatActionDeps,\n session: HostSession = hostSession(deps),\n) {\n const { enforcing } = deps;\n const { welcome, requireWelcome, learnAgents, mint, welcomed } = session;\n return {\n hostHello: chatAction(\"host\", enforcing, {\n description:\n \"A link's first call: agree on the host protocol and report this computer online with its agents.\",\n input: z.object({\n protocols: z.object({\n min: z.number().int().min(1),\n max: z.number().int().min(1),\n }),\n hostVersion: z.string().min(1).max(32),\n name: z.string().min(1).max(80),\n platform: z.string().min(1).max(32),\n agents: z.array(agentInfoSchema).max(32),\n devices: z.array(z.string().min(1).max(64)).max(256).optional(),\n presenceDue: presenceDueSchema.optional(),\n }),\n writes: [HOSTS_TAG],\n run: async (input, host, ctx): Promise<HostWelcome & { readonly id: string }> => {\n const id = host.host.hostId;\n const protocols = { min: MIN_HOST_PROTOCOL, max: HOST_PROTOCOL };\n const refuse = async (reason: \"host_too_old\" | \"app_too_old\") => {\n welcomed.delete(id);\n await deps.store.pruneHosts(dbOf(ctx), host, [id]);\n return { id, accepted: false as const, reason, protocols };\n };\n if (input.protocols.max < protocols.min) return refuse(\"host_too_old\");\n const protocol = Math.min(input.protocols.max, protocols.max);\n if (protocol < input.protocols.min) return refuse(\"app_too_old\");\n await deps.store.reportHost(dbOf(ctx), host, host.host, {\n protocol,\n name: input.name,\n platform: input.platform,\n agents: input.agents,\n devices: input.devices,\n presenceDue: input.presenceDue,\n online: true,\n ttlMs: 2 * deps.heartbeatMs,\n });\n learnAgents(id, input.agents);\n welcomed.add(id);\n return {\n id,\n accepted: true,\n protocol,\n leaseMs: deps.leaseMs,\n heartbeatMs: deps.heartbeatMs,\n userActivity: true,\n };\n },\n }),\n hostReport: chatAction(\"host\", enforcing, {\n description: \"This computer went offline or changed its agents.\",\n input: z.object({\n online: z.boolean(),\n agents: z.array(agentInfoSchema).max(32),\n devices: z.array(z.string().min(1).max(64)).max(256).optional(),\n presenceDue: presenceDueSchema.optional(),\n }),\n writes: [HOSTS_TAG],\n run: async (\n input,\n host,\n ctx,\n ): Promise<{ readonly id: string; readonly onlineUntil: number }> => {\n const db = dbOf(ctx);\n const known = await welcome(host, db);\n const { onlineUntil } = await deps.store.reportHost(db, host, host.host, {\n protocol: known.protocol,\n name: known.name,\n platform: known.platform,\n agents: input.agents,\n devices: input.devices,\n presenceDue: input.presenceDue,\n online: input.online,\n ttlMs: 2 * deps.heartbeatMs,\n });\n learnAgents(host.host.hostId, input.agents);\n return { id: host.host.hostId, onlineUntil };\n },\n }),\n hostAgentToken: chatAction(\"host\", enforcing, {\n description:\n \"A token for an agent on this computer outside any turn, such as Claude Code in a terminal, to call the app's actions as the user; revoked with the grant.\",\n input: z.object({ agent: z.string().min(1).max(120) }),\n run: async ({ agent }, host, ctx): Promise<Delegation> => {\n await requireWelcome(host, dbOf(ctx));\n if (!deps.auth.delegateAgent) {\n throw new ActionError(\n \"not_found\",\n \"This app's agents run only in its sidebar.\",\n );\n }\n return deps.auth.delegateAgent(host.host, { agent, ttlMs: AGENT_TOKEN_TTL_MS });\n },\n }),\n hostClaim: chatAction(\"host\", enforcing, {\n description:\n \"Take the next turn addressed to this computer with its turn token; not_found when none waits.\",\n input: z.object({}),\n run: async (_input, host, ctx): Promise<ClaimedTurn> => {\n const claimed = await session.claim(host, dbOf(ctx));\n if (!claimed) throw new ActionError(\"not_found\", \"No turn is waiting.\");\n return claimed;\n },\n }),\n hostSignals: chatAction(\"host\", enforcing, {\n description: \"Answers and stop requests for the turns this computer runs.\",\n input: z.object({ turns: z.array(z.object({ turnId, afterSeq })).max(16) }),\n run: async (input, host, ctx): Promise<TurnSignals[]> => {\n for (const turn of input.turns) deps.pushed?.confirm(turn.turnId);\n const db = dbOf(ctx);\n await requireWelcome(host, db);\n const signals = await deps.store.readSignals(db, host, host.host, input.turns);\n return Promise.all(\n signals.map(async (batch): Promise<TurnSignals> => {\n const answering = new Set(\n batch.items.flatMap((item) =>\n item.kind === \"answer\" && item.body.signed\n ? [item.body.signed.deviceId]\n : [],\n ),\n );\n const devices = (\n await Promise.all(\n [...answering].map((deviceId) =>\n deps.auth.device?.(host.userId, deviceId),\n ),\n )\n ).filter((device) => device !== undefined);\n return devices.length > 0 ? { ...batch, devices } : batch;\n }),\n );\n },\n }),\n hostAppend: chatAction(\"host\", enforcing, {\n description:\n \"Append finished items of a running turn and extend its lease; no items only renews it.\",\n input: z.object({ turnId, items: z.array(hostItemDraft).max(64) }),\n run: async (\n input,\n host,\n ctx,\n ): Promise<{\n readonly id: string;\n readonly leaseUntil: number;\n readonly token: ClaimedTurn[\"token\"];\n }> => {\n deps.pushed?.confirm(input.turnId);\n await requireWelcome(host, dbOf(ctx));\n const appended = await deps.transact(host, async (tx) => {\n const result = await deps.store.appendHostItems(\n tx,\n host,\n host.host,\n input.turnId,\n input.items,\n deps.leaseMs,\n );\n return {\n result,\n threadId: input.items.length > 0 ? result.threadId : undefined,\n };\n });\n const token = await mint(host, dbOf(ctx), { ...appended, turnId: input.turnId });\n return { id: appended.threadId, leaseUntil: appended.leaseUntil, token };\n },\n }),\n hostFinish: chatAction(\"host\", enforcing, {\n description: \"End a turn, once.\",\n input: z.object({\n turnId,\n outcome: z.discriminatedUnion(\"state\", [\n z.object({ state: z.literal(\"done\"), stopReason: z.string() }),\n z.object({ state: z.literal(\"cancelled\") }),\n z.object({ state: z.literal(\"failed\"), reason: z.enum(TURN_FAILURES) }),\n ]),\n }),\n run: async (input, host, ctx): Promise<{ readonly id: string }> => {\n deps.pushed?.confirm(input.turnId);\n await requireWelcome(host, dbOf(ctx));\n const finished = await deps.transact(host, async (tx) => {\n const result = await deps.store.finishTurn(\n tx,\n host,\n host.host,\n input.turnId,\n input.outcome,\n );\n return { result, threadId: result.threadId };\n });\n deps.relay.settle(host, finished.threadId, input.turnId);\n return { id: finished.threadId };\n },\n }),\n };\n}\n\n/**\n * The chat's actions at `/_parlor/chat/actions/<name>`: plugin actions, so never on MCP\n * and never callable by an agent. Writes return the thread or host id as `id`.\n */\nexport function chatActions(\n deps: ChatActionDeps,\n session: HostSession = hostSession(deps),\n) {\n return createRegistry({ ...userChatActions(deps), ...hostChatActions(deps, session) });\n}\n\nexport type ChatActionRegistry = ReturnType<typeof chatActions>;\nexport type ChatActionMap = ActionsOf<ChatActionRegistry>;\nexport type ChatUserActionMap = ReturnType<typeof userChatActions>;\nexport type ChatHostActionMap = ReturnType<typeof hostChatActions>;\n"]}
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/server/actions.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type ActionContext,\n ActionError,\n type HostId,\n type ThreadId,\n type TurnId,\n} from \"@parlor/core\";\nimport { type ActionsOf, createRegistry } from \"@parlor/core/registry\";\nimport { type AuthProvider, type Delegation, HOST_GRANTS_TAG } from \"@parlor/server\";\nimport { z } from \"zod\";\n\nimport { idSchema } from \"../id-schemas.js\";\nimport { chatItemBodies, hostItemDraft, type LoggedItem } from \"../items.js\";\nimport type {\n AgentInfo,\n ChatOwner,\n ChatSnapshot,\n ThreadHistory,\n ThreadList,\n ClaimedTurn,\n HostSummary,\n TurnSignals,\n} from \"../model.js\";\nimport { HOST_PROTOCOL, type HostWelcome, PUSHED_TURNS_PROTOCOL } from \"../protocol.js\";\nimport {\n CHAT_ACTIVITY_TAG,\n CHAT_AGENTS_CHECK_TAG,\n CHAT_TAG,\n HOSTS_TAG,\n} from \"../tags.js\";\nimport { turnContext } from \"./context.js\";\nimport type { LiveRelay } from \"./live.js\";\nimport { type ChatHost, chatAction } from \"./party.js\";\nimport type { TurnPush } from \"./push.js\";\nimport { agentInfoSchema, TURN_FAILURES } from \"./rows.js\";\n\nconst presenceDueSchema = z\n .record(z.string().min(1).max(64), z.number().int().nonnegative())\n .refine((due) => Object.keys(due).length <= 256, \"At most 256 devices.\");\nimport {\n type ChatDb,\n type ChatStore,\n type StoredHost,\n THREAD_LIST_LIMIT,\n} from \"./store.js\";\n\nexport { CHAT_ACTIVITY_TAG, CHAT_TAG, HOSTS_TAG, HOST_GRANTS_TAG };\n\nexport interface Written<T> {\n readonly result: T;\n readonly threadId: ThreadId | undefined;\n}\n\nexport interface ChatActionDeps {\n readonly enforcing: boolean;\n /**\n * Runs `work` in one transaction with the thread's sync event. Actions that call the auth\n * provider do so outside it, because a provider may read through another connection\n * (PGlite has one, and the transaction holds it).\n */\n /** Runs `work` in one transaction and wakes only `owner`'s tabs and computers. */\n readonly transact: <T>(\n owner: ChatOwner,\n work: (tx: ChatDb) => Promise<Written<T>>,\n ) => Promise<T>;\n /** Commits the lapsed leases and liveness of `owner`, with the sync events they owe. */\n readonly reconcile: (owner: ChatOwner) => Promise<void>;\n /** Drops the owner's computer rows whose grant is gone; best effort, never fails a read. */\n readonly pruneHosts: (owner: ChatOwner, hostIds: readonly HostId[]) => Promise<void>;\n readonly auth: AuthProvider;\n readonly store: ChatStore;\n readonly relay: LiveRelay;\n readonly leaseMs: number;\n readonly heartbeatMs: number;\n readonly maxQueued: number;\n readonly instructions: string | undefined;\n readonly appName: string;\n readonly appOrigin: () => string;\n /** Hands a queued turn straight to its computer; without it computers only claim. */\n readonly pushed?: TurnPush | undefined;\n}\n\nconst threadId = idSchema(\"thread\");\nconst turnId = idSchema(\"turn\");\nconst itemId = idSchema(\"item\");\nconst afterSeq = z.number().int().min(0);\n\nconst MIN_HOST_PROTOCOL = 2;\nconst CONTEXT_HISTORY_ITEMS = 200;\n/** An agent outside a turn asks again well inside the revocation horizon. */\nconst AGENT_TOKEN_TTL_MS = 10 * 60_000;\nconst TERMINAL: ReadonlySet<string> = new Set([\"done\", \"failed\", \"cancelled\"]);\n\nconst dbOf = (ctx: ActionContext) => ctx.db as ChatDb;\n\nasync function activeHosts(\n deps: ChatActionDeps,\n db: ChatDb,\n owner: ChatOwner,\n): Promise<StoredHost[]> {\n const hosts = await deps.store.listHosts(db, owner);\n const { hostActive } = deps.auth;\n if (!hostActive) return hosts;\n const holding = await Promise.all(\n hosts.map((host) => hostActive.call(deps.auth, host.grantId)),\n );\n const gone = hosts.filter((_host, at) => !holding[at]);\n if (gone.length > 0) {\n await deps.pruneHosts(\n owner,\n gone.map((host) => host.id),\n );\n }\n return hosts.filter((_host, at) => holding[at]);\n}\n\nconst summaryOf = ({\n grantId: _grantId,\n protocol: _protocol,\n ...summary\n}: StoredHost): HostSummary => summary;\n\nexport function userChatActions(deps: ChatActionDeps) {\n const { enforcing } = deps;\n return {\n open: chatAction(\"user\", enforcing, {\n description:\n \"The sidebar's first paint in one round trip: threads, computers, and a thread's last page with what streams now.\",\n input: z.object({\n threadId: threadId.optional(),\n limit: z.number().int().min(1).max(500).default(200),\n }),\n reads: (input) => [\n [CHAT_TAG, ...(input.threadId ? [input.threadId] : [])],\n [HOSTS_TAG],\n [HOST_GRANTS_TAG],\n ],\n run: async (input, user, ctx): Promise<ChatSnapshot> => {\n const db = dbOf(ctx);\n const [threads, hosts, page] = await Promise.all([\n deps.store.listThreads(db, user),\n activeHosts(deps, db, user),\n deps.store.readPage(db, user, input.threadId, input.limit),\n ]);\n const thread = page.thread;\n const open = thread ? deps.relay.open(user, thread.id) : [];\n const streaming = open.filter((turn) => {\n const state = page.turns.find((status) => status.turnId === turn.turnId)?.state;\n const ended = state !== undefined && TERMINAL.has(state);\n if (ended) deps.relay.settle(user, turn.threadId, turn.turnId);\n return !ended;\n });\n return {\n threads,\n ...(threads.length >= THREAD_LIST_LIMIT ? { moreThreads: true } : {}),\n hosts: hosts.map(summaryOf),\n page: { ...page, open: streaming },\n };\n },\n }),\n items: chatAction(\"user\", enforcing, {\n description: \"A thread's items after a sequence number.\",\n input: z.object({ threadId, afterSeq }),\n reads: (input) => [[CHAT_TAG, input.threadId]],\n run: (input, user, ctx): Promise<LoggedItem[]> =>\n deps.store.readItemsAfter(dbOf(ctx), user, input.threadId, input.afterSeq),\n }),\n history: chatAction(\"user\", enforcing, {\n description:\n \"A thread's items before a sequence number, oldest first, with their turns; hasMore while older ones remain.\",\n input: z.object({\n threadId,\n beforeSeq: z.number().int().min(1),\n limit: z.number().int().min(1).max(500).default(200),\n }),\n reads: (input) => [[CHAT_TAG, input.threadId]],\n run: async (input, user, ctx): Promise<ThreadHistory> => {\n const read = deps.store.readItemsBefore?.bind(deps.store);\n if (!read)\n throw new ActionError(\"not_found\", \"This chat store keeps no history.\");\n return read(dbOf(ctx), user, input.threadId, input.beforeSeq, input.limit);\n },\n }),\n threadsBefore: chatAction(\"user\", enforcing, {\n description:\n \"The user's threads updated before a thread, newest first, for the list past what open returned.\",\n input: z.object({\n before: z.object({ updatedAt: z.number().int().min(0), id: threadId }),\n limit: z.number().int().min(1).max(500).default(200),\n }),\n reads: [CHAT_TAG],\n run: async (input, user, ctx): Promise<ThreadList> => {\n const list = deps.store.listThreadsBefore?.bind(deps.store);\n if (!list)\n throw new ActionError(\"not_found\", \"This chat store keeps no history.\");\n return list(dbOf(ctx), user, input.before, input.limit);\n },\n }),\n hosts: chatAction(\"user\", enforcing, {\n description: \"The user's computers and the agents on them.\",\n input: z.object({}),\n reads: [HOSTS_TAG, HOST_GRANTS_TAG],\n run: async (_input, user, ctx): Promise<HostSummary[]> =>\n (await activeHosts(deps, dbOf(ctx), user)).map(summaryOf),\n }),\n send: chatAction(\"user\", enforcing, {\n description: \"Send a prompt to an agent on one of the user's computers.\",\n input: z.object({\n threadId,\n turnId,\n itemId,\n clientId: z.string().min(1).max(128),\n prompt: chatItemBodies.prompt.body,\n }),\n run: async (\n input,\n user,\n ctx,\n ): Promise<{ readonly id: string; readonly turnId: string }> => {\n const hosts = await activeHosts(deps, dbOf(ctx), user);\n const host = hosts.find(\n (candidate) => candidate.id === input.prompt.agent.hostId,\n );\n if (!host) throw new ActionError(\"not_found\", \"Computer not found\");\n const sent = await deps.transact(user, async (tx) => {\n await deps.store.appendUserItems(tx, user, {\n threadId: input.threadId,\n turnId: input.turnId,\n items: [{ id: input.itemId, kind: \"prompt\", body: input.prompt }],\n turn: {\n turnId: input.turnId,\n agent: input.prompt.agent,\n clientId: input.clientId,\n deviceId: user.deviceId,\n maxQueued: deps.maxQueued,\n },\n });\n return {\n result: { id: input.threadId, turnId: input.turnId },\n threadId: input.threadId,\n };\n });\n if (host.protocol >= PUSHED_TURNS_PROTOCOL) deps.pushed?.offer(user, host.id);\n return sent;\n },\n }),\n answer: chatAction(\"user\", enforcing, {\n description: \"Answer the agent's permission prompt or question.\",\n input: z.object({ threadId, turnId, itemId, answer: chatItemBodies.answer.body }),\n run: async (input, user): Promise<{ readonly id: string }> => {\n const { signed } = input.answer;\n if (signed && deps.auth.device) {\n const device = await deps.auth.device(user.userId, signed.deviceId);\n if (!device) {\n throw new ActionError(\"forbidden\", \"This device cannot answer.\");\n }\n }\n return deps.transact(user, async (tx) => {\n await deps.store.appendUserItems(tx, user, {\n threadId: input.threadId,\n turnId: input.turnId,\n items: [{ id: input.itemId, kind: \"answer\", body: input.answer }],\n });\n return { result: { id: input.threadId }, threadId: input.threadId };\n });\n },\n }),\n cancel: chatAction(\"user\", enforcing, {\n description: \"Stop the running turn; what the agent already said is kept.\",\n input: z.object({ threadId, turnId, itemId }),\n writes: [CHAT_TAG],\n run: async (input, user, ctx): Promise<{ readonly id: string }> => {\n await deps.store.appendUserItems(dbOf(ctx), user, {\n threadId: input.threadId,\n turnId: input.turnId,\n items: [{ id: input.itemId, kind: \"cancel\", body: {} }],\n });\n return { id: input.threadId };\n },\n }),\n userActive: chatAction(\"user\", enforcing, {\n description:\n \"Tell the user's computers a tab is in use, so a polling computer speeds up; carries no content and writes no table.\",\n input: z.object({}),\n writes: [CHAT_ACTIVITY_TAG],\n run: (): { readonly ok: true } => ({ ok: true }),\n }),\n checkAgents: chatAction(\"user\", enforcing, {\n description:\n \"Ask the user's computers to look again for the coding agents installed on them; each reports what it found, stamped `agentsCheckedAt`. Answers when it asked, by the same clock.\",\n input: z.object({}),\n writes: [CHAT_AGENTS_CHECK_TAG],\n run: (): { readonly askedAt: number } => ({ askedAt: Date.now() }),\n }),\n };\n}\n\n/**\n * What the server keeps about the computers it serves: which said hello, their agents'\n * names, and how a turn is claimed for one, by `hostClaim` or pushed to it.\n */\nexport function hostSession(deps: ChatActionDeps) {\n const welcomed = new Set<HostId>();\n const welcome = async (host: ChatHost, db: ChatDb) => {\n const hosts = await deps.store.listHosts(db, host);\n const known = hosts.find((candidate) => candidate.id === host.host.hostId);\n if (!known) throw new ActionError(\"forbidden\", \"Say hello before anything else.\");\n if (known.protocol < MIN_HOST_PROTOCOL) {\n await deps.pruneHosts(host, [known.id]);\n throw new ActionError(\"forbidden\", \"Say hello before anything else.\");\n }\n welcomed.add(known.id);\n return known;\n };\n const requireWelcome = async (host: ChatHost, db: ChatDb) => {\n if (!welcomed.has(host.host.hostId)) await welcome(host, db);\n };\n const agentNames = new Map<HostId, ReadonlyMap<string, string>>();\n const learnAgents = (hostId: HostId, agents: readonly AgentInfo[]) => {\n agentNames.set(hostId, new Map(agents.map((agent) => [agent.id, agent.name])));\n };\n const agentNameOf = async (host: ChatHost, db: ChatDb, agentId: string) => {\n if (!agentNames.has(host.host.hostId)) {\n const known = (await deps.store.listHosts(db, host)).find(\n (candidate) => candidate.id === host.host.hostId,\n );\n if (known) learnAgents(known.id, known.agents);\n }\n return agentNames.get(host.host.hostId)?.get(agentId) ?? agentId;\n };\n const mint = async (\n host: ChatHost,\n db: ChatDb,\n turn: { threadId: ThreadId; turnId: TurnId; clientId: string; agentId: string },\n ) => {\n if (!deps.auth.delegate) {\n throw new ActionError(\"internal\", \"The auth provider cannot mint turn tokens.\");\n }\n return deps.auth.delegate(host.host, {\n threadId: turn.threadId,\n turnId: turn.turnId,\n clientId: turn.clientId,\n agent: await agentNameOf(host, db, turn.agentId),\n ttlMs: deps.leaseMs,\n });\n };\n /** The next turn waiting for `host`, claimed for it with its token and context; undefined when none waits. */\n const claim = async (host: ChatHost, db: ChatDb): Promise<ClaimedTurn | undefined> => {\n await requireWelcome(host, db);\n await deps.reconcile(host);\n const claimed = await deps.transact(host, async (tx) => {\n const taken = await deps.store.claimTurn(tx, host, host.host, deps.leaseMs);\n return { result: taken, threadId: taken?.id };\n });\n if (!claimed) return undefined;\n try {\n const deviceId = claimed.prompt.body.signed?.deviceId;\n const [token, device, account, page] = await Promise.all([\n mint(host, db, {\n threadId: claimed.id,\n turnId: claimed.turnId,\n clientId: claimed.clientId,\n agentId: claimed.agent.agentId,\n }),\n deviceId ? deps.auth.device?.(host.userId, deviceId) : undefined,\n deps.auth.account?.(host.userId),\n deps.store.readPage(db, host, claimed.id, CONTEXT_HISTORY_ITEMS),\n ]);\n const context = turnContext({\n appName: deps.appName,\n appOrigin: deps.appOrigin(),\n account,\n device,\n instructions: deps.instructions,\n history: page.items.filter((item) => item.seq < claimed.prompt.seq),\n });\n return { ...claimed, device, context, token };\n } catch (error) {\n await release(host, claimed.id, claimed.turnId).catch(() => false);\n throw error;\n }\n };\n /** Puts a claimed turn back in the queue, waking the computer to claim it again. */\n const release = (host: ChatHost, thread: ThreadId, turn: TurnId) =>\n deps.transact(host, async (tx) => {\n const released = await deps.store.releaseClaim(tx, host, host.host, turn);\n return { result: released, threadId: thread };\n });\n return {\n welcome,\n requireWelcome,\n learnAgents,\n agentNameOf,\n mint,\n claim,\n release,\n welcomed,\n };\n}\n\nexport type HostSession = ReturnType<typeof hostSession>;\n\n/** What the user's computers call; `hostHello` first on every link. */\nexport function hostChatActions(\n deps: ChatActionDeps,\n session: HostSession = hostSession(deps),\n) {\n const { enforcing } = deps;\n const { welcome, requireWelcome, learnAgents, mint, welcomed } = session;\n return {\n hostHello: chatAction(\"host\", enforcing, {\n description:\n \"A link's first call: agree on the host protocol and report this computer online with its agents.\",\n input: z.object({\n protocols: z.object({\n min: z.number().int().min(1),\n max: z.number().int().min(1),\n }),\n hostVersion: z.string().min(1).max(32),\n name: z.string().min(1).max(80),\n platform: z.string().min(1).max(32),\n agents: z.array(agentInfoSchema).max(32),\n devices: z.array(z.string().min(1).max(64)).max(256).optional(),\n presenceDue: presenceDueSchema.optional(),\n }),\n writes: [HOSTS_TAG],\n run: async (input, host, ctx): Promise<HostWelcome & { readonly id: string }> => {\n const id = host.host.hostId;\n const protocols = { min: MIN_HOST_PROTOCOL, max: HOST_PROTOCOL };\n const refuse = async (reason: \"host_too_old\" | \"app_too_old\") => {\n welcomed.delete(id);\n await deps.store.pruneHosts(dbOf(ctx), host, [id]);\n return { id, accepted: false as const, reason, protocols };\n };\n if (input.protocols.max < protocols.min) return refuse(\"host_too_old\");\n const protocol = Math.min(input.protocols.max, protocols.max);\n if (protocol < input.protocols.min) return refuse(\"app_too_old\");\n await deps.store.reportHost(dbOf(ctx), host, host.host, {\n protocol,\n name: input.name,\n platform: input.platform,\n agents: input.agents,\n devices: input.devices,\n presenceDue: input.presenceDue,\n online: true,\n ttlMs: 2 * deps.heartbeatMs,\n });\n learnAgents(id, input.agents);\n welcomed.add(id);\n return {\n id,\n accepted: true,\n protocol,\n leaseMs: deps.leaseMs,\n heartbeatMs: deps.heartbeatMs,\n userActivity: true,\n };\n },\n }),\n hostReport: chatAction(\"host\", enforcing, {\n description:\n \"This computer went offline, changed its agents, or looked for them again (`agentsChecked`).\",\n input: z.object({\n online: z.boolean(),\n agents: z.array(agentInfoSchema).max(32),\n devices: z.array(z.string().min(1).max(64)).max(256).optional(),\n presenceDue: presenceDueSchema.optional(),\n agentsChecked: z.literal(true).optional(),\n }),\n writes: [HOSTS_TAG],\n run: async (\n input,\n host,\n ctx,\n ): Promise<{ readonly id: string; readonly onlineUntil: number }> => {\n const db = dbOf(ctx);\n const known = await welcome(host, db);\n const { onlineUntil } = await deps.store.reportHost(db, host, host.host, {\n protocol: known.protocol,\n name: known.name,\n platform: known.platform,\n agents: input.agents,\n devices: input.devices,\n presenceDue: input.presenceDue,\n agentsCheckedAt: input.agentsChecked ? Date.now() : undefined,\n online: input.online,\n ttlMs: 2 * deps.heartbeatMs,\n });\n learnAgents(host.host.hostId, input.agents);\n return { id: host.host.hostId, onlineUntil };\n },\n }),\n hostAgentToken: chatAction(\"host\", enforcing, {\n description:\n \"A token for an agent on this computer outside any turn, such as Claude Code in a terminal, to call the app's actions as the user; revoked with the grant.\",\n input: z.object({ agent: z.string().min(1).max(120) }),\n run: async ({ agent }, host, ctx): Promise<Delegation> => {\n await requireWelcome(host, dbOf(ctx));\n if (!deps.auth.delegateAgent) {\n throw new ActionError(\n \"not_found\",\n \"This app's agents run only in its sidebar.\",\n );\n }\n return deps.auth.delegateAgent(host.host, { agent, ttlMs: AGENT_TOKEN_TTL_MS });\n },\n }),\n hostClaim: chatAction(\"host\", enforcing, {\n description:\n \"Take the next turn addressed to this computer with its turn token; not_found when none waits.\",\n input: z.object({}),\n run: async (_input, host, ctx): Promise<ClaimedTurn> => {\n const claimed = await session.claim(host, dbOf(ctx));\n if (!claimed) throw new ActionError(\"not_found\", \"No turn is waiting.\");\n return claimed;\n },\n }),\n hostSignals: chatAction(\"host\", enforcing, {\n description: \"Answers and stop requests for the turns this computer runs.\",\n input: z.object({ turns: z.array(z.object({ turnId, afterSeq })).max(16) }),\n run: async (input, host, ctx): Promise<TurnSignals[]> => {\n for (const turn of input.turns) deps.pushed?.confirm(turn.turnId);\n const db = dbOf(ctx);\n await requireWelcome(host, db);\n const signals = await deps.store.readSignals(db, host, host.host, input.turns);\n return Promise.all(\n signals.map(async (batch): Promise<TurnSignals> => {\n const answering = new Set(\n batch.items.flatMap((item) =>\n item.kind === \"answer\" && item.body.signed\n ? [item.body.signed.deviceId]\n : [],\n ),\n );\n const devices = (\n await Promise.all(\n [...answering].map((deviceId) =>\n deps.auth.device?.(host.userId, deviceId),\n ),\n )\n ).filter((device) => device !== undefined);\n return devices.length > 0 ? { ...batch, devices } : batch;\n }),\n );\n },\n }),\n hostAppend: chatAction(\"host\", enforcing, {\n description:\n \"Append finished items of a running turn and extend its lease; no items only renews it.\",\n input: z.object({ turnId, items: z.array(hostItemDraft).max(64) }),\n run: async (\n input,\n host,\n ctx,\n ): Promise<{\n readonly id: string;\n readonly leaseUntil: number;\n readonly token: ClaimedTurn[\"token\"];\n }> => {\n deps.pushed?.confirm(input.turnId);\n await requireWelcome(host, dbOf(ctx));\n const appended = await deps.transact(host, async (tx) => {\n const result = await deps.store.appendHostItems(\n tx,\n host,\n host.host,\n input.turnId,\n input.items,\n deps.leaseMs,\n );\n return {\n result,\n threadId: input.items.length > 0 ? result.threadId : undefined,\n };\n });\n const token = await mint(host, dbOf(ctx), { ...appended, turnId: input.turnId });\n return { id: appended.threadId, leaseUntil: appended.leaseUntil, token };\n },\n }),\n hostFinish: chatAction(\"host\", enforcing, {\n description: \"End a turn, once.\",\n input: z.object({\n turnId,\n outcome: z.discriminatedUnion(\"state\", [\n z.object({ state: z.literal(\"done\"), stopReason: z.string() }),\n z.object({ state: z.literal(\"cancelled\") }),\n z.object({ state: z.literal(\"failed\"), reason: z.enum(TURN_FAILURES) }),\n ]),\n }),\n run: async (input, host, ctx): Promise<{ readonly id: string }> => {\n deps.pushed?.confirm(input.turnId);\n await requireWelcome(host, dbOf(ctx));\n const finished = await deps.transact(host, async (tx) => {\n const result = await deps.store.finishTurn(\n tx,\n host,\n host.host,\n input.turnId,\n input.outcome,\n );\n return { result, threadId: result.threadId };\n });\n deps.relay.settle(host, finished.threadId, input.turnId);\n return { id: finished.threadId };\n },\n }),\n };\n}\n\n/**\n * The chat's actions at `/_parlor/chat/actions/<name>`: plugin actions, so never on MCP\n * and never callable by an agent. Writes return the thread or host id as `id`.\n */\nexport function chatActions(\n deps: ChatActionDeps,\n session: HostSession = hostSession(deps),\n) {\n return createRegistry({ ...userChatActions(deps), ...hostChatActions(deps, session) });\n}\n\nexport type ChatActionRegistry = ReturnType<typeof chatActions>;\nexport type ChatActionMap = ActionsOf<ChatActionRegistry>;\nexport type ChatUserActionMap = ReturnType<typeof userChatActions>;\nexport type ChatHostActionMap = ReturnType<typeof hostChatActions>;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/server/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,eAAO,MAAM,eAAe,EAAE,SAAS,SAAS,
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/server/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,eAAO,MAAM,eAAe,EAAE,SAAS,SAAS,EAkG/C,CAAC"}
|
|
@@ -92,5 +92,9 @@ export const CHAT_MIGRATIONS = [
|
|
|
92
92
|
id: "chat/0004_host_presence",
|
|
93
93
|
sql: `alter table parlor_chat_hosts add column presence_due jsonb;`,
|
|
94
94
|
},
|
|
95
|
+
{
|
|
96
|
+
id: "chat/0005_host_agents_checked",
|
|
97
|
+
sql: `alter table parlor_chat_hosts add column agents_checked_at timestamptz;`,
|
|
98
|
+
},
|
|
95
99
|
];
|
|
96
100
|
//# sourceMappingURL=migrations.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/server/migrations.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAyB;IACnD;QACE,EAAE,EAAE,mBAAmB;QACvB,GAAG,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oEAuE2D;KACjE;IACD;QACE,EAAE,EAAE,wBAAwB;QAC5B,GAAG,EAAE;;;;;;qEAM4D;KAClE;IACD;QACE,EAAE,EAAE,wBAAwB;QAC5B,GAAG,EAAE,yDAAyD;KAC/D;IACD;QACE,EAAE,EAAE,yBAAyB;QAC7B,GAAG,EAAE,8DAA8D;KACpE;CACF,CAAC","sourcesContent":["import type { Migration } from \"@parlor/server\";\n\nexport const CHAT_MIGRATIONS: readonly Migration[] = [\n {\n id: \"chat/0001_threads\",\n sql: `\n create table parlor_chat_threads (\n id text primary key,\n scope text not null,\n owner_id text not null,\n title text not null default '',\n host_id text,\n agent_id text,\n last_seq bigint not null default 0,\n created_at timestamptz not null default now(),\n updated_at timestamptz not null default now()\n );\n create index parlor_chat_threads_owner\n on parlor_chat_threads (owner_id, scope, updated_at desc);\n\n create table parlor_chat_items (\n id text primary key,\n thread_id text not null references parlor_chat_threads (id) on delete cascade,\n turn_id text not null,\n seq bigint not null,\n author text not null check (author in ('user', 'agent', 'system')),\n kind text not null,\n body jsonb not null,\n created_at timestamptz not null default now(),\n unique (thread_id, seq)\n );\n create unique index parlor_chat_items_one_answer\n on parlor_chat_items (thread_id, (body->>'askId')) where kind = 'answer';\n\n create table parlor_chat_turns (\n id text primary key,\n thread_id text not null references parlor_chat_threads (id) on delete cascade,\n scope text not null,\n owner_id text not null,\n host_id text not null,\n agent_id text not null,\n client_id text not null,\n device_id text,\n prompt_item_id text not null,\n state text not null\n check (state in ('queued', 'running', 'done', 'failed', 'cancelled')),\n lease_until timestamptz,\n outcome jsonb,\n created_at timestamptz not null default now(),\n finished_at timestamptz\n );\n create index parlor_chat_turns_queue\n on parlor_chat_turns (host_id, state, created_at) where state = 'queued';\n create unique index parlor_chat_turns_one_running\n on parlor_chat_turns (thread_id) where state = 'running';\n create index parlor_chat_turns_thread_state on parlor_chat_turns (thread_id, state);\n create index parlor_chat_turns_lease\n on parlor_chat_turns (lease_until) where state = 'running';\n\n create index parlor_chat_items_signals\n on parlor_chat_items (turn_id, seq) where kind in ('answer', 'cancel');\n\n create table parlor_chat_hosts (\n id text primary key,\n scope text not null,\n owner_id text not null,\n grant_id text not null,\n protocol integer not null,\n name text not null,\n platform text not null,\n agents jsonb not null,\n online_until timestamptz not null,\n announced_online boolean not null\n );\n create index parlor_chat_hosts_owner on parlor_chat_hosts (owner_id, scope);\n create index parlor_chat_hosts_lapse\n on parlor_chat_hosts (online_until) where announced_online;`,\n },\n {\n id: \"chat/0002_answer_retry\",\n sql: `\n drop index parlor_chat_items_one_answer;\n create index parlor_chat_items_answers\n on parlor_chat_items (thread_id, (body->>'askId')) where kind = 'answer';\n create index parlor_chat_items_rejections\n on parlor_chat_items (thread_id, (body->>'itemId'))\n where kind = 'event' and body->>'event' = 'answer_rejected';`,\n },\n {\n id: \"chat/0003_host_devices\",\n sql: `alter table parlor_chat_hosts add column devices jsonb;`,\n },\n {\n id: \"chat/0004_host_presence\",\n sql: `alter table parlor_chat_hosts add column presence_due jsonb;`,\n },\n];\n"]}
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/server/migrations.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAyB;IACnD;QACE,EAAE,EAAE,mBAAmB;QACvB,GAAG,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oEAuE2D;KACjE;IACD;QACE,EAAE,EAAE,wBAAwB;QAC5B,GAAG,EAAE;;;;;;qEAM4D;KAClE;IACD;QACE,EAAE,EAAE,wBAAwB;QAC5B,GAAG,EAAE,yDAAyD;KAC/D;IACD;QACE,EAAE,EAAE,yBAAyB;QAC7B,GAAG,EAAE,8DAA8D;KACpE;IACD;QACE,EAAE,EAAE,+BAA+B;QACnC,GAAG,EAAE,yEAAyE;KAC/E;CACF,CAAC","sourcesContent":["import type { Migration } from \"@parlor/server\";\n\nexport const CHAT_MIGRATIONS: readonly Migration[] = [\n {\n id: \"chat/0001_threads\",\n sql: `\n create table parlor_chat_threads (\n id text primary key,\n scope text not null,\n owner_id text not null,\n title text not null default '',\n host_id text,\n agent_id text,\n last_seq bigint not null default 0,\n created_at timestamptz not null default now(),\n updated_at timestamptz not null default now()\n );\n create index parlor_chat_threads_owner\n on parlor_chat_threads (owner_id, scope, updated_at desc);\n\n create table parlor_chat_items (\n id text primary key,\n thread_id text not null references parlor_chat_threads (id) on delete cascade,\n turn_id text not null,\n seq bigint not null,\n author text not null check (author in ('user', 'agent', 'system')),\n kind text not null,\n body jsonb not null,\n created_at timestamptz not null default now(),\n unique (thread_id, seq)\n );\n create unique index parlor_chat_items_one_answer\n on parlor_chat_items (thread_id, (body->>'askId')) where kind = 'answer';\n\n create table parlor_chat_turns (\n id text primary key,\n thread_id text not null references parlor_chat_threads (id) on delete cascade,\n scope text not null,\n owner_id text not null,\n host_id text not null,\n agent_id text not null,\n client_id text not null,\n device_id text,\n prompt_item_id text not null,\n state text not null\n check (state in ('queued', 'running', 'done', 'failed', 'cancelled')),\n lease_until timestamptz,\n outcome jsonb,\n created_at timestamptz not null default now(),\n finished_at timestamptz\n );\n create index parlor_chat_turns_queue\n on parlor_chat_turns (host_id, state, created_at) where state = 'queued';\n create unique index parlor_chat_turns_one_running\n on parlor_chat_turns (thread_id) where state = 'running';\n create index parlor_chat_turns_thread_state on parlor_chat_turns (thread_id, state);\n create index parlor_chat_turns_lease\n on parlor_chat_turns (lease_until) where state = 'running';\n\n create index parlor_chat_items_signals\n on parlor_chat_items (turn_id, seq) where kind in ('answer', 'cancel');\n\n create table parlor_chat_hosts (\n id text primary key,\n scope text not null,\n owner_id text not null,\n grant_id text not null,\n protocol integer not null,\n name text not null,\n platform text not null,\n agents jsonb not null,\n online_until timestamptz not null,\n announced_online boolean not null\n );\n create index parlor_chat_hosts_owner on parlor_chat_hosts (owner_id, scope);\n create index parlor_chat_hosts_lapse\n on parlor_chat_hosts (online_until) where announced_online;`,\n },\n {\n id: \"chat/0002_answer_retry\",\n sql: `\n drop index parlor_chat_items_one_answer;\n create index parlor_chat_items_answers\n on parlor_chat_items (thread_id, (body->>'askId')) where kind = 'answer';\n create index parlor_chat_items_rejections\n on parlor_chat_items (thread_id, (body->>'itemId'))\n where kind = 'event' and body->>'event' = 'answer_rejected';`,\n },\n {\n id: \"chat/0003_host_devices\",\n sql: `alter table parlor_chat_hosts add column devices jsonb;`,\n },\n {\n id: \"chat/0004_host_presence\",\n sql: `alter table parlor_chat_hosts add column presence_due jsonb;`,\n },\n {\n id: \"chat/0005_host_agents_checked\",\n sql: `alter table parlor_chat_hosts add column agents_checked_at timestamptz;`,\n },\n];\n"]}
|
package/dist/server/store.d.ts
CHANGED
|
@@ -104,6 +104,8 @@ export interface ChatStore {
|
|
|
104
104
|
readonly devices?: readonly string[] | undefined;
|
|
105
105
|
/** Left as it was when the host does not report it. */
|
|
106
106
|
readonly presenceDue?: Readonly<Record<string, number>> | undefined;
|
|
107
|
+
/** When the host looked for its agents; left as it was when this report is not that. */
|
|
108
|
+
readonly agentsCheckedAt?: number | undefined;
|
|
107
109
|
readonly online: boolean;
|
|
108
110
|
readonly ttlMs: number;
|
|
109
111
|
}): Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/server/store.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/server/store.ts"],"names":[],"mappings":"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"}
|
package/dist/server/store.js
CHANGED
|
@@ -459,18 +459,20 @@ export const sqlChatStore = {
|
|
|
459
459
|
const ttlMs = report.online ? report.ttlMs : 0;
|
|
460
460
|
const [row] = await query(tx, sql `insert into parlor_chat_hosts
|
|
461
461
|
(id, scope, owner_id, grant_id, protocol, name, platform, agents, devices,
|
|
462
|
-
presence_due, online_until, announced_online)
|
|
462
|
+
presence_due, agents_checked_at, online_until, announced_online)
|
|
463
463
|
values (${host.hostId}, ${owner.scope}, ${owner.userId}, ${host.grantId},
|
|
464
464
|
${report.protocol}, ${report.name}, ${report.platform},
|
|
465
465
|
${JSON.stringify(report.agents)}::jsonb,
|
|
466
466
|
${report.devices ? JSON.stringify(report.devices) : null}::jsonb,
|
|
467
467
|
${report.presenceDue ? JSON.stringify(report.presenceDue) : null}::jsonb,
|
|
468
|
+
${report.agentsCheckedAt === undefined ? null : new Date(report.agentsCheckedAt).toISOString()}::timestamptz,
|
|
468
469
|
${leaseSql(ttlMs)}, ${report.online})
|
|
469
470
|
on conflict (id) do update set
|
|
470
471
|
grant_id = excluded.grant_id, protocol = excluded.protocol, name = excluded.name,
|
|
471
472
|
platform = excluded.platform, agents = excluded.agents,
|
|
472
473
|
devices = coalesce(excluded.devices, parlor_chat_hosts.devices),
|
|
473
474
|
presence_due = coalesce(excluded.presence_due, parlor_chat_hosts.presence_due),
|
|
475
|
+
agents_checked_at = coalesce(excluded.agents_checked_at, parlor_chat_hosts.agents_checked_at),
|
|
474
476
|
online_until = excluded.online_until,
|
|
475
477
|
announced_online = excluded.announced_online
|
|
476
478
|
where parlor_chat_hosts.owner_id = excluded.owner_id
|
|
@@ -491,7 +493,7 @@ export const sqlChatStore = {
|
|
|
491
493
|
},
|
|
492
494
|
async listHosts(db, owner) {
|
|
493
495
|
return query(db, sql `select id, grant_id, protocol, name, platform, agents, devices, presence_due,
|
|
494
|
-
online_until > now() as online
|
|
496
|
+
${ms("agents_checked_at")} as agents_checked_at, online_until > now() as online
|
|
495
497
|
from parlor_chat_hosts
|
|
496
498
|
where owner_id = ${owner.userId} and scope = ${owner.scope}
|
|
497
499
|
order by name, id`, z
|
|
@@ -504,12 +506,14 @@ export const sqlChatStore = {
|
|
|
504
506
|
agents: z.array(agentInfoSchema),
|
|
505
507
|
devices: z.array(z.string()).nullable(),
|
|
506
508
|
presence_due: z.record(z.string(), z.number()).nullable(),
|
|
509
|
+
agents_checked_at: count.nullable(),
|
|
507
510
|
online: z.boolean(),
|
|
508
511
|
})
|
|
509
|
-
.transform(({ grant_id, devices, presence_due, ...host }) => ({
|
|
512
|
+
.transform(({ grant_id, devices, presence_due, agents_checked_at, ...host }) => ({
|
|
510
513
|
...host,
|
|
511
514
|
...(devices ? { devices } : {}),
|
|
512
515
|
...(presence_due ? { presenceDue: presence_due } : {}),
|
|
516
|
+
...(agents_checked_at === null ? {} : { agentsCheckedAt: agents_checked_at }),
|
|
513
517
|
grantId: grant_id,
|
|
514
518
|
})));
|
|
515
519
|
},
|
package/dist/server/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/server/store.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\n\nimport {\n ActionError,\n asId,\n type DeviceId,\n type GrantId,\n type HostId,\n type HostPrincipal,\n type ItemId,\n type ThreadId,\n type TurnId,\n type UserId,\n} from \"@parlor/core\";\nimport { type SQL, sql } from \"drizzle-orm\";\nimport type { PgDatabase, PgQueryResultHKT } from \"drizzle-orm/pg-core\";\nimport { z } from \"zod\";\n\nimport { idSchema } from \"../id-schemas.js\";\nimport { chatItemBodies, type ChatItemBody, type ChatItemKind } from \"../items.js\";\nimport type { HostItemDraft, LoggedItem, UserItemKind } from \"../items.js\";\nimport type {\n AgentInfo,\n AgentRef,\n ChatOwner,\n ClaimedTurn,\n HostSummary,\n ThreadPage,\n ThreadSummary,\n TurnOutcome,\n TurnSignals,\n TurnStatus,\n} from \"../model.js\";\nimport {\n agentInfoSchema,\n itemRow,\n threadRow,\n toLoggedItem,\n toThreadSummary,\n TURN_FAILURES,\n turnStateSchema,\n} from \"./rows.js\";\n\nexport type ChatDb = PgDatabase<PgQueryResultHKT>;\n\nexport type UserDraft = {\n [K in UserItemKind]: {\n readonly id: LoggedItem<K>[\"id\"];\n readonly kind: K;\n readonly body: LoggedItem<K>[\"body\"];\n };\n}[UserItemKind];\n\nexport interface NewTurn {\n readonly turnId: TurnId;\n readonly agent: AgentRef;\n readonly clientId: string;\n readonly deviceId: DeviceId | undefined;\n /** The most turns a thread may have waiting; checked under the thread's lock. */\n readonly maxQueued: number;\n}\n\nexport interface TurnHolder {\n readonly owner: ChatOwner;\n readonly threadId: ThreadId;\n readonly hostId: HostId;\n}\n\n/** A turn's holder with whether it runs now: running, and its lease not yet lapsed. */\nexport interface StreamTurn extends TurnHolder {\n readonly live: boolean;\n}\n\n/** What one reconciliation changed in a scope, for the sync events it must emit. */\nexport interface OlderItems {\n readonly items: readonly LoggedItem[];\n readonly turns: readonly TurnStatus[];\n readonly hasMore: boolean;\n}\n\nexport interface ThreadCursor {\n readonly updatedAt: number;\n readonly id: ThreadId;\n}\n\nexport interface OlderThreads {\n readonly threads: readonly ThreadSummary[];\n readonly hasMore: boolean;\n}\n\nexport interface Lapsed extends ChatOwner {\n readonly threads: readonly ThreadId[];\n readonly hosts: readonly HostId[];\n}\n\n/**\n * The thread log in SQL. Every function filters by the owner's scope and user in the same\n * statement, so another user's thread id reads as not found. Appends lock the thread row\n * to assign gap-free `seq` and run in the action's transaction so the thread's sync event\n * commits with them.\n */\nexport interface ChatStore {\n listThreads(db: ChatDb, owner: ChatOwner): Promise<ThreadSummary[]>;\n readPage(\n db: ChatDb,\n owner: ChatOwner,\n threadId: ThreadId | undefined,\n limit: number,\n ): Promise<Omit<ThreadPage, \"open\">>;\n /** Items before `beforeSeq`, oldest first, with their turns; `hasMore` while older ones remain. */\n readItemsBefore?(\n db: ChatDb,\n owner: ChatOwner,\n threadId: ThreadId,\n beforeSeq: number,\n limit: number,\n ): Promise<OlderItems>;\n /** Threads updated before `before`, newest first, after the ones `listThreads` returned. */\n listThreadsBefore?(\n db: ChatDb,\n owner: ChatOwner,\n before: ThreadCursor,\n limit: number,\n ): Promise<OlderThreads>;\n readItemsAfter(\n db: ChatDb,\n owner: ChatOwner,\n threadId: ThreadId,\n afterSeq: number,\n ): Promise<LoggedItem[]>;\n /** With `turn`, also queues it; the thread is created on its first prompt. */\n appendUserItems(\n tx: ChatDb,\n owner: ChatOwner,\n input: {\n readonly threadId: ThreadId;\n readonly turnId: TurnId;\n readonly items: readonly UserDraft[];\n readonly turn?: NewTurn | undefined;\n },\n ): Promise<LoggedItem[]>;\n claimTurn(\n tx: ChatDb,\n owner: ChatOwner,\n host: HostPrincipal,\n leaseMs: number,\n ): Promise<Omit<ClaimedTurn, \"context\" | \"token\" | \"device\"> | undefined>;\n /** Whether anything waits for `expireLapsed`; one read, so the idle path writes nothing. */\n hasLapsed(db: ChatDb, owner: ChatOwner | undefined): Promise<boolean>;\n /**\n * Fails the running turns whose lease lapsed (`host_lost`) and marks the computers whose\n * liveness lapsed offline, for `owner` or, without one, for everyone. Commit it apart\n * from any claim, because a claim that finds nothing aborts its own transaction.\n */\n expireLapsed(tx: ChatDb, owner: ChatOwner | undefined): Promise<Lapsed[]>;\n /**\n * Puts a claimed turn back in the queue when the host never learned of the claim.\n * Refused (false) once the turn has an agent item or is no longer running.\n */\n releaseClaim(\n tx: ChatDb,\n owner: ChatOwner,\n host: HostPrincipal,\n turnId: TurnId,\n ): Promise<boolean>;\n appendHostItems(\n tx: ChatDb,\n owner: ChatOwner,\n host: HostPrincipal,\n turnId: TurnId,\n items: readonly HostItemDraft[],\n leaseMs: number,\n ): Promise<{\n readonly threadId: ThreadId;\n readonly leaseUntil: number;\n /** What the renewed turn token binds, so the caller need not read the turn again. */\n readonly clientId: string;\n readonly agentId: string;\n }>;\n /** Once per turn; a second call with any outcome is refused and changes nothing. */\n finishTurn(\n tx: ChatDb,\n owner: ChatOwner,\n host: HostPrincipal,\n turnId: TurnId,\n outcome: TurnOutcome,\n ): Promise<{ readonly threadId: ThreadId }>;\n readSignals(\n db: ChatDb,\n owner: ChatOwner,\n host: HostPrincipal,\n turns: readonly { readonly turnId: TurnId; readonly afterSeq: number }[],\n ): Promise<TurnSignals[]>;\n reportHost(\n tx: ChatDb,\n owner: ChatOwner,\n host: HostPrincipal,\n report: {\n readonly protocol: number;\n readonly name: string;\n readonly platform: string;\n readonly agents: readonly AgentInfo[];\n /** Left as it was when the host does not report it. */\n readonly devices?: readonly string[] | undefined;\n /** Left as it was when the host does not report it. */\n readonly presenceDue?: Readonly<Record<string, number>> | undefined;\n readonly online: boolean;\n readonly ttlMs: number;\n },\n ): Promise<{ readonly onlineUntil: number }>;\n /**\n * One UPDATE of `online_until`. `returned` is true when the sidebar had been told the\n * computer was offline, so the caller announces its return.\n */\n heartbeat(\n db: ChatDb,\n owner: ChatOwner,\n host: HostPrincipal,\n ttlMs: number,\n ): Promise<{ readonly returned: boolean }>;\n listHosts(db: ChatDb, owner: ChatOwner): Promise<StoredHost[]>;\n /** Drops the owner's computer rows whose grant is gone. */\n pruneHosts(tx: ChatDb, owner: ChatOwner, hostIds: readonly HostId[]): Promise<void>;\n turnHolder(db: ChatDb, turnId: TurnId): Promise<StreamTurn | undefined>;\n}\n\nexport interface StoredHost extends HostSummary {\n readonly grantId: GrantId;\n readonly protocol: number;\n}\n\nfunction rowsOf(result: unknown): unknown[] {\n if (Array.isArray(result)) return result;\n const rows = (result as { rows?: unknown[] } | null)?.rows;\n return rows ?? [];\n}\n\nasync function query<S extends z.ZodType>(\n db: ChatDb,\n statement: SQL,\n schema: S,\n): Promise<z.output<S>[]> {\n const result = await db.execute(statement);\n return rowsOf(result).map((row) => schema.parse(row));\n}\n\nconst count = z.coerce.number();\nconst ms = (column: string) => sql.raw(`(extract(epoch from ${column}) * 1000)::bigint`);\nconst ITEM_COLUMNS = sql`id, thread_id, turn_id, seq, kind, body, ${ms(\"created_at\")} as at`;\nconst ITEM_COLUMNS_OF_I = sql`i.id, i.thread_id, i.turn_id, i.seq, i.kind, i.body, ${ms(\"i.created_at\")} as at`;\nconst THREAD_COLUMNS = sql`id, title, host_id, agent_id, last_seq, ${ms(\"updated_at\")} as updated_at`;\n\nexport const THREAD_LIST_LIMIT = 200;\nconst TITLE_CHARS = 80;\nconst TERMINAL_STATES: ReadonlySet<string> = new Set([\"done\", \"failed\", \"cancelled\"]);\n\nconst threadMissing = () => new ActionError(\"not_found\", \"Thread not found\");\nconst turnMissing = () => new ActionError(\"not_found\", \"Turn not found\");\n\nconst inList = (values: readonly string[]) =>\n sql.join(\n values.map((value) => sql`${value}`),\n sql`, `,\n );\n\nconst authorOf = (kind: ChatItemKind) => chatItemBodies[kind].author;\n\nfunction titleOf(text: string): string {\n const firstLine = text.trim().split(\"\\n\")[0] ?? \"\";\n return [...firstLine].slice(0, TITLE_CHARS).join(\"\");\n}\n\ninterface ItemInsert {\n readonly id: ItemId;\n readonly turnId: TurnId;\n readonly kind: ChatItemKind;\n readonly body: unknown;\n}\n\ninterface LogLock {\n readonly lastSeq: number;\n readonly turnState: string | undefined;\n /** Running and its lease has not lapsed: the only turn a host may write to. */\n readonly leased: boolean;\n}\n\n/** The only place the log is locked: the thread row, then the turn row. */\nasync function lockLog(\n tx: ChatDb,\n owner: ChatOwner,\n threadId: ThreadId,\n turnId?: TurnId,\n): Promise<LogLock> {\n const [row] = await query(\n tx,\n sql`select last_seq from parlor_chat_threads\n where id = ${threadId} and scope = ${owner.scope} and owner_id = ${owner.userId}\n for update`,\n z.object({ last_seq: count }),\n );\n if (!row) throw threadMissing();\n if (turnId === undefined) {\n return { lastSeq: row.last_seq, turnState: undefined, leased: false };\n }\n const [turn] = await query(\n tx,\n sql`select state, coalesce(state = 'running' and lease_until >= now(), false) as leased\n from parlor_chat_turns where id = ${turnId} and thread_id = ${threadId} for update`,\n z.object({ state: z.string(), leased: z.boolean() }),\n );\n return {\n lastSeq: row.last_seq,\n turnState: turn?.state,\n leased: turn?.leased ?? false,\n };\n}\n\nasync function insertItems(\n tx: ChatDb,\n threadId: ThreadId,\n lastSeq: number,\n rows: readonly ItemInsert[],\n): Promise<number> {\n if (rows.length === 0) return lastSeq;\n const values = rows.map(\n (row, index) =>\n sql`(${row.id}, ${threadId}, ${row.turnId}, ${lastSeq + index + 1}, ${authorOf(row.kind)}, ${row.kind}, ${JSON.stringify(row.body)}::jsonb)`,\n );\n await tx.execute(\n sql`insert into parlor_chat_items (id, thread_id, turn_id, seq, author, kind, body)\n values ${sql.join(values, sql`, `)}`,\n );\n const next = lastSeq + rows.length;\n await tx.execute(\n sql`update parlor_chat_threads set last_seq = ${next}, updated_at = now() where id = ${threadId}`,\n );\n return next;\n}\n\nasync function itemThreads(\n tx: ChatDb,\n ids: readonly ItemId[],\n): Promise<Map<string, string>> {\n if (ids.length === 0) return new Map();\n const rows = await query(\n tx,\n sql`select id, thread_id from parlor_chat_items where id in (${inList(ids)})`,\n z.object({ id: z.string(), thread_id: z.string() }),\n );\n return new Map(rows.map((row) => [row.id, row.thread_id]));\n}\n\nasync function itemsById(\n db: ChatDb,\n threadId: ThreadId,\n ids: readonly ItemId[],\n): Promise<LoggedItem[]> {\n if (ids.length === 0) return [];\n const rows = await query(\n db,\n sql`select ${ITEM_COLUMNS} from parlor_chat_items\n where thread_id = ${threadId} and id in (${inList(ids)}) order by seq`,\n itemRow,\n );\n return rows.map(toLoggedItem);\n}\n\nconst turnRow = z.object({\n id: idSchema(\"turn\"),\n thread_id: idSchema(\"thread\"),\n host_id: idSchema(\"host\"),\n agent_id: z.string(),\n state: turnStateSchema,\n lapsed: z.boolean(),\n failure: z.enum(TURN_FAILURES).nullable(),\n});\n\nasync function createTurn(\n tx: ChatDb,\n owner: ChatOwner,\n threadId: ThreadId,\n turn: NewTurn,\n promptItemId: ItemId,\n): Promise<void> {\n const [existing] = await query(\n tx,\n sql`select thread_id, owner_id, scope from parlor_chat_turns where id = ${turn.turnId}`,\n z.object({ thread_id: z.string(), owner_id: z.string(), scope: z.string() }),\n );\n if (existing) {\n const sameThread =\n existing.thread_id === threadId &&\n existing.owner_id === owner.userId &&\n existing.scope === owner.scope;\n if (!sameThread) throw turnMissing();\n return;\n }\n const [queued] = await query(\n tx,\n sql`select count(*) as waiting from parlor_chat_turns\n where thread_id = ${threadId} and state = 'queued'`,\n z.object({ waiting: count }),\n );\n if ((queued?.waiting ?? 0) >= turn.maxQueued) {\n throw new ActionError(\n \"invalid_input\",\n \"Too many prompts are waiting for the agent; wait for it to catch up.\",\n );\n }\n await tx.execute(\n sql`insert into parlor_chat_turns\n (id, thread_id, scope, owner_id, host_id, agent_id, client_id, device_id, prompt_item_id, state)\n values (${turn.turnId}, ${threadId}, ${owner.scope}, ${owner.userId}, ${turn.agent.hostId},\n ${turn.agent.agentId}, ${turn.clientId}, ${turn.deviceId ?? null}, ${promptItemId}, 'queued')`,\n );\n}\n\nasync function admitsUserItem(\n tx: ChatDb,\n threadId: ThreadId,\n turnId: TurnId,\n draft: UserDraft,\n): Promise<boolean> {\n if (draft.kind === \"prompt\") return true;\n if (draft.kind === \"answer\") {\n const askId = draft.body.askId;\n const [ask] = await query(\n tx,\n sql`select turn_id, body->>'approval' as approval from parlor_chat_items\n where thread_id = ${threadId} and id = ${askId} and kind = 'ask'`,\n z.object({ turn_id: z.string(), approval: z.string().nullable() }),\n );\n if (!ask || ask.turn_id !== turnId)\n throw new ActionError(\"not_found\", \"Question not found\");\n if (ask.approval === \"computer\") {\n throw new ActionError(\"forbidden\", \"This question is answered on the computer.\");\n }\n const { signed } = draft.body;\n if (ask.approval === \"presence\" && signed?.signature.presence !== \"user\") {\n throw new ActionError(\"forbidden\", \"This question needs a presence check.\");\n }\n if (ask.approval === \"device\" && !signed) {\n throw new ActionError(\n \"forbidden\",\n \"This question is answered on the device that asked it.\",\n );\n }\n const [state] = await query(\n tx,\n sql`select state from parlor_chat_turns where id = ${turnId} for update`,\n z.object({ state: z.string() }),\n );\n const [standing] = await query(\n tx,\n sql`select a.id from parlor_chat_items a\n where a.thread_id = ${threadId} and a.kind = 'answer' and a.body->>'askId' = ${askId}\n and not exists (\n select 1 from parlor_chat_items e\n where e.thread_id = ${threadId} and e.kind = 'event'\n and e.body->>'event' = 'answer_rejected' and e.body->>'itemId' = a.id)\n limit 1`,\n z.object({ id: z.string() }),\n );\n if (standing) {\n throw new ActionError(\"invalid_input\", \"This question was already answered.\");\n }\n if (state?.state !== \"running\") {\n throw new ActionError(\n \"invalid_input\",\n \"The agent is no longer waiting for this answer.\",\n );\n }\n return true;\n }\n const [turn] = await query(\n tx,\n sql`select state from parlor_chat_turns where id = ${turnId} and thread_id = ${threadId}`,\n z.object({ state: z.string() }),\n );\n if (!turn) throw turnMissing();\n if (TERMINAL_STATES.has(turn.state)) return false;\n if (turn.state === \"queued\") {\n await tx.execute(\n sql`update parlor_chat_turns\n set state = 'cancelled', outcome = '{\"state\":\"cancelled\"}'::jsonb, finished_at = now()\n where id = ${turnId} and state = 'queued'`,\n );\n }\n return true;\n}\n\nconst lostItemId = () => asId(\"item\", `lost.${randomUUID()}`);\n\nconst ownedBy = (owner: ChatOwner | undefined) =>\n owner ? sql`and owner_id = ${owner.userId} and scope = ${owner.scope}` : sql``;\n\nasync function lapsedFor(db: ChatDb, owner: ChatOwner | undefined): Promise<boolean> {\n const [found] = await query(\n db,\n sql`select (\n exists (select 1 from parlor_chat_turns\n where state = 'running' and lease_until < now() ${ownedBy(owner)})\n or exists (select 1 from parlor_chat_hosts\n where announced_online and online_until <= now() ${ownedBy(owner)})\n ) as lapsed`,\n z.object({ lapsed: z.boolean() }),\n );\n return found?.lapsed ?? false;\n}\n\nasync function expireLapsed(tx: ChatDb, owner: ChatOwner | undefined): Promise<Lapsed[]> {\n const changes = new Map<string, Lapsed & { threads: ThreadId[]; hosts: HostId[] }>();\n const changed = (scope: string, userId: UserId) => {\n const key = `${scope}\\u0000${userId}`;\n let change = changes.get(key);\n if (!change) changes.set(key, (change = { scope, userId, threads: [], hosts: [] }));\n return change;\n };\n const lapsed = await query(\n tx,\n sql`select distinct scope, owner_id, thread_id from parlor_chat_turns\n where state = 'running' and lease_until < now() ${ownedBy(owner)}\n order by thread_id`,\n z.object({\n scope: z.string(),\n owner_id: idSchema(\"user\"),\n thread_id: idSchema(\"thread\"),\n }),\n );\n for (const { scope, owner_id: userId, thread_id: threadId } of lapsed) {\n const { lastSeq } = await lockLog(tx, { scope, userId }, threadId);\n const expired = await query(\n tx,\n sql`update parlor_chat_turns\n set state = 'failed', outcome = '{\"state\":\"failed\",\"reason\":\"host_lost\"}'::jsonb,\n finished_at = now()\n where thread_id = ${threadId} and state = 'running' and lease_until < now()\n returning id`,\n z.object({ id: idSchema(\"turn\") }),\n );\n if (expired.length === 0) continue;\n await insertItems(\n tx,\n threadId,\n lastSeq,\n expired.map(({ id }) => ({\n id: lostItemId(),\n turnId: id,\n kind: \"event\",\n body: { event: \"host_lost\" } satisfies ChatItemBody<\"event\">,\n })),\n );\n changed(scope, userId).threads.push(threadId);\n }\n const offline = await query(\n tx,\n sql`update parlor_chat_hosts set announced_online = false\n where announced_online and online_until <= now() ${ownedBy(owner)}\n returning id, scope, owner_id`,\n z.object({ id: idSchema(\"host\"), scope: z.string(), owner_id: idSchema(\"user\") }),\n );\n for (const { id, scope, owner_id: userId } of offline) {\n changed(scope, userId).hosts.push(id);\n }\n return [...changes.values()];\n}\n\nasync function lockRunningTurn(\n tx: ChatDb,\n owner: ChatOwner,\n host: HostPrincipal,\n turnId: TurnId,\n): Promise<{\n readonly threadId: ThreadId;\n readonly lastSeq: number;\n readonly clientId: string;\n readonly agentId: string;\n}> {\n const [found] = await query(\n tx,\n sql`select thread_id, client_id, agent_id from parlor_chat_turns\n where id = ${turnId} and host_id = ${host.hostId}\n and owner_id = ${owner.userId} and scope = ${owner.scope}`,\n z.object({\n thread_id: idSchema(\"thread\"),\n client_id: z.string(),\n agent_id: z.string(),\n }),\n );\n if (!found) throw turnMissing();\n const { lastSeq, leased } = await lockLog(tx, owner, found.thread_id, turnId);\n if (!leased) throw new ActionError(\"forbidden\", \"The turn is not running.\");\n return {\n threadId: found.thread_id,\n lastSeq,\n clientId: found.client_id,\n agentId: found.agent_id,\n };\n}\n\nconst leaseSql = (leaseMs: number) =>\n sql`now() + ${leaseMs}::float8 * interval '1 millisecond'`;\n\nasync function requireThread(db: ChatDb, owner: ChatOwner, threadId: ThreadId) {\n const [thread] = await query(\n db,\n sql`select id from parlor_chat_threads\n where id = ${threadId} and owner_id = ${owner.userId} and scope = ${owner.scope}`,\n z.object({ id: z.string() }),\n );\n if (!thread) throw threadMissing();\n}\n\n/** The turns that `items`, a run of consecutive seqs, belong to. */\nasync function turnsOf(\n db: ChatDb,\n threadId: ThreadId,\n items: readonly LoggedItem[],\n): Promise<TurnStatus[]> {\n const first = items[0];\n const last = items.at(-1);\n if (!first || !last) return [];\n const turns = await query(\n db,\n sql`select id, thread_id, host_id, agent_id, state,\n coalesce(state = 'running' and lease_until < now(), false) as lapsed,\n case when state = 'failed' then outcome->>'reason' end as failure\n from parlor_chat_turns\n where thread_id = ${threadId}\n and id in (select turn_id from parlor_chat_items\n where thread_id = ${threadId} and seq between ${first.seq} and ${last.seq})\n order by created_at, id`,\n turnRow,\n );\n return turns.map((turn) => ({\n turnId: turn.id,\n state: turn.lapsed ? \"failed\" : turn.state,\n agent: { hostId: turn.host_id, agentId: turn.agent_id },\n failure: turn.lapsed ? \"host_lost\" : (turn.failure ?? undefined),\n }));\n}\n\nexport const sqlChatStore: ChatStore = {\n async listThreads(db, owner) {\n const rows = await query(\n db,\n sql`select ${THREAD_COLUMNS} from parlor_chat_threads\n where owner_id = ${owner.userId} and scope = ${owner.scope}\n order by updated_at desc, id limit ${THREAD_LIST_LIMIT}`,\n threadRow,\n );\n return rows.map(toThreadSummary);\n },\n\n async readPage(db, owner, threadId, limit) {\n const [row] = await query(\n db,\n threadId\n ? sql`select ${THREAD_COLUMNS} from parlor_chat_threads\n where id = ${threadId} and owner_id = ${owner.userId} and scope = ${owner.scope}`\n : sql`select ${THREAD_COLUMNS} from parlor_chat_threads\n where owner_id = ${owner.userId} and scope = ${owner.scope}\n order by updated_at desc, id limit 1`,\n threadRow,\n );\n if (!row) return { thread: undefined, items: [], turns: [], hasMore: false };\n const rows = await query(\n db,\n sql`select ${ITEM_COLUMNS} from parlor_chat_items\n where thread_id = ${row.id} order by seq desc limit ${limit + 1}`,\n itemRow,\n );\n const hasMore = rows.length > limit;\n const items = rows.slice(0, limit).reverse().map(toLoggedItem);\n return {\n thread: toThreadSummary(row),\n items,\n turns: await turnsOf(db, row.id, items),\n hasMore,\n };\n },\n\n async readItemsBefore(db, owner, threadId, beforeSeq, limit) {\n const rows = await query(\n db,\n sql`select ${ITEM_COLUMNS_OF_I} from parlor_chat_items i\n join parlor_chat_threads t on t.id = i.thread_id\n where t.id = ${threadId} and t.owner_id = ${owner.userId} and t.scope = ${owner.scope}\n and i.seq < ${beforeSeq}\n order by i.seq desc limit ${limit + 1}`,\n itemRow,\n );\n if (rows.length === 0) await requireThread(db, owner, threadId);\n const items = rows.slice(0, limit).reverse().map(toLoggedItem);\n return {\n items,\n turns: await turnsOf(db, threadId, items),\n hasMore: rows.length > limit,\n };\n },\n\n async listThreadsBefore(db, owner, before, limit) {\n const updated = ms(\"updated_at\");\n const rows = await query(\n db,\n sql`select ${THREAD_COLUMNS} from parlor_chat_threads\n where owner_id = ${owner.userId} and scope = ${owner.scope}\n and (${updated} < ${before.updatedAt}\n or (${updated} = ${before.updatedAt} and id < ${before.id}))\n order by updated_at desc, id desc limit ${limit + 1}`,\n threadRow,\n );\n return {\n threads: rows.slice(0, limit).map(toThreadSummary),\n hasMore: rows.length > limit,\n };\n },\n\n async readItemsAfter(db, owner, threadId, afterSeq) {\n const rows = await query(\n db,\n sql`select ${ITEM_COLUMNS_OF_I} from parlor_chat_items i\n join parlor_chat_threads t on t.id = i.thread_id\n where t.id = ${threadId} and t.owner_id = ${owner.userId} and t.scope = ${owner.scope}\n and i.seq > ${afterSeq}\n order by i.seq`,\n itemRow,\n );\n if (rows.length === 0) await requireThread(db, owner, threadId);\n return rows.map(toLoggedItem);\n },\n\n async appendUserItems(tx, owner, input) {\n const { threadId, turnId, items, turn } = input;\n if (turn) {\n const prompt = items.find((draft) => draft.kind === \"prompt\");\n await tx.execute(\n sql`insert into parlor_chat_threads (id, scope, owner_id, title, host_id, agent_id)\n values (${threadId}, ${owner.scope}, ${owner.userId},\n ${prompt?.kind === \"prompt\" ? titleOf(prompt.body.text) : \"\"},\n ${turn.agent.hostId}, ${turn.agent.agentId})\n on conflict (id) do nothing`,\n );\n }\n const { lastSeq } = await lockLog(tx, owner, threadId);\n if (turn) {\n const prompt = items.find((draft) => draft.kind === \"prompt\");\n if (!prompt) throw new ActionError(\"invalid_input\", \"A turn starts with a prompt.\");\n await createTurn(tx, owner, threadId, turn, prompt.id);\n }\n const known = await itemThreads(\n tx,\n items.map((draft) => draft.id),\n );\n const fresh: UserDraft[] = [];\n for (const draft of items) {\n const where = known.get(draft.id);\n if (where === undefined) {\n if (await admitsUserItem(tx, threadId, turnId, draft)) fresh.push(draft);\n } else if (where !== threadId) {\n throw threadMissing();\n }\n }\n await insertItems(\n tx,\n threadId,\n lastSeq,\n fresh.map((draft) => ({\n id: draft.id,\n turnId,\n kind: draft.kind,\n body: draft.body,\n })),\n );\n if (turn) {\n await tx.execute(\n sql`update parlor_chat_threads set host_id = ${turn.agent.hostId}, agent_id = ${turn.agent.agentId}\n where id = ${threadId}`,\n );\n }\n return itemsById(\n tx,\n threadId,\n items.map((draft) => draft.id),\n );\n },\n\n async hasLapsed(db, owner) {\n return lapsedFor(db, owner);\n },\n\n expireLapsed,\n\n async claimTurn(tx, owner, host, leaseMs) {\n const [claimed] = await query(\n tx,\n sql`select t.id, t.thread_id, t.agent_id, t.client_id, t.prompt_item_id\n from parlor_chat_turns t\n where t.host_id = ${host.hostId} and t.owner_id = ${owner.userId}\n and t.scope = ${owner.scope} and t.state = 'queued'\n and not exists (\n select 1 from parlor_chat_turns earlier\n where earlier.thread_id = t.thread_id and earlier.state in ('queued', 'running')\n and (earlier.created_at, earlier.id) < (t.created_at, t.id))\n order by t.created_at, t.id\n limit 1\n for update of t skip locked`,\n z.object({\n id: idSchema(\"turn\"),\n thread_id: idSchema(\"thread\"),\n agent_id: z.string(),\n client_id: z.string(),\n prompt_item_id: idSchema(\"item\"),\n }),\n );\n if (!claimed) return undefined;\n const [lease] = await query(\n tx,\n sql`update parlor_chat_turns set state = 'running', lease_until = ${leaseSql(leaseMs)}\n where id = ${claimed.id}\n returning ${ms(\"lease_until\")} as lease_until`,\n z.object({ lease_until: count }),\n );\n const [prompt] = await itemsById(tx, claimed.thread_id, [claimed.prompt_item_id]);\n if (!lease || prompt?.kind !== \"prompt\") {\n throw new ActionError(\"internal\", \"The claimed turn lost its prompt.\");\n }\n return {\n id: claimed.thread_id,\n turnId: claimed.id,\n agent: { hostId: host.hostId, agentId: claimed.agent_id },\n clientId: claimed.client_id,\n prompt,\n leaseUntil: lease.lease_until,\n };\n },\n\n async releaseClaim(tx, owner, host, turnId) {\n const released = await query(\n tx,\n sql`update parlor_chat_turns set state = 'queued', lease_until = null\n where id = ${turnId} and host_id = ${host.hostId} and owner_id = ${owner.userId}\n and scope = ${owner.scope} and state = 'running' and lease_until >= now()\n and not exists (\n select 1 from parlor_chat_items i\n where i.turn_id = parlor_chat_turns.id and i.author <> 'user')\n returning thread_id`,\n z.object({ thread_id: idSchema(\"thread\") }),\n );\n return released.length > 0;\n },\n\n async appendHostItems(tx, owner, host, turnId, items, leaseMs) {\n const { threadId, lastSeq, clientId, agentId } = await lockRunningTurn(\n tx,\n owner,\n host,\n turnId,\n );\n const known = await itemThreads(\n tx,\n items.map((draft) => draft.id),\n );\n const fresh: HostItemDraft[] = [];\n for (const draft of items) {\n const where = known.get(draft.id);\n if (where === undefined) fresh.push(draft);\n else if (where !== threadId)\n throw new ActionError(\"forbidden\", \"That item id is taken.\");\n }\n await insertItems(\n tx,\n threadId,\n lastSeq,\n fresh.map((draft) => ({\n id: draft.id,\n turnId,\n kind: draft.kind,\n body: draft.body,\n })),\n );\n const [lease] = await query(\n tx,\n sql`update parlor_chat_turns set lease_until = ${leaseSql(leaseMs)}\n where id = ${turnId} returning ${ms(\"lease_until\")} as lease_until`,\n z.object({ lease_until: count }),\n );\n return { threadId, leaseUntil: lease?.lease_until ?? 0, clientId, agentId };\n },\n\n async finishTurn(tx, owner, host, turnId, outcome) {\n const { threadId } = await lockRunningTurn(tx, owner, host, turnId);\n await tx.execute(\n sql`update parlor_chat_turns\n set state = ${outcome.state}, outcome = ${JSON.stringify(outcome)}::jsonb, finished_at = now()\n where id = ${turnId}`,\n );\n await tx.execute(\n sql`update parlor_chat_threads set updated_at = now() where id = ${threadId}`,\n );\n return { threadId };\n },\n\n async readSignals(db, owner, host, turns) {\n if (turns.length === 0) return [];\n const wanted = turns.map(\n ({ turnId, afterSeq }) => sql`(${turnId}::text, ${afterSeq}::bigint)`,\n );\n const rows = await query(\n db,\n sql`select ${ITEM_COLUMNS_OF_I}\n from parlor_chat_items i\n join parlor_chat_turns t on t.id = i.turn_id and t.thread_id = i.thread_id\n join (values ${sql.join(wanted, sql`, `)}) as q(turn_id, after_seq)\n on q.turn_id = i.turn_id\n where t.host_id = ${host.hostId} and t.owner_id = ${owner.userId}\n and t.scope = ${owner.scope} and i.kind in ('answer', 'cancel')\n and i.seq > q.after_seq\n order by i.turn_id, i.seq`,\n itemRow,\n );\n const byTurn = new Map<TurnId, LoggedItem<\"answer\" | \"cancel\">[]>();\n for (const item of rows.map(toLoggedItem)) {\n if (item.kind !== \"answer\" && item.kind !== \"cancel\") continue;\n const list = byTurn.get(item.turnId) ?? [];\n list.push(item);\n byTurn.set(item.turnId, list);\n }\n return [...byTurn].map(([turnId, items]) => ({ turnId, items }));\n },\n\n async reportHost(tx, owner, host, report) {\n const ttlMs = report.online ? report.ttlMs : 0;\n const [row] = await query(\n tx,\n sql`insert into parlor_chat_hosts\n (id, scope, owner_id, grant_id, protocol, name, platform, agents, devices,\n presence_due, online_until, announced_online)\n values (${host.hostId}, ${owner.scope}, ${owner.userId}, ${host.grantId},\n ${report.protocol}, ${report.name}, ${report.platform},\n ${JSON.stringify(report.agents)}::jsonb,\n ${report.devices ? JSON.stringify(report.devices) : null}::jsonb,\n ${report.presenceDue ? JSON.stringify(report.presenceDue) : null}::jsonb,\n ${leaseSql(ttlMs)}, ${report.online})\n on conflict (id) do update set\n grant_id = excluded.grant_id, protocol = excluded.protocol, name = excluded.name,\n platform = excluded.platform, agents = excluded.agents,\n devices = coalesce(excluded.devices, parlor_chat_hosts.devices),\n presence_due = coalesce(excluded.presence_due, parlor_chat_hosts.presence_due),\n online_until = excluded.online_until,\n announced_online = excluded.announced_online\n where parlor_chat_hosts.owner_id = excluded.owner_id\n and parlor_chat_hosts.scope = excluded.scope\n returning ${ms(\"online_until\")} as online_until`,\n z.object({ online_until: count }),\n );\n if (!row)\n throw new ActionError(\"forbidden\", \"This computer belongs to another account.\");\n return { onlineUntil: row.online_until };\n },\n\n async heartbeat(db, owner, host, ttlMs) {\n const [beat] = await query(\n db,\n sql`update parlor_chat_hosts as h\n set online_until = ${leaseSql(ttlMs)}, announced_online = true\n from (select announced_online as was from parlor_chat_hosts where id = ${host.hostId}) as prev\n where h.id = ${host.hostId} and h.owner_id = ${owner.userId}\n and h.scope = ${owner.scope} and h.grant_id = ${host.grantId}\n returning prev.was as was`,\n z.object({ was: z.boolean() }),\n );\n return { returned: beat !== undefined && !beat.was };\n },\n\n async listHosts(db, owner) {\n return query(\n db,\n sql`select id, grant_id, protocol, name, platform, agents, devices, presence_due,\n online_until > now() as online\n from parlor_chat_hosts\n where owner_id = ${owner.userId} and scope = ${owner.scope}\n order by name, id`,\n z\n .object({\n id: idSchema(\"host\"),\n grant_id: idSchema(\"grant\"),\n protocol: z.number().int(),\n name: z.string(),\n platform: z.string(),\n agents: z.array(agentInfoSchema),\n devices: z.array(z.string()).nullable(),\n presence_due: z.record(z.string(), z.number()).nullable(),\n online: z.boolean(),\n })\n .transform(({ grant_id, devices, presence_due, ...host }) => ({\n ...host,\n ...(devices ? { devices } : {}),\n ...(presence_due ? { presenceDue: presence_due } : {}),\n grantId: grant_id,\n })),\n );\n },\n\n async pruneHosts(tx, owner, hostIds) {\n if (hostIds.length === 0) return;\n await tx.execute(\n sql`delete from parlor_chat_hosts\n where owner_id = ${owner.userId} and scope = ${owner.scope} and id in (${inList(hostIds)})`,\n );\n },\n\n async turnHolder(db, turnId) {\n const [row] = await query(\n db,\n sql`select scope, owner_id, thread_id, host_id,\n coalesce(state = 'running' and lease_until >= now(), false) as live\n from parlor_chat_turns where id = ${turnId}`,\n z.object({\n scope: z.string(),\n owner_id: idSchema(\"user\"),\n thread_id: idSchema(\"thread\"),\n host_id: idSchema(\"host\"),\n live: z.boolean(),\n }),\n );\n return row\n ? {\n owner: { scope: row.scope, userId: row.owner_id },\n threadId: row.thread_id,\n hostId: row.host_id,\n live: row.live,\n }\n : undefined;\n },\n};\n"]}
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/server/store.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\n\nimport {\n ActionError,\n asId,\n type DeviceId,\n type GrantId,\n type HostId,\n type HostPrincipal,\n type ItemId,\n type ThreadId,\n type TurnId,\n type UserId,\n} from \"@parlor/core\";\nimport { type SQL, sql } from \"drizzle-orm\";\nimport type { PgDatabase, PgQueryResultHKT } from \"drizzle-orm/pg-core\";\nimport { z } from \"zod\";\n\nimport { idSchema } from \"../id-schemas.js\";\nimport { chatItemBodies, type ChatItemBody, type ChatItemKind } from \"../items.js\";\nimport type { HostItemDraft, LoggedItem, UserItemKind } from \"../items.js\";\nimport type {\n AgentInfo,\n AgentRef,\n ChatOwner,\n ClaimedTurn,\n HostSummary,\n ThreadPage,\n ThreadSummary,\n TurnOutcome,\n TurnSignals,\n TurnStatus,\n} from \"../model.js\";\nimport {\n agentInfoSchema,\n itemRow,\n threadRow,\n toLoggedItem,\n toThreadSummary,\n TURN_FAILURES,\n turnStateSchema,\n} from \"./rows.js\";\n\nexport type ChatDb = PgDatabase<PgQueryResultHKT>;\n\nexport type UserDraft = {\n [K in UserItemKind]: {\n readonly id: LoggedItem<K>[\"id\"];\n readonly kind: K;\n readonly body: LoggedItem<K>[\"body\"];\n };\n}[UserItemKind];\n\nexport interface NewTurn {\n readonly turnId: TurnId;\n readonly agent: AgentRef;\n readonly clientId: string;\n readonly deviceId: DeviceId | undefined;\n /** The most turns a thread may have waiting; checked under the thread's lock. */\n readonly maxQueued: number;\n}\n\nexport interface TurnHolder {\n readonly owner: ChatOwner;\n readonly threadId: ThreadId;\n readonly hostId: HostId;\n}\n\n/** A turn's holder with whether it runs now: running, and its lease not yet lapsed. */\nexport interface StreamTurn extends TurnHolder {\n readonly live: boolean;\n}\n\n/** What one reconciliation changed in a scope, for the sync events it must emit. */\nexport interface OlderItems {\n readonly items: readonly LoggedItem[];\n readonly turns: readonly TurnStatus[];\n readonly hasMore: boolean;\n}\n\nexport interface ThreadCursor {\n readonly updatedAt: number;\n readonly id: ThreadId;\n}\n\nexport interface OlderThreads {\n readonly threads: readonly ThreadSummary[];\n readonly hasMore: boolean;\n}\n\nexport interface Lapsed extends ChatOwner {\n readonly threads: readonly ThreadId[];\n readonly hosts: readonly HostId[];\n}\n\n/**\n * The thread log in SQL. Every function filters by the owner's scope and user in the same\n * statement, so another user's thread id reads as not found. Appends lock the thread row\n * to assign gap-free `seq` and run in the action's transaction so the thread's sync event\n * commits with them.\n */\nexport interface ChatStore {\n listThreads(db: ChatDb, owner: ChatOwner): Promise<ThreadSummary[]>;\n readPage(\n db: ChatDb,\n owner: ChatOwner,\n threadId: ThreadId | undefined,\n limit: number,\n ): Promise<Omit<ThreadPage, \"open\">>;\n /** Items before `beforeSeq`, oldest first, with their turns; `hasMore` while older ones remain. */\n readItemsBefore?(\n db: ChatDb,\n owner: ChatOwner,\n threadId: ThreadId,\n beforeSeq: number,\n limit: number,\n ): Promise<OlderItems>;\n /** Threads updated before `before`, newest first, after the ones `listThreads` returned. */\n listThreadsBefore?(\n db: ChatDb,\n owner: ChatOwner,\n before: ThreadCursor,\n limit: number,\n ): Promise<OlderThreads>;\n readItemsAfter(\n db: ChatDb,\n owner: ChatOwner,\n threadId: ThreadId,\n afterSeq: number,\n ): Promise<LoggedItem[]>;\n /** With `turn`, also queues it; the thread is created on its first prompt. */\n appendUserItems(\n tx: ChatDb,\n owner: ChatOwner,\n input: {\n readonly threadId: ThreadId;\n readonly turnId: TurnId;\n readonly items: readonly UserDraft[];\n readonly turn?: NewTurn | undefined;\n },\n ): Promise<LoggedItem[]>;\n claimTurn(\n tx: ChatDb,\n owner: ChatOwner,\n host: HostPrincipal,\n leaseMs: number,\n ): Promise<Omit<ClaimedTurn, \"context\" | \"token\" | \"device\"> | undefined>;\n /** Whether anything waits for `expireLapsed`; one read, so the idle path writes nothing. */\n hasLapsed(db: ChatDb, owner: ChatOwner | undefined): Promise<boolean>;\n /**\n * Fails the running turns whose lease lapsed (`host_lost`) and marks the computers whose\n * liveness lapsed offline, for `owner` or, without one, for everyone. Commit it apart\n * from any claim, because a claim that finds nothing aborts its own transaction.\n */\n expireLapsed(tx: ChatDb, owner: ChatOwner | undefined): Promise<Lapsed[]>;\n /**\n * Puts a claimed turn back in the queue when the host never learned of the claim.\n * Refused (false) once the turn has an agent item or is no longer running.\n */\n releaseClaim(\n tx: ChatDb,\n owner: ChatOwner,\n host: HostPrincipal,\n turnId: TurnId,\n ): Promise<boolean>;\n appendHostItems(\n tx: ChatDb,\n owner: ChatOwner,\n host: HostPrincipal,\n turnId: TurnId,\n items: readonly HostItemDraft[],\n leaseMs: number,\n ): Promise<{\n readonly threadId: ThreadId;\n readonly leaseUntil: number;\n /** What the renewed turn token binds, so the caller need not read the turn again. */\n readonly clientId: string;\n readonly agentId: string;\n }>;\n /** Once per turn; a second call with any outcome is refused and changes nothing. */\n finishTurn(\n tx: ChatDb,\n owner: ChatOwner,\n host: HostPrincipal,\n turnId: TurnId,\n outcome: TurnOutcome,\n ): Promise<{ readonly threadId: ThreadId }>;\n readSignals(\n db: ChatDb,\n owner: ChatOwner,\n host: HostPrincipal,\n turns: readonly { readonly turnId: TurnId; readonly afterSeq: number }[],\n ): Promise<TurnSignals[]>;\n reportHost(\n tx: ChatDb,\n owner: ChatOwner,\n host: HostPrincipal,\n report: {\n readonly protocol: number;\n readonly name: string;\n readonly platform: string;\n readonly agents: readonly AgentInfo[];\n /** Left as it was when the host does not report it. */\n readonly devices?: readonly string[] | undefined;\n /** Left as it was when the host does not report it. */\n readonly presenceDue?: Readonly<Record<string, number>> | undefined;\n /** When the host looked for its agents; left as it was when this report is not that. */\n readonly agentsCheckedAt?: number | undefined;\n readonly online: boolean;\n readonly ttlMs: number;\n },\n ): Promise<{ readonly onlineUntil: number }>;\n /**\n * One UPDATE of `online_until`. `returned` is true when the sidebar had been told the\n * computer was offline, so the caller announces its return.\n */\n heartbeat(\n db: ChatDb,\n owner: ChatOwner,\n host: HostPrincipal,\n ttlMs: number,\n ): Promise<{ readonly returned: boolean }>;\n listHosts(db: ChatDb, owner: ChatOwner): Promise<StoredHost[]>;\n /** Drops the owner's computer rows whose grant is gone. */\n pruneHosts(tx: ChatDb, owner: ChatOwner, hostIds: readonly HostId[]): Promise<void>;\n turnHolder(db: ChatDb, turnId: TurnId): Promise<StreamTurn | undefined>;\n}\n\nexport interface StoredHost extends HostSummary {\n readonly grantId: GrantId;\n readonly protocol: number;\n}\n\nfunction rowsOf(result: unknown): unknown[] {\n if (Array.isArray(result)) return result;\n const rows = (result as { rows?: unknown[] } | null)?.rows;\n return rows ?? [];\n}\n\nasync function query<S extends z.ZodType>(\n db: ChatDb,\n statement: SQL,\n schema: S,\n): Promise<z.output<S>[]> {\n const result = await db.execute(statement);\n return rowsOf(result).map((row) => schema.parse(row));\n}\n\nconst count = z.coerce.number();\nconst ms = (column: string) => sql.raw(`(extract(epoch from ${column}) * 1000)::bigint`);\nconst ITEM_COLUMNS = sql`id, thread_id, turn_id, seq, kind, body, ${ms(\"created_at\")} as at`;\nconst ITEM_COLUMNS_OF_I = sql`i.id, i.thread_id, i.turn_id, i.seq, i.kind, i.body, ${ms(\"i.created_at\")} as at`;\nconst THREAD_COLUMNS = sql`id, title, host_id, agent_id, last_seq, ${ms(\"updated_at\")} as updated_at`;\n\nexport const THREAD_LIST_LIMIT = 200;\nconst TITLE_CHARS = 80;\nconst TERMINAL_STATES: ReadonlySet<string> = new Set([\"done\", \"failed\", \"cancelled\"]);\n\nconst threadMissing = () => new ActionError(\"not_found\", \"Thread not found\");\nconst turnMissing = () => new ActionError(\"not_found\", \"Turn not found\");\n\nconst inList = (values: readonly string[]) =>\n sql.join(\n values.map((value) => sql`${value}`),\n sql`, `,\n );\n\nconst authorOf = (kind: ChatItemKind) => chatItemBodies[kind].author;\n\nfunction titleOf(text: string): string {\n const firstLine = text.trim().split(\"\\n\")[0] ?? \"\";\n return [...firstLine].slice(0, TITLE_CHARS).join(\"\");\n}\n\ninterface ItemInsert {\n readonly id: ItemId;\n readonly turnId: TurnId;\n readonly kind: ChatItemKind;\n readonly body: unknown;\n}\n\ninterface LogLock {\n readonly lastSeq: number;\n readonly turnState: string | undefined;\n /** Running and its lease has not lapsed: the only turn a host may write to. */\n readonly leased: boolean;\n}\n\n/** The only place the log is locked: the thread row, then the turn row. */\nasync function lockLog(\n tx: ChatDb,\n owner: ChatOwner,\n threadId: ThreadId,\n turnId?: TurnId,\n): Promise<LogLock> {\n const [row] = await query(\n tx,\n sql`select last_seq from parlor_chat_threads\n where id = ${threadId} and scope = ${owner.scope} and owner_id = ${owner.userId}\n for update`,\n z.object({ last_seq: count }),\n );\n if (!row) throw threadMissing();\n if (turnId === undefined) {\n return { lastSeq: row.last_seq, turnState: undefined, leased: false };\n }\n const [turn] = await query(\n tx,\n sql`select state, coalesce(state = 'running' and lease_until >= now(), false) as leased\n from parlor_chat_turns where id = ${turnId} and thread_id = ${threadId} for update`,\n z.object({ state: z.string(), leased: z.boolean() }),\n );\n return {\n lastSeq: row.last_seq,\n turnState: turn?.state,\n leased: turn?.leased ?? false,\n };\n}\n\nasync function insertItems(\n tx: ChatDb,\n threadId: ThreadId,\n lastSeq: number,\n rows: readonly ItemInsert[],\n): Promise<number> {\n if (rows.length === 0) return lastSeq;\n const values = rows.map(\n (row, index) =>\n sql`(${row.id}, ${threadId}, ${row.turnId}, ${lastSeq + index + 1}, ${authorOf(row.kind)}, ${row.kind}, ${JSON.stringify(row.body)}::jsonb)`,\n );\n await tx.execute(\n sql`insert into parlor_chat_items (id, thread_id, turn_id, seq, author, kind, body)\n values ${sql.join(values, sql`, `)}`,\n );\n const next = lastSeq + rows.length;\n await tx.execute(\n sql`update parlor_chat_threads set last_seq = ${next}, updated_at = now() where id = ${threadId}`,\n );\n return next;\n}\n\nasync function itemThreads(\n tx: ChatDb,\n ids: readonly ItemId[],\n): Promise<Map<string, string>> {\n if (ids.length === 0) return new Map();\n const rows = await query(\n tx,\n sql`select id, thread_id from parlor_chat_items where id in (${inList(ids)})`,\n z.object({ id: z.string(), thread_id: z.string() }),\n );\n return new Map(rows.map((row) => [row.id, row.thread_id]));\n}\n\nasync function itemsById(\n db: ChatDb,\n threadId: ThreadId,\n ids: readonly ItemId[],\n): Promise<LoggedItem[]> {\n if (ids.length === 0) return [];\n const rows = await query(\n db,\n sql`select ${ITEM_COLUMNS} from parlor_chat_items\n where thread_id = ${threadId} and id in (${inList(ids)}) order by seq`,\n itemRow,\n );\n return rows.map(toLoggedItem);\n}\n\nconst turnRow = z.object({\n id: idSchema(\"turn\"),\n thread_id: idSchema(\"thread\"),\n host_id: idSchema(\"host\"),\n agent_id: z.string(),\n state: turnStateSchema,\n lapsed: z.boolean(),\n failure: z.enum(TURN_FAILURES).nullable(),\n});\n\nasync function createTurn(\n tx: ChatDb,\n owner: ChatOwner,\n threadId: ThreadId,\n turn: NewTurn,\n promptItemId: ItemId,\n): Promise<void> {\n const [existing] = await query(\n tx,\n sql`select thread_id, owner_id, scope from parlor_chat_turns where id = ${turn.turnId}`,\n z.object({ thread_id: z.string(), owner_id: z.string(), scope: z.string() }),\n );\n if (existing) {\n const sameThread =\n existing.thread_id === threadId &&\n existing.owner_id === owner.userId &&\n existing.scope === owner.scope;\n if (!sameThread) throw turnMissing();\n return;\n }\n const [queued] = await query(\n tx,\n sql`select count(*) as waiting from parlor_chat_turns\n where thread_id = ${threadId} and state = 'queued'`,\n z.object({ waiting: count }),\n );\n if ((queued?.waiting ?? 0) >= turn.maxQueued) {\n throw new ActionError(\n \"invalid_input\",\n \"Too many prompts are waiting for the agent; wait for it to catch up.\",\n );\n }\n await tx.execute(\n sql`insert into parlor_chat_turns\n (id, thread_id, scope, owner_id, host_id, agent_id, client_id, device_id, prompt_item_id, state)\n values (${turn.turnId}, ${threadId}, ${owner.scope}, ${owner.userId}, ${turn.agent.hostId},\n ${turn.agent.agentId}, ${turn.clientId}, ${turn.deviceId ?? null}, ${promptItemId}, 'queued')`,\n );\n}\n\nasync function admitsUserItem(\n tx: ChatDb,\n threadId: ThreadId,\n turnId: TurnId,\n draft: UserDraft,\n): Promise<boolean> {\n if (draft.kind === \"prompt\") return true;\n if (draft.kind === \"answer\") {\n const askId = draft.body.askId;\n const [ask] = await query(\n tx,\n sql`select turn_id, body->>'approval' as approval from parlor_chat_items\n where thread_id = ${threadId} and id = ${askId} and kind = 'ask'`,\n z.object({ turn_id: z.string(), approval: z.string().nullable() }),\n );\n if (!ask || ask.turn_id !== turnId)\n throw new ActionError(\"not_found\", \"Question not found\");\n if (ask.approval === \"computer\") {\n throw new ActionError(\"forbidden\", \"This question is answered on the computer.\");\n }\n const { signed } = draft.body;\n if (ask.approval === \"presence\" && signed?.signature.presence !== \"user\") {\n throw new ActionError(\"forbidden\", \"This question needs a presence check.\");\n }\n if (ask.approval === \"device\" && !signed) {\n throw new ActionError(\n \"forbidden\",\n \"This question is answered on the device that asked it.\",\n );\n }\n const [state] = await query(\n tx,\n sql`select state from parlor_chat_turns where id = ${turnId} for update`,\n z.object({ state: z.string() }),\n );\n const [standing] = await query(\n tx,\n sql`select a.id from parlor_chat_items a\n where a.thread_id = ${threadId} and a.kind = 'answer' and a.body->>'askId' = ${askId}\n and not exists (\n select 1 from parlor_chat_items e\n where e.thread_id = ${threadId} and e.kind = 'event'\n and e.body->>'event' = 'answer_rejected' and e.body->>'itemId' = a.id)\n limit 1`,\n z.object({ id: z.string() }),\n );\n if (standing) {\n throw new ActionError(\"invalid_input\", \"This question was already answered.\");\n }\n if (state?.state !== \"running\") {\n throw new ActionError(\n \"invalid_input\",\n \"The agent is no longer waiting for this answer.\",\n );\n }\n return true;\n }\n const [turn] = await query(\n tx,\n sql`select state from parlor_chat_turns where id = ${turnId} and thread_id = ${threadId}`,\n z.object({ state: z.string() }),\n );\n if (!turn) throw turnMissing();\n if (TERMINAL_STATES.has(turn.state)) return false;\n if (turn.state === \"queued\") {\n await tx.execute(\n sql`update parlor_chat_turns\n set state = 'cancelled', outcome = '{\"state\":\"cancelled\"}'::jsonb, finished_at = now()\n where id = ${turnId} and state = 'queued'`,\n );\n }\n return true;\n}\n\nconst lostItemId = () => asId(\"item\", `lost.${randomUUID()}`);\n\nconst ownedBy = (owner: ChatOwner | undefined) =>\n owner ? sql`and owner_id = ${owner.userId} and scope = ${owner.scope}` : sql``;\n\nasync function lapsedFor(db: ChatDb, owner: ChatOwner | undefined): Promise<boolean> {\n const [found] = await query(\n db,\n sql`select (\n exists (select 1 from parlor_chat_turns\n where state = 'running' and lease_until < now() ${ownedBy(owner)})\n or exists (select 1 from parlor_chat_hosts\n where announced_online and online_until <= now() ${ownedBy(owner)})\n ) as lapsed`,\n z.object({ lapsed: z.boolean() }),\n );\n return found?.lapsed ?? false;\n}\n\nasync function expireLapsed(tx: ChatDb, owner: ChatOwner | undefined): Promise<Lapsed[]> {\n const changes = new Map<string, Lapsed & { threads: ThreadId[]; hosts: HostId[] }>();\n const changed = (scope: string, userId: UserId) => {\n const key = `${scope}\\u0000${userId}`;\n let change = changes.get(key);\n if (!change) changes.set(key, (change = { scope, userId, threads: [], hosts: [] }));\n return change;\n };\n const lapsed = await query(\n tx,\n sql`select distinct scope, owner_id, thread_id from parlor_chat_turns\n where state = 'running' and lease_until < now() ${ownedBy(owner)}\n order by thread_id`,\n z.object({\n scope: z.string(),\n owner_id: idSchema(\"user\"),\n thread_id: idSchema(\"thread\"),\n }),\n );\n for (const { scope, owner_id: userId, thread_id: threadId } of lapsed) {\n const { lastSeq } = await lockLog(tx, { scope, userId }, threadId);\n const expired = await query(\n tx,\n sql`update parlor_chat_turns\n set state = 'failed', outcome = '{\"state\":\"failed\",\"reason\":\"host_lost\"}'::jsonb,\n finished_at = now()\n where thread_id = ${threadId} and state = 'running' and lease_until < now()\n returning id`,\n z.object({ id: idSchema(\"turn\") }),\n );\n if (expired.length === 0) continue;\n await insertItems(\n tx,\n threadId,\n lastSeq,\n expired.map(({ id }) => ({\n id: lostItemId(),\n turnId: id,\n kind: \"event\",\n body: { event: \"host_lost\" } satisfies ChatItemBody<\"event\">,\n })),\n );\n changed(scope, userId).threads.push(threadId);\n }\n const offline = await query(\n tx,\n sql`update parlor_chat_hosts set announced_online = false\n where announced_online and online_until <= now() ${ownedBy(owner)}\n returning id, scope, owner_id`,\n z.object({ id: idSchema(\"host\"), scope: z.string(), owner_id: idSchema(\"user\") }),\n );\n for (const { id, scope, owner_id: userId } of offline) {\n changed(scope, userId).hosts.push(id);\n }\n return [...changes.values()];\n}\n\nasync function lockRunningTurn(\n tx: ChatDb,\n owner: ChatOwner,\n host: HostPrincipal,\n turnId: TurnId,\n): Promise<{\n readonly threadId: ThreadId;\n readonly lastSeq: number;\n readonly clientId: string;\n readonly agentId: string;\n}> {\n const [found] = await query(\n tx,\n sql`select thread_id, client_id, agent_id from parlor_chat_turns\n where id = ${turnId} and host_id = ${host.hostId}\n and owner_id = ${owner.userId} and scope = ${owner.scope}`,\n z.object({\n thread_id: idSchema(\"thread\"),\n client_id: z.string(),\n agent_id: z.string(),\n }),\n );\n if (!found) throw turnMissing();\n const { lastSeq, leased } = await lockLog(tx, owner, found.thread_id, turnId);\n if (!leased) throw new ActionError(\"forbidden\", \"The turn is not running.\");\n return {\n threadId: found.thread_id,\n lastSeq,\n clientId: found.client_id,\n agentId: found.agent_id,\n };\n}\n\nconst leaseSql = (leaseMs: number) =>\n sql`now() + ${leaseMs}::float8 * interval '1 millisecond'`;\n\nasync function requireThread(db: ChatDb, owner: ChatOwner, threadId: ThreadId) {\n const [thread] = await query(\n db,\n sql`select id from parlor_chat_threads\n where id = ${threadId} and owner_id = ${owner.userId} and scope = ${owner.scope}`,\n z.object({ id: z.string() }),\n );\n if (!thread) throw threadMissing();\n}\n\n/** The turns that `items`, a run of consecutive seqs, belong to. */\nasync function turnsOf(\n db: ChatDb,\n threadId: ThreadId,\n items: readonly LoggedItem[],\n): Promise<TurnStatus[]> {\n const first = items[0];\n const last = items.at(-1);\n if (!first || !last) return [];\n const turns = await query(\n db,\n sql`select id, thread_id, host_id, agent_id, state,\n coalesce(state = 'running' and lease_until < now(), false) as lapsed,\n case when state = 'failed' then outcome->>'reason' end as failure\n from parlor_chat_turns\n where thread_id = ${threadId}\n and id in (select turn_id from parlor_chat_items\n where thread_id = ${threadId} and seq between ${first.seq} and ${last.seq})\n order by created_at, id`,\n turnRow,\n );\n return turns.map((turn) => ({\n turnId: turn.id,\n state: turn.lapsed ? \"failed\" : turn.state,\n agent: { hostId: turn.host_id, agentId: turn.agent_id },\n failure: turn.lapsed ? \"host_lost\" : (turn.failure ?? undefined),\n }));\n}\n\nexport const sqlChatStore: ChatStore = {\n async listThreads(db, owner) {\n const rows = await query(\n db,\n sql`select ${THREAD_COLUMNS} from parlor_chat_threads\n where owner_id = ${owner.userId} and scope = ${owner.scope}\n order by updated_at desc, id limit ${THREAD_LIST_LIMIT}`,\n threadRow,\n );\n return rows.map(toThreadSummary);\n },\n\n async readPage(db, owner, threadId, limit) {\n const [row] = await query(\n db,\n threadId\n ? sql`select ${THREAD_COLUMNS} from parlor_chat_threads\n where id = ${threadId} and owner_id = ${owner.userId} and scope = ${owner.scope}`\n : sql`select ${THREAD_COLUMNS} from parlor_chat_threads\n where owner_id = ${owner.userId} and scope = ${owner.scope}\n order by updated_at desc, id limit 1`,\n threadRow,\n );\n if (!row) return { thread: undefined, items: [], turns: [], hasMore: false };\n const rows = await query(\n db,\n sql`select ${ITEM_COLUMNS} from parlor_chat_items\n where thread_id = ${row.id} order by seq desc limit ${limit + 1}`,\n itemRow,\n );\n const hasMore = rows.length > limit;\n const items = rows.slice(0, limit).reverse().map(toLoggedItem);\n return {\n thread: toThreadSummary(row),\n items,\n turns: await turnsOf(db, row.id, items),\n hasMore,\n };\n },\n\n async readItemsBefore(db, owner, threadId, beforeSeq, limit) {\n const rows = await query(\n db,\n sql`select ${ITEM_COLUMNS_OF_I} from parlor_chat_items i\n join parlor_chat_threads t on t.id = i.thread_id\n where t.id = ${threadId} and t.owner_id = ${owner.userId} and t.scope = ${owner.scope}\n and i.seq < ${beforeSeq}\n order by i.seq desc limit ${limit + 1}`,\n itemRow,\n );\n if (rows.length === 0) await requireThread(db, owner, threadId);\n const items = rows.slice(0, limit).reverse().map(toLoggedItem);\n return {\n items,\n turns: await turnsOf(db, threadId, items),\n hasMore: rows.length > limit,\n };\n },\n\n async listThreadsBefore(db, owner, before, limit) {\n const updated = ms(\"updated_at\");\n const rows = await query(\n db,\n sql`select ${THREAD_COLUMNS} from parlor_chat_threads\n where owner_id = ${owner.userId} and scope = ${owner.scope}\n and (${updated} < ${before.updatedAt}\n or (${updated} = ${before.updatedAt} and id < ${before.id}))\n order by updated_at desc, id desc limit ${limit + 1}`,\n threadRow,\n );\n return {\n threads: rows.slice(0, limit).map(toThreadSummary),\n hasMore: rows.length > limit,\n };\n },\n\n async readItemsAfter(db, owner, threadId, afterSeq) {\n const rows = await query(\n db,\n sql`select ${ITEM_COLUMNS_OF_I} from parlor_chat_items i\n join parlor_chat_threads t on t.id = i.thread_id\n where t.id = ${threadId} and t.owner_id = ${owner.userId} and t.scope = ${owner.scope}\n and i.seq > ${afterSeq}\n order by i.seq`,\n itemRow,\n );\n if (rows.length === 0) await requireThread(db, owner, threadId);\n return rows.map(toLoggedItem);\n },\n\n async appendUserItems(tx, owner, input) {\n const { threadId, turnId, items, turn } = input;\n if (turn) {\n const prompt = items.find((draft) => draft.kind === \"prompt\");\n await tx.execute(\n sql`insert into parlor_chat_threads (id, scope, owner_id, title, host_id, agent_id)\n values (${threadId}, ${owner.scope}, ${owner.userId},\n ${prompt?.kind === \"prompt\" ? titleOf(prompt.body.text) : \"\"},\n ${turn.agent.hostId}, ${turn.agent.agentId})\n on conflict (id) do nothing`,\n );\n }\n const { lastSeq } = await lockLog(tx, owner, threadId);\n if (turn) {\n const prompt = items.find((draft) => draft.kind === \"prompt\");\n if (!prompt) throw new ActionError(\"invalid_input\", \"A turn starts with a prompt.\");\n await createTurn(tx, owner, threadId, turn, prompt.id);\n }\n const known = await itemThreads(\n tx,\n items.map((draft) => draft.id),\n );\n const fresh: UserDraft[] = [];\n for (const draft of items) {\n const where = known.get(draft.id);\n if (where === undefined) {\n if (await admitsUserItem(tx, threadId, turnId, draft)) fresh.push(draft);\n } else if (where !== threadId) {\n throw threadMissing();\n }\n }\n await insertItems(\n tx,\n threadId,\n lastSeq,\n fresh.map((draft) => ({\n id: draft.id,\n turnId,\n kind: draft.kind,\n body: draft.body,\n })),\n );\n if (turn) {\n await tx.execute(\n sql`update parlor_chat_threads set host_id = ${turn.agent.hostId}, agent_id = ${turn.agent.agentId}\n where id = ${threadId}`,\n );\n }\n return itemsById(\n tx,\n threadId,\n items.map((draft) => draft.id),\n );\n },\n\n async hasLapsed(db, owner) {\n return lapsedFor(db, owner);\n },\n\n expireLapsed,\n\n async claimTurn(tx, owner, host, leaseMs) {\n const [claimed] = await query(\n tx,\n sql`select t.id, t.thread_id, t.agent_id, t.client_id, t.prompt_item_id\n from parlor_chat_turns t\n where t.host_id = ${host.hostId} and t.owner_id = ${owner.userId}\n and t.scope = ${owner.scope} and t.state = 'queued'\n and not exists (\n select 1 from parlor_chat_turns earlier\n where earlier.thread_id = t.thread_id and earlier.state in ('queued', 'running')\n and (earlier.created_at, earlier.id) < (t.created_at, t.id))\n order by t.created_at, t.id\n limit 1\n for update of t skip locked`,\n z.object({\n id: idSchema(\"turn\"),\n thread_id: idSchema(\"thread\"),\n agent_id: z.string(),\n client_id: z.string(),\n prompt_item_id: idSchema(\"item\"),\n }),\n );\n if (!claimed) return undefined;\n const [lease] = await query(\n tx,\n sql`update parlor_chat_turns set state = 'running', lease_until = ${leaseSql(leaseMs)}\n where id = ${claimed.id}\n returning ${ms(\"lease_until\")} as lease_until`,\n z.object({ lease_until: count }),\n );\n const [prompt] = await itemsById(tx, claimed.thread_id, [claimed.prompt_item_id]);\n if (!lease || prompt?.kind !== \"prompt\") {\n throw new ActionError(\"internal\", \"The claimed turn lost its prompt.\");\n }\n return {\n id: claimed.thread_id,\n turnId: claimed.id,\n agent: { hostId: host.hostId, agentId: claimed.agent_id },\n clientId: claimed.client_id,\n prompt,\n leaseUntil: lease.lease_until,\n };\n },\n\n async releaseClaim(tx, owner, host, turnId) {\n const released = await query(\n tx,\n sql`update parlor_chat_turns set state = 'queued', lease_until = null\n where id = ${turnId} and host_id = ${host.hostId} and owner_id = ${owner.userId}\n and scope = ${owner.scope} and state = 'running' and lease_until >= now()\n and not exists (\n select 1 from parlor_chat_items i\n where i.turn_id = parlor_chat_turns.id and i.author <> 'user')\n returning thread_id`,\n z.object({ thread_id: idSchema(\"thread\") }),\n );\n return released.length > 0;\n },\n\n async appendHostItems(tx, owner, host, turnId, items, leaseMs) {\n const { threadId, lastSeq, clientId, agentId } = await lockRunningTurn(\n tx,\n owner,\n host,\n turnId,\n );\n const known = await itemThreads(\n tx,\n items.map((draft) => draft.id),\n );\n const fresh: HostItemDraft[] = [];\n for (const draft of items) {\n const where = known.get(draft.id);\n if (where === undefined) fresh.push(draft);\n else if (where !== threadId)\n throw new ActionError(\"forbidden\", \"That item id is taken.\");\n }\n await insertItems(\n tx,\n threadId,\n lastSeq,\n fresh.map((draft) => ({\n id: draft.id,\n turnId,\n kind: draft.kind,\n body: draft.body,\n })),\n );\n const [lease] = await query(\n tx,\n sql`update parlor_chat_turns set lease_until = ${leaseSql(leaseMs)}\n where id = ${turnId} returning ${ms(\"lease_until\")} as lease_until`,\n z.object({ lease_until: count }),\n );\n return { threadId, leaseUntil: lease?.lease_until ?? 0, clientId, agentId };\n },\n\n async finishTurn(tx, owner, host, turnId, outcome) {\n const { threadId } = await lockRunningTurn(tx, owner, host, turnId);\n await tx.execute(\n sql`update parlor_chat_turns\n set state = ${outcome.state}, outcome = ${JSON.stringify(outcome)}::jsonb, finished_at = now()\n where id = ${turnId}`,\n );\n await tx.execute(\n sql`update parlor_chat_threads set updated_at = now() where id = ${threadId}`,\n );\n return { threadId };\n },\n\n async readSignals(db, owner, host, turns) {\n if (turns.length === 0) return [];\n const wanted = turns.map(\n ({ turnId, afterSeq }) => sql`(${turnId}::text, ${afterSeq}::bigint)`,\n );\n const rows = await query(\n db,\n sql`select ${ITEM_COLUMNS_OF_I}\n from parlor_chat_items i\n join parlor_chat_turns t on t.id = i.turn_id and t.thread_id = i.thread_id\n join (values ${sql.join(wanted, sql`, `)}) as q(turn_id, after_seq)\n on q.turn_id = i.turn_id\n where t.host_id = ${host.hostId} and t.owner_id = ${owner.userId}\n and t.scope = ${owner.scope} and i.kind in ('answer', 'cancel')\n and i.seq > q.after_seq\n order by i.turn_id, i.seq`,\n itemRow,\n );\n const byTurn = new Map<TurnId, LoggedItem<\"answer\" | \"cancel\">[]>();\n for (const item of rows.map(toLoggedItem)) {\n if (item.kind !== \"answer\" && item.kind !== \"cancel\") continue;\n const list = byTurn.get(item.turnId) ?? [];\n list.push(item);\n byTurn.set(item.turnId, list);\n }\n return [...byTurn].map(([turnId, items]) => ({ turnId, items }));\n },\n\n async reportHost(tx, owner, host, report) {\n const ttlMs = report.online ? report.ttlMs : 0;\n const [row] = await query(\n tx,\n sql`insert into parlor_chat_hosts\n (id, scope, owner_id, grant_id, protocol, name, platform, agents, devices,\n presence_due, agents_checked_at, online_until, announced_online)\n values (${host.hostId}, ${owner.scope}, ${owner.userId}, ${host.grantId},\n ${report.protocol}, ${report.name}, ${report.platform},\n ${JSON.stringify(report.agents)}::jsonb,\n ${report.devices ? JSON.stringify(report.devices) : null}::jsonb,\n ${report.presenceDue ? JSON.stringify(report.presenceDue) : null}::jsonb,\n ${report.agentsCheckedAt === undefined ? null : new Date(report.agentsCheckedAt).toISOString()}::timestamptz,\n ${leaseSql(ttlMs)}, ${report.online})\n on conflict (id) do update set\n grant_id = excluded.grant_id, protocol = excluded.protocol, name = excluded.name,\n platform = excluded.platform, agents = excluded.agents,\n devices = coalesce(excluded.devices, parlor_chat_hosts.devices),\n presence_due = coalesce(excluded.presence_due, parlor_chat_hosts.presence_due),\n agents_checked_at = coalesce(excluded.agents_checked_at, parlor_chat_hosts.agents_checked_at),\n online_until = excluded.online_until,\n announced_online = excluded.announced_online\n where parlor_chat_hosts.owner_id = excluded.owner_id\n and parlor_chat_hosts.scope = excluded.scope\n returning ${ms(\"online_until\")} as online_until`,\n z.object({ online_until: count }),\n );\n if (!row)\n throw new ActionError(\"forbidden\", \"This computer belongs to another account.\");\n return { onlineUntil: row.online_until };\n },\n\n async heartbeat(db, owner, host, ttlMs) {\n const [beat] = await query(\n db,\n sql`update parlor_chat_hosts as h\n set online_until = ${leaseSql(ttlMs)}, announced_online = true\n from (select announced_online as was from parlor_chat_hosts where id = ${host.hostId}) as prev\n where h.id = ${host.hostId} and h.owner_id = ${owner.userId}\n and h.scope = ${owner.scope} and h.grant_id = ${host.grantId}\n returning prev.was as was`,\n z.object({ was: z.boolean() }),\n );\n return { returned: beat !== undefined && !beat.was };\n },\n\n async listHosts(db, owner) {\n return query(\n db,\n sql`select id, grant_id, protocol, name, platform, agents, devices, presence_due,\n ${ms(\"agents_checked_at\")} as agents_checked_at, online_until > now() as online\n from parlor_chat_hosts\n where owner_id = ${owner.userId} and scope = ${owner.scope}\n order by name, id`,\n z\n .object({\n id: idSchema(\"host\"),\n grant_id: idSchema(\"grant\"),\n protocol: z.number().int(),\n name: z.string(),\n platform: z.string(),\n agents: z.array(agentInfoSchema),\n devices: z.array(z.string()).nullable(),\n presence_due: z.record(z.string(), z.number()).nullable(),\n agents_checked_at: count.nullable(),\n online: z.boolean(),\n })\n .transform(({ grant_id, devices, presence_due, agents_checked_at, ...host }) => ({\n ...host,\n ...(devices ? { devices } : {}),\n ...(presence_due ? { presenceDue: presence_due } : {}),\n ...(agents_checked_at === null ? {} : { agentsCheckedAt: agents_checked_at }),\n grantId: grant_id,\n })),\n );\n },\n\n async pruneHosts(tx, owner, hostIds) {\n if (hostIds.length === 0) return;\n await tx.execute(\n sql`delete from parlor_chat_hosts\n where owner_id = ${owner.userId} and scope = ${owner.scope} and id in (${inList(hostIds)})`,\n );\n },\n\n async turnHolder(db, turnId) {\n const [row] = await query(\n db,\n sql`select scope, owner_id, thread_id, host_id,\n coalesce(state = 'running' and lease_until >= now(), false) as live\n from parlor_chat_turns where id = ${turnId}`,\n z.object({\n scope: z.string(),\n owner_id: idSchema(\"user\"),\n thread_id: idSchema(\"thread\"),\n host_id: idSchema(\"host\"),\n live: z.boolean(),\n }),\n );\n return row\n ? {\n owner: { scope: row.scope, userId: row.owner_id },\n threadId: row.thread_id,\n hostId: row.host_id,\n live: row.live,\n }\n : undefined;\n },\n};\n"]}
|
package/dist/tags.d.ts
CHANGED
|
@@ -4,4 +4,6 @@ export declare const CHAT_TAG = "parlor_chat";
|
|
|
4
4
|
export declare const HOSTS_TAG = "parlor_chat_hosts";
|
|
5
5
|
/** Emitted when a signed-in tab is in use, carrying no thread, item or text; it wakes no host's claim loop. */
|
|
6
6
|
export declare const CHAT_ACTIVITY_TAG = "parlor_chat_activity";
|
|
7
|
+
/** Emitted when a tab asks the user's computers to look again for the agents installed on them. */
|
|
8
|
+
export declare const CHAT_AGENTS_CHECK_TAG = "parlor_chat_agents_check";
|
|
7
9
|
//# sourceMappingURL=tags.d.ts.map
|
package/dist/tags.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../src/tags.ts"],"names":[],"mappings":"AAAA,4GAA4G;AAC5G,eAAO,MAAM,QAAQ,gBAAgB,CAAC;AACtC,iEAAiE;AACjE,eAAO,MAAM,SAAS,sBAAsB,CAAC;AAC7C,+GAA+G;AAC/G,eAAO,MAAM,iBAAiB,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../src/tags.ts"],"names":[],"mappings":"AAAA,4GAA4G;AAC5G,eAAO,MAAM,QAAQ,gBAAgB,CAAC;AACtC,iEAAiE;AACjE,eAAO,MAAM,SAAS,sBAAsB,CAAC;AAC7C,+GAA+G;AAC/G,eAAO,MAAM,iBAAiB,yBAAyB,CAAC;AACxD,mGAAmG;AACnG,eAAO,MAAM,qBAAqB,6BAA6B,CAAC"}
|
package/dist/tags.js
CHANGED
|
@@ -4,4 +4,6 @@ export const CHAT_TAG = "parlor_chat";
|
|
|
4
4
|
export const HOSTS_TAG = "parlor_chat_hosts";
|
|
5
5
|
/** Emitted when a signed-in tab is in use, carrying no thread, item or text; it wakes no host's claim loop. */
|
|
6
6
|
export const CHAT_ACTIVITY_TAG = "parlor_chat_activity";
|
|
7
|
+
/** Emitted when a tab asks the user's computers to look again for the agents installed on them. */
|
|
8
|
+
export const CHAT_AGENTS_CHECK_TAG = "parlor_chat_agents_check";
|
|
7
9
|
//# sourceMappingURL=tags.js.map
|
package/dist/tags.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../src/tags.ts"],"names":[],"mappings":"AAAA,4GAA4G;AAC5G,MAAM,CAAC,MAAM,QAAQ,GAAG,aAAa,CAAC;AACtC,iEAAiE;AACjE,MAAM,CAAC,MAAM,SAAS,GAAG,mBAAmB,CAAC;AAC7C,+GAA+G;AAC/G,MAAM,CAAC,MAAM,iBAAiB,GAAG,sBAAsB,CAAC","sourcesContent":["/** Every chat write emits `[\"parlor_chat\", threadId]`, the one event that wakes hosts and other devices. */\nexport const CHAT_TAG = \"parlor_chat\";\n/** Emitted when a computer comes, goes or changes its agents. */\nexport const HOSTS_TAG = \"parlor_chat_hosts\";\n/** Emitted when a signed-in tab is in use, carrying no thread, item or text; it wakes no host's claim loop. */\nexport const CHAT_ACTIVITY_TAG = \"parlor_chat_activity\";\n"]}
|
|
1
|
+
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../src/tags.ts"],"names":[],"mappings":"AAAA,4GAA4G;AAC5G,MAAM,CAAC,MAAM,QAAQ,GAAG,aAAa,CAAC;AACtC,iEAAiE;AACjE,MAAM,CAAC,MAAM,SAAS,GAAG,mBAAmB,CAAC;AAC7C,+GAA+G;AAC/G,MAAM,CAAC,MAAM,iBAAiB,GAAG,sBAAsB,CAAC;AACxD,mGAAmG;AACnG,MAAM,CAAC,MAAM,qBAAqB,GAAG,0BAA0B,CAAC","sourcesContent":["/** Every chat write emits `[\"parlor_chat\", threadId]`, the one event that wakes hosts and other devices. */\nexport const CHAT_TAG = \"parlor_chat\";\n/** Emitted when a computer comes, goes or changes its agents. */\nexport const HOSTS_TAG = \"parlor_chat_hosts\";\n/** Emitted when a signed-in tab is in use, carrying no thread, item or text; it wakes no host's claim loop. */\nexport const CHAT_ACTIVITY_TAG = \"parlor_chat_activity\";\n/** Emitted when a tab asks the user's computers to look again for the agents installed on them. */\nexport const CHAT_AGENTS_CHECK_TAG = \"parlor_chat_agents_check\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parlor/chat",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"homepage": "https://cychien.github.io/parlor",
|
|
5
5
|
"bugs": "https://github.com/cychien/parlor/issues",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,16 +31,16 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"drizzle-orm": "^0.45.4",
|
|
33
33
|
"zod": "^4.6.5",
|
|
34
|
-
"@parlor/agent-ui": "0.3.
|
|
35
|
-
"@parlor/server": "0.3.
|
|
36
|
-
"@parlor/core": "0.3.
|
|
37
|
-
"@parlor/sync": "0.3.
|
|
34
|
+
"@parlor/agent-ui": "0.3.3",
|
|
35
|
+
"@parlor/server": "0.3.3",
|
|
36
|
+
"@parlor/core": "0.3.3",
|
|
37
|
+
"@parlor/sync": "0.3.3"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^24.14.0",
|
|
41
41
|
"typescript": "^7.0.2",
|
|
42
42
|
"vitest": "^5.0.3",
|
|
43
|
-
"@parlor/data": "0.3.
|
|
43
|
+
"@parlor/data": "0.3.3"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"build": "tsc -p tsconfig.json",
|