@parlor/chat 0.0.0-stage → 0.1.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.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +23 -2
  3. package/dist/events.d.ts +4 -0
  4. package/dist/events.d.ts.map +1 -0
  5. package/dist/events.js +12 -0
  6. package/dist/events.js.map +1 -0
  7. package/dist/id-schemas.d.ts +5 -0
  8. package/dist/id-schemas.d.ts.map +1 -0
  9. package/dist/id-schemas.js +11 -0
  10. package/dist/id-schemas.js.map +1 -0
  11. package/dist/index.d.ts +9 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +7 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/items.d.ts +295 -0
  16. package/dist/items.d.ts.map +1 -0
  17. package/dist/items.js +113 -0
  18. package/dist/items.js.map +1 -0
  19. package/dist/limits.d.ts +4 -0
  20. package/dist/limits.d.ts.map +1 -0
  21. package/dist/limits.js +4 -0
  22. package/dist/limits.js.map +1 -0
  23. package/dist/model.d.ts +143 -0
  24. package/dist/model.d.ts.map +1 -0
  25. package/dist/model.js +2 -0
  26. package/dist/model.js.map +1 -0
  27. package/dist/open-turns.d.ts +19 -0
  28. package/dist/open-turns.d.ts.map +1 -0
  29. package/dist/open-turns.js +31 -0
  30. package/dist/open-turns.js.map +1 -0
  31. package/dist/protocol.d.ts +67 -0
  32. package/dist/protocol.d.ts.map +1 -0
  33. package/dist/protocol.js +78 -0
  34. package/dist/protocol.js.map +1 -0
  35. package/dist/server/actions.d.ts +561 -0
  36. package/dist/server/actions.d.ts.map +1 -0
  37. package/dist/server/actions.js +422 -0
  38. package/dist/server/actions.js.map +1 -0
  39. package/dist/server/context.d.ts +24 -0
  40. package/dist/server/context.d.ts.map +1 -0
  41. package/dist/server/context.js +77 -0
  42. package/dist/server/context.js.map +1 -0
  43. package/dist/server/index.d.ts +35 -0
  44. package/dist/server/index.d.ts.map +1 -0
  45. package/dist/server/index.js +129 -0
  46. package/dist/server/index.js.map +1 -0
  47. package/dist/server/live.d.ts +24 -0
  48. package/dist/server/live.d.ts.map +1 -0
  49. package/dist/server/live.js +130 -0
  50. package/dist/server/live.js.map +1 -0
  51. package/dist/server/migrations.d.ts +3 -0
  52. package/dist/server/migrations.d.ts.map +1 -0
  53. package/dist/server/migrations.js +96 -0
  54. package/dist/server/migrations.js.map +1 -0
  55. package/dist/server/party.d.ts +24 -0
  56. package/dist/server/party.d.ts.map +1 -0
  57. package/dist/server/party.js +38 -0
  58. package/dist/server/party.js.map +1 -0
  59. package/dist/server/routes.d.ts +17 -0
  60. package/dist/server/routes.d.ts.map +1 -0
  61. package/dist/server/routes.js +105 -0
  62. package/dist/server/routes.js.map +1 -0
  63. package/dist/server/rows.d.ts +49 -0
  64. package/dist/server/rows.d.ts.map +1 -0
  65. package/dist/server/rows.js +136 -0
  66. package/dist/server/rows.js.map +1 -0
  67. package/dist/server/store.d.ts +130 -0
  68. package/dist/server/store.d.ts.map +1 -0
  69. package/dist/server/store.js +539 -0
  70. package/dist/server/store.js.map +1 -0
  71. package/dist/tags.d.ts +7 -0
  72. package/dist/tags.d.ts.map +1 -0
  73. package/dist/tags.js +7 -0
  74. package/dist/tags.js.map +1 -0
  75. package/dist/testing/index.d.ts +46 -0
  76. package/dist/testing/index.d.ts.map +1 -0
  77. package/dist/testing/index.js +96 -0
  78. package/dist/testing/index.js.map +1 -0
  79. package/dist/view.d.ts +87 -0
  80. package/dist/view.d.ts.map +1 -0
  81. package/dist/view.js +236 -0
  82. package/dist/view.js.map +1 -0
  83. package/package.json +47 -3
