negotium 0.6.4 → 0.6.6

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/registry.js CHANGED
@@ -133,7 +133,7 @@ var codexRegistryOperations = {
133
133
  return { sessionId: threadId, rolloutPath };
134
134
  },
135
135
  async forkSession({ parentSessionId }) {
136
- const { forkCodexSession } = await import("./chunk-tfwbft4r.js");
136
+ const { forkCodexSession } = await import("./chunk-pxnv3gh2.js");
137
137
  return await forkCodexSession(parentSessionId);
138
138
  },
139
139
  async cleanupRollouts({ sessionIds }) {
@@ -79,7 +79,10 @@ export interface RunArchiverTurnParams {
79
79
  rawArchivePaths?: string[];
80
80
  /** Number of messages in the archive — gates the MIN threshold. */
81
81
  messageCount: number;
82
- /** Deleted topics update the #General memory hub; active idle snapshots do not. */
82
+ /**
83
+ * Both update the #General memory hub the same way; only the prompt and the
84
+ * fallback completion text differ ("deleted" vs. "snapshotted").
85
+ */
83
86
  mode?: "deleted-topic" | "active-topic";
84
87
  /** Override the archiver agent backend (default: maestro). */
85
88
  agent?: AgentKind;
@@ -227,6 +230,12 @@ export function createArchiverRuntime(host: ArchiverHost): ArchiverRuntime {
227
230
  const model = params.model;
228
231
 
229
232
  const outputLanguage = resolveMemoryLanguage();
233
+ // Both a deleted topic and an idle/session-reset snapshot roll into the
234
+ // #General memory hub (see `finalizeGeneralMemory` below), so both modes
235
+ // ask the archiver for the same short completion reply to display there.
236
+ const generalReplyInstruction =
237
+ `Reply with a short completion message in ${outputLanguage} for display in #General. ` +
238
+ "Do not include tool-call logs or raw transcripts — just briefly name the summary / brief / articles you saved.";
230
239
  const prompt =
231
240
  mode === "active-topic"
232
241
  ? [
@@ -235,6 +244,8 @@ export function createArchiverRuntime(host: ArchiverHost): ArchiverRuntime {
235
244
  ...rawArchivePaths.map((path) => `raw_archive_path: ${path}`),
236
245
  `wiki_dir: ${wikiDir}`,
237
246
  `output_language: ${outputLanguage}`,
247
+ "",
248
+ generalReplyInstruction,
238
249
  ].join("\n")
239
250
  : [
240
251
  `Session "${topicTitle}" was deleted. Extract durable memory from the archive below and save it into the wiki.`,
@@ -243,8 +254,7 @@ export function createArchiverRuntime(host: ArchiverHost): ArchiverRuntime {
243
254
  `wiki_dir: ${wikiDir}`,
244
255
  `output_language: ${outputLanguage}`,
245
256
  "",
246
- `Reply with a short completion message in ${outputLanguage} for display in #General. ` +
247
- "Do not include tool-call logs or raw transcripts — just briefly name the summary / brief / articles you saved.",
257
+ generalReplyInstruction,
248
258
  ].join("\n");
249
259
 
250
260
  const activeSessionId = `memory:${host.config.createId()}`;
@@ -421,21 +431,23 @@ export function createArchiverRuntime(host: ArchiverHost): ArchiverRuntime {
421
431
  host.config.warn({ err, userId, topicTitle }, "archiver: settlement callback failed");
422
432
  }
423
433
  }
424
- if (mode === "deleted-topic") {
425
- // Roll the deleted topic into the #General memory hub regardless of LLM
426
- // success — even a failed distillation should leave a digest breadcrumb.
427
- const text = finalText.trimEnd();
428
- finalizeGeneralMemory(
429
- host,
430
- userId,
431
- topicTitle,
432
- messageCount,
433
- startMs,
434
- ok,
435
- topicId,
436
- ok && text ? { text, agent, model, usage } : undefined,
437
- );
438
- }
434
+ // Roll every archiver run — deleted topic or idle/session-reset
435
+ // snapshot alike — into the #General memory hub regardless of LLM
436
+ // success: even a failed distillation should leave a digest
437
+ // breadcrumb, and participants should see the hub absorb memory no
438
+ // matter why the archiver ran.
439
+ const text = finalText.trimEnd();
440
+ finalizeGeneralMemory(
441
+ host,
442
+ userId,
443
+ topicTitle,
444
+ messageCount,
445
+ startMs,
446
+ ok,
447
+ mode,
448
+ topicId,
449
+ ok && text ? { text, agent, model, usage } : undefined,
450
+ );
439
451
  });
440
452
  topicQueues.set(safeTopic, work);
441
453
  void work.finally(() => {
@@ -499,9 +511,10 @@ export function findSummaryFile(
499
511
 
500
512
  /**
501
513
  * Update the #General brief with a rolling digest entry for the archived topic
502
- * and post the archiver completion reply. The brief feeds the General turn's
503
- * system prompt, so this is the channel that carries deleted-topic memory into
504
- * the user's private hub. Best-effort — never throws.
514
+ * (deleted, or idle/session-reset snapshot) and post the archiver completion
515
+ * reply. The brief feeds the General turn's system prompt, so this is the
516
+ * channel that carries every archiver run's memory into the user's private
517
+ * hub. Best-effort — never throws.
505
518
  */
506
519
  function finalizeGeneralMemory(
507
520
  host: ArchiverHost,
@@ -510,6 +523,7 @@ function finalizeGeneralMemory(
510
523
  messageCount: number,
511
524
  startMs: number,
512
525
  ok: boolean,
526
+ mode: "deleted-topic" | "active-topic",
513
527
  topicId?: string,
514
528
  generalReply?: GeneralArchiverReply,
515
529
  ): void {
@@ -533,7 +547,7 @@ function finalizeGeneralMemory(
533
547
  newEntry,
534
548
  ...prevEntries.filter((l) => !l.startsWith(`- **${topicTitle}** `)),
535
549
  ].slice(0, MAX_BRIEF_ENTRIES);
536
- const briefMd = `# Workspace Memory Hub\n\nRecent memory digest distilled from deleted topics. Use \`wiki_query\` for details.\n\n## Recent Archives\n${rolled.join("\n")}`;
550
+ const briefMd = `# Workspace Memory Hub\n\nRecent memory digest distilled from archived topics (deletions and idle/session-reset snapshots). Use \`wiki_query\` for details.\n\n## Recent Archives\n${rolled.join("\n")}`;
537
551
 
538
552
  host.storage.setTopicBrief(generalTopicId, {
539
553
  briefMd,
@@ -554,9 +568,13 @@ function finalizeGeneralMemory(
554
568
  const replyText = generalReply?.text.trim();
555
569
  const text =
556
570
  replyText ||
557
- (ok
558
- ? `🗂 Topic "${topicTitle}" was deleted and archived into #General memory.`
559
- : `🗂 Archived topic "${topicTitle}" (summary extraction failed — raw log preserved in wiki/archive).`);
571
+ (mode === "deleted-topic"
572
+ ? ok
573
+ ? `🗂 Topic "${topicTitle}" was deleted and archived into #General memory.`
574
+ : `🗂 Archived topic "${topicTitle}" (summary extraction failed — raw log preserved in wiki/archive).`
575
+ : ok
576
+ ? `🗂 Session "${topicTitle}" was snapshotted and archived into #General memory.`
577
+ : `🗂 Archived a snapshot of "${topicTitle}" (summary extraction failed — raw log preserved in wiki/archive).`);
560
578
  const replyMeta =
561
579
  generalReply && replyText
562
580
  ? {
@@ -168,7 +168,7 @@ export {
168
168
  STATE_DIR,
169
169
  WORKSPACE_DIR,
170
170
  } from "#platform/config";
171
- export { FROM_AUTO_CONTINUE } from "#platform/constants";
171
+ export { FROM_AUTO_CONTINUE, NODE_LOCAL_USER_ID } from "#platform/constants";
172
172
  export { errMsg } from "#platform/error";
173
173
  export { appendJsonlEntry } from "#platform/jsonl";
174
174
  export { onShutdown, runShutdown } from "#platform/lifecycle";
@@ -31,7 +31,7 @@ export {
31
31
  resolveRuntimeMcpToken,
32
32
  } from "#mcp/runtime-spec";
33
33
  export { WORKSPACE_DIR } from "#platform/config";
34
- export { FROM_AUTO_CONTINUE } from "#platform/constants";
34
+ export { FROM_AUTO_CONTINUE, NODE_LOCAL_USER_ID } from "#platform/constants";
35
35
  export { errMsg } from "#platform/error";
36
36
  export { appendJsonlEntry } from "#platform/jsonl";
37
37
  export { logger } from "#platform/logger";
@@ -76,6 +76,7 @@ export {
76
76
  getApiMessage,
77
77
  getLastMessagePreviews,
78
78
  listApiMessages,
79
+ softDeleteApiMessage,
79
80
  } from "#storage/api-messages";
80
81
  export { getTopic, upsertTopic } from "#storage/api-topics";
81
82
  export { getGlobalAiName, setGlobalAiName } from "#storage/app-settings";
@@ -14,5 +14,17 @@ export const RESERVED_TOPIC_NAMES: ReadonlySet<string> = new Set([
14
14
  /** Legacy shared General id. New General rooms use per-user UUIDs. */
15
15
  export const GENERAL_TOPIC_ID = "general";
16
16
 
17
+ /**
18
+ * Sanitized log name every private General resolves to.
19
+ *
20
+ * `general` is reserved above, so a manager room is the only room that can
21
+ * produce it — which is what lets conversation storage qualify just that one
22
+ * file per owner instead of namespacing the whole directory.
23
+ */
24
+ export const MANAGER_TOPIC_LOG_NAME = "general";
25
+
26
+ /** The principal a standalone node runs as when no hub names another. */
27
+ export const NODE_LOCAL_USER_ID = "local";
28
+
17
29
  /** Internal topic name for the forum manager session (General topic). */
18
30
  export const TOPIC_MANAGER = "__manager__";
@@ -95,6 +95,15 @@ export interface RuntimeGatewayManagerTopic {
95
95
  participants: Array<{ userId: string; role: "owner" | "member" }>;
96
96
  }
97
97
 
98
+ export interface RuntimeGatewayDeletedMessage {
99
+ id: string;
100
+ topicId: string;
101
+ authorId: string;
102
+ text: string;
103
+ deleted: true;
104
+ createdAt: string;
105
+ }
106
+
98
107
  export interface RuntimeGatewayCronJob {
99
108
  id: string;
100
109
  name: string;
@@ -215,6 +224,18 @@ function validManagerTopic(value: unknown): value is RuntimeGatewayManagerTopic
215
224
  );
216
225
  }
217
226
 
227
+ function validDeletedMessage(value: unknown): value is RuntimeGatewayDeletedMessage {
228
+ const message = record(value);
229
+ return Boolean(
230
+ typeof message?.id === "string" &&
231
+ typeof message.topicId === "string" &&
232
+ typeof message.authorId === "string" &&
233
+ typeof message.text === "string" &&
234
+ message.deleted === true &&
235
+ typeof message.createdAt === "string",
236
+ );
237
+ }
238
+
218
239
  function validCronJob(value: unknown): value is RuntimeGatewayCronJob {
219
240
  const job = record(value);
220
241
  return Boolean(
@@ -435,6 +456,46 @@ export class RuntimeGatewayClient {
435
456
  return body.topic;
436
457
  }
437
458
 
459
+ async deleteMessage(
460
+ topicId: string,
461
+ messageId: string,
462
+ actorUserId: string,
463
+ allowAdmin = false,
464
+ ): Promise<RuntimeGatewayDeletedMessage> {
465
+ const response = await this.send(
466
+ `/topics/${encodeURIComponent(topicId)}/messages/${encodeURIComponent(messageId)}`,
467
+ {
468
+ method: "DELETE",
469
+ headers: { "content-type": "application/json" },
470
+ body: JSON.stringify({
471
+ v: RUNTIME_GATEWAY_VERSION,
472
+ actorUserId,
473
+ ...(allowAdmin ? { allowAdmin: true } : {}),
474
+ }),
475
+ },
476
+ this.requestTimeoutMs,
477
+ );
478
+ if (!response.ok) {
479
+ throw new RuntimeGatewayError(
480
+ "Runtime Gateway message delete failed",
481
+ "http",
482
+ response.status,
483
+ );
484
+ }
485
+ const body = record(await json(response));
486
+ if (
487
+ body?.ok !== true ||
488
+ body.v !== RUNTIME_GATEWAY_VERSION ||
489
+ !validDeletedMessage(body.message)
490
+ ) {
491
+ throw new RuntimeGatewayError(
492
+ "Runtime Gateway message delete response is incompatible",
493
+ "protocol",
494
+ );
495
+ }
496
+ return body.message;
497
+ }
498
+
438
499
  private async cronRequest(path: string, init: RequestInit): Promise<Record<string, unknown>> {
439
500
  const response = await this.send(path, init, this.requestTimeoutMs);
440
501
  if (!response.ok) {
@@ -7,9 +7,10 @@ import {
7
7
  writeFileSync,
8
8
  } from "node:fs";
9
9
  import { dirname, join } from "node:path";
10
+ import { MANAGER_TOPIC_LOG_NAME, NODE_LOCAL_USER_ID } from "#platform/constants";
10
11
  import { appendJsonlLine } from "#platform/jsonl";
11
12
  import { logger } from "#platform/logger";
12
- import { sanitizeTopicName } from "#security/sanitize";
13
+ import { sanitizeId, sanitizeTopicName } from "#security/sanitize";
13
14
  import { resolveStorageDataDir } from "#storage/storage-host";
14
15
  import type { AgentKind, UnifiedEvent } from "#types";
15
16
 
@@ -21,6 +22,9 @@ import type { AgentKind, UnifiedEvent } from "#types";
21
22
  * {DATA_DIR}/conversations/{sanitizedTopicName}.jsonl
22
23
  * {DATA_DIR}/conversations/{sanitizedTopicName}.active.jsonl
23
24
  *
25
+ * A private General is the one room several users may hold at once, so its
26
+ * pair is qualified with the owner — see {@link topicFilename}.
27
+ *
24
28
  * The first file is append-only and retains every yielded UnifiedEvent for
25
29
  * archive and teardown. The optional active file is a replaceable provider
26
30
  * projection: compaction writes its summary there and later turns append to
@@ -49,14 +53,30 @@ function conversationDir(_userId: number | string): string {
49
53
  return join(resolveStorageDataDir(), "conversations");
50
54
  }
51
55
 
52
- function topicFilename(topicName: string): string {
56
+ /**
57
+ * One flat namespace is safe because a room title is unique per surface (S-3)
58
+ * — with exactly one exception. A manager room is deliberately exempt from
59
+ * title conflicts, since every person gets a private "General" per workspace,
60
+ * and `general` is a reserved name no other room can take. Keying the log on
61
+ * the title alone therefore pointed every user's private General at the same
62
+ * `general.jsonl`: two people's transcripts interleaved in one append-only
63
+ * file, and whatever reads it back by name (rollout reconstruction, archive,
64
+ * teardown) hands one person the other's private history.
65
+ *
66
+ * Only that room is qualified with its owner, so nothing else moves, and the
67
+ * standalone node's own principal keeps the unqualified path it has always
68
+ * written — an existing install needs no migration.
69
+ */
70
+ function topicFilename(userId: number | string, topicName: string): string {
53
71
  const t = sanitizeTopicName(topicName, true);
54
- return `${t}.jsonl`;
72
+ const owner = String(userId);
73
+ if (t !== MANAGER_TOPIC_LOG_NAME || owner === NODE_LOCAL_USER_ID) return `${t}.jsonl`;
74
+ return `${t}.${sanitizeId(owner)}.jsonl`;
55
75
  }
56
76
 
57
77
  /** Compute the absolute path for a given user/topic conversation log. */
58
78
  export function getConversationPath(userId: number | string, topicName: string): string {
59
- return join(conversationDir(userId), topicFilename(topicName));
79
+ return join(conversationDir(userId), topicFilename(userId, topicName));
60
80
  }
61
81
 
62
82
  /** Replaceable provider context derived from the append-only raw conversation log. */
@@ -1 +1 @@
1
- export const NEGOTIUM_VERSION = "0.6.4";
1
+ export const NEGOTIUM_VERSION = "0.6.6";
@@ -34,6 +34,10 @@ function validManagerTopic(value) {
34
34
  const topic = record(value);
35
35
  return Boolean(typeof topic?.id === "string" && typeof topic.title === "string" && topic.kind === "manager" && Array.isArray(topic.participants));
36
36
  }
37
+ function validDeletedMessage(value) {
38
+ const message = record(value);
39
+ return Boolean(typeof message?.id === "string" && typeof message.topicId === "string" && typeof message.authorId === "string" && typeof message.text === "string" && message.deleted === true && typeof message.createdAt === "string");
40
+ }
37
41
  function validCronJob(value) {
38
42
  const job = record(value);
39
43
  return Boolean(typeof job?.id === "string" && typeof job.name === "string" && typeof job.executionPrincipalUserId === "string" && typeof job.actorOwnerUserId === "string" && typeof job.topicId === "string" && typeof job.schedule === "string" && typeof job.enabled === "boolean" && typeof job.nextRunAt === "string" && typeof job.canMutate === "boolean");
@@ -200,6 +204,25 @@ class RuntimeGatewayClient {
200
204
  }
201
205
  return body.topic;
202
206
  }
207
+ async deleteMessage(topicId, messageId, actorUserId, allowAdmin = false) {
208
+ const response = await this.send(`/topics/${encodeURIComponent(topicId)}/messages/${encodeURIComponent(messageId)}`, {
209
+ method: "DELETE",
210
+ headers: { "content-type": "application/json" },
211
+ body: JSON.stringify({
212
+ v: RUNTIME_GATEWAY_VERSION,
213
+ actorUserId,
214
+ ...allowAdmin ? { allowAdmin: true } : {}
215
+ })
216
+ }, this.requestTimeoutMs);
217
+ if (!response.ok) {
218
+ throw new RuntimeGatewayError("Runtime Gateway message delete failed", "http", response.status);
219
+ }
220
+ const body = record(await json(response));
221
+ if (body?.ok !== true || body.v !== RUNTIME_GATEWAY_VERSION || !validDeletedMessage(body.message)) {
222
+ throw new RuntimeGatewayError("Runtime Gateway message delete response is incompatible", "protocol");
223
+ }
224
+ return body.message;
225
+ }
203
226
  async cronRequest(path, init) {
204
227
  const response = await this.send(path, init, this.requestTimeoutMs);
205
228
  if (!response.ok) {
@@ -350,4 +373,4 @@ export {
350
373
  RUNTIME_GATEWAY_CONTROL_PATH
351
374
  };
352
375
 
353
- //# debugId=A4DC2005942CF37964756E2164756E21
376
+ //# debugId=1B400FCBBC9E65B364756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/core/src/runtime-gateway.ts"],
4
4
  "sourcesContent": [
5
- "export const RUNTIME_GATEWAY_VERSION = 1 as const;\nexport const RUNTIME_GATEWAY_CONTROL_PATH = \"/api/v1/control/runtime/v1\";\n\nexport type RuntimeGatewayErrorKind = \"config\" | \"timeout\" | \"transport\" | \"protocol\" | \"http\";\n\nexport class RuntimeGatewayError extends Error {\n constructor(\n message: string,\n public readonly kind: RuntimeGatewayErrorKind,\n public readonly status?: number,\n ) {\n super(message);\n }\n}\n\nexport interface RuntimeGatewayHealth {\n ok: true;\n v: typeof RUNTIME_GATEWAY_VERSION;\n nodeId?: string;\n aiName?: string;\n capabilities: string[];\n cursor: number;\n}\n\nexport interface RuntimeGatewayTurnInput {\n topicId: string;\n /** Canonical principal on the execution node. */\n userId: string;\n /** Product-side actor, when it differs from the execution principal. */\n actorUserId?: string;\n actorLabel?: string;\n vaultUserId?: string;\n text: string;\n clientMessageId: string;\n requestId?: string;\n allowAutoContinue?: boolean;\n threadRootId?: string;\n respond?: boolean;\n /** Run without adding the injected prompt or output to the visible transcript. */\n silent?: boolean;\n attachments?: string[];\n visualTools?: boolean;\n fileDeliveryTools?: boolean;\n}\n\nexport interface RuntimeGatewayTurnAcknowledgement {\n ok: true;\n v: typeof RUNTIME_GATEWAY_VERSION;\n accepted: true;\n deduplicated: boolean;\n requestId: string;\n clientMessageId: string;\n topicId: string;\n messageId: string;\n cursor: number;\n}\n\nexport interface RuntimeGatewayTopicDeriveInput {\n userId: string;\n copyHistory: boolean;\n name?: string;\n}\n\nexport interface RuntimeGatewayDerivedTopic {\n id: string;\n title: string;\n kind?: string;\n agent?: string;\n defaultModel?: string;\n defaultEffort?: string;\n parentTopicId?: string;\n isFork?: boolean;\n}\n\nexport interface RuntimeGatewaySseEvent {\n id?: number;\n event: string;\n data: unknown;\n}\n\nexport interface RuntimeGatewayTopicUsage {\n queries: number;\n inputTokens: number;\n outputTokens: number;\n cacheCreationInputTokens: number;\n cacheReadInputTokens: number;\n estimatedCostUsd: number;\n}\n\nexport interface RuntimeGatewayManagerTopic {\n id: string;\n title: string;\n kind: \"manager\";\n agent?: \"claude\" | \"codex\" | \"maestro\";\n participants: Array<{ userId: string; role: \"owner\" | \"member\" }>;\n}\n\nexport interface RuntimeGatewayCronJob {\n id: string;\n name: string;\n executionPrincipalUserId: string;\n actorOwnerUserId: string;\n topicId: string;\n source: \"prompt\" | \"script\";\n script: string | null;\n scriptExists: boolean;\n prompt: string | null;\n promptPreview: string | null;\n summary: string | null;\n schedule: string;\n timezone: string | null;\n enabled: boolean;\n agent: \"claude\" | \"codex\" | \"maestro\" | null;\n model: string | null;\n effort: string | null;\n nextRunAt: string;\n runCount: number;\n lastRun: Record<string, unknown> | null;\n createdAt: string;\n updatedAt: string;\n canMutate: boolean;\n}\n\nexport interface RuntimeGatewayCronCreateInput {\n userId: string;\n actorUserId: string;\n topicId: string;\n name: string;\n script: string;\n schedule: string;\n timezone?: string;\n agent?: \"claude\" | \"codex\" | \"maestro\";\n model?: string;\n effort?: string;\n}\n\nexport interface RuntimeGatewayCronPatch {\n name?: string;\n topicId?: string;\n script?: string;\n schedule?: string;\n timezone?: string | null;\n enabled?: boolean;\n agent?: \"claude\" | \"codex\" | \"maestro\" | null;\n model?: string | null;\n effort?: string | null;\n}\n\nexport type RuntimeGatewayToken = string | (() => string | Promise<string>);\nexport type RuntimeGatewayFetch = (\n input: string | URL | Request,\n init?: RequestInit,\n) => Promise<Response>;\n\nexport interface RuntimeGatewayClientOptions {\n baseUrl: string;\n token: RuntimeGatewayToken;\n /** Loopback control path or an authenticated relay forward prefix. */\n pathPrefix?: string;\n fetch?: RuntimeGatewayFetch;\n requestTimeoutMs?: number;\n compactTimeoutMs?: number;\n}\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nasync function json(response: Response): Promise<unknown> {\n try {\n return await response.json();\n } catch {\n throw new RuntimeGatewayError(\n \"Runtime Gateway returned invalid JSON\",\n \"protocol\",\n response.status,\n );\n }\n}\n\nfunction validHealth(value: unknown): value is RuntimeGatewayHealth {\n const body = record(value);\n return Boolean(\n body?.ok === true &&\n body.v === RUNTIME_GATEWAY_VERSION &&\n Array.isArray(body.capabilities) &&\n typeof body.cursor === \"number\",\n );\n}\n\nfunction validTurnAck(value: unknown): value is RuntimeGatewayTurnAcknowledgement {\n const body = record(value);\n return Boolean(\n body?.ok === true &&\n body.v === RUNTIME_GATEWAY_VERSION &&\n body.accepted === true &&\n typeof body.deduplicated === \"boolean\" &&\n typeof body.requestId === \"string\" &&\n typeof body.clientMessageId === \"string\" &&\n typeof body.topicId === \"string\" &&\n typeof body.messageId === \"string\" &&\n typeof body.cursor === \"number\",\n );\n}\n\nfunction validManagerTopic(value: unknown): value is RuntimeGatewayManagerTopic {\n const topic = record(value);\n return Boolean(\n typeof topic?.id === \"string\" &&\n typeof topic.title === \"string\" &&\n topic.kind === \"manager\" &&\n Array.isArray(topic.participants),\n );\n}\n\nfunction validCronJob(value: unknown): value is RuntimeGatewayCronJob {\n const job = record(value);\n return Boolean(\n typeof job?.id === \"string\" &&\n typeof job.name === \"string\" &&\n typeof job.executionPrincipalUserId === \"string\" &&\n typeof job.actorOwnerUserId === \"string\" &&\n typeof job.topicId === \"string\" &&\n typeof job.schedule === \"string\" &&\n typeof job.enabled === \"boolean\" &&\n typeof job.nextRunAt === \"string\" &&\n typeof job.canMutate === \"boolean\",\n );\n}\n\nexport async function* parseRuntimeGatewaySse(\n body: ReadableStream<Uint8Array>,\n): AsyncGenerator<RuntimeGatewaySseEvent> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let event = \"message\";\n let id: number | undefined;\n let data: string[] = [];\n const flush = (): RuntimeGatewaySseEvent | null => {\n if (data.length === 0) return null;\n const raw = data.join(\"\\n\");\n data = [];\n try {\n return { event, id, data: JSON.parse(raw) };\n } catch {\n throw new RuntimeGatewayError(\"Runtime Gateway SSE event has invalid JSON\", \"protocol\");\n } finally {\n event = \"message\";\n id = undefined;\n }\n };\n try {\n while (true) {\n const chunk = await reader.read();\n if (chunk.done) break;\n buffer += decoder.decode(chunk.value, { stream: true }).replace(/\\r\\n/g, \"\\n\");\n let newline = buffer.indexOf(\"\\n\");\n while (newline >= 0) {\n const line = buffer.slice(0, newline);\n buffer = buffer.slice(newline + 1);\n if (line === \"\") {\n const parsed = flush();\n if (parsed) yield parsed;\n } else if (line.startsWith(\"event:\")) {\n event = line.slice(6).trim() || \"message\";\n } else if (line.startsWith(\"id:\")) {\n const parsed = Number.parseInt(line.slice(3).trim(), 10);\n if (Number.isFinite(parsed)) id = parsed;\n } else if (line.startsWith(\"data:\")) {\n data.push(line.slice(5).trimStart());\n }\n newline = buffer.indexOf(\"\\n\");\n }\n }\n buffer += decoder.decode();\n if (buffer.startsWith(\"data:\")) data.push(buffer.slice(5).trimStart());\n const parsed = flush();\n if (parsed) yield parsed;\n } finally {\n reader.releaseLock();\n }\n}\n\nexport class RuntimeGatewayClient {\n private readonly pathPrefix: string;\n private readonly request: RuntimeGatewayFetch;\n private readonly requestTimeoutMs: number;\n private readonly compactTimeoutMs: number;\n\n constructor(private readonly options: RuntimeGatewayClientOptions) {\n this.pathPrefix = options.pathPrefix ?? RUNTIME_GATEWAY_CONTROL_PATH;\n this.request = options.fetch ?? fetch;\n this.requestTimeoutMs = options.requestTimeoutMs ?? 5_000;\n this.compactTimeoutMs = options.compactTimeoutMs ?? 5 * 60_000;\n }\n\n private endpoint(path: string): string {\n if (!this.options.baseUrl || !this.options.token) {\n throw new RuntimeGatewayError(\"Runtime Gateway is not configured\", \"config\");\n }\n return `${this.options.baseUrl.replace(/\\/+$/, \"\")}${this.pathPrefix}${path}`;\n }\n\n private async authorization(): Promise<string> {\n try {\n const token =\n typeof this.options.token === \"function\" ? await this.options.token() : this.options.token;\n return `Bearer ${token}`;\n } catch (error) {\n throw new RuntimeGatewayError(\n error instanceof Error ? error.message : \"Runtime Gateway token resolution failed\",\n \"config\",\n );\n }\n }\n\n private async send(path: string, init: RequestInit, timeoutMs?: number): Promise<Response> {\n const authorization = await this.authorization();\n try {\n return await this.request(this.endpoint(path), {\n ...init,\n headers: { authorization, ...init.headers },\n signal: timeoutMs === undefined ? init.signal : AbortSignal.timeout(timeoutMs),\n });\n } catch (error) {\n if (error instanceof DOMException && error.name === \"TimeoutError\") {\n throw new RuntimeGatewayError(\"Runtime Gateway request timed out\", \"timeout\");\n }\n throw new RuntimeGatewayError(\"Runtime Gateway request failed\", \"transport\");\n }\n }\n\n async health(): Promise<RuntimeGatewayHealth> {\n const response = await this.send(\"/health\", { method: \"GET\" }, this.requestTimeoutMs);\n if (!response.ok) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway health request failed\",\n \"http\",\n response.status,\n );\n }\n const body = await json(response);\n if (!validHealth(body)) {\n throw new RuntimeGatewayError(\"Runtime Gateway health response is incompatible\", \"protocol\");\n }\n return body;\n }\n\n async submitTurn(input: RuntimeGatewayTurnInput): Promise<RuntimeGatewayTurnAcknowledgement> {\n const response = await this.send(\n \"/turns\",\n {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ v: RUNTIME_GATEWAY_VERSION, ...input }),\n },\n this.requestTimeoutMs,\n );\n if (response.status !== 202) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway turn was not accepted\",\n \"http\",\n response.status,\n );\n }\n const body = await json(response);\n if (!validTurnAck(body)) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway turn acknowledgement is incompatible\",\n \"protocol\",\n );\n }\n return body;\n }\n\n async deriveTopic(\n topicId: string,\n input: RuntimeGatewayTopicDeriveInput,\n ): Promise<RuntimeGatewayDerivedTopic> {\n const response = await this.send(\n `/topics/${encodeURIComponent(topicId)}/derive`,\n {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ v: RUNTIME_GATEWAY_VERSION, ...input }),\n },\n this.requestTimeoutMs,\n );\n if (response.status !== 201) {\n throw new RuntimeGatewayError(\"Runtime Gateway topic derive failed\", \"http\", response.status);\n }\n const body = await json(response);\n const topic = record(body)?.topic;\n const topicRecord = record(topic);\n if (\n !topicRecord ||\n typeof topicRecord.id !== \"string\" ||\n typeof topicRecord.title !== \"string\"\n ) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway topic derive response is incompatible\",\n \"protocol\",\n );\n }\n return topic as unknown as RuntimeGatewayDerivedTopic;\n }\n\n async ensureManagerTopic(userId: string): Promise<RuntimeGatewayManagerTopic> {\n const response = await this.send(\n \"/manager-topic\",\n {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ v: RUNTIME_GATEWAY_VERSION, userId }),\n },\n this.requestTimeoutMs,\n );\n if (!response.ok) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway manager topic request failed\",\n \"http\",\n response.status,\n );\n }\n const body = record(await json(response));\n if (body?.ok !== true || body.v !== RUNTIME_GATEWAY_VERSION || !validManagerTopic(body.topic)) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway manager topic response is incompatible\",\n \"protocol\",\n );\n }\n return body.topic;\n }\n\n private async cronRequest(path: string, init: RequestInit): Promise<Record<string, unknown>> {\n const response = await this.send(path, init, this.requestTimeoutMs);\n if (!response.ok) {\n throw new RuntimeGatewayError(\"Runtime Gateway cron request failed\", \"http\", response.status);\n }\n const body = record(await json(response));\n if (body?.ok !== true || body.v !== RUNTIME_GATEWAY_VERSION) {\n throw new RuntimeGatewayError(\"Runtime Gateway cron response is incompatible\", \"protocol\");\n }\n return body;\n }\n\n async listCronScripts(): Promise<string[]> {\n const body = await this.cronRequest(\"/cron/scripts\", { method: \"GET\" });\n if (!Array.isArray(body.scripts) || !body.scripts.every((value) => typeof value === \"string\")) {\n throw new RuntimeGatewayError(\"Runtime Gateway cron scripts are incompatible\", \"protocol\");\n }\n return body.scripts;\n }\n\n async listCronJobs(\n userId: string,\n actorUserId: string,\n actorIsAdmin = false,\n ): Promise<RuntimeGatewayCronJob[]> {\n const search = new URLSearchParams({\n user: userId,\n actorUserId,\n actorIsAdmin: actorIsAdmin ? \"1\" : \"0\",\n });\n const body = await this.cronRequest(`/cron/jobs?${search}`, { method: \"GET\" });\n if (!Array.isArray(body.jobs) || !body.jobs.every(validCronJob)) {\n throw new RuntimeGatewayError(\"Runtime Gateway cron jobs are incompatible\", \"protocol\");\n }\n return body.jobs;\n }\n\n async createCronJob(input: RuntimeGatewayCronCreateInput): Promise<RuntimeGatewayCronJob> {\n const body = await this.cronRequest(\"/cron/jobs\", {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ v: RUNTIME_GATEWAY_VERSION, ...input }),\n });\n if (!validCronJob(body.job)) {\n throw new RuntimeGatewayError(\"Runtime Gateway cron job is incompatible\", \"protocol\");\n }\n return body.job;\n }\n\n async updateCronJob(\n jobId: string,\n userId: string,\n actorUserId: string,\n patch: RuntimeGatewayCronPatch,\n actorIsAdmin = false,\n ): Promise<RuntimeGatewayCronJob> {\n const body = await this.cronRequest(`/cron/jobs/${encodeURIComponent(jobId)}`, {\n method: \"PATCH\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n v: RUNTIME_GATEWAY_VERSION,\n userId,\n actorUserId,\n actorIsAdmin,\n patch,\n }),\n });\n if (!validCronJob(body.job)) {\n throw new RuntimeGatewayError(\"Runtime Gateway cron job is incompatible\", \"protocol\");\n }\n return body.job;\n }\n\n async deleteCronJob(\n jobId: string,\n userId: string,\n actorUserId: string,\n actorIsAdmin = false,\n ): Promise<string> {\n const search = new URLSearchParams({\n user: userId,\n actorUserId,\n actorIsAdmin: actorIsAdmin ? \"1\" : \"0\",\n });\n const body = await this.cronRequest(`/cron/jobs/${encodeURIComponent(jobId)}?${search}`, {\n method: \"DELETE\",\n });\n if (typeof body.deleted !== \"string\") {\n throw new RuntimeGatewayError(\"Runtime Gateway cron delete is incompatible\", \"protocol\");\n }\n return body.deleted;\n }\n\n async *events(\n after: number,\n topicId?: string,\n signal?: AbortSignal,\n ): AsyncGenerator<RuntimeGatewaySseEvent> {\n const search = new URLSearchParams({ after: String(Math.max(0, after)) });\n if (topicId) search.set(\"topicId\", topicId);\n const response = await this.send(`/events?${search}`, { method: \"GET\", signal });\n if (!response.ok || !response.body) {\n throw new RuntimeGatewayError(\"Runtime Gateway event stream failed\", \"http\", response.status);\n }\n yield* parseRuntimeGatewaySse(response.body);\n }\n\n async getTopicUsage(topicId: string, userId: string): Promise<RuntimeGatewayTopicUsage> {\n const response = await this.send(\n `/topics/${encodeURIComponent(topicId)}/usage?user=${encodeURIComponent(userId)}`,\n { method: \"GET\" },\n this.requestTimeoutMs,\n );\n if (!response.ok) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway topic usage request failed\",\n \"http\",\n response.status,\n );\n }\n const usage = record(record(await json(response))?.usage);\n const read = (key: keyof RuntimeGatewayTopicUsage): number => {\n const value = usage?.[key];\n return typeof value === \"number\" && Number.isFinite(value) ? value : 0;\n };\n return {\n queries: read(\"queries\"),\n inputTokens: read(\"inputTokens\"),\n outputTokens: read(\"outputTokens\"),\n cacheCreationInputTokens: read(\"cacheCreationInputTokens\"),\n cacheReadInputTokens: read(\"cacheReadInputTokens\"),\n estimatedCostUsd: read(\"estimatedCostUsd\"),\n };\n }\n\n async abortTurn(topicId: string, userId: string): Promise<boolean> {\n const response = await this.send(\n `/topics/${encodeURIComponent(topicId)}/abort`,\n {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ v: RUNTIME_GATEWAY_VERSION, userId }),\n },\n this.requestTimeoutMs,\n );\n if (!response.ok) {\n throw new RuntimeGatewayError(\"Runtime Gateway turn abort failed\", \"http\", response.status);\n }\n const body = record(await json(response));\n if (\n body?.ok !== true ||\n body.v !== RUNTIME_GATEWAY_VERSION ||\n typeof body.aborted !== \"boolean\"\n ) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway turn abort response is incompatible\",\n \"protocol\",\n );\n }\n return body.aborted;\n }\n\n async resetSession(\n topicId: string,\n userId: string,\n reason?: string,\n ): Promise<string | undefined> {\n return this.sessionCommand(topicId, userId, \"reset\", reason);\n }\n\n async compactSession(\n topicId: string,\n userId: string,\n reason?: string,\n ): Promise<string | undefined> {\n return this.sessionCommand(topicId, userId, \"compact\", reason);\n }\n\n private async sessionCommand(\n topicId: string,\n userId: string,\n command: \"reset\" | \"compact\",\n reason?: string,\n ): Promise<string | undefined> {\n const response = await this.send(\n `/topics/${encodeURIComponent(topicId)}/session/${command}`,\n {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n v: RUNTIME_GATEWAY_VERSION,\n userId,\n ...(reason ? { reason } : {}),\n }),\n },\n command === \"compact\" ? this.compactTimeoutMs : this.requestTimeoutMs,\n );\n if (!response.ok) {\n throw new RuntimeGatewayError(\n `Runtime Gateway session ${command} failed`,\n \"http\",\n response.status,\n );\n }\n const body = record(await json(response));\n if (body?.ok !== true || body.v !== RUNTIME_GATEWAY_VERSION) {\n throw new RuntimeGatewayError(\n `Runtime Gateway session ${command} response is incompatible`,\n \"protocol\",\n );\n }\n return typeof body.result === \"string\" ? body.result : undefined;\n }\n}\n"
5
+ "export const RUNTIME_GATEWAY_VERSION = 1 as const;\nexport const RUNTIME_GATEWAY_CONTROL_PATH = \"/api/v1/control/runtime/v1\";\n\nexport type RuntimeGatewayErrorKind = \"config\" | \"timeout\" | \"transport\" | \"protocol\" | \"http\";\n\nexport class RuntimeGatewayError extends Error {\n constructor(\n message: string,\n public readonly kind: RuntimeGatewayErrorKind,\n public readonly status?: number,\n ) {\n super(message);\n }\n}\n\nexport interface RuntimeGatewayHealth {\n ok: true;\n v: typeof RUNTIME_GATEWAY_VERSION;\n nodeId?: string;\n aiName?: string;\n capabilities: string[];\n cursor: number;\n}\n\nexport interface RuntimeGatewayTurnInput {\n topicId: string;\n /** Canonical principal on the execution node. */\n userId: string;\n /** Product-side actor, when it differs from the execution principal. */\n actorUserId?: string;\n actorLabel?: string;\n vaultUserId?: string;\n text: string;\n clientMessageId: string;\n requestId?: string;\n allowAutoContinue?: boolean;\n threadRootId?: string;\n respond?: boolean;\n /** Run without adding the injected prompt or output to the visible transcript. */\n silent?: boolean;\n attachments?: string[];\n visualTools?: boolean;\n fileDeliveryTools?: boolean;\n}\n\nexport interface RuntimeGatewayTurnAcknowledgement {\n ok: true;\n v: typeof RUNTIME_GATEWAY_VERSION;\n accepted: true;\n deduplicated: boolean;\n requestId: string;\n clientMessageId: string;\n topicId: string;\n messageId: string;\n cursor: number;\n}\n\nexport interface RuntimeGatewayTopicDeriveInput {\n userId: string;\n copyHistory: boolean;\n name?: string;\n}\n\nexport interface RuntimeGatewayDerivedTopic {\n id: string;\n title: string;\n kind?: string;\n agent?: string;\n defaultModel?: string;\n defaultEffort?: string;\n parentTopicId?: string;\n isFork?: boolean;\n}\n\nexport interface RuntimeGatewaySseEvent {\n id?: number;\n event: string;\n data: unknown;\n}\n\nexport interface RuntimeGatewayTopicUsage {\n queries: number;\n inputTokens: number;\n outputTokens: number;\n cacheCreationInputTokens: number;\n cacheReadInputTokens: number;\n estimatedCostUsd: number;\n}\n\nexport interface RuntimeGatewayManagerTopic {\n id: string;\n title: string;\n kind: \"manager\";\n agent?: \"claude\" | \"codex\" | \"maestro\";\n participants: Array<{ userId: string; role: \"owner\" | \"member\" }>;\n}\n\nexport interface RuntimeGatewayDeletedMessage {\n id: string;\n topicId: string;\n authorId: string;\n text: string;\n deleted: true;\n createdAt: string;\n}\n\nexport interface RuntimeGatewayCronJob {\n id: string;\n name: string;\n executionPrincipalUserId: string;\n actorOwnerUserId: string;\n topicId: string;\n source: \"prompt\" | \"script\";\n script: string | null;\n scriptExists: boolean;\n prompt: string | null;\n promptPreview: string | null;\n summary: string | null;\n schedule: string;\n timezone: string | null;\n enabled: boolean;\n agent: \"claude\" | \"codex\" | \"maestro\" | null;\n model: string | null;\n effort: string | null;\n nextRunAt: string;\n runCount: number;\n lastRun: Record<string, unknown> | null;\n createdAt: string;\n updatedAt: string;\n canMutate: boolean;\n}\n\nexport interface RuntimeGatewayCronCreateInput {\n userId: string;\n actorUserId: string;\n topicId: string;\n name: string;\n script: string;\n schedule: string;\n timezone?: string;\n agent?: \"claude\" | \"codex\" | \"maestro\";\n model?: string;\n effort?: string;\n}\n\nexport interface RuntimeGatewayCronPatch {\n name?: string;\n topicId?: string;\n script?: string;\n schedule?: string;\n timezone?: string | null;\n enabled?: boolean;\n agent?: \"claude\" | \"codex\" | \"maestro\" | null;\n model?: string | null;\n effort?: string | null;\n}\n\nexport type RuntimeGatewayToken = string | (() => string | Promise<string>);\nexport type RuntimeGatewayFetch = (\n input: string | URL | Request,\n init?: RequestInit,\n) => Promise<Response>;\n\nexport interface RuntimeGatewayClientOptions {\n baseUrl: string;\n token: RuntimeGatewayToken;\n /** Loopback control path or an authenticated relay forward prefix. */\n pathPrefix?: string;\n fetch?: RuntimeGatewayFetch;\n requestTimeoutMs?: number;\n compactTimeoutMs?: number;\n}\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nasync function json(response: Response): Promise<unknown> {\n try {\n return await response.json();\n } catch {\n throw new RuntimeGatewayError(\n \"Runtime Gateway returned invalid JSON\",\n \"protocol\",\n response.status,\n );\n }\n}\n\nfunction validHealth(value: unknown): value is RuntimeGatewayHealth {\n const body = record(value);\n return Boolean(\n body?.ok === true &&\n body.v === RUNTIME_GATEWAY_VERSION &&\n Array.isArray(body.capabilities) &&\n typeof body.cursor === \"number\",\n );\n}\n\nfunction validTurnAck(value: unknown): value is RuntimeGatewayTurnAcknowledgement {\n const body = record(value);\n return Boolean(\n body?.ok === true &&\n body.v === RUNTIME_GATEWAY_VERSION &&\n body.accepted === true &&\n typeof body.deduplicated === \"boolean\" &&\n typeof body.requestId === \"string\" &&\n typeof body.clientMessageId === \"string\" &&\n typeof body.topicId === \"string\" &&\n typeof body.messageId === \"string\" &&\n typeof body.cursor === \"number\",\n );\n}\n\nfunction validManagerTopic(value: unknown): value is RuntimeGatewayManagerTopic {\n const topic = record(value);\n return Boolean(\n typeof topic?.id === \"string\" &&\n typeof topic.title === \"string\" &&\n topic.kind === \"manager\" &&\n Array.isArray(topic.participants),\n );\n}\n\nfunction validDeletedMessage(value: unknown): value is RuntimeGatewayDeletedMessage {\n const message = record(value);\n return Boolean(\n typeof message?.id === \"string\" &&\n typeof message.topicId === \"string\" &&\n typeof message.authorId === \"string\" &&\n typeof message.text === \"string\" &&\n message.deleted === true &&\n typeof message.createdAt === \"string\",\n );\n}\n\nfunction validCronJob(value: unknown): value is RuntimeGatewayCronJob {\n const job = record(value);\n return Boolean(\n typeof job?.id === \"string\" &&\n typeof job.name === \"string\" &&\n typeof job.executionPrincipalUserId === \"string\" &&\n typeof job.actorOwnerUserId === \"string\" &&\n typeof job.topicId === \"string\" &&\n typeof job.schedule === \"string\" &&\n typeof job.enabled === \"boolean\" &&\n typeof job.nextRunAt === \"string\" &&\n typeof job.canMutate === \"boolean\",\n );\n}\n\nexport async function* parseRuntimeGatewaySse(\n body: ReadableStream<Uint8Array>,\n): AsyncGenerator<RuntimeGatewaySseEvent> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let event = \"message\";\n let id: number | undefined;\n let data: string[] = [];\n const flush = (): RuntimeGatewaySseEvent | null => {\n if (data.length === 0) return null;\n const raw = data.join(\"\\n\");\n data = [];\n try {\n return { event, id, data: JSON.parse(raw) };\n } catch {\n throw new RuntimeGatewayError(\"Runtime Gateway SSE event has invalid JSON\", \"protocol\");\n } finally {\n event = \"message\";\n id = undefined;\n }\n };\n try {\n while (true) {\n const chunk = await reader.read();\n if (chunk.done) break;\n buffer += decoder.decode(chunk.value, { stream: true }).replace(/\\r\\n/g, \"\\n\");\n let newline = buffer.indexOf(\"\\n\");\n while (newline >= 0) {\n const line = buffer.slice(0, newline);\n buffer = buffer.slice(newline + 1);\n if (line === \"\") {\n const parsed = flush();\n if (parsed) yield parsed;\n } else if (line.startsWith(\"event:\")) {\n event = line.slice(6).trim() || \"message\";\n } else if (line.startsWith(\"id:\")) {\n const parsed = Number.parseInt(line.slice(3).trim(), 10);\n if (Number.isFinite(parsed)) id = parsed;\n } else if (line.startsWith(\"data:\")) {\n data.push(line.slice(5).trimStart());\n }\n newline = buffer.indexOf(\"\\n\");\n }\n }\n buffer += decoder.decode();\n if (buffer.startsWith(\"data:\")) data.push(buffer.slice(5).trimStart());\n const parsed = flush();\n if (parsed) yield parsed;\n } finally {\n reader.releaseLock();\n }\n}\n\nexport class RuntimeGatewayClient {\n private readonly pathPrefix: string;\n private readonly request: RuntimeGatewayFetch;\n private readonly requestTimeoutMs: number;\n private readonly compactTimeoutMs: number;\n\n constructor(private readonly options: RuntimeGatewayClientOptions) {\n this.pathPrefix = options.pathPrefix ?? RUNTIME_GATEWAY_CONTROL_PATH;\n this.request = options.fetch ?? fetch;\n this.requestTimeoutMs = options.requestTimeoutMs ?? 5_000;\n this.compactTimeoutMs = options.compactTimeoutMs ?? 5 * 60_000;\n }\n\n private endpoint(path: string): string {\n if (!this.options.baseUrl || !this.options.token) {\n throw new RuntimeGatewayError(\"Runtime Gateway is not configured\", \"config\");\n }\n return `${this.options.baseUrl.replace(/\\/+$/, \"\")}${this.pathPrefix}${path}`;\n }\n\n private async authorization(): Promise<string> {\n try {\n const token =\n typeof this.options.token === \"function\" ? await this.options.token() : this.options.token;\n return `Bearer ${token}`;\n } catch (error) {\n throw new RuntimeGatewayError(\n error instanceof Error ? error.message : \"Runtime Gateway token resolution failed\",\n \"config\",\n );\n }\n }\n\n private async send(path: string, init: RequestInit, timeoutMs?: number): Promise<Response> {\n const authorization = await this.authorization();\n try {\n return await this.request(this.endpoint(path), {\n ...init,\n headers: { authorization, ...init.headers },\n signal: timeoutMs === undefined ? init.signal : AbortSignal.timeout(timeoutMs),\n });\n } catch (error) {\n if (error instanceof DOMException && error.name === \"TimeoutError\") {\n throw new RuntimeGatewayError(\"Runtime Gateway request timed out\", \"timeout\");\n }\n throw new RuntimeGatewayError(\"Runtime Gateway request failed\", \"transport\");\n }\n }\n\n async health(): Promise<RuntimeGatewayHealth> {\n const response = await this.send(\"/health\", { method: \"GET\" }, this.requestTimeoutMs);\n if (!response.ok) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway health request failed\",\n \"http\",\n response.status,\n );\n }\n const body = await json(response);\n if (!validHealth(body)) {\n throw new RuntimeGatewayError(\"Runtime Gateway health response is incompatible\", \"protocol\");\n }\n return body;\n }\n\n async submitTurn(input: RuntimeGatewayTurnInput): Promise<RuntimeGatewayTurnAcknowledgement> {\n const response = await this.send(\n \"/turns\",\n {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ v: RUNTIME_GATEWAY_VERSION, ...input }),\n },\n this.requestTimeoutMs,\n );\n if (response.status !== 202) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway turn was not accepted\",\n \"http\",\n response.status,\n );\n }\n const body = await json(response);\n if (!validTurnAck(body)) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway turn acknowledgement is incompatible\",\n \"protocol\",\n );\n }\n return body;\n }\n\n async deriveTopic(\n topicId: string,\n input: RuntimeGatewayTopicDeriveInput,\n ): Promise<RuntimeGatewayDerivedTopic> {\n const response = await this.send(\n `/topics/${encodeURIComponent(topicId)}/derive`,\n {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ v: RUNTIME_GATEWAY_VERSION, ...input }),\n },\n this.requestTimeoutMs,\n );\n if (response.status !== 201) {\n throw new RuntimeGatewayError(\"Runtime Gateway topic derive failed\", \"http\", response.status);\n }\n const body = await json(response);\n const topic = record(body)?.topic;\n const topicRecord = record(topic);\n if (\n !topicRecord ||\n typeof topicRecord.id !== \"string\" ||\n typeof topicRecord.title !== \"string\"\n ) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway topic derive response is incompatible\",\n \"protocol\",\n );\n }\n return topic as unknown as RuntimeGatewayDerivedTopic;\n }\n\n async ensureManagerTopic(userId: string): Promise<RuntimeGatewayManagerTopic> {\n const response = await this.send(\n \"/manager-topic\",\n {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ v: RUNTIME_GATEWAY_VERSION, userId }),\n },\n this.requestTimeoutMs,\n );\n if (!response.ok) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway manager topic request failed\",\n \"http\",\n response.status,\n );\n }\n const body = record(await json(response));\n if (body?.ok !== true || body.v !== RUNTIME_GATEWAY_VERSION || !validManagerTopic(body.topic)) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway manager topic response is incompatible\",\n \"protocol\",\n );\n }\n return body.topic;\n }\n\n async deleteMessage(\n topicId: string,\n messageId: string,\n actorUserId: string,\n allowAdmin = false,\n ): Promise<RuntimeGatewayDeletedMessage> {\n const response = await this.send(\n `/topics/${encodeURIComponent(topicId)}/messages/${encodeURIComponent(messageId)}`,\n {\n method: \"DELETE\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n v: RUNTIME_GATEWAY_VERSION,\n actorUserId,\n ...(allowAdmin ? { allowAdmin: true } : {}),\n }),\n },\n this.requestTimeoutMs,\n );\n if (!response.ok) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway message delete failed\",\n \"http\",\n response.status,\n );\n }\n const body = record(await json(response));\n if (\n body?.ok !== true ||\n body.v !== RUNTIME_GATEWAY_VERSION ||\n !validDeletedMessage(body.message)\n ) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway message delete response is incompatible\",\n \"protocol\",\n );\n }\n return body.message;\n }\n\n private async cronRequest(path: string, init: RequestInit): Promise<Record<string, unknown>> {\n const response = await this.send(path, init, this.requestTimeoutMs);\n if (!response.ok) {\n throw new RuntimeGatewayError(\"Runtime Gateway cron request failed\", \"http\", response.status);\n }\n const body = record(await json(response));\n if (body?.ok !== true || body.v !== RUNTIME_GATEWAY_VERSION) {\n throw new RuntimeGatewayError(\"Runtime Gateway cron response is incompatible\", \"protocol\");\n }\n return body;\n }\n\n async listCronScripts(): Promise<string[]> {\n const body = await this.cronRequest(\"/cron/scripts\", { method: \"GET\" });\n if (!Array.isArray(body.scripts) || !body.scripts.every((value) => typeof value === \"string\")) {\n throw new RuntimeGatewayError(\"Runtime Gateway cron scripts are incompatible\", \"protocol\");\n }\n return body.scripts;\n }\n\n async listCronJobs(\n userId: string,\n actorUserId: string,\n actorIsAdmin = false,\n ): Promise<RuntimeGatewayCronJob[]> {\n const search = new URLSearchParams({\n user: userId,\n actorUserId,\n actorIsAdmin: actorIsAdmin ? \"1\" : \"0\",\n });\n const body = await this.cronRequest(`/cron/jobs?${search}`, { method: \"GET\" });\n if (!Array.isArray(body.jobs) || !body.jobs.every(validCronJob)) {\n throw new RuntimeGatewayError(\"Runtime Gateway cron jobs are incompatible\", \"protocol\");\n }\n return body.jobs;\n }\n\n async createCronJob(input: RuntimeGatewayCronCreateInput): Promise<RuntimeGatewayCronJob> {\n const body = await this.cronRequest(\"/cron/jobs\", {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ v: RUNTIME_GATEWAY_VERSION, ...input }),\n });\n if (!validCronJob(body.job)) {\n throw new RuntimeGatewayError(\"Runtime Gateway cron job is incompatible\", \"protocol\");\n }\n return body.job;\n }\n\n async updateCronJob(\n jobId: string,\n userId: string,\n actorUserId: string,\n patch: RuntimeGatewayCronPatch,\n actorIsAdmin = false,\n ): Promise<RuntimeGatewayCronJob> {\n const body = await this.cronRequest(`/cron/jobs/${encodeURIComponent(jobId)}`, {\n method: \"PATCH\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n v: RUNTIME_GATEWAY_VERSION,\n userId,\n actorUserId,\n actorIsAdmin,\n patch,\n }),\n });\n if (!validCronJob(body.job)) {\n throw new RuntimeGatewayError(\"Runtime Gateway cron job is incompatible\", \"protocol\");\n }\n return body.job;\n }\n\n async deleteCronJob(\n jobId: string,\n userId: string,\n actorUserId: string,\n actorIsAdmin = false,\n ): Promise<string> {\n const search = new URLSearchParams({\n user: userId,\n actorUserId,\n actorIsAdmin: actorIsAdmin ? \"1\" : \"0\",\n });\n const body = await this.cronRequest(`/cron/jobs/${encodeURIComponent(jobId)}?${search}`, {\n method: \"DELETE\",\n });\n if (typeof body.deleted !== \"string\") {\n throw new RuntimeGatewayError(\"Runtime Gateway cron delete is incompatible\", \"protocol\");\n }\n return body.deleted;\n }\n\n async *events(\n after: number,\n topicId?: string,\n signal?: AbortSignal,\n ): AsyncGenerator<RuntimeGatewaySseEvent> {\n const search = new URLSearchParams({ after: String(Math.max(0, after)) });\n if (topicId) search.set(\"topicId\", topicId);\n const response = await this.send(`/events?${search}`, { method: \"GET\", signal });\n if (!response.ok || !response.body) {\n throw new RuntimeGatewayError(\"Runtime Gateway event stream failed\", \"http\", response.status);\n }\n yield* parseRuntimeGatewaySse(response.body);\n }\n\n async getTopicUsage(topicId: string, userId: string): Promise<RuntimeGatewayTopicUsage> {\n const response = await this.send(\n `/topics/${encodeURIComponent(topicId)}/usage?user=${encodeURIComponent(userId)}`,\n { method: \"GET\" },\n this.requestTimeoutMs,\n );\n if (!response.ok) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway topic usage request failed\",\n \"http\",\n response.status,\n );\n }\n const usage = record(record(await json(response))?.usage);\n const read = (key: keyof RuntimeGatewayTopicUsage): number => {\n const value = usage?.[key];\n return typeof value === \"number\" && Number.isFinite(value) ? value : 0;\n };\n return {\n queries: read(\"queries\"),\n inputTokens: read(\"inputTokens\"),\n outputTokens: read(\"outputTokens\"),\n cacheCreationInputTokens: read(\"cacheCreationInputTokens\"),\n cacheReadInputTokens: read(\"cacheReadInputTokens\"),\n estimatedCostUsd: read(\"estimatedCostUsd\"),\n };\n }\n\n async abortTurn(topicId: string, userId: string): Promise<boolean> {\n const response = await this.send(\n `/topics/${encodeURIComponent(topicId)}/abort`,\n {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ v: RUNTIME_GATEWAY_VERSION, userId }),\n },\n this.requestTimeoutMs,\n );\n if (!response.ok) {\n throw new RuntimeGatewayError(\"Runtime Gateway turn abort failed\", \"http\", response.status);\n }\n const body = record(await json(response));\n if (\n body?.ok !== true ||\n body.v !== RUNTIME_GATEWAY_VERSION ||\n typeof body.aborted !== \"boolean\"\n ) {\n throw new RuntimeGatewayError(\n \"Runtime Gateway turn abort response is incompatible\",\n \"protocol\",\n );\n }\n return body.aborted;\n }\n\n async resetSession(\n topicId: string,\n userId: string,\n reason?: string,\n ): Promise<string | undefined> {\n return this.sessionCommand(topicId, userId, \"reset\", reason);\n }\n\n async compactSession(\n topicId: string,\n userId: string,\n reason?: string,\n ): Promise<string | undefined> {\n return this.sessionCommand(topicId, userId, \"compact\", reason);\n }\n\n private async sessionCommand(\n topicId: string,\n userId: string,\n command: \"reset\" | \"compact\",\n reason?: string,\n ): Promise<string | undefined> {\n const response = await this.send(\n `/topics/${encodeURIComponent(topicId)}/session/${command}`,\n {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n v: RUNTIME_GATEWAY_VERSION,\n userId,\n ...(reason ? { reason } : {}),\n }),\n },\n command === \"compact\" ? this.compactTimeoutMs : this.requestTimeoutMs,\n );\n if (!response.ok) {\n throw new RuntimeGatewayError(\n `Runtime Gateway session ${command} failed`,\n \"http\",\n response.status,\n );\n }\n const body = record(await json(response));\n if (body?.ok !== true || body.v !== RUNTIME_GATEWAY_VERSION) {\n throw new RuntimeGatewayError(\n `Runtime Gateway session ${command} response is incompatible`,\n \"protocol\",\n );\n }\n return typeof body.result === \"string\" ? body.result : undefined;\n }\n}\n"
6
6
  ],
7
- "mappings": ";;AAAO,IAAM,0BAA0B;AAChC,IAAM,+BAA+B;AAAA;AAIrC,MAAM,4BAA4B,MAAM;AAAA,EAG3B;AAAA,EACA;AAAA,EAHlB,WAAW,CACT,SACgB,MACA,QAChB;AAAA,IACA,MAAM,OAAO;AAAA,IAHG;AAAA,IACA;AAAA;AAIpB;AAuJA,SAAS,MAAM,CAAC,OAAgD;AAAA,EAC9D,OAAO,SAAS,OAAO,UAAU,aAAa,MAAM,QAAQ,KAAK,IAC5D,QACD;AAAA;AAGN,eAAe,IAAI,CAAC,UAAsC;AAAA,EACxD,IAAI;AAAA,IACF,OAAO,MAAM,SAAS,KAAK;AAAA,IAC3B,MAAM;AAAA,IACN,MAAM,IAAI,oBACR,yCACA,YACA,SAAS,MACX;AAAA;AAAA;AAIJ,SAAS,WAAW,CAAC,OAA+C;AAAA,EAClE,MAAM,OAAO,OAAO,KAAK;AAAA,EACzB,OAAO,QACL,MAAM,OAAO,QACX,KAAK,MAAM,2BACX,MAAM,QAAQ,KAAK,YAAY,KAC/B,OAAO,KAAK,WAAW,QAC3B;AAAA;AAGF,SAAS,YAAY,CAAC,OAA4D;AAAA,EAChF,MAAM,OAAO,OAAO,KAAK;AAAA,EACzB,OAAO,QACL,MAAM,OAAO,QACX,KAAK,MAAM,2BACX,KAAK,aAAa,QAClB,OAAO,KAAK,iBAAiB,aAC7B,OAAO,KAAK,cAAc,YAC1B,OAAO,KAAK,oBAAoB,YAChC,OAAO,KAAK,YAAY,YACxB,OAAO,KAAK,cAAc,YAC1B,OAAO,KAAK,WAAW,QAC3B;AAAA;AAGF,SAAS,iBAAiB,CAAC,OAAqD;AAAA,EAC9E,MAAM,QAAQ,OAAO,KAAK;AAAA,EAC1B,OAAO,QACL,OAAO,OAAO,OAAO,YACnB,OAAO,MAAM,UAAU,YACvB,MAAM,SAAS,aACf,MAAM,QAAQ,MAAM,YAAY,CACpC;AAAA;AAGF,SAAS,YAAY,CAAC,OAAgD;AAAA,EACpE,MAAM,MAAM,OAAO,KAAK;AAAA,EACxB,OAAO,QACL,OAAO,KAAK,OAAO,YACjB,OAAO,IAAI,SAAS,YACpB,OAAO,IAAI,6BAA6B,YACxC,OAAO,IAAI,qBAAqB,YAChC,OAAO,IAAI,YAAY,YACvB,OAAO,IAAI,aAAa,YACxB,OAAO,IAAI,YAAY,aACvB,OAAO,IAAI,cAAc,YACzB,OAAO,IAAI,cAAc,SAC7B;AAAA;AAGF,gBAAuB,sBAAsB,CAC3C,MACwC;AAAA,EACxC,MAAM,SAAS,KAAK,UAAU;AAAA,EAC9B,MAAM,UAAU,IAAI;AAAA,EACpB,IAAI,SAAS;AAAA,EACb,IAAI,QAAQ;AAAA,EACZ,IAAI;AAAA,EACJ,IAAI,OAAiB,CAAC;AAAA,EACtB,MAAM,QAAQ,MAAqC;AAAA,IACjD,IAAI,KAAK,WAAW;AAAA,MAAG,OAAO;AAAA,IAC9B,MAAM,MAAM,KAAK,KAAK;AAAA,CAAI;AAAA,IAC1B,OAAO,CAAC;AAAA,IACR,IAAI;AAAA,MACF,OAAO,EAAE,OAAO,IAAI,MAAM,KAAK,MAAM,GAAG,EAAE;AAAA,MAC1C,MAAM;AAAA,MACN,MAAM,IAAI,oBAAoB,8CAA8C,UAAU;AAAA,cACtF;AAAA,MACA,QAAQ;AAAA,MACR,KAAK;AAAA;AAAA;AAAA,EAGT,IAAI;AAAA,IACF,OAAO,MAAM;AAAA,MACX,MAAM,QAAQ,MAAM,OAAO,KAAK;AAAA,MAChC,IAAI,MAAM;AAAA,QAAM;AAAA,MAChB,UAAU,QAAQ,OAAO,MAAM,OAAO,EAAE,QAAQ,KAAK,CAAC,EAAE,QAAQ,SAAS;AAAA,CAAI;AAAA,MAC7E,IAAI,UAAU,OAAO,QAAQ;AAAA,CAAI;AAAA,MACjC,OAAO,WAAW,GAAG;AAAA,QACnB,MAAM,OAAO,OAAO,MAAM,GAAG,OAAO;AAAA,QACpC,SAAS,OAAO,MAAM,UAAU,CAAC;AAAA,QACjC,IAAI,SAAS,IAAI;AAAA,UACf,MAAM,UAAS,MAAM;AAAA,UACrB,IAAI;AAAA,YAAQ,MAAM;AAAA,QACpB,EAAO,SAAI,KAAK,WAAW,QAAQ,GAAG;AAAA,UACpC,QAAQ,KAAK,MAAM,CAAC,EAAE,KAAK,KAAK;AAAA,QAClC,EAAO,SAAI,KAAK,WAAW,KAAK,GAAG;AAAA,UACjC,MAAM,UAAS,OAAO,SAAS,KAAK,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE;AAAA,UACvD,IAAI,OAAO,SAAS,OAAM;AAAA,YAAG,KAAK;AAAA,QACpC,EAAO,SAAI,KAAK,WAAW,OAAO,GAAG;AAAA,UACnC,KAAK,KAAK,KAAK,MAAM,CAAC,EAAE,UAAU,CAAC;AAAA,QACrC;AAAA,QACA,UAAU,OAAO,QAAQ;AAAA,CAAI;AAAA,MAC/B;AAAA,IACF;AAAA,IACA,UAAU,QAAQ,OAAO;AAAA,IACzB,IAAI,OAAO,WAAW,OAAO;AAAA,MAAG,KAAK,KAAK,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC;AAAA,IACrE,MAAM,SAAS,MAAM;AAAA,IACrB,IAAI;AAAA,MAAQ,MAAM;AAAA,YAClB;AAAA,IACA,OAAO,YAAY;AAAA;AAAA;AAAA;AAIhB,MAAM,qBAAqB;AAAA,EAMH;AAAA,EALZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,WAAW,CAAkB,SAAsC;AAAA,IAAtC;AAAA,IAC3B,KAAK,aAAa,QAAQ,cAAc;AAAA,IACxC,KAAK,UAAU,QAAQ,SAAS;AAAA,IAChC,KAAK,mBAAmB,QAAQ,oBAAoB;AAAA,IACpD,KAAK,mBAAmB,QAAQ,oBAAoB,IAAI;AAAA;AAAA,EAGlD,QAAQ,CAAC,MAAsB;AAAA,IACrC,KAAK,KAAK,QAAQ,YAAY,KAAK,QAAQ,OAAO;AAAA,MAChD,MAAM,IAAI,oBAAoB,qCAAqC,QAAQ;AAAA,IAC7E;AAAA,IACA,OAAO,GAAG,KAAK,QAAQ,QAAQ,QAAQ,QAAQ,EAAE,IAAI,KAAK,aAAa;AAAA;AAAA,OAG3D,cAAa,GAAoB;AAAA,IAC7C,IAAI;AAAA,MACF,MAAM,QACJ,OAAO,KAAK,QAAQ,UAAU,aAAa,MAAM,KAAK,QAAQ,MAAM,IAAI,KAAK,QAAQ;AAAA,MACvF,OAAO,UAAU;AAAA,MACjB,OAAO,OAAO;AAAA,MACd,MAAM,IAAI,oBACR,iBAAiB,QAAQ,MAAM,UAAU,2CACzC,QACF;AAAA;AAAA;AAAA,OAIU,KAAI,CAAC,MAAc,MAAmB,WAAuC;AAAA,IACzF,MAAM,gBAAgB,MAAM,KAAK,cAAc;AAAA,IAC/C,IAAI;AAAA,MACF,OAAO,MAAM,KAAK,QAAQ,KAAK,SAAS,IAAI,GAAG;AAAA,WAC1C;AAAA,QACH,SAAS,EAAE,kBAAkB,KAAK,QAAQ;AAAA,QAC1C,QAAQ,cAAc,YAAY,KAAK,SAAS,YAAY,QAAQ,SAAS;AAAA,MAC/E,CAAC;AAAA,MACD,OAAO,OAAO;AAAA,MACd,IAAI,iBAAiB,gBAAgB,MAAM,SAAS,gBAAgB;AAAA,QAClE,MAAM,IAAI,oBAAoB,qCAAqC,SAAS;AAAA,MAC9E;AAAA,MACA,MAAM,IAAI,oBAAoB,kCAAkC,WAAW;AAAA;AAAA;AAAA,OAIzE,OAAM,GAAkC;AAAA,IAC5C,MAAM,WAAW,MAAM,KAAK,KAAK,WAAW,EAAE,QAAQ,MAAM,GAAG,KAAK,gBAAgB;AAAA,IACpF,KAAK,SAAS,IAAI;AAAA,MAChB,MAAM,IAAI,oBACR,yCACA,QACA,SAAS,MACX;AAAA,IACF;AAAA,IACA,MAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,IAChC,KAAK,YAAY,IAAI,GAAG;AAAA,MACtB,MAAM,IAAI,oBAAoB,mDAAmD,UAAU;AAAA,IAC7F;AAAA,IACA,OAAO;AAAA;AAAA,OAGH,WAAU,CAAC,OAA4E;AAAA,IAC3F,MAAM,WAAW,MAAM,KAAK,KAC1B,UACA;AAAA,MACE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,EAAE,GAAG,4BAA4B,MAAM,CAAC;AAAA,IAC/D,GACA,KAAK,gBACP;AAAA,IACA,IAAI,SAAS,WAAW,KAAK;AAAA,MAC3B,MAAM,IAAI,oBACR,yCACA,QACA,SAAS,MACX;AAAA,IACF;AAAA,IACA,MAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,IAChC,KAAK,aAAa,IAAI,GAAG;AAAA,MACvB,MAAM,IAAI,oBACR,wDACA,UACF;AAAA,IACF;AAAA,IACA,OAAO;AAAA;AAAA,OAGH,YAAW,CACf,SACA,OACqC;AAAA,IACrC,MAAM,WAAW,MAAM,KAAK,KAC1B,WAAW,mBAAmB,OAAO,YACrC;AAAA,MACE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,EAAE,GAAG,4BAA4B,MAAM,CAAC;AAAA,IAC/D,GACA,KAAK,gBACP;AAAA,IACA,IAAI,SAAS,WAAW,KAAK;AAAA,MAC3B,MAAM,IAAI,oBAAoB,uCAAuC,QAAQ,SAAS,MAAM;AAAA,IAC9F;AAAA,IACA,MAAM,OAAO,MAAM,KAAK,QAAQ;AAAA,IAChC,MAAM,QAAQ,OAAO,IAAI,GAAG;AAAA,IAC5B,MAAM,cAAc,OAAO,KAAK;AAAA,IAChC,KACG,eACD,OAAO,YAAY,OAAO,YAC1B,OAAO,YAAY,UAAU,UAC7B;AAAA,MACA,MAAM,IAAI,oBACR,yDACA,UACF;AAAA,IACF;AAAA,IACA,OAAO;AAAA;AAAA,OAGH,mBAAkB,CAAC,QAAqD;AAAA,IAC5E,MAAM,WAAW,MAAM,KAAK,KAC1B,kBACA;AAAA,MACE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,EAAE,GAAG,yBAAyB,OAAO,CAAC;AAAA,IAC7D,GACA,KAAK,gBACP;AAAA,IACA,KAAK,SAAS,IAAI;AAAA,MAChB,MAAM,IAAI,oBACR,gDACA,QACA,SAAS,MACX;AAAA,IACF;AAAA,IACA,MAAM,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC;AAAA,IACxC,IAAI,MAAM,OAAO,QAAQ,KAAK,MAAM,4BAA4B,kBAAkB,KAAK,KAAK,GAAG;AAAA,MAC7F,MAAM,IAAI,oBACR,0DACA,UACF;AAAA,IACF;AAAA,IACA,OAAO,KAAK;AAAA;AAAA,OAGA,YAAW,CAAC,MAAc,MAAqD;AAAA,IAC3F,MAAM,WAAW,MAAM,KAAK,KAAK,MAAM,MAAM,KAAK,gBAAgB;AAAA,IAClE,KAAK,SAAS,IAAI;AAAA,MAChB,MAAM,IAAI,oBAAoB,uCAAuC,QAAQ,SAAS,MAAM;AAAA,IAC9F;AAAA,IACA,MAAM,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC;AAAA,IACxC,IAAI,MAAM,OAAO,QAAQ,KAAK,MAAM,yBAAyB;AAAA,MAC3D,MAAM,IAAI,oBAAoB,iDAAiD,UAAU;AAAA,IAC3F;AAAA,IACA,OAAO;AAAA;AAAA,OAGH,gBAAe,GAAsB;AAAA,IACzC,MAAM,OAAO,MAAM,KAAK,YAAY,iBAAiB,EAAE,QAAQ,MAAM,CAAC;AAAA,IACtE,KAAK,MAAM,QAAQ,KAAK,OAAO,MAAM,KAAK,QAAQ,MAAM,CAAC,UAAU,OAAO,UAAU,QAAQ,GAAG;AAAA,MAC7F,MAAM,IAAI,oBAAoB,iDAAiD,UAAU;AAAA,IAC3F;AAAA,IACA,OAAO,KAAK;AAAA;AAAA,OAGR,aAAY,CAChB,QACA,aACA,eAAe,OACmB;AAAA,IAClC,MAAM,SAAS,IAAI,gBAAgB;AAAA,MACjC,MAAM;AAAA,MACN;AAAA,MACA,cAAc,eAAe,MAAM;AAAA,IACrC,CAAC;AAAA,IACD,MAAM,OAAO,MAAM,KAAK,YAAY,cAAc,UAAU,EAAE,QAAQ,MAAM,CAAC;AAAA,IAC7E,KAAK,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,KAAK,MAAM,YAAY,GAAG;AAAA,MAC/D,MAAM,IAAI,oBAAoB,8CAA8C,UAAU;AAAA,IACxF;AAAA,IACA,OAAO,KAAK;AAAA;AAAA,OAGR,cAAa,CAAC,OAAsE;AAAA,IACxF,MAAM,OAAO,MAAM,KAAK,YAAY,cAAc;AAAA,MAChD,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,EAAE,GAAG,4BAA4B,MAAM,CAAC;AAAA,IAC/D,CAAC;AAAA,IACD,KAAK,aAAa,KAAK,GAAG,GAAG;AAAA,MAC3B,MAAM,IAAI,oBAAoB,4CAA4C,UAAU;AAAA,IACtF;AAAA,IACA,OAAO,KAAK;AAAA;AAAA,OAGR,cAAa,CACjB,OACA,QACA,aACA,OACA,eAAe,OACiB;AAAA,IAChC,MAAM,OAAO,MAAM,KAAK,YAAY,cAAc,mBAAmB,KAAK,KAAK;AAAA,MAC7E,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU;AAAA,QACnB,GAAG;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,IACD,KAAK,aAAa,KAAK,GAAG,GAAG;AAAA,MAC3B,MAAM,IAAI,oBAAoB,4CAA4C,UAAU;AAAA,IACtF;AAAA,IACA,OAAO,KAAK;AAAA;AAAA,OAGR,cAAa,CACjB,OACA,QACA,aACA,eAAe,OACE;AAAA,IACjB,MAAM,SAAS,IAAI,gBAAgB;AAAA,MACjC,MAAM;AAAA,MACN;AAAA,MACA,cAAc,eAAe,MAAM;AAAA,IACrC,CAAC;AAAA,IACD,MAAM,OAAO,MAAM,KAAK,YAAY,cAAc,mBAAmB,KAAK,KAAK,UAAU;AAAA,MACvF,QAAQ;AAAA,IACV,CAAC;AAAA,IACD,IAAI,OAAO,KAAK,YAAY,UAAU;AAAA,MACpC,MAAM,IAAI,oBAAoB,+CAA+C,UAAU;AAAA,IACzF;AAAA,IACA,OAAO,KAAK;AAAA;AAAA,SAGP,MAAM,CACX,OACA,SACA,QACwC;AAAA,IACxC,MAAM,SAAS,IAAI,gBAAgB,EAAE,OAAO,OAAO,KAAK,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;AAAA,IACxE,IAAI;AAAA,MAAS,OAAO,IAAI,WAAW,OAAO;AAAA,IAC1C,MAAM,WAAW,MAAM,KAAK,KAAK,WAAW,UAAU,EAAE,QAAQ,OAAO,OAAO,CAAC;AAAA,IAC/E,KAAK,SAAS,OAAO,SAAS,MAAM;AAAA,MAClC,MAAM,IAAI,oBAAoB,uCAAuC,QAAQ,SAAS,MAAM;AAAA,IAC9F;AAAA,IACA,OAAO,uBAAuB,SAAS,IAAI;AAAA;AAAA,OAGvC,cAAa,CAAC,SAAiB,QAAmD;AAAA,IACtF,MAAM,WAAW,MAAM,KAAK,KAC1B,WAAW,mBAAmB,OAAO,gBAAgB,mBAAmB,MAAM,KAC9E,EAAE,QAAQ,MAAM,GAChB,KAAK,gBACP;AAAA,IACA,KAAK,SAAS,IAAI;AAAA,MAChB,MAAM,IAAI,oBACR,8CACA,QACA,SAAS,MACX;AAAA,IACF;AAAA,IACA,MAAM,QAAQ,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG,KAAK;AAAA,IACxD,MAAM,OAAO,CAAC,QAAgD;AAAA,MAC5D,MAAM,QAAQ,QAAQ;AAAA,MACtB,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,QAAQ;AAAA;AAAA,IAEvE,OAAO;AAAA,MACL,SAAS,KAAK,SAAS;AAAA,MACvB,aAAa,KAAK,aAAa;AAAA,MAC/B,cAAc,KAAK,cAAc;AAAA,MACjC,0BAA0B,KAAK,0BAA0B;AAAA,MACzD,sBAAsB,KAAK,sBAAsB;AAAA,MACjD,kBAAkB,KAAK,kBAAkB;AAAA,IAC3C;AAAA;AAAA,OAGI,UAAS,CAAC,SAAiB,QAAkC;AAAA,IACjE,MAAM,WAAW,MAAM,KAAK,KAC1B,WAAW,mBAAmB,OAAO,WACrC;AAAA,MACE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,EAAE,GAAG,yBAAyB,OAAO,CAAC;AAAA,IAC7D,GACA,KAAK,gBACP;AAAA,IACA,KAAK,SAAS,IAAI;AAAA,MAChB,MAAM,IAAI,oBAAoB,qCAAqC,QAAQ,SAAS,MAAM;AAAA,IAC5F;AAAA,IACA,MAAM,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC;AAAA,IACxC,IACE,MAAM,OAAO,QACb,KAAK,MAAM,2BACX,OAAO,KAAK,YAAY,WACxB;AAAA,MACA,MAAM,IAAI,oBACR,uDACA,UACF;AAAA,IACF;AAAA,IACA,OAAO,KAAK;AAAA;AAAA,OAGR,aAAY,CAChB,SACA,QACA,QAC6B;AAAA,IAC7B,OAAO,KAAK,eAAe,SAAS,QAAQ,SAAS,MAAM;AAAA;AAAA,OAGvD,eAAc,CAClB,SACA,QACA,QAC6B;AAAA,IAC7B,OAAO,KAAK,eAAe,SAAS,QAAQ,WAAW,MAAM;AAAA;AAAA,OAGjD,eAAc,CAC1B,SACA,QACA,SACA,QAC6B;AAAA,IAC7B,MAAM,WAAW,MAAM,KAAK,KAC1B,WAAW,mBAAmB,OAAO,aAAa,WAClD;AAAA,MACE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU;AAAA,QACnB,GAAG;AAAA,QACH;AAAA,WACI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,MAC7B,CAAC;AAAA,IACH,GACA,YAAY,YAAY,KAAK,mBAAmB,KAAK,gBACvD;AAAA,IACA,KAAK,SAAS,IAAI;AAAA,MAChB,MAAM,IAAI,oBACR,2BAA2B,kBAC3B,QACA,SAAS,MACX;AAAA,IACF;AAAA,IACA,MAAM,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC;AAAA,IACxC,IAAI,MAAM,OAAO,QAAQ,KAAK,MAAM,yBAAyB;AAAA,MAC3D,MAAM,IAAI,oBACR,2BAA2B,oCAC3B,UACF;AAAA,IACF;AAAA,IACA,OAAO,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAAA;AAE3D;",
8
- "debugId": "A4DC2005942CF37964756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "1B400FCBBC9E65B364756E2164756E21",
9
9
  "names": []
10
10
  }
package/dist/storage.js CHANGED
@@ -198,6 +198,9 @@ function sanitizeFileName(name) {
198
198
  return "_";
199
199
  return safe;
200
200
  }
201
+ function sanitizeId(id) {
202
+ return id.replace(/[^a-zA-Z0-9_-]/g, "_") || "_";
203
+ }
201
204
 
202
205
  // ../../packages/core/src/storage/storage-host.ts
203
206
  import { mkdirSync as mkdirSync2 } from "fs";
@@ -1256,6 +1259,8 @@ var RESERVED_TOPIC_NAMES = new Set([
1256
1259
  "general"
1257
1260
  ]);
1258
1261
  var GENERAL_TOPIC_ID = "general";
1262
+ var MANAGER_TOPIC_LOG_NAME = "general";
1263
+ var NODE_LOCAL_USER_ID = "local";
1259
1264
 
1260
1265
  // ../../packages/core/src/storage/api-topics.ts
1261
1266
  var DEFAULT_AGENT_ROOM_AGENT = "maestro";
@@ -2269,12 +2274,15 @@ import { dirname as dirname4, join as join4 } from "path";
2269
2274
  function conversationDir(_userId) {
2270
2275
  return join4(resolveStorageDataDir(), "conversations");
2271
2276
  }
2272
- function topicFilename(topicName) {
2277
+ function topicFilename(userId, topicName) {
2273
2278
  const t = sanitizeTopicName(topicName, true);
2274
- return `${t}.jsonl`;
2279
+ const owner = String(userId);
2280
+ if (t !== MANAGER_TOPIC_LOG_NAME || owner === NODE_LOCAL_USER_ID)
2281
+ return `${t}.jsonl`;
2282
+ return `${t}.${sanitizeId(owner)}.jsonl`;
2275
2283
  }
2276
2284
  function getConversationPath(userId, topicName) {
2277
- return join4(conversationDir(userId), topicFilename(topicName));
2285
+ return join4(conversationDir(userId), topicFilename(userId, topicName));
2278
2286
  }
2279
2287
  function getActiveConversationPath(userId, topicName) {
2280
2288
  const rawPath = getConversationPath(userId, topicName);
@@ -4583,4 +4591,4 @@ export {
4583
4591
  ConversationLogDivergedError
4584
4592
  };
4585
4593
 
4586
- //# debugId=86311A70E20BDB1064756E2164756E21
4594
+ //# debugId=76F1E5E0607605BC64756E2164756E21