tomo-ai 0.8.2 → 0.8.4

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 (136) hide show
  1. package/CHANGELOG.md +49 -1
  2. package/README.md +11 -1
  3. package/defaults/AGENT.md +13 -0
  4. package/defaults/CONTINUITY.md +1 -1
  5. package/defaults/skills/system/CONFIG.md +4 -1
  6. package/defaults/skills/system/SKILL.md +3 -0
  7. package/dist/agent/audience.d.ts +19 -0
  8. package/dist/agent/audience.d.ts.map +1 -0
  9. package/dist/agent/audience.js +28 -0
  10. package/dist/agent/audience.js.map +1 -0
  11. package/dist/agent/commands.d.ts +36 -0
  12. package/dist/agent/commands.d.ts.map +1 -0
  13. package/dist/agent/commands.js +260 -0
  14. package/dist/agent/commands.js.map +1 -0
  15. package/dist/agent/inbound-batcher.d.ts +54 -0
  16. package/dist/agent/inbound-batcher.d.ts.map +1 -0
  17. package/dist/agent/inbound-batcher.js +148 -0
  18. package/dist/agent/inbound-batcher.js.map +1 -0
  19. package/dist/agent/live-session.d.ts +75 -1
  20. package/dist/agent/live-session.d.ts.map +1 -1
  21. package/dist/agent/live-session.js +275 -50
  22. package/dist/agent/live-session.js.map +1 -1
  23. package/dist/agent/sdk-options.d.ts +6 -0
  24. package/dist/agent/sdk-options.d.ts.map +1 -1
  25. package/dist/agent/sdk-options.js +7 -1
  26. package/dist/agent/sdk-options.js.map +1 -1
  27. package/dist/agent.d.ts +65 -37
  28. package/dist/agent.d.ts.map +1 -1
  29. package/dist/agent.js +500 -439
  30. package/dist/agent.js.map +1 -1
  31. package/dist/channels/attachments.d.ts +8 -0
  32. package/dist/channels/attachments.d.ts.map +1 -0
  33. package/dist/channels/attachments.js +46 -0
  34. package/dist/channels/attachments.js.map +1 -0
  35. package/dist/channels/imessage.d.ts +0 -1
  36. package/dist/channels/imessage.d.ts.map +1 -1
  37. package/dist/channels/imessage.js +72 -93
  38. package/dist/channels/imessage.js.map +1 -1
  39. package/dist/channels/telegram.d.ts.map +1 -1
  40. package/dist/channels/telegram.js +112 -78
  41. package/dist/channels/telegram.js.map +1 -1
  42. package/dist/channels/text-utils.d.ts +7 -0
  43. package/dist/channels/text-utils.d.ts.map +1 -0
  44. package/dist/channels/text-utils.js +27 -0
  45. package/dist/channels/text-utils.js.map +1 -0
  46. package/dist/channels/types.d.ts +6 -1
  47. package/dist/channels/types.d.ts.map +1 -1
  48. package/dist/cli/backup.js +24 -9
  49. package/dist/cli/backup.js.map +1 -1
  50. package/dist/cli/config/shared.d.ts.map +1 -1
  51. package/dist/cli/config/shared.js +4 -5
  52. package/dist/cli/config/shared.js.map +1 -1
  53. package/dist/cli/init.d.ts.map +1 -1
  54. package/dist/cli/init.js +4 -4
  55. package/dist/cli/init.js.map +1 -1
  56. package/dist/cli/sessions.js +11 -7
  57. package/dist/cli/sessions.js.map +1 -1
  58. package/dist/cli/start.js +23 -2
  59. package/dist/cli/start.js.map +1 -1
  60. package/dist/config.d.ts +18 -0
  61. package/dist/config.d.ts.map +1 -1
  62. package/dist/config.js +43 -4
  63. package/dist/config.js.map +1 -1
  64. package/dist/continuity-defaults.d.ts +4 -0
  65. package/dist/continuity-defaults.d.ts.map +1 -0
  66. package/dist/continuity-defaults.js +4 -0
  67. package/dist/continuity-defaults.js.map +1 -0
  68. package/dist/continuity.d.ts +2 -0
  69. package/dist/continuity.d.ts.map +1 -1
  70. package/dist/continuity.js +19 -3
  71. package/dist/continuity.js.map +1 -1
  72. package/dist/cron/scheduler.d.ts +1 -0
  73. package/dist/cron/scheduler.d.ts.map +1 -1
  74. package/dist/cron/scheduler.js +22 -5
  75. package/dist/cron/scheduler.js.map +1 -1
  76. package/dist/cron/store.d.ts.map +1 -1
  77. package/dist/cron/store.js +8 -2
  78. package/dist/cron/store.js.map +1 -1
  79. package/dist/fs-utils.d.ts +6 -0
  80. package/dist/fs-utils.d.ts.map +1 -0
  81. package/dist/fs-utils.js +43 -0
  82. package/dist/fs-utils.js.map +1 -0
  83. package/dist/jsonl.d.ts +3 -0
  84. package/dist/jsonl.d.ts.map +1 -0
  85. package/dist/jsonl.js +21 -0
  86. package/dist/jsonl.js.map +1 -0
  87. package/dist/lcm/blocks.d.ts +0 -7
  88. package/dist/lcm/blocks.d.ts.map +1 -1
  89. package/dist/lcm/blocks.js +3 -31
  90. package/dist/lcm/blocks.js.map +1 -1
  91. package/dist/lcm/compact.d.ts +35 -0
  92. package/dist/lcm/compact.d.ts.map +1 -1
  93. package/dist/lcm/compact.js +14 -26
  94. package/dist/lcm/compact.js.map +1 -1
  95. package/dist/lcm/prune-tools.d.ts +5 -0
  96. package/dist/lcm/prune-tools.d.ts.map +1 -1
  97. package/dist/lcm/prune-tools.js +100 -32
  98. package/dist/lcm/prune-tools.js.map +1 -1
  99. package/dist/lcm/runner.d.ts.map +1 -1
  100. package/dist/lcm/runner.js +3 -2
  101. package/dist/lcm/runner.js.map +1 -1
  102. package/dist/lcm/stats.d.ts.map +1 -1
  103. package/dist/lcm/stats.js +6 -23
  104. package/dist/lcm/stats.js.map +1 -1
  105. package/dist/mcp/internal-server.d.ts.map +1 -1
  106. package/dist/mcp/internal-server.js +2 -0
  107. package/dist/mcp/internal-server.js.map +1 -1
  108. package/dist/mcp/oauth.d.ts.map +1 -1
  109. package/dist/mcp/oauth.js +7 -3
  110. package/dist/mcp/oauth.js.map +1 -1
  111. package/dist/mcp/pet-store.d.ts.map +1 -1
  112. package/dist/mcp/pet-store.js +10 -5
  113. package/dist/mcp/pet-store.js.map +1 -1
  114. package/dist/mcp/pet-tools.d.ts.map +1 -1
  115. package/dist/mcp/pet-tools.js +3 -1
  116. package/dist/mcp/pet-tools.js.map +1 -1
  117. package/dist/router.d.ts +28 -1
  118. package/dist/router.d.ts.map +1 -1
  119. package/dist/router.js +78 -2
  120. package/dist/router.js.map +1 -1
  121. package/dist/sessions/keys.d.ts +20 -0
  122. package/dist/sessions/keys.d.ts.map +1 -0
  123. package/dist/sessions/keys.js +45 -0
  124. package/dist/sessions/keys.js.map +1 -0
  125. package/dist/sessions/repair.d.ts.map +1 -1
  126. package/dist/sessions/repair.js +3 -2
  127. package/dist/sessions/repair.js.map +1 -1
  128. package/dist/sessions/store.d.ts +17 -2
  129. package/dist/sessions/store.d.ts.map +1 -1
  130. package/dist/sessions/store.js +134 -34
  131. package/dist/sessions/store.js.map +1 -1
  132. package/dist/sessions/summon-store.d.ts +36 -0
  133. package/dist/sessions/summon-store.d.ts.map +1 -0
  134. package/dist/sessions/summon-store.js +89 -0
  135. package/dist/sessions/summon-store.js.map +1 -0
  136. package/package.json +4 -4
@@ -0,0 +1,148 @@
1
+ import { config } from "../config.js";
2
+ import { log } from "../logger.js";
3
+ /**
4
+ * Per-session inbound message batching. Messages that pile up behind an
5
+ * in-flight turn are merged into a single follow-up turn so the agent sees
6
+ * them together (e.g. "do X" → "wait" → "nevermind" all become one prompt).
7
+ * iMessage additionally gets a settle window so provider-side fragments
8
+ * coalesce before they reach the model.
9
+ */
10
+ export class InboundBatcher {
11
+ host;
12
+ // Messages waiting to be coalesced into one user turn, keyed by sessionKey.
13
+ // Drained by the next queued task; later tasks find nothing and no-op.
14
+ pendingBatches = new Map();
15
+ pendingBatchSettleUntil = new Map();
16
+ pendingBatchSettleStartedAt = new Map();
17
+ pendingBatchDrainScheduled = new Set();
18
+ lastImessageReceiptAt = new Map();
19
+ constructor(host) {
20
+ this.host = host;
21
+ }
22
+ /**
23
+ * Queue a message for its session. For DMs and passive groups
24
+ * (`canCoalesce`), messages that arrive in quick succession are coalesced
25
+ * into one turn. Mention-required groups bypass coalescing because
26
+ * per-message mention filtering would be lost.
27
+ *
28
+ * Fire-and-forget: returns as soon as the message is queued, NOT when the
29
+ * SDK turn completes. If a caller (e.g. a channel adapter) awaits this,
30
+ * that's fine — they don't block the next ingress on an in-flight turn,
31
+ * which is what lets rapid messages pile up for the queue to coalesce.
32
+ */
33
+ enqueue(sessionKey, channel, message, canCoalesce, resolution) {
34
+ const receivedAt = Date.now();
35
+ const item = { channel, message, resolution };
36
+ if (!canCoalesce) {
37
+ this.host.enqueueForSession(sessionKey, () => this.host.processInboundItems([item]))
38
+ .catch((err) => log.error({ err, sessionKey }, "Unhandled error in message queue"));
39
+ return;
40
+ }
41
+ const batch = this.pendingBatches.get(sessionKey) ?? [];
42
+ batch.push(item);
43
+ this.pendingBatches.set(sessionKey, batch);
44
+ // With steering on, the drain runs OUTSIDE the per-session queue so it
45
+ // can inject into an in-flight turn instead of waiting behind it. The
46
+ // settle window still applies either way (iMessage fragments must
47
+ // coalesce before they reach the model). Without steering, queueing the
48
+ // drain behind the in-flight turn is what coalesces rapid messages into
49
+ // one follow-up turn.
50
+ const steerable = config.steering;
51
+ const dispatchDrain = (task) => {
52
+ if (steerable) {
53
+ task().catch((err) => log.error({ err, sessionKey }, "Unhandled error in message queue"));
54
+ }
55
+ else {
56
+ this.host.enqueueForSession(sessionKey, task)
57
+ .catch((err) => log.error({ err, sessionKey }, "Unhandled error in message queue"));
58
+ }
59
+ };
60
+ const settleMs = this.settleMs(channel.name);
61
+ const maxSettleMs = this.maxSettleMs(channel.name);
62
+ if (channel.name === "imessage") {
63
+ this.logImessageReceipt(sessionKey, message, receivedAt, batch.length, settleMs, maxSettleMs);
64
+ }
65
+ if (settleMs <= 0) {
66
+ dispatchDrain(() => this.drainPendingBatch(sessionKey, steerable));
67
+ return;
68
+ }
69
+ const settleStartedAt = this.pendingBatchSettleStartedAt.get(sessionKey) ?? receivedAt;
70
+ this.pendingBatchSettleStartedAt.set(sessionKey, settleStartedAt);
71
+ const uncappedSettleUntil = receivedAt + settleMs;
72
+ const cappedSettleUntil = maxSettleMs > 0
73
+ ? Math.min(uncappedSettleUntil, settleStartedAt + maxSettleMs)
74
+ : uncappedSettleUntil;
75
+ this.pendingBatchSettleUntil.set(sessionKey, cappedSettleUntil);
76
+ if (this.pendingBatchDrainScheduled.has(sessionKey))
77
+ return;
78
+ this.pendingBatchDrainScheduled.add(sessionKey);
79
+ dispatchDrain(async () => {
80
+ await this.waitForBatchSettle(sessionKey);
81
+ this.pendingBatchSettleUntil.delete(sessionKey);
82
+ this.pendingBatchSettleStartedAt.delete(sessionKey);
83
+ this.pendingBatchDrainScheduled.delete(sessionKey);
84
+ await this.drainPendingBatch(sessionKey, steerable);
85
+ });
86
+ }
87
+ settleMs(channelName) {
88
+ if (channelName !== "imessage")
89
+ return 0;
90
+ const ms = config.imessageInboundSettleMs;
91
+ return Number.isFinite(ms) && ms > 0 ? ms : 0;
92
+ }
93
+ maxSettleMs(channelName) {
94
+ if (channelName !== "imessage")
95
+ return 0;
96
+ const ms = config.imessageInboundMaxSettleMs;
97
+ return Number.isFinite(ms) && ms > 0 ? ms : 0;
98
+ }
99
+ logImessageReceipt(sessionKey, message, receivedAt, batchSize, settleMs, maxSettleMs) {
100
+ const previousReceivedAt = this.lastImessageReceiptAt.get(sessionKey);
101
+ this.lastImessageReceiptAt.set(sessionKey, receivedAt);
102
+ const providerLagMs = Number.isFinite(message.timestamp) ? receivedAt - message.timestamp : undefined;
103
+ log.debug({
104
+ sessionKey,
105
+ messageId: message.id,
106
+ receivedAt,
107
+ receivedAtIso: new Date(receivedAt).toISOString(),
108
+ providerTimestamp: message.timestamp,
109
+ providerLagMs,
110
+ interReceiptMs: previousReceivedAt === undefined ? undefined : receivedAt - previousReceivedAt,
111
+ batchSize,
112
+ settleMs,
113
+ maxSettleMs: maxSettleMs > 0 ? maxSettleMs : undefined,
114
+ }, "iMessage inbound fragment received");
115
+ }
116
+ async waitForBatchSettle(sessionKey) {
117
+ while (true) {
118
+ const settleUntil = this.pendingBatchSettleUntil.get(sessionKey);
119
+ if (!settleUntil)
120
+ return;
121
+ const delay = settleUntil - Date.now();
122
+ if (delay <= 0)
123
+ return;
124
+ await new Promise((resolve) => setTimeout(resolve, delay));
125
+ }
126
+ }
127
+ async drainPendingBatch(sessionKey, steerable = false) {
128
+ const items = this.pendingBatches.get(sessionKey);
129
+ if (!items || items.length === 0)
130
+ return;
131
+ this.pendingBatches.delete(sessionKey);
132
+ if (items.length > 1) {
133
+ log.info({ sessionKey, count: items.length }, `Coalescing ${items.length} queued messages into one turn`);
134
+ }
135
+ if (steerable) {
136
+ if (this.host.hasBusyLiveSession(sessionKey)) {
137
+ await this.host.processInboundItems(items, true);
138
+ return;
139
+ }
140
+ // No turn in flight — process through the ordinary per-session queue.
141
+ this.host.enqueueForSession(sessionKey, () => this.host.processInboundItems(items))
142
+ .catch((err) => log.error({ err, sessionKey }, "Unhandled error in message queue"));
143
+ return;
144
+ }
145
+ await this.host.processInboundItems(items);
146
+ }
147
+ }
148
+ //# sourceMappingURL=inbound-batcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbound-batcher.js","sourceRoot":"","sources":["../../src/agent/inbound-batcher.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,16 @@ export interface MessageRequest {
15
15
  resolve: (response: string) => void;
16
16
  reject: (err: Error) => void;
17
17
  }
18
+ /**
19
+ * Sentinel resolution for a steered message that merged into the in-flight
20
+ * turn: that turn's owner request receives (and delivers) the combined
21
+ * response, so the steered caller gets this empty marker instead. The empty
22
+ * string is safe as a sentinel only because send()/steer() can never
23
+ * legitimately resolve with "" — empty turns fall back to "I'm not sure how
24
+ * to respond to that." in the result handler.
25
+ */
26
+ export declare const STEER_MERGED = "";
27
+ export declare const QUERY_TIMEOUT_ERROR_PREFIX = "Query timed out after";
18
28
  export interface QueryResult {
19
29
  costUsd: number;
20
30
  inputTokens: number;
@@ -30,8 +40,13 @@ export interface QueryResult {
30
40
  }
31
41
  export declare class LiveSession {
32
42
  private q;
33
- private pendingMessage;
43
+ private inputQueue;
44
+ private inputWaiter;
34
45
  private currentRequest;
46
+ private mergedRequests;
47
+ private pendingSteers;
48
+ private promotedSteerText;
49
+ private idleWaiters;
35
50
  private parts;
36
51
  private streamingText;
37
52
  private sessionId;
@@ -45,8 +60,48 @@ export declare class LiveSession {
45
60
  private activeStreamBlockTypes;
46
61
  constructor(options: ReturnType<typeof sdkOptions>, sessionKey?: string, turnBudget?: TurnBudget);
47
62
  private messageGenerator;
63
+ private pushInput;
48
64
  private consumeEvents;
65
+ /**
66
+ * Reject the in-flight turn's owner plus any merged/pending steered
67
+ * requests, clear turn state, and wake idle waiters. No-op when idle.
68
+ */
69
+ private failTurn;
70
+ /** Resolves when no turn is in flight (or the session dies). */
71
+ waitForIdle(): Promise<void>;
72
+ private notifyIdle;
73
+ /**
74
+ * A local timeout means the SDK child may still be working on input we have
75
+ * already yielded. Retire the live child instead of merely clearing request
76
+ * bookkeeping; otherwise later sends can be pushed into a stale in-flight
77
+ * conversation that this wrapper now believes is idle.
78
+ */
79
+ private timeoutTurn;
80
+ /**
81
+ * True while a turn is in flight — including steered messages the CLI may
82
+ * still run as a follow-up turn after the current one resolves.
83
+ */
84
+ isBusy(): boolean;
49
85
  private handleEvent;
86
+ /**
87
+ * Observability-only path for subagent events (parent_tool_use_id set):
88
+ * log tool activity so subagent work shows up in the logs, but never touch
89
+ * turn state (parts/streamingText) or channel-facing callbacks.
90
+ */
91
+ private logSubagentEvent;
92
+ private logToolResults;
93
+ /**
94
+ * Steered-message bookkeeping from the CLI's replay events (requires the
95
+ * --replay-user-messages flag, passed via extraArgs when config.steering
96
+ * is on; non-replay user events never carry steered text verbatim, so
97
+ * matching is restricted to isReplay events to avoid false positives).
98
+ * Two shapes appear:
99
+ * - A pending steer's text echoed mid-turn → the CLI injected it into
100
+ * the in-flight turn at a tool boundary; fold it into this turn.
101
+ * - The promoted steer's own text echoed at its turn's start → the CLI
102
+ * batched the remaining queued steers into that promoted turn.
103
+ */
104
+ private matchSteerEchoes;
50
105
  private logContextUsage;
51
106
  send(text: string, onText?: (text: string) => void, images?: Array<{
52
107
  data: string;
@@ -56,6 +111,25 @@ export declare class LiveSession {
56
111
  mediaType: string;
57
112
  filename?: string;
58
113
  }>): Promise<string>;
114
+ /**
115
+ * Inject a message into the in-flight turn instead of waiting behind it
116
+ * (config `steering`). The CLI delivers it at the next tool-call boundary;
117
+ * if the turn has no boundary left, the CLI queues it and runs it as the
118
+ * next turn. Resolution:
119
+ * - merged into the in-flight turn → resolves with STEER_MERGED; the
120
+ * turn's owner request streams and resolves the combined response.
121
+ * - ran as its own follow-up turn → resolves with that turn's response,
122
+ * streamed through the callbacks passed here.
123
+ * Falls back to a plain send() when no turn is in flight.
124
+ */
125
+ steer(text: string, onText?: (text: string) => void, images?: Array<{
126
+ data: string;
127
+ mediaType: string;
128
+ }>, onBlockComplete?: (text: string) => void | Promise<void>, documents?: Array<{
129
+ data: string;
130
+ mediaType: string;
131
+ filename?: string;
132
+ }>): Promise<string>;
59
133
  getSessionId(): string | null;
60
134
  isAlive(): boolean;
61
135
  close(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"live-session.d.ts","sourceRoot":"","sources":["../../src/agent/live-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAmB,MAAM,gCAAgC,CAAC;AAEzG,OAAO,EAAmB,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAErF,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,cAAc,CAAC;IACxB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,MAAM,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACvD;AAmDD,qBAAa,WAAW;IACtB,OAAO,CAAC,CAAC,CAAQ;IACjB,OAAO,CAAC,cAAc,CAAgD;IACtE,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,KAAK,CAAQ;IACrB,UAAU,EAAE,WAAW,GAAG,IAAI,CAAQ;IACtC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,UAAU,CAAyB;IAG3C,OAAO,CAAC,gBAAgB,CAA6B;IACrD,OAAO,CAAC,sBAAsB,CAA6B;gBAE/C,OAAO,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,UAAU;YAOjF,gBAAgB;YAUjB,aAAa;YAeb,WAAW;YAyIX,eAAe;IA6CvB,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAC/B,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,EACnD,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EACxD,SAAS,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GACxE,OAAO,CAAC,MAAM,CAAC;IA2DlB,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B,OAAO,IAAI,OAAO;IAIlB,KAAK,IAAI,IAAI;CAId"}
1
+ {"version":3,"file":"live-session.d.ts","sourceRoot":"","sources":["../../src/agent/live-session.ts"],"names":[],"mappings":"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"}