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.
- package/CHANGELOG.md +49 -1
- package/README.md +11 -1
- package/defaults/AGENT.md +13 -0
- package/defaults/CONTINUITY.md +1 -1
- package/defaults/skills/system/CONFIG.md +4 -1
- package/defaults/skills/system/SKILL.md +3 -0
- package/dist/agent/audience.d.ts +19 -0
- package/dist/agent/audience.d.ts.map +1 -0
- package/dist/agent/audience.js +28 -0
- package/dist/agent/audience.js.map +1 -0
- package/dist/agent/commands.d.ts +36 -0
- package/dist/agent/commands.d.ts.map +1 -0
- package/dist/agent/commands.js +260 -0
- package/dist/agent/commands.js.map +1 -0
- package/dist/agent/inbound-batcher.d.ts +54 -0
- package/dist/agent/inbound-batcher.d.ts.map +1 -0
- package/dist/agent/inbound-batcher.js +148 -0
- package/dist/agent/inbound-batcher.js.map +1 -0
- package/dist/agent/live-session.d.ts +75 -1
- package/dist/agent/live-session.d.ts.map +1 -1
- package/dist/agent/live-session.js +275 -50
- package/dist/agent/live-session.js.map +1 -1
- package/dist/agent/sdk-options.d.ts +6 -0
- package/dist/agent/sdk-options.d.ts.map +1 -1
- package/dist/agent/sdk-options.js +7 -1
- package/dist/agent/sdk-options.js.map +1 -1
- package/dist/agent.d.ts +65 -37
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +500 -439
- package/dist/agent.js.map +1 -1
- package/dist/channels/attachments.d.ts +8 -0
- package/dist/channels/attachments.d.ts.map +1 -0
- package/dist/channels/attachments.js +46 -0
- package/dist/channels/attachments.js.map +1 -0
- package/dist/channels/imessage.d.ts +0 -1
- package/dist/channels/imessage.d.ts.map +1 -1
- package/dist/channels/imessage.js +72 -93
- package/dist/channels/imessage.js.map +1 -1
- package/dist/channels/telegram.d.ts.map +1 -1
- package/dist/channels/telegram.js +112 -78
- package/dist/channels/telegram.js.map +1 -1
- package/dist/channels/text-utils.d.ts +7 -0
- package/dist/channels/text-utils.d.ts.map +1 -0
- package/dist/channels/text-utils.js +27 -0
- package/dist/channels/text-utils.js.map +1 -0
- package/dist/channels/types.d.ts +6 -1
- package/dist/channels/types.d.ts.map +1 -1
- package/dist/cli/backup.js +24 -9
- package/dist/cli/backup.js.map +1 -1
- package/dist/cli/config/shared.d.ts.map +1 -1
- package/dist/cli/config/shared.js +4 -5
- package/dist/cli/config/shared.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +4 -4
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/sessions.js +11 -7
- package/dist/cli/sessions.js.map +1 -1
- package/dist/cli/start.js +23 -2
- package/dist/cli/start.js.map +1 -1
- package/dist/config.d.ts +18 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +43 -4
- package/dist/config.js.map +1 -1
- package/dist/continuity-defaults.d.ts +4 -0
- package/dist/continuity-defaults.d.ts.map +1 -0
- package/dist/continuity-defaults.js +4 -0
- package/dist/continuity-defaults.js.map +1 -0
- package/dist/continuity.d.ts +2 -0
- package/dist/continuity.d.ts.map +1 -1
- package/dist/continuity.js +19 -3
- package/dist/continuity.js.map +1 -1
- package/dist/cron/scheduler.d.ts +1 -0
- package/dist/cron/scheduler.d.ts.map +1 -1
- package/dist/cron/scheduler.js +22 -5
- package/dist/cron/scheduler.js.map +1 -1
- package/dist/cron/store.d.ts.map +1 -1
- package/dist/cron/store.js +8 -2
- package/dist/cron/store.js.map +1 -1
- package/dist/fs-utils.d.ts +6 -0
- package/dist/fs-utils.d.ts.map +1 -0
- package/dist/fs-utils.js +43 -0
- package/dist/fs-utils.js.map +1 -0
- package/dist/jsonl.d.ts +3 -0
- package/dist/jsonl.d.ts.map +1 -0
- package/dist/jsonl.js +21 -0
- package/dist/jsonl.js.map +1 -0
- package/dist/lcm/blocks.d.ts +0 -7
- package/dist/lcm/blocks.d.ts.map +1 -1
- package/dist/lcm/blocks.js +3 -31
- package/dist/lcm/blocks.js.map +1 -1
- package/dist/lcm/compact.d.ts +35 -0
- package/dist/lcm/compact.d.ts.map +1 -1
- package/dist/lcm/compact.js +14 -26
- package/dist/lcm/compact.js.map +1 -1
- package/dist/lcm/prune-tools.d.ts +5 -0
- package/dist/lcm/prune-tools.d.ts.map +1 -1
- package/dist/lcm/prune-tools.js +100 -32
- package/dist/lcm/prune-tools.js.map +1 -1
- package/dist/lcm/runner.d.ts.map +1 -1
- package/dist/lcm/runner.js +3 -2
- package/dist/lcm/runner.js.map +1 -1
- package/dist/lcm/stats.d.ts.map +1 -1
- package/dist/lcm/stats.js +6 -23
- package/dist/lcm/stats.js.map +1 -1
- package/dist/mcp/internal-server.d.ts.map +1 -1
- package/dist/mcp/internal-server.js +2 -0
- package/dist/mcp/internal-server.js.map +1 -1
- package/dist/mcp/oauth.d.ts.map +1 -1
- package/dist/mcp/oauth.js +7 -3
- package/dist/mcp/oauth.js.map +1 -1
- package/dist/mcp/pet-store.d.ts.map +1 -1
- package/dist/mcp/pet-store.js +10 -5
- package/dist/mcp/pet-store.js.map +1 -1
- package/dist/mcp/pet-tools.d.ts.map +1 -1
- package/dist/mcp/pet-tools.js +3 -1
- package/dist/mcp/pet-tools.js.map +1 -1
- package/dist/router.d.ts +28 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +78 -2
- package/dist/router.js.map +1 -1
- package/dist/sessions/keys.d.ts +20 -0
- package/dist/sessions/keys.d.ts.map +1 -0
- package/dist/sessions/keys.js +45 -0
- package/dist/sessions/keys.js.map +1 -0
- package/dist/sessions/repair.d.ts.map +1 -1
- package/dist/sessions/repair.js +3 -2
- package/dist/sessions/repair.js.map +1 -1
- package/dist/sessions/store.d.ts +17 -2
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +134 -34
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/summon-store.d.ts +36 -0
- package/dist/sessions/summon-store.d.ts.map +1 -0
- package/dist/sessions/summon-store.js +89 -0
- package/dist/sessions/summon-store.js.map +1 -0
- 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
|
|
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;
|
|
1
|
+
{"version":3,"file":"live-session.d.ts","sourceRoot":"","sources":["../../src/agent/live-session.ts"],"names":[],"mappings":"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"}
|