@parlor/chat 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/items.d.ts +3 -0
- package/dist/items.d.ts.map +1 -1
- package/dist/items.js +8 -2
- package/dist/items.js.map +1 -1
- package/dist/model.d.ts +42 -0
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js.map +1 -1
- package/dist/protocol.d.ts +14 -2
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +4 -1
- package/dist/protocol.js.map +1 -1
- package/dist/server/actions.d.ts +125 -7
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/actions.js +91 -48
- package/dist/server/actions.js.map +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +8 -3
- package/dist/server/index.js.map +1 -1
- package/dist/server/live.d.ts +7 -2
- package/dist/server/live.d.ts.map +1 -1
- package/dist/server/live.js +17 -5
- package/dist/server/live.js.map +1 -1
- package/dist/server/push.d.ts +26 -0
- package/dist/server/push.d.ts.map +1 -0
- package/dist/server/push.js +56 -0
- package/dist/server/push.js.map +1 -0
- package/dist/server/rows.d.ts +21 -0
- package/dist/server/rows.d.ts.map +1 -1
- package/dist/server/rows.js +32 -0
- package/dist/server/rows.js.map +1 -1
- package/dist/server/store.d.ts.map +1 -1
- package/dist/server/store.js +3 -0
- package/dist/server/store.js.map +1 -1
- package/dist/view.d.ts +2 -0
- package/dist/view.d.ts.map +1 -1
- package/dist/view.js.map +1 -1
- package/package.json +6 -6
package/dist/server/live.js
CHANGED
|
@@ -8,6 +8,9 @@ const encoder = new TextEncoder();
|
|
|
8
8
|
function ownerKey(scope, userId) {
|
|
9
9
|
return `${scope}\u001f${userId ?? DEV_USER_ID}`;
|
|
10
10
|
}
|
|
11
|
+
function computerKey(scope, userId, hostId) {
|
|
12
|
+
return `${ownerKey(scope, userId)}\u001f${hostId}`;
|
|
13
|
+
}
|
|
11
14
|
function sizeOf(frame) {
|
|
12
15
|
return frame.type === "delta"
|
|
13
16
|
? encoder.encode(frame.text).length
|
|
@@ -16,6 +19,7 @@ function sizeOf(frame) {
|
|
|
16
19
|
/** The default: one instance, in memory. */
|
|
17
20
|
export function inProcessRelay() {
|
|
18
21
|
const connections = new Map();
|
|
22
|
+
const computers = new Map();
|
|
19
23
|
const turns = new Map();
|
|
20
24
|
const settled = new Set();
|
|
21
25
|
let closed = false;
|
|
@@ -35,21 +39,25 @@ export function inProcessRelay() {
|
|
|
35
39
|
};
|
|
36
40
|
const channel = {
|
|
37
41
|
event: CHAT_CHANNEL,
|
|
42
|
+
hosts: true,
|
|
38
43
|
connect(connection) {
|
|
39
44
|
if (closed || connection.closed?.aborted)
|
|
40
45
|
return () => { };
|
|
41
|
-
const
|
|
42
|
-
|
|
46
|
+
const { principal } = connection;
|
|
47
|
+
const [joined, key] = principal?.kind === "host"
|
|
48
|
+
? [computers, computerKey(connection.scope, principal.userId, principal.hostId)]
|
|
49
|
+
: [connections, ownerKey(connection.scope, userOf(principal))];
|
|
50
|
+
let audience = joined.get(key);
|
|
43
51
|
if (!audience) {
|
|
44
52
|
audience = new Set();
|
|
45
|
-
|
|
53
|
+
joined.set(key, audience);
|
|
46
54
|
}
|
|
47
55
|
audience.add(connection);
|
|
48
56
|
const detach = () => {
|
|
49
|
-
const current =
|
|
57
|
+
const current = joined.get(key);
|
|
50
58
|
current?.delete(connection);
|
|
51
59
|
if (current?.size === 0)
|
|
52
|
-
|
|
60
|
+
joined.delete(key);
|
|
53
61
|
connection.closed?.removeEventListener("abort", detach);
|
|
54
62
|
};
|
|
55
63
|
connection.closed?.addEventListener("abort", detach, { once: true });
|
|
@@ -109,6 +117,9 @@ export function inProcessRelay() {
|
|
|
109
117
|
forget(turnId);
|
|
110
118
|
push(owner, { type: "settled", threadId, turnId });
|
|
111
119
|
},
|
|
120
|
+
computer(owner, hostId) {
|
|
121
|
+
return [...(computers.get(computerKey(owner.scope, owner.userId, hostId)) ?? [])];
|
|
122
|
+
},
|
|
112
123
|
open(owner, threadId) {
|
|
113
124
|
const open = [];
|
|
114
125
|
for (const [turnId, state] of turns) {
|
|
@@ -123,6 +134,7 @@ export function inProcessRelay() {
|
|
|
123
134
|
close() {
|
|
124
135
|
closed = true;
|
|
125
136
|
connections.clear();
|
|
137
|
+
computers.clear();
|
|
126
138
|
turns.clear();
|
|
127
139
|
},
|
|
128
140
|
};
|
package/dist/server/live.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live.js","sourceRoot":"","sources":["../../src/server/live.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DEV_USER_ID,\n type ThreadId,\n type TurnId,\n type UserId,\n userOf,\n} from \"@parlor/core\";\nimport type { ChannelConnection, ServerChannel } from \"@parlor/sync\";\n\nimport type { ChatOwner, OpenItem, OpenTurn } from \"../model.js\";\nimport { applyFrame } from \"../open-turns.js\";\nimport { CHAT_CHANNEL, type ChatFrame, type HostStreamBatch } from \"../protocol.js\";\nimport type { TurnHolder } from \"./store.js\";\n\nexport const MAX_OPEN_BYTES_PER_TURN = 256 * 1024;\nexport const MAX_OPEN_TURNS = 1024;\n\n/**\n * The live half of the chat: what is streaming now, carried to the `chat` channel of the\n * owner's own streams. Nothing here is the truth; drop it and every client still\n * converges on the log, only without token streaming. So it writes nothing and can be\n * replaced by a relay that crosses instances.\n */\nexport interface LiveRelay {\n readonly channel: ServerChannel;\n /** Applies a batch to the open turn and pushes it; a turn over its byte budget stops streaming. */\n accept(turn: TurnHolder, batch: HostStreamBatch): void;\n settle(owner: ChatOwner, threadId: ThreadId, turnId: TurnId): void;\n open(owner: ChatOwner, threadId: ThreadId): readonly OpenTurn[];\n close(): void;\n}\n\ninterface OpenState {\n readonly owner: ChatOwner;\n readonly threadId: ThreadId;\n items: readonly OpenItem[];\n bytes: number;\n overBudget: boolean;\n}\n\nconst SETTLED_MEMORY = 4 * MAX_OPEN_TURNS;\nconst encoder = new TextEncoder();\n\nfunction ownerKey(scope: string, userId: UserId | undefined): string {\n return `${scope}\\u001f${userId ?? DEV_USER_ID}`;\n}\n\nfunction sizeOf(frame: Extract<ChatFrame, { type: \"delta\" | \"item\" }>): number {\n return frame.type === \"delta\"\n ? encoder.encode(frame.text).length\n : encoder.encode(JSON.stringify(frame.item)).length;\n}\n\n/** The default: one instance, in memory. */\nexport function inProcessRelay(): LiveRelay {\n const connections = new Map<string, Set<ChannelConnection>>();\n const turns = new Map<TurnId, OpenState>();\n const settled = new Set<TurnId>();\n let closed = false;\n\n const push = (owner: ChatOwner, frame: ChatFrame) => {\n const audience = connections.get(ownerKey(owner.scope, owner.userId));\n if (!audience || audience.size === 0) return;\n const data = JSON.stringify(frame);\n for (const connection of audience) {\n try {\n connection.send(data);\n } catch {\n audience.delete(connection);\n }\n }\n };\n\n const channel: ServerChannel = {\n event: CHAT_CHANNEL,\n connect(connection) {\n if (closed || connection.closed?.aborted) return () => {};\n const key = ownerKey(connection.scope, userOf(connection.principal));\n let audience = connections.get(key);\n if (!audience) {\n audience = new Set();\n connections.set(key, audience);\n }\n audience.add(connection);\n const detach = () => {\n const current = connections.get(key);\n current?.delete(connection);\n if (current?.size === 0) connections.delete(key);\n connection.closed?.removeEventListener(\"abort\", detach);\n };\n connection.closed?.addEventListener(\"abort\", detach, { once: true });\n return detach;\n },\n };\n\n const forget = (turnId: TurnId) => {\n turns.delete(turnId);\n settled.add(turnId);\n if (settled.size > SETTLED_MEMORY) {\n const oldest = settled.values().next();\n if (!oldest.done) settled.delete(oldest.value);\n }\n };\n\n return {\n channel,\n accept(holder, batch) {\n if (closed || settled.has(batch.turnId)) return;\n let state = turns.get(batch.turnId);\n if (!state) {\n if (turns.size >= MAX_OPEN_TURNS) {\n const oldest = turns.keys().next();\n if (!oldest.done) turns.delete(oldest.value);\n }\n state = {\n owner: holder.owner,\n threadId: holder.threadId,\n items: [],\n bytes: 0,\n overBudget: false,\n };\n turns.set(batch.turnId, state);\n }\n for (const hostFrame of batch.frames) {\n const frame: Extract<ChatFrame, { type: \"delta\" | \"item\" }> = {\n ...hostFrame,\n threadId: state.threadId,\n turnId: batch.turnId,\n };\n const cost = sizeOf(frame);\n if (state.overBudget || state.bytes + cost > MAX_OPEN_BYTES_PER_TURN) {\n state.overBudget = true;\n break;\n }\n const applied = applyFrame(state.items, frame);\n if (!applied) continue;\n state.items = applied.items;\n state.bytes += cost;\n push(state.owner, applied.frame);\n }\n },\n settle(owner, threadId, turnId) {\n forget(turnId);\n push(owner, { type: \"settled\", threadId, turnId });\n },\n open(owner, threadId) {\n const open: OpenTurn[] = [];\n for (const [turnId, state] of turns) {\n if (\n state.threadId === threadId &&\n state.owner.scope === owner.scope &&\n state.owner.userId === owner.userId\n ) {\n open.push({ turnId, threadId, items: state.items });\n }\n }\n return open;\n },\n close() {\n closed = true;\n connections.clear();\n turns.clear();\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"live.js","sourceRoot":"","sources":["../../src/server/live.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DEV_USER_ID,\n type HostId,\n type ThreadId,\n type TurnId,\n type UserId,\n userOf,\n} from \"@parlor/core\";\nimport type { ChannelConnection, ServerChannel } from \"@parlor/sync\";\n\nimport type { ChatOwner, OpenItem, OpenTurn } from \"../model.js\";\nimport { applyFrame } from \"../open-turns.js\";\nimport { CHAT_CHANNEL, type ChatFrame, type HostStreamBatch } from \"../protocol.js\";\nimport type { TurnHolder } from \"./store.js\";\n\nexport const MAX_OPEN_BYTES_PER_TURN = 256 * 1024;\nexport const MAX_OPEN_TURNS = 1024;\n\n/**\n * The live half of the chat: what is streaming now, carried to the `chat` channel of the\n * owner's own streams. Nothing here is the truth; drop it and every client still\n * converges on the log, only without token streaming. So it writes nothing and can be\n * replaced by a relay that crosses instances.\n */\nexport interface LiveRelay {\n readonly channel: ServerChannel;\n /** Applies a batch to the open turn and pushes it; a turn over its byte budget stops streaming. */\n accept(turn: TurnHolder, batch: HostStreamBatch): void;\n settle(owner: ChatOwner, threadId: ThreadId, turnId: TurnId): void;\n open(owner: ChatOwner, threadId: ThreadId): readonly OpenTurn[];\n /**\n * The open streams of one of the owner's computers, by its principal: a turn pushed to it\n * goes to these only, never to the user's tabs.\n */\n computer(owner: ChatOwner, hostId: HostId): readonly ChannelConnection[];\n close(): void;\n}\n\ninterface OpenState {\n readonly owner: ChatOwner;\n readonly threadId: ThreadId;\n items: readonly OpenItem[];\n bytes: number;\n overBudget: boolean;\n}\n\nconst SETTLED_MEMORY = 4 * MAX_OPEN_TURNS;\nconst encoder = new TextEncoder();\n\nfunction ownerKey(scope: string, userId: UserId | undefined): string {\n return `${scope}\\u001f${userId ?? DEV_USER_ID}`;\n}\n\nfunction computerKey(scope: string, userId: UserId, hostId: HostId): string {\n return `${ownerKey(scope, userId)}\\u001f${hostId}`;\n}\n\nfunction sizeOf(frame: Extract<ChatFrame, { type: \"delta\" | \"item\" }>): number {\n return frame.type === \"delta\"\n ? encoder.encode(frame.text).length\n : encoder.encode(JSON.stringify(frame.item)).length;\n}\n\n/** The default: one instance, in memory. */\nexport function inProcessRelay(): LiveRelay {\n const connections = new Map<string, Set<ChannelConnection>>();\n const computers = new Map<string, Set<ChannelConnection>>();\n const turns = new Map<TurnId, OpenState>();\n const settled = new Set<TurnId>();\n let closed = false;\n\n const push = (owner: ChatOwner, frame: ChatFrame) => {\n const audience = connections.get(ownerKey(owner.scope, owner.userId));\n if (!audience || audience.size === 0) return;\n const data = JSON.stringify(frame);\n for (const connection of audience) {\n try {\n connection.send(data);\n } catch {\n audience.delete(connection);\n }\n }\n };\n\n const channel: ServerChannel = {\n event: CHAT_CHANNEL,\n hosts: true,\n connect(connection) {\n if (closed || connection.closed?.aborted) return () => {};\n const { principal } = connection;\n const [joined, key] =\n principal?.kind === \"host\"\n ? [computers, computerKey(connection.scope, principal.userId, principal.hostId)]\n : [connections, ownerKey(connection.scope, userOf(principal))];\n let audience = joined.get(key);\n if (!audience) {\n audience = new Set();\n joined.set(key, audience);\n }\n audience.add(connection);\n const detach = () => {\n const current = joined.get(key);\n current?.delete(connection);\n if (current?.size === 0) joined.delete(key);\n connection.closed?.removeEventListener(\"abort\", detach);\n };\n connection.closed?.addEventListener(\"abort\", detach, { once: true });\n return detach;\n },\n };\n\n const forget = (turnId: TurnId) => {\n turns.delete(turnId);\n settled.add(turnId);\n if (settled.size > SETTLED_MEMORY) {\n const oldest = settled.values().next();\n if (!oldest.done) settled.delete(oldest.value);\n }\n };\n\n return {\n channel,\n accept(holder, batch) {\n if (closed || settled.has(batch.turnId)) return;\n let state = turns.get(batch.turnId);\n if (!state) {\n if (turns.size >= MAX_OPEN_TURNS) {\n const oldest = turns.keys().next();\n if (!oldest.done) turns.delete(oldest.value);\n }\n state = {\n owner: holder.owner,\n threadId: holder.threadId,\n items: [],\n bytes: 0,\n overBudget: false,\n };\n turns.set(batch.turnId, state);\n }\n for (const hostFrame of batch.frames) {\n const frame: Extract<ChatFrame, { type: \"delta\" | \"item\" }> = {\n ...hostFrame,\n threadId: state.threadId,\n turnId: batch.turnId,\n };\n const cost = sizeOf(frame);\n if (state.overBudget || state.bytes + cost > MAX_OPEN_BYTES_PER_TURN) {\n state.overBudget = true;\n break;\n }\n const applied = applyFrame(state.items, frame);\n if (!applied) continue;\n state.items = applied.items;\n state.bytes += cost;\n push(state.owner, applied.frame);\n }\n },\n settle(owner, threadId, turnId) {\n forget(turnId);\n push(owner, { type: \"settled\", threadId, turnId });\n },\n computer(owner, hostId) {\n return [...(computers.get(computerKey(owner.scope, owner.userId, hostId)) ?? [])];\n },\n open(owner, threadId) {\n const open: OpenTurn[] = [];\n for (const [turnId, state] of turns) {\n if (\n state.threadId === threadId &&\n state.owner.scope === owner.scope &&\n state.owner.userId === owner.userId\n ) {\n open.push({ turnId, threadId, items: state.items });\n }\n }\n return open;\n },\n close() {\n closed = true;\n connections.clear();\n computers.clear();\n turns.clear();\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { HostId, TurnId } from "@parlor/core";
|
|
2
|
+
import type { ChatOwner } from "../model.js";
|
|
3
|
+
import type { HostSession } from "./actions.js";
|
|
4
|
+
import type { LiveRelay } from "./live.js";
|
|
5
|
+
import type { ChatDb } from "./store.js";
|
|
6
|
+
/** How long a pushed turn waits for its computer to confirm it before it goes back to the queue. */
|
|
7
|
+
export declare const PICKUP_MS = 5000;
|
|
8
|
+
/**
|
|
9
|
+
* Hands a turn to its computer the moment it is queued, saving the computer the round trip
|
|
10
|
+
* of being woken and claiming it. Best effort: a turn it cannot push, or that the computer
|
|
11
|
+
* never confirms, stays with or goes back to `hostClaim`.
|
|
12
|
+
*/
|
|
13
|
+
export interface TurnPush {
|
|
14
|
+
/** A turn was just queued for `hostId`; claims it and pushes it if the computer is listening. */
|
|
15
|
+
offer(owner: ChatOwner, hostId: HostId): void;
|
|
16
|
+
/** The computer called about `turnId`, so it has the turn. */
|
|
17
|
+
confirm(turnId: TurnId): void;
|
|
18
|
+
close(): void;
|
|
19
|
+
}
|
|
20
|
+
export declare function turnPush(deps: {
|
|
21
|
+
readonly relay: LiveRelay;
|
|
22
|
+
readonly session: HostSession;
|
|
23
|
+
readonly db: () => ChatDb;
|
|
24
|
+
readonly pickupMs?: number | undefined;
|
|
25
|
+
}): TurnPush;
|
|
26
|
+
//# sourceMappingURL=push.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/server/push.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,oGAAoG;AACpG,eAAO,MAAM,SAAS,OAAQ,CAAC;AAE/B;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,iGAAiG;IACjG,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,8DAA8D;IAC9D,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,KAAK,IAAI,IAAI,CAAC;CACf;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC,GAAG,QAAQ,CAoDX"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** How long a pushed turn waits for its computer to confirm it before it goes back to the queue. */
|
|
2
|
+
export const PICKUP_MS = 5_000;
|
|
3
|
+
export function turnPush(deps) {
|
|
4
|
+
const unconfirmed = new Map();
|
|
5
|
+
const push = async (owner, hostId) => {
|
|
6
|
+
// The newest stream: during a handover the older one belongs to a draining service.
|
|
7
|
+
const connection = deps.relay.computer(owner, hostId).at(-1);
|
|
8
|
+
const principal = connection?.principal;
|
|
9
|
+
if (!connection || principal?.kind !== "host")
|
|
10
|
+
return;
|
|
11
|
+
const host = {
|
|
12
|
+
scope: connection.scope,
|
|
13
|
+
userId: principal.userId,
|
|
14
|
+
host: principal,
|
|
15
|
+
};
|
|
16
|
+
const turn = await deps.session.claim(host, deps.db());
|
|
17
|
+
if (!turn)
|
|
18
|
+
return;
|
|
19
|
+
const frame = { type: "claimed", turn };
|
|
20
|
+
try {
|
|
21
|
+
connection.send(JSON.stringify(frame));
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
await deps.session.release(host, turn.id, turn.turnId);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const timer = setTimeout(() => {
|
|
28
|
+
unconfirmed.delete(turn.turnId);
|
|
29
|
+
deps.session.release(host, turn.id, turn.turnId).catch((error) => {
|
|
30
|
+
console.warn("[parlor] chat: returning an unconfirmed turn failed:", error);
|
|
31
|
+
});
|
|
32
|
+
}, deps.pickupMs ?? PICKUP_MS);
|
|
33
|
+
timer.unref?.();
|
|
34
|
+
unconfirmed.set(turn.turnId, timer);
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
offer(owner, hostId) {
|
|
38
|
+
push(owner, hostId).catch((error) => {
|
|
39
|
+
console.warn("[parlor] chat: pushing a turn failed; its computer claims it:", error);
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
confirm(turnId) {
|
|
43
|
+
const timer = unconfirmed.get(turnId);
|
|
44
|
+
if (!timer)
|
|
45
|
+
return;
|
|
46
|
+
clearTimeout(timer);
|
|
47
|
+
unconfirmed.delete(turnId);
|
|
48
|
+
},
|
|
49
|
+
close() {
|
|
50
|
+
for (const timer of unconfirmed.values())
|
|
51
|
+
clearTimeout(timer);
|
|
52
|
+
unconfirmed.clear();
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=push.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/server/push.ts"],"names":[],"mappings":"AASA,oGAAoG;AACpG,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAC;AAe/B,MAAM,UAAU,QAAQ,CAAC,IAKxB;IACC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAyC,CAAC;IAErE,MAAM,IAAI,GAAG,KAAK,EAAE,KAAgB,EAAE,MAAc,EAAE,EAAE;QACtD,oFAAoF;QACpF,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7D,MAAM,SAAS,GAAG,UAAU,EAAE,SAAS,CAAC;QACxC,IAAI,CAAC,UAAU,IAAI,SAAS,EAAE,IAAI,KAAK,MAAM;YAAE,OAAO;QACtD,MAAM,IAAI,GAAa;YACrB,KAAK,EAAE,UAAU,CAAC,KAAK;YACvB,MAAM,EAAE,SAAS,CAAC,MAAM;YACxB,IAAI,EAAE,SAAS;SAChB,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACvD,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,MAAM,KAAK,GAAe,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QACpD,IAAI,CAAC;YACH,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACvD,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAChC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;gBACxE,OAAO,CAAC,IAAI,CAAC,sDAAsD,EAAE,KAAK,CAAC,CAAC;YAC9E,CAAC,CAAC,CAAC;QACL,CAAC,EAAE,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC,CAAC;QAC9B,KAAgC,CAAC,KAAK,EAAE,EAAE,CAAC;QAC5C,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,CAAC,KAAK,EAAE,MAAM;YACjB,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;gBAC3C,OAAO,CAAC,IAAI,CACV,+DAA+D,EAC/D,KAAK,CACN,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,CAAC,MAAM;YACZ,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACtC,IAAI,CAAC,KAAK;gBAAE,OAAO;YACnB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC;QACD,KAAK;YACH,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;YAC9D,WAAW,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { HostId, TurnId } from \"@parlor/core\";\n\nimport type { ChatOwner } from \"../model.js\";\nimport type { PushedTurn } from \"../protocol.js\";\nimport type { HostSession } from \"./actions.js\";\nimport type { LiveRelay } from \"./live.js\";\nimport type { ChatHost } from \"./party.js\";\nimport type { ChatDb } from \"./store.js\";\n\n/** How long a pushed turn waits for its computer to confirm it before it goes back to the queue. */\nexport const PICKUP_MS = 5_000;\n\n/**\n * Hands a turn to its computer the moment it is queued, saving the computer the round trip\n * of being woken and claiming it. Best effort: a turn it cannot push, or that the computer\n * never confirms, stays with or goes back to `hostClaim`.\n */\nexport interface TurnPush {\n /** A turn was just queued for `hostId`; claims it and pushes it if the computer is listening. */\n offer(owner: ChatOwner, hostId: HostId): void;\n /** The computer called about `turnId`, so it has the turn. */\n confirm(turnId: TurnId): void;\n close(): void;\n}\n\nexport function turnPush(deps: {\n readonly relay: LiveRelay;\n readonly session: HostSession;\n readonly db: () => ChatDb;\n readonly pickupMs?: number | undefined;\n}): TurnPush {\n const unconfirmed = new Map<TurnId, ReturnType<typeof setTimeout>>();\n\n const push = async (owner: ChatOwner, hostId: HostId) => {\n // The newest stream: during a handover the older one belongs to a draining service.\n const connection = deps.relay.computer(owner, hostId).at(-1);\n const principal = connection?.principal;\n if (!connection || principal?.kind !== \"host\") return;\n const host: ChatHost = {\n scope: connection.scope,\n userId: principal.userId,\n host: principal,\n };\n const turn = await deps.session.claim(host, deps.db());\n if (!turn) return;\n const frame: PushedTurn = { type: \"claimed\", turn };\n try {\n connection.send(JSON.stringify(frame));\n } catch {\n await deps.session.release(host, turn.id, turn.turnId);\n return;\n }\n const timer = setTimeout(() => {\n unconfirmed.delete(turn.turnId);\n deps.session.release(host, turn.id, turn.turnId).catch((error: unknown) => {\n console.warn(\"[parlor] chat: returning an unconfirmed turn failed:\", error);\n });\n }, deps.pickupMs ?? PICKUP_MS);\n (timer as { unref?: () => void }).unref?.();\n unconfirmed.set(turn.turnId, timer);\n };\n\n return {\n offer(owner, hostId) {\n push(owner, hostId).catch((error: unknown) => {\n console.warn(\n \"[parlor] chat: pushing a turn failed; its computer claims it:\",\n error,\n );\n });\n },\n confirm(turnId) {\n const timer = unconfirmed.get(turnId);\n if (!timer) return;\n clearTimeout(timer);\n unconfirmed.delete(turnId);\n },\n close() {\n for (const timer of unconfirmed.values()) clearTimeout(timer);\n unconfirmed.clear();\n },\n };\n}\n"]}
|
package/dist/server/rows.d.ts
CHANGED
|
@@ -7,6 +7,27 @@ export declare const agentInfoSchema: z.ZodObject<{
|
|
|
7
7
|
version: z.ZodOptional<z.ZodString>;
|
|
8
8
|
ready: z.ZodBoolean;
|
|
9
9
|
problem: z.ZodOptional<z.ZodString>;
|
|
10
|
+
options: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
11
|
+
id: z.ZodString;
|
|
12
|
+
name: z.ZodString;
|
|
13
|
+
category: z.ZodOptional<z.ZodString>;
|
|
14
|
+
current: z.ZodString;
|
|
15
|
+
values: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
16
|
+
id: z.ZodString;
|
|
17
|
+
name: z.ZodString;
|
|
18
|
+
description: z.ZodOptional<z.ZodString>;
|
|
19
|
+
}, z.core.$strip>>>;
|
|
20
|
+
}, z.core.$strip>>>>;
|
|
21
|
+
usage: z.ZodOptional<z.ZodObject<{
|
|
22
|
+
windows: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
23
|
+
id: z.ZodString;
|
|
24
|
+
minutes: z.ZodNumber;
|
|
25
|
+
used: z.ZodNumber;
|
|
26
|
+
resetsAt: z.ZodOptional<z.ZodNumber>;
|
|
27
|
+
}, z.core.$strip>>>;
|
|
28
|
+
at: z.ZodNumber;
|
|
29
|
+
}, z.core.$strip>>;
|
|
30
|
+
outsideName: z.ZodOptional<z.ZodString>;
|
|
10
31
|
}, z.core.$strip>;
|
|
11
32
|
export declare const itemRow: z.ZodObject<{
|
|
12
33
|
id: z.ZodPipe<z.ZodString, z.ZodTransform<import("@parlor/core").Id<"item">, string>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rows.d.ts","sourceRoot":"","sources":["../../src/server/rows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAY,aAAa,EAA0B,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"rows.d.ts","sourceRoot":"","sources":["../../src/server/rows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAY,aAAa,EAA0B,MAAM,aAAa,CAAC;AAkCnF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAY1B,CAAC;AAgBH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;iBAQlB,CAAC;AAEH,wBAAgB,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,OAAO,CAAC,GAAG,UAAU,CAyEtE;AAED,eAAO,MAAM,SAAS;;;;;;;iBAOpB,CAAC;AAEH,wBAAgB,eAAe,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,SAAS,CAAC,GAAG,aAAa,CAY9E;AAED,eAAO,MAAM,aAAa,uHAOiB,CAAC;AAE5C,eAAO,MAAM,WAAW,YAAI,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAU,CAAC;AACzF,eAAO,MAAM,eAAe;;;;;;EAAqD,CAAC"}
|
package/dist/server/rows.js
CHANGED
|
@@ -1,12 +1,44 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { idSchema } from "../id-schemas.js";
|
|
3
3
|
import { chatItemBodies } from "../items.js";
|
|
4
|
+
const agentOptionSchema = z.object({
|
|
5
|
+
id: z.string().min(1).max(100),
|
|
6
|
+
name: z.string().max(100),
|
|
7
|
+
category: z.string().max(50).optional(),
|
|
8
|
+
current: z.string().max(200),
|
|
9
|
+
values: z
|
|
10
|
+
.array(z.object({
|
|
11
|
+
id: z.string().min(1).max(200),
|
|
12
|
+
name: z.string().max(200),
|
|
13
|
+
description: z.string().max(500).optional(),
|
|
14
|
+
}))
|
|
15
|
+
.max(50)
|
|
16
|
+
.readonly(),
|
|
17
|
+
});
|
|
18
|
+
const agentUsageSchema = z.object({
|
|
19
|
+
windows: z
|
|
20
|
+
.array(z.object({
|
|
21
|
+
id: z.string().min(1).max(50),
|
|
22
|
+
minutes: z.number().positive(),
|
|
23
|
+
used: z.number().min(0).max(1),
|
|
24
|
+
resetsAt: z.number().optional(),
|
|
25
|
+
}))
|
|
26
|
+
.max(10)
|
|
27
|
+
.readonly(),
|
|
28
|
+
at: z.number(),
|
|
29
|
+
});
|
|
4
30
|
export const agentInfoSchema = z.object({
|
|
5
31
|
id: z.string().min(1),
|
|
6
32
|
name: z.string(),
|
|
7
33
|
version: z.string().optional(),
|
|
8
34
|
ready: z.boolean(),
|
|
9
35
|
problem: z.string().optional(),
|
|
36
|
+
options: z.array(agentOptionSchema).max(10).readonly().optional(),
|
|
37
|
+
usage: agentUsageSchema.optional(),
|
|
38
|
+
outsideName: z
|
|
39
|
+
.string()
|
|
40
|
+
.regex(/^[a-z0-9][a-z0-9_-]{0,79}$/)
|
|
41
|
+
.optional(),
|
|
10
42
|
});
|
|
11
43
|
const ITEM_KINDS = [
|
|
12
44
|
"prompt",
|
package/dist/server/rows.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rows.js","sourceRoot":"","sources":["../../src/server/rows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAmB,MAAM,aAAa,CAAC;AAG9D,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE;IAClB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;
|
|
1
|
+
{"version":3,"file":"rows.js","sourceRoot":"","sources":["../../src/server/rows.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nimport { idSchema } from \"../id-schemas.js\";\nimport { chatItemBodies, type LoggedItem } from \"../items.js\";\nimport type { AgentRef, ThreadSummary, TurnFailure, TurnState } from \"../model.js\";\n\nconst agentOptionSchema = z.object({\n id: z.string().min(1).max(100),\n name: z.string().max(100),\n category: z.string().max(50).optional(),\n current: z.string().max(200),\n values: z\n .array(\n z.object({\n id: z.string().min(1).max(200),\n name: z.string().max(200),\n description: z.string().max(500).optional(),\n }),\n )\n .max(50)\n .readonly(),\n});\n\nconst agentUsageSchema = z.object({\n windows: z\n .array(\n z.object({\n id: z.string().min(1).max(50),\n minutes: z.number().positive(),\n used: z.number().min(0).max(1),\n resetsAt: z.number().optional(),\n }),\n )\n .max(10)\n .readonly(),\n at: z.number(),\n});\n\nexport const agentInfoSchema = z.object({\n id: z.string().min(1),\n name: z.string(),\n version: z.string().optional(),\n ready: z.boolean(),\n problem: z.string().optional(),\n options: z.array(agentOptionSchema).max(10).readonly().optional(),\n usage: agentUsageSchema.optional(),\n outsideName: z\n .string()\n .regex(/^[a-z0-9][a-z0-9_-]{0,79}$/)\n .optional(),\n});\n\nconst ITEM_KINDS = [\n \"prompt\",\n \"answer\",\n \"cancel\",\n \"reply\",\n \"reasoning\",\n \"tool\",\n \"plan\",\n \"ask\",\n \"event\",\n] as const;\n\nconst count = z.coerce.number();\n\nexport const itemRow = z.object({\n id: idSchema(\"item\"),\n thread_id: idSchema(\"thread\"),\n turn_id: idSchema(\"turn\"),\n seq: count,\n at: count,\n kind: z.enum(ITEM_KINDS),\n body: z.unknown(),\n});\n\nexport function toLoggedItem(row: z.output<typeof itemRow>): LoggedItem {\n const common = {\n id: row.id,\n threadId: row.thread_id,\n turnId: row.turn_id,\n seq: row.seq,\n at: row.at,\n };\n switch (row.kind) {\n case \"prompt\":\n return {\n ...common,\n author: \"user\",\n kind: \"prompt\",\n body: chatItemBodies.prompt.body.parse(row.body),\n };\n case \"answer\":\n return {\n ...common,\n author: \"user\",\n kind: \"answer\",\n body: chatItemBodies.answer.body.parse(row.body),\n };\n case \"cancel\":\n return {\n ...common,\n author: \"user\",\n kind: \"cancel\",\n body: chatItemBodies.cancel.body.parse(row.body),\n };\n case \"reply\":\n return {\n ...common,\n author: \"agent\",\n kind: \"reply\",\n body: chatItemBodies.reply.body.parse(row.body),\n };\n case \"reasoning\":\n return {\n ...common,\n author: \"agent\",\n kind: \"reasoning\",\n body: chatItemBodies.reasoning.body.parse(row.body),\n };\n case \"tool\":\n return {\n ...common,\n author: \"agent\",\n kind: \"tool\",\n body: chatItemBodies.tool.body.parse(row.body),\n };\n case \"plan\":\n return {\n ...common,\n author: \"agent\",\n kind: \"plan\",\n body: chatItemBodies.plan.body.parse(row.body),\n };\n case \"ask\":\n return {\n ...common,\n author: \"agent\",\n kind: \"ask\",\n body: chatItemBodies.ask.body.parse(row.body),\n };\n case \"event\":\n return {\n ...common,\n author: \"system\",\n kind: \"event\",\n body: chatItemBodies.event.body.parse(row.body),\n };\n }\n}\n\nexport const threadRow = z.object({\n id: idSchema(\"thread\"),\n title: z.string(),\n host_id: idSchema(\"host\").nullable(),\n agent_id: z.string().nullable(),\n last_seq: count,\n updated_at: count,\n});\n\nexport function toThreadSummary(row: z.output<typeof threadRow>): ThreadSummary {\n const agent: AgentRef | undefined =\n row.host_id !== null && row.agent_id !== null\n ? { hostId: row.host_id, agentId: row.agent_id }\n : undefined;\n return {\n id: row.id,\n title: row.title,\n agent,\n updatedAt: row.updated_at,\n lastSeq: row.last_seq,\n };\n}\n\nexport const TURN_FAILURES = [\n \"agent_exited\",\n \"agent_unavailable\",\n \"device_rejected\",\n \"signature_invalid\",\n \"prompt_expired\",\n \"host_lost\",\n] as const satisfies readonly TurnFailure[];\n\nexport const TURN_STATES = [\"queued\", \"running\", \"done\", \"failed\", \"cancelled\"] as const;\nexport const turnStateSchema = z.enum(TURN_STATES) satisfies z.ZodType<TurnState>;\n"]}
|
|
@@ -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
|
@@ -117,6 +117,9 @@ async function admitsUserItem(tx, threadId, turnId, draft) {
|
|
|
117
117
|
if (ask.approval === "presence" && signed?.signature.presence !== "user") {
|
|
118
118
|
throw new ActionError("forbidden", "This question needs a presence check.");
|
|
119
119
|
}
|
|
120
|
+
if (ask.approval === "device" && !signed) {
|
|
121
|
+
throw new ActionError("forbidden", "This question is answered on the device that asked it.");
|
|
122
|
+
}
|
|
120
123
|
const [state] = await query(tx, sql `select state from parlor_chat_turns where id = ${turnId} for update`, z.object({ state: z.string() }));
|
|
121
124
|
const [standing] = await query(tx, sql `select a.id from parlor_chat_items a
|
|
122
125
|
where a.thread_id = ${threadId} and a.kind = 'answer' and a.body->>'askId' = ${askId}
|