@@ -0,0 +1,143 @@
1
+ import type { HostId, ItemId, ThreadId, TurnId, UserId } from "@parlor/core";
2
+ import type { Delegation, DeviceKeys } from "@parlor/server";
3
+ import type { ChatItemBody, LoggedItem, UserItemKind } from "./items.js";
4
+ export interface AgentRef {
5
+ readonly hostId: HostId;
6
+ /** A profile id on that host (`claude`, `codex`), not an entity. */
7
+ readonly agentId: string;
8
+ }
9
+ /**
10
+ * Whose chat a row is. Every thread, turn and host row carries both and every chat query
11
+ * filters by both, so members of one organization scope never see each other's chats.
12
+ */
13
+ export interface ChatOwner {
14
+ readonly scope: string;
15
+ readonly userId: UserId;
16
+ }
17
+ export interface HostSummary {
18
+ readonly id: HostId;
19
+ readonly name: string;
20
+ readonly platform: string;
21
+ readonly online: boolean;
22
+ readonly agents: readonly AgentInfo[];
23
+ /** The devices this computer runs prompts from; absent when it is too old to say. */
24
+ readonly devices?: readonly string[] | undefined;
25
+ /**
26
+ * When each of those devices must sign its next prompt with Face ID or Touch ID again
27
+ * (epoch ms); a device it never asks is missing.
28
+ */
29
+ readonly presenceDue?: Readonly<Record<string, number>> | undefined;
30
+ }
31
+ export interface AgentInfo {
32
+ readonly id: string;
33
+ readonly name: string;
34
+ readonly version?: string | undefined;
35
+ readonly ready: boolean;
36
+ /** Why a not-ready agent cannot run yet ("run `claude` to log in"). */
37
+ readonly problem?: string | undefined;
38
+ }
39
+ export interface ThreadSummary {
40
+ readonly id: ThreadId;
41
+ readonly title: string;
42
+ readonly agent: AgentRef | undefined;
43
+ readonly updatedAt: number;
44
+ readonly lastSeq: number;
45
+ }
46
+ export type TurnState = "queued" | "running" | "done" | "failed" | "cancelled";
47
+ export type TurnFailure = "agent_exited" | "agent_unavailable" | "device_rejected" | "signature_invalid" | "prompt_expired" | "host_lost";
48
+ export type TurnOutcome = {
49
+ readonly state: "done";
50
+ readonly stopReason: string;
51
+ } | {
52
+ readonly state: "cancelled";
53
+ } | {
54
+ readonly state: "failed";
55
+ readonly reason: TurnFailure;
56
+ };
57
+ /** Still being produced: only in memory, on the instance the host posts to. */
58
+ export type OpenItem = {
59
+ readonly id: ItemId;
60
+ readonly kind: "reply" | "reasoning";
61
+ readonly text: string;
62
+ } | {
63
+ readonly id: ItemId;
64
+ readonly kind: "tool";
65
+ readonly title: string;
66
+ readonly status: "pending" | "running";
67
+ } | {
68
+ readonly id: ItemId;
69
+ readonly kind: "plan";
70
+ readonly entries: ChatItemBody<"plan">["entries"];
71
+ };
72
+ export interface OpenTurn {
73
+ readonly turnId: TurnId;
74
+ readonly threadId: ThreadId;
75
+ readonly items: readonly OpenItem[];
76
+ }
77
+ export interface TurnStatus {
78
+ readonly turnId: TurnId;
79
+ readonly state: TurnState;
80
+ readonly agent: AgentRef;
81
+ readonly failure?: TurnFailure | undefined;
82
+ }
83
+ export interface ThreadPage {
84
+ readonly thread: ThreadSummary | undefined;
85
+ readonly items: readonly LoggedItem[];
86
+ readonly open: readonly OpenTurn[];
87
+ readonly turns: readonly TurnStatus[];
88
+ readonly hasMore: boolean;
89
+ }
90
+ export interface ChatSnapshot {
91
+ readonly threads: readonly ThreadSummary[];
92
+ /** `threads` was cut at its limit; `threadsBefore` reads on from its last one. */
93
+ readonly moreThreads?: boolean | undefined;
94
+ readonly hosts: readonly HostSummary[];
95
+ readonly page: ThreadPage;
96
+ }
97
+ /** What `history` returns: earlier items of a thread, oldest first, with their turns. */
98
+ export interface ThreadHistory {
99
+ readonly items: readonly LoggedItem[];
100
+ readonly turns: readonly TurnStatus[];
101
+ readonly hasMore: boolean;
102
+ }
103
+ /** What `threadsBefore` returns: the next older threads, newest first. */
104
+ export interface ThreadList {
105
+ readonly threads: readonly ThreadSummary[];
106
+ readonly hasMore: boolean;
107
+ }
108
+ /** The device's keys as the account has them; the host compares them with its own pins. */
109
+ export type ClaimedDevice = DeviceKeys;
110
+ export interface ClaimedTurn {
111
+ /** The thread id; every chat write returns it as `id`, which becomes its sync tag. */
112
+ readonly id: ThreadId;
113
+ readonly turnId: TurnId;
114
+ readonly agent: AgentRef;
115
+ /** The client the prompt came from; the turn token binds `ui_*` to it. */
116
+ readonly clientId: string;
117
+ readonly prompt: LoggedItem<"prompt">;
118
+ readonly device: ClaimedDevice | undefined;
119
+ /** The `<parlor-context>` block for a fresh agent session. */
120
+ readonly context: string;
121
+ readonly token: Delegation;
122
+ readonly leaseUntil: number;
123
+ }
124
+ export interface TurnSignals {
125
+ readonly turnId: TurnId;
126
+ readonly items: readonly LoggedItem<Exclude<UserItemKind, "prompt">>[];
127
+ /** The keys of each device that answered, as the account lists them; revoked ones are left out. */
128
+ readonly devices?: readonly DeviceKeys[];
129
+ }
130
+ /** What a device signs for a prompt; the host rebuilds the same statement from the item. */
131
+ export interface PromptToSign {
132
+ readonly threadId: ThreadId;
133
+ readonly turnId: TurnId;
134
+ readonly agent: AgentRef;
135
+ readonly text: string;
136
+ }
137
+ export interface AnswerToSign {
138
+ readonly threadId: ThreadId;
139
+ readonly askId: ItemId;
140
+ readonly choice: string;
141
+ readonly values?: ChatItemBody<"answer">["values"];
142
+ }
143
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
package/dist/model.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ import type { OpenItem } from "./model.js";
2
+ import type { ChatFrame } from "./protocol.js";
3
+ export interface AppliedFrame {
4
+ readonly items: readonly OpenItem[];
5
+ /** What actually changed: a delta overlapping the text already held is cut to its new part. */
6
+ readonly frame: Exclude<ChatFrame, {
7
+ type: "settled";
8
+ }>;
9
+ }
10
+ /**
11
+ * Applies a `delta` or `item` frame to one turn's open items. A delta whose text is
12
+ * already held is skipped and one that starts past the end of the text is a gap; both
13
+ * answer `undefined`, and after a gap every later delta is a gap too, so the item waits
14
+ * for its durable twin instead of drawing a hole.
15
+ */
16
+ export declare function applyFrame(items: readonly OpenItem[], frame: Exclude<ChatFrame, {
17
+ type: "settled";
18
+ }>): AppliedFrame | undefined;
19
+ //# sourceMappingURL=open-turns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-turns.d.ts","sourceRoot":"","sources":["../src/open-turns.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC,+FAA+F;IAC/F,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;CACzD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,QAAQ,EAAE,EAC1B,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,GAC7C,YAAY,GAAG,SAAS,CAqB1B"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Applies a `delta` or `item` frame to one turn's open items. A delta whose text is
3
+ * already held is skipped and one that starts past the end of the text is a gap; both
4
+ * answer `undefined`, and after a gap every later delta is a gap too, so the item waits
5
+ * for its durable twin instead of drawing a hole.
6
+ */
7
+ export function applyFrame(items, frame) {
8
+ if (frame.type === "item") {
9
+ const index = items.findIndex((item) => item.id === frame.item.id);
10
+ const next = index < 0
11
+ ? [...items, frame.item]
12
+ : items.map((item, at) => (at === index ? frame.item : item));
13
+ return { items: next, frame };
14
+ }
15
+ const index = items.findIndex((item) => item.id === frame.itemId);
16
+ const held = index < 0 ? undefined : items[index];
17
+ if (held && held.kind !== "reply" && held.kind !== "reasoning")
18
+ return undefined;
19
+ const have = held ? held.text : "";
20
+ if (frame.offset > have.length)
21
+ return undefined;
22
+ const fresh = frame.text.slice(have.length - frame.offset);
23
+ if (fresh.length === 0)
24
+ return undefined;
25
+ const grown = { id: frame.itemId, kind: frame.kind, text: have + fresh };
26
+ const next = held
27
+ ? items.map((item, at) => (at === index ? grown : item))
28
+ : [...items, grown];
29
+ return { items: next, frame: { ...frame, offset: have.length, text: fresh } };
30
+ }
31
+ //# sourceMappingURL=open-turns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-turns.js","sourceRoot":"","sources":["../src/open-turns.ts"],"names":[],"mappings":"AASA;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CACxB,KAA0B,EAC1B,KAA8C;IAE9C,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnE,MAAM,IAAI,GACR,KAAK,GAAG,CAAC;YACP,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC;YACxB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAClE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAChC,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC;IAClE,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAClD,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW;QAAE,OAAO,SAAS,CAAC;IACjF,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACnC,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IACjD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,KAAK,GAAa,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,GAAG,KAAK,EAAE,CAAC;IACnF,MAAM,IAAI,GAAG,IAAI;QACf,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,CAAC;IACtB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;AAChF,CAAC"}
@@ -0,0 +1,67 @@
1
+ import { type ItemId, type ThreadId, type TurnId } from "@parlor/core";
2
+ import type { AgentInfo, OpenItem } from "./model.js";
3
+ export declare const CHAT_CHANNEL = "chat";
4
+ export type StreamingKind = "reply" | "reasoning";
5
+ /**
6
+ * Server to browser on the `chat` channel; never persisted. `offset` makes a duplicate
7
+ * delta skippable and a gap detectable, after which the client waits for the durable
8
+ * item. `settled` drops a turn's open items: durable now, or gone.
9
+ */
10
+ export type ChatFrame = {
11
+ readonly type: "delta";
12
+ readonly threadId: ThreadId;
13
+ readonly turnId: TurnId;
14
+ readonly itemId: ItemId;
15
+ readonly kind: StreamingKind;
16
+ readonly offset: number;
17
+ readonly text: string;
18
+ } | {
19
+ readonly type: "item";
20
+ readonly threadId: ThreadId;
21
+ readonly turnId: TurnId;
22
+ readonly item: Extract<OpenItem, {
23
+ kind: "tool" | "plan";
24
+ }>;
25
+ } | {
26
+ readonly type: "settled";
27
+ readonly threadId: ThreadId;
28
+ readonly turnId: TurnId;
29
+ };
30
+ /** Host to server: the same frames minus what the batch's turn implies. Only the server settles. */
31
+ export type HostFrame = ChatFrame extends infer F ? F extends {
32
+ readonly type: "delta" | "item";
33
+ } ? Omit<F, "threadId" | "turnId"> : never : never;
34
+ /** `POST /_parlor/chat/stream` */
35
+ export interface HostStreamBatch {
36
+ readonly turnId: TurnId;
37
+ readonly frames: readonly HostFrame[];
38
+ }
39
+ /**
40
+ * The versioned contract between an app's backend and Parlor Host: host actions, item
41
+ * kinds, frames and cursor rules. Bumped on any change an older peer could misread.
42
+ */
43
+ export declare const HOST_PROTOCOL = 2;
44
+ export interface ProtocolRange {
45
+ readonly min: number;
46
+ readonly max: number;
47
+ }
48
+ export interface HostHello {
49
+ readonly protocols: ProtocolRange;
50
+ readonly hostVersion: string;
51
+ readonly name: string;
52
+ readonly platform: string;
53
+ readonly agents: readonly AgentInfo[];
54
+ }
55
+ export type HostWelcome = {
56
+ readonly accepted: true;
57
+ readonly protocol: number;
58
+ readonly leaseMs: number;
59
+ readonly heartbeatMs: number;
60
+ readonly userActivity?: true;
61
+ } | {
62
+ readonly accepted: false;
63
+ readonly reason: "host_too_old" | "app_too_old";
64
+ readonly protocols: ProtocolRange;
65
+ };
66
+ export declare function parseChatFrame(data: string): ChatFrame | undefined;
67
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,MAAM,EACZ,MAAM,cAAc,CAAC;AAGtB,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtD,eAAO,MAAM,YAAY,SAAS,CAAC;AAEnC,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,WAAW,CAAC;AAElD;;;;GAIG;AACH,MAAM,MAAM,SAAS,GACjB;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7D,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvF,oGAAoG;AACpG,MAAM,MAAM,SAAS,GAAG,SAAS,SAAS,MAAM,CAAC,GAC7C,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAA;CAAE,GAC3C,IAAI,CAAC,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC,GAC9B,KAAK,GACP,KAAK,CAAC;AAEV,kCAAkC;AAClC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;CACvC;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,IAAI,CAAC;AAE/B,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;CACvC;AAED,MAAM,MAAM,WAAW,GACnB;IACE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC;CAC9B,GACD;IACE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,aAAa,CAAC;IAChD,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;CACnC,CAAC;AAwCN,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CA8BlE"}
@@ -0,0 +1,78 @@
1
+ import { asId, } from "@parlor/core";
2
+ export const CHAT_CHANNEL = "chat";
3
+ /**
4
+ * The versioned contract between an app's backend and Parlor Host: host actions, item
5
+ * kinds, frames and cursor rules. Bumped on any change an older peer could misread.
6
+ */
7
+ export const HOST_PROTOCOL = 2;
8
+ function isFields(value) {
9
+ return typeof value === "object" && value !== null && !Array.isArray(value);
10
+ }
11
+ function oneOf(values, value) {
12
+ return values.find((candidate) => candidate === value);
13
+ }
14
+ function idOf(kind, value) {
15
+ return typeof value === "string" && value.length > 0 ? asId(kind, value) : undefined;
16
+ }
17
+ function openItemOf(value) {
18
+ if (!isFields(value))
19
+ return undefined;
20
+ const id = idOf("item", value.id);
21
+ if (!id)
22
+ return undefined;
23
+ if (value.kind === "tool") {
24
+ const status = oneOf(["pending", "running"], value.status);
25
+ if (typeof value.title !== "string" || !status)
26
+ return undefined;
27
+ return { id, kind: "tool", title: value.title, status };
28
+ }
29
+ if (value.kind === "plan" && Array.isArray(value.entries)) {
30
+ const entries = [];
31
+ for (const entry of value.entries) {
32
+ if (!isFields(entry) || typeof entry.content !== "string")
33
+ return undefined;
34
+ const status = oneOf(["pending", "in_progress", "completed"], entry.status);
35
+ if (!status)
36
+ return undefined;
37
+ entries.push({ content: entry.content, status });
38
+ }
39
+ return { id, kind: "plan", entries };
40
+ }
41
+ return undefined;
42
+ }
43
+ export function parseChatFrame(data) {
44
+ let value;
45
+ try {
46
+ value = JSON.parse(data);
47
+ }
48
+ catch {
49
+ return undefined;
50
+ }
51
+ if (!isFields(value))
52
+ return undefined;
53
+ const threadId = idOf("thread", value.threadId);
54
+ const turnId = idOf("turn", value.turnId);
55
+ if (!threadId || !turnId)
56
+ return undefined;
57
+ switch (value.type) {
58
+ case "settled":
59
+ return { type: "settled", threadId, turnId };
60
+ case "item": {
61
+ const item = openItemOf(value.item);
62
+ return item ? { type: "item", threadId, turnId, item } : undefined;
63
+ }
64
+ case "delta": {
65
+ const itemId = idOf("item", value.itemId);
66
+ const kind = oneOf(["reply", "reasoning"], value.kind);
67
+ const { offset, text } = value;
68
+ if (!itemId || !kind || typeof text !== "string")
69
+ return undefined;
70
+ if (typeof offset !== "number" || !Number.isInteger(offset) || offset < 0)
71
+ return undefined;
72
+ return { type: "delta", threadId, turnId, itemId, kind, offset, text };
73
+ }
74
+ default:
75
+ return undefined;
76
+ }
77
+ }
78
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}