@agimon-ai/po-autocompact 0.0.0-alpha.2 → 0.0.0-alpha.21

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.
@@ -2,16 +2,17 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_compactionPolicy = require("../compactionPolicy-BIJJHcBP.cjs");
6
- let _agimon_ai_po_core_serverFacet = require("@agimon-ai/po-core/serverFacet");
5
+ const require_compactionPolicy = require("../compactionPolicy-C76UDULA.cjs");
6
+ let _agimon_ai_po_core_serverPlugin = require("@agimon-ai/po-core/serverPlugin");
7
7
  let _agimon_ai_po_core_extensionFile = require("@agimon-ai/po-core/extensionFile");
8
+ let _agimon_ai_po_artifact_artifactFiles = require("@agimon-ai/po-artifact/artifactFiles");
8
9
  let _agimon_ai_po_core_contextContributions = require("@agimon-ai/po-core/contextContributions");
9
10
  let _agimon_ai_po_core_uiHub = require("@agimon-ai/po-core/uiHub");
10
11
  let _agimon_ai_po_config = require("@agimon-ai/po-config");
11
12
  let _agimon_ai_po_telemetry = require("@agimon-ai/po-telemetry");
12
13
  let minimatch = require("minimatch");
13
- const FOOTER_SOURCE = "doom-autocompact";
14
- const STATUS_KEY = "doom-autocompact";
14
+ const FOOTER_SOURCE = "po-autocompact";
15
+ const STATUS_KEY = "po-autocompact";
15
16
  //#endregion
16
17
  //#region src/services/autocompactRuntime/index.ts
17
18
  function errorMessage(error) {
@@ -41,7 +42,7 @@ function readContextContributionsSnapshot(service) {
41
42
  return {
42
43
  entries: [],
43
44
  errors: [{
44
- source: _agimon_ai_po_core_contextContributions.DOOM_CONTEXT_CONTRIBUTIONS_SERVICE,
45
+ source: _agimon_ai_po_core_contextContributions.PO_CONTEXT_CONTRIBUTIONS_SERVICE,
45
46
  id: "service-snapshot",
46
47
  label: "Context contributions",
47
48
  order: 0,
@@ -67,7 +68,7 @@ function formatRuntimeState(snapshot) {
67
68
  return `<compaction-runtime-state>
68
69
  Authoritative runtime state captured when compaction committed. Use it to resume coordination without reconstructing state from the summary.
69
70
  <active-plan>
70
- ${snapshot.planPath ? `Source: ${snapshot.planPath}\nExact plan content is restored separately by Doom Plan.` : "(no active plan document)"}
71
+ ${snapshot.planPath ? `Source: ${snapshot.planPath}\nExact plan content is restored separately by Po Plan.` : "(no active plan document)"}
71
72
  </active-plan>
72
73
  <context-contributions>
73
74
  ${formatContextContributions({
@@ -97,7 +98,7 @@ ${importantContext.length > 0 ? importantContext.join("\n") : "(none recorded ou
97
98
  }
98
99
  function checkpointInstructions(pass, steering) {
99
100
  const decision = pass === 2 ? "Start with exactly <shouldCompact>true</shouldCompact> or <shouldCompact>false</shouldCompact>. Use true when the staged summary safely retains the important parent context. Use false only when it is not yet sufficient for safe compaction.\n\n" : "";
100
- return `Create Doom autocompact checkpoint pass ${pass}.
101
+ return `Create Po autocompact checkpoint pass ${pass}.
101
102
 
102
103
  ${steeringEnvelope(steering)}
103
104
 
@@ -121,7 +122,7 @@ const DEFAULT_RUNTIME_CONFIG = {
121
122
  overrides: []
122
123
  };
123
124
  /**
124
- * What the Doom config says about this package.
125
+ * What the Po config says about this package.
125
126
  *
126
127
  * `modes.autocompact` is read first and `modes.planning.subagents` is the
127
128
  * fallback, because summarization borrowed the planning subagent model before
@@ -130,9 +131,9 @@ const DEFAULT_RUNTIME_CONFIG = {
130
131
  function autocompactRuntimeConfig(root, onLoadFailure) {
131
132
  let modes;
132
133
  try {
133
- modes = (0, _agimon_ai_po_config.loadDoomConfig)(root).modes;
134
+ modes = (0, _agimon_ai_po_config.loadPoConfig)(root).modes;
134
135
  } catch (error) {
135
- process.emitWarning("Doom autocompact configuration could not be loaded; using the active session model instead.");
136
+ process.emitWarning("Po autocompact configuration could not be loaded; using the active session model instead.");
136
137
  onLoadFailure?.(error);
137
138
  return DEFAULT_RUNTIME_CONFIG;
138
139
  }
@@ -155,23 +156,24 @@ function autocompactRuntimeConfig(root, onLoadFailure) {
155
156
  }
156
157
  //#endregion
157
158
  //#region src/services/autocompactTelemetry/index.ts
158
- const SERVICE_NAME = "doom-autocompact";
159
+ const SERVICE_NAME = "po-autocompact";
159
160
  const PACKAGE_NAME = "@agimon-ai/po-autocompact";
160
161
  const AUTOCOMPACT_EVENT = {
161
- checkpointStarted: "doom_autocompact.checkpoint_started",
162
- checkpointCompleted: "doom_autocompact.checkpoint_completed",
163
- checkpointFailed: "doom_autocompact.checkpoint_failed",
164
- checkpointInvalid: "doom_autocompact.checkpoint_invalid",
165
- configurationLoadFailed: "doom_autocompact.configuration_load_failed",
166
- contextContributionDegraded: "doom_autocompact.context_contribution_degraded",
167
- contextCommitted: "doom_autocompact.context_committed",
168
- contextApplied: "doom_autocompact.context_applied",
169
- contextMarkerInvalid: "doom_autocompact.context_marker_invalid",
170
- contextHookSlow: "doom_autocompact.context_hook_slow",
171
- nativeCompactionCompleted: "doom_autocompact.native_compaction_completed"
162
+ checkpointStarted: "po_autocompact.checkpoint_started",
163
+ checkpointCompleted: "po_autocompact.checkpoint_completed",
164
+ checkpointFailed: "po_autocompact.checkpoint_failed",
165
+ checkpointInvalid: "po_autocompact.checkpoint_invalid",
166
+ configurationLoadFailed: "po_autocompact.configuration_load_failed",
167
+ contextContributionDegraded: "po_autocompact.context_contribution_degraded",
168
+ contextCommitted: "po_autocompact.context_committed",
169
+ contextApplied: "po_autocompact.context_applied",
170
+ contextMarkerInvalid: "po_autocompact.context_marker_invalid",
171
+ contextHookSlow: "po_autocompact.context_hook_slow",
172
+ nativeCompactionCompleted: "po_autocompact.native_compaction_completed",
173
+ historyWriteFailed: "po_autocompact.history_write_failed"
172
174
  };
173
175
  function createAutocompactTelemetry(options = {}) {
174
- const telemetry = (0, _agimon_ai_po_telemetry.createDoomTelemetry)({
176
+ const telemetry = (0, _agimon_ai_po_telemetry.createPoTelemetry)({
175
177
  serviceName: SERVICE_NAME,
176
178
  packageName: PACKAGE_NAME,
177
179
  cwd: options.cwd,
@@ -192,6 +194,119 @@ function createAutocompactTelemetry(options = {}) {
192
194
  };
193
195
  }
194
196
  //#endregion
197
+ //#region src/services/compactionHistory/index.ts
198
+ const FORMAT = "po-compaction/1";
199
+ const HEADER = `---\nformat: ${JSON.stringify(FORMAT)}\n`;
200
+ const HISTORY_PATH = new RegExp(`^${_agimon_ai_po_artifact_artifactFiles.COMPACTION_ARTIFACT_DIRECTORY}/(?:epoch-\\d+/(?:summary|checkpoint-\\d+)|in-epoch/checkpoint-\\d+)\\.md$`);
201
+ const NATIVE_PREFIX = "The conversation history before this point was compacted into the following summary:\n\n<summary>\n";
202
+ const NATIVE_SUFFIX = "\n</summary>";
203
+ function historyFile(path, fields, body) {
204
+ const header = Object.entries({
205
+ format: FORMAT,
206
+ ...fields
207
+ }).flatMap(([key, value]) => value === void 0 ? [] : [`${key}: ${JSON.stringify(value)}`]);
208
+ return {
209
+ path: `${_agimon_ai_po_artifact_artifactFiles.COMPACTION_ARTIFACT_DIRECTORY}/${path}`,
210
+ text: `---\n${header.join("\n")}\n---\n\n${body}\n`
211
+ };
212
+ }
213
+ function isoTime(value) {
214
+ const time = new Date(value);
215
+ return Number.isFinite(time.getTime()) ? time.toISOString() : void 0;
216
+ }
217
+ function passOf(value) {
218
+ if (typeof value !== "object" || value === null || !("pass" in value)) return void 0;
219
+ return value.pass === 1 || value.pass === 2 || value.pass === 3 ? value.pass : void 0;
220
+ }
221
+ function committedFields(entry) {
222
+ if (entry.type === "compaction") {
223
+ const summary = entry.summary.trim();
224
+ return {
225
+ body: summary.startsWith(NATIVE_PREFIX) && summary.endsWith(NATIVE_SUFFIX) ? summary.slice(96, -11).trim() : summary,
226
+ fields: {
227
+ source: "compact",
228
+ tokensBefore: entry.tokensBefore > 0 ? entry.tokensBefore : void 0
229
+ }
230
+ };
231
+ }
232
+ const marker = require_compactionPolicy.customMessage(entry);
233
+ const details = marker?.customType === "po-autocompact-context" ? require_compactionPolicy.contextDetailsFromUnknown(marker.details) : void 0;
234
+ if (!details) return void 0;
235
+ return {
236
+ body: require_compactionPolicy.checkpointSummaryFromEntry(entry) ?? "",
237
+ fields: {
238
+ source: "autocompact",
239
+ pass: details.poAutocompact.pass,
240
+ tokensBefore: details.poAutocompact.tokensBefore
241
+ }
242
+ };
243
+ }
244
+ /** Number commits along the active branch so a rewind rewrites the same epoch folders. */
245
+ function wantedHistory(entries) {
246
+ const files = [];
247
+ let staged = [];
248
+ let epoch = 1;
249
+ const checkpoints = (folder) => staged.map(({ entry, summary, pass }, index) => historyFile(`${folder}/checkpoint-${index + 1}.md`, {
250
+ kind: "checkpoint",
251
+ epoch,
252
+ checkpoint: index + 1,
253
+ entryId: entry.id,
254
+ source: "autocompact",
255
+ pass,
256
+ timestamp: isoTime(entry.timestamp)
257
+ }, summary));
258
+ for (const entry of entries) {
259
+ const marker = require_compactionPolicy.customMessage(entry);
260
+ if (entry.type === "custom" && entry.customType === "po-autocompact-checkpoint" || marker?.customType === "po-autocompact-checkpoint") {
261
+ const summary = require_compactionPolicy.checkpointSummaryFromEntry(entry);
262
+ if (summary) staged.push({
263
+ entry,
264
+ summary,
265
+ pass: passOf(entry.type === "custom" ? entry.data : marker?.details)
266
+ });
267
+ continue;
268
+ }
269
+ const committed = committedFields(entry);
270
+ if (!committed) continue;
271
+ files.push(...checkpoints(`epoch-${epoch}`), historyFile(`epoch-${epoch}/summary.md`, {
272
+ kind: "summary",
273
+ epoch,
274
+ entryId: entry.id,
275
+ ...committed.fields,
276
+ timestamp: isoTime(entry.timestamp)
277
+ }, committed.body));
278
+ staged = [];
279
+ epoch += 1;
280
+ }
281
+ files.push(...checkpoints("in-epoch"));
282
+ return files;
283
+ }
284
+ async function ownedHistory(root, path) {
285
+ const file = await (0, _agimon_ai_po_artifact_artifactFiles.openArtifact)(root, path).catch((error) => {
286
+ if (error instanceof _agimon_ai_po_artifact_artifactFiles.ArtifactAccessError && error.status === 404) return void 0;
287
+ throw error;
288
+ });
289
+ if (!file) return false;
290
+ try {
291
+ const bytes = await (0, _agimon_ai_po_artifact_artifactFiles.readArtifactBytes)(file.handle, Math.min(file.stat.size, HEADER.length));
292
+ return new TextDecoder().decode(bytes) === HEADER;
293
+ } finally {
294
+ await file.handle.close();
295
+ }
296
+ }
297
+ /** Mirror history into the session artifact folder. Pruning touches only files carrying this mirror's header. */
298
+ async function mirrorCompactionHistory(root, entries) {
299
+ const files = wantedHistory(entries);
300
+ if (files.length === 0) return;
301
+ for (const file of files) await (0, _agimon_ai_po_artifact_artifactFiles.writeArtifactText)(root, file.path, file.text);
302
+ const listed = await (0, _agimon_ai_po_artifact_artifactFiles.listArtifacts)(root);
303
+ if (listed.error) throw new Error(listed.error);
304
+ const wanted = new Set(files.map((file) => file.path));
305
+ const stale = listed.items.filter((item) => HISTORY_PATH.test(item.path) && !wanted.has(item.path));
306
+ for (const item of stale) if (await ownedHistory(root, item.path)) await (0, _agimon_ai_po_artifact_artifactFiles.removeArtifact)(root, item.path);
307
+ for (const folder of new Set(stale.map((item) => item.path.slice(0, item.path.lastIndexOf("/"))))) await (0, _agimon_ai_po_artifact_artifactFiles.removeArtifact)(root, folder);
308
+ }
309
+ //#endregion
195
310
  //#region src/services/modelOverrides/index.ts
196
311
  /**
197
312
  * A pattern naming a provider is matched against `provider/id`, anything else
@@ -237,7 +352,7 @@ function tailAfter(snapshot, current) {
237
352
  return current.slice(snapshot.length);
238
353
  }
239
354
  function leaf(entries) {
240
- return entries.findLast((entry) => entry.type !== "custom" || entry.customType !== "doom-autocompact-state" && entry.customType !== "doom-autocompact-checkpoint")?.id ?? "root";
355
+ return entries.findLast((entry) => entry.type !== "custom" || entry.customType !== "po-autocompact-state" && entry.customType !== "po-autocompact-checkpoint")?.id ?? "root";
241
356
  }
242
357
  function createNativeAutocompact(dependencies = {}) {
243
358
  const telemetry = dependencies.telemetry ?? createAutocompactTelemetry();
@@ -256,8 +371,11 @@ function createNativeAutocompact(dependencies = {}) {
256
371
  let configFailureReported = false;
257
372
  let footer;
258
373
  let navigating = false;
374
+ let degraded = false;
259
375
  let lastNativeCompactionId;
260
376
  let checkpointBoundary;
377
+ let mirrorQueued = false;
378
+ let historyWarnedSession;
261
379
  const attributes = () => ({
262
380
  "pi.session.id": context?.sessionId ?? "",
263
381
  "autocompact.cycle": state.cycle,
@@ -293,8 +411,6 @@ function createNativeAutocompact(dependencies = {}) {
293
411
  if (!alive(version)) return;
294
412
  await execution.session.appendCustomEntry(require_compactionPolicy.STATE_CUSTOM_TYPE, {
295
413
  ...state,
296
- nativeSnapshot: snapshot,
297
- nativePreviousSnapshot: previousSnapshot,
298
414
  nativeLastCompactionId: lastNativeCompactionId
299
415
  });
300
416
  if (alive(version)) refreshStatus(execution);
@@ -309,6 +425,7 @@ function createNativeAutocompact(dependencies = {}) {
309
425
  };
310
426
  const fail = async (execution, version, error, malformed = false) => {
311
427
  if (!alive(version)) return;
428
+ degraded = true;
312
429
  const eventAttributes = attributes();
313
430
  const attempts = state.invalidAttempts + 1;
314
431
  const pass = state.pass;
@@ -322,28 +439,51 @@ function createNativeAutocompact(dependencies = {}) {
322
439
  state.phase = "waiting";
323
440
  clear();
324
441
  state.lastAttemptLeafId = failedLeaf;
325
- await persist(execution, version);
442
+ const errors = [error];
443
+ try {
444
+ await persist(execution, version);
445
+ } catch (persistError) {
446
+ errors.push(persistError);
447
+ }
326
448
  if (!alive(version)) return;
327
- await execution.client.notify({
328
- body: `Doom autocompact summarization pass ${pass} failed: ${error instanceof Error ? error.message : String(error)}`,
449
+ await Promise.allSettled([Promise.resolve().then(() => execution.client.notify({
450
+ body: `Po autocompact summarization pass ${pass} failed: ${error instanceof Error ? error.message : String(error)}`,
329
451
  level: "error"
330
- });
331
- await telemetry.recordError(malformed ? AUTOCOMPACT_EVENT.checkpointInvalid : AUTOCOMPACT_EVENT.checkpointFailed, error, {
452
+ })), ...errors.map((failure) => Promise.resolve().then(() => telemetry.recordError(malformed ? AUTOCOMPACT_EVENT.checkpointInvalid : AUTOCOMPACT_EVENT.checkpointFailed, failure, {
332
453
  ...eventAttributes,
333
454
  "autocompact.checkpoint.attempts": attempts,
334
455
  "autocompact.checkpoint.exhausted": attempts >= 3
335
- });
456
+ })))]);
336
457
  };
337
458
  const branch = async (execution) => await execution.session.entries();
338
459
  const canonical = async (execution, entries) => {
339
460
  if (!execution.session.contextMessages) throw new Error("Canonical context is unavailable for autocompact.");
340
461
  return require_compactionPolicy.projectContextMessages(await execution.session.contextMessages(), entries).messages;
341
462
  };
463
+ const scheduleMirror = (execution) => {
464
+ if (mirrorQueued) return;
465
+ mirrorQueued = true;
466
+ enqueue(async () => {
467
+ mirrorQueued = false;
468
+ try {
469
+ await mirrorCompactionHistory((0, _agimon_ai_po_artifact_artifactFiles.artifactRoot)(execution.sessionId, execution.environment), await branch(execution));
470
+ } catch (error) {
471
+ const warn = historyWarnedSession !== execution.sessionId;
472
+ historyWarnedSession = execution.sessionId;
473
+ await Promise.allSettled([Promise.resolve().then(() => telemetry.recordWarning(AUTOCOMPACT_EVENT.historyWriteFailed, error, attributes())), ...warn ? [Promise.resolve().then(() => execution.client.notify({
474
+ body: `Po autocompact could not save compaction history: ${error instanceof Error ? error.message : String(error)}`,
475
+ level: "warning"
476
+ }))] : []]);
477
+ }
478
+ }).finally(() => {
479
+ mirrorQueued = false;
480
+ });
481
+ };
342
482
  const contributionSnapshot = async (execution) => {
343
483
  const result = readContextContributionsSnapshot(contributions);
344
484
  for (const error of result.errors) {
345
485
  await execution.client.notify({
346
- body: `Doom autocompact context contribution degraded (${error.source}/${error.id}): ${error.message}`,
486
+ body: `Po autocompact context contribution degraded (${error.source}/${error.id}): ${error.message}`,
347
487
  level: "warning"
348
488
  });
349
489
  await telemetry.recordWarning(AUTOCOMPACT_EVENT.contextContributionDegraded, new Error(error.message), {
@@ -373,6 +513,54 @@ function createNativeAutocompact(dependencies = {}) {
373
513
  "autocompact.runtime.contribution_error_count": saved.contributionErrors.length
374
514
  };
375
515
  };
516
+ const summaryModel = async (execution, configuration) => {
517
+ const ownReference = configuration.agent?.model ? parseModelReference(configuration.agent.model) : void 0;
518
+ const candidate = ownReference ? `${ownReference.provider}/${ownReference.modelId}` : void 0;
519
+ const reference = candidate && execution.textCompletion.available(candidate) ? candidate : execution.model ? `${execution.model.provider}/${execution.model.id}` : "";
520
+ return {
521
+ reference,
522
+ thinking: configuration.agent?.thinking ?? (reference === candidate ? ownReference?.thinking : void 0) ?? (await execution.session.readModelSettings?.())?.thinkingLevel
523
+ };
524
+ };
525
+ const manualCompaction = async (event, execution) => {
526
+ const configuration = configured(execution);
527
+ if (!configuration.enabled || !execution.textCompletion?.summarize) return;
528
+ try {
529
+ const entries = await branch(execution);
530
+ const messages = await canonical(execution, entries);
531
+ const delta = state.pass > 1 && previousSnapshot ? tailAfter(previousSnapshot, messages) : void 0;
532
+ const previous = state.pass > 1 ? require_compactionPolicy.checkpointSummaryFromEntry(require_compactionPolicy.latestCheckpointArtifactEntry(entries)) : void 0;
533
+ const { reference, thinking } = await summaryModel(execution, configuration);
534
+ const instructions = checkpointInstructions(3, {
535
+ plan: latestPlanSnapshot(entries),
536
+ contextContributions: await contributionSnapshot(execution),
537
+ readFiles: state.readFiles,
538
+ modifiedFiles: state.modifiedFiles
539
+ });
540
+ const { summary } = require_compactionPolicy.parseCheckpointDecision(await execution.textCompletion.summarize(reference, {
541
+ messages: delta ?? messages,
542
+ instructions: typeof event.instructions === "string" && event.instructions.trim() ? `${instructions}\n\n${event.instructions}` : instructions,
543
+ ...previous ? { previousSummary: previous } : {},
544
+ ...thinking ? { thinkingLevel: thinking } : {},
545
+ ...execution.signal ? { signal: execution.signal } : {}
546
+ }));
547
+ if (!require_compactionPolicy.isStructuredCheckpoint(summary)) throw new Error("Summarization returned an incomplete checkpoint.");
548
+ const files = require_compactionPolicy.mergeFileDetails(state, require_compactionPolicy.fileOperationsFromMessages(messages));
549
+ const usage = await execution.session.contextUsage?.();
550
+ return { compaction: {
551
+ summary: require_compactionPolicy.withCanonicalFileSections(summary, files),
552
+ tokensBefore: usage?.tokens ?? 0,
553
+ retainedTail: [],
554
+ details: files
555
+ } };
556
+ } catch (error) {
557
+ await execution.client.notify({
558
+ body: `Po autocompact manual compaction failed: ${error instanceof Error ? error.message : String(error)}`,
559
+ level: "error"
560
+ });
561
+ throw error;
562
+ }
563
+ };
376
564
  const resetCycle = () => {
377
565
  state.phase = "waiting";
378
566
  state.checkpointQueue = [];
@@ -416,13 +604,14 @@ function createNativeAutocompact(dependencies = {}) {
416
604
  state.invalidAttempts = 0;
417
605
  clear();
418
606
  await persist(execution, version);
607
+ scheduleMirror(execution);
419
608
  return false;
420
609
  }
421
610
  if (!execution.session.appendMessage) throw new Error("Checkpoint messages are unavailable.");
422
611
  const files = require_compactionPolicy.mergeFileDetails(state, require_compactionPolicy.fileOperationsFromMessages(messages));
423
612
  const details = {
424
613
  ...files,
425
- doomAutocompact: {
614
+ poAutocompact: {
426
615
  version: 2,
427
616
  cycle: state.cycle,
428
617
  pass,
@@ -450,6 +639,7 @@ function createNativeAutocompact(dependencies = {}) {
450
639
  state.modifiedFiles = files.modifiedFiles;
451
640
  resetCycle();
452
641
  await persist(execution, version);
642
+ scheduleMirror(execution);
453
643
  if (!alive(version)) return false;
454
644
  await telemetry.recordEvent(AUTOCOMPACT_EVENT.contextCommitted, {
455
645
  ...committedAttributes,
@@ -458,10 +648,19 @@ function createNativeAutocompact(dependencies = {}) {
458
648
  "autocompact.apply_mode": idle ? "idle" : "turn_end",
459
649
  ...runtimeAttributes
460
650
  });
461
- if (idle && alive(version)) await execution.session.admitPrompt?.("Asynchronous compaction completed. Continue from the compacted checkpoint's immediate next action without repeating completed work.", "steer", void 0, `${require_compactionPolicy.RESUME_MESSAGE_TYPE}:${details.doomAutocompact.requestId}`);
651
+ if (idle && alive(version)) await execution.session.admitPrompt?.("Asynchronous compaction completed. Continue from the compacted checkpoint's immediate next action without repeating completed work.", "steer", void 0, `${require_compactionPolicy.RESUME_MESSAGE_TYPE}:${details.poAutocompact.requestId}`);
462
652
  return true;
463
653
  };
464
- const progress = async (execution, allowBusy = false, appendMessage = checkpointBoundary?.appendMessage.bind(checkpointBoundary)) => {
654
+ const ensureCheckpointBoundary = (execution) => {
655
+ if (checkpointBoundary) return;
656
+ if (!execution.session.registerCheckpointBoundary) throw new Error("Native checkpoint boundaries are unavailable.");
657
+ checkpointBoundary = execution.session.registerCheckpointBoundary(async (boundary) => {
658
+ if (!active || navigating || boundary.signal?.aborted) return;
659
+ const current = context ?? execution;
660
+ await enqueue(() => boundary.signal?.aborted ? Promise.resolve() : progress(current, true, boundary.appendMessage.bind(boundary)));
661
+ });
662
+ };
663
+ const advance = async (execution, allowBusy = false, appendMessage = checkpointBoundary?.appendMessage.bind(checkpointBoundary)) => {
465
664
  const version = generation;
466
665
  context = execution;
467
666
  const activity = await execution.session.activity();
@@ -514,20 +713,18 @@ function createNativeAutocompact(dependencies = {}) {
514
713
  delete state.pendingCheckpoint;
515
714
  await persist(execution, version);
516
715
  if (!alive(version)) return;
716
+ degraded = false;
517
717
  controller?.abort();
518
718
  controller = new AbortController();
519
719
  const signal = controller.signal;
520
- const ownReference = configuration.agent?.model ? parseModelReference(configuration.agent.model) : void 0;
521
- const candidate = ownReference ? `${ownReference.provider}/${ownReference.modelId}` : void 0;
522
- const reference = candidate && execution.textCompletion.available(candidate) ? candidate : execution.model ? `${execution.model.provider}/${execution.model.id}` : "";
523
- const thinking = configuration.agent?.thinking ?? (reference === candidate ? ownReference?.thinking : void 0) ?? (await execution.session.readModelSettings?.())?.thinkingLevel;
524
- if (!alive(version)) return;
525
720
  const requestAttributes = {
526
721
  ...attributes(),
527
722
  "autocompact.message_count.before": messages.length
528
723
  };
529
724
  const delta = previousSnapshot ? tailAfter(previousSnapshot, messages) : void 0;
530
- const completion = telemetry.runInSpan("doom_autocompact.checkpoint", requestAttributes, async () => {
725
+ const completion = telemetry.runInSpan("po_autocompact.checkpoint", requestAttributes, async () => {
726
+ const { reference, thinking } = await summaryModel(execution, configuration);
727
+ if (!alive(version) || signal.aborted) return "";
531
728
  await telemetry.recordEvent(AUTOCOMPACT_EVENT.checkpointStarted, requestAttributes);
532
729
  return execution.textCompletion.summarize(reference, {
533
730
  messages: pass > 1 && delta ? delta : messages,
@@ -566,16 +763,21 @@ function createNativeAutocompact(dependencies = {}) {
566
763
  work.add(completion);
567
764
  completion.then(() => work.delete(completion), () => work.delete(completion));
568
765
  };
569
- const restore = async (execution) => {
570
- if (!active) return;
571
- if (!checkpointBoundary) {
572
- if (!execution.session.registerCheckpointBoundary) throw new Error("Native checkpoint boundaries are unavailable.");
573
- checkpointBoundary = execution.session.registerCheckpointBoundary(async (boundary) => {
574
- if (!active || navigating || boundary.signal?.aborted) return;
575
- const current = context ?? execution;
576
- await enqueue(() => boundary.signal?.aborted ? Promise.resolve() : progress(current, true, boundary.appendMessage.bind(boundary)));
577
- });
766
+ const progress = async (execution, allowBusy = false, appendMessage) => {
767
+ const version = generation;
768
+ try {
769
+ ensureCheckpointBoundary(execution);
770
+ await advance(execution, allowBusy, appendMessage);
771
+ } catch (error) {
772
+ try {
773
+ await fail(execution, version, error);
774
+ } finally {
775
+ if (alive(version)) delete state.lastAttemptLeafId;
776
+ }
578
777
  }
778
+ };
779
+ const load = async (execution) => {
780
+ if (!active) return;
579
781
  navigating = false;
580
782
  generation += 1;
581
783
  const version = generation;
@@ -586,7 +788,7 @@ function createNativeAutocompact(dependencies = {}) {
586
788
  invalid.clear();
587
789
  const entries = await branch(execution);
588
790
  if (!alive(version)) return;
589
- const entry = entries.findLast((item) => item.type === "custom" && item.customType === "doom-autocompact-state");
791
+ const entry = entries.findLast((item) => item.type === "custom" && item.customType === "po-autocompact-state");
590
792
  const data = entry?.type === "custom" && entry.data && typeof entry.data === "object" ? entry.data : void 0;
591
793
  state = require_compactionPolicy.parseState(data) ?? require_compactionPolicy.createInitialState();
592
794
  lastNativeCompactionId = typeof data?.nativeLastCompactionId === "string" ? data.nativeLastCompactionId : void 0;
@@ -597,9 +799,9 @@ function createNativeAutocompact(dependencies = {}) {
597
799
  const artifacts = entries.slice(entry ? entries.indexOf(entry) + 1 : 0);
598
800
  const committed = artifacts.findLast((item) => {
599
801
  const message = item.type === "message" ? item.message : void 0;
600
- if (message?.role !== "custom" || message.customType !== "doom-autocompact-context") return false;
802
+ if (message?.role !== "custom" || message.customType !== "po-autocompact-context") return false;
601
803
  const details = require_compactionPolicy.contextDetailsFromUnknown(message.details);
602
- return details !== void 0 && details.doomAutocompact.requestId === state.requestId && details.doomAutocompact.cycle === state.cycle && details.doomAutocompact.pass === state.pass && details.doomAutocompact.snapshotLeafId === state.snapshotLeafId && require_compactionPolicy.isStructuredCheckpoint(require_compactionPolicy.checkpointSummaryFromEntry(item) ?? "");
804
+ return details !== void 0 && details.poAutocompact.requestId === state.requestId && details.poAutocompact.cycle === state.cycle && details.poAutocompact.pass === state.pass && details.poAutocompact.snapshotLeafId === state.snapshotLeafId && require_compactionPolicy.isStructuredCheckpoint(require_compactionPolicy.checkpointSummaryFromEntry(item) ?? "");
603
805
  });
604
806
  if (committed?.type === "message" && committed.message.role === "custom") {
605
807
  const details = require_compactionPolicy.contextDetailsFromUnknown(committed.message.details);
@@ -608,7 +810,7 @@ function createNativeAutocompact(dependencies = {}) {
608
810
  resetCycle();
609
811
  await persist(execution, version);
610
812
  } else if (artifacts.findLast((item) => {
611
- if (item.type !== "custom" || item.customType !== "doom-autocompact-checkpoint") return false;
813
+ if (item.type !== "custom" || item.customType !== "po-autocompact-checkpoint") return false;
612
814
  const details = item.data;
613
815
  return details?.version === 2 && details.requestId === state.requestId && details.cycle === state.cycle && details.pass === state.pass && require_compactionPolicy.isStructuredCheckpoint(require_compactionPolicy.checkpointSummaryFromEntry(item) ?? "");
614
816
  }) && (state.pass === 1 || state.pass === 2)) {
@@ -622,12 +824,24 @@ function createNativeAutocompact(dependencies = {}) {
622
824
  await persist(execution, version);
623
825
  }
624
826
  }
625
- if (state.phase !== "waiting" && state.phase !== "checkpoint_ready") {
827
+ if (state.phase !== "waiting" && (state.phase !== "checkpoint_ready" || !snapshot)) {
626
828
  state.phase = "waiting";
627
829
  clear();
830
+ delete state.lastAttemptLeafId;
628
831
  await persist(execution, version);
629
832
  }
630
- if (alive(version)) await enqueue(() => progress(execution));
833
+ if (!alive(version)) return;
834
+ const progressed = enqueue(() => progress(execution));
835
+ scheduleMirror(execution);
836
+ await progressed;
837
+ };
838
+ const restore = async (execution) => {
839
+ const version = generation + 1;
840
+ try {
841
+ await load(execution);
842
+ } catch (error) {
843
+ await fail(execution, version, error);
844
+ }
631
845
  };
632
846
  return {
633
847
  hooks: [
@@ -658,7 +872,11 @@ function createNativeAutocompact(dependencies = {}) {
658
872
  },
659
873
  {
660
874
  event: "session_before_compact",
661
- handle: (event, execution) => active && !navigating && configured(execution).enabled && event.reason === "threshold" && (state.phase === "checkpoint_pending" || state.phase === "checkpoint_ready" || state.baselinePending) ? { cancel: true } : void 0
875
+ handle: (event, execution) => {
876
+ if (!active || navigating) return;
877
+ if (event.reason === "manual") return manualCompaction(event, execution);
878
+ return !degraded && configured(execution).enabled && event.reason === "threshold" && (state.phase === "checkpoint_pending" || state.phase === "checkpoint_ready") ? { cancel: true } : void 0;
879
+ }
662
880
  },
663
881
  {
664
882
  event: "context",
@@ -674,7 +892,7 @@ function createNativeAutocompact(dependencies = {}) {
674
892
  const id = leaf(entries);
675
893
  if (!invalid.has(id)) {
676
894
  invalid.add(id);
677
- await telemetry.recordError(AUTOCOMPACT_EVENT.contextMarkerInvalid, /* @__PURE__ */ new Error("Doom autocompact context marker is malformed."), {
895
+ await telemetry.recordError(AUTOCOMPACT_EVENT.contextMarkerInvalid, /* @__PURE__ */ new Error("Po autocompact context marker is malformed."), {
678
896
  ...attributes(),
679
897
  "autocompact.leaf_id": id
680
898
  });
@@ -731,6 +949,7 @@ function createNativeAutocompact(dependencies = {}) {
731
949
  const nativeAttributes = attributes();
732
950
  resetCycle();
733
951
  await persist(execution, version);
952
+ scheduleMirror(execution);
734
953
  if (alive(version)) await telemetry.recordEvent(AUTOCOMPACT_EVENT.nativeCompactionCompleted, {
735
954
  ...nativeAttributes,
736
955
  "autocompact.native.reason": typeof event.reason === "string" ? event.reason : "unknown",
@@ -743,8 +962,8 @@ function createNativeAutocompact(dependencies = {}) {
743
962
  }
744
963
  ],
745
964
  plugin(cordis) {
746
- cordis.inject([_agimon_ai_po_core_uiHub.DOOM_UI_HUB_SERVICE], (injected) => {
747
- const contribution = (0, _agimon_ai_po_core_uiHub.requireDoomUiHub)(injected).registerFooter({
965
+ cordis.inject([_agimon_ai_po_core_uiHub.PO_UI_HUB_SERVICE], (injected) => {
966
+ const contribution = (0, _agimon_ai_po_core_uiHub.requirePoUiHub)(injected).registerFooter({
748
967
  source: FOOTER_SOURCE,
749
968
  id: "autocompact",
750
969
  order: 20
@@ -756,8 +975,8 @@ function createNativeAutocompact(dependencies = {}) {
756
975
  if (footer === contribution) footer = void 0;
757
976
  };
758
977
  });
759
- cordis.inject([_agimon_ai_po_core_contextContributions.DOOM_CONTEXT_CONTRIBUTIONS_SERVICE], (injected) => {
760
- const service = (0, _agimon_ai_po_core_contextContributions.requireDoomContextContributions)(injected);
978
+ cordis.inject([_agimon_ai_po_core_contextContributions.PO_CONTEXT_CONTRIBUTIONS_SERVICE], (injected) => {
979
+ const service = (0, _agimon_ai_po_core_contextContributions.requirePoContextContributions)(injected);
761
980
  contributions = service;
762
981
  return () => {
763
982
  if (contributions === service) contributions = void 0;
@@ -819,11 +1038,12 @@ const via = (identity, value) => value === void 0 ? void 0 : {
819
1038
  ...identity,
820
1039
  ...value
821
1040
  };
822
- const facet = (0, _agimon_ai_po_core_serverFacet.defineServerPlugin)({
1041
+ const serverPlugin = (0, _agimon_ai_po_core_serverPlugin.defineServerPlugin)({
823
1042
  name: "@agimon-ai/po-autocompact",
824
- providerOverrides: (0, _agimon_ai_po_core_serverFacet.composeServerProviderOverrides)(root_server_default),
1043
+ providerOverrides: (0, _agimon_ai_po_core_serverPlugin.composeServerProviderOverrides)(root_server_default),
1044
+ injects: (0, _agimon_ai_po_core_extensionFile.composeRootInjects)({ session: [root_server_default] }),
825
1045
  session: async (context) => {
826
- const scopeSession = await root_server_default(context);
1046
+ const scopeSession = await context.scopeRoot("session", root_server_default, context);
827
1047
  const contextSession = {
828
1048
  ...context,
829
1049
  root: scopeSession.value
@@ -849,7 +1069,7 @@ const facet = (0, _agimon_ai_po_core_serverFacet.defineServerPlugin)({
849
1069
  }
850
1070
  });
851
1071
  //#endregion
852
- exports.default = facet;
853
- exports.facet = facet;
1072
+ exports.default = serverPlugin;
1073
+ exports.serverPlugin = serverPlugin;
854
1074
 
855
1075
  //# sourceMappingURL=server.cjs.map