@parlor/chat 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +23 -2
- package/dist/events.d.ts +4 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +12 -0
- package/dist/events.js.map +1 -0
- package/dist/id-schemas.d.ts +5 -0
- package/dist/id-schemas.d.ts.map +1 -0
- package/dist/id-schemas.js +11 -0
- package/dist/id-schemas.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/items.d.ts +295 -0
- package/dist/items.d.ts.map +1 -0
- package/dist/items.js +113 -0
- package/dist/items.js.map +1 -0
- package/dist/limits.d.ts +4 -0
- package/dist/limits.d.ts.map +1 -0
- package/dist/limits.js +4 -0
- package/dist/limits.js.map +1 -0
- package/dist/model.d.ts +143 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +2 -0
- package/dist/model.js.map +1 -0
- package/dist/open-turns.d.ts +19 -0
- package/dist/open-turns.d.ts.map +1 -0
- package/dist/open-turns.js +31 -0
- package/dist/open-turns.js.map +1 -0
- package/dist/protocol.d.ts +69 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +80 -0
- package/dist/protocol.js.map +1 -0
- package/dist/server/actions.d.ts +561 -0
- package/dist/server/actions.d.ts.map +1 -0
- package/dist/server/actions.js +422 -0
- package/dist/server/actions.js.map +1 -0
- package/dist/server/context.d.ts +24 -0
- package/dist/server/context.d.ts.map +1 -0
- package/dist/server/context.js +77 -0
- package/dist/server/context.js.map +1 -0
- package/dist/server/index.d.ts +50 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +145 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/live.d.ts +24 -0
- package/dist/server/live.d.ts.map +1 -0
- package/dist/server/live.js +130 -0
- package/dist/server/live.js.map +1 -0
- package/dist/server/migrations.d.ts +3 -0
- package/dist/server/migrations.d.ts.map +1 -0
- package/dist/server/migrations.js +96 -0
- package/dist/server/migrations.js.map +1 -0
- package/dist/server/party.d.ts +24 -0
- package/dist/server/party.d.ts.map +1 -0
- package/dist/server/party.js +38 -0
- package/dist/server/party.js.map +1 -0
- package/dist/server/routes.d.ts +17 -0
- package/dist/server/routes.d.ts.map +1 -0
- package/dist/server/routes.js +105 -0
- package/dist/server/routes.js.map +1 -0
- package/dist/server/rows.d.ts +49 -0
- package/dist/server/rows.d.ts.map +1 -0
- package/dist/server/rows.js +136 -0
- package/dist/server/rows.js.map +1 -0
- package/dist/server/store.d.ts +130 -0
- package/dist/server/store.d.ts.map +1 -0
- package/dist/server/store.js +539 -0
- package/dist/server/store.js.map +1 -0
- package/dist/tags.d.ts +7 -0
- package/dist/tags.d.ts.map +1 -0
- package/dist/tags.js +7 -0
- package/dist/tags.js.map +1 -0
- package/dist/testing/index.d.ts +46 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +96 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/view.d.ts +87 -0
- package/dist/view.d.ts.map +1 -0
- package/dist/view.js +236 -0
- package/dist/view.js.map +1 -0
- package/package.json +47 -3
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { ActionError } from "@parlor/core";
|
|
2
|
+
import { pluginRoute, readBoundedText } from "@parlor/server";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { idSchema } from "../id-schemas.js";
|
|
5
|
+
export const MAX_STREAM_BODY_BYTES = 64 * 1024;
|
|
6
|
+
const MAX_FRAMES_PER_BATCH = 512;
|
|
7
|
+
const streamBatch = z.object({
|
|
8
|
+
turnId: idSchema("turn"),
|
|
9
|
+
frames: z
|
|
10
|
+
.array(z.discriminatedUnion("type", [
|
|
11
|
+
z.object({
|
|
12
|
+
type: z.literal("delta"),
|
|
13
|
+
itemId: idSchema("item"),
|
|
14
|
+
kind: z.enum(["reply", "reasoning"]),
|
|
15
|
+
offset: z.number().int().min(0),
|
|
16
|
+
text: z.string(),
|
|
17
|
+
}),
|
|
18
|
+
z.object({
|
|
19
|
+
type: z.literal("item"),
|
|
20
|
+
item: z.discriminatedUnion("kind", [
|
|
21
|
+
z.object({
|
|
22
|
+
id: idSchema("item"),
|
|
23
|
+
kind: z.literal("tool"),
|
|
24
|
+
title: z.string(),
|
|
25
|
+
status: z.enum(["pending", "running"]),
|
|
26
|
+
}),
|
|
27
|
+
z.object({
|
|
28
|
+
id: idSchema("item"),
|
|
29
|
+
kind: z.literal("plan"),
|
|
30
|
+
entries: z.array(z.object({
|
|
31
|
+
content: z.string(),
|
|
32
|
+
status: z.enum(["pending", "in_progress", "completed"]),
|
|
33
|
+
})),
|
|
34
|
+
}),
|
|
35
|
+
]),
|
|
36
|
+
}),
|
|
37
|
+
]))
|
|
38
|
+
.max(MAX_FRAMES_PER_BATCH),
|
|
39
|
+
});
|
|
40
|
+
const tooLarge = () => Response.json({
|
|
41
|
+
error: {
|
|
42
|
+
code: "invalid_input",
|
|
43
|
+
message: `A stream batch is at most ${MAX_STREAM_BODY_BYTES} bytes.`,
|
|
44
|
+
},
|
|
45
|
+
}, { status: 413 });
|
|
46
|
+
/** Plain routes only a host principal reaches, by type: no browser session, no agent token. */
|
|
47
|
+
export function chatRoutes(deps) {
|
|
48
|
+
return [
|
|
49
|
+
pluginRoute({
|
|
50
|
+
method: "POST",
|
|
51
|
+
path: "/stream",
|
|
52
|
+
access: ["host"],
|
|
53
|
+
handle: async (request, caller) => {
|
|
54
|
+
const text = await readBoundedText(request, MAX_STREAM_BODY_BYTES);
|
|
55
|
+
if (text === undefined)
|
|
56
|
+
return tooLarge();
|
|
57
|
+
const parsed = streamBatch.safeParse(parseJson(text));
|
|
58
|
+
if (!parsed.success) {
|
|
59
|
+
throw new ActionError("invalid_input", "Not a stream batch", {
|
|
60
|
+
issues: parsed.error.issues,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
const batch = parsed.data;
|
|
64
|
+
const holder = await deps.store.turnHolder(deps.db(), batch.turnId);
|
|
65
|
+
const { principal } = caller;
|
|
66
|
+
const owns = holder !== undefined &&
|
|
67
|
+
holder.hostId === principal.hostId &&
|
|
68
|
+
holder.owner.userId === principal.userId &&
|
|
69
|
+
holder.owner.scope === caller.scope;
|
|
70
|
+
if (!owns)
|
|
71
|
+
throw new ActionError("forbidden", "This turn is not yours.");
|
|
72
|
+
const { live, ...heldBy } = holder;
|
|
73
|
+
if (!live)
|
|
74
|
+
throw new ActionError("forbidden", "The turn is not running.");
|
|
75
|
+
deps.relay.accept(heldBy, batch);
|
|
76
|
+
return new Response(null, { status: 204 });
|
|
77
|
+
},
|
|
78
|
+
}),
|
|
79
|
+
pluginRoute({
|
|
80
|
+
method: "POST",
|
|
81
|
+
path: "/heartbeat",
|
|
82
|
+
access: ["host"],
|
|
83
|
+
handle: async (_request, caller) => {
|
|
84
|
+
const { principal } = caller;
|
|
85
|
+
const owner = { scope: caller.scope, userId: principal.userId };
|
|
86
|
+
const { returned } = await deps.store.heartbeat(deps.db(), owner, principal, 2 * deps.heartbeatMs);
|
|
87
|
+
if (returned)
|
|
88
|
+
await deps.announceHost(owner, principal.hostId);
|
|
89
|
+
await deps.reconcile(owner).catch((error) => {
|
|
90
|
+
console.warn("[parlor] chat: reconciling lapsed turns failed:", error);
|
|
91
|
+
});
|
|
92
|
+
return new Response(null, { status: 204 });
|
|
93
|
+
},
|
|
94
|
+
}),
|
|
95
|
+
];
|
|
96
|
+
}
|
|
97
|
+
function parseJson(text) {
|
|
98
|
+
try {
|
|
99
|
+
return JSON.parse(text);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
throw new ActionError("invalid_input", "Request body must be JSON");
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/server/routes.ts"],"names":[],"mappings":"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","sourcesContent":["import { ActionError, type HostId } from \"@parlor/core\";\nimport { type AnyPluginRoute, pluginRoute, readBoundedText } from \"@parlor/server\";\nimport { z } from \"zod\";\n\nimport { idSchema } from \"../id-schemas.js\";\nimport type { ChatOwner } from \"../model.js\";\nimport type { HostStreamBatch } from \"../protocol.js\";\nimport type { LiveRelay } from \"./live.js\";\nimport type { ChatDb, ChatStore } from \"./store.js\";\n\nexport const MAX_STREAM_BODY_BYTES = 64 * 1024;\nconst MAX_FRAMES_PER_BATCH = 512;\n\nexport interface ChatRouteDeps {\n readonly db: () => ChatDb;\n readonly store: ChatStore;\n readonly relay: LiveRelay;\n readonly heartbeatMs: number;\n readonly reconcile: (owner: ChatOwner) => Promise<void>;\n readonly announceHost: (owner: ChatOwner, hostId: HostId) => Promise<void>;\n}\n\nconst streamBatch = z.object({\n turnId: idSchema(\"turn\"),\n frames: z\n .array(\n z.discriminatedUnion(\"type\", [\n z.object({\n type: z.literal(\"delta\"),\n itemId: idSchema(\"item\"),\n kind: z.enum([\"reply\", \"reasoning\"]),\n offset: z.number().int().min(0),\n text: z.string(),\n }),\n z.object({\n type: z.literal(\"item\"),\n item: z.discriminatedUnion(\"kind\", [\n z.object({\n id: idSchema(\"item\"),\n kind: z.literal(\"tool\"),\n title: z.string(),\n status: z.enum([\"pending\", \"running\"]),\n }),\n z.object({\n id: idSchema(\"item\"),\n kind: z.literal(\"plan\"),\n entries: z.array(\n z.object({\n content: z.string(),\n status: z.enum([\"pending\", \"in_progress\", \"completed\"]),\n }),\n ),\n }),\n ]),\n }),\n ]),\n )\n .max(MAX_FRAMES_PER_BATCH),\n}) satisfies z.ZodType<HostStreamBatch>;\n\nconst tooLarge = () =>\n Response.json(\n {\n error: {\n code: \"invalid_input\",\n message: `A stream batch is at most ${MAX_STREAM_BODY_BYTES} bytes.`,\n },\n },\n { status: 413 },\n );\n\n/** Plain routes only a host principal reaches, by type: no browser session, no agent token. */\nexport function chatRoutes(deps: ChatRouteDeps): readonly AnyPluginRoute[] {\n return [\n pluginRoute({\n method: \"POST\",\n path: \"/stream\",\n access: [\"host\"],\n handle: async (request, caller) => {\n const text = await readBoundedText(request, MAX_STREAM_BODY_BYTES);\n if (text === undefined) return tooLarge();\n const parsed = streamBatch.safeParse(parseJson(text));\n if (!parsed.success) {\n throw new ActionError(\"invalid_input\", \"Not a stream batch\", {\n issues: parsed.error.issues,\n });\n }\n const batch = parsed.data;\n const holder = await deps.store.turnHolder(deps.db(), batch.turnId);\n const { principal } = caller;\n const owns =\n holder !== undefined &&\n holder.hostId === principal.hostId &&\n holder.owner.userId === principal.userId &&\n holder.owner.scope === caller.scope;\n if (!owns) throw new ActionError(\"forbidden\", \"This turn is not yours.\");\n const { live, ...heldBy } = holder;\n if (!live) throw new ActionError(\"forbidden\", \"The turn is not running.\");\n deps.relay.accept(heldBy, batch);\n return new Response(null, { status: 204 });\n },\n }),\n pluginRoute({\n method: \"POST\",\n path: \"/heartbeat\",\n access: [\"host\"],\n handle: async (_request, caller) => {\n const { principal } = caller;\n const owner = { scope: caller.scope, userId: principal.userId };\n const { returned } = await deps.store.heartbeat(\n deps.db(),\n owner,\n principal,\n 2 * deps.heartbeatMs,\n );\n if (returned) await deps.announceHost(owner, principal.hostId);\n await deps.reconcile(owner).catch((error: unknown) => {\n console.warn(\"[parlor] chat: reconciling lapsed turns failed:\", error);\n });\n return new Response(null, { status: 204 });\n },\n }),\n ];\n}\n\nfunction parseJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n throw new ActionError(\"invalid_input\", \"Request body must be JSON\");\n }\n}\n"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type LoggedItem } from "../items.js";
|
|
3
|
+
import type { ThreadSummary } from "../model.js";
|
|
4
|
+
export declare const agentInfoSchema: z.ZodObject<{
|
|
5
|
+
id: z.ZodString;
|
|
6
|
+
name: z.ZodString;
|
|
7
|
+
version: z.ZodOptional<z.ZodString>;
|
|
8
|
+
ready: z.ZodBoolean;
|
|
9
|
+
problem: z.ZodOptional<z.ZodString>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export declare const itemRow: z.ZodObject<{
|
|
12
|
+
id: z.ZodPipe<z.ZodString, z.ZodTransform<import("@parlor/core").Id<"item">, string>>;
|
|
13
|
+
thread_id: z.ZodPipe<z.ZodString, z.ZodTransform<import("@parlor/core").Id<"thread">, string>>;
|
|
14
|
+
turn_id: z.ZodPipe<z.ZodString, z.ZodTransform<import("@parlor/core").Id<"turn">, string>>;
|
|
15
|
+
seq: z.ZodCoercedNumber<unknown>;
|
|
16
|
+
at: z.ZodCoercedNumber<unknown>;
|
|
17
|
+
kind: z.ZodEnum<{
|
|
18
|
+
answer: "answer";
|
|
19
|
+
ask: "ask";
|
|
20
|
+
cancel: "cancel";
|
|
21
|
+
event: "event";
|
|
22
|
+
plan: "plan";
|
|
23
|
+
prompt: "prompt";
|
|
24
|
+
reasoning: "reasoning";
|
|
25
|
+
reply: "reply";
|
|
26
|
+
tool: "tool";
|
|
27
|
+
}>;
|
|
28
|
+
body: z.ZodUnknown;
|
|
29
|
+
}, z.core.$strip>;
|
|
30
|
+
export declare function toLoggedItem(row: z.output<typeof itemRow>): LoggedItem;
|
|
31
|
+
export declare const threadRow: z.ZodObject<{
|
|
32
|
+
id: z.ZodPipe<z.ZodString, z.ZodTransform<import("@parlor/core").Id<"thread">, string>>;
|
|
33
|
+
title: z.ZodString;
|
|
34
|
+
host_id: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<import("@parlor/core").Id<"host">, string>>>;
|
|
35
|
+
agent_id: z.ZodNullable<z.ZodString>;
|
|
36
|
+
last_seq: z.ZodCoercedNumber<unknown>;
|
|
37
|
+
updated_at: z.ZodCoercedNumber<unknown>;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
export declare function toThreadSummary(row: z.output<typeof threadRow>): ThreadSummary;
|
|
40
|
+
export declare const TURN_FAILURES: readonly ["agent_exited", "agent_unavailable", "device_rejected", "signature_invalid", "prompt_expired", "host_lost"];
|
|
41
|
+
export declare const TURN_STATES: readonly ["queued", "running", "done", "failed", "cancelled"];
|
|
42
|
+
export declare const turnStateSchema: z.ZodEnum<{
|
|
43
|
+
cancelled: "cancelled";
|
|
44
|
+
done: "done";
|
|
45
|
+
failed: "failed";
|
|
46
|
+
queued: "queued";
|
|
47
|
+
running: "running";
|
|
48
|
+
}>;
|
|
49
|
+
//# sourceMappingURL=rows.d.ts.map
|
|
@@ -0,0 +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;AAEnF,eAAO,MAAM,eAAe;;;;;;iBAM1B,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"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { idSchema } from "../id-schemas.js";
|
|
3
|
+
import { chatItemBodies } from "../items.js";
|
|
4
|
+
export const agentInfoSchema = z.object({
|
|
5
|
+
id: z.string().min(1),
|
|
6
|
+
name: z.string(),
|
|
7
|
+
version: z.string().optional(),
|
|
8
|
+
ready: z.boolean(),
|
|
9
|
+
problem: z.string().optional(),
|
|
10
|
+
});
|
|
11
|
+
const ITEM_KINDS = [
|
|
12
|
+
"prompt",
|
|
13
|
+
"answer",
|
|
14
|
+
"cancel",
|
|
15
|
+
"reply",
|
|
16
|
+
"reasoning",
|
|
17
|
+
"tool",
|
|
18
|
+
"plan",
|
|
19
|
+
"ask",
|
|
20
|
+
"event",
|
|
21
|
+
];
|
|
22
|
+
const count = z.coerce.number();
|
|
23
|
+
export const itemRow = z.object({
|
|
24
|
+
id: idSchema("item"),
|
|
25
|
+
thread_id: idSchema("thread"),
|
|
26
|
+
turn_id: idSchema("turn"),
|
|
27
|
+
seq: count,
|
|
28
|
+
at: count,
|
|
29
|
+
kind: z.enum(ITEM_KINDS),
|
|
30
|
+
body: z.unknown(),
|
|
31
|
+
});
|
|
32
|
+
export function toLoggedItem(row) {
|
|
33
|
+
const common = {
|
|
34
|
+
id: row.id,
|
|
35
|
+
threadId: row.thread_id,
|
|
36
|
+
turnId: row.turn_id,
|
|
37
|
+
seq: row.seq,
|
|
38
|
+
at: row.at,
|
|
39
|
+
};
|
|
40
|
+
switch (row.kind) {
|
|
41
|
+
case "prompt":
|
|
42
|
+
return {
|
|
43
|
+
...common,
|
|
44
|
+
author: "user",
|
|
45
|
+
kind: "prompt",
|
|
46
|
+
body: chatItemBodies.prompt.body.parse(row.body),
|
|
47
|
+
};
|
|
48
|
+
case "answer":
|
|
49
|
+
return {
|
|
50
|
+
...common,
|
|
51
|
+
author: "user",
|
|
52
|
+
kind: "answer",
|
|
53
|
+
body: chatItemBodies.answer.body.parse(row.body),
|
|
54
|
+
};
|
|
55
|
+
case "cancel":
|
|
56
|
+
return {
|
|
57
|
+
...common,
|
|
58
|
+
author: "user",
|
|
59
|
+
kind: "cancel",
|
|
60
|
+
body: chatItemBodies.cancel.body.parse(row.body),
|
|
61
|
+
};
|
|
62
|
+
case "reply":
|
|
63
|
+
return {
|
|
64
|
+
...common,
|
|
65
|
+
author: "agent",
|
|
66
|
+
kind: "reply",
|
|
67
|
+
body: chatItemBodies.reply.body.parse(row.body),
|
|
68
|
+
};
|
|
69
|
+
case "reasoning":
|
|
70
|
+
return {
|
|
71
|
+
...common,
|
|
72
|
+
author: "agent",
|
|
73
|
+
kind: "reasoning",
|
|
74
|
+
body: chatItemBodies.reasoning.body.parse(row.body),
|
|
75
|
+
};
|
|
76
|
+
case "tool":
|
|
77
|
+
return {
|
|
78
|
+
...common,
|
|
79
|
+
author: "agent",
|
|
80
|
+
kind: "tool",
|
|
81
|
+
body: chatItemBodies.tool.body.parse(row.body),
|
|
82
|
+
};
|
|
83
|
+
case "plan":
|
|
84
|
+
return {
|
|
85
|
+
...common,
|
|
86
|
+
author: "agent",
|
|
87
|
+
kind: "plan",
|
|
88
|
+
body: chatItemBodies.plan.body.parse(row.body),
|
|
89
|
+
};
|
|
90
|
+
case "ask":
|
|
91
|
+
return {
|
|
92
|
+
...common,
|
|
93
|
+
author: "agent",
|
|
94
|
+
kind: "ask",
|
|
95
|
+
body: chatItemBodies.ask.body.parse(row.body),
|
|
96
|
+
};
|
|
97
|
+
case "event":
|
|
98
|
+
return {
|
|
99
|
+
...common,
|
|
100
|
+
author: "system",
|
|
101
|
+
kind: "event",
|
|
102
|
+
body: chatItemBodies.event.body.parse(row.body),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
export const threadRow = z.object({
|
|
107
|
+
id: idSchema("thread"),
|
|
108
|
+
title: z.string(),
|
|
109
|
+
host_id: idSchema("host").nullable(),
|
|
110
|
+
agent_id: z.string().nullable(),
|
|
111
|
+
last_seq: count,
|
|
112
|
+
updated_at: count,
|
|
113
|
+
});
|
|
114
|
+
export function toThreadSummary(row) {
|
|
115
|
+
const agent = row.host_id !== null && row.agent_id !== null
|
|
116
|
+
? { hostId: row.host_id, agentId: row.agent_id }
|
|
117
|
+
: undefined;
|
|
118
|
+
return {
|
|
119
|
+
id: row.id,
|
|
120
|
+
title: row.title,
|
|
121
|
+
agent,
|
|
122
|
+
updatedAt: row.updated_at,
|
|
123
|
+
lastSeq: row.last_seq,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
export const TURN_FAILURES = [
|
|
127
|
+
"agent_exited",
|
|
128
|
+
"agent_unavailable",
|
|
129
|
+
"device_rejected",
|
|
130
|
+
"signature_invalid",
|
|
131
|
+
"prompt_expired",
|
|
132
|
+
"host_lost",
|
|
133
|
+
];
|
|
134
|
+
export const TURN_STATES = ["queued", "running", "done", "failed", "cancelled"];
|
|
135
|
+
export const turnStateSchema = z.enum(TURN_STATES);
|
|
136
|
+
//# sourceMappingURL=rows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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\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});\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"]}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { type DeviceId, type GrantId, type HostId, type HostPrincipal, type ThreadId, type TurnId } from "@parlor/core";
|
|
2
|
+
import type { PgDatabase, PgQueryResultHKT } from "drizzle-orm/pg-core";
|
|
3
|
+
import type { HostItemDraft, LoggedItem, UserItemKind } from "../items.js";
|
|
4
|
+
import type { AgentInfo, AgentRef, ChatOwner, ClaimedTurn, HostSummary, ThreadPage, ThreadSummary, TurnOutcome, TurnSignals, TurnStatus } from "../model.js";
|
|
5
|
+
export type ChatDb = PgDatabase<PgQueryResultHKT>;
|
|
6
|
+
export type UserDraft = {
|
|
7
|
+
[K in UserItemKind]: {
|
|
8
|
+
readonly id: LoggedItem<K>["id"];
|
|
9
|
+
readonly kind: K;
|
|
10
|
+
readonly body: LoggedItem<K>["body"];
|
|
11
|
+
};
|
|
12
|
+
}[UserItemKind];
|
|
13
|
+
export interface NewTurn {
|
|
14
|
+
readonly turnId: TurnId;
|
|
15
|
+
readonly agent: AgentRef;
|
|
16
|
+
readonly clientId: string;
|
|
17
|
+
readonly deviceId: DeviceId | undefined;
|
|
18
|
+
/** The most turns a thread may have waiting; checked under the thread's lock. */
|
|
19
|
+
readonly maxQueued: number;
|
|
20
|
+
}
|
|
21
|
+
export interface TurnHolder {
|
|
22
|
+
readonly owner: ChatOwner;
|
|
23
|
+
readonly threadId: ThreadId;
|
|
24
|
+
readonly hostId: HostId;
|
|
25
|
+
}
|
|
26
|
+
/** A turn's holder with whether it runs now: running, and its lease not yet lapsed. */
|
|
27
|
+
export interface StreamTurn extends TurnHolder {
|
|
28
|
+
readonly live: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** What one reconciliation changed in a scope, for the sync events it must emit. */
|
|
31
|
+
export interface OlderItems {
|
|
32
|
+
readonly items: readonly LoggedItem[];
|
|
33
|
+
readonly turns: readonly TurnStatus[];
|
|
34
|
+
readonly hasMore: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface ThreadCursor {
|
|
37
|
+
readonly updatedAt: number;
|
|
38
|
+
readonly id: ThreadId;
|
|
39
|
+
}
|
|
40
|
+
export interface OlderThreads {
|
|
41
|
+
readonly threads: readonly ThreadSummary[];
|
|
42
|
+
readonly hasMore: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface Lapsed extends ChatOwner {
|
|
45
|
+
readonly threads: readonly ThreadId[];
|
|
46
|
+
readonly hosts: readonly HostId[];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The thread log in SQL. Every function filters by the owner's scope and user in the same
|
|
50
|
+
* statement, so another user's thread id reads as not found. Appends lock the thread row
|
|
51
|
+
* to assign gap-free `seq` and run in the action's transaction so the thread's sync event
|
|
52
|
+
* commits with them.
|
|
53
|
+
*/
|
|
54
|
+
export interface ChatStore {
|
|
55
|
+
listThreads(db: ChatDb, owner: ChatOwner): Promise<ThreadSummary[]>;
|
|
56
|
+
readPage(db: ChatDb, owner: ChatOwner, threadId: ThreadId | undefined, limit: number): Promise<Omit<ThreadPage, "open">>;
|
|
57
|
+
/** Items before `beforeSeq`, oldest first, with their turns; `hasMore` while older ones remain. */
|
|
58
|
+
readItemsBefore?(db: ChatDb, owner: ChatOwner, threadId: ThreadId, beforeSeq: number, limit: number): Promise<OlderItems>;
|
|
59
|
+
/** Threads updated before `before`, newest first, after the ones `listThreads` returned. */
|
|
60
|
+
listThreadsBefore?(db: ChatDb, owner: ChatOwner, before: ThreadCursor, limit: number): Promise<OlderThreads>;
|
|
61
|
+
readItemsAfter(db: ChatDb, owner: ChatOwner, threadId: ThreadId, afterSeq: number): Promise<LoggedItem[]>;
|
|
62
|
+
/** With `turn`, also queues it; the thread is created on its first prompt. */
|
|
63
|
+
appendUserItems(tx: ChatDb, owner: ChatOwner, input: {
|
|
64
|
+
readonly threadId: ThreadId;
|
|
65
|
+
readonly turnId: TurnId;
|
|
66
|
+
readonly items: readonly UserDraft[];
|
|
67
|
+
readonly turn?: NewTurn | undefined;
|
|
68
|
+
}): Promise<LoggedItem[]>;
|
|
69
|
+
claimTurn(tx: ChatDb, owner: ChatOwner, host: HostPrincipal, leaseMs: number): Promise<Omit<ClaimedTurn, "context" | "token" | "device"> | undefined>;
|
|
70
|
+
/** Whether anything waits for `expireLapsed`; one read, so the idle path writes nothing. */
|
|
71
|
+
hasLapsed(db: ChatDb, owner: ChatOwner | undefined): Promise<boolean>;
|
|
72
|
+
/**
|
|
73
|
+
* Fails the running turns whose lease lapsed (`host_lost`) and marks the computers whose
|
|
74
|
+
* liveness lapsed offline, for `owner` or, without one, for everyone. Commit it apart
|
|
75
|
+
* from any claim, because a claim that finds nothing aborts its own transaction.
|
|
76
|
+
*/
|
|
77
|
+
expireLapsed(tx: ChatDb, owner: ChatOwner | undefined): Promise<Lapsed[]>;
|
|
78
|
+
/**
|
|
79
|
+
* Puts a claimed turn back in the queue when the host never learned of the claim.
|
|
80
|
+
* Refused (false) once the turn has an agent item or is no longer running.
|
|
81
|
+
*/
|
|
82
|
+
releaseClaim(tx: ChatDb, owner: ChatOwner, host: HostPrincipal, turnId: TurnId): Promise<boolean>;
|
|
83
|
+
appendHostItems(tx: ChatDb, owner: ChatOwner, host: HostPrincipal, turnId: TurnId, items: readonly HostItemDraft[], leaseMs: number): Promise<{
|
|
84
|
+
readonly threadId: ThreadId;
|
|
85
|
+
readonly leaseUntil: number;
|
|
86
|
+
/** What the renewed turn token binds, so the caller need not read the turn again. */
|
|
87
|
+
readonly clientId: string;
|
|
88
|
+
readonly agentId: string;
|
|
89
|
+
}>;
|
|
90
|
+
/** Once per turn; a second call with any outcome is refused and changes nothing. */
|
|
91
|
+
finishTurn(tx: ChatDb, owner: ChatOwner, host: HostPrincipal, turnId: TurnId, outcome: TurnOutcome): Promise<{
|
|
92
|
+
readonly threadId: ThreadId;
|
|
93
|
+
}>;
|
|
94
|
+
readSignals(db: ChatDb, owner: ChatOwner, host: HostPrincipal, turns: readonly {
|
|
95
|
+
readonly turnId: TurnId;
|
|
96
|
+
readonly afterSeq: number;
|
|
97
|
+
}[]): Promise<TurnSignals[]>;
|
|
98
|
+
reportHost(tx: ChatDb, owner: ChatOwner, host: HostPrincipal, report: {
|
|
99
|
+
readonly protocol: number;
|
|
100
|
+
readonly name: string;
|
|
101
|
+
readonly platform: string;
|
|
102
|
+
readonly agents: readonly AgentInfo[];
|
|
103
|
+
/** Left as it was when the host does not report it. */
|
|
104
|
+
readonly devices?: readonly string[] | undefined;
|
|
105
|
+
/** Left as it was when the host does not report it. */
|
|
106
|
+
readonly presenceDue?: Readonly<Record<string, number>> | undefined;
|
|
107
|
+
readonly online: boolean;
|
|
108
|
+
readonly ttlMs: number;
|
|
109
|
+
}): Promise<{
|
|
110
|
+
readonly onlineUntil: number;
|
|
111
|
+
}>;
|
|
112
|
+
/**
|
|
113
|
+
* One UPDATE of `online_until`. `returned` is true when the sidebar had been told the
|
|
114
|
+
* computer was offline, so the caller announces its return.
|
|
115
|
+
*/
|
|
116
|
+
heartbeat(db: ChatDb, owner: ChatOwner, host: HostPrincipal, ttlMs: number): Promise<{
|
|
117
|
+
readonly returned: boolean;
|
|
118
|
+
}>;
|
|
119
|
+
listHosts(db: ChatDb, owner: ChatOwner): Promise<StoredHost[]>;
|
|
120
|
+
/** Drops the owner's computer rows whose grant is gone. */
|
|
121
|
+
pruneHosts(tx: ChatDb, owner: ChatOwner, hostIds: readonly HostId[]): Promise<void>;
|
|
122
|
+
turnHolder(db: ChatDb, turnId: TurnId): Promise<StreamTurn | undefined>;
|
|
123
|
+
}
|
|
124
|
+
export interface StoredHost extends HostSummary {
|
|
125
|
+
readonly grantId: GrantId;
|
|
126
|
+
readonly protocol: number;
|
|
127
|
+
}
|
|
128
|
+
export declare const THREAD_LIST_LIMIT = 200;
|
|
129
|
+
export declare const sqlChatStore: ChatStore;
|
|
130
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/server/store.ts"],"names":[],"mappings":"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"}
|