@agentknight/sdk 0.9.37 → 0.9.38

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  SessionOperationError
3
- } from "./chunk-UJZPAP64.js";
3
+ } from "./chunk-6GVMVE5N.js";
4
4
 
5
5
  // src/adapters/copilot/runtime/session-identity.ts
6
6
  function assertMainSessionId(sessionId) {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  isContentfulAssistant
3
- } from "./chunk-QLGX7333.js";
3
+ } from "./chunk-34DUD2Y4.js";
4
4
  import {
5
5
  SessionOperationError
6
- } from "./chunk-UJZPAP64.js";
6
+ } from "./chunk-6GVMVE5N.js";
7
7
  import {
8
8
  CONVERSATION_SOURCE_ID_LIMIT,
9
9
  SESSION_DIRECTORY_LIST_OPERATION,
@@ -13,6 +13,7 @@ import {
13
13
  SessionGitProjectSchema,
14
14
  TIMELINE_IMAGE_OPERATION,
15
15
  TIMELINE_SYNC_OPERATION,
16
+ TimelineResyncReasonSchema,
16
17
  WORKBENCH_OPERATIONS,
17
18
  WorkbenchAskResultSchema,
18
19
  WorkbenchCommandResultSchema,
@@ -21,14 +22,14 @@ import {
21
22
  WorkbenchInsightsSchema,
22
23
  WorkbenchQueueMutationResultSchema,
23
24
  WorkbenchQueueSnapshotSchema
24
- } from "./chunk-N2LIXMIM.js";
25
+ } from "./chunk-GNQC2IS2.js";
25
26
 
26
27
  // src/operation-diagnostics.ts
27
28
  import { AsyncLocalStorage } from "node:async_hooks";
28
29
  import { createHash } from "node:crypto";
29
30
  import { performance } from "node:perf_hooks";
30
31
  import { getSystemErrorMap } from "node:util";
31
- import { ZodError } from "zod";
32
+ import { z, ZodError } from "zod";
32
33
 
33
34
  // src/copilot-connection-errors.ts
34
35
  function isClosedCopilotConnection(error) {
@@ -71,6 +72,29 @@ function sessionRestoreFailure(error) {
71
72
  }
72
73
 
73
74
  // src/operation-diagnostics.ts
75
+ var diagnosticCount = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
76
+ var timelineSyncDiagnosticSchema = z.object({
77
+ mode: z.enum(["snapshot", "resume", "replay"]),
78
+ epochMatches: z.boolean(),
79
+ requestedSequence: diagnosticCount,
80
+ currentSequence: diagnosticCount,
81
+ oldestAvailableSequence: diagnosticCount,
82
+ retainedEvents: diagnosticCount,
83
+ retainedBytes: diagnosticCount,
84
+ baselinePublished: z.boolean(),
85
+ headReadAttempts: diagnosticCount,
86
+ headReadRestarts: diagnosticCount,
87
+ restartCause: z.enum(["epoch-changed", "sequence-changed", "cold-step-changed", "head-reconciled"]),
88
+ status: z.enum(["snapshot", "replay", "resync"]),
89
+ resyncReason: TimelineResyncReasonSchema,
90
+ responseItems: diagnosticCount,
91
+ responseEvents: diagnosticCount,
92
+ hasMore: z.boolean(),
93
+ historyReadMode: z.enum(["reload", "reuse"]),
94
+ historyReadPages: diagnosticCount,
95
+ historyRawEvents: diagnosticCount,
96
+ historyItems: diagnosticCount
97
+ }).partial();
74
98
  var current = new AsyncLocalStorage();
75
99
  var systemCodes = new Set([...getSystemErrorMap().values()].map(([code]) => code));
76
100
  var errorTypes = /* @__PURE__ */ new Set(["Error", "TypeError", "RangeError", "SyntaxError", "AbortError", "TimeoutError", "AggregateError"]);
@@ -142,20 +166,25 @@ async function measureOperationPhase(phase, action) {
142
166
  const diagnostics = current.getStore();
143
167
  if (diagnostics?.running !== true) return action();
144
168
  const start = performance.now();
169
+ const token = diagnostics.startPhase(phase, start);
145
170
  try {
146
171
  return await action();
147
172
  } catch (error) {
148
173
  diagnostics.recordFailure(error, phase);
149
174
  throw error;
150
175
  } finally {
151
- diagnostics.durations[phase] += performance.now() - start;
152
- if (phase === "read") diagnostics.readCount += 1;
176
+ diagnostics.finishPhase(token);
177
+ if (diagnostics.running) {
178
+ diagnostics.durations[phase] += performance.now() - start;
179
+ if (phase === "read") diagnostics.readCount += 1;
180
+ }
153
181
  }
154
182
  }
155
183
  async function measureOperationStage(stage, action) {
156
184
  const diagnostics = current.getStore();
157
185
  if (diagnostics?.running !== true) return action();
158
186
  const start = performance.now();
187
+ const token = diagnostics.startStage(stage, start);
159
188
  let failed = false;
160
189
  try {
161
190
  return await action();
@@ -164,9 +193,14 @@ async function measureOperationStage(stage, action) {
164
193
  diagnostics.recordStageFailure(error, stage);
165
194
  throw error;
166
195
  } finally {
196
+ diagnostics.finishStage(token);
167
197
  diagnostics.recordStage(stage, performance.now() - start, failed);
168
198
  }
169
199
  }
200
+ function recordTimelineSyncDiagnostic(details) {
201
+ const diagnostics = current.getStore();
202
+ if (diagnostics?.running === true) diagnostics.recordTimelineSync(details);
203
+ }
170
204
  function recordOperationTimelineRead(diagnostic) {
171
205
  const diagnostics = current.getStore();
172
206
  if (diagnostics?.running === true) diagnostics.recordTimelineRead(diagnostic);
@@ -179,18 +213,51 @@ var OperationDiagnostics = class {
179
213
  #stages = /* @__PURE__ */ new Map();
180
214
  #stageFailures = /* @__PURE__ */ new Map();
181
215
  #timelineReads = [];
182
- async run(action) {
216
+ #activePhases = /* @__PURE__ */ new Map();
217
+ #activeStages = /* @__PURE__ */ new Map();
218
+ #timelineSync;
219
+ async run(action, options = {}) {
220
+ const alreadyRunning = this.#running;
183
221
  this.#running = true;
184
222
  try {
185
- return await current.run(this, () => measureOperationPhase("handle", action));
223
+ return await current.run(this, () => options.measureHandle === false ? action() : measureOperationPhase("handle", action));
186
224
  } finally {
187
- this.#running = false;
188
- this.#stageFailures.clear();
225
+ this.#running = alreadyRunning;
226
+ if (!alreadyRunning) {
227
+ this.#stageFailures.clear();
228
+ this.#activePhases.clear();
229
+ this.#activeStages.clear();
230
+ }
189
231
  }
190
232
  }
191
233
  get running() {
192
234
  return this.#running;
193
235
  }
236
+ startPhase(phase, start) {
237
+ const token = /* @__PURE__ */ Symbol();
238
+ this.#activePhases.set(token, { name: phase, start });
239
+ return token;
240
+ }
241
+ finishPhase(token) {
242
+ this.#activePhases.delete(token);
243
+ }
244
+ startStage(stage, start) {
245
+ const token = /* @__PURE__ */ Symbol();
246
+ this.#activeStages.set(token, { name: stage, start });
247
+ return token;
248
+ }
249
+ finishStage(token) {
250
+ this.#activeStages.delete(token);
251
+ }
252
+ recordTimelineSync(details) {
253
+ const parsed = timelineSyncDiagnosticSchema.safeParse(details);
254
+ if (this.#running && parsed.success) {
255
+ this.#timelineSync = {
256
+ ...this.#timelineSync,
257
+ ...Object.fromEntries(Object.entries(parsed.data).filter(([, value]) => value !== void 0))
258
+ };
259
+ }
260
+ }
194
261
  recordFailure(error, phase) {
195
262
  const stage = [...this.#stageFailures].find(([, failure]) => Object.is(error, failure))?.[0];
196
263
  this.#failure ??= { phase, ...diagnosticError(error), ...stage === void 0 ? {} : { stage } };
@@ -242,10 +309,28 @@ var OperationDiagnostics = class {
242
309
  ...sample,
243
310
  elapsedMs: Math.round(sample.elapsedMs)
244
311
  })) },
245
- ...this.#timelineReads.length === 0 ? {} : { timelineReads: [...this.#timelineReads] }
312
+ ...this.#timelineReads.length === 0 ? {} : { timelineReads: [...this.#timelineReads] },
313
+ ...this.#timelineSync === void 0 ? {} : { timelineSync: { ...this.#timelineSync } },
314
+ ...this.#activePhases.size === 0 ? {} : {
315
+ activePhases: activeSamples(this.#activePhases).map(({ name, ...sample }) => ({ phase: name, ...sample }))
316
+ },
317
+ ...this.#activeStages.size === 0 ? {} : {
318
+ activeStages: activeSamples(this.#activeStages).map(({ name, ...sample }) => ({ stage: name, ...sample }))
319
+ }
246
320
  };
247
321
  }
248
322
  };
323
+ function activeSamples(active) {
324
+ const now = performance.now();
325
+ const samples = /* @__PURE__ */ new Map();
326
+ for (const { name, start } of active.values()) {
327
+ const sample = samples.get(name) ?? { name, activeCalls: 0, elapsedMs: 0 };
328
+ sample.activeCalls++;
329
+ sample.elapsedMs = Math.max(sample.elapsedMs, Math.round(Math.max(0, now - start)));
330
+ samples.set(name, sample);
331
+ }
332
+ return [...samples.values()];
333
+ }
249
334
  var OperationMetrics = class {
250
335
  #samples = /* @__PURE__ */ new Map();
251
336
  record(request, diagnostics, failed) {
@@ -2114,7 +2199,7 @@ var PromptPreparationError = class extends Error {
2114
2199
  // src/session-project-identity.ts
2115
2200
  import { realpath as realpath2, stat } from "node:fs/promises";
2116
2201
  import { isAbsolute as isAbsolute2 } from "node:path";
2117
- var SESSION_PROJECT_IDENTITY_CONCURRENCY = 4;
2202
+ var SESSION_PROJECT_IDENTITY_CONCURRENCY = 20;
2118
2203
  var errors = {
2119
2204
  SESSION_NOT_FOUND: "The session is unavailable",
2120
2205
  SESSION_ROOT_UNAVAILABLE: "The session working directory is unavailable",
@@ -2133,7 +2218,7 @@ async function rootIdentity(workingDirectory) {
2133
2218
  const root = await realpath2(workingDirectory);
2134
2219
  const info = await stat(root);
2135
2220
  if (!info.isDirectory()) throw new SessionProjectIdentityError("SESSION_ROOT_UNAVAILABLE");
2136
- return `${root}\0${info.dev}\0${info.ino}`;
2221
+ return { path: root, key: `${root}\0${info.dev}\0${info.ino}` };
2137
2222
  }
2138
2223
  var SessionProjectIdentityReader = class {
2139
2224
  constructor(metadata, inspect = resolveGitProjectIdentity) {
@@ -2143,6 +2228,7 @@ var SessionProjectIdentityReader = class {
2143
2228
  metadata;
2144
2229
  inspect;
2145
2230
  #active = 0;
2231
+ #inspections = /* @__PURE__ */ new Map();
2146
2232
  async get(sessionId) {
2147
2233
  if (this.#active >= SESSION_PROJECT_IDENTITY_CONCURRENCY) {
2148
2234
  throw new SessionProjectIdentityError("PROJECT_IDENTITY_BUSY");
@@ -2164,7 +2250,7 @@ var SessionProjectIdentityReader = class {
2164
2250
  let project;
2165
2251
  let inspectionError;
2166
2252
  try {
2167
- const identity = await this.inspect(cwd);
2253
+ const identity = await this.#inspectRoot(initialRoot);
2168
2254
  project = SessionGitProjectSchema.parse({
2169
2255
  localRepositoryKey: identity.localRepositoryKey,
2170
2256
  worktreeRoot: identity.worktreeRoot,
@@ -2180,7 +2266,7 @@ var SessionProjectIdentityReader = class {
2180
2266
  if (latest === void 0) throw new SessionProjectIdentityError("SESSION_NOT_FOUND");
2181
2267
  if (latest.workingDirectory !== cwd) throw new SessionProjectIdentityError("SESSION_ROOT_CHANGED");
2182
2268
  try {
2183
- if (await rootIdentity(cwd) !== initialRoot) {
2269
+ if ((await rootIdentity(cwd)).key !== initialRoot.key) {
2184
2270
  throw new SessionProjectIdentityError("SESSION_ROOT_CHANGED");
2185
2271
  }
2186
2272
  } catch (cause) {
@@ -2195,11 +2281,22 @@ var SessionProjectIdentityReader = class {
2195
2281
  this.#active--;
2196
2282
  }
2197
2283
  }
2284
+ async #inspectRoot(root) {
2285
+ const pending = this.#inspections.get(root.key);
2286
+ if (pending !== void 0) return pending;
2287
+ const inspection = Promise.resolve().then(() => this.inspect(root.path));
2288
+ this.#inspections.set(root.key, inspection);
2289
+ try {
2290
+ return await inspection;
2291
+ } finally {
2292
+ this.#inspections.delete(root.key);
2293
+ }
2294
+ }
2198
2295
  };
2199
2296
 
2200
2297
  // src/session-workbench-runtime.ts
2201
2298
  import { createHash as createHash4 } from "node:crypto";
2202
- import { z } from "zod";
2299
+ import { z as z2 } from "zod";
2203
2300
  var WorkbenchRuntimeError = class extends SessionOperationError {
2204
2301
  constructor(code, message) {
2205
2302
  super(code, message);
@@ -2209,21 +2306,21 @@ var WorkbenchRuntimeError = class extends SessionOperationError {
2209
2306
  var WorkbenchOutcomeUncertainError = class extends Error {
2210
2307
  code = "stale-runtime";
2211
2308
  };
2212
- var queueSchema = z.object({
2213
- items: z.array(z.object({
2214
- id: z.string().min(1).max(256),
2215
- kind: z.enum(["message", "command"]),
2216
- displayText: z.string().max(1e5),
2217
- agentMode: z.enum(["interactive", "plan", "autopilot", "shell"])
2309
+ var queueSchema = z2.object({
2310
+ items: z2.array(z2.object({
2311
+ id: z2.string().min(1).max(256),
2312
+ kind: z2.enum(["message", "command"]),
2313
+ displayText: z2.string().max(1e5),
2314
+ agentMode: z2.enum(["interactive", "plan", "autopilot", "shell"])
2218
2315
  })).max(512),
2219
- steeringMessages: z.array(z.string().max(1e5)).max(512)
2316
+ steeringMessages: z2.array(z2.string().max(1e5)).max(512)
2220
2317
  });
2221
- var resultBase = { runtimeSettingsChanged: z.boolean().optional() };
2222
- var invocationSchema = z.discriminatedUnion("kind", [
2223
- z.object({ kind: z.literal("text"), text: z.string().max(64 * 1024), markdown: z.boolean().optional(), preserveAnsi: z.boolean().optional(), ...resultBase }),
2224
- z.object({ kind: z.literal("completed"), message: z.string().max(64 * 1024).optional(), ...resultBase }),
2225
- z.object({ kind: z.literal("agent-prompt"), prompt: z.string().min(1).max(64 * 1024), displayPrompt: z.string().max(64 * 1024), mode: z.enum(["interactive", "plan", "autopilot"]).optional(), notice: z.string().max(64 * 1024).optional(), ...resultBase }),
2226
- z.object({ kind: z.literal("select-subcommand"), command: z.string().max(256), title: z.string().max(4096), options: z.array(z.object({ name: z.string().max(256), description: z.string().max(4096), group: z.string().max(256).optional() })).max(256), ...resultBase })
2318
+ var resultBase = { runtimeSettingsChanged: z2.boolean().optional() };
2319
+ var invocationSchema = z2.discriminatedUnion("kind", [
2320
+ z2.object({ kind: z2.literal("text"), text: z2.string().max(64 * 1024), markdown: z2.boolean().optional(), preserveAnsi: z2.boolean().optional(), ...resultBase }),
2321
+ z2.object({ kind: z2.literal("completed"), message: z2.string().max(64 * 1024).optional(), ...resultBase }),
2322
+ z2.object({ kind: z2.literal("agent-prompt"), prompt: z2.string().min(1).max(64 * 1024), displayPrompt: z2.string().max(64 * 1024), mode: z2.enum(["interactive", "plan", "autopilot"]).optional(), notice: z2.string().max(64 * 1024).optional(), ...resultBase }),
2323
+ z2.object({ kind: z2.literal("select-subcommand"), command: z2.string().max(256), title: z2.string().max(4096), options: z2.array(z2.object({ name: z2.string().max(256), description: z2.string().max(4096), group: z2.string().max(256).optional() })).max(256), ...resultBase })
2227
2324
  ]);
2228
2325
  function nanoAiu(value) {
2229
2326
  if (!Number.isSafeInteger(value) || value < 0) {
@@ -2322,7 +2419,7 @@ var SessionWorkbenchRuntime = class {
2322
2419
  }
2323
2420
  }
2324
2421
  async ask(sessionId, question) {
2325
- z.string().trim().min(1).max(16 * 1024).parse(question);
2422
+ z2.string().trim().min(1).max(16 * 1024).parse(question);
2326
2423
  this.dependencies.assertAvailable(sessionId);
2327
2424
  const runtime = this.dependencies.getRuntime(sessionId);
2328
2425
  if (runtime.workbench.compacting || runtime.workbench.activeQuestions > 0 || this.#activeQuestions >= 2) {
@@ -2335,7 +2432,12 @@ var SessionWorkbenchRuntime = class {
2335
2432
  if (session.rpc.ui.ephemeralQuery === void 0) {
2336
2433
  throw new WorkbenchRuntimeError("unsupported", "This runtime does not support side questions");
2337
2434
  }
2338
- const result = z.object({ answer: z.string().max(64 * 1024) }).parse(
2435
+ const { modelId } = await session.rpc.model.getCurrent();
2436
+ this.#assertGeneration(sessionId, generation);
2437
+ if (modelId === "auto") {
2438
+ throw new WorkbenchRuntimeError("unsupported", "Choose a specific model instead of Auto to use Ask.");
2439
+ }
2440
+ const result = z2.object({ answer: z2.string().max(64 * 1024) }).parse(
2339
2441
  await session.rpc.ui.ephemeralQuery({ question })
2340
2442
  );
2341
2443
  this.#assertGeneration(sessionId, generation);
@@ -2399,14 +2501,14 @@ var SessionWorkbenchRuntime = class {
2399
2501
  let outcome;
2400
2502
  switch (input.action) {
2401
2503
  case "edit":
2402
- z.string().trim().min(1).max(1e5).parse(input.text);
2504
+ z2.string().trim().min(1).max(1e5).parse(input.text);
2403
2505
  outcome = (await queue.updateText({ id: input.id, prompt: input.text, displayPrompt: input.text })).updated ? "updated" : "unchanged";
2404
2506
  break;
2405
2507
  case "remove":
2406
2508
  outcome = (await queue.removeAt({ id: input.id })).removed ? "removed" : "not-found";
2407
2509
  break;
2408
2510
  case "move":
2409
- z.number().int().nonnegative().max(511).parse(input.toPosition);
2511
+ z2.number().int().nonnegative().max(511).parse(input.toPosition);
2410
2512
  outcome = (await queue.moveItem({ id: input.id, toPosition: input.toPosition })).changed ? "moved" : "unchanged";
2411
2513
  break;
2412
2514
  case "send-now":
@@ -2589,7 +2691,7 @@ var SessionWorkbenchRuntime = class {
2589
2691
  await this.dependencies.configureSession(sessionId, { modelId: selected });
2590
2692
  } else {
2591
2693
  const mode = command.name === "plan" ? "plan" : command.name === "autopilot" ? "autopilot" : selected;
2592
- const parsedMode = z.enum(["interactive", "plan", "autopilot"]).safeParse(mode);
2694
+ const parsedMode = z2.enum(["interactive", "plan", "autopilot"]).safeParse(mode);
2593
2695
  if (!parsedMode.success) throw new WorkbenchRuntimeError("unsupported", "Choose a model or mode using session configuration");
2594
2696
  await this.dependencies.configureSession(sessionId, { agentMode: parsedMode.data });
2595
2697
  }
@@ -2646,6 +2748,7 @@ export {
2646
2748
  validateOperationResponse,
2647
2749
  measureOperationPhase,
2648
2750
  measureOperationStage,
2751
+ recordTimelineSyncDiagnostic,
2649
2752
  recordOperationTimelineRead,
2650
2753
  OperationDiagnostics,
2651
2754
  OperationMetrics,
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  AgentSessionRenameError,
3
3
  validateSessionName
4
- } from "./chunk-UJZPAP64.js";
4
+ } from "./chunk-6GVMVE5N.js";
5
5
  import {
6
6
  ConversationItemSchema,
7
7
  GroupChatInfoSchema,
8
8
  GroupChatParticipantSchema,
9
9
  SESSION_TIMELINE_PAGE_SIZE,
10
10
  SessionSummarySchema
11
- } from "./chunk-N2LIXMIM.js";
11
+ } from "./chunk-GNQC2IS2.js";
12
12
 
13
13
  // src/group-chat.ts
14
14
  import { createHash, randomUUID } from "node:crypto";
@@ -15,26 +15,27 @@ import {
15
15
  measureOperationStage,
16
16
  recordOperationFailure,
17
17
  recordOperationTimelineRead,
18
+ recordTimelineSyncDiagnostic,
18
19
  resolveGitProjectIdentity,
19
20
  sanitizeGitRemoteUrl
20
- } from "./chunk-7JRY2FRZ.js";
21
+ } from "./chunk-UIM3KQRC.js";
21
22
  import {
22
23
  assertMainSessionId,
23
24
  isResearchSessionId
24
- } from "./chunk-DSHLLGE2.js";
25
+ } from "./chunk-SREMK7S4.js";
25
26
  import {
26
27
  GroupChatError,
27
28
  GroupChatMessageSchema,
28
29
  GroupChatRuntime
29
- } from "./chunk-VXZ25DKC.js";
30
+ } from "./chunk-YSJRQ35E.js";
30
31
  import {
31
32
  isContentfulAssistant
32
- } from "./chunk-QLGX7333.js";
33
+ } from "./chunk-34DUD2Y4.js";
33
34
  import {
34
35
  AgentSessionRenameError,
35
36
  SessionOperationError,
36
37
  validateSessionName
37
- } from "./chunk-UJZPAP64.js";
38
+ } from "./chunk-6GVMVE5N.js";
38
39
  import {
39
40
  ConversationItemSchema,
40
41
  CopilotModelOptionSchema,
@@ -54,7 +55,7 @@ import {
54
55
  WorkbenchScheduleEntrySchema,
55
56
  WorkbenchScheduleProposalSchema,
56
57
  WorkbenchScheduleSnapshotSchema
57
- } from "./chunk-N2LIXMIM.js";
58
+ } from "./chunk-GNQC2IS2.js";
58
59
 
59
60
  // src/copilot-adapter.ts
60
61
  import { createHash as createHash4, randomUUID as randomUUID6 } from "node:crypto";
@@ -2046,9 +2047,16 @@ var TimelineHistory = class {
2046
2047
  const pageSize = options.pageSize;
2047
2048
  const runtime = this.ports.state(sessionId);
2048
2049
  const shouldReloadHead = options.cursor === void 0 && this.ports.provisional(sessionId) === void 0 && this.ports.lifecycle.canRefreshSessionConnection(sessionId);
2050
+ const reload = shouldReloadHead || this.ports.current(sessionId) === void 0 && !this.ports.hasPendingSend(sessionId);
2051
+ recordTimelineSyncDiagnostic({
2052
+ historyReadMode: reload ? "reload" : "reuse",
2053
+ historyReadPages: 0,
2054
+ historyRawEvents: 0,
2055
+ historyItems: 0
2056
+ });
2049
2057
  const session = await measureOperationStage(
2050
2058
  "session-open",
2051
- () => shouldReloadHead || this.ports.current(sessionId) === void 0 && !this.ports.hasPendingSend(sessionId) ? this.ports.lifecycle.reloadSession(sessionId) : this.ports.lifecycle.getSession(sessionId)
2059
+ () => reload ? this.ports.lifecycle.reloadSession(sessionId) : this.ports.lifecycle.getSession(sessionId)
2052
2060
  );
2053
2061
  beginRead();
2054
2062
  const toolLifecycles = runtime.toolLifecycles;
@@ -2057,6 +2065,8 @@ var TimelineHistory = class {
2057
2065
  let hasMore = true;
2058
2066
  let cursorStatus = "ok";
2059
2067
  let rawEventCount = 0;
2068
+ let readPages = 0;
2069
+ let readEvents = 0;
2060
2070
  let rawEvents = [];
2061
2071
  let displayItems = [];
2062
2072
  const rawEventLimit = pageSize * MAX_TIMELINE_RAW_EVENT_MULTIPLIER;
@@ -2073,8 +2083,11 @@ var TimelineHistory = class {
2073
2083
  includeEphemeral: false
2074
2084
  }));
2075
2085
  const events = response.events;
2086
+ readPages++;
2087
+ readEvents += events.length;
2088
+ recordTimelineSyncDiagnostic({ historyReadPages: readPages, historyRawEvents: readEvents });
2076
2089
  const candidateRawEvents = [...events, ...rawEvents];
2077
- const candidateDisplayItems = normalizeTimelineEvents(candidateRawEvents, toolLifecycles, resolveInputProvenance);
2090
+ const candidateDisplayItems = await measureOperationStage("timeline-normalize", () => normalizeTimelineEvents(candidateRawEvents, toolLifecycles, resolveInputProvenance));
2078
2091
  const candidatePageItems = candidateDisplayItems.slice(-pageSize);
2079
2092
  if (candidateDisplayItems.length > pageSize && displayItems.length >= pageSize) {
2080
2093
  displayItems = candidateDisplayItems;
@@ -2108,13 +2121,13 @@ var TimelineHistory = class {
2108
2121
  const hydratedNormalizer = new ConversationNormalizer((failure) => {
2109
2122
  this.ports.callbacks()?.onImageProjectionFailure?.(sessionId, failure);
2110
2123
  }, toolLifecycles, resolveInputProvenance);
2111
- hydratedNormalizer.apply(rawEvents);
2124
+ await measureOperationStage("timeline-normalize", () => hydratedNormalizer.apply(rawEvents));
2112
2125
  if (hydratedNormalizer.pendingImageAssetIds().length > 0) {
2113
- await this.ports.resolveImages(
2126
+ await measureOperationStage("timeline-image-resolve", () => this.ports.resolveImages(
2114
2127
  sessionId,
2115
2128
  session,
2116
2129
  hydratedNormalizer
2117
- );
2130
+ ));
2118
2131
  displayItems = hydratedNormalizer.snapshot();
2119
2132
  if (timelineItemsSize(displayItems.slice(-pageSize)) > TIMELINE_PAGE_PAYLOAD_BUDGET_BYTES) {
2120
2133
  throw new Error(
@@ -2123,6 +2136,7 @@ var TimelineHistory = class {
2123
2136
  }
2124
2137
  }
2125
2138
  await this.#observePersistedSessionLog(sessionId);
2139
+ recordTimelineSyncDiagnostic({ historyItems: Math.min(displayItems.length, pageSize) });
2126
2140
  return SessionTimelinePageSchema.parse({
2127
2141
  items: displayItems.slice(-pageSize),
2128
2142
  cursor,
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  AgentSelectionSchema,
3
3
  assertSelectionSnapshotFits
4
- } from "./chunk-U2HBI4SH.js";
4
+ } from "./chunk-6YF3VZLR.js";
5
5
  import {
6
6
  isResearchSessionId
7
- } from "./chunk-DSHLLGE2.js";
7
+ } from "./chunk-SREMK7S4.js";
8
8
  import {
9
9
  GroupChatError
10
- } from "./chunk-VXZ25DKC.js";
10
+ } from "./chunk-YSJRQ35E.js";
11
11
  import {
12
12
  AgentModelListingError,
13
13
  AgentSessionRenameError,
@@ -15,11 +15,11 @@ import {
15
15
  UnsupportedAgentOperationError,
16
16
  captureWorkbenchAccess,
17
17
  validateSessionName
18
- } from "./chunk-UJZPAP64.js";
18
+ } from "./chunk-6GVMVE5N.js";
19
19
  import {
20
20
  InteractionResponseSchema,
21
21
  SessionSummarySchema
22
- } from "./chunk-N2LIXMIM.js";
22
+ } from "./chunk-GNQC2IS2.js";
23
23
 
24
24
  // src/managed-agent-adapter.ts
25
25
  import { createHash, randomUUID } from "node:crypto";
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  latestPreviewItems
3
- } from "./chunk-QLGX7333.js";
3
+ } from "./chunk-34DUD2Y4.js";
4
4
  import {
5
5
  AgentSessionRenameError,
6
6
  UnsupportedAgentOperationError,
7
7
  validateSessionName
8
- } from "./chunk-UJZPAP64.js";
8
+ } from "./chunk-6GVMVE5N.js";
9
9
  import {
10
10
  InteractionRequestSchema,
11
11
  REASONING_EFFORTS,
12
12
  SESSION_TIMELINE_PAGE_SIZE
13
- } from "./chunk-N2LIXMIM.js";
13
+ } from "./chunk-GNQC2IS2.js";
14
14
 
15
15
  // src/pi-adapter.ts
16
16
  import { createHash as createHash2, randomUUID } from "node:crypto";
package/dist/index.d.ts CHANGED
@@ -892,9 +892,9 @@ declare const ConversationItemSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
892
892
  assistant: "assistant";
893
893
  }>;
894
894
  operation: z.ZodEnum<{
895
+ deleted: "deleted";
895
896
  created: "created";
896
897
  updated: "updated";
897
- deleted: "deleted";
898
898
  }>;
899
899
  content: z.ZodString;
900
900
  todos: z.ZodArray<z.ZodObject<{
@@ -1140,9 +1140,9 @@ declare const SessionTimelinePageSchema: z.ZodObject<{
1140
1140
  assistant: "assistant";
1141
1141
  }>;
1142
1142
  operation: z.ZodEnum<{
1143
+ deleted: "deleted";
1143
1144
  created: "created";
1144
1145
  updated: "updated";
1145
- deleted: "deleted";
1146
1146
  }>;
1147
1147
  content: z.ZodString;
1148
1148
  todos: z.ZodArray<z.ZodObject<{
@@ -1884,6 +1884,8 @@ type OutboundArguments = {
1884
1884
  interface RelaySocket {
1885
1885
  readonly connected: boolean;
1886
1886
  readonly active: boolean;
1887
+ /** Native Socket.IO backlog; invalidated when the registered connection ends. */
1888
+ readonly sendBuffer?: unknown[];
1887
1889
  readonly io: {
1888
1890
  readonly engine?: {
1889
1891
  readonly transport?: {