@agentskit/chat-protocol 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.
package/dist/index.cjs ADDED
@@ -0,0 +1,902 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ ANSWER_MAX_CITATIONS: () => ANSWER_MAX_CITATIONS,
24
+ ANSWER_MAX_SUGGESTIONS: () => ANSWER_MAX_SUGGESTIONS,
25
+ ANSWER_PROTOCOL: () => ANSWER_PROTOCOL,
26
+ ANSWER_PROTOCOL_VERSION: () => ANSWER_PROTOCOL_VERSION,
27
+ ASK_EVENT_MAX_BYTES: () => ASK_EVENT_MAX_BYTES,
28
+ ASK_EVENT_MAX_RECORDS: () => ASK_EVENT_MAX_RECORDS,
29
+ ASK_SERVICE_PROTOCOL_VERSION: () => ASK_SERVICE_PROTOCOL_VERSION,
30
+ ASSISTANT_CONTENT_MAX_BYTES: () => ASSISTANT_CONTENT_MAX_BYTES,
31
+ ASSISTANT_CONTENT_MAX_RECORDS: () => ASSISTANT_CONTENT_MAX_RECORDS,
32
+ ASSISTANT_CONTENT_PREFIX: () => ASSISTANT_CONTENT_PREFIX,
33
+ ASSISTANT_CONTENT_PROTOCOL: () => ASSISTANT_CONTENT_PROTOCOL,
34
+ ASSISTANT_CONTENT_PROTOCOL_VERSION: () => ASSISTANT_CONTENT_PROTOCOL_VERSION,
35
+ AnswerCitationSchema: () => AnswerCitationSchema,
36
+ AnswerConfidenceSchema: () => AnswerConfidenceSchema,
37
+ AnswerResponseSchema: () => AnswerResponseSchema,
38
+ AnswerSuggestionSchema: () => AnswerSuggestionSchema,
39
+ AskEventSchema: () => AskEventSchema,
40
+ AssistantComponentPartSchema: () => AssistantComponentPartSchema,
41
+ AssistantContentPartSchema: () => AssistantContentPartSchema,
42
+ AssistantTextPartSchema: () => AssistantTextPartSchema,
43
+ COMPONENT_PROTOCOL: () => COMPONENT_PROTOCOL,
44
+ COMPONENT_PROTOCOL_VERSION: () => COMPONENT_PROTOCOL_VERSION,
45
+ ComponentFallbackSchema: () => ComponentFallbackSchema,
46
+ ComponentInteractionEventSchema: () => ComponentInteractionEventSchema,
47
+ ComponentKeySchema: () => ComponentKeySchema,
48
+ ComponentRenderFrameSchema: () => ComponentRenderFrameSchema,
49
+ ComponentSelectionEventSchema: () => ComponentSelectionEventSchema,
50
+ DETERMINISTIC_ARTIFACT_MAX_BYTES: () => DETERMINISTIC_ARTIFACT_MAX_BYTES,
51
+ DETERMINISTIC_ARTIFACT_MAX_ENTRIES: () => DETERMINISTIC_ARTIFACT_MAX_ENTRIES,
52
+ DETERMINISTIC_KNOWLEDGE_PROTOCOL: () => DETERMINISTIC_KNOWLEDGE_PROTOCOL,
53
+ DETERMINISTIC_KNOWLEDGE_PROTOCOL_VERSION: () => DETERMINISTIC_KNOWLEDGE_PROTOCOL_VERSION,
54
+ DETERMINISTIC_MATCH_MAX_VALUES: () => DETERMINISTIC_MATCH_MAX_VALUES,
55
+ DETERMINISTIC_QUERY_MAX_CHARS: () => DETERMINISTIC_QUERY_MAX_CHARS,
56
+ DETERMINISTIC_SITE_PROTOCOL: () => DETERMINISTIC_SITE_PROTOCOL,
57
+ DETERMINISTIC_SITE_PROTOCOL_VERSION: () => DETERMINISTIC_SITE_PROTOCOL_VERSION,
58
+ DeterministicKnowledgeEntrySchema: () => DeterministicKnowledgeEntrySchema,
59
+ DeterministicSiteConfigSchema: () => DeterministicSiteConfigSchema,
60
+ LocalKnowledgeArtifactSchema: () => LocalKnowledgeArtifactSchema,
61
+ SESSION_PROTOCOL: () => SESSION_PROTOCOL,
62
+ SESSION_PROTOCOL_VERSION: () => SESSION_PROTOCOL_VERSION,
63
+ SessionConfirmationSchema: () => SessionConfirmationSchema,
64
+ SessionSnapshotSchema: () => SessionSnapshotSchema,
65
+ TURN_PROTOCOL: () => TURN_PROTOCOL,
66
+ TURN_PROTOCOL_VERSION: () => TURN_PROTOCOL_VERSION,
67
+ TokenUsageSchema: () => TokenUsageSchema,
68
+ TurnDiagnosticSchema: () => TurnDiagnosticSchema,
69
+ TurnEventSchema: () => TurnEventSchema,
70
+ canonicalizeLocalKnowledgeArtifact: () => canonicalizeLocalKnowledgeArtifact,
71
+ computeLocalKnowledgeArtifactContentHash: () => computeLocalKnowledgeArtifactContentHash,
72
+ createAssistantContentEncoder: () => createAssistantContentEncoder,
73
+ createInteractionEvent: () => createInteractionEvent,
74
+ createSelectionEvent: () => createSelectionEvent,
75
+ createSnapshotEvent: () => createSnapshotEvent,
76
+ createTurnSnapshotCursor: () => createTurnSnapshotCursor,
77
+ decodeAnswerResponse: () => decodeAnswerResponse,
78
+ decodeAskEvents: () => decodeAskEvents,
79
+ decodeAssistantContent: () => decodeAssistantContent,
80
+ decodeComponentFrame: () => decodeComponentFrame,
81
+ decodeDeterministicSiteConfig: () => decodeDeterministicSiteConfig,
82
+ decodeLocalKnowledgeArtifact: () => decodeLocalKnowledgeArtifact,
83
+ decodeSessionSnapshot: () => decodeSessionSnapshot,
84
+ decodeTurnEvent: () => decodeTurnEvent,
85
+ encodeTurnEvent: () => encodeTurnEvent,
86
+ isAssistantContentCandidate: () => isAssistantContentCandidate,
87
+ isComponentFrameCandidate: () => isComponentFrameCandidate,
88
+ normalizeKnowledgeKey: () => normalizeKnowledgeKey,
89
+ snapshotMessages: () => snapshotMessages,
90
+ verifyLocalKnowledgeArtifact: () => verifyLocalKnowledgeArtifact,
91
+ verifyLocalKnowledgeArtifactSync: () => verifyLocalKnowledgeArtifactSync
92
+ });
93
+ module.exports = __toCommonJS(index_exports);
94
+ var import_core = require("@agentskit/core");
95
+ var import_memory_validation = require("@agentskit/core/memory-validation");
96
+ var import_zod3 = require("zod");
97
+
98
+ // src/ask.ts
99
+ var import_zod = require("zod");
100
+ var ASK_EVENT_MAX_BYTES = 1048576;
101
+ var ASK_EVENT_MAX_RECORDS = 4096;
102
+ var ASK_SERVICE_PROTOCOL_VERSION = 1;
103
+ var AskArgsSchema = import_zod.z.record(import_zod.z.string().max(128), import_zod.z.unknown());
104
+ var AskEventSchema = import_zod.z.discriminatedUnion("type", [
105
+ import_zod.z.object({ type: import_zod.z.literal("text"), delta: import_zod.z.string().max(ASK_EVENT_MAX_BYTES) }).strict(),
106
+ import_zod.z.object({ type: import_zod.z.literal("tool"), id: import_zod.z.string().max(256), name: import_zod.z.string().max(128), args: AskArgsSchema }).strict(),
107
+ import_zod.z.object({ type: import_zod.z.literal("done"), model: import_zod.z.string().max(256).optional() }).strict(),
108
+ import_zod.z.object({ type: import_zod.z.literal("error"), message: import_zod.z.string().min(1).max(4096) }).strict()
109
+ ]);
110
+ var byteLength = (value) => new TextEncoder().encode(value).byteLength;
111
+ function decodeAskEvents(buffer) {
112
+ const events = [];
113
+ let cursor = 0;
114
+ let records = 0;
115
+ while (records < ASK_EVENT_MAX_RECORDS) {
116
+ const lineEnd = buffer.indexOf("\n", cursor);
117
+ if (lineEnd < 0) break;
118
+ const line = buffer.slice(cursor, lineEnd);
119
+ cursor = lineEnd + 1;
120
+ records += 1;
121
+ const candidate = line.trim();
122
+ if (candidate === "" || byteLength(candidate) > ASK_EVENT_MAX_BYTES) continue;
123
+ try {
124
+ const parsed = AskEventSchema.safeParse(JSON.parse(candidate));
125
+ if (parsed.success) events.push(parsed.data);
126
+ } catch {
127
+ }
128
+ }
129
+ if (records === ASK_EVENT_MAX_RECORDS) {
130
+ const lastLineEnd = buffer.lastIndexOf("\n");
131
+ if (lastLineEnd >= cursor) cursor = lastLineEnd + 1;
132
+ }
133
+ const partial = buffer.slice(cursor);
134
+ const discardedPartial = byteLength(partial) > ASK_EVENT_MAX_BYTES;
135
+ return { events: Object.freeze(events), rest: discardedPartial ? "" : partial, discardedPartial };
136
+ }
137
+
138
+ // src/deterministic.ts
139
+ var import_sha2 = require("@noble/hashes/sha2.js");
140
+ var import_utils = require("@noble/hashes/utils.js");
141
+ var import_zod2 = require("zod");
142
+ var DETERMINISTIC_SITE_PROTOCOL = "agentskit.chat.site";
143
+ var DETERMINISTIC_SITE_PROTOCOL_VERSION = 1;
144
+ var DETERMINISTIC_KNOWLEDGE_PROTOCOL = "agentskit.chat.knowledge";
145
+ var DETERMINISTIC_KNOWLEDGE_PROTOCOL_VERSION = 1;
146
+ var ANSWER_PROTOCOL = "agentskit.chat.answer";
147
+ var ANSWER_PROTOCOL_VERSION = 1;
148
+ var DETERMINISTIC_ARTIFACT_MAX_BYTES = 524288;
149
+ var DETERMINISTIC_ARTIFACT_MAX_ENTRIES = 1024;
150
+ var DETERMINISTIC_MATCH_MAX_VALUES = 16;
151
+ var DETERMINISTIC_QUERY_MAX_CHARS = 512;
152
+ var ANSWER_MAX_CITATIONS = 8;
153
+ var ANSWER_MAX_SUGGESTIONS = 8;
154
+ var SafeIdentifierSchema = import_zod2.z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/);
155
+ var ContentHashSchema = import_zod2.z.string().regex(/^sha256:[a-f0-9]{64}$/);
156
+ var DateTimeSchema = import_zod2.z.string().datetime({ offset: true });
157
+ var isSafeHref = (value) => {
158
+ if (/[\u0000-\u001F\u007F\\]/u.test(value)) return false;
159
+ if (value.startsWith("//")) return false;
160
+ if (!/^[A-Za-z][A-Za-z0-9+.-]*:/.test(value)) {
161
+ return /^\/(?!\/)/.test(value);
162
+ }
163
+ try {
164
+ const url = new URL(value);
165
+ return (url.protocol === "http:" || url.protocol === "https:") && url.username === "" && url.password === "";
166
+ } catch {
167
+ return false;
168
+ }
169
+ };
170
+ var SafeHrefSchema = import_zod2.z.string().min(1).max(2048).refine(isSafeHref, "Link must be a safe relative, HTTP, or HTTPS URL.");
171
+ var normalizeKnowledgeKey = (value) => value.normalize("NFKC").trim().replace(/\s+/gu, " ").toLocaleLowerCase("en-US");
172
+ var DeterministicSiteConfigSchema = import_zod2.z.object({
173
+ protocol: import_zod2.z.literal(DETERMINISTIC_SITE_PROTOCOL),
174
+ version: import_zod2.z.literal(DETERMINISTIC_SITE_PROTOCOL_VERSION),
175
+ siteId: SafeIdentifierSchema,
176
+ artifact: import_zod2.z.object({
177
+ href: SafeHrefSchema,
178
+ contentHash: ContentHashSchema
179
+ }).readonly(),
180
+ fallback: import_zod2.z.object({ mode: import_zod2.z.enum(["backend", "disabled"]) }).readonly()
181
+ }).readonly();
182
+ var AnswerCitationSchema = import_zod2.z.object({
183
+ id: SafeIdentifierSchema,
184
+ title: import_zod2.z.string().trim().min(1).max(256),
185
+ href: SafeHrefSchema
186
+ }).readonly();
187
+ var DeterministicKnowledgeEntrySchema = import_zod2.z.object({
188
+ id: SafeIdentifierSchema,
189
+ kind: import_zod2.z.enum(["command", "package", "navigation", "contribution", "ecosystem", "restricted-faq", "document"]),
190
+ label: import_zod2.z.string().trim().min(1).max(256),
191
+ match: import_zod2.z.object({
192
+ type: import_zod2.z.literal("exact"),
193
+ values: import_zod2.z.array(import_zod2.z.string().trim().min(1).max(DETERMINISTIC_QUERY_MAX_CHARS)).min(1).max(DETERMINISTIC_MATCH_MAX_VALUES).superRefine((values, context) => {
194
+ const seen = /* @__PURE__ */ new Set();
195
+ values.forEach((value, index) => {
196
+ const normalized = normalizeKnowledgeKey(value);
197
+ if (normalized.length > DETERMINISTIC_QUERY_MAX_CHARS) {
198
+ context.addIssue({ code: "custom", path: [index], message: "Normalized match values must fit the deterministic query limit." });
199
+ }
200
+ if (seen.has(normalized)) context.addIssue({ code: "custom", path: [index], message: "Match values must be unique after normalization." });
201
+ seen.add(normalized);
202
+ });
203
+ }).readonly()
204
+ }).readonly(),
205
+ answer: import_zod2.z.object({
206
+ markdown: import_zod2.z.string().trim().min(1).max(16384),
207
+ citations: import_zod2.z.array(AnswerCitationSchema).max(ANSWER_MAX_CITATIONS).readonly()
208
+ }).readonly()
209
+ }).readonly();
210
+ var LocalKnowledgeArtifactSchema = import_zod2.z.object({
211
+ protocol: import_zod2.z.literal(DETERMINISTIC_KNOWLEDGE_PROTOCOL),
212
+ version: import_zod2.z.literal(DETERMINISTIC_KNOWLEDGE_PROTOCOL_VERSION),
213
+ artifactId: SafeIdentifierSchema,
214
+ siteId: SafeIdentifierSchema,
215
+ contentHash: ContentHashSchema,
216
+ generatedAt: DateTimeSchema,
217
+ expiresAt: DateTimeSchema.optional(),
218
+ entries: import_zod2.z.array(DeterministicKnowledgeEntrySchema).max(DETERMINISTIC_ARTIFACT_MAX_ENTRIES).readonly()
219
+ }).superRefine((artifact, context) => {
220
+ const ids = /* @__PURE__ */ new Set();
221
+ const aliases = /* @__PURE__ */ new Map();
222
+ artifact.entries.forEach((entry, index) => {
223
+ if (ids.has(entry.id)) context.addIssue({ code: "custom", path: ["entries", index, "id"], message: "Entry ids must be unique." });
224
+ ids.add(entry.id);
225
+ for (const value of entry.match.values) {
226
+ const key = normalizeKnowledgeKey(value);
227
+ const entryIds = aliases.get(key) ?? /* @__PURE__ */ new Set();
228
+ entryIds.add(entry.id);
229
+ aliases.set(key, entryIds);
230
+ }
231
+ });
232
+ artifact.entries.forEach((entry, index) => {
233
+ if (!entry.match.values.some((value) => aliases.get(normalizeKnowledgeKey(value))?.size === 1)) {
234
+ context.addIssue({ code: "custom", path: ["entries", index, "match", "values"], message: "Every entry must have at least one globally unique exact alias." });
235
+ }
236
+ });
237
+ if (artifact.expiresAt !== void 0 && Date.parse(artifact.expiresAt) <= Date.parse(artifact.generatedAt)) {
238
+ context.addIssue({ code: "custom", path: ["expiresAt"], message: "Expiration must be after generation." });
239
+ }
240
+ }).readonly();
241
+ var AnswerConfidenceSchema = import_zod2.z.object({
242
+ level: import_zod2.z.enum(["high", "medium", "low"]),
243
+ basis: import_zod2.z.enum(["exact", "ambiguous", "miss", "stale", "corrupt", "offline", "backend"])
244
+ }).readonly();
245
+ var LocalProvenanceSchema = import_zod2.z.object({
246
+ source: import_zod2.z.literal("local"),
247
+ artifactId: SafeIdentifierSchema,
248
+ contentHash: ContentHashSchema,
249
+ entryIds: import_zod2.z.array(SafeIdentifierSchema).min(1).max(ANSWER_MAX_SUGGESTIONS).readonly()
250
+ }).readonly();
251
+ var BackendProvenanceSchema = import_zod2.z.object({
252
+ source: import_zod2.z.literal("backend"),
253
+ provider: import_zod2.z.string().trim().min(1).max(128).optional(),
254
+ model: import_zod2.z.string().trim().min(1).max(128).optional()
255
+ }).readonly();
256
+ var AnswerSuggestionSchema = import_zod2.z.object({
257
+ id: SafeIdentifierSchema,
258
+ label: import_zod2.z.string().trim().min(1).max(256),
259
+ value: import_zod2.z.string().trim().min(1).max(DETERMINISTIC_QUERY_MAX_CHARS)
260
+ }).readonly();
261
+ var AnswerQuerySchema = import_zod2.z.string().max(DETERMINISTIC_QUERY_MAX_CHARS);
262
+ var AnswerResponseSchema = import_zod2.z.discriminatedUnion("outcome", [
263
+ import_zod2.z.object({
264
+ protocol: import_zod2.z.literal(ANSWER_PROTOCOL),
265
+ version: import_zod2.z.literal(ANSWER_PROTOCOL_VERSION),
266
+ outcome: import_zod2.z.literal("answer"),
267
+ query: AnswerQuerySchema,
268
+ normalizedQuery: AnswerQuerySchema,
269
+ answer: import_zod2.z.object({ markdown: import_zod2.z.string().min(1).max(16384), citations: import_zod2.z.array(AnswerCitationSchema).max(ANSWER_MAX_CITATIONS).readonly() }).readonly(),
270
+ provenance: import_zod2.z.union([LocalProvenanceSchema, BackendProvenanceSchema]),
271
+ confidence: AnswerConfidenceSchema
272
+ }).readonly(),
273
+ import_zod2.z.object({
274
+ protocol: import_zod2.z.literal(ANSWER_PROTOCOL),
275
+ version: import_zod2.z.literal(ANSWER_PROTOCOL_VERSION),
276
+ outcome: import_zod2.z.literal("choices"),
277
+ query: AnswerQuerySchema,
278
+ normalizedQuery: AnswerQuerySchema,
279
+ message: import_zod2.z.string().min(1).max(4096),
280
+ suggestions: import_zod2.z.array(AnswerSuggestionSchema).min(2).max(ANSWER_MAX_SUGGESTIONS).readonly(),
281
+ provenance: LocalProvenanceSchema,
282
+ confidence: AnswerConfidenceSchema
283
+ }).readonly(),
284
+ import_zod2.z.object({
285
+ protocol: import_zod2.z.literal(ANSWER_PROTOCOL),
286
+ version: import_zod2.z.literal(ANSWER_PROTOCOL_VERSION),
287
+ outcome: import_zod2.z.literal("escalation"),
288
+ query: AnswerQuerySchema,
289
+ normalizedQuery: AnswerQuerySchema,
290
+ message: import_zod2.z.string().min(1).max(4096),
291
+ reason: import_zod2.z.enum(["miss", "stale", "corrupt", "offline"]),
292
+ candidateEntryIds: import_zod2.z.array(SafeIdentifierSchema).max(ANSWER_MAX_SUGGESTIONS).readonly().optional(),
293
+ confidence: AnswerConfidenceSchema
294
+ }).readonly()
295
+ ]).superRefine((response, context) => {
296
+ if (response.normalizedQuery !== normalizeKnowledgeKey(response.query).slice(0, DETERMINISTIC_QUERY_MAX_CHARS)) {
297
+ context.addIssue({ code: "custom", path: ["normalizedQuery"], message: "Normalized query must match the canonical normalization rule." });
298
+ }
299
+ if (response.outcome === "answer") {
300
+ const validLocal = response.provenance.source === "local" && response.confidence.level === "high" && response.confidence.basis === "exact" && response.provenance.entryIds.length === 1;
301
+ const validBackend = response.provenance.source === "backend" && response.confidence.level === "high" && response.confidence.basis === "backend";
302
+ if (!validLocal && !validBackend) context.addIssue({ code: "custom", path: ["confidence"], message: "Answer confidence must match its provenance." });
303
+ } else if (response.outcome === "choices") {
304
+ if (response.confidence.level !== "medium" || response.confidence.basis !== "ambiguous") {
305
+ context.addIssue({ code: "custom", path: ["confidence"], message: "Choices require medium ambiguous confidence." });
306
+ }
307
+ const suggestionIds = response.suggestions.map((suggestion) => suggestion.id);
308
+ if (suggestionIds.length !== response.provenance.entryIds.length || suggestionIds.some((id, index) => id !== response.provenance.entryIds[index])) {
309
+ context.addIssue({ code: "custom", path: ["provenance", "entryIds"], message: "Choice provenance must match suggestions in order." });
310
+ }
311
+ } else if (response.confidence.level !== "low" || response.confidence.basis !== response.reason) {
312
+ context.addIssue({ code: "custom", path: ["confidence"], message: "Escalation confidence must match its reason." });
313
+ }
314
+ });
315
+ var failure = (code, message) => ({
316
+ ok: false,
317
+ diagnostic: { code, message, retryable: false }
318
+ });
319
+ var parseBoundedInput = (input, schema, protocol, version, maxBytes) => {
320
+ let candidate = input;
321
+ if (typeof input === "string") {
322
+ if (maxBytes !== void 0 && new TextEncoder().encode(input).byteLength > maxBytes) {
323
+ return failure("DETERMINISTIC_LIMIT_EXCEEDED", "Deterministic payload exceeds its safety limit.");
324
+ }
325
+ try {
326
+ candidate = JSON.parse(input);
327
+ } catch {
328
+ return failure("DETERMINISTIC_INVALID_PAYLOAD", "Deterministic payload is not valid JSON.");
329
+ }
330
+ }
331
+ try {
332
+ if (typeof candidate === "object" && candidate !== null && !Array.isArray(candidate)) {
333
+ const record = candidate;
334
+ if (record.protocol === protocol && typeof record.version === "number" && record.version !== version) {
335
+ return failure("DETERMINISTIC_UNSUPPORTED_VERSION", "Deterministic payload uses an unsupported version.");
336
+ }
337
+ }
338
+ const parsed = schema.safeParse(candidate);
339
+ if (!parsed.success) return failure("DETERMINISTIC_INVALID_PAYLOAD", "Deterministic payload is invalid.");
340
+ if (maxBytes !== void 0 && typeof input !== "string" && new TextEncoder().encode(JSON.stringify(parsed.data)).byteLength > maxBytes) {
341
+ return failure("DETERMINISTIC_LIMIT_EXCEEDED", "Deterministic payload exceeds its safety limit.");
342
+ }
343
+ return { ok: true, value: parsed.data };
344
+ } catch {
345
+ return failure("DETERMINISTIC_INVALID_PAYLOAD", "Deterministic payload is invalid.");
346
+ }
347
+ };
348
+ var decodeDeterministicSiteConfig = (input) => parseBoundedInput(input, DeterministicSiteConfigSchema, DETERMINISTIC_SITE_PROTOCOL, DETERMINISTIC_SITE_PROTOCOL_VERSION, 16384);
349
+ var decodeLocalKnowledgeArtifact = (input, options = {}) => {
350
+ const decoded = parseBoundedInput(input, LocalKnowledgeArtifactSchema, DETERMINISTIC_KNOWLEDGE_PROTOCOL, DETERMINISTIC_KNOWLEDGE_PROTOCOL_VERSION, DETERMINISTIC_ARTIFACT_MAX_BYTES);
351
+ if (!decoded.ok) return decoded;
352
+ if (options.expectedContentHash !== void 0 && decoded.value.contentHash !== options.expectedContentHash) {
353
+ return failure("DETERMINISTIC_HASH_MISMATCH", "Deterministic artifact does not match the configured content hash.");
354
+ }
355
+ if (options.expectedSiteId !== void 0 && decoded.value.siteId !== options.expectedSiteId) {
356
+ return failure("DETERMINISTIC_INVALID_PAYLOAD", "Deterministic artifact belongs to a different site.");
357
+ }
358
+ return decoded;
359
+ };
360
+ var canonicalizeLocalKnowledgeArtifact = (artifact) => JSON.stringify({
361
+ protocol: artifact.protocol,
362
+ version: artifact.version,
363
+ artifactId: artifact.artifactId,
364
+ siteId: artifact.siteId,
365
+ generatedAt: artifact.generatedAt,
366
+ ...artifact.expiresAt === void 0 ? {} : { expiresAt: artifact.expiresAt },
367
+ entries: artifact.entries.map((entry) => ({
368
+ id: entry.id,
369
+ kind: entry.kind,
370
+ label: entry.label,
371
+ match: { type: entry.match.type, values: [...entry.match.values] },
372
+ answer: {
373
+ markdown: entry.answer.markdown,
374
+ citations: entry.answer.citations.map((citation) => ({ id: citation.id, title: citation.title, href: citation.href }))
375
+ }
376
+ }))
377
+ });
378
+ var HASH_PLACEHOLDER = `sha256:${"0".repeat(64)}`;
379
+ var calculateLocalKnowledgeArtifactContentHash = (artifactInput) => {
380
+ const decoded = decodeLocalKnowledgeArtifact({ ...artifactInput, contentHash: HASH_PLACEHOLDER });
381
+ if (!decoded.ok) throw new TypeError(decoded.diagnostic.message);
382
+ const digest = (0, import_sha2.sha256)(new TextEncoder().encode(canonicalizeLocalKnowledgeArtifact(decoded.value)));
383
+ return `sha256:${(0, import_utils.bytesToHex)(digest)}`;
384
+ };
385
+ var computeLocalKnowledgeArtifactContentHash = async (artifactInput) => calculateLocalKnowledgeArtifactContentHash(artifactInput);
386
+ var TrustedArtifactOptionsSchema = import_zod2.z.object({
387
+ expectedContentHash: ContentHashSchema,
388
+ expectedSiteId: SafeIdentifierSchema
389
+ }).readonly();
390
+ var verifyLocalKnowledgeArtifactSync = (input, options) => {
391
+ const trusted = TrustedArtifactOptionsSchema.safeParse(options);
392
+ if (!trusted.success) return failure("DETERMINISTIC_INVALID_PAYLOAD", "Trusted deterministic artifact configuration is invalid.");
393
+ const decoded = decodeLocalKnowledgeArtifact(input, trusted.data);
394
+ if (!decoded.ok) return decoded;
395
+ try {
396
+ const actual = calculateLocalKnowledgeArtifactContentHash(decoded.value);
397
+ if (actual !== decoded.value.contentHash) {
398
+ return failure("DETERMINISTIC_HASH_MISMATCH", "Deterministic artifact content does not match its SHA-256 hash.");
399
+ }
400
+ return { ok: true, value: decoded.value };
401
+ } catch {
402
+ return failure("DETERMINISTIC_INVALID_PAYLOAD", "Deterministic artifact integrity could not be verified.");
403
+ }
404
+ };
405
+ var verifyLocalKnowledgeArtifact = async (input, options) => verifyLocalKnowledgeArtifactSync(input, options);
406
+ var decodeAnswerResponse = (input) => parseBoundedInput(input, AnswerResponseSchema, ANSWER_PROTOCOL, ANSWER_PROTOCOL_VERSION, 262144);
407
+
408
+ // src/index.ts
409
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
410
+ var isBoundedJsonValue = (input) => {
411
+ const seen = /* @__PURE__ */ new WeakSet();
412
+ let nodes = 0;
413
+ const visit = (value, depth) => {
414
+ nodes += 1;
415
+ if (nodes > 1e3 || depth > 20) return false;
416
+ if (value === null || typeof value === "boolean") return true;
417
+ if (typeof value === "string") return value.length <= 16384;
418
+ if (typeof value === "number") return Number.isFinite(value);
419
+ if (typeof value !== "object") return false;
420
+ if (seen.has(value)) return false;
421
+ seen.add(value);
422
+ if (Array.isArray(value)) return value.length <= 1e3 && value.every((item) => visit(item, depth + 1));
423
+ if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) return false;
424
+ const entries = Object.entries(value);
425
+ return entries.length <= 1e3 && entries.every(([key, item]) => key.length <= 256 && visit(item, depth + 1));
426
+ };
427
+ try {
428
+ return visit(input, 0);
429
+ } catch {
430
+ return false;
431
+ }
432
+ };
433
+ var TURN_PROTOCOL = "agentskit.chat.turn";
434
+ var TURN_PROTOCOL_VERSION = 1;
435
+ var COMPONENT_PROTOCOL = "agentskit.chat.component";
436
+ var COMPONENT_PROTOCOL_VERSION = 1;
437
+ var ASSISTANT_CONTENT_PROTOCOL = "agentskit.chat.content";
438
+ var ASSISTANT_CONTENT_PROTOCOL_VERSION = 1;
439
+ var ASSISTANT_CONTENT_PREFIX = `${ASSISTANT_CONTENT_PROTOCOL}/${ASSISTANT_CONTENT_PROTOCOL_VERSION}
440
+ `;
441
+ var ASSISTANT_CONTENT_PREFIX_ROOT = `${ASSISTANT_CONTENT_PROTOCOL}/`;
442
+ var ASSISTANT_CONTENT_MAX_BYTES = 262144;
443
+ var ASSISTANT_CONTENT_MAX_RECORDS = 512;
444
+ var ComponentKeySchema = import_zod3.z.string().regex(/^[a-z][a-z0-9-]{0,63}$/);
445
+ var ComponentFallbackSchema = import_zod3.z.object({
446
+ kind: import_zod3.z.string().min(1).max(64),
447
+ summary: import_zod3.z.string().min(1).max(4096)
448
+ }).readonly();
449
+ var ComponentRenderFrameSchema = import_zod3.z.object({
450
+ protocol: import_zod3.z.literal(COMPONENT_PROTOCOL),
451
+ version: import_zod3.z.literal(COMPONENT_PROTOCOL_VERSION),
452
+ type: import_zod3.z.literal("render"),
453
+ componentKey: ComponentKeySchema,
454
+ instanceId: import_zod3.z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/),
455
+ props: import_zod3.z.unknown().refine(isBoundedJsonValue),
456
+ fallback: ComponentFallbackSchema
457
+ }).readonly();
458
+ var ComponentSelectionEventSchema = import_zod3.z.object({
459
+ protocol: import_zod3.z.literal(COMPONENT_PROTOCOL),
460
+ version: import_zod3.z.literal(COMPONENT_PROTOCOL_VERSION),
461
+ type: import_zod3.z.literal("select"),
462
+ componentKey: ComponentKeySchema,
463
+ instanceId: import_zod3.z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/),
464
+ choiceId: import_zod3.z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/)
465
+ }).readonly();
466
+ var ComponentInteractionEventSchema = import_zod3.z.object({
467
+ protocol: import_zod3.z.literal(COMPONENT_PROTOCOL),
468
+ version: import_zod3.z.literal(COMPONENT_PROTOCOL_VERSION),
469
+ type: import_zod3.z.literal("interact"),
470
+ componentKey: ComponentKeySchema,
471
+ instanceId: import_zod3.z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/),
472
+ event: import_zod3.z.string().regex(/^[a-z][a-z0-9-]{0,63}$/),
473
+ value: import_zod3.z.unknown().refine(isBoundedJsonValue).optional()
474
+ }).readonly();
475
+ var AssistantTextPartSchema = import_zod3.z.object({
476
+ kind: import_zod3.z.literal("text"),
477
+ text: import_zod3.z.string().min(1).max(16384)
478
+ }).readonly();
479
+ var AssistantComponentPartSchema = import_zod3.z.object({
480
+ kind: import_zod3.z.literal("component"),
481
+ frame: ComponentRenderFrameSchema
482
+ }).readonly();
483
+ var AssistantContentPartSchema = import_zod3.z.discriminatedUnion("kind", [AssistantTextPartSchema, AssistantComponentPartSchema]);
484
+ var createAssistantContentEncoder = () => {
485
+ let started = false;
486
+ return {
487
+ encode: (part) => {
488
+ const parsed = AssistantContentPartSchema.parse(part);
489
+ const prefix = started ? "" : ASSISTANT_CONTENT_PREFIX;
490
+ started = true;
491
+ return `${prefix}${JSON.stringify(parsed)}
492
+ `;
493
+ }
494
+ };
495
+ };
496
+ var assistantContentFailure = (code, message) => ({
497
+ ok: false,
498
+ diagnostic: { code, message, retryable: false }
499
+ });
500
+ var isAssistantContentCandidate = (input) => typeof input === "string" && input.startsWith("");
501
+ var decodeAssistantContent = (input) => {
502
+ if (typeof input !== "string" || !input.startsWith("")) {
503
+ return assistantContentFailure("ASSISTANT_CONTENT_INVALID_RECORD", "Assistant content envelope is invalid.");
504
+ }
505
+ if (!input.startsWith(ASSISTANT_CONTENT_PREFIX_ROOT) && ASSISTANT_CONTENT_PREFIX_ROOT.startsWith(input)) {
506
+ return { ok: true, parts: [], complete: false };
507
+ }
508
+ if (!input.startsWith(ASSISTANT_CONTENT_PREFIX_ROOT)) {
509
+ return assistantContentFailure("ASSISTANT_CONTENT_INVALID_RECORD", "Assistant content envelope is invalid.");
510
+ }
511
+ if (ASSISTANT_CONTENT_PREFIX.startsWith(input)) {
512
+ return { ok: true, parts: [], complete: false };
513
+ }
514
+ if (!input.startsWith(ASSISTANT_CONTENT_PREFIX)) {
515
+ return assistantContentFailure("ASSISTANT_CONTENT_UNSUPPORTED_VERSION", "Assistant content envelope uses an unsupported version.");
516
+ }
517
+ if (new TextEncoder().encode(input).byteLength > ASSISTANT_CONTENT_MAX_BYTES) {
518
+ return assistantContentFailure("ASSISTANT_CONTENT_LIMIT_EXCEEDED", "Assistant content envelope exceeds its safety limit.");
519
+ }
520
+ const payload = input.slice(ASSISTANT_CONTENT_PREFIX.length);
521
+ const complete = payload.endsWith("\n");
522
+ const records = payload.split("\n");
523
+ if (!complete) records.pop();
524
+ else records.pop();
525
+ if (records.length > ASSISTANT_CONTENT_MAX_RECORDS) {
526
+ return assistantContentFailure("ASSISTANT_CONTENT_LIMIT_EXCEEDED", "Assistant content envelope exceeds its record limit.");
527
+ }
528
+ const parts = [];
529
+ try {
530
+ for (const record of records) {
531
+ if (record === "") return assistantContentFailure("ASSISTANT_CONTENT_INVALID_RECORD", "Assistant content record is invalid.");
532
+ const parsed = AssistantContentPartSchema.safeParse(JSON.parse(record));
533
+ if (!parsed.success) return assistantContentFailure("ASSISTANT_CONTENT_INVALID_RECORD", "Assistant content record is invalid.");
534
+ parts.push(parsed.data);
535
+ }
536
+ return { ok: true, parts: Object.freeze(parts), complete };
537
+ } catch {
538
+ return assistantContentFailure("ASSISTANT_CONTENT_INVALID_RECORD", "Assistant content record is invalid.");
539
+ }
540
+ };
541
+ var decodeComponentFrame = (input) => {
542
+ let candidate = input;
543
+ if (typeof input === "string") {
544
+ try {
545
+ candidate = JSON.parse(input);
546
+ } catch {
547
+ return {
548
+ ok: false,
549
+ diagnostic: { code: "COMPONENT_INVALID_FRAME", message: "Component frame is not valid JSON.", retryable: false }
550
+ };
551
+ }
552
+ }
553
+ try {
554
+ if (isRecord(candidate) && candidate.protocol === COMPONENT_PROTOCOL) {
555
+ if (typeof candidate.version === "number" && candidate.version !== COMPONENT_PROTOCOL_VERSION) {
556
+ return {
557
+ ok: false,
558
+ diagnostic: { code: "COMPONENT_UNSUPPORTED_VERSION", message: "Component frame uses an unsupported version.", retryable: false }
559
+ };
560
+ }
561
+ if (candidate.type !== "render") {
562
+ return {
563
+ ok: false,
564
+ diagnostic: { code: "COMPONENT_UNKNOWN_TYPE", message: "Component frame type is unknown.", retryable: false }
565
+ };
566
+ }
567
+ }
568
+ const parsed = ComponentRenderFrameSchema.safeParse(candidate);
569
+ return parsed.success ? { ok: true, frame: parsed.data } : {
570
+ ok: false,
571
+ diagnostic: { code: "COMPONENT_INVALID_FRAME", message: "Component frame payload is invalid.", retryable: false }
572
+ };
573
+ } catch {
574
+ return {
575
+ ok: false,
576
+ diagnostic: { code: "COMPONENT_INVALID_FRAME", message: "Component frame payload is invalid.", retryable: false }
577
+ };
578
+ }
579
+ };
580
+ var isComponentFrameCandidate = (input) => {
581
+ try {
582
+ const candidate = typeof input === "string" ? JSON.parse(input) : input;
583
+ return isRecord(candidate) && candidate.protocol === COMPONENT_PROTOCOL;
584
+ } catch {
585
+ return false;
586
+ }
587
+ };
588
+ var createSelectionEvent = (frame, choiceId) => ComponentSelectionEventSchema.parse({
589
+ protocol: COMPONENT_PROTOCOL,
590
+ version: COMPONENT_PROTOCOL_VERSION,
591
+ type: "select",
592
+ componentKey: frame.componentKey,
593
+ instanceId: frame.instanceId,
594
+ choiceId
595
+ });
596
+ var createInteractionEvent = (frame, event, value) => ComponentInteractionEventSchema.parse({
597
+ protocol: COMPONENT_PROTOCOL,
598
+ version: COMPONENT_PROTOCOL_VERSION,
599
+ type: "interact",
600
+ componentKey: frame.componentKey,
601
+ instanceId: frame.instanceId,
602
+ event,
603
+ ...value === void 0 ? {} : { value }
604
+ });
605
+ var TokenUsageSchema = import_zod3.z.object({
606
+ promptTokens: import_zod3.z.number().int().nonnegative(),
607
+ completionTokens: import_zod3.z.number().int().nonnegative(),
608
+ totalTokens: import_zod3.z.number().int().nonnegative()
609
+ });
610
+ var TurnDiagnosticSchema = import_zod3.z.object({
611
+ version: import_zod3.z.literal(1),
612
+ code: import_zod3.z.string().regex(/^[A-Z][A-Z0-9_]*$/),
613
+ message: import_zod3.z.string().min(1),
614
+ retryable: import_zod3.z.boolean()
615
+ });
616
+ var SafeIdentifierSchema2 = import_zod3.z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/);
617
+ var EnvelopeFields = {
618
+ protocol: import_zod3.z.literal(TURN_PROTOCOL),
619
+ version: import_zod3.z.literal(TURN_PROTOCOL_VERSION),
620
+ eventId: import_zod3.z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/),
621
+ sessionId: import_zod3.z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/),
622
+ turnId: import_zod3.z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/),
623
+ sequence: import_zod3.z.number().int().nonnegative(),
624
+ emittedAt: import_zod3.z.string().datetime({ offset: true })
625
+ };
626
+ var MemoryMessagesSchema = import_zod3.z.array(import_zod3.z.unknown()).transform((messages, context) => {
627
+ try {
628
+ return (0, import_memory_validation.validateMemoryRecord)({ version: 1, messages }).messages;
629
+ } catch {
630
+ context.addIssue({ code: "custom", message: "Messages are not a valid AgentsKit memory record." });
631
+ return import_zod3.z.NEVER;
632
+ }
633
+ });
634
+ var TurnLineageSchema = import_zod3.z.discriminatedUnion("operation", [
635
+ import_zod3.z.object({ operation: import_zod3.z.literal("submit") }),
636
+ import_zod3.z.object({ operation: import_zod3.z.enum(["retry", "edit", "regenerate"]), parentTurnId: SafeIdentifierSchema2, sourceMessageId: SafeIdentifierSchema2 })
637
+ ]);
638
+ var SubmitEventSchema = import_zod3.z.object({
639
+ ...EnvelopeFields,
640
+ event: import_zod3.z.literal("client.turn.submit"),
641
+ payload: import_zod3.z.object({
642
+ input: import_zod3.z.string().min(1).refine((value) => value.trim().length > 0)
643
+ })
644
+ });
645
+ var SnapshotEventSchema = import_zod3.z.object({
646
+ ...EnvelopeFields,
647
+ event: import_zod3.z.literal("server.turn.snapshot"),
648
+ payload: import_zod3.z.object({
649
+ messages: MemoryMessagesSchema,
650
+ status: import_zod3.z.enum(["idle", "streaming", "complete", "error"]),
651
+ usage: TokenUsageSchema,
652
+ error: TurnDiagnosticSchema.optional(),
653
+ lineage: TurnLineageSchema.optional()
654
+ })
655
+ });
656
+ var DiagnosticEventSchema = import_zod3.z.object({
657
+ ...EnvelopeFields,
658
+ event: import_zod3.z.literal("server.turn.diagnostic"),
659
+ payload: TurnDiagnosticSchema
660
+ });
661
+ var TurnEventSchema = import_zod3.z.discriminatedUnion("event", [
662
+ SubmitEventSchema,
663
+ SnapshotEventSchema,
664
+ DiagnosticEventSchema
665
+ ]);
666
+ var deepFreeze = (value) => {
667
+ if (typeof value !== "object" || value === null || Object.isFrozen(value)) return value;
668
+ for (const child of Object.values(value)) deepFreeze(child);
669
+ return Object.freeze(value);
670
+ };
671
+ var createSnapshotEvent = (options) => SnapshotEventSchema.parse({
672
+ protocol: TURN_PROTOCOL,
673
+ version: TURN_PROTOCOL_VERSION,
674
+ eventId: options.eventId,
675
+ sessionId: options.sessionId,
676
+ turnId: options.turnId,
677
+ sequence: options.sequence,
678
+ emittedAt: options.emittedAt,
679
+ event: "server.turn.snapshot",
680
+ payload: {
681
+ messages: (0, import_core.serializeMessages)([...options.messages]).messages,
682
+ status: options.status,
683
+ usage: options.usage,
684
+ ...options.lineage === void 0 ? {} : { lineage: options.lineage },
685
+ ...options.error === void 0 ? {} : { error: options.error }
686
+ }
687
+ });
688
+ var createTurnSnapshotCursor = (sessionId) => {
689
+ const expectedSessionId = SafeIdentifierSchema2.parse(sessionId);
690
+ let snapshot;
691
+ return {
692
+ apply(input) {
693
+ const decoded = decodeTurnEvent(input);
694
+ if (!decoded.ok || decoded.event.event !== "server.turn.snapshot") return false;
695
+ const next = decoded.event;
696
+ if (next.sessionId !== expectedSessionId || snapshot && next.sequence <= snapshot.sequence) return false;
697
+ snapshot = deepFreeze(next);
698
+ return true;
699
+ },
700
+ getSnapshot: () => snapshot
701
+ };
702
+ };
703
+ var eventNames = /* @__PURE__ */ new Set(["client.turn.submit", "server.turn.snapshot", "server.turn.diagnostic"]);
704
+ var safeEventId = (input) => {
705
+ try {
706
+ if (!isRecord(input)) return void 0;
707
+ const parsed = SafeIdentifierSchema2.safeParse(input.eventId);
708
+ return parsed.success ? parsed.data : void 0;
709
+ } catch {
710
+ return void 0;
711
+ }
712
+ };
713
+ var diagnostic = (code, message, input) => {
714
+ const eventId = safeEventId(input);
715
+ return {
716
+ ok: false,
717
+ diagnostic: {
718
+ code,
719
+ message,
720
+ retryable: false,
721
+ ...eventId === void 0 ? {} : { eventId }
722
+ }
723
+ };
724
+ };
725
+ var decodeTurnEvent = (input) => {
726
+ let candidate = input;
727
+ if (typeof input === "string") {
728
+ try {
729
+ candidate = JSON.parse(input);
730
+ } catch {
731
+ return diagnostic("PROTOCOL_INVALID_PAYLOAD", "Turn event is not valid JSON.", input);
732
+ }
733
+ }
734
+ try {
735
+ if (isRecord(candidate) && candidate.protocol === TURN_PROTOCOL && typeof candidate.version === "number" && candidate.version !== TURN_PROTOCOL_VERSION) {
736
+ return diagnostic(
737
+ "PROTOCOL_UNSUPPORTED_VERSION",
738
+ "Turn event uses an unsupported protocol version.",
739
+ candidate
740
+ );
741
+ }
742
+ if (isRecord(candidate) && candidate.protocol === TURN_PROTOCOL && candidate.version === TURN_PROTOCOL_VERSION && typeof candidate.event === "string" && !eventNames.has(candidate.event)) {
743
+ return diagnostic(
744
+ "PROTOCOL_UNKNOWN_EVENT",
745
+ "Turn event kind is unknown.",
746
+ candidate
747
+ );
748
+ }
749
+ const parsed = TurnEventSchema.safeParse(candidate);
750
+ return parsed.success ? { ok: true, event: parsed.data } : diagnostic("PROTOCOL_INVALID_PAYLOAD", "Turn event payload is invalid.", candidate);
751
+ } catch {
752
+ return diagnostic("PROTOCOL_INVALID_PAYLOAD", "Turn event payload is invalid.", candidate);
753
+ }
754
+ };
755
+ var encodeTurnEvent = (event) => JSON.stringify(TurnEventSchema.parse(event));
756
+ var snapshotMessages = (event) => {
757
+ const validated = SnapshotEventSchema.parse(event);
758
+ return (0, import_core.deserializeMessages)({ version: 1, messages: validated.payload.messages });
759
+ };
760
+ var SESSION_PROTOCOL = "agentskit.chat.session";
761
+ var SESSION_PROTOCOL_VERSION = 1;
762
+ var SessionDecisionSchema = import_zod3.z.object({
763
+ messageId: SafeIdentifierSchema2,
764
+ input: import_zod3.z.string().max(16384),
765
+ routeId: SafeIdentifierSchema2,
766
+ kind: import_zod3.z.enum(["deterministic", "repaired", "fallback"]),
767
+ content: import_zod3.z.string().max(65536),
768
+ fromState: import_zod3.z.string().min(1).max(128),
769
+ toState: import_zod3.z.string().min(1).max(128)
770
+ }).readonly();
771
+ var SessionConfirmationSchema = import_zod3.z.object({
772
+ token: SafeIdentifierSchema2,
773
+ action: SafeIdentifierSchema2,
774
+ input: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).refine(isBoundedJsonValue),
775
+ toolCallId: SafeIdentifierSchema2,
776
+ expiresAt: import_zod3.z.number().int().nonnegative(),
777
+ status: import_zod3.z.enum(["pending", "approving", "rejecting", "expiring", "approved", "rejected", "expired"])
778
+ }).readonly();
779
+ var uniqueBy = (items, key, context, path) => {
780
+ const seen = /* @__PURE__ */ new Set();
781
+ items.forEach((item, index) => {
782
+ const value = key(item);
783
+ if (seen.has(value)) context.addIssue({ code: "custom", path: [index, path], message: `${path} must be unique.` });
784
+ seen.add(value);
785
+ });
786
+ };
787
+ var SessionDecisionsSchema = import_zod3.z.array(SessionDecisionSchema).max(1e3).superRefine((items, context) => uniqueBy(items, (item) => item.messageId, context, "messageId"));
788
+ var SessionConfirmationsSchema = import_zod3.z.array(SessionConfirmationSchema).max(1e3).superRefine((items, context) => {
789
+ uniqueBy(items, (item) => item.token, context, "token");
790
+ uniqueBy(items, (item) => item.toolCallId, context, "toolCallId");
791
+ });
792
+ var SessionSnapshotObjectSchema = import_zod3.z.object({
793
+ protocol: import_zod3.z.literal(SESSION_PROTOCOL),
794
+ version: import_zod3.z.literal(SESSION_PROTOCOL_VERSION),
795
+ sessionId: SafeIdentifierSchema2,
796
+ definitionId: SafeIdentifierSchema2,
797
+ definitionRevision: import_zod3.z.number().int().positive(),
798
+ updatedAt: import_zod3.z.string().datetime({ offset: true }),
799
+ cursor: import_zod3.z.number().int().nonnegative(),
800
+ activeTurn: import_zod3.z.object({ turnId: SafeIdentifierSchema2, expiresAt: import_zod3.z.number().int().nonnegative() }).readonly().optional(),
801
+ terminalTurns: import_zod3.z.array(import_zod3.z.object({ turnId: SafeIdentifierSchema2, outcome: import_zod3.z.enum(["completed", "indeterminate"]) }).readonly()).max(64).superRefine((items, context) => uniqueBy(items, (item) => item.turnId, context, "turnId")).readonly().optional(),
802
+ conversation: import_zod3.z.object({
803
+ state: import_zod3.z.string().min(1).max(128),
804
+ decisions: SessionDecisionsSchema
805
+ }).readonly().optional(),
806
+ confirmations: SessionConfirmationsSchema
807
+ });
808
+ var SessionSnapshotSchema = SessionSnapshotObjectSchema.readonly();
809
+ var LegacySessionSnapshotSchema = SessionSnapshotObjectSchema.omit({ protocol: true, version: true }).extend({ version: import_zod3.z.literal(0) });
810
+ var decodeSessionSnapshot = (input) => {
811
+ let candidate = input;
812
+ if (typeof input === "string") {
813
+ try {
814
+ candidate = JSON.parse(input);
815
+ } catch {
816
+ return { ok: false, diagnostic: { code: "SESSION_INVALID_SNAPSHOT", message: "Session snapshot is not valid JSON.", retryable: false } };
817
+ }
818
+ }
819
+ try {
820
+ if (isRecord(candidate) && typeof candidate.version === "number" && candidate.version !== 0 && candidate.version !== SESSION_PROTOCOL_VERSION) {
821
+ return { ok: false, diagnostic: { code: "SESSION_UNSUPPORTED_VERSION", message: "Session snapshot uses an unsupported version.", retryable: false } };
822
+ }
823
+ const current = SessionSnapshotSchema.safeParse(candidate);
824
+ if (current.success) return { ok: true, snapshot: current.data };
825
+ const legacy = LegacySessionSnapshotSchema.safeParse(candidate);
826
+ return legacy.success ? { ok: true, snapshot: SessionSnapshotSchema.parse({ ...legacy.data, protocol: SESSION_PROTOCOL, version: SESSION_PROTOCOL_VERSION }) } : { ok: false, diagnostic: { code: "SESSION_INVALID_SNAPSHOT", message: "Session snapshot payload is invalid.", retryable: false } };
827
+ } catch {
828
+ return { ok: false, diagnostic: { code: "SESSION_INVALID_SNAPSHOT", message: "Session snapshot payload is invalid.", retryable: false } };
829
+ }
830
+ };
831
+ // Annotate the CommonJS export names for ESM import in node:
832
+ 0 && (module.exports = {
833
+ ANSWER_MAX_CITATIONS,
834
+ ANSWER_MAX_SUGGESTIONS,
835
+ ANSWER_PROTOCOL,
836
+ ANSWER_PROTOCOL_VERSION,
837
+ ASK_EVENT_MAX_BYTES,
838
+ ASK_EVENT_MAX_RECORDS,
839
+ ASK_SERVICE_PROTOCOL_VERSION,
840
+ ASSISTANT_CONTENT_MAX_BYTES,
841
+ ASSISTANT_CONTENT_MAX_RECORDS,
842
+ ASSISTANT_CONTENT_PREFIX,
843
+ ASSISTANT_CONTENT_PROTOCOL,
844
+ ASSISTANT_CONTENT_PROTOCOL_VERSION,
845
+ AnswerCitationSchema,
846
+ AnswerConfidenceSchema,
847
+ AnswerResponseSchema,
848
+ AnswerSuggestionSchema,
849
+ AskEventSchema,
850
+ AssistantComponentPartSchema,
851
+ AssistantContentPartSchema,
852
+ AssistantTextPartSchema,
853
+ COMPONENT_PROTOCOL,
854
+ COMPONENT_PROTOCOL_VERSION,
855
+ ComponentFallbackSchema,
856
+ ComponentInteractionEventSchema,
857
+ ComponentKeySchema,
858
+ ComponentRenderFrameSchema,
859
+ ComponentSelectionEventSchema,
860
+ DETERMINISTIC_ARTIFACT_MAX_BYTES,
861
+ DETERMINISTIC_ARTIFACT_MAX_ENTRIES,
862
+ DETERMINISTIC_KNOWLEDGE_PROTOCOL,
863
+ DETERMINISTIC_KNOWLEDGE_PROTOCOL_VERSION,
864
+ DETERMINISTIC_MATCH_MAX_VALUES,
865
+ DETERMINISTIC_QUERY_MAX_CHARS,
866
+ DETERMINISTIC_SITE_PROTOCOL,
867
+ DETERMINISTIC_SITE_PROTOCOL_VERSION,
868
+ DeterministicKnowledgeEntrySchema,
869
+ DeterministicSiteConfigSchema,
870
+ LocalKnowledgeArtifactSchema,
871
+ SESSION_PROTOCOL,
872
+ SESSION_PROTOCOL_VERSION,
873
+ SessionConfirmationSchema,
874
+ SessionSnapshotSchema,
875
+ TURN_PROTOCOL,
876
+ TURN_PROTOCOL_VERSION,
877
+ TokenUsageSchema,
878
+ TurnDiagnosticSchema,
879
+ TurnEventSchema,
880
+ canonicalizeLocalKnowledgeArtifact,
881
+ computeLocalKnowledgeArtifactContentHash,
882
+ createAssistantContentEncoder,
883
+ createInteractionEvent,
884
+ createSelectionEvent,
885
+ createSnapshotEvent,
886
+ createTurnSnapshotCursor,
887
+ decodeAnswerResponse,
888
+ decodeAskEvents,
889
+ decodeAssistantContent,
890
+ decodeComponentFrame,
891
+ decodeDeterministicSiteConfig,
892
+ decodeLocalKnowledgeArtifact,
893
+ decodeSessionSnapshot,
894
+ decodeTurnEvent,
895
+ encodeTurnEvent,
896
+ isAssistantContentCandidate,
897
+ isComponentFrameCandidate,
898
+ normalizeKnowledgeKey,
899
+ snapshotMessages,
900
+ verifyLocalKnowledgeArtifact,
901
+ verifyLocalKnowledgeArtifactSync
902
+ });