@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.
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 +69 -0
  32. package/dist/protocol.d.ts.map +1 -0
  33. package/dist/protocol.js +80 -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 +50 -0
  44. package/dist/server/index.d.ts.map +1 -0
  45. package/dist/server/index.js +145 -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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 cychien
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,24 @@
1
- # Temporary Holding Version
1
+ # @parlor/chat
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The server half of the agent sidebar: threads, prompts, agent replies and approvals, as a `createServer` plugin.
4
+
5
+ ```sh
6
+ pnpm add @parlor/chat
7
+ ```
8
+
9
+ ```ts
10
+ import { chat } from "@parlor/chat/server";
11
+ import { createRegistry } from "@parlor/core/registry";
12
+ import { createDatabase } from "@parlor/data";
13
+ import { createServer } from "@parlor/server";
14
+
15
+ const database = await createDatabase({ migrationsFolder: "migrations" });
16
+
17
+ export default createServer({
18
+ actions: createRegistry({}),
19
+ database,
20
+ plugins: [chat()],
21
+ });
22
+ ```
23
+
24
+ New apps include it. Docs: https://cychien.github.io/parlor/guides/agent-sidebar/
@@ -0,0 +1,4 @@
1
+ export declare const CHAT_EVENTS: readonly ["device_pending", "device_rejected", "agent_started", "agent_exited", "agent_switched", "host_lost", "turn_failed", "answer_rejected", "answered_on_computer"];
2
+ export type ChatEvent = (typeof CHAT_EVENTS)[number];
3
+ export type FoldedEvent = Extract<ChatEvent, "answered_on_computer">;
4
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,YACtB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,sBAAsB,CACd,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC"}
package/dist/events.js ADDED
@@ -0,0 +1,12 @@
1
+ export const CHAT_EVENTS = [
2
+ "device_pending",
3
+ "device_rejected",
4
+ "agent_started",
5
+ "agent_exited",
6
+ "agent_switched",
7
+ "host_lost",
8
+ "turn_failed",
9
+ "answer_rejected",
10
+ "answered_on_computer",
11
+ ];
12
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,gBAAgB;IAChB,iBAAiB;IACjB,eAAe;IACf,cAAc;IACd,gBAAgB;IAChB,WAAW;IACX,aAAa;IACb,iBAAiB;IACjB,sBAAsB;CACd,CAAC","sourcesContent":["export const CHAT_EVENTS = [\n \"device_pending\",\n \"device_rejected\",\n \"agent_started\",\n \"agent_exited\",\n \"agent_switched\",\n \"host_lost\",\n \"turn_failed\",\n \"answer_rejected\",\n \"answered_on_computer\",\n] as const;\n\nexport type ChatEvent = (typeof CHAT_EVENTS)[number];\n\nexport type FoldedEvent = Extract<ChatEvent, \"answered_on_computer\">;\n"]}
@@ -0,0 +1,5 @@
1
+ import { type Id, type IdKind } from "@parlor/core";
2
+ import { z } from "zod";
3
+ /** A request field naming an entity: validated, then branded, at the boundary. */
4
+ export declare function idSchema<K extends IdKind>(kind: K): z.ZodPipe<z.ZodString, z.ZodTransform<Id<K>, string>>;
5
+ //# sourceMappingURL=id-schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id-schemas.d.ts","sourceRoot":"","sources":["../src/id-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,EAAE,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,kFAAkF;AAClF,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EACvC,IAAI,EAAE,CAAC,GACN,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAMvD"}
@@ -0,0 +1,11 @@
1
+ import { asId } from "@parlor/core";
2
+ import { z } from "zod";
3
+ /** A request field naming an entity: validated, then branded, at the boundary. */
4
+ export function idSchema(kind) {
5
+ return z
6
+ .string()
7
+ .min(1)
8
+ .max(64)
9
+ .transform((value) => asId(kind, value));
10
+ }
11
+ //# sourceMappingURL=id-schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id-schemas.js","sourceRoot":"","sources":["../src/id-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAwB,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,kFAAkF;AAClF,MAAM,UAAU,QAAQ,CACtB,IAAO;IAEP,OAAO,CAAC;SACL,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,EAAE,CAAC;SACP,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["import { asId, type Id, type IdKind } from \"@parlor/core\";\nimport { z } from \"zod\";\n\n/** A request field naming an entity: validated, then branded, at the boundary. */\nexport function idSchema<K extends IdKind>(\n kind: K,\n): z.ZodPipe<z.ZodString, z.ZodTransform<Id<K>, string>> {\n return z\n .string()\n .min(1)\n .max(64)\n .transform((value) => asId(kind, value));\n}\n"]}
@@ -0,0 +1,9 @@
1
+ export { CHAT_EVENTS, type ChatEvent } from "./events.js";
2
+ export type { Author, AuthorOf, ChatItemBody, ChatItemKind, HostItemDraft, HostItemKind, ItemSignature, LoggedItem, UserItemKind, } from "./items.js";
3
+ export { type AppliedFrame, applyFrame } from "./open-turns.js";
4
+ export { isPromptTooLong, MAX_PROMPT_CHARS, PROMPT_LIMIT_MESSAGE } from "./limits.js";
5
+ export type { AgentInfo, AgentRef, AnswerToSign, ChatOwner, ChatSnapshot, ClaimedDevice, ClaimedTurn, HostSummary, OpenItem, OpenTurn, PromptToSign, ThreadHistory, ThreadList, ThreadPage, ThreadSummary, TurnFailure, TurnOutcome, TurnSignals, TurnState, TurnStatus, } from "./model.js";
6
+ export { CHAT_CHANNEL, CHAT_PLUGIN, type ChatFrame, HOST_PROTOCOL, type HostFrame, type HostHello, type HostStreamBatch, type HostWelcome, parseChatFrame, type ProtocolRange, type StreamingKind, } from "./protocol.js";
7
+ export { CHAT_ACTIVITY_TAG, CHAT_TAG, HOSTS_TAG } from "./tags.js";
8
+ export { type AskState, type ChatItem, type FoldedKind, type FoldInput, foldThread, type ItemFolders, type ThreadConfirmation, } from "./view.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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,QAAQ,EACR,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,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACnE,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 ADDED
@@ -0,0 +1,7 @@
1
+ export { CHAT_EVENTS } from "./events.js";
2
+ export { applyFrame } from "./open-turns.js";
3
+ export { isPromptTooLong, MAX_PROMPT_CHARS, PROMPT_LIMIT_MESSAGE } from "./limits.js";
4
+ export { CHAT_CHANNEL, CHAT_PLUGIN, HOST_PROTOCOL, parseChatFrame, } from "./protocol.js";
5
+ export { CHAT_ACTIVITY_TAG, CHAT_TAG, HOSTS_TAG } from "./tags.js";
6
+ export { foldThread, } from "./view.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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;AAuBtF,OAAO,EACL,YAAY,EACZ,WAAW,EAEX,aAAa,EAKb,cAAc,GAGf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACnE,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 AgentRef,\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 type ProtocolRange,\n type StreamingKind,\n} from \"./protocol.js\";\nexport { CHAT_ACTIVITY_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"]}
@@ -0,0 +1,295 @@
1
+ import type { ItemId, ThreadId, TurnId } from "@parlor/core";
2
+ import { z } from "zod";
3
+ import { idSchema } from "./id-schemas.js";
4
+ declare const signed: z.ZodObject<{
5
+ deviceId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@parlor/core").Id<"device">, string>>;
6
+ at: z.ZodNumber;
7
+ signature: z.ZodObject<{
8
+ keyId: z.ZodString;
9
+ presence: z.ZodEnum<{
10
+ none: "none";
11
+ user: "user";
12
+ }>;
13
+ format: z.ZodEnum<{
14
+ "es256-raw": "es256-raw";
15
+ webauthn: "webauthn";
16
+ }>;
17
+ signature: z.ZodString;
18
+ authenticatorData: z.ZodOptional<z.ZodString>;
19
+ clientDataJSON: z.ZodOptional<z.ZodString>;
20
+ }, z.core.$strip>;
21
+ pairing: z.ZodOptional<z.ZodString>;
22
+ }, z.core.$strip>;
23
+ /**
24
+ * The one table of item kinds: who writes each and the body it carries. Types, the
25
+ * server's parsers, the host's append type and the client's view all derive from it.
26
+ */
27
+ export declare const chatItemBodies: {
28
+ readonly prompt: {
29
+ readonly author: "user";
30
+ readonly body: z.ZodObject<{
31
+ text: z.ZodString;
32
+ agent: z.ZodObject<{
33
+ hostId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@parlor/core").Id<"host">, string>>;
34
+ agentId: z.ZodString;
35
+ }, z.core.$strip>;
36
+ signed: z.ZodOptional<z.ZodObject<{
37
+ deviceId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@parlor/core").Id<"device">, string>>;
38
+ at: z.ZodNumber;
39
+ signature: z.ZodObject<{
40
+ keyId: z.ZodString;
41
+ presence: z.ZodEnum<{
42
+ none: "none";
43
+ user: "user";
44
+ }>;
45
+ format: z.ZodEnum<{
46
+ "es256-raw": "es256-raw";
47
+ webauthn: "webauthn";
48
+ }>;
49
+ signature: z.ZodString;
50
+ authenticatorData: z.ZodOptional<z.ZodString>;
51
+ clientDataJSON: z.ZodOptional<z.ZodString>;
52
+ }, z.core.$strip>;
53
+ pairing: z.ZodOptional<z.ZodString>;
54
+ }, z.core.$strip>>;
55
+ }, z.core.$strip>;
56
+ };
57
+ readonly answer: {
58
+ readonly author: "user";
59
+ readonly body: z.ZodObject<{
60
+ askId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@parlor/core").Id<"item">, string>>;
61
+ choice: z.ZodString;
62
+ values: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
63
+ signed: z.ZodOptional<z.ZodObject<{
64
+ deviceId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@parlor/core").Id<"device">, string>>;
65
+ at: z.ZodNumber;
66
+ signature: z.ZodObject<{
67
+ keyId: z.ZodString;
68
+ presence: z.ZodEnum<{
69
+ none: "none";
70
+ user: "user";
71
+ }>;
72
+ format: z.ZodEnum<{
73
+ "es256-raw": "es256-raw";
74
+ webauthn: "webauthn";
75
+ }>;
76
+ signature: z.ZodString;
77
+ authenticatorData: z.ZodOptional<z.ZodString>;
78
+ clientDataJSON: z.ZodOptional<z.ZodString>;
79
+ }, z.core.$strip>;
80
+ pairing: z.ZodOptional<z.ZodString>;
81
+ }, z.core.$strip>>;
82
+ }, z.core.$strip>;
83
+ };
84
+ readonly cancel: {
85
+ readonly author: "user";
86
+ readonly body: z.ZodObject<{}, z.core.$strip>;
87
+ };
88
+ readonly reply: {
89
+ readonly author: "agent";
90
+ readonly body: z.ZodObject<{
91
+ text: z.ZodString;
92
+ interrupted: z.ZodOptional<z.ZodLiteral<true>>;
93
+ }, z.core.$strip>;
94
+ };
95
+ readonly reasoning: {
96
+ readonly author: "agent";
97
+ readonly body: z.ZodObject<{
98
+ text: z.ZodString;
99
+ }, z.core.$strip>;
100
+ };
101
+ readonly tool: {
102
+ readonly author: "agent";
103
+ readonly body: z.ZodObject<{
104
+ title: z.ZodString;
105
+ tool: z.ZodObject<{
106
+ kind: z.ZodEnum<{
107
+ app: "app";
108
+ local: "local";
109
+ }>;
110
+ name: z.ZodString;
111
+ }, z.core.$strip>;
112
+ status: z.ZodEnum<{
113
+ cancelled: "cancelled";
114
+ done: "done";
115
+ failed: "failed";
116
+ }>;
117
+ detail: z.ZodOptional<z.ZodString>;
118
+ }, z.core.$strip>;
119
+ };
120
+ readonly plan: {
121
+ readonly author: "agent";
122
+ readonly body: z.ZodObject<{
123
+ entries: z.ZodArray<z.ZodObject<{
124
+ content: z.ZodString;
125
+ status: z.ZodEnum<{
126
+ completed: "completed";
127
+ in_progress: "in_progress";
128
+ pending: "pending";
129
+ }>;
130
+ }, z.core.$strip>>;
131
+ }, z.core.$strip>;
132
+ };
133
+ readonly ask: {
134
+ readonly author: "agent";
135
+ readonly body: z.ZodObject<{
136
+ question: z.ZodString;
137
+ choices: z.ZodArray<z.ZodObject<{
138
+ id: z.ZodString;
139
+ label: z.ZodString;
140
+ effect: z.ZodEnum<{
141
+ allow_always: "allow_always";
142
+ allow_once: "allow_once";
143
+ reject_always: "reject_always";
144
+ reject_once: "reject_once";
145
+ }>;
146
+ }, z.core.$strip>>;
147
+ form: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
148
+ approval: z.ZodOptional<z.ZodEnum<{
149
+ computer: "computer";
150
+ presence: "presence";
151
+ }>>;
152
+ }, z.core.$strip>;
153
+ };
154
+ readonly event: {
155
+ readonly author: "system";
156
+ readonly body: z.ZodObject<{
157
+ event: z.ZodEnum<{
158
+ agent_exited: "agent_exited";
159
+ agent_started: "agent_started";
160
+ agent_switched: "agent_switched";
161
+ answer_rejected: "answer_rejected";
162
+ answered_on_computer: "answered_on_computer";
163
+ device_pending: "device_pending";
164
+ device_rejected: "device_rejected";
165
+ host_lost: "host_lost";
166
+ turn_failed: "turn_failed";
167
+ }>;
168
+ detail: z.ZodOptional<z.ZodString>;
169
+ itemId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@parlor/core").Id<"item">, string>>>;
170
+ choice: z.ZodOptional<z.ZodString>;
171
+ }, z.core.$strip>;
172
+ };
173
+ };
174
+ type Bodies = typeof chatItemBodies;
175
+ export type ChatItemKind = keyof Bodies;
176
+ export type Author = Bodies[ChatItemKind]["author"];
177
+ export type AuthorOf<K extends ChatItemKind> = Bodies[K]["author"];
178
+ export type ChatItemBody<K extends ChatItemKind> = z.output<Bodies[K]["body"]>;
179
+ export type ItemSignature = z.output<typeof signed>;
180
+ type KindsBy<A extends Author> = {
181
+ [K in ChatItemKind]: AuthorOf<K> extends A ? K : never;
182
+ }[ChatItemKind];
183
+ /** Appended only by the user's devices, through the user actions. */
184
+ export type UserItemKind = KindsBy<"user">;
185
+ /** Appended only by the user's computer, through the host actions. */
186
+ export type HostItemKind = KindsBy<"agent" | "system">;
187
+ export type LoggedItem<K extends ChatItemKind = ChatItemKind> = {
188
+ [Kind in K]: {
189
+ readonly id: ItemId;
190
+ readonly threadId: ThreadId;
191
+ readonly turnId: TurnId;
192
+ /** Gap-free per thread, assigned under the thread row's lock. */
193
+ readonly seq: number;
194
+ readonly at: number;
195
+ readonly author: AuthorOf<Kind>;
196
+ readonly kind: Kind;
197
+ readonly body: ChatItemBody<Kind>;
198
+ };
199
+ }[K];
200
+ /** Its id is `<turnId>.<n>`, chosen by the host, so a retried append is a no-op. */
201
+ export type HostItemDraft = {
202
+ [K in HostItemKind]: {
203
+ readonly id: ItemId;
204
+ readonly kind: K;
205
+ readonly body: ChatItemBody<K>;
206
+ };
207
+ }[HostItemKind];
208
+ export declare const hostItemDraft: z.ZodDiscriminatedUnion<[z.ZodObject<{
209
+ id: ReturnType<typeof idSchema<"item">>;
210
+ kind: z.ZodLiteral<"reply">;
211
+ body: z.ZodObject<{
212
+ text: z.ZodString;
213
+ interrupted: z.ZodOptional<z.ZodLiteral<true>>;
214
+ }, z.core.$strip>;
215
+ }, z.core.$strip>, z.ZodObject<{
216
+ id: ReturnType<typeof idSchema<"item">>;
217
+ kind: z.ZodLiteral<"reasoning">;
218
+ body: z.ZodObject<{
219
+ text: z.ZodString;
220
+ }, z.core.$strip>;
221
+ }, z.core.$strip>, z.ZodObject<{
222
+ id: ReturnType<typeof idSchema<"item">>;
223
+ kind: z.ZodLiteral<"tool">;
224
+ body: z.ZodObject<{
225
+ title: z.ZodString;
226
+ tool: z.ZodObject<{
227
+ kind: z.ZodEnum<{
228
+ app: "app";
229
+ local: "local";
230
+ }>;
231
+ name: z.ZodString;
232
+ }, z.core.$strip>;
233
+ status: z.ZodEnum<{
234
+ cancelled: "cancelled";
235
+ done: "done";
236
+ failed: "failed";
237
+ }>;
238
+ detail: z.ZodOptional<z.ZodString>;
239
+ }, z.core.$strip>;
240
+ }, z.core.$strip>, z.ZodObject<{
241
+ id: ReturnType<typeof idSchema<"item">>;
242
+ kind: z.ZodLiteral<"plan">;
243
+ body: z.ZodObject<{
244
+ entries: z.ZodArray<z.ZodObject<{
245
+ content: z.ZodString;
246
+ status: z.ZodEnum<{
247
+ completed: "completed";
248
+ in_progress: "in_progress";
249
+ pending: "pending";
250
+ }>;
251
+ }, z.core.$strip>>;
252
+ }, z.core.$strip>;
253
+ }, z.core.$strip>, z.ZodObject<{
254
+ id: ReturnType<typeof idSchema<"item">>;
255
+ kind: z.ZodLiteral<"ask">;
256
+ body: z.ZodObject<{
257
+ question: z.ZodString;
258
+ choices: z.ZodArray<z.ZodObject<{
259
+ id: z.ZodString;
260
+ label: z.ZodString;
261
+ effect: z.ZodEnum<{
262
+ allow_always: "allow_always";
263
+ allow_once: "allow_once";
264
+ reject_always: "reject_always";
265
+ reject_once: "reject_once";
266
+ }>;
267
+ }, z.core.$strip>>;
268
+ form: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
269
+ approval: z.ZodOptional<z.ZodEnum<{
270
+ computer: "computer";
271
+ presence: "presence";
272
+ }>>;
273
+ }, z.core.$strip>;
274
+ }, z.core.$strip>, z.ZodObject<{
275
+ id: ReturnType<typeof idSchema<"item">>;
276
+ kind: z.ZodLiteral<"event">;
277
+ body: z.ZodObject<{
278
+ event: z.ZodEnum<{
279
+ agent_exited: "agent_exited";
280
+ agent_started: "agent_started";
281
+ agent_switched: "agent_switched";
282
+ answer_rejected: "answer_rejected";
283
+ answered_on_computer: "answered_on_computer";
284
+ device_pending: "device_pending";
285
+ device_rejected: "device_rejected";
286
+ host_lost: "host_lost";
287
+ turn_failed: "turn_failed";
288
+ }>;
289
+ detail: z.ZodOptional<z.ZodString>;
290
+ itemId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@parlor/core").Id<"item">, string>>>;
291
+ choice: z.ZodOptional<z.ZodString>;
292
+ }, z.core.$strip>;
293
+ }, z.core.$strip>], "kind">;
294
+ export {};
295
+ //# sourceMappingURL=items.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"items.d.ts","sourceRoot":"","sources":["../src/items.ts"],"names":[],"mappings":"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"}
package/dist/items.js ADDED
@@ -0,0 +1,113 @@
1
+ import { z } from "zod";
2
+ import { CHAT_EVENTS } from "./events.js";
3
+ import { idSchema } from "./id-schemas.js";
4
+ import { MAX_PROMPT_CHARS } from "./limits.js";
5
+ const signature = z.object({
6
+ keyId: z.string(),
7
+ presence: z.enum(["none", "user"]),
8
+ format: z.enum(["es256-raw", "webauthn"]),
9
+ signature: z.string(),
10
+ authenticatorData: z.string().optional(),
11
+ clientDataJSON: z.string().optional(),
12
+ });
13
+ const signed = z.object({
14
+ deviceId: idSchema("device"),
15
+ at: z.number(),
16
+ signature,
17
+ /** The browser that approved the computer's connect proving it, so the computer trusts it unasked. */
18
+ pairing: z
19
+ .string()
20
+ .regex(/^[A-Za-z0-9_-]{43}$/)
21
+ .optional(),
22
+ });
23
+ const agentRef = z.object({ hostId: idSchema("host"), agentId: z.string().min(1) });
24
+ const askChoice = z.object({
25
+ id: z.string().min(1),
26
+ label: z.string(),
27
+ effect: z.enum(["allow_once", "allow_always", "reject_once", "reject_always"]),
28
+ });
29
+ /**
30
+ * The one table of item kinds: who writes each and the body it carries. Types, the
31
+ * server's parsers, the host's append type and the client's view all derive from it.
32
+ */
33
+ export const chatItemBodies = {
34
+ prompt: {
35
+ author: "user",
36
+ body: z.object({
37
+ text: z.string().min(1).max(MAX_PROMPT_CHARS),
38
+ agent: agentRef,
39
+ signed: signed.optional(),
40
+ }),
41
+ },
42
+ answer: {
43
+ author: "user",
44
+ body: z.object({
45
+ askId: idSchema("item"),
46
+ choice: z.string().min(1),
47
+ values: z
48
+ .record(z.string(), z.union([z.string(), z.number(), z.boolean()]))
49
+ .optional(),
50
+ signed: signed.optional(),
51
+ }),
52
+ },
53
+ cancel: { author: "user", body: z.object({}) },
54
+ reply: {
55
+ author: "agent",
56
+ body: z.object({ text: z.string(), interrupted: z.literal(true).optional() }),
57
+ },
58
+ reasoning: { author: "agent", body: z.object({ text: z.string() }) },
59
+ tool: {
60
+ author: "agent",
61
+ body: z.object({
62
+ title: z.string(),
63
+ tool: z.object({ kind: z.enum(["app", "local"]), name: z.string() }),
64
+ status: z.enum(["done", "failed", "cancelled"]),
65
+ detail: z.string().max(4_000).optional(),
66
+ }),
67
+ },
68
+ plan: {
69
+ author: "agent",
70
+ body: z.object({
71
+ entries: z.array(z.object({
72
+ content: z.string(),
73
+ status: z.enum(["pending", "in_progress", "completed"]),
74
+ })),
75
+ }),
76
+ },
77
+ ask: {
78
+ author: "agent",
79
+ body: z.object({
80
+ question: z.string(),
81
+ choices: z.array(askChoice),
82
+ form: z.record(z.string(), z.unknown()).optional(),
83
+ /**
84
+ * Set by the host's policy, never by the app. Absent: any device answers from the
85
+ * chat, without presence.
86
+ */
87
+ approval: z.enum(["presence", "computer"]).optional(),
88
+ }),
89
+ },
90
+ event: {
91
+ author: "system",
92
+ body: z.object({
93
+ event: z.enum(CHAT_EVENTS),
94
+ detail: z.string().max(500).optional(),
95
+ itemId: idSchema("item").optional(),
96
+ choice: z.string().min(1).optional(),
97
+ }),
98
+ },
99
+ };
100
+ const draft = (kind) => z.object({
101
+ id: idSchema("item"),
102
+ kind: z.literal(kind),
103
+ body: chatItemBodies[kind].body,
104
+ });
105
+ export const hostItemDraft = z.discriminatedUnion("kind", [
106
+ draft("reply"),
107
+ draft("reasoning"),
108
+ draft("tool"),
109
+ draft("plan"),
110
+ draft("ask"),
111
+ draft("event"),
112
+ ]);
113
+ //# sourceMappingURL=items.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"items.js","sourceRoot":"","sources":["../src/items.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACzC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACxC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACtC,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACtB,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC;IAC5B,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,SAAS;IACT,sGAAsG;IACtG,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,KAAK,CAAC,qBAAqB,CAAC;SAC5B,QAAQ,EAAE;CACd,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAEpF,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC;CAC/E,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,MAAM,EAAE;QACN,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;YACb,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC;YAC7C,KAAK,EAAE,QAAQ;YACf,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE;SAC1B,CAAC;KACH;IACD,MAAM,EAAE;QACN,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;YACb,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC;YACvB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YACzB,MAAM,EAAE,CAAC;iBACN,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;iBAClE,QAAQ,EAAE;YACb,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE;SAC1B,CAAC;KACH;IACD,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;IAC9C,KAAK,EAAE;QACL,MAAM,EAAE,OAAO;QACf,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;KAC9E;IACD,SAAS,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;IACpE,IAAI,EAAE;QACJ,MAAM,EAAE,OAAO;QACf,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;YACb,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;YACjB,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;YACpE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;YAC/C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE;SACzC,CAAC;KACH;IACD,IAAI,EAAE;QACJ,MAAM,EAAE,OAAO;QACf,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;YACb,OAAO,EAAE,CAAC,CAAC,KAAK,CACd,CAAC,CAAC,MAAM,CAAC;gBACP,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;gBACnB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;aACxD,CAAC,CACH;SACF,CAAC;KACH;IACD,GAAG,EAAE;QACH,MAAM,EAAE,OAAO;QACf,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;YACb,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;YACpB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC;YAC3B,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;YAClD;;;eAGG;YACH,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE;SACtD,CAAC;KACH;IACD,KAAK,EAAE;QACL,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;YACb,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;YAC1B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;YACtC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;YACnC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;SACrC,CAAC;KACH;CACO,CAAC;AA0CX,MAAM,KAAK,GAAG,CACZ,IAAO,EAKN,EAAE,CACH,CAAC,CAAC,MAAM,CAAC;IACP,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC;IACpB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IACrB,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,IAAyB;CACrD,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IACxD,KAAK,CAAC,OAAO,CAAC;IACd,KAAK,CAAC,WAAW,CAAC;IAClB,KAAK,CAAC,MAAM,CAAC;IACb,KAAK,CAAC,MAAM,CAAC;IACb,KAAK,CAAC,KAAK,CAAC;IACZ,KAAK,CAAC,OAAO,CAAC;CACf,CAAC,CAAC","sourcesContent":["import type { ItemId, ThreadId, TurnId } from \"@parlor/core\";\nimport { z } from \"zod\";\n\nimport { CHAT_EVENTS } from \"./events.js\";\nimport { idSchema } from \"./id-schemas.js\";\nimport { MAX_PROMPT_CHARS } from \"./limits.js\";\n\nconst signature = z.object({\n keyId: z.string(),\n presence: z.enum([\"none\", \"user\"]),\n format: z.enum([\"es256-raw\", \"webauthn\"]),\n signature: z.string(),\n authenticatorData: z.string().optional(),\n clientDataJSON: z.string().optional(),\n});\n\nconst signed = z.object({\n deviceId: idSchema(\"device\"),\n at: z.number(),\n signature,\n /** The browser that approved the computer's connect proving it, so the computer trusts it unasked. */\n pairing: z\n .string()\n .regex(/^[A-Za-z0-9_-]{43}$/)\n .optional(),\n});\n\nconst agentRef = z.object({ hostId: idSchema(\"host\"), agentId: z.string().min(1) });\n\nconst askChoice = z.object({\n id: z.string().min(1),\n label: z.string(),\n effect: z.enum([\"allow_once\", \"allow_always\", \"reject_once\", \"reject_always\"]),\n});\n\n/**\n * The one table of item kinds: who writes each and the body it carries. Types, the\n * server's parsers, the host's append type and the client's view all derive from it.\n */\nexport const chatItemBodies = {\n prompt: {\n author: \"user\",\n body: z.object({\n text: z.string().min(1).max(MAX_PROMPT_CHARS),\n agent: agentRef,\n signed: signed.optional(),\n }),\n },\n answer: {\n author: \"user\",\n body: z.object({\n askId: idSchema(\"item\"),\n choice: z.string().min(1),\n values: z\n .record(z.string(), z.union([z.string(), z.number(), z.boolean()]))\n .optional(),\n signed: signed.optional(),\n }),\n },\n cancel: { author: \"user\", body: z.object({}) },\n reply: {\n author: \"agent\",\n body: z.object({ text: z.string(), interrupted: z.literal(true).optional() }),\n },\n reasoning: { author: \"agent\", body: z.object({ text: z.string() }) },\n tool: {\n author: \"agent\",\n body: z.object({\n title: z.string(),\n tool: z.object({ kind: z.enum([\"app\", \"local\"]), name: z.string() }),\n status: z.enum([\"done\", \"failed\", \"cancelled\"]),\n detail: z.string().max(4_000).optional(),\n }),\n },\n plan: {\n author: \"agent\",\n body: z.object({\n entries: z.array(\n z.object({\n content: z.string(),\n status: z.enum([\"pending\", \"in_progress\", \"completed\"]),\n }),\n ),\n }),\n },\n ask: {\n author: \"agent\",\n body: z.object({\n question: z.string(),\n choices: z.array(askChoice),\n form: z.record(z.string(), z.unknown()).optional(),\n /**\n * Set by the host's policy, never by the app. Absent: any device answers from the\n * chat, without presence.\n */\n approval: z.enum([\"presence\", \"computer\"]).optional(),\n }),\n },\n event: {\n author: \"system\",\n body: z.object({\n event: z.enum(CHAT_EVENTS),\n detail: z.string().max(500).optional(),\n itemId: idSchema(\"item\").optional(),\n choice: z.string().min(1).optional(),\n }),\n },\n} as const;\n\ntype Bodies = typeof chatItemBodies;\n\nexport type ChatItemKind = keyof Bodies;\nexport type Author = Bodies[ChatItemKind][\"author\"];\nexport type AuthorOf<K extends ChatItemKind> = Bodies[K][\"author\"];\nexport type ChatItemBody<K extends ChatItemKind> = z.output<Bodies[K][\"body\"]>;\nexport type ItemSignature = z.output<typeof signed>;\n\ntype KindsBy<A extends Author> = {\n [K in ChatItemKind]: AuthorOf<K> extends A ? K : never;\n}[ChatItemKind];\n\n/** Appended only by the user's devices, through the user actions. */\nexport type UserItemKind = KindsBy<\"user\">;\n/** Appended only by the user's computer, through the host actions. */\nexport type HostItemKind = KindsBy<\"agent\" | \"system\">;\n\nexport type LoggedItem<K extends ChatItemKind = ChatItemKind> = {\n [Kind in K]: {\n readonly id: ItemId;\n readonly threadId: ThreadId;\n readonly turnId: TurnId;\n /** Gap-free per thread, assigned under the thread row's lock. */\n readonly seq: number;\n readonly at: number;\n readonly author: AuthorOf<Kind>;\n readonly kind: Kind;\n readonly body: ChatItemBody<Kind>;\n };\n}[K];\n\n/** Its id is `<turnId>.<n>`, chosen by the host, so a retried append is a no-op. */\nexport type HostItemDraft = {\n [K in HostItemKind]: {\n readonly id: ItemId;\n readonly kind: K;\n readonly body: ChatItemBody<K>;\n };\n}[HostItemKind];\n\nconst draft = <K extends HostItemKind>(\n kind: K,\n): z.ZodObject<{\n id: ReturnType<typeof idSchema<\"item\">>;\n kind: z.ZodLiteral<K>;\n body: Bodies[K][\"body\"];\n}> =>\n z.object({\n id: idSchema(\"item\"),\n kind: z.literal(kind),\n body: chatItemBodies[kind].body as Bodies[K][\"body\"],\n });\n\nexport const hostItemDraft = z.discriminatedUnion(\"kind\", [\n draft(\"reply\"),\n draft(\"reasoning\"),\n draft(\"tool\"),\n draft(\"plan\"),\n draft(\"ask\"),\n draft(\"event\"),\n]);\n"]}
@@ -0,0 +1,4 @@
1
+ export declare const MAX_PROMPT_CHARS = 32000;
2
+ export declare const PROMPT_LIMIT_MESSAGE: string;
3
+ export declare const isPromptTooLong: (text: string) => boolean;
4
+ //# sourceMappingURL=limits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,QAAS,CAAC;AAEvC,eAAO,MAAM,oBAAoB,QAAoF,CAAC;AAEtH,eAAO,MAAM,eAAe,SAAU,MAAM,KAAG,OACR,CAAC"}
package/dist/limits.js ADDED
@@ -0,0 +1,4 @@
1
+ export const MAX_PROMPT_CHARS = 32_000;
2
+ export const PROMPT_LIMIT_MESSAGE = `Messages can be at most ${MAX_PROMPT_CHARS.toLocaleString("en-US")} characters.`;
3
+ export const isPromptTooLong = (text) => text.trim().length > MAX_PROMPT_CHARS;
4
+ //# sourceMappingURL=limits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limits.js","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEvC,MAAM,CAAC,MAAM,oBAAoB,GAAG,2BAA2B,gBAAgB,CAAC,cAAc,CAAC,OAAO,CAAC,cAAc,CAAC;AAEtH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAY,EAAW,EAAE,CACvD,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,gBAAgB,CAAC","sourcesContent":["export const MAX_PROMPT_CHARS = 32_000;\n\nexport const PROMPT_LIMIT_MESSAGE = `Messages can be at most ${MAX_PROMPT_CHARS.toLocaleString(\"en-US\")} characters.`;\n\nexport const isPromptTooLong = (text: string): boolean =>\n text.trim().length > MAX_PROMPT_CHARS;\n"]}