@nority/bridge-sdk 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 (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +164 -0
  3. package/dist/agent.d.ts +101 -0
  4. package/dist/agent.d.ts.map +1 -0
  5. package/dist/agent.js +6 -0
  6. package/dist/agent.js.map +1 -0
  7. package/dist/auth/jwt.d.ts +38 -0
  8. package/dist/auth/jwt.d.ts.map +1 -0
  9. package/dist/auth/jwt.js +83 -0
  10. package/dist/auth/jwt.js.map +1 -0
  11. package/dist/auth/pairing.d.ts +14 -0
  12. package/dist/auth/pairing.d.ts.map +1 -0
  13. package/dist/auth/pairing.js +34 -0
  14. package/dist/auth/pairing.js.map +1 -0
  15. package/dist/auth/reconnect.d.ts +28 -0
  16. package/dist/auth/reconnect.d.ts.map +1 -0
  17. package/dist/auth/reconnect.js +110 -0
  18. package/dist/auth/reconnect.js.map +1 -0
  19. package/dist/bridge.d.ts +44 -0
  20. package/dist/bridge.d.ts.map +1 -0
  21. package/dist/bridge.js +311 -0
  22. package/dist/bridge.js.map +1 -0
  23. package/dist/config.d.ts +6 -0
  24. package/dist/config.d.ts.map +1 -0
  25. package/dist/config.js +47 -0
  26. package/dist/config.js.map +1 -0
  27. package/dist/conversation/replay.d.ts +30 -0
  28. package/dist/conversation/replay.d.ts.map +1 -0
  29. package/dist/conversation/replay.js +85 -0
  30. package/dist/conversation/replay.js.map +1 -0
  31. package/dist/conversation/runtime.d.ts +43 -0
  32. package/dist/conversation/runtime.d.ts.map +1 -0
  33. package/dist/conversation/runtime.js +481 -0
  34. package/dist/conversation/runtime.js.map +1 -0
  35. package/dist/conversation/state.d.ts +25 -0
  36. package/dist/conversation/state.d.ts.map +1 -0
  37. package/dist/conversation/state.js +130 -0
  38. package/dist/conversation/state.js.map +1 -0
  39. package/dist/crypto/conversation.d.ts +20 -0
  40. package/dist/crypto/conversation.d.ts.map +1 -0
  41. package/dist/crypto/conversation.js +134 -0
  42. package/dist/crypto/conversation.js.map +1 -0
  43. package/dist/crypto/hkdf-sha3.d.ts +5 -0
  44. package/dist/crypto/hkdf-sha3.d.ts.map +1 -0
  45. package/dist/crypto/hkdf-sha3.js +8 -0
  46. package/dist/crypto/hkdf-sha3.js.map +1 -0
  47. package/dist/crypto/identity.d.ts +21 -0
  48. package/dist/crypto/identity.d.ts.map +1 -0
  49. package/dist/crypto/identity.js +70 -0
  50. package/dist/crypto/identity.js.map +1 -0
  51. package/dist/crypto/payload.d.ts +10 -0
  52. package/dist/crypto/payload.d.ts.map +1 -0
  53. package/dist/crypto/payload.js +28 -0
  54. package/dist/crypto/payload.js.map +1 -0
  55. package/dist/crypto/x25519.d.ts +16 -0
  56. package/dist/crypto/x25519.d.ts.map +1 -0
  57. package/dist/crypto/x25519.js +44 -0
  58. package/dist/crypto/x25519.js.map +1 -0
  59. package/dist/index.d.ts +27 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +18 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/protocol/frames.d.ts +27 -0
  64. package/dist/protocol/frames.d.ts.map +1 -0
  65. package/dist/protocol/frames.js +43 -0
  66. package/dist/protocol/frames.js.map +1 -0
  67. package/dist/protocol/validation.d.ts +6 -0
  68. package/dist/protocol/validation.d.ts.map +1 -0
  69. package/dist/protocol/validation.js +33 -0
  70. package/dist/protocol/validation.js.map +1 -0
  71. package/dist/runtime/proactive.d.ts +14 -0
  72. package/dist/runtime/proactive.d.ts.map +1 -0
  73. package/dist/runtime/proactive.js +36 -0
  74. package/dist/runtime/proactive.js.map +1 -0
  75. package/dist/storage/conversation-store.d.ts +15 -0
  76. package/dist/storage/conversation-store.d.ts.map +1 -0
  77. package/dist/storage/conversation-store.js +75 -0
  78. package/dist/storage/conversation-store.js.map +1 -0
  79. package/dist/storage/state-store.d.ts +20 -0
  80. package/dist/storage/state-store.d.ts.map +1 -0
  81. package/dist/storage/state-store.js +74 -0
  82. package/dist/storage/state-store.js.map +1 -0
  83. package/dist/transport/outbound-queue.d.ts +18 -0
  84. package/dist/transport/outbound-queue.d.ts.map +1 -0
  85. package/dist/transport/outbound-queue.js +37 -0
  86. package/dist/transport/outbound-queue.js.map +1 -0
  87. package/dist/transport/websocket.d.ts +109 -0
  88. package/dist/transport/websocket.d.ts.map +1 -0
  89. package/dist/transport/websocket.js +346 -0
  90. package/dist/transport/websocket.js.map +1 -0
  91. package/package.json +37 -0
@@ -0,0 +1,481 @@
1
+ import { decryptJsonPayload, encryptJsonPayload } from "../crypto/payload.js";
2
+ import { deriveConversationKeyFromBase64, generateX25519EphemeralKeyPair, } from "../crypto/x25519.js";
3
+ import { appendTurn, cloneTurn, createConversationEntry, } from "./state.js";
4
+ import { FileConversationStore } from "../storage/conversation-store.js";
5
+ import { createFrame } from "../protocol/frames.js";
6
+ import { createProactiveTurnFrame, } from "../runtime/proactive.js";
7
+ const noopLogger = {
8
+ debug: () => { },
9
+ info: () => { },
10
+ warn: () => { },
11
+ error: () => { },
12
+ };
13
+ /**
14
+ * Conversation runtime for key exchange, encrypted message handling, replay, and deletion.
15
+ */
16
+ export class ConversationRuntime {
17
+ agent;
18
+ logger;
19
+ clock;
20
+ store;
21
+ conversations = new Map();
22
+ activeInvocations = new Map();
23
+ constructor(options) {
24
+ if (!options) {
25
+ throw new Error("ConversationRuntime: options are required");
26
+ }
27
+ if (!options.dataDir) {
28
+ throw new Error("ConversationRuntime: dataDir is required");
29
+ }
30
+ if (!options.agent) {
31
+ throw new Error("ConversationRuntime: agent is required");
32
+ }
33
+ this.agent = options.agent;
34
+ this.logger = options.logger ?? noopLogger;
35
+ this.clock = options.clock ?? (() => new Date());
36
+ this.store = new FileConversationStore(options.dataDir, this.logger);
37
+ }
38
+ async loadPersistedConversations() {
39
+ const persisted = await this.store.loadAll();
40
+ this.conversations.clear();
41
+ for (const entry of persisted) {
42
+ this.conversations.set(entry.conversationId, entry);
43
+ }
44
+ }
45
+ hasConversation(conversationId) {
46
+ if (!conversationId) {
47
+ throw new Error("ConversationRuntime.hasConversation: conversationId is required");
48
+ }
49
+ return this.conversations.has(conversationId);
50
+ }
51
+ createReplayRequestFrame() {
52
+ if (this.conversations.size === 0) {
53
+ return null;
54
+ }
55
+ return createFrame("replay_request", {
56
+ cursors: Array.from(this.conversations.values()).map((entry) => ({
57
+ conversation_id: entry.conversationId,
58
+ last_acknowledged_seq: entry.lastAppliedSeq,
59
+ })),
60
+ });
61
+ }
62
+ createProactiveTurnFrame(conversationId, request) {
63
+ if (!this.conversations.has(conversationId)) {
64
+ throw new Error("ConversationRuntime.createProactiveTurnFrame: conversation must exist");
65
+ }
66
+ return createProactiveTurnFrame(conversationId, request);
67
+ }
68
+ stop() {
69
+ for (const controller of this.activeInvocations.values()) {
70
+ controller.abort();
71
+ }
72
+ }
73
+ activeInvocationCount() {
74
+ return this.activeInvocations.size;
75
+ }
76
+ async handleFrame(frame, sendFrame) {
77
+ if (!frame) {
78
+ throw new Error("ConversationRuntime.handleFrame: frame is required");
79
+ }
80
+ if (typeof sendFrame !== "function") {
81
+ throw new Error("ConversationRuntime.handleFrame: sendFrame must be a function");
82
+ }
83
+ switch (frame.type) {
84
+ case "key_exchange":
85
+ await this.handleKeyExchange(frame, sendFrame);
86
+ break;
87
+ case "message":
88
+ await this.handleMessage(frame, sendFrame);
89
+ break;
90
+ case "replay":
91
+ await this.handleReplay(frame);
92
+ break;
93
+ case "conversation_deleted":
94
+ await this.handleConversationDeleted(frame);
95
+ break;
96
+ default:
97
+ this.logger.debug("ConversationRuntime.handleFrame: ignoring unsupported frame type", frame.type);
98
+ break;
99
+ }
100
+ }
101
+ async handleKeyExchange(frame, sendFrame) {
102
+ if (!frame.conversation_id) {
103
+ throw new Error("ConversationRuntime.handleKeyExchange: conversation_id is required");
104
+ }
105
+ const clientPublicKey = getRequiredString(frame.payload, "client_public_key", "ConversationRuntime.handleKeyExchange");
106
+ const bridgeKeys = generateX25519EphemeralKeyPair();
107
+ const symmetricKey = deriveConversationKeyFromBase64(bridgeKeys.privateKey, clientPublicKey);
108
+ const entry = createConversationEntry(frame.conversation_id, symmetricKey);
109
+ this.conversations.set(frame.conversation_id, entry);
110
+ await this.store.save(entry);
111
+ sendFrame(createFrame("key_exchange_response", {
112
+ bridge_public_key: bridgeKeys.publicKeyBase64,
113
+ }, frame.conversation_id));
114
+ }
115
+ async handleMessage(frame, sendFrame) {
116
+ if (!frame.conversation_id) {
117
+ throw new Error("ConversationRuntime.handleMessage: conversation_id is required");
118
+ }
119
+ const entry = this.conversations.get(frame.conversation_id);
120
+ if (!entry) {
121
+ throw new Error("ConversationRuntime.handleMessage: conversation not found");
122
+ }
123
+ const encryptedPayload = getRequiredString(frame.payload, "encrypted_payload", "ConversationRuntime.handleMessage");
124
+ const payload = decryptJsonPayload(entry.symmetricKey, encryptedPayload);
125
+ const inputParts = normalizeInputPayload(payload);
126
+ const historyBeforeMessage = entry.turns.map(cloneTurn);
127
+ if (this.activeInvocations.has(entry.conversationId)) {
128
+ throw new Error("ConversationRuntime.handleMessage: conversation already has an active invocation");
129
+ }
130
+ appendTurn(entry, "user", inputParts);
131
+ const controller = new AbortController();
132
+ this.activeInvocations.set(entry.conversationId, controller);
133
+ const messageId = globalThis.crypto.randomUUID();
134
+ let assistantText = "";
135
+ try {
136
+ for await (const event of this.agent.invokeAgent(controller.signal, {
137
+ conversationId: entry.conversationId,
138
+ inputs: inputParts.map(cloneContentPart),
139
+ history: historyBeforeMessage,
140
+ })) {
141
+ if (controller.signal.aborted) {
142
+ break;
143
+ }
144
+ const outboundEvent = buildAgentEventFrame(entry, event, this.clock, messageId);
145
+ if (outboundEvent !== null) {
146
+ sendFrame(createFrame("agent_event", { events: [outboundEvent] }, entry.conversationId));
147
+ }
148
+ if (event.type === "text_delta") {
149
+ assistantText += event.content;
150
+ }
151
+ }
152
+ }
153
+ catch (error) {
154
+ if (controller.signal.aborted) {
155
+ return;
156
+ }
157
+ throw error;
158
+ }
159
+ finally {
160
+ if (this.activeInvocations.get(entry.conversationId) === controller) {
161
+ this.activeInvocations.delete(entry.conversationId);
162
+ }
163
+ }
164
+ if (controller.signal.aborted || !this.conversations.has(entry.conversationId)) {
165
+ return;
166
+ }
167
+ if (assistantText.length > 0) {
168
+ appendTurn(entry, "assistant", [{ kind: "text", text: assistantText }]);
169
+ }
170
+ await this.store.save(entry);
171
+ }
172
+ async handleReplay(frame) {
173
+ const payloadEvents = frame.payload.events;
174
+ if (!Array.isArray(payloadEvents)) {
175
+ throw new Error("ConversationRuntime.handleReplay: payload.events must be an array");
176
+ }
177
+ const grouped = new Map();
178
+ for (const event of payloadEvents) {
179
+ if (!isReplayWireEvent(event)) {
180
+ continue;
181
+ }
182
+ const entry = this.conversations.get(event.conversation_id);
183
+ if (!entry) {
184
+ this.logger.warn("ConversationRuntime.handleReplay: replay for unknown conversation", event.conversation_id);
185
+ continue;
186
+ }
187
+ const decrypted = decryptJsonPayload(entry.symmetricKey, event.encrypted_payload);
188
+ if (typeof decrypted !== "object" || decrypted === null) {
189
+ throw new Error("ConversationRuntime.handleReplay: decrypted replay payload must be an object");
190
+ }
191
+ const existing = grouped.get(event.conversation_id) ?? [];
192
+ existing.push({
193
+ seq: event.seq,
194
+ payload: decrypted,
195
+ });
196
+ grouped.set(event.conversation_id, existing);
197
+ }
198
+ for (const [conversationId, replayEvents] of grouped) {
199
+ const entry = this.conversations.get(conversationId);
200
+ if (!entry) {
201
+ continue;
202
+ }
203
+ this.applyReplayEvents(entry, replayEvents);
204
+ await this.store.save(entry);
205
+ }
206
+ }
207
+ async handleConversationDeleted(frame) {
208
+ if (!frame.conversation_id) {
209
+ throw new Error("ConversationRuntime.handleConversationDeleted: conversation_id is required");
210
+ }
211
+ this.abortInvocation(frame.conversation_id);
212
+ this.conversations.delete(frame.conversation_id);
213
+ await this.store.delete(frame.conversation_id);
214
+ }
215
+ applyReplayEvents(entry, replayEvents) {
216
+ const dedupedEvents = new Map();
217
+ for (const replayEvent of replayEvents) {
218
+ if (replayEvent.seq <= entry.lastAppliedSeq) {
219
+ continue;
220
+ }
221
+ if (!dedupedEvents.has(replayEvent.seq)) {
222
+ dedupedEvents.set(replayEvent.seq, replayEvent.payload);
223
+ }
224
+ }
225
+ for (const seq of Array.from(dedupedEvents.keys()).sort((left, right) => left - right)) {
226
+ const payload = dedupedEvents.get(seq);
227
+ if (payload === undefined) {
228
+ throw new Error("ConversationRuntime.applyReplayEvents: payload must exist");
229
+ }
230
+ this.applyReplayPayload(entry, seq, payload);
231
+ entry.lastAppliedSeq = seq;
232
+ }
233
+ }
234
+ applyReplayPayload(entry, seq, payload) {
235
+ const type = typeof payload.type === "string" ? payload.type : "";
236
+ switch (type) {
237
+ case "user_message":
238
+ appendTurn(entry, "user", [
239
+ {
240
+ kind: "text",
241
+ text: getReplayTextPayload(payload, "ConversationRuntime.applyReplayPayload"),
242
+ },
243
+ ]);
244
+ return;
245
+ case "text_delta":
246
+ this.applyAssistantReplayDelta(entry, getReplayMessageId(payload, "ConversationRuntime.applyReplayPayload"), getReplayDeltaPayload(payload, "ConversationRuntime.applyReplayPayload"));
247
+ return;
248
+ case "done":
249
+ this.completeAssistantReplayTurn(entry, getReplayMessageId(payload, "ConversationRuntime.applyReplayPayload"));
250
+ return;
251
+ case "tool_call_start":
252
+ case "tool_result":
253
+ case "run_status":
254
+ // Acknowledged but not rendered in history turns.
255
+ return;
256
+ default:
257
+ // Gracefully skip unknown types instead of crashing replay.
258
+ // This prevents reconnect loops if the backend stores a type
259
+ // the SDK doesn't know about yet.
260
+ this.logger.warn(`ConversationRuntime.applyReplayPayload: skipping unknown replay type ${type} at seq ${seq}`);
261
+ return;
262
+ }
263
+ }
264
+ applyAssistantReplayDelta(entry, messageId, delta) {
265
+ const existingTurnIndex = entry.pendingAssistantTurns[messageId];
266
+ if (existingTurnIndex === undefined) {
267
+ entry.turns.push({
268
+ role: "assistant",
269
+ parts: [{ kind: "text", text: delta }],
270
+ });
271
+ entry.pendingAssistantTurns[messageId] = entry.turns.length - 1;
272
+ return;
273
+ }
274
+ const turn = entry.turns[existingTurnIndex];
275
+ if (!turn || turn.role !== "assistant") {
276
+ throw new Error("ConversationRuntime.applyAssistantReplayDelta: pending assistant turn must exist");
277
+ }
278
+ const lastPart = turn.parts.at(-1);
279
+ if (lastPart?.kind === "text") {
280
+ lastPart.text += delta;
281
+ return;
282
+ }
283
+ turn.parts.push({ kind: "text", text: delta });
284
+ }
285
+ completeAssistantReplayTurn(entry, messageId) {
286
+ delete entry.pendingAssistantTurns[messageId];
287
+ }
288
+ abortInvocation(conversationId) {
289
+ const controller = this.activeInvocations.get(conversationId);
290
+ controller?.abort();
291
+ }
292
+ }
293
+ function normalizeInputPayload(payload) {
294
+ if (typeof payload === "string") {
295
+ return [{ kind: "text", text: payload }];
296
+ }
297
+ if (typeof payload !== "object" || payload === null) {
298
+ throw new Error("normalizeInputPayload: payload must be a string or object");
299
+ }
300
+ const record = payload;
301
+ if (Array.isArray(record.input)) {
302
+ return record.input.map(normalizeContentPart);
303
+ }
304
+ if (typeof record.content === "string") {
305
+ return [{ kind: "text", text: record.content }];
306
+ }
307
+ throw new Error("normalizeInputPayload: payload must contain content or multimodal input");
308
+ }
309
+ function normalizeContentPart(part) {
310
+ if (typeof part !== "object" || part === null || !("kind" in part)) {
311
+ throw new Error("normalizeContentPart: part.kind is required");
312
+ }
313
+ const record = part;
314
+ if (record.kind === "text") {
315
+ if (typeof record.text !== "string") {
316
+ throw new Error("normalizeContentPart: text part requires string text");
317
+ }
318
+ return { kind: "text", text: record.text };
319
+ }
320
+ if (record.kind === "media") {
321
+ if (typeof record.media_id !== "string" ||
322
+ typeof record.media_type !== "string" ||
323
+ typeof record.size !== "number") {
324
+ throw new Error("normalizeContentPart: media part requires media_id, media_type, and size");
325
+ }
326
+ return {
327
+ kind: "media",
328
+ media: {
329
+ mediaId: record.media_id,
330
+ mediaType: record.media_type,
331
+ size: record.size,
332
+ },
333
+ };
334
+ }
335
+ throw new Error(`normalizeContentPart: unsupported kind ${String(record.kind)}`);
336
+ }
337
+ function buildAgentEventFrame(entry, event, clock, messageId) {
338
+ const payload = serializeAgentEvent(event);
339
+ if (payload === null) {
340
+ return null;
341
+ }
342
+ // Include message_id in the encrypted body so replay can group
343
+ // deltas from the same invocation into a single assistant turn.
344
+ payload.body.message_id = messageId;
345
+ return {
346
+ event_type: payload.eventType,
347
+ encrypted_payload: encryptJsonPayload(entry.symmetricKey, payload.body),
348
+ emitted_at: toProtocolTimestamp(clock()),
349
+ };
350
+ }
351
+ export function serializeAgentEvent(event) {
352
+ switch (event.type) {
353
+ case "text_delta":
354
+ return {
355
+ eventType: "text_delta",
356
+ body: { type: "text_delta", content: event.content },
357
+ };
358
+ case "tool_call_start":
359
+ return {
360
+ eventType: "tool_call_start",
361
+ body: {
362
+ type: "tool_call_start",
363
+ toolCallId: event.toolCallId,
364
+ name: event.toolName,
365
+ arguments: event.arguments,
366
+ },
367
+ };
368
+ case "tool_call_update":
369
+ return {
370
+ eventType: "tool_call_update",
371
+ body: {
372
+ type: "tool_call_update",
373
+ toolCallId: event.toolCallId,
374
+ partialResult: event.partialResult ?? "",
375
+ status: event.status ?? "in_progress",
376
+ },
377
+ };
378
+ case "tool_result":
379
+ return {
380
+ eventType: "tool_result",
381
+ body: {
382
+ type: "tool_result",
383
+ toolCallId: event.toolCallId,
384
+ result: event.result,
385
+ status: event.status ?? "success",
386
+ },
387
+ };
388
+ case "thinking_start":
389
+ return {
390
+ eventType: "thinking_start",
391
+ body: {
392
+ type: "thinking_start",
393
+ thinkingBlockId: event.thinkingBlockId,
394
+ },
395
+ };
396
+ case "thinking_delta":
397
+ return {
398
+ eventType: "thinking_delta",
399
+ body: {
400
+ type: "thinking_delta",
401
+ thinkingBlockId: event.thinkingBlockId,
402
+ content: event.content,
403
+ },
404
+ };
405
+ case "thinking_complete":
406
+ return {
407
+ eventType: "thinking_complete",
408
+ body: {
409
+ type: "thinking_complete",
410
+ thinkingBlockId: event.thinkingBlockId,
411
+ },
412
+ };
413
+ case "run_status":
414
+ return {
415
+ eventType: "run_status",
416
+ body: {
417
+ type: "run_status",
418
+ runStatus: event.runStatus,
419
+ reason: event.reason ?? "",
420
+ },
421
+ };
422
+ case "error":
423
+ return {
424
+ eventType: "error",
425
+ body: {
426
+ type: "error",
427
+ errorMessage: event.errorMessage,
428
+ reason: event.reason ?? "",
429
+ },
430
+ };
431
+ case "done":
432
+ return {
433
+ eventType: "done",
434
+ body: { type: "done" },
435
+ };
436
+ default:
437
+ return null;
438
+ }
439
+ }
440
+ function cloneContentPart(part) {
441
+ return part.kind === "text"
442
+ ? { kind: "text", text: part.text }
443
+ : { kind: "media", media: { ...part.media } };
444
+ }
445
+ function getRequiredString(payload, field, caller) {
446
+ const value = payload[field];
447
+ if (typeof value !== "string" || value.length === 0) {
448
+ throw new Error(`${caller}: payload.${field} is required`);
449
+ }
450
+ return value;
451
+ }
452
+ function isReplayWireEvent(value) {
453
+ return (typeof value === "object" &&
454
+ value !== null &&
455
+ typeof value.conversation_id === "string" &&
456
+ typeof value.seq === "number" &&
457
+ typeof value.encrypted_payload === "string");
458
+ }
459
+ function getReplayTextPayload(payload, caller) {
460
+ if (typeof payload.content === "string") {
461
+ return payload.content;
462
+ }
463
+ throw new Error(`${caller}: replay content is required`);
464
+ }
465
+ function getReplayDeltaPayload(payload, caller) {
466
+ if (typeof payload.content === "string") {
467
+ return payload.content;
468
+ }
469
+ throw new Error(`${caller}: replay content is required`);
470
+ }
471
+ function getReplayMessageId(payload, _caller) {
472
+ if (typeof payload.message_id === "string" && payload.message_id.length > 0) {
473
+ return payload.message_id;
474
+ }
475
+ // Fallback for events stored before message_id was added to bridge events.
476
+ return "unknown";
477
+ }
478
+ function toProtocolTimestamp(date) {
479
+ return date.toISOString().replace(/\.\d{3}Z$/, "Z");
480
+ }
481
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/conversation/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { ChatTurn, ContentPart } from "../agent.js";
2
+ /**
3
+ * Per-conversation state managed by the bridge.
4
+ */
5
+ export interface ConversationEntry {
6
+ conversationId: string;
7
+ symmetricKey: Buffer;
8
+ turns: ChatTurn[];
9
+ lastAppliedSeq: number;
10
+ pendingAssistantTurns: Record<string, number>;
11
+ }
12
+ export interface PersistedConversationEntry {
13
+ conversationId: string;
14
+ symmetricKeyBase64: string;
15
+ turns: ChatTurn[];
16
+ lastAppliedSeq: number;
17
+ pendingAssistantTurns?: Record<string, number>;
18
+ }
19
+ export declare function createConversationEntry(conversationId: string, symmetricKey: Buffer): ConversationEntry;
20
+ export declare function serializeConversationEntry(entry: ConversationEntry): PersistedConversationEntry;
21
+ export declare function deserializeConversationEntry(entry: PersistedConversationEntry): ConversationEntry;
22
+ export declare function appendTurn(entry: ConversationEntry, role: ChatTurn["role"], parts: ContentPart[]): void;
23
+ export declare function cloneTurn(turn: ChatTurn): ChatTurn;
24
+ export declare function extractPlainText(parts: ContentPart[]): string;
25
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/conversation/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,0BAA0B;IACzC,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChD;AAED,wBAAgB,uBAAuB,CACrC,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,GACnB,iBAAiB,CAiBnB;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,iBAAiB,GACvB,0BAA0B,CAS5B;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,0BAA0B,GAChC,iBAAiB,CA+BnB;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,iBAAiB,EACxB,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,EACtB,KAAK,EAAE,WAAW,EAAE,GACnB,IAAI,CAUN;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAYlD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAS7D"}
@@ -0,0 +1,130 @@
1
+ export function createConversationEntry(conversationId, symmetricKey) {
2
+ if (!conversationId) {
3
+ throw new Error("createConversationEntry: conversationId is required");
4
+ }
5
+ if (!Buffer.isBuffer(symmetricKey) || symmetricKey.length !== 32) {
6
+ throw new Error(`createConversationEntry: symmetricKey must be a 32-byte Buffer, got ${symmetricKey.length}`);
7
+ }
8
+ return {
9
+ conversationId,
10
+ symmetricKey,
11
+ turns: [],
12
+ lastAppliedSeq: 0,
13
+ pendingAssistantTurns: {},
14
+ };
15
+ }
16
+ export function serializeConversationEntry(entry) {
17
+ assertConversationEntry(entry, "serializeConversationEntry");
18
+ return {
19
+ conversationId: entry.conversationId,
20
+ symmetricKeyBase64: entry.symmetricKey.toString("base64"),
21
+ turns: entry.turns.map(cloneTurn),
22
+ lastAppliedSeq: entry.lastAppliedSeq,
23
+ pendingAssistantTurns: { ...entry.pendingAssistantTurns },
24
+ };
25
+ }
26
+ export function deserializeConversationEntry(entry) {
27
+ if (!entry) {
28
+ throw new Error("deserializeConversationEntry: entry is required");
29
+ }
30
+ if (!entry.conversationId) {
31
+ throw new Error("deserializeConversationEntry: conversationId is required");
32
+ }
33
+ if (!entry.symmetricKeyBase64) {
34
+ throw new Error("deserializeConversationEntry: symmetricKeyBase64 is required");
35
+ }
36
+ if (!Array.isArray(entry.turns)) {
37
+ throw new Error("deserializeConversationEntry: turns must be an array");
38
+ }
39
+ if (!Number.isInteger(entry.lastAppliedSeq) || entry.lastAppliedSeq < 0) {
40
+ throw new Error(`deserializeConversationEntry: lastAppliedSeq must be a non-negative integer, got ${entry.lastAppliedSeq}`);
41
+ }
42
+ const symmetricKey = Buffer.from(entry.symmetricKeyBase64, "base64");
43
+ const deserialized = {
44
+ conversationId: entry.conversationId,
45
+ symmetricKey,
46
+ turns: entry.turns.map(cloneTurn),
47
+ lastAppliedSeq: entry.lastAppliedSeq,
48
+ pendingAssistantTurns: clonePendingAssistantTurns(entry.pendingAssistantTurns),
49
+ };
50
+ assertConversationEntry(deserialized, "deserializeConversationEntry");
51
+ return deserialized;
52
+ }
53
+ export function appendTurn(entry, role, parts) {
54
+ assertConversationEntry(entry, "appendTurn");
55
+ if (!Array.isArray(parts) || parts.length === 0) {
56
+ throw new Error("appendTurn: parts must be a non-empty array");
57
+ }
58
+ entry.turns.push({
59
+ role,
60
+ parts: parts.map(clonePart),
61
+ });
62
+ }
63
+ export function cloneTurn(turn) {
64
+ if (!turn) {
65
+ throw new Error("cloneTurn: turn is required");
66
+ }
67
+ if (!Array.isArray(turn.parts)) {
68
+ throw new Error("cloneTurn: turn.parts must be an array");
69
+ }
70
+ return {
71
+ role: turn.role,
72
+ parts: turn.parts.map(clonePart),
73
+ };
74
+ }
75
+ export function extractPlainText(parts) {
76
+ if (!Array.isArray(parts)) {
77
+ throw new Error("extractPlainText: parts must be an array");
78
+ }
79
+ return parts
80
+ .filter((part) => part.kind === "text")
81
+ .map((part) => part.text)
82
+ .join("");
83
+ }
84
+ function clonePart(part) {
85
+ if (part.kind === "text") {
86
+ return { kind: "text", text: part.text };
87
+ }
88
+ return {
89
+ kind: "media",
90
+ media: { ...part.media },
91
+ };
92
+ }
93
+ function assertConversationEntry(entry, caller) {
94
+ if (!entry.conversationId) {
95
+ throw new Error(`${caller}: conversationId is required`);
96
+ }
97
+ if (!Buffer.isBuffer(entry.symmetricKey) || entry.symmetricKey.length !== 32) {
98
+ throw new Error(`${caller}: symmetricKey must be a 32-byte Buffer`);
99
+ }
100
+ if (!Array.isArray(entry.turns)) {
101
+ throw new Error(`${caller}: turns must be an array`);
102
+ }
103
+ if (!Number.isInteger(entry.lastAppliedSeq) || entry.lastAppliedSeq < 0) {
104
+ throw new Error(`${caller}: lastAppliedSeq must be a non-negative integer`);
105
+ }
106
+ assertPendingAssistantTurns(entry.pendingAssistantTurns, caller);
107
+ }
108
+ function clonePendingAssistantTurns(pendingAssistantTurns) {
109
+ if (pendingAssistantTurns === undefined) {
110
+ return {};
111
+ }
112
+ assertPendingAssistantTurns(pendingAssistantTurns, "clonePendingAssistantTurns");
113
+ return { ...pendingAssistantTurns };
114
+ }
115
+ function assertPendingAssistantTurns(pendingAssistantTurns, caller) {
116
+ if (typeof pendingAssistantTurns !== "object" ||
117
+ pendingAssistantTurns === null ||
118
+ Array.isArray(pendingAssistantTurns)) {
119
+ throw new Error(`${caller}: pendingAssistantTurns must be an object`);
120
+ }
121
+ for (const [messageId, turnIndex] of Object.entries(pendingAssistantTurns)) {
122
+ if (!messageId) {
123
+ throw new Error(`${caller}: pendingAssistantTurns keys must be non-empty`);
124
+ }
125
+ if (!Number.isInteger(turnIndex) || turnIndex < 0) {
126
+ throw new Error(`${caller}: pendingAssistantTurns values must be non-negative integers`);
127
+ }
128
+ }
129
+ }
130
+ //# sourceMappingURL=state.js.map