@posthog/agent 2.3.167 → 2.3.169
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/agent.js +570 -386
- package/dist/agent.js.map +1 -1
- package/dist/gateway-models.d.ts +2 -1
- package/dist/gateway-models.js +2 -0
- package/dist/gateway-models.js.map +1 -1
- package/dist/posthog-api.js +1 -1
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.js +580 -397
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +557 -377
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +1 -1
- package/src/adapters/acp-connection.ts +53 -334
- package/src/adapters/base-acp-agent.ts +13 -2
- package/src/adapters/codex/codex-agent.ts +355 -0
- package/src/adapters/codex/codex-client.ts +151 -0
- package/src/adapters/codex/session-state.ts +65 -0
- package/src/adapters/codex/settings.ts +127 -0
- package/src/agent.ts +4 -1
- package/src/gateway-models.ts +2 -0
package/package.json
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
import { AgentSideConnection, ndJsonStream } from "@agentclientprotocol/sdk";
|
|
2
|
-
import { POSTHOG_NOTIFICATIONS } from "../acp-extensions";
|
|
3
|
-
import { formatModelId } from "../gateway-models";
|
|
4
2
|
import type { SessionLogWriter } from "../session-log-writer";
|
|
5
3
|
import type { ProcessSpawnedCallback } from "../types";
|
|
6
4
|
import { Logger } from "../utils/logger";
|
|
7
5
|
import {
|
|
8
6
|
createBidirectionalStreams,
|
|
9
7
|
createTappedWritableStream,
|
|
10
|
-
nodeReadableToWebReadable,
|
|
11
|
-
nodeWritableToWebWritable,
|
|
12
8
|
type StreamPair,
|
|
13
9
|
} from "../utils/streams";
|
|
14
10
|
import { ClaudeAcpAgent } from "./claude/claude-agent";
|
|
15
|
-
import {
|
|
11
|
+
import { CodexAcpAgent } from "./codex/codex-agent";
|
|
12
|
+
import type { CodexProcessOptions } from "./codex/spawn";
|
|
16
13
|
|
|
17
14
|
type AgentAdapter = "claude" | "codex";
|
|
18
15
|
|
|
@@ -37,108 +34,6 @@ export type AcpConnection = {
|
|
|
37
34
|
|
|
38
35
|
export type InProcessAcpConnection = AcpConnection;
|
|
39
36
|
|
|
40
|
-
type ModelOption = { value?: string; name?: string };
|
|
41
|
-
type ModelGroup = { group?: string; name?: string; options?: ModelOption[] };
|
|
42
|
-
|
|
43
|
-
type ConfigOption = {
|
|
44
|
-
id?: string;
|
|
45
|
-
category?: string | null;
|
|
46
|
-
currentValue?: string;
|
|
47
|
-
options?: Array<ModelOption | ModelGroup>;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
function isGroupedOptions(
|
|
51
|
-
options: NonNullable<ConfigOption["options"]>,
|
|
52
|
-
): options is ModelGroup[] {
|
|
53
|
-
return options.length > 0 && "group" in options[0];
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function formatOption(o: ModelOption): ModelOption {
|
|
57
|
-
if (!o.value) return o;
|
|
58
|
-
return { ...o, name: formatModelId(o.value) };
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function filterModelConfigOptions(
|
|
62
|
-
msg: Record<string, unknown>,
|
|
63
|
-
allowedModelIds: Set<string>,
|
|
64
|
-
): Record<string, unknown> | null {
|
|
65
|
-
const payload = msg as {
|
|
66
|
-
method?: string;
|
|
67
|
-
result?: { configOptions?: ConfigOption[] };
|
|
68
|
-
params?: {
|
|
69
|
-
update?: { sessionUpdate?: string; configOptions?: ConfigOption[] };
|
|
70
|
-
};
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
const configOptions =
|
|
74
|
-
payload.result?.configOptions ?? payload.params?.update?.configOptions;
|
|
75
|
-
if (!configOptions) return null;
|
|
76
|
-
|
|
77
|
-
const filtered = configOptions.map((opt) => {
|
|
78
|
-
if (opt.category !== "model" || !opt.options) return opt;
|
|
79
|
-
|
|
80
|
-
const options = opt.options;
|
|
81
|
-
if (isGroupedOptions(options)) {
|
|
82
|
-
const filteredOptions = options.map((group) => ({
|
|
83
|
-
...group,
|
|
84
|
-
options: (group.options ?? [])
|
|
85
|
-
.filter((o) => o?.value && allowedModelIds.has(o.value))
|
|
86
|
-
.map(formatOption),
|
|
87
|
-
}));
|
|
88
|
-
const flat = filteredOptions.flatMap((g) => g.options ?? []);
|
|
89
|
-
const currentAllowed =
|
|
90
|
-
opt.currentValue && allowedModelIds.has(opt.currentValue);
|
|
91
|
-
const nextCurrent =
|
|
92
|
-
currentAllowed || flat.length === 0 ? opt.currentValue : flat[0]?.value;
|
|
93
|
-
|
|
94
|
-
return {
|
|
95
|
-
...opt,
|
|
96
|
-
currentValue: nextCurrent,
|
|
97
|
-
options: filteredOptions,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const valueOptions = options as ModelOption[];
|
|
102
|
-
const filteredOptions = valueOptions
|
|
103
|
-
.filter((o) => o?.value && allowedModelIds.has(o.value))
|
|
104
|
-
.map(formatOption);
|
|
105
|
-
const currentAllowed =
|
|
106
|
-
opt.currentValue && allowedModelIds.has(opt.currentValue);
|
|
107
|
-
const nextCurrent =
|
|
108
|
-
currentAllowed || filteredOptions.length === 0
|
|
109
|
-
? opt.currentValue
|
|
110
|
-
: filteredOptions[0]?.value;
|
|
111
|
-
|
|
112
|
-
return {
|
|
113
|
-
...opt,
|
|
114
|
-
currentValue: nextCurrent,
|
|
115
|
-
options: filteredOptions,
|
|
116
|
-
};
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
if (payload.result?.configOptions) {
|
|
120
|
-
return { ...msg, result: { ...payload.result, configOptions: filtered } };
|
|
121
|
-
}
|
|
122
|
-
if (payload.params?.update?.configOptions) {
|
|
123
|
-
return {
|
|
124
|
-
...msg,
|
|
125
|
-
params: {
|
|
126
|
-
...payload.params,
|
|
127
|
-
update: { ...payload.params.update, configOptions: filtered },
|
|
128
|
-
},
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function extractReasoningEffort(
|
|
135
|
-
configOptions: ConfigOption[] | undefined,
|
|
136
|
-
): string | undefined {
|
|
137
|
-
if (!configOptions) return undefined;
|
|
138
|
-
const option = configOptions.find((opt) => opt.id === "reasoning_effort");
|
|
139
|
-
return option?.currentValue ?? undefined;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
37
|
/**
|
|
143
38
|
* Creates an ACP connection with the specified agent framework.
|
|
144
39
|
*
|
|
@@ -234,247 +129,51 @@ function createClaudeConnection(config: AcpConnectionConfig): AcpConnection {
|
|
|
234
129
|
};
|
|
235
130
|
}
|
|
236
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Creates an ACP connection to codex-acp via an in-process proxy agent.
|
|
134
|
+
*
|
|
135
|
+
* The CodexAcpAgent implements the ACP Agent interface and delegates to
|
|
136
|
+
* the codex-acp binary over a ClientSideConnection. This replaces the
|
|
137
|
+
* previous raw stream transform approach and gives us proper interception
|
|
138
|
+
* points for PostHog-specific features.
|
|
139
|
+
*/
|
|
237
140
|
function createCodexConnection(config: AcpConnectionConfig): AcpConnection {
|
|
238
141
|
const logger =
|
|
239
142
|
config.logger?.child("CodexConnection") ??
|
|
240
143
|
new Logger({ debug: true, prefix: "[CodexConnection]" });
|
|
241
144
|
|
|
242
145
|
const { logWriter } = config;
|
|
243
|
-
const allowedModelIds = config.allowedModelIds;
|
|
244
|
-
|
|
245
|
-
const codexProcess = spawnCodexProcess({
|
|
246
|
-
...config.codexOptions,
|
|
247
|
-
logger,
|
|
248
|
-
processCallbacks: config.processCallbacks,
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
let clientReadable = nodeReadableToWebReadable(codexProcess.stdout);
|
|
252
|
-
let clientWritable = nodeWritableToWebWritable(codexProcess.stdin);
|
|
253
|
-
|
|
254
|
-
let isLoadingSession = false;
|
|
255
|
-
let loadRequestId: string | number | null = null;
|
|
256
|
-
let newSessionRequestId: string | number | null = null;
|
|
257
|
-
let sdkSessionEmitted = false;
|
|
258
|
-
const reasoningEffortBySessionId = new Map<string, string>();
|
|
259
|
-
let injectedConfigId = 0;
|
|
260
|
-
|
|
261
|
-
const decoder = new TextDecoder();
|
|
262
|
-
const encoder = new TextEncoder();
|
|
263
|
-
let readBuffer = "";
|
|
264
|
-
|
|
265
|
-
const taskRunId = config.taskRunId;
|
|
266
|
-
|
|
267
|
-
const filteringReadable = clientReadable.pipeThrough(
|
|
268
|
-
new TransformStream<Uint8Array, Uint8Array>({
|
|
269
|
-
transform(chunk, controller) {
|
|
270
|
-
readBuffer += decoder.decode(chunk, { stream: true });
|
|
271
|
-
const lines = readBuffer.split("\n");
|
|
272
|
-
readBuffer = lines.pop() ?? "";
|
|
273
|
-
|
|
274
|
-
const outputLines: string[] = [];
|
|
275
|
-
|
|
276
|
-
for (const line of lines) {
|
|
277
|
-
const trimmed = line.trim();
|
|
278
|
-
if (!trimmed) {
|
|
279
|
-
outputLines.push(line);
|
|
280
|
-
continue;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
let shouldFilter = false;
|
|
284
146
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
const sessionId =
|
|
288
|
-
msg?.params?.sessionId ?? msg?.result?.sessionId ?? null;
|
|
289
|
-
const configOptions =
|
|
290
|
-
msg?.result?.configOptions ?? msg?.params?.update?.configOptions;
|
|
291
|
-
if (sessionId && configOptions) {
|
|
292
|
-
const effort = extractReasoningEffort(configOptions);
|
|
293
|
-
if (effort) {
|
|
294
|
-
reasoningEffortBySessionId.set(sessionId, effort);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if (
|
|
299
|
-
!sdkSessionEmitted &&
|
|
300
|
-
newSessionRequestId !== null &&
|
|
301
|
-
msg.id === newSessionRequestId &&
|
|
302
|
-
"result" in msg
|
|
303
|
-
) {
|
|
304
|
-
const sessionId = msg.result?.sessionId;
|
|
305
|
-
if (sessionId && taskRunId) {
|
|
306
|
-
const sdkSessionNotification = {
|
|
307
|
-
jsonrpc: "2.0",
|
|
308
|
-
method: POSTHOG_NOTIFICATIONS.SDK_SESSION,
|
|
309
|
-
params: {
|
|
310
|
-
taskRunId,
|
|
311
|
-
sessionId,
|
|
312
|
-
adapter: "codex",
|
|
313
|
-
},
|
|
314
|
-
};
|
|
315
|
-
outputLines.push(JSON.stringify(sdkSessionNotification));
|
|
316
|
-
sdkSessionEmitted = true;
|
|
317
|
-
}
|
|
318
|
-
newSessionRequestId = null;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
if (isLoadingSession) {
|
|
322
|
-
if (msg.id === loadRequestId && "result" in msg) {
|
|
323
|
-
logger.debug("session/load complete, resuming stream");
|
|
324
|
-
isLoadingSession = false;
|
|
325
|
-
loadRequestId = null;
|
|
326
|
-
} else if (msg.method === "session/update") {
|
|
327
|
-
shouldFilter = true;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
if (!shouldFilter && allowedModelIds && allowedModelIds.size > 0) {
|
|
332
|
-
const updated = filterModelConfigOptions(msg, allowedModelIds);
|
|
333
|
-
if (updated) {
|
|
334
|
-
outputLines.push(JSON.stringify(updated));
|
|
335
|
-
continue;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
} catch {
|
|
339
|
-
// Not valid JSON, pass through
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
if (!shouldFilter) {
|
|
343
|
-
outputLines.push(line);
|
|
344
|
-
const isChunkNoise =
|
|
345
|
-
trimmed.includes('"sessionUpdate":"agent_message_chunk"') ||
|
|
346
|
-
trimmed.includes('"sessionUpdate":"agent_thought_chunk"');
|
|
347
|
-
if (!isChunkNoise) {
|
|
348
|
-
logger.debug("codex-acp stdout:", trimmed);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
if (outputLines.length > 0) {
|
|
354
|
-
const output = `${outputLines.join("\n")}\n`;
|
|
355
|
-
controller.enqueue(encoder.encode(output));
|
|
356
|
-
}
|
|
357
|
-
},
|
|
358
|
-
flush(controller) {
|
|
359
|
-
if (readBuffer.trim()) {
|
|
360
|
-
controller.enqueue(encoder.encode(readBuffer));
|
|
361
|
-
}
|
|
362
|
-
},
|
|
363
|
-
}),
|
|
364
|
-
);
|
|
365
|
-
clientReadable = filteringReadable;
|
|
366
|
-
|
|
367
|
-
const originalWritable = clientWritable;
|
|
368
|
-
clientWritable = new WritableStream({
|
|
369
|
-
write(chunk) {
|
|
370
|
-
const text = decoder.decode(chunk, { stream: true });
|
|
371
|
-
const trimmed = text.trim();
|
|
372
|
-
logger.debug("codex-acp stdin:", trimmed);
|
|
373
|
-
|
|
374
|
-
try {
|
|
375
|
-
const msg = JSON.parse(trimmed);
|
|
376
|
-
if (
|
|
377
|
-
msg.method === "session/set_config_option" &&
|
|
378
|
-
msg.params?.configId === "reasoning_effort" &&
|
|
379
|
-
msg.params?.sessionId &&
|
|
380
|
-
msg.params?.value
|
|
381
|
-
) {
|
|
382
|
-
reasoningEffortBySessionId.set(
|
|
383
|
-
msg.params.sessionId,
|
|
384
|
-
msg.params.value,
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
if (msg.method === "session/prompt" && msg.params?.sessionId) {
|
|
388
|
-
const effort = reasoningEffortBySessionId.get(msg.params.sessionId);
|
|
389
|
-
if (effort) {
|
|
390
|
-
const injection = {
|
|
391
|
-
jsonrpc: "2.0",
|
|
392
|
-
id: `reasoning_effort_${Date.now()}_${injectedConfigId++}`,
|
|
393
|
-
method: "session/set_config_option",
|
|
394
|
-
params: {
|
|
395
|
-
sessionId: msg.params.sessionId,
|
|
396
|
-
configId: "reasoning_effort",
|
|
397
|
-
value: effort,
|
|
398
|
-
},
|
|
399
|
-
};
|
|
400
|
-
const injectionLine = `${JSON.stringify(injection)}\n`;
|
|
401
|
-
const writer = originalWritable.getWriter();
|
|
402
|
-
return writer
|
|
403
|
-
.write(encoder.encode(injectionLine))
|
|
404
|
-
.then(() => writer.releaseLock())
|
|
405
|
-
.then(() => {
|
|
406
|
-
const nextWriter = originalWritable.getWriter();
|
|
407
|
-
return nextWriter
|
|
408
|
-
.write(chunk)
|
|
409
|
-
.finally(() => nextWriter.releaseLock());
|
|
410
|
-
});
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
if (msg.method === "session/new" && msg.id) {
|
|
414
|
-
logger.debug("session/new detected, tracking request ID");
|
|
415
|
-
newSessionRequestId = msg.id;
|
|
416
|
-
} else if (msg.method === "session/load" && msg.id) {
|
|
417
|
-
logger.debug("session/load detected, pausing stream updates");
|
|
418
|
-
isLoadingSession = true;
|
|
419
|
-
loadRequestId = msg.id;
|
|
420
|
-
}
|
|
421
|
-
} catch {
|
|
422
|
-
// Not valid JSON
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
const writer = originalWritable.getWriter();
|
|
426
|
-
return writer.write(chunk).finally(() => writer.releaseLock());
|
|
427
|
-
},
|
|
428
|
-
close() {
|
|
429
|
-
const writer = originalWritable.getWriter();
|
|
430
|
-
return writer.close().finally(() => writer.releaseLock());
|
|
431
|
-
},
|
|
432
|
-
});
|
|
147
|
+
// Create bidirectional streams for client ↔ agent communication
|
|
148
|
+
const streams = createBidirectionalStreams();
|
|
433
149
|
|
|
434
|
-
|
|
150
|
+
let agentWritable = streams.agent.writable;
|
|
151
|
+
let clientWritable = streams.client.writable;
|
|
435
152
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
if (!logWriter.isRegistered(taskRunId)) {
|
|
439
|
-
logWriter.register(taskRunId, {
|
|
440
|
-
taskId: config.taskId ?? taskRunId,
|
|
441
|
-
runId: taskRunId,
|
|
153
|
+
// Tap streams for session log writing
|
|
154
|
+
if (config.taskRunId && logWriter) {
|
|
155
|
+
if (!logWriter.isRegistered(config.taskRunId)) {
|
|
156
|
+
logWriter.register(config.taskRunId, {
|
|
157
|
+
taskId: config.taskId ?? config.taskRunId,
|
|
158
|
+
runId: config.taskRunId,
|
|
159
|
+
deviceType: config.deviceType,
|
|
442
160
|
});
|
|
443
161
|
}
|
|
444
162
|
|
|
445
|
-
|
|
163
|
+
const taskRunId = config.taskRunId;
|
|
164
|
+
agentWritable = createTappedWritableStream(streams.agent.writable, {
|
|
446
165
|
onMessage: (line) => {
|
|
447
166
|
logWriter.appendRawLine(taskRunId, line);
|
|
448
167
|
},
|
|
449
168
|
logger,
|
|
450
169
|
});
|
|
451
170
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
transform(chunk, controller) {
|
|
459
|
-
logBuffer += logDecoder.decode(chunk, { stream: true });
|
|
460
|
-
const lines = logBuffer.split("\n");
|
|
461
|
-
logBuffer = lines.pop() ?? "";
|
|
462
|
-
|
|
463
|
-
for (const line of lines) {
|
|
464
|
-
if (line.trim()) {
|
|
465
|
-
logWriter.appendRawLine(taskRunId, line);
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
controller.enqueue(chunk);
|
|
470
|
-
},
|
|
471
|
-
flush() {
|
|
472
|
-
if (logBuffer.trim()) {
|
|
473
|
-
logWriter.appendRawLine(taskRunId, logBuffer);
|
|
474
|
-
}
|
|
475
|
-
},
|
|
476
|
-
}),
|
|
477
|
-
);
|
|
171
|
+
clientWritable = createTappedWritableStream(streams.client.writable, {
|
|
172
|
+
onMessage: (line) => {
|
|
173
|
+
logWriter.appendRawLine(taskRunId, line);
|
|
174
|
+
},
|
|
175
|
+
logger,
|
|
176
|
+
});
|
|
478
177
|
} else {
|
|
479
178
|
logger.info("Tapped streams NOT enabled for Codex", {
|
|
480
179
|
hasTaskRunId: !!config.taskRunId,
|
|
@@ -482,18 +181,38 @@ function createCodexConnection(config: AcpConnectionConfig): AcpConnection {
|
|
|
482
181
|
});
|
|
483
182
|
}
|
|
484
183
|
|
|
184
|
+
const agentStream = ndJsonStream(agentWritable, streams.agent.readable);
|
|
185
|
+
|
|
186
|
+
let agent: CodexAcpAgent | null = null;
|
|
187
|
+
const agentConnection = new AgentSideConnection((client) => {
|
|
188
|
+
agent = new CodexAcpAgent(client, {
|
|
189
|
+
codexProcessOptions: config.codexOptions ?? {},
|
|
190
|
+
processCallbacks: config.processCallbacks,
|
|
191
|
+
});
|
|
192
|
+
logger.info(`Created ${agent.adapterName} agent`);
|
|
193
|
+
return agent;
|
|
194
|
+
}, agentStream);
|
|
195
|
+
|
|
485
196
|
return {
|
|
486
|
-
agentConnection
|
|
197
|
+
agentConnection,
|
|
487
198
|
clientStreams: {
|
|
488
|
-
readable:
|
|
199
|
+
readable: streams.client.readable,
|
|
489
200
|
writable: clientWritable,
|
|
490
201
|
},
|
|
491
202
|
cleanup: async () => {
|
|
492
203
|
logger.info("Cleaning up Codex connection");
|
|
493
|
-
|
|
204
|
+
|
|
205
|
+
if (agent) {
|
|
206
|
+
await agent.closeSession();
|
|
207
|
+
}
|
|
494
208
|
|
|
495
209
|
try {
|
|
496
|
-
await
|
|
210
|
+
await streams.client.writable.close();
|
|
211
|
+
} catch {
|
|
212
|
+
// Stream may already be closed
|
|
213
|
+
}
|
|
214
|
+
try {
|
|
215
|
+
await streams.agent.writable.close();
|
|
497
216
|
} catch {
|
|
498
217
|
// Stream may already be closed
|
|
499
218
|
}
|
|
@@ -24,14 +24,25 @@ import {
|
|
|
24
24
|
isAnthropicModel,
|
|
25
25
|
} from "../gateway-models";
|
|
26
26
|
import { Logger } from "../utils/logger";
|
|
27
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Shared settings manager interface that both Claude's SettingsManager
|
|
29
|
+
* and Codex's CodexSettingsManager implement. BaseAcpAgent only calls
|
|
30
|
+
* dispose() on this; each adapter's Session type narrows it to the
|
|
31
|
+
* concrete implementation.
|
|
32
|
+
*/
|
|
33
|
+
export interface BaseSettingsManager {
|
|
34
|
+
dispose(): void;
|
|
35
|
+
getCwd(): string;
|
|
36
|
+
setCwd(cwd: string): Promise<void>;
|
|
37
|
+
initialize(): Promise<void>;
|
|
38
|
+
}
|
|
28
39
|
|
|
29
40
|
export interface BaseSession {
|
|
30
41
|
notificationHistory: SessionNotification[];
|
|
31
42
|
cancelled: boolean;
|
|
32
43
|
interruptReason?: string;
|
|
33
44
|
abortController: AbortController;
|
|
34
|
-
settingsManager:
|
|
45
|
+
settingsManager: BaseSettingsManager;
|
|
35
46
|
}
|
|
36
47
|
|
|
37
48
|
const DEFAULT_CONTEXT_WINDOW = 200_000;
|