@agimon-ai/po-autocompact 0.0.0-alpha.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.mjs","names":["rootSession","hookAgentSettled","hookContext","hookSessionBeforeCompact","hookSessionCompact","hookSessionStart","hookSessionTree","hookTurnEnd"],"sources":["../../src/constants/runtime.ts","../../src/services/autocompactRuntime/index.ts","../../src/services/autocompactTelemetry/index.ts","../../src/services/modelOverrides/index.ts","../../src/services/summarizationModel/index.ts","../../src/services/nativeAutocompact/index.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/context.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-before-compact.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-compact.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-start.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-tree.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/turn-end.server.ts","../../generated/server.ts"],"sourcesContent":["export const ROOT_WORKING_LEAF = '@root';\nexport const PLAN_DOCUMENT_ENTRY = 'agent-harness-plan-document';\nexport const FOOTER_SOURCE = 'doom-autocompact';\nexport const FOOTER_ORDER = 20;\nexport const STATUS_KEY = 'doom-autocompact';\nexport const STATE_PHASE = {\n waiting: 'waiting',\n checkpointPending: 'checkpoint_pending',\n checkpointReady: 'checkpoint_ready',\n compacting: 'compacting',\n} as const;\n\n/**\n * Above this, the context hook is worth a telemetry event. Below it the hook is\n * noise against a round trip measured in seconds, and it runs on every request.\n */\nexport const SLOW_CONTEXT_HOOK_MS = 25;\n","import { loadDoomConfig, type AutocompactOverrideConfig, type PlanningAgentConfig } from '@agimon-ai/po-config';\nimport {\n DOOM_CONTEXT_CONTRIBUTIONS_SERVICE,\n type DoomContextContributionEntry,\n type DoomContextContributionError,\n type DoomContextContributionsService,\n type DoomContextContributionsSnapshot,\n} from '@agimon-ai/po-core/contextContributions';\n\nimport { PLAN_DOCUMENT_ENTRY } from '../../constants/runtime';\nimport type { AutocompactPass, AutocompactRatioOverrides } from '../../types/autocompact';\nimport type { CompactionPolicyEntry } from '../compactionPolicy';\n\ninterface PlanSnapshot {\n content: string;\n path: string;\n}\n\ninterface SteeringSnapshot {\n plan?: PlanSnapshot;\n contextContributions: DoomContextContributionsSnapshot;\n readFiles: string[];\n modifiedFiles: string[];\n}\n\ninterface RuntimeStateSnapshot {\n planPath?: string;\n contributions: readonly DoomContextContributionEntry[];\n contributionErrors: readonly DoomContextContributionError[];\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport function latestPlanSnapshot(branch: readonly CompactionPolicyEntry[]): PlanSnapshot | undefined {\n for (const entry of branch.toReversed()) {\n if (entry.type !== 'custom' || entry.customType !== PLAN_DOCUMENT_ENTRY) continue;\n if (!entry.data || typeof entry.data !== 'object') return undefined;\n const data = entry.data as Record<string, unknown>;\n if (typeof data.content !== 'string' || typeof data.path !== 'string') return undefined;\n return { content: data.content, path: data.path };\n }\n return undefined;\n}\n\nconst EMPTY_CONTEXT_CONTRIBUTIONS: DoomContextContributionsSnapshot = Object.freeze({\n entries: Object.freeze([]),\n errors: Object.freeze([]),\n});\n\nexport function readContextContributionsSnapshot(\n service: DoomContextContributionsService | undefined,\n): DoomContextContributionsSnapshot {\n if (!service) return EMPTY_CONTEXT_CONTRIBUTIONS;\n try {\n return service.snapshot();\n } catch (error) {\n return {\n entries: [],\n errors: [\n {\n source: DOOM_CONTEXT_CONTRIBUTIONS_SERVICE,\n id: 'service-snapshot',\n label: 'Context contributions',\n order: 0,\n message: errorMessage(error),\n },\n ],\n };\n }\n}\n\nfunction formatContextContributions(snapshot: DoomContextContributionsSnapshot): string {\n const sections = snapshot.entries.map((entry) => `### ${entry.label}\\n${entry.text}`);\n sections.push(...snapshot.errors.map((error) => `### ${error.label}\\n(unavailable: ${error.message})`));\n return sections.length > 0 ? sections.join('\\n\\n') : '(no registered context contributions)';\n}\n\nexport function runtimeStateSnapshot(\n branch: readonly CompactionPolicyEntry[],\n contextContributions: DoomContextContributionsSnapshot,\n): RuntimeStateSnapshot {\n const plan = latestPlanSnapshot(branch);\n return {\n ...(plan ? { planPath: plan.path } : {}),\n contributions: contextContributions.entries,\n contributionErrors: contextContributions.errors,\n };\n}\n\nexport function formatRuntimeState(snapshot: RuntimeStateSnapshot): string {\n const plan = snapshot.planPath\n ? `Source: ${snapshot.planPath}\\nExact plan content is restored separately by Doom Plan.`\n : '(no active plan document)';\n return `<compaction-runtime-state>\nAuthoritative runtime state captured when compaction committed. Use it to resume coordination without reconstructing state from the summary.\n<active-plan>\n${plan}\n</active-plan>\n<context-contributions>\n${formatContextContributions({ entries: snapshot.contributions, errors: snapshot.contributionErrors })}\n</context-contributions>\n</compaction-runtime-state>`;\n}\n\nfunction steeringEnvelope(snapshot: SteeringSnapshot): string {\n const plan = snapshot.plan\n ? `Source: ${snapshot.plan.path}\\n\\n${snapshot.plan.content}`\n : '(no active plan document)';\n const importantContext = [\n snapshot.readFiles.length > 0 ? `Read files: ${snapshot.readFiles.join(', ')}` : undefined,\n snapshot.modifiedFiles.length > 0 ? `Modified files: ${snapshot.modifiedFiles.join(', ')}` : undefined,\n ].filter((value): value is string => Boolean(value));\n\n return `<compaction-steering priority=\"user,plan,context-contributions,important-context,recent-messages\">\n<user-prompt source=\"conversation\">\nTreat the user's explicit goals, constraints, corrections, and preferences in the conversation as authoritative. Newer user instructions override older ones.\n</user-prompt>\n<active-plan>\n${plan}\n</active-plan>\n<context-contributions>\n${formatContextContributions(snapshot.contextContributions)}\n</context-contributions>\n<important-context>\n${importantContext.length > 0 ? importantContext.join('\\n') : '(none recorded outside the conversation)'}\n</important-context>\n</compaction-steering>`;\n}\n\nexport function checkpointInstructions(pass: AutocompactPass, steering: SteeringSnapshot): string {\n const decision =\n pass === 2\n ? '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'\n : '';\n\n // Summarization is a tool-less single LLM call, so instructions describe only what to\n // produce. Directives aimed at an implementing agent leak into the checkpoint body.\n return `Create Doom autocompact checkpoint pass ${pass}.\n\n${steeringEnvelope(steering)}\n\nApply the steering evidence in priority order. Do not invent plan or contributed runtime state. Preserve verified facts and mark unresolved inference explicitly. Newer evidence replaces superseded information.\n\n${decision}Return only the decision tag when required, followed by a concise structured checkpoint using every heading below. Keep exact goals, constraints, decisions, blockers, commands, errors, file paths, validation evidence, and the immediate next action. Separate verified facts from unresolved inference.\n\n## Goal\n## Constraints & Preferences\n## Progress\n### Done\n### In Progress\n### Blocked\n## Key Decisions\n## Next Steps\n## Critical Context`;\n}\n\ninterface AutocompactRuntimeConfig {\n /** Off leaves compaction to the host; unset is on. */\n enabled: boolean;\n /** The agent that writes the summaries, from autocompact's own keys or planning's. */\n agent?: PlanningAgentConfig;\n ratios: AutocompactRatioOverrides;\n /** Per-model absolute token checkpoints, tried in file order. */\n overrides: AutocompactOverrideConfig[];\n}\n\nconst DEFAULT_RUNTIME_CONFIG: AutocompactRuntimeConfig = { enabled: true, ratios: {}, overrides: [] };\n\n/**\n * What the Doom config says about this package.\n *\n * `modes.autocompact` is read first and `modes.planning.subagents` is the\n * fallback, because summarization borrowed the planning subagent model before\n * it had keys of its own and existing files still spell it that way.\n */\nexport function autocompactRuntimeConfig(\n root: string,\n onLoadFailure?: (error: unknown) => void,\n): AutocompactRuntimeConfig {\n let modes: ReturnType<typeof loadDoomConfig>['modes'];\n try {\n modes = loadDoomConfig(root).modes;\n } catch (error) {\n process.emitWarning('Doom autocompact configuration could not be loaded; using the active session model instead.');\n onLoadFailure?.(error);\n return DEFAULT_RUNTIME_CONFIG;\n }\n const configured = modes?.autocompact;\n const ownAgent: PlanningAgentConfig | undefined =\n configured && (configured.model !== undefined || configured.thinking !== undefined)\n ? {\n ...(configured.model ? { model: configured.model } : {}),\n ...(configured.thinking ? { thinking: configured.thinking } : {}),\n }\n : undefined;\n const agent = ownAgent ?? modes?.planning?.subagents;\n const thresholds = configured?.thresholds;\n return {\n enabled: configured?.enabled ?? true,\n ...(agent ? { agent } : {}),\n ratios: {\n ...(thresholds?.pass1 === undefined ? {} : { 1: thresholds.pass1 }),\n ...(thresholds?.pass2 === undefined ? {} : { 2: thresholds.pass2 }),\n ...(thresholds?.pass3 === undefined ? {} : { 3: thresholds.pass3 }),\n },\n overrides: configured?.overrides ?? [],\n };\n}\n","import { createDoomTelemetry, type DoomTelemetry, type DoomTelemetryOptions } from '@agimon-ai/po-telemetry';\n\nconst SERVICE_NAME = 'doom-autocompact';\nconst PACKAGE_NAME = '@agimon-ai/po-autocompact';\n\nexport const AUTOCOMPACT_EVENT = {\n checkpointStarted: 'doom_autocompact.checkpoint_started',\n checkpointCompleted: 'doom_autocompact.checkpoint_completed',\n checkpointFailed: 'doom_autocompact.checkpoint_failed',\n checkpointInvalid: 'doom_autocompact.checkpoint_invalid',\n configurationLoadFailed: 'doom_autocompact.configuration_load_failed',\n contextContributionDegraded: 'doom_autocompact.context_contribution_degraded',\n contextCommitted: 'doom_autocompact.context_committed',\n contextApplied: 'doom_autocompact.context_applied',\n contextMarkerInvalid: 'doom_autocompact.context_marker_invalid',\n contextHookSlow: 'doom_autocompact.context_hook_slow',\n nativeCompactionCompleted: 'doom_autocompact.native_compaction_completed',\n} as const;\n\nexport type AutocompactEventName = (typeof AUTOCOMPACT_EVENT)[keyof typeof AUTOCOMPACT_EVENT];\nexport type AutocompactEventAttributes = Record<string, string | number | boolean>;\n\nexport interface AutocompactTelemetryOptions {\n cwd?: string;\n workspaceRoot?: string;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: NonNullable<DoomTelemetryOptions['telemetryFactory']>;\n warn?: (message: string) => void;\n}\n\nexport interface AutocompactTelemetry {\n recordError(event: AutocompactEventName, error: unknown, attributes?: AutocompactEventAttributes): Promise<void>;\n recordWarning(event: AutocompactEventName, error: unknown, attributes?: AutocompactEventAttributes): Promise<void>;\n recordEvent(event: AutocompactEventName, attributes?: AutocompactEventAttributes): Promise<void>;\n runInSpan<T>(name: string, attributes: AutocompactEventAttributes, callback: () => Promise<T>): Promise<T>;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n}\n\nexport function createAutocompactTelemetry(options: AutocompactTelemetryOptions = {}): AutocompactTelemetry {\n const telemetry: DoomTelemetry = createDoomTelemetry({\n serviceName: SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: options.cwd,\n workspaceRoot: options.workspaceRoot,\n env: options.env,\n telemetryFactory: options.telemetryFactory,\n warn: options.warn,\n enableLogs: true,\n enableTraces: true,\n });\n return {\n recordError: (event, error, attributes) => telemetry.recordError(event, error, attributes),\n recordWarning: (event, error, attributes) => telemetry.recordWarning(event, error, attributes),\n recordEvent: (event, attributes) => telemetry.recordEvent(event, attributes),\n runInSpan: (name, attributes, callback) => telemetry.runInSpan(name, attributes, callback),\n flush: () => telemetry.flush(),\n shutdown: () => telemetry.shutdown(),\n };\n}\n","/**\n * Picks the absolute token checkpoints configured for the model a session is running.\n *\n * DESIGN PATTERNS:\n * - Pure decision function, so the matching rule is unit-testable without a session,\n * a config file or a filesystem\n * - First match in file order wins, so a reader resolves a model by reading down the\n * list rather than by working out which pattern is the most specific\n * - A model matching nothing returns no overrides at all, which leaves the ratio\n * ladder exactly as it behaves without this feature\n *\n * AVOID:\n * - Stripping a thinking suffix the way subagent model scope does. That matches\n * free-typed config strings; this matches a resolved `Model`, whose `id` carries\n * the level in a separate field and never in the id itself.\n * - Matching a bare pattern against `provider/id`. The glob wildcard does not cross\n * the separator, so the subject has to follow the pattern's own shape.\n */\n\nimport type { AutocompactOverrideConfig } from '@agimon-ai/po-config';\nimport { minimatch } from 'minimatch';\n\nimport type { AutocompactTokenOverrides } from '../../types/autocompact';\n\n/** The parts of a resolved model the rules match on. */\nexport interface AutocompactModelIdentity {\n id: string;\n provider: string;\n}\n\n/**\n * A pattern naming a provider is matched against `provider/id`, anything else\n * against the bare id. `*` does not cross `/`, so a bare pattern tested against a\n * qualified subject would never match and would read as a silently dead rule.\n */\nfunction matchesModelPattern(pattern: string, model: AutocompactModelIdentity): boolean {\n const subject = pattern.includes('/') ? `${model.provider}/${model.id}` : model.id;\n return minimatch(subject, pattern, { nocase: true });\n}\n\nexport function resolveModelTokenOverrides(\n model: AutocompactModelIdentity | undefined,\n overrides: readonly AutocompactOverrideConfig[],\n): AutocompactTokenOverrides {\n if (!model) return {};\n const matched = overrides.find((entry) => matchesModelPattern(entry.model, model));\n if (!matched) return {};\n const { pass1, pass2, pass3 } = matched.tokens;\n return {\n ...(pass1 === undefined ? {} : { 1: pass1 }),\n ...(pass2 === undefined ? {} : { 2: pass2 }),\n ...(pass3 === undefined ? {} : { 3: pass3 }),\n };\n}\n","import type { ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nconst THINKING_SUFFIX_PATTERN = /:(off|minimal|low|medium|high|xhigh|max)$/;\n\nexport interface SummarizationModel {\n model: NonNullable<ExtensionContext['model']>;\n thinkingLevel?: NonNullable<ExtensionContext['thinkingLevel']>;\n}\n\nexport interface ModelReference {\n provider: string;\n modelId: string;\n thinking?: NonNullable<ExtensionContext['thinkingLevel']>;\n}\n\n/** Splits a `provider/model` reference, tolerating the optional thinking suffix. */\nexport function parseModelReference(reference: string): ModelReference | undefined {\n const trimmed = reference.trim();\n const thinking = THINKING_SUFFIX_PATTERN.exec(trimmed)?.[1] as SummarizationModel['thinkingLevel'];\n const identity = trimmed.replace(THINKING_SUFFIX_PATTERN, '');\n const separator = identity.indexOf('/');\n if (separator <= 0 || separator >= identity.length - 1) return undefined;\n return {\n provider: identity.slice(0, separator),\n modelId: identity.slice(separator + 1),\n ...(thinking ? { thinking } : {}),\n };\n}\n","import {\n DOOM_CONTEXT_CONTRIBUTIONS_SERVICE,\n requireDoomContextContributions,\n type DoomContextContributionsService,\n} from '@agimon-ai/po-core/contextContributions';\nimport type { DoomFooterContributionHandle } from '@agimon-ai/po-core/footer';\nimport type { DoomHeadlessExecutionContext, DoomHeadlessHook } from '@agimon-ai/po-core/headless';\nimport { DOOM_UI_HUB_SERVICE, requireDoomUiHub } from '@agimon-ai/po-core/uiHub';\n\nimport {\n CHECKPOINT_MESSAGE_TYPE,\n CONTEXT_MESSAGE_TYPE,\n MAX_INVALID_CHECKPOINT_ATTEMPTS,\n RESUME_MESSAGE_TYPE,\n RUNTIME_STATE_MESSAGE_TYPE,\n STATE_CUSTOM_TYPE,\n STATE_VERSION,\n} from '../../constants/autocompact';\nimport { FOOTER_ORDER, FOOTER_SOURCE, SLOW_CONTEXT_HOOK_MS, STATUS_KEY } from '../../constants/runtime';\nimport type { AutocompactContextDetails, AutocompactMessage, AutocompactState } from '../../types/autocompact';\nimport {\n autocompactRuntimeConfig,\n checkpointInstructions,\n formatRuntimeState,\n latestPlanSnapshot,\n readContextContributionsSnapshot,\n runtimeStateSnapshot,\n} from '../autocompactRuntime';\nimport { AUTOCOMPACT_EVENT, createAutocompactTelemetry } from '../autocompactTelemetry';\nimport {\n baselineUsageIsSettled,\n checkpointRequestDetails,\n checkpointSummaryFromEntry,\n contextDetailsFromUnknown,\n createInitialState,\n createRequestId,\n effectiveThresholds,\n fileDetailsFromUnknown,\n fileOperationsFromMessages,\n isStructuredCheckpoint,\n latestCheckpointArtifactEntry,\n mergeFileDetails,\n parseCheckpointDecision,\n parseState,\n projectContextMessages,\n withCanonicalFileSections,\n type CompactionPolicyEntry,\n} from '../compactionPolicy';\nimport { resolveModelTokenOverrides } from '../modelOverrides';\nimport { parseModelReference } from '../summarizationModel';\nimport type { NativeAutocompactDependencies, NativeAutocompactRuntime } from './type';\n\n/** Exact canonical-prefix comparison refuses to apply summaries to edited or replaced evidence. */\nfunction tailAfter(\n snapshot: readonly AutocompactMessage[],\n current: readonly AutocompactMessage[],\n): AutocompactMessage[] | undefined {\n if (\n snapshot.length > current.length ||\n snapshot.some((message, index) => JSON.stringify(message) !== JSON.stringify(current[index]))\n )\n return undefined;\n return current.slice(snapshot.length);\n}\n\nfunction leaf(entries: readonly CompactionPolicyEntry[]): string {\n return (\n entries.findLast(\n (entry) =>\n entry.type !== 'custom' ||\n (entry.customType !== STATE_CUSTOM_TYPE && entry.customType !== CHECKPOINT_MESSAGE_TYPE),\n )?.id ?? 'root'\n );\n}\n\nexport function createNativeAutocompact(dependencies: NativeAutocompactDependencies = {}): NativeAutocompactRuntime {\n const telemetry = dependencies.telemetry ?? createAutocompactTelemetry();\n let active = true;\n let generation = 0;\n let state: AutocompactState = createInitialState();\n let snapshot: AutocompactMessage[] | undefined;\n let previousSnapshot: AutocompactMessage[] | undefined;\n let context: DoomHeadlessExecutionContext | undefined;\n let contributions: DoomContextContributionsService | undefined;\n let controller: AbortController | undefined;\n let serial: Promise<void> = Promise.resolve();\n const work = new Set<Promise<void>>();\n const applied = new Set<string>();\n const invalid = new Set<string>();\n let configFailureReported = false;\n let footer: DoomFooterContributionHandle | undefined;\n let navigating = false;\n let lastNativeCompactionId: string | undefined;\n let checkpointBoundary:\n | ReturnType<NonNullable<DoomHeadlessExecutionContext['session']['registerCheckpointBoundary']>>\n | undefined;\n\n const attributes = () => ({\n 'pi.session.id': context?.sessionId ?? '',\n 'autocompact.cycle': state.cycle,\n 'autocompact.pass': state.pass,\n ...(state.requestId ? { 'autocompact.request.id': state.requestId } : {}),\n ...(state.snapshotLeafId ? { 'autocompact.snapshot_leaf_id': state.snapshotLeafId } : {}),\n ...(state.snapshotTokens === undefined ? {} : { 'autocompact.tokens_before': state.snapshotTokens }),\n });\n const configured = (execution: DoomHeadlessExecutionContext) =>\n autocompactRuntimeConfig(execution.repoRoot, (error) => {\n if (!configFailureReported) {\n configFailureReported = true;\n void telemetry.recordWarning(AUTOCOMPACT_EVENT.configurationLoadFailed, error, attributes());\n }\n });\n const alive = (version: number) => active && !navigating && generation === version;\n const refreshStatus = (execution: DoomHeadlessExecutionContext) => {\n const phase =\n state.phase === 'checkpoint_pending'\n ? 'summarizing'\n : state.phase === 'checkpoint_ready'\n ? 'applying'\n : undefined;\n footer?.update(phase ? { fullText: `Compacting p${state.pass}`, compactText: `C${state.pass}` } : undefined);\n execution.client.setStatus(STATUS_KEY, phase ? `Compacting pass ${state.pass} (${phase})…` : undefined);\n };\n const enqueue = (callback: () => Promise<void>): Promise<void> => {\n const version = generation;\n const operation = serial.then(async () => {\n if (alive(version)) await callback();\n });\n serial = operation.catch(() => undefined);\n return operation;\n };\n const persist = async (execution: DoomHeadlessExecutionContext, version: number) => {\n if (!alive(version)) return;\n await execution.session.appendCustomEntry(STATE_CUSTOM_TYPE, {\n ...state,\n nativeSnapshot: snapshot,\n nativePreviousSnapshot: previousSnapshot,\n nativeLastCompactionId: lastNativeCompactionId,\n });\n if (alive(version)) refreshStatus(execution);\n };\n const clear = () => {\n delete state.requestId;\n delete state.snapshotLeafId;\n delete state.snapshotTokens;\n delete state.pendingCheckpoint;\n delete state.compactionPass;\n snapshot = undefined;\n };\n const fail = async (execution: DoomHeadlessExecutionContext, version: number, error: unknown, malformed = false) => {\n if (!alive(version)) return;\n const eventAttributes = attributes();\n const attempts = state.invalidAttempts + 1;\n const pass = state.pass;\n const failedLeaf = state.snapshotLeafId;\n state.invalidAttempts += 1;\n if (state.invalidAttempts >= MAX_INVALID_CHECKPOINT_ATTEMPTS) {\n state.checkpointQueue = state.checkpointQueue.filter((item) => item !== pass);\n state.exhaustedPasses.push(pass);\n state.invalidAttempts = 0;\n }\n state.phase = 'waiting';\n clear();\n state.lastAttemptLeafId = failedLeaf;\n await persist(execution, version);\n if (!alive(version)) return;\n await execution.client.notify({\n body: `Doom autocompact summarization pass ${pass} failed: ${error instanceof Error ? error.message : String(error)}`,\n level: 'error',\n });\n await telemetry.recordError(\n malformed ? AUTOCOMPACT_EVENT.checkpointInvalid : AUTOCOMPACT_EVENT.checkpointFailed,\n error,\n {\n ...eventAttributes,\n 'autocompact.checkpoint.attempts': attempts,\n 'autocompact.checkpoint.exhausted': attempts >= MAX_INVALID_CHECKPOINT_ATTEMPTS,\n },\n );\n };\n const branch = async (execution: DoomHeadlessExecutionContext) =>\n (await execution.session.entries()) as unknown as CompactionPolicyEntry[];\n const canonical = async (execution: DoomHeadlessExecutionContext, entries: CompactionPolicyEntry[]) => {\n if (!execution.session.contextMessages) throw new Error('Canonical context is unavailable for autocompact.');\n return projectContextMessages(\n (await execution.session.contextMessages()) as unknown as AutocompactMessage[],\n entries,\n ).messages;\n };\n const contributionSnapshot = async (execution: DoomHeadlessExecutionContext) => {\n const result = readContextContributionsSnapshot(contributions);\n for (const error of result.errors) {\n await execution.client.notify({\n body: `Doom autocompact context contribution degraded (${error.source}/${error.id}): ${error.message}`,\n level: 'warning',\n });\n await telemetry.recordWarning(AUTOCOMPACT_EVENT.contextContributionDegraded, new Error(error.message), {\n ...attributes(),\n 'autocompact.context_contribution.source': error.source,\n 'autocompact.context_contribution.id': error.id,\n 'autocompact.context_contribution.order': error.order,\n });\n }\n return result;\n };\n const runtimeState = async (\n execution: DoomHeadlessExecutionContext,\n entries: CompactionPolicyEntry[],\n version: number,\n appendMessage: DoomHeadlessExecutionContext['session']['appendMessage'] = checkpointBoundary?.appendMessage.bind(\n checkpointBoundary,\n ),\n ) => {\n const saved = runtimeStateSnapshot(entries, await contributionSnapshot(execution));\n if (!alive(version)) return;\n await appendMessage?.({\n type: RUNTIME_STATE_MESSAGE_TYPE,\n text: formatRuntimeState(saved),\n display: false,\n details: { version: 2, ...saved },\n });\n return {\n 'autocompact.runtime.plan_present': Boolean(saved.planPath),\n 'autocompact.runtime.contribution_count': saved.contributions.length,\n 'autocompact.runtime.contribution_error_count': saved.contributionErrors.length,\n };\n };\n const resetCycle = () => {\n state.phase = 'waiting';\n state.checkpointQueue = [];\n state.exhaustedPasses = [];\n state.invalidAttempts = 0;\n state.baselinePending = true;\n state.cycle += 1;\n state.pass = 1;\n delete state.lastAttemptLeafId;\n delete state.latestCheckpointSnapshotLeafId;\n clear();\n previousSnapshot = undefined;\n };\n const applyReady = async (execution: DoomHeadlessExecutionContext, version: number): Promise<boolean> => {\n if (state.phase !== 'checkpoint_ready' || !state.pendingCheckpoint || !state.requestId || !state.snapshotLeafId)\n return false;\n const decision = parseCheckpointDecision(state.pendingCheckpoint);\n if (!isStructuredCheckpoint(decision.summary)) {\n await fail(execution, version, new Error('Summarization returned an incomplete checkpoint.'), true);\n return false;\n }\n const entries = await branch(execution);\n const messages = await canonical(execution, entries);\n if (!alive(version)) return false;\n // Persisted legacy pending summaries lack canonical evidence. Retry rather than fabricate a retained tail.\n const tail = snapshot && tailAfter(snapshot, messages);\n if (!tail) {\n await fail(execution, version, new Error('Canonical checkpoint evidence changed; summary must be regenerated.'));\n return false;\n }\n const pass = state.pass;\n if (pass === 1 || (pass === 2 && decision.shouldCompact !== true)) {\n await execution.session.appendCustomEntry(CHECKPOINT_MESSAGE_TYPE, {\n ...checkpointRequestDetails(state.cycle, pass, state.requestId),\n summary: decision.summary,\n });\n if (!alive(version)) return false;\n previousSnapshot = snapshot;\n state.latestCheckpointSnapshotLeafId = state.snapshotLeafId;\n state.checkpointQueue = state.checkpointQueue.filter((item) => item !== pass);\n state.pass = pass === 1 ? 2 : 3;\n state.phase = 'waiting';\n state.invalidAttempts = 0;\n clear();\n await persist(execution, version);\n return false;\n }\n if (!execution.session.appendMessage) throw new Error('Checkpoint messages are unavailable.');\n const files = mergeFileDetails(state, fileOperationsFromMessages(messages));\n const details: AutocompactContextDetails = {\n ...files,\n doomAutocompact: {\n version: STATE_VERSION,\n cycle: state.cycle,\n pass,\n requestId: state.requestId,\n snapshotLeafId: state.snapshotLeafId,\n tokensBefore: state.snapshotTokens ?? 0,\n },\n retainedMessages: tail,\n };\n const idle = (await execution.session.activity()).isIdle;\n if (!alive(version)) return false;\n const id = await execution.session.appendMessage({\n type: CONTEXT_MESSAGE_TYPE,\n text: withCanonicalFileSections(decision.summary, files),\n display: false,\n details,\n });\n if (!alive(version) || !id) return false;\n await execution.session.setLabel?.(id, `autocompact:c${state.cycle}:p${pass}`);\n if (!alive(version)) return false;\n const runtimeAttributes = await runtimeState(\n execution,\n entries,\n version,\n execution.session.appendMessage.bind(execution.session),\n );\n if (!alive(version)) return false;\n const committedAttributes = attributes();\n state.readFiles = files.readFiles;\n state.modifiedFiles = files.modifiedFiles;\n resetCycle();\n await persist(execution, version);\n if (!alive(version)) return false;\n await telemetry.recordEvent(AUTOCOMPACT_EVENT.contextCommitted, {\n ...committedAttributes,\n 'autocompact.message_count.before': messages.length,\n 'autocompact.message_count.retained': tail.length,\n 'autocompact.apply_mode': idle ? 'idle' : 'turn_end',\n ...runtimeAttributes,\n });\n if (idle && alive(version))\n await execution.session.admitPrompt?.(\n \"Asynchronous compaction completed. Continue from the compacted checkpoint's immediate next action without repeating completed work.\",\n 'steer',\n undefined,\n `${RESUME_MESSAGE_TYPE}:${details.doomAutocompact.requestId}`,\n );\n return true;\n };\n const progress = async (\n execution: DoomHeadlessExecutionContext,\n allowBusy = false,\n appendMessage = checkpointBoundary?.appendMessage.bind(checkpointBoundary),\n ) => {\n const version = generation;\n context = execution;\n const activity = await execution.session.activity();\n if (!alive(version) || activity.hasPendingMessages) return;\n if (appendMessage && (activity.isIdle || allowBusy)) {\n const checkpointExecution = { ...execution, session: { ...execution.session, appendMessage } };\n if (await applyReady(checkpointExecution, version)) return;\n }\n if (!alive(version) || state.phase !== 'waiting') return;\n const configuration = configured(execution);\n if (!configuration.enabled || !execution.session.contextUsage || !execution.textCompletion?.summarize) return;\n const usage = await execution.session.contextUsage();\n const entries = await branch(execution);\n if (!alive(version) || !usage || usage.tokens === null) return;\n if (state.baselinePending) {\n if (!baselineUsageIsSettled(entries)) return;\n state.baselineTokens = usage.tokens;\n state.baselinePending = false;\n await persist(execution, version);\n return;\n }\n const currentLeaf = leaf(entries);\n if (currentLeaf === state.lastAttemptLeafId) return;\n const thresholds = effectiveThresholds(\n usage.contextWindow,\n state.baselineTokens,\n configuration.ratios,\n resolveModelTokenOverrides(execution.model, configuration.overrides),\n );\n for (const pass of [1, 2, 3] as const) {\n if (\n pass >= state.pass &&\n !state.checkpointQueue.includes(pass) &&\n !state.exhaustedPasses.includes(pass) &&\n usage.tokens >= thresholds[pass]\n )\n state.checkpointQueue.push(pass);\n }\n const pass = state.checkpointQueue[0];\n if (!pass) return;\n const messages = await canonical(execution, entries);\n const steering = await contributionSnapshot(execution);\n if (!alive(version)) return;\n snapshot = messages;\n const previous = pass > 1 ? checkpointSummaryFromEntry(latestCheckpointArtifactEntry(entries)) : undefined;\n const requestId = createRequestId(execution.sessionId, state.cycle, pass, currentLeaf);\n state.phase = 'checkpoint_pending';\n state.pass = pass;\n state.requestId = requestId;\n state.snapshotLeafId = currentLeaf;\n state.snapshotTokens = usage.tokens;\n delete state.lastAttemptLeafId;\n delete state.pendingCheckpoint;\n await persist(execution, version);\n if (!alive(version)) return;\n controller?.abort();\n controller = new AbortController();\n const signal = controller.signal;\n const ownReference = configuration.agent?.model ? parseModelReference(configuration.agent.model) : undefined;\n const candidate = ownReference ? `${ownReference.provider}/${ownReference.modelId}` : undefined;\n const reference =\n candidate && execution.textCompletion.available(candidate)\n ? candidate\n : execution.model\n ? `${execution.model.provider}/${execution.model.id}`\n : '';\n const thinking =\n configuration.agent?.thinking ??\n (reference === candidate ? ownReference?.thinking : undefined) ??\n (await execution.session.readModelSettings?.())?.thinkingLevel;\n if (!alive(version)) return;\n const requestAttributes = { ...attributes(), 'autocompact.message_count.before': messages.length };\n const delta = previousSnapshot ? tailAfter(previousSnapshot, messages) : undefined;\n const completion = telemetry\n .runInSpan('doom_autocompact.checkpoint', requestAttributes, async () => {\n await telemetry.recordEvent(AUTOCOMPACT_EVENT.checkpointStarted, requestAttributes);\n return execution.textCompletion!.summarize!(reference, {\n messages: (pass > 1 && delta ? delta : messages) as unknown as Record<string, unknown>[],\n instructions: checkpointInstructions(pass, {\n plan: latestPlanSnapshot(entries),\n contextContributions: steering,\n readFiles: state.readFiles,\n modifiedFiles: state.modifiedFiles,\n }),\n ...(previous ? { previousSummary: previous } : {}),\n ...(thinking ? { thinkingLevel: thinking } : {}),\n signal,\n });\n })\n .then(async (summary) => {\n await enqueue(async () => {\n if (!alive(version) || signal.aborted || state.requestId !== requestId) return;\n if (!summary.trim()) {\n await fail(execution, version, new Error('Summarization returned an empty checkpoint.'));\n return;\n }\n state.phase = 'checkpoint_ready';\n state.pendingCheckpoint = summary.trim();\n await persist(execution, version);\n if (!alive(version)) return;\n await telemetry.recordEvent(AUTOCOMPACT_EVENT.checkpointCompleted, {\n ...requestAttributes,\n 'autocompact.checkpoint.characters': summary.length,\n });\n if ((await execution.session.activity()).isIdle && alive(version)) await progress(execution);\n });\n })\n .catch(async (error: unknown) => {\n await enqueue(async () => {\n if (alive(version) && state.requestId === requestId) await fail(execution, version, error);\n });\n });\n work.add(completion);\n void completion.then(\n () => work.delete(completion),\n () => work.delete(completion),\n );\n };\n const restore = async (execution: DoomHeadlessExecutionContext) => {\n if (!active) return;\n if (!checkpointBoundary) {\n if (!execution.session.registerCheckpointBoundary)\n throw new Error('Native checkpoint boundaries are unavailable.');\n checkpointBoundary = execution.session.registerCheckpointBoundary(async (boundary) => {\n if (!active || navigating || boundary.signal?.aborted) return;\n const current = context ?? execution;\n await enqueue(() =>\n boundary.signal?.aborted ? Promise.resolve() : progress(current, true, boundary.appendMessage.bind(boundary)),\n );\n });\n }\n navigating = false;\n generation += 1;\n const version = generation;\n controller?.abort(new Error('Autocompact session generation changed.'));\n controller = undefined;\n context = execution;\n applied.clear();\n invalid.clear();\n const entries = await branch(execution);\n if (!alive(version)) return;\n const entry = entries.findLast((item) => item.type === 'custom' && item.customType === STATE_CUSTOM_TYPE);\n const data =\n entry?.type === 'custom' && entry.data && typeof entry.data === 'object'\n ? (entry.data as Record<string, unknown>)\n : undefined;\n state = parseState(data) ?? createInitialState();\n lastNativeCompactionId = typeof data?.nativeLastCompactionId === 'string' ? data.nativeLastCompactionId : undefined;\n const validMessages = (value: unknown): value is AutocompactMessage[] =>\n Array.isArray(value) &&\n value.every((message) => message && typeof message === 'object' && typeof message.role === 'string');\n snapshot = validMessages(data?.nativeSnapshot) ? data.nativeSnapshot : undefined;\n previousSnapshot = validMessages(data?.nativePreviousSnapshot) ? data.nativePreviousSnapshot : undefined;\n // A marker can commit before its following state entry. Recover only the exact\n // request after the saved state, rather than retrying against already-compacted evidence.\n if (state.phase === 'checkpoint_ready' && state.requestId) {\n const artifacts = entries.slice(entry ? entries.indexOf(entry) + 1 : 0);\n const committed = artifacts.findLast((item) => {\n const message = item.type === 'message' ? item.message : undefined;\n if (message?.role !== 'custom' || message.customType !== CONTEXT_MESSAGE_TYPE) return false;\n const details = contextDetailsFromUnknown(message.details);\n return (\n details !== undefined &&\n details.doomAutocompact.requestId === state.requestId &&\n details.doomAutocompact.cycle === state.cycle &&\n details.doomAutocompact.pass === state.pass &&\n details.doomAutocompact.snapshotLeafId === state.snapshotLeafId &&\n isStructuredCheckpoint(checkpointSummaryFromEntry(item) ?? '')\n );\n });\n if (committed?.type === 'message' && committed.message.role === 'custom') {\n const details = contextDetailsFromUnknown(committed.message.details)!;\n state.readFiles = details.readFiles;\n state.modifiedFiles = details.modifiedFiles;\n resetCycle();\n await persist(execution, version);\n } else {\n const staged = artifacts.findLast((item) => {\n if (item.type !== 'custom' || item.customType !== CHECKPOINT_MESSAGE_TYPE) return false;\n const details = item.data as Record<string, unknown> | undefined;\n return (\n details?.version === STATE_VERSION &&\n details.requestId === state.requestId &&\n details.cycle === state.cycle &&\n details.pass === state.pass &&\n isStructuredCheckpoint(checkpointSummaryFromEntry(item) ?? '')\n );\n });\n if (staged && (state.pass === 1 || state.pass === 2)) {\n previousSnapshot = snapshot;\n state.latestCheckpointSnapshotLeafId = state.snapshotLeafId;\n state.checkpointQueue = state.checkpointQueue.filter((pass) => pass !== state.pass);\n state.pass = state.pass === 1 ? 2 : 3;\n state.phase = 'waiting';\n state.invalidAttempts = 0;\n clear();\n await persist(execution, version);\n }\n }\n }\n if (state.phase !== 'waiting' && state.phase !== 'checkpoint_ready') {\n state.phase = 'waiting';\n clear();\n await persist(execution, version);\n }\n if (alive(version)) await enqueue(() => progress(execution));\n };\n const hooks: DoomHeadlessHook[] = [\n { event: 'session_start', handle: (_event, execution) => restore(execution) },\n {\n event: 'session_tree',\n handle: (event, execution) => {\n if (!active) return;\n if (event.status === 'started') {\n navigating = true;\n generation += 1;\n controller?.abort(new Error('Autocompact navigation started.'));\n return;\n }\n return restore(execution);\n },\n },\n {\n event: 'turn_end',\n handle: (_event, execution) => enqueue(() => progress(execution)),\n },\n { event: 'agent_settled', handle: (_event, execution) => enqueue(() => progress(execution)) },\n {\n event: 'session_before_compact',\n handle: (event, execution) =>\n active &&\n !navigating &&\n configured(execution).enabled &&\n event.reason === 'threshold' &&\n (state.phase === 'checkpoint_pending' || state.phase === 'checkpoint_ready' || state.baselinePending)\n ? { cancel: true }\n : undefined,\n },\n {\n event: 'context',\n async handle(event, execution) {\n if (!active || navigating || !Array.isArray(event.messages)) return;\n const started = Date.now();\n try {\n const version = generation;\n const entries = await branch(execution);\n if (!alive(version)) return;\n const projection = projectContextMessages(event.messages as AutocompactMessage[], entries);\n if (projection.invalidMarker) {\n const id = leaf(entries);\n if (!invalid.has(id)) {\n invalid.add(id);\n await telemetry.recordError(\n AUTOCOMPACT_EVENT.contextMarkerInvalid,\n new Error('Doom autocompact context marker is malformed.'),\n { ...attributes(), 'autocompact.leaf_id': id },\n );\n }\n return;\n }\n if (!projection.marker) return;\n if (!applied.has(projection.marker.requestId)) {\n applied.add(projection.marker.requestId);\n await telemetry.recordEvent(AUTOCOMPACT_EVENT.contextApplied, {\n ...attributes(),\n 'autocompact.request.id': projection.marker.requestId,\n 'autocompact.cycle': projection.marker.cycle,\n 'autocompact.pass': projection.marker.pass,\n 'autocompact.snapshot_leaf_id': projection.marker.snapshotLeafId,\n 'autocompact.tokens_before': projection.marker.tokensBefore,\n 'autocompact.message_count.before': event.messages.length,\n 'autocompact.message_count.after': projection.messages.length,\n 'autocompact.message_count.retained': projection.retainedMessageCount,\n });\n }\n return alive(version) ? { messages: projection.messages } : undefined;\n } finally {\n const hookMs = Date.now() - started;\n if (active && hookMs >= SLOW_CONTEXT_HOOK_MS)\n await telemetry.recordEvent(AUTOCOMPACT_EVENT.contextHookSlow, {\n ...attributes(),\n hook_ms: hookMs,\n 'autocompact.message_count': event.messages.length,\n });\n }\n },\n },\n {\n event: 'session_compact',\n handle: (event, execution) => {\n if (\n !active ||\n event.status !== 'completed' ||\n typeof event.entryId !== 'string' ||\n event.entryId === lastNativeCompactionId\n )\n return;\n const observedGeneration = generation;\n return enqueue(async () => {\n const entries = await branch(execution);\n const compacted = entries.findLast((entry) => entry.type === 'compaction');\n if (\n !alive(observedGeneration) ||\n !compacted ||\n compacted.id !== event.entryId ||\n compacted.id === lastNativeCompactionId\n )\n return;\n generation += 1;\n const version = generation;\n controller?.abort(new Error('Native compaction superseded checkpoint.'));\n controller = undefined;\n lastNativeCompactionId = compacted.id;\n const files = mergeFileDetails(\n state,\n undefined,\n fileDetailsFromUnknown('details' in compacted ? compacted.details : undefined),\n );\n state.readFiles = files.readFiles;\n state.modifiedFiles = files.modifiedFiles;\n await execution.session.setLabel?.(compacted.id, `autocompact:c${state.cycle}:external`);\n if (!alive(version)) return;\n const runtimeAttributes = await runtimeState(execution, entries, version);\n if (!alive(version)) return;\n const nativeAttributes = attributes();\n resetCycle();\n await persist(execution, version);\n if (alive(version))\n await telemetry.recordEvent(AUTOCOMPACT_EVENT.nativeCompactionCompleted, {\n ...nativeAttributes,\n 'autocompact.native.reason': typeof event.reason === 'string' ? event.reason : 'unknown',\n 'autocompact.native.from_extension': 'fromHook' in compacted && compacted.fromHook === true,\n 'autocompact.tokens_before': compacted.tokensBefore,\n ...runtimeAttributes,\n });\n });\n },\n },\n ];\n return {\n hooks,\n plugin(cordis) {\n cordis.inject([DOOM_UI_HUB_SERVICE], (injected) => {\n const contribution = requireDoomUiHub(injected).registerFooter({\n source: FOOTER_SOURCE,\n id: 'autocompact',\n order: FOOTER_ORDER,\n });\n footer = contribution;\n if (context && active) refreshStatus(context);\n return () => {\n contribution.dispose();\n if (footer === contribution) footer = undefined;\n };\n });\n cordis.inject([DOOM_CONTEXT_CONTRIBUTIONS_SERVICE], (injected) => {\n const service = requireDoomContextContributions(injected);\n contributions = service;\n return () => {\n if (contributions === service) contributions = undefined;\n };\n });\n },\n start: restore,\n async stop() {\n active = false;\n checkpointBoundary?.dispose();\n checkpointBoundary = undefined;\n generation += 1;\n controller?.abort(new Error('Autocompact is shutting down.'));\n await Promise.allSettled([...work, serial]);\n context?.client.setStatus(STATUS_KEY, undefined);\n footer?.update(undefined);\n footer = undefined;\n context = undefined;\n contributions = undefined;\n await telemetry.shutdown();\n },\n };\n}\n","import { defineRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport { createNativeAutocompact } from '../../../../services/nativeAutocompact';\n\nexport default defineRoot(() => {\n const runtime = createNativeAutocompact();\n return { value: runtime, services: [runtime.plugin], onDispose: runtime.stop };\n});\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport type { NativeAutocompactRuntime } from '../../../../../services/nativeAutocompact/type';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, NativeAutocompactRuntime>) =>\n root.hooks.find((hook) => hook.event === 'agent_settled')!,\n);\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport type { NativeAutocompactRuntime } from '../../../../../services/nativeAutocompact/type';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, NativeAutocompactRuntime>) =>\n root.hooks.find((hook) => hook.event === 'context')!,\n);\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport type { NativeAutocompactRuntime } from '../../../../../services/nativeAutocompact/type';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, NativeAutocompactRuntime>) =>\n root.hooks.find((hook) => hook.event === 'session_before_compact')!,\n);\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport type { NativeAutocompactRuntime } from '../../../../../services/nativeAutocompact/type';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, NativeAutocompactRuntime>) =>\n root.hooks.find((hook) => hook.event === 'session_compact')!,\n);\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport type { NativeAutocompactRuntime } from '../../../../../services/nativeAutocompact/type';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, NativeAutocompactRuntime>) =>\n root.hooks.find((hook) => hook.event === 'session_start')!,\n);\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport type { NativeAutocompactRuntime } from '../../../../../services/nativeAutocompact/type';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, NativeAutocompactRuntime>) =>\n root.hooks.find((hook) => hook.event === 'session_tree')!,\n);\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport type { NativeAutocompactRuntime } from '../../../../../services/nativeAutocompact/type';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, NativeAutocompactRuntime>) =>\n root.hooks.find((hook) => hook.event === 'turn_end')!,\n);\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/po-core/serverFacet';\nimport { composeServerProviderOverrides } from '@agimon-ai/po-core/serverFacet';\nimport { composeRootHooks } from '@agimon-ai/po-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport hookAgentSettled from '../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.server';\nimport hookContext from '../src/extensions/workspaces/sessions/(backend)/hook/context.server';\nimport hookSessionBeforeCompact from '../src/extensions/workspaces/sessions/(backend)/hook/session-before-compact.server';\nimport hookSessionCompact from '../src/extensions/workspaces/sessions/(backend)/hook/session-compact.server';\nimport hookSessionStart from '../src/extensions/workspaces/sessions/(backend)/hook/session-start.server';\nimport hookSessionTree from '../src/extensions/workspaces/sessions/(backend)/hook/session-tree.server';\nimport hookTurnEnd from '../src/extensions/workspaces/sessions/(backend)/hook/turn-end.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const facet = defineServerPlugin({\n name: '@agimon-ai/po-autocompact',\n providerOverrides: composeServerProviderOverrides(rootSession),\n session: async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get hooks(): DoomServerSessionPlugin['hooks'] { return [via({ event: 'agent_settled' }, at(hookAgentSettled, contextSession)), via({ event: 'context' }, at(hookContext, contextSession)), via({ event: 'session_before_compact' }, at(hookSessionBeforeCompact, contextSession)), via({ event: 'session_compact' }, at(hookSessionCompact, contextSession)), via({ event: 'session_start' }, at(hookSessionStart, contextSession)), via({ event: 'session_tree' }, at(hookSessionTree, contextSession)), via({ event: 'turn_end' }, at(hookTurnEnd, contextSession))]; },\n services: [...(scopeSession.services ?? [])],\n get activities(): DoomServerSessionPlugin['activities'] { return [...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default facet;\n"],"mappings":"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"}
@@ -0,0 +1,161 @@
1
+ import { defineSettingsSection, defineWebPlugin } from "@agimon-ai/po-core/web";
2
+ //#region src/constants/autocompact.ts
3
+ const COMPACTION_THRESHOLDS = {
4
+ 1: {
5
+ ratio: .5,
6
+ capTokens: 2e5
7
+ },
8
+ 2: {
9
+ ratio: .75,
10
+ capTokens: 5e5
11
+ },
12
+ 3: {
13
+ ratio: .95,
14
+ capTokens: 8e5
15
+ }
16
+ };
17
+ //#endregion
18
+ //#region src/types/autocompactSettings.ts
19
+ /**
20
+ * The autocompact settings, described once for both surfaces.
21
+ *
22
+ * The cockpit's settings page renders these, and the runtime reads the same key
23
+ * paths out of `.po/config.yaml`, so the ids, labels and key paths live here
24
+ * rather than in either place.
25
+ *
26
+ * It lives under src/types because that is the one server root a browser bundle
27
+ * may read, which also means it may import nothing outside this directory:
28
+ * pulling the config package in for the thinking levels would drag a node
29
+ * module into the page. They are spelled out instead, and a test asserts they
30
+ * still match the parser's.
31
+ */
32
+ const AUTOCOMPACT_CONFIG_SECTION_ID = "autocompact";
33
+ const AUTOCOMPACT_PATH = ["modes", AUTOCOMPACT_CONFIG_SECTION_ID];
34
+ const THRESHOLDS_KEY = "thresholds";
35
+ /** Unset means the session's own model and thinking level do the summarizing. */
36
+ const INHERIT_MODEL = "inherit the session model";
37
+ const INHERIT_THINKING = "inherit";
38
+ /** Mirrors DOOM_PLANNING_THINKING_LEVELS; pinned by this package's config test. */
39
+ const AUTOCOMPACT_THINKING_LEVELS = [
40
+ "off",
41
+ "minimal",
42
+ "low",
43
+ "medium",
44
+ "high",
45
+ "xhigh",
46
+ "max"
47
+ ];
48
+ /** The parser accepts a real boolean too; the page can only write strings. */
49
+ const AUTOCOMPACT_ENABLED_VALUES = ["true", "false"];
50
+ //#endregion
51
+ //#region src/extensions/(frontend)/_lib/autocompactSettings.ts
52
+ /**
53
+ * The autocompact settings, as the cockpit's settings page renders them.
54
+ *
55
+ * Built from the same descriptor table the runtime resolves against, so the
56
+ * page and the extension cannot disagree about which config key a field writes.
57
+ * The host owns the scope switch and the writes; this only says what the fields
58
+ * are.
59
+ */
60
+ const autocompactSettingsSection = {
61
+ id: AUTOCOMPACT_CONFIG_SECTION_ID,
62
+ label: "autocompact",
63
+ detail: "the model that writes checkpoint summaries, and when each compaction pass fires",
64
+ order: 40,
65
+ fields: [
66
+ {
67
+ id: "enabled",
68
+ label: "enabled",
69
+ keyPath: [...AUTOCOMPACT_PATH, "enabled"],
70
+ placeholder: "on",
71
+ detail: "off leaves compaction to Pi. unset is on.",
72
+ options: AUTOCOMPACT_ENABLED_VALUES
73
+ },
74
+ {
75
+ id: "model",
76
+ label: "summarization model",
77
+ keyPath: [...AUTOCOMPACT_PATH, "model"],
78
+ placeholder: INHERIT_MODEL,
79
+ detail: "model that writes the checkpoint summaries.",
80
+ models: true
81
+ },
82
+ {
83
+ id: "thinking",
84
+ label: "summarization thinking",
85
+ keyPath: [...AUTOCOMPACT_PATH, "thinking"],
86
+ placeholder: INHERIT_THINKING,
87
+ detail: "thinking level appended to the summarization model.",
88
+ options: AUTOCOMPACT_THINKING_LEVELS
89
+ },
90
+ {
91
+ id: "thresholds.pass1",
92
+ label: "pass 1 threshold",
93
+ keyPath: [
94
+ ...AUTOCOMPACT_PATH,
95
+ THRESHOLDS_KEY,
96
+ "pass1"
97
+ ],
98
+ placeholder: String(COMPACTION_THRESHOLDS[1].ratio),
99
+ detail: "fraction of the remaining context window at which the first pass fires."
100
+ },
101
+ {
102
+ id: "thresholds.pass2",
103
+ label: "pass 2 threshold",
104
+ keyPath: [
105
+ ...AUTOCOMPACT_PATH,
106
+ THRESHOLDS_KEY,
107
+ "pass2"
108
+ ],
109
+ placeholder: String(COMPACTION_THRESHOLDS[2].ratio),
110
+ detail: "second pass. a value below pass 1 is raised back to it."
111
+ },
112
+ {
113
+ id: "thresholds.pass3",
114
+ label: "pass 3 threshold",
115
+ keyPath: [
116
+ ...AUTOCOMPACT_PATH,
117
+ THRESHOLDS_KEY,
118
+ "pass3"
119
+ ],
120
+ placeholder: String(COMPACTION_THRESHOLDS[3].ratio),
121
+ detail: "last pass before Pi compacts natively. a value below pass 2 is raised back to it."
122
+ }
123
+ ].map((shape) => ({
124
+ id: shape.id,
125
+ label: shape.label,
126
+ kind: shape.models === true || shape.options !== void 0 ? "select" : "text",
127
+ keyPath: shape.keyPath,
128
+ detail: shape.detail,
129
+ placeholder: shape.placeholder,
130
+ ...shape.models === true ? { optionsFrom: "models" } : {},
131
+ ...shape.options === void 0 ? {} : { options: shape.options.map((option) => ({
132
+ value: option,
133
+ label: option
134
+ })) }
135
+ }))
136
+ };
137
+ //#endregion
138
+ //#region src/extensions/(frontend)/setting/autocompact.web.ts
139
+ var autocompact_web_default$1 = defineSettingsSection(autocompactSettingsSection);
140
+ //#endregion
141
+ //#region src/extensions/workspaces/(frontend)/setting/autocompact.web.ts
142
+ var autocompact_web_default = defineSettingsSection(autocompactSettingsSection);
143
+ //#endregion
144
+ //#region generated/web.ts
145
+ const via = (identity, value) => value === void 0 ? void 0 : {
146
+ ...identity,
147
+ ...value
148
+ };
149
+ const webPlugin = defineWebPlugin({
150
+ id: "autocompact",
151
+ global: { get settingsSections() {
152
+ return [via({ id: "autocompact" }, autocompact_web_default$1)];
153
+ } },
154
+ workspace: { get settingsSections() {
155
+ return [via({ id: "autocompact" }, autocompact_web_default)];
156
+ } }
157
+ });
158
+ //#endregion
159
+ export { webPlugin };
160
+
161
+ //# sourceMappingURL=web.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.mjs","names":["settingAutocompact","settingAutocompact2"],"sources":["../../src/constants/autocompact.ts","../../src/types/autocompactSettings.ts","../../src/extensions/(frontend)/_lib/autocompactSettings.ts","../../src/extensions/(frontend)/setting/autocompact.web.ts","../../src/extensions/workspaces/(frontend)/setting/autocompact.web.ts","../../generated/web.ts"],"sourcesContent":["export const STATE_CUSTOM_TYPE = 'doom-autocompact-state';\nexport const CHECKPOINT_MESSAGE_TYPE = 'doom-autocompact-checkpoint';\nexport const CONTEXT_MESSAGE_TYPE = 'doom-autocompact-context';\nexport const RESUME_MESSAGE_TYPE = 'doom-autocompact-resume';\nexport const RUNTIME_STATE_MESSAGE_TYPE = 'doom-autocompact-runtime-state';\nexport const STATE_VERSION = 2;\n/** Retrying a malformed checkpoint costs a full summarization call per turn, so a pass that\n * keeps failing is abandoned instead of retried for the rest of the session. */\nexport const MAX_INVALID_CHECKPOINT_ATTEMPTS = 3;\n\nexport const COMPACTION_THRESHOLDS = {\n 1: { ratio: 0.5, capTokens: 200_000 },\n 2: { ratio: 0.75, capTokens: 500_000 },\n 3: { ratio: 0.95, capTokens: 800_000 },\n} as const;\n\nexport const CHECKPOINT_HEADINGS = [\n '## Goal',\n '## Constraints & Preferences',\n '## Progress',\n '### Done',\n '### In Progress',\n '### Blocked',\n '## Key Decisions',\n '## Next Steps',\n '## Critical Context',\n] as const;\n","/**\n * The autocompact settings, described once for both surfaces.\n *\n * The cockpit's settings page renders these, and the runtime reads the same key\n * paths out of `.po/config.yaml`, so the ids, labels and key paths live here\n * rather than in either place.\n *\n * It lives under src/types because that is the one server root a browser bundle\n * may read, which also means it may import nothing outside this directory:\n * pulling the config package in for the thinking levels would drag a node\n * module into the page. They are spelled out instead, and a test asserts they\n * still match the parser's.\n */\n\nimport { COMPACTION_THRESHOLDS } from '../constants/autocompact';\n\nexport const AUTOCOMPACT_CONFIG_SECTION_ID = 'autocompact';\nconst AUTOCOMPACT_PATH = ['modes', AUTOCOMPACT_CONFIG_SECTION_ID] as const;\nconst THRESHOLDS_KEY = 'thresholds';\n\n/** Unset means the session's own model and thinking level do the summarizing. */\nconst INHERIT_MODEL = 'inherit the session model';\nconst INHERIT_THINKING = 'inherit';\n\n/** Mirrors DOOM_PLANNING_THINKING_LEVELS; pinned by this package's config test. */\nexport const AUTOCOMPACT_THINKING_LEVELS: readonly string[] = [\n 'off',\n 'minimal',\n 'low',\n 'medium',\n 'high',\n 'xhigh',\n 'max',\n];\n\n/** The parser accepts a real boolean too; the page can only write strings. */\nexport const AUTOCOMPACT_ENABLED_VALUES: readonly string[] = ['true', 'false'];\n\nexport interface AutocompactSettingShape {\n readonly id: string;\n readonly label: string;\n readonly keyPath: readonly string[];\n readonly placeholder: string;\n readonly detail: string;\n /** Present for a closed set; a renderer offers these rather than free text. */\n readonly options?: readonly string[];\n /** Offers the machine's authenticated models rather than free text. */\n readonly models?: boolean;\n}\n\nexport const AUTOCOMPACT_SETTING_SHAPES: readonly AutocompactSettingShape[] = [\n {\n id: 'enabled',\n label: 'enabled',\n keyPath: [...AUTOCOMPACT_PATH, 'enabled'],\n placeholder: 'on',\n detail: 'off leaves compaction to Pi. unset is on.',\n options: AUTOCOMPACT_ENABLED_VALUES,\n },\n {\n id: 'model',\n label: 'summarization model',\n keyPath: [...AUTOCOMPACT_PATH, 'model'],\n placeholder: INHERIT_MODEL,\n detail: 'model that writes the checkpoint summaries.',\n models: true,\n },\n {\n id: 'thinking',\n label: 'summarization thinking',\n keyPath: [...AUTOCOMPACT_PATH, 'thinking'],\n placeholder: INHERIT_THINKING,\n detail: 'thinking level appended to the summarization model.',\n options: AUTOCOMPACT_THINKING_LEVELS,\n },\n {\n id: 'thresholds.pass1',\n label: 'pass 1 threshold',\n keyPath: [...AUTOCOMPACT_PATH, THRESHOLDS_KEY, 'pass1'],\n placeholder: String(COMPACTION_THRESHOLDS[1].ratio),\n detail: 'fraction of the remaining context window at which the first pass fires.',\n },\n {\n id: 'thresholds.pass2',\n label: 'pass 2 threshold',\n keyPath: [...AUTOCOMPACT_PATH, THRESHOLDS_KEY, 'pass2'],\n placeholder: String(COMPACTION_THRESHOLDS[2].ratio),\n detail: 'second pass. a value below pass 1 is raised back to it.',\n },\n {\n id: 'thresholds.pass3',\n label: 'pass 3 threshold',\n keyPath: [...AUTOCOMPACT_PATH, THRESHOLDS_KEY, 'pass3'],\n placeholder: String(COMPACTION_THRESHOLDS[3].ratio),\n detail: 'last pass before Pi compacts natively. a value below pass 2 is raised back to it.',\n },\n];\n","import type { SettingsSectionContribution } from '@agimon-ai/po-core/web';\n\nimport { AUTOCOMPACT_CONFIG_SECTION_ID, AUTOCOMPACT_SETTING_SHAPES } from '../../../types/autocompactSettings';\n\n/**\n * The autocompact settings, as the cockpit's settings page renders them.\n *\n * Built from the same descriptor table the runtime resolves against, so the\n * page and the extension cannot disagree about which config key a field writes.\n * The host owns the scope switch and the writes; this only says what the fields\n * are.\n */\nexport const autocompactSettingsSection: SettingsSectionContribution = {\n id: AUTOCOMPACT_CONFIG_SECTION_ID,\n label: 'autocompact',\n detail: 'the model that writes checkpoint summaries, and when each compaction pass fires',\n order: 40,\n fields: AUTOCOMPACT_SETTING_SHAPES.map((shape) => ({\n id: shape.id,\n label: shape.label,\n // A model field offers the machine's authenticated models, which only the\n // host can enumerate; the rest are a closed set or free text.\n kind: shape.models === true || shape.options !== undefined ? ('select' as const) : ('text' as const),\n keyPath: shape.keyPath,\n detail: shape.detail,\n placeholder: shape.placeholder,\n ...(shape.models === true ? { optionsFrom: 'models' as const } : {}),\n ...(shape.options === undefined\n ? {}\n : { options: shape.options.map((option) => ({ value: option, label: option })) }),\n })),\n};\n","import { defineSettingsSection } from '@agimon-ai/po-core/web';\n\nimport { autocompactSettingsSection } from '../_lib/autocompactSettings';\n\nexport default defineSettingsSection(autocompactSettingsSection);\n","import { defineSettingsSection } from '@agimon-ai/po-core/web';\n\nimport { autocompactSettingsSection } from '../../../(frontend)/_lib/autocompactSettings';\n\nexport default defineSettingsSection(autocompactSettingsSection);\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/po-core/web';\n\nimport settingAutocompact from '../src/extensions/(frontend)/setting/autocompact.web';\nimport settingAutocompact2 from '../src/extensions/workspaces/(frontend)/setting/autocompact.web';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const webPlugin = defineWebPlugin({\n id: 'autocompact',\n global: {\n get settingsSections(): WebPluginContributions['settingsSections'] { return [via({ id: 'autocompact' }, settingAutocompact)]; },\n },\n workspace: {\n get settingsSections(): WebPluginContributions['settingsSections'] { return [via({ id: 'autocompact' }, settingAutocompact2)]; },\n },\n});\n"],"mappings":";;AAUA,MAAa,wBAAwB;CACnC,GAAG;EAAE,OAAO;EAAK,WAAW;CAAQ;CACpC,GAAG;EAAE,OAAO;EAAM,WAAW;CAAQ;CACrC,GAAG;EAAE,OAAO;EAAM,WAAW;CAAQ;AACvC;;;;;;;;;;;;;;;;ACEA,MAAa,gCAAgC;AAC7C,MAAM,mBAAmB,CAAC,SAAS,6BAA6B;AAChE,MAAM,iBAAiB;;AAGvB,MAAM,gBAAgB;AACtB,MAAM,mBAAmB;;AAGzB,MAAa,8BAAiD;CAC5D;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;AAGA,MAAa,6BAAgD,CAAC,QAAQ,OAAO;;;;;;;;;;;ACxB7E,MAAa,6BAA0D;CACrE,IAAI;CACJ,OAAO;CACP,QAAQ;CACR,OAAO;CACP,QAAQ;EDkCR;GACE,IAAI;GACJ,OAAO;GACP,SAAS,CAAC,GAAG,kBAAkB,SAAS;GACxC,aAAa;GACb,QAAQ;GACR,SAAS;EACX;EACA;GACE,IAAI;GACJ,OAAO;GACP,SAAS,CAAC,GAAG,kBAAkB,OAAO;GACtC,aAAa;GACb,QAAQ;GACR,QAAQ;EACV;EACA;GACE,IAAI;GACJ,OAAO;GACP,SAAS,CAAC,GAAG,kBAAkB,UAAU;GACzC,aAAa;GACb,QAAQ;GACR,SAAS;EACX;EACA;GACE,IAAI;GACJ,OAAO;GACP,SAAS;IAAC,GAAG;IAAkB;IAAgB;GAAO;GACtD,aAAa,OAAO,sBAAsB,EAAE,CAAC,KAAK;GAClD,QAAQ;EACV;EACA;GACE,IAAI;GACJ,OAAO;GACP,SAAS;IAAC,GAAG;IAAkB;IAAgB;GAAO;GACtD,aAAa,OAAO,sBAAsB,EAAE,CAAC,KAAK;GAClD,QAAQ;EACV;EACA;GACE,IAAI;GACJ,OAAO;GACP,SAAS;IAAC,GAAG;IAAkB;IAAgB;GAAO;GACtD,aAAa,OAAO,sBAAsB,EAAE,CAAC,KAAK;GAClD,QAAQ;EACV;CC9EQ,CAAA,CAA2B,KAAK,WAAW;EACjD,IAAI,MAAM;EACV,OAAO,MAAM;EAGb,MAAM,MAAM,WAAW,QAAQ,MAAM,YAAY,KAAA,IAAa,WAAsB;EACpF,SAAS,MAAM;EACf,QAAQ,MAAM;EACd,aAAa,MAAM;EACnB,GAAI,MAAM,WAAW,OAAO,EAAE,aAAa,SAAkB,IAAI,CAAC;EAClE,GAAI,MAAM,YAAY,KAAA,IAClB,CAAC,IACD,EAAE,SAAS,MAAM,QAAQ,KAAK,YAAY;GAAE,OAAO;GAAQ,OAAO;EAAO,EAAE,EAAE;CACnF,EAAE;AACJ;;;AC3BA,IAAA,4BAAe,sBAAsB,0BAA0B;;;ACA/D,IAAA,0BAAe,sBAAsB,0BAA0B;;;ACE/D,MAAM,OAAU,UAAmC,UAChD,UAAU,KAAA,IAAY,KAAA,IAAY;CAAE,GAAG;CAAU,GAAI;AAAiB;AAEzE,MAAa,YAAY,gBAAgB;CACvC,IAAI;CACJ,QAAQ,EACN,IAAI,mBAA+D;EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,cAAc,GAAGA,yBAAkB,CAAC;CAAG,EAChI;CACA,WAAW,EACT,IAAI,mBAA+D;EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,cAAc,GAAGC,uBAAmB,CAAC;CAAG,EACjI;AACF,CAAC"}
package/dist/index.cjs ADDED
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_compactionPolicy = require("./compactionPolicy-BIJJHcBP.cjs");
3
+ exports.thresholdTokens = require_compactionPolicy.thresholdTokens;
@@ -0,0 +1,11 @@
1
+ import "@earendil-works/pi-coding-agent";
2
+ //#region src/types/autocompact.d.ts
3
+ type AutocompactPass = 1 | 2 | 3;
4
+ /** Configured pass ratios, keyed by pass; an absent pass keeps its default. */
5
+ type AutocompactRatioOverrides = Partial<Record<AutocompactPass, number>>;
6
+ //#endregion
7
+ //#region src/services/compactionPolicy/index.d.ts
8
+ export declare function thresholdTokens(pass: AutocompactPass, contextWindow: number, baselineTokens?: number, configured?: AutocompactRatioOverrides): number;
9
+ //#endregion
10
+ export type { AutocompactPass };
11
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types/autocompact.ts","../src/services/compactionPolicy/index.ts"],"mappings":";;KAEY;;KAKA,4BAA4B,QAAQ,OAAO;;;wBCoJvC,gBACd,MAAM,iBACN,uBACA,yBACA,aAAY"}
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { g as thresholdTokens } from "./compactionPolicy-CDCYTj2b.mjs";
2
+ export { thresholdTokens };
package/package.json ADDED
@@ -0,0 +1,111 @@
1
+ {
2
+ "name": "@agimon-ai/po-autocompact",
3
+ "version": "0.0.0-alpha.0",
4
+ "description": "Iterative context compaction and checkpoint summaries for Po headless agent sessions.",
5
+ "keywords": [
6
+ "ai",
7
+ "coding-agent",
8
+ "context-compaction",
9
+ "context-window",
10
+ "developer-tools",
11
+ "pi-coding-agent",
12
+ "po",
13
+ "summarization"
14
+ ],
15
+ "homepage": "https://agimon.ai",
16
+ "bugs": {
17
+ "url": "https://github.com/AgiFlow/po/issues"
18
+ },
19
+ "license": "MIT",
20
+ "author": "Vuong Ngo",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/AgiFlow/po.git",
24
+ "directory": "packages/default/po-autocompact"
25
+ },
26
+ "files": [
27
+ "dist"
28
+ ],
29
+ "type": "module",
30
+ "main": "./dist/index.cjs",
31
+ "module": "./dist/index.mjs",
32
+ "types": "./dist/index.d.mts",
33
+ "jsnext:main": "./dist/index.mjs",
34
+ "exports": {
35
+ ".": {
36
+ "types": "./dist/index.d.mts",
37
+ "import": "./dist/index.mjs",
38
+ "require": "./dist/index.cjs"
39
+ },
40
+ "./apiContracts": {
41
+ "types": "./dist/apiContracts.d.mts",
42
+ "import": "./dist/apiContracts.mjs",
43
+ "require": "./dist/apiContracts.cjs"
44
+ },
45
+ "./extensions/server": {
46
+ "types": "./dist/extensions/server.d.mts",
47
+ "import": "./dist/extensions/server.mjs",
48
+ "require": "./dist/extensions/server.cjs"
49
+ },
50
+ "./extensions/web": {
51
+ "import": "./dist/extensions/web.mjs"
52
+ },
53
+ "./package.json": "./package.json"
54
+ },
55
+ "publishConfig": {
56
+ "access": "public"
57
+ },
58
+ "dependencies": {
59
+ "@agimon-ai/po-config": "0.0.0-alpha.0",
60
+ "@agimon-ai/po-core": "0.0.0-alpha.0",
61
+ "@agimon-ai/po-telemetry": "0.0.0-alpha.0",
62
+ "@deepseek-ai/cordis": "4.0.4",
63
+ "minimatch": "10.2.6"
64
+ },
65
+ "devDependencies": {
66
+ "@agimon-ai/po-build": "0.0.0-alpha.0",
67
+ "@earendil-works/pi-coding-agent": "1.0.2",
68
+ "@types/node": "26.6.4",
69
+ "@vitest/coverage-v8": "5.0.3",
70
+ "typescript": "7.0.2",
71
+ "vitest": "5.0.3"
72
+ },
73
+ "peerDependencies": {
74
+ "@earendil-works/pi-coding-agent": "1.0.2"
75
+ },
76
+ "peerDependenciesMeta": {
77
+ "@earendil-works/pi-coding-agent": {
78
+ "optional": true
79
+ }
80
+ },
81
+ "engines": {
82
+ "node": ">=24"
83
+ },
84
+ "poServer": {
85
+ "entry": "./generated/server.ts",
86
+ "dist": "./dist/extensions/server.mjs",
87
+ "scopes": [
88
+ "session"
89
+ ],
90
+ "contracts": {
91
+ "entry": "./src/exports/apiContracts.ts",
92
+ "dist": "./dist/apiContracts.mjs"
93
+ }
94
+ },
95
+ "poWeb": {
96
+ "pluginId": "autocompact",
97
+ "channels": [],
98
+ "client": "./dist/extensions/web.mjs",
99
+ "scopes": [
100
+ "global",
101
+ "workspace"
102
+ ]
103
+ },
104
+ "scripts": {
105
+ "build": "tsdown",
106
+ "test": "vitest --run",
107
+ "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.web.json",
108
+ "lint": "oxlint . && oxfmt . --check",
109
+ "fixcode": "oxlint . --fix && oxfmt ."
110
+ }
111
+ }