@theokit/sdk 4.32.0 → 4.33.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.
Files changed (102) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/{agent-ES57DGAT.cjs → agent-2STDGKNI.cjs} +11 -10
  3. package/dist/{agent-ES57DGAT.cjs.map → agent-2STDGKNI.cjs.map} +1 -1
  4. package/dist/{agent-FBFPSBTX.js → agent-LFSVFAUI.js} +10 -9
  5. package/dist/{agent-FBFPSBTX.js.map → agent-LFSVFAUI.js.map} +1 -1
  6. package/dist/{chunk-DQSILMWU.cjs → chunk-2DYI7MIF.cjs} +2 -2
  7. package/dist/chunk-2DYI7MIF.cjs.map +1 -0
  8. package/dist/{chunk-OIYQBUW4.cjs → chunk-6M6A6WWW.cjs} +2 -2
  9. package/dist/{chunk-OIYQBUW4.cjs.map → chunk-6M6A6WWW.cjs.map} +1 -1
  10. package/dist/chunk-B3HUL2OQ.js +78 -0
  11. package/dist/chunk-B3HUL2OQ.js.map +1 -0
  12. package/dist/{chunk-I4QDIQ45.cjs → chunk-E33A7YIR.cjs} +28 -6
  13. package/dist/chunk-E33A7YIR.cjs.map +1 -0
  14. package/dist/chunk-FER7UMIC.cjs +75 -0
  15. package/dist/chunk-FER7UMIC.cjs.map +1 -0
  16. package/dist/{chunk-CVSNCUBU.cjs → chunk-FTRNHGAD.cjs} +11 -11
  17. package/dist/{chunk-CVSNCUBU.cjs.map → chunk-FTRNHGAD.cjs.map} +1 -1
  18. package/dist/{chunk-EVADEGM7.cjs → chunk-FX2DAR5R.cjs} +7 -5
  19. package/dist/chunk-FX2DAR5R.cjs.map +1 -0
  20. package/dist/{chunk-WA3FO4R7.js → chunk-GBCQ5742.js} +7 -6
  21. package/dist/chunk-GBCQ5742.js.map +1 -0
  22. package/dist/{chunk-JPG7NMNH.cjs → chunk-HTO4C32Q.cjs} +54 -48
  23. package/dist/chunk-HTO4C32Q.cjs.map +1 -0
  24. package/dist/{chunk-SQVQH4EK.js → chunk-KT6SWUY6.js} +4 -4
  25. package/dist/{chunk-SQVQH4EK.js.map → chunk-KT6SWUY6.js.map} +1 -1
  26. package/dist/chunk-LDDUIXWS.cjs +81 -0
  27. package/dist/chunk-LDDUIXWS.cjs.map +1 -0
  28. package/dist/chunk-OMDRRHRF.js +73 -0
  29. package/dist/chunk-OMDRRHRF.js.map +1 -0
  30. package/dist/{chunk-OQX2DG36.cjs → chunk-PZ4Q5K7O.cjs} +5 -5
  31. package/dist/{chunk-OQX2DG36.cjs.map → chunk-PZ4Q5K7O.cjs.map} +1 -1
  32. package/dist/{chunk-WPBTPSKQ.js → chunk-Q56IYTBZ.js} +2 -2
  33. package/dist/chunk-Q56IYTBZ.js.map +1 -0
  34. package/dist/{chunk-334WDVFZ.js → chunk-SDYJESYZ.js} +27 -6
  35. package/dist/chunk-SDYJESYZ.js.map +1 -0
  36. package/dist/{chunk-NI4PAMJQ.js → chunk-TKE4RTYA.js} +18 -12
  37. package/dist/chunk-TKE4RTYA.js.map +1 -0
  38. package/dist/{chunk-HBTEK5LK.js → chunk-WBGCDZDV.js} +3 -3
  39. package/dist/{chunk-HBTEK5LK.js.map → chunk-WBGCDZDV.js.map} +1 -1
  40. package/dist/{chunk-DGRZNMTU.js → chunk-XV2RBL6D.js} +2 -2
  41. package/dist/{chunk-DGRZNMTU.js.map → chunk-XV2RBL6D.js.map} +1 -1
  42. package/dist/{compact-session-OKXLKJIS.cjs → compact-session-24PK2G4M.cjs} +13 -13
  43. package/dist/{compact-session-OKXLKJIS.cjs.map → compact-session-24PK2G4M.cjs.map} +1 -1
  44. package/dist/{compact-session-UHGMWPMW.js → compact-session-J7VNCICZ.js} +5 -5
  45. package/dist/{compact-session-UHGMWPMW.js.map → compact-session-J7VNCICZ.js.map} +1 -1
  46. package/dist/compaction.cjs +17 -13
  47. package/dist/compaction.d.cts +8 -0
  48. package/dist/compaction.d.ts +8 -0
  49. package/dist/compaction.js +1 -1
  50. package/dist/cron.cjs +10 -9
  51. package/dist/cron.js +9 -8
  52. package/dist/eval.cjs +9 -8
  53. package/dist/eval.cjs.map +1 -1
  54. package/dist/eval.js +8 -7
  55. package/dist/eval.js.map +1 -1
  56. package/dist/fs-session-store-MZ4GD2C6.js +10 -0
  57. package/dist/{fs-session-store-2J5JOXC2.js.map → fs-session-store-MZ4GD2C6.js.map} +1 -1
  58. package/dist/fs-session-store-YMBSJ5Y7.cjs +19 -0
  59. package/dist/{fs-session-store-DNAJ6RQG.cjs.map → fs-session-store-YMBSJ5Y7.cjs.map} +1 -1
  60. package/dist/index.cjs +35 -35
  61. package/dist/index.cjs.map +1 -1
  62. package/dist/index.js +15 -15
  63. package/dist/index.js.map +1 -1
  64. package/dist/{inject-session-24FJ65LP.cjs → inject-session-343WIDCM.cjs} +6 -6
  65. package/dist/{inject-session-24FJ65LP.cjs.map → inject-session-343WIDCM.cjs.map} +1 -1
  66. package/dist/{inject-session-JXQO33T3.js → inject-session-RZEDWO53.js} +4 -4
  67. package/dist/{inject-session-JXQO33T3.js.map → inject-session-RZEDWO53.js.map} +1 -1
  68. package/dist/internal/local-agent/local-agent.d.ts +93 -1
  69. package/dist/internal/persistence/fs-session-store.d.cts +16 -0
  70. package/dist/internal/persistence/fs-session-store.d.ts +16 -0
  71. package/dist/internal/persistence/index.cjs +7 -7
  72. package/dist/internal/persistence/index.js +1 -1
  73. package/dist/internal/persistence/paths.d.cts +11 -1
  74. package/dist/internal/persistence/paths.d.ts +11 -1
  75. package/dist/internal/persistence/session-writer.d.cts +8 -0
  76. package/dist/internal/persistence/session-writer.d.ts +8 -0
  77. package/dist/internal/session/agent-session.d.ts +22 -0
  78. package/dist/persistence.cjs +13 -39
  79. package/dist/persistence.cjs.map +1 -1
  80. package/dist/persistence.d.cts +1 -1
  81. package/dist/persistence.d.ts +1 -1
  82. package/dist/persistence.js +4 -36
  83. package/dist/persistence.js.map +1 -1
  84. package/dist/{session-transcript-QS6CXHHD.js → session-transcript-F2ANTA2M.js} +3 -3
  85. package/dist/{session-transcript-QS6CXHHD.js.map → session-transcript-F2ANTA2M.js.map} +1 -1
  86. package/dist/{session-transcript-F5OXXO6G.cjs → session-transcript-JXFMPLOT.cjs} +13 -13
  87. package/dist/{session-transcript-F5OXXO6G.cjs.map → session-transcript-JXFMPLOT.cjs.map} +1 -1
  88. package/package.json +1 -1
  89. package/dist/chunk-334WDVFZ.js.map +0 -1
  90. package/dist/chunk-DQSILMWU.cjs.map +0 -1
  91. package/dist/chunk-EIPSZ4GA.js +0 -28
  92. package/dist/chunk-EIPSZ4GA.js.map +0 -1
  93. package/dist/chunk-EVADEGM7.cjs.map +0 -1
  94. package/dist/chunk-HCXDDR6P.cjs +0 -30
  95. package/dist/chunk-HCXDDR6P.cjs.map +0 -1
  96. package/dist/chunk-I4QDIQ45.cjs.map +0 -1
  97. package/dist/chunk-JPG7NMNH.cjs.map +0 -1
  98. package/dist/chunk-NI4PAMJQ.js.map +0 -1
  99. package/dist/chunk-WA3FO4R7.js.map +0 -1
  100. package/dist/chunk-WPBTPSKQ.js.map +0 -1
  101. package/dist/fs-session-store-2J5JOXC2.js +0 -8
  102. package/dist/fs-session-store-DNAJ6RQG.cjs +0 -17
@@ -130,15 +130,16 @@ var ContextWindowMarginError = class extends chunkA44COQJJ_cjs.TheokitAgentError
130
130
  };
131
131
  var CONTEXT_WINDOW_MARGIN = 0.95;
132
132
  var CONTEXT_WINDOW_FLOOR = 128e3;
133
+ var TETO_ABSOLUTO_DE_JANELA = 2e6;
133
134
  function resolveEffectiveContextWindow(input) {
134
135
  if (!(input.margin > 0) || input.margin > 1) {
135
136
  throw new ContextWindowMarginError(input.margin);
136
137
  }
137
138
  const withMargin = (raw) => Math.floor(raw * input.margin);
138
139
  if (input.override !== void 0) {
139
- const clamped = input.catalog !== void 0 && input.override > input.catalog;
140
- const raw = clamped ? input.catalog : input.override;
141
- return { window: withMargin(raw), source: "override", clamped };
140
+ const teto = input.catalog ?? TETO_ABSOLUTO_DE_JANELA;
141
+ const clamped = input.override > teto;
142
+ return { window: withMargin(clamped ? teto : input.override), source: "override", clamped };
142
143
  }
143
144
  if (input.catalog !== void 0) {
144
145
  return { window: withMargin(input.catalog), source: "catalog", clamped: false };
@@ -157,6 +158,7 @@ exports.CONTEXT_WINDOW_FLOOR = CONTEXT_WINDOW_FLOOR;
157
158
  exports.CONTEXT_WINDOW_MARGIN = CONTEXT_WINDOW_MARGIN;
158
159
  exports.ContextWindowMarginError = ContextWindowMarginError;
159
160
  exports.SUMMARY_TEMPLATE = SUMMARY_TEMPLATE;
161
+ exports.TETO_ABSOLUTO_DE_JANELA = TETO_ABSOLUTO_DE_JANELA;
160
162
  exports.buildCheckpoint = buildCheckpoint;
161
163
  exports.compactTranscript = compactTranscript;
162
164
  exports.estimateTokens = estimateTokens;
@@ -164,5 +166,5 @@ exports.filterFromLatestCheckpoint = filterFromLatestCheckpoint;
164
166
  exports.isContextOverflowError = isContextOverflowError;
165
167
  exports.resolveEffectiveContextWindow = resolveEffectiveContextWindow;
166
168
  exports.shouldCompact = shouldCompact;
167
- //# sourceMappingURL=chunk-EVADEGM7.cjs.map
168
- //# sourceMappingURL=chunk-EVADEGM7.cjs.map
169
+ //# sourceMappingURL=chunk-FX2DAR5R.cjs.map
170
+ //# sourceMappingURL=chunk-FX2DAR5R.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/runtime/compression/compression-helpers.ts","../src/compaction.ts"],"names":["TheokitAgentError","redactSecrets"],"mappings":"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","file":"chunk-FX2DAR5R.cjs","sourcesContent":["/**\n * Compression helpers (T2.3, ADR D92).\n *\n * Scaffold for future compression LLM integration:\n * - `selectCompressionWindow` — splits messages into compress/preserve halves\n * - `assertCompressionReduced` — 10% reduction floor to detect \"compression placebo\"\n *\n * The compression LLM call itself is out of scope for this plan (requires\n * an auxiliary-model ADR). These helpers are used by `Agent.send` when a\n * future iteration adds compression.\n *\n * @internal\n */\n\nexport interface CompressionWindow<M> {\n toCompress: M[];\n toPreserve: M[];\n}\n\n/**\n * Split `messages` into the half to compress (older) and the half to\n * preserve verbatim (recent). When `messages.length <= preserveLast`,\n * everything is preserved.\n *\n * @internal\n */\nexport function selectCompressionWindow<M>(\n messages: readonly M[],\n preserveLast = 6,\n): CompressionWindow<M> {\n if (messages.length <= preserveLast) {\n return { toCompress: [], toPreserve: [...messages] };\n }\n return {\n toCompress: messages.slice(0, -preserveLast),\n toPreserve: messages.slice(-preserveLast),\n };\n}\n\nexport interface CompressionCheck {\n reduced: boolean;\n reductionPct: number;\n reason?: string;\n}\n\n/**\n * Check that compression actually reduced token count by at least `minPct`\n * (default 10%). Returns `{ reduced: false }` for spirals-in-formation\n * (compression LLM outputs that grow or barely shrink).\n *\n * @internal\n */\nexport function assertCompressionReduced(\n before: number,\n after: number,\n minPct = 10,\n): CompressionCheck {\n if (before <= 0) {\n return { reduced: false, reductionPct: 0, reason: \"before count was zero\" };\n }\n const reductionPct = ((before - after) / before) * 100;\n if (reductionPct >= minPct) {\n return { reduced: true, reductionPct };\n }\n return {\n reduced: false,\n reductionPct,\n reason: `compression reduced ${reductionPct.toFixed(1)}% (< ${minPct}% min). Spiral likely.`,\n };\n}\n","/**\n * Public compaction / context-management helpers (M2-1, extended V3-3).\n *\n * Promotes the SDK's compaction capability to a public surface so consumers can\n * compact a transcript, mark/filter conversation checkpoints, and detect\n * context-overflow — without reaching into `internal/`.\n *\n * Two recent-window modes (V3-3):\n * - `keepRecent` (turn-count, default) — keeps the last N turns verbatim and\n * always preserves leading system PROMPTS; reuses the internal\n * `selectCompressionWindow` (no second algorithm).\n * - `keepTokens` (token-budget) — keeps the trailing turns whose accumulated\n * `estimateTokens` fits the budget (theocode `splitTranscript` semantics). In\n * this mode leading system prompts are NOT special-cased (D6).\n *\n * Summarization is delegated to a caller-supplied callback (which receives the\n * older window + the summary template). With `failSafe`, a thrown summarizer\n * returns the ORIGINAL transcript + a structured warn (compaction is an\n * optimization, never a cause of data loss); without it, the error propagates.\n *\n * Public from the `@theokit/sdk/compaction` sub-path.\n */\n\nimport { TheokitAgentError } from \"./errors.js\";\nimport { selectCompressionWindow } from \"./internal/runtime/compression/compression-helpers.js\";\nimport { redactSecrets } from \"./internal/security/redact.js\";\n\n/**\n * Minimal message shape for compaction/compression input. THE canonical public origin (leaf type —\n * rollup-plugin-dts cannot re-export types from internal modules into entry bundles; M42 lesson).\n *\n * @public\n */\nexport interface CompressibleMessage {\n role: \"user\" | \"assistant\" | \"system\";\n content: string;\n}\n\n/**\n * Sentinel prefix marking a conversation checkpoint turn. A visible, structured,\n * prose-unlikely token (no invisible/control bytes — safe to persist and to read\n * in source). Only {@link buildCheckpoint} should produce content beginning with it.\n */\nexport const CHECKPOINT_MARKER = \"[[theokit:checkpoint]] \";\n\n/**\n * The 7-section summary template handed to the `summarize` callback (theocode\n * parity shape). Every header is always present so the summarizer cannot silently\n * drop a category; the model is told to preserve file paths, commands, and error\n * text verbatim. Override per-call via {@link CompactTranscriptOptions.summaryTemplate}.\n */\nexport const SUMMARY_TEMPLATE = `Summarize the conversation so far into these sections (keep every header even if empty):\n\n## Goal\nWhat the user is ultimately trying to achieve.\n\n## Constraints\nHard requirements, conventions, and rules stated.\n\n## Progress\nWhat has been done so far.\n\n## Decisions\nChoices made and their rationale.\n\n## Next\nThe immediate next steps.\n\n## Critical\nAnything that MUST NOT be forgotten (preserve verbatim: error messages, exact values).\n\n## Files\nFile paths touched or referenced (verbatim).`;\n\n/** Reject an empty marker — it would match every turn via `startsWith(\"\")` (EC-3). */\nfunction assertMarker(marker: string): void {\n if (marker === \"\") {\n throw new TheokitAgentError(\"compaction marker must be non-empty\", {\n code: \"invalid_argument\",\n });\n }\n}\n\n/** True for a real system prompt — a `system` turn that is NOT a checkpoint marker. */\nfunction isSystemPrompt(message: CompressibleMessage, marker: string): boolean {\n return message.role === \"system\" && !message.content.startsWith(marker);\n}\n\n/** Carried split: leading system prompts (preserved), the older window, the verbatim tail. */\ninterface TranscriptSplit {\n systemPrompts: CompressibleMessage[];\n head: CompressibleMessage[];\n recent: CompressibleMessage[];\n}\n\n/**\n * Token-budget split (theocode `splitTranscript`): walk from the END accumulating\n * `estimateTokens` until `keepTokens` is exceeded; everything older is the head.\n * Always keeps ≥ 1 recent turn. No system-prompt special-casing (D6).\n */\nfunction selectByTokenBudget(\n messages: CompressibleMessage[],\n keepTokens: number,\n): { head: CompressibleMessage[]; recent: CompressibleMessage[] } {\n let acc = 0;\n let splitIndex = messages.length;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n acc += estimateTokens(messages[i]?.content ?? \"\");\n if (acc > keepTokens && i < messages.length - 1) {\n splitIndex = i + 1;\n break;\n }\n splitIndex = i;\n }\n return { head: messages.slice(0, splitIndex), recent: messages.slice(splitIndex) };\n}\n\n/** Turn-count split (M2): preserve leading system prompts; window the rest by `keepRecent`. */\nfunction splitByRecent(\n messages: CompressibleMessage[],\n keepRecent: number,\n marker: string,\n): TranscriptSplit {\n const systemPrompts = messages.filter((m) => isSystemPrompt(m, marker));\n const rest = messages.filter((m) => !isSystemPrompt(m, marker));\n const { toCompress, toPreserve } = selectCompressionWindow(rest, keepRecent);\n return { systemPrompts, head: toCompress, recent: toPreserve };\n}\n\n/** Options for {@link compactTranscript}. */\nexport interface CompactTranscriptOptions {\n /** Trailing turns preserved verbatim by COUNT (default 6). Ignored when `keepTokens` is set. */\n keepRecent?: number;\n /**\n * Trailing turns preserved verbatim by TOKEN BUDGET (theocode mode). When set,\n * takes precedence over `keepRecent` and disables system-prompt preservation (D6).\n */\n keepTokens?: number;\n /** Checkpoint marker (default {@link CHECKPOINT_MARKER}). Must be non-empty. */\n marker?: string;\n /** Summary template passed to `summarize` (default {@link SUMMARY_TEMPLATE}). */\n summaryTemplate?: string;\n /** Summarize the older window into one turn; if omitted, the older window is dropped. */\n summarize?: (older: CompressibleMessage[], template: string) => Promise<CompressibleMessage>;\n /**\n * When true, a thrown `summarize` returns the ORIGINAL transcript + a structured\n * warn (compaction never loses data). Default false: the error propagates.\n */\n failSafe?: boolean;\n}\n\n/** Sentinel returned by {@link runSummarize} when fail-safe swallowed a throw. */\nconst FAILSAFE_ABORT = Symbol(\"failsafe-abort\");\n\n/** Run the summarizer; on throw, either propagate or (fail-safe) warn + signal abort. */\nasync function runSummarize(\n summarize: NonNullable<CompactTranscriptOptions[\"summarize\"]>,\n head: CompressibleMessage[],\n template: string,\n failSafe: boolean,\n): Promise<CompressibleMessage | typeof FAILSAFE_ABORT> {\n try {\n return await summarize(head, template);\n } catch (err) {\n if (!failSafe) throw err;\n // Unbreakable Rule 8 — never fail silently. The breadcrumb points at the root\n // cause when a summarizer fails every turn and context grows unchecked. The\n // summarizer is caller-supplied, so its error text is routed through\n // `redactSecrets` (ADR D68 — no unredacted output sink in src/).\n console.warn(\n `[compaction] summarizer failed — proceeding uncompacted: ${redactSecrets(err instanceof Error ? err.message : String(err))}`,\n );\n return FAILSAFE_ABORT;\n }\n}\n\n/**\n * Compact a transcript. In `keepRecent` mode (default) the last `keepRecent` turns\n * are kept verbatim and leading system PROMPTS preserved; in `keepTokens` mode the\n * trailing turns within the token budget are kept (no system special-casing, D6).\n * The older window is summarized (via `summarize`, receiving the template) or\n * dropped. Never mutates the input.\n */\nexport async function compactTranscript(\n messages: CompressibleMessage[],\n options: CompactTranscriptOptions = {},\n): Promise<CompressibleMessage[]> {\n const marker = options.marker ?? CHECKPOINT_MARKER;\n assertMarker(marker);\n const split =\n options.keepTokens != null\n ? { systemPrompts: [], ...selectByTokenBudget(messages, options.keepTokens) }\n : splitByRecent(messages, options.keepRecent ?? 6, marker);\n if (split.head.length === 0) {\n return [...messages];\n }\n if (!options.summarize) {\n return [...split.systemPrompts, ...split.recent];\n }\n const template = options.summaryTemplate ?? SUMMARY_TEMPLATE;\n const summary = await runSummarize(\n options.summarize,\n split.head,\n template,\n options.failSafe ?? false,\n );\n if (summary === FAILSAFE_ABORT) {\n return [...messages];\n }\n return [...split.systemPrompts, summary, ...split.recent];\n}\n\n/**\n * Build a checkpoint marker turn (a `system` turn whose content starts with\n * `marker`, default {@link CHECKPOINT_MARKER}). `marker` must be non-empty.\n */\nexport function buildCheckpoint(\n label?: string,\n marker: string = CHECKPOINT_MARKER,\n): CompressibleMessage {\n assertMarker(marker);\n return { role: \"system\", content: marker + (label ?? \"\") };\n}\n\n/** Options for {@link filterFromLatestCheckpoint}. */\nexport interface FilterCheckpointOptions {\n /** Marker to scan for (default {@link CHECKPOINT_MARKER}). */\n marker?: string;\n /**\n * `'after'` (default, M2) returns turns AFTER the latest marker (exclusive);\n * `'from'` (theocode) returns turns FROM the latest marker (inclusive).\n */\n include?: \"after\" | \"from\";\n}\n\n/**\n * Return the turns relative to the most recent checkpoint marker (all turns if\n * none). `include: 'after'` (default) excludes the checkpoint; `'from'` includes\n * it (the summary stands in for the pruned head). Never mutates the input.\n */\nexport function filterFromLatestCheckpoint(\n messages: CompressibleMessage[],\n options: FilterCheckpointOptions = {},\n): CompressibleMessage[] {\n const marker = options.marker ?? CHECKPOINT_MARKER;\n const offset = options.include === \"from\" ? 0 : 1;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n if (messages[i]?.content.startsWith(marker)) {\n return messages.slice(i + offset);\n }\n }\n return [...messages];\n}\n\n/**\n * True iff `err` is a {@link TheokitAgentError} (or subclass) reporting a\n * context-window-exceeded condition (the typed `context_too_long` code). Reads\n * both `code` (set by provider mappers) and `metadata.code` (the preferred field)\n * — never a brittle message regex.\n */\nexport function isContextOverflowError(err: unknown): boolean {\n return (\n err instanceof TheokitAgentError &&\n (err.code === \"context_too_long\" || err.metadata?.code === \"context_too_long\")\n );\n}\n\n/**\n * M77 — the margin is outside `(0, 1]`. Typed, because a margin > 1 would GROW the assumed window,\n * which is the unsafe direction: `shouldCompact` is monotonically decreasing in `contextWindow`, so\n * overestimating it makes the trigger fire too late and the context overflow.\n */\nexport class ContextWindowMarginError extends TheokitAgentError {\n constructor(readonly margin: number) {\n super(\n `context-window margin must be in (0, 1], got ${String(margin)}. ` +\n `A margin above 1 grows the assumed window and delays compaction past the real limit.`,\n { code: \"invalid_context_window_margin\" },\n );\n }\n}\n\n/**\n * M77 — default safety margin on the context window.\n *\n * `0.95` is not a guess: it is the single reference's value. Codex ships\n * `effective_context_window_percent: 95` (`models-manager/src/model_info.rs:158`) and never budgets\n * against 100% of a window. Being MULTIPLICATIVE, it stays conservative at any window size, which a\n * fixed subtraction would not.\n */\nexport const CONTEXT_WINDOW_MARGIN = 0.95;\n\n/**\n * M77 — the floor used ONLY when neither the catalog nor the caller knows the window.\n *\n * Honest about its own weakness. This number has **one** source (the M77 milestone text); the search\n * for a second one failed, because the reference has no fallback at all — Codex returns `Option` and\n * its callers early-return (`core/src/session/turn_context.rs:213`, `core/src/compact_remote.rs:374`).\n *\n * It is conservative only UPWARD. For a model whose real window is larger, budgeting against 128k\n * compacts early — wasteful but safe. For a model whose real window is SMALLER (an 8k or 32k model\n * absent from the catalog), it compacts too late and the context still overflows. That residual risk\n * is real and is why {@link resolveEffectiveContextWindow} never lets this floor compete with a known\n * catalog value, and why the `compaction_fallback` event exists: a surface can show that the budget is\n * a guess instead of the user finding out when the provider rejects the request.\n */\nexport const CONTEXT_WINDOW_FLOOR = 128_000;\n\n/** Where the effective window came from — carried into the M77 structured event. */\nexport type ContextWindowSource = \"override\" | \"catalog\" | \"fallback\";\n\n/** Input to {@link resolveEffectiveContextWindow}. */\nexport interface EffectiveContextWindowInput {\n /** Caller-supplied window, in tokens. Clamped by `catalog` when both are present. */\n readonly override?: number | undefined;\n /** The model's window from the catalog, in tokens. Absent when the model is unknown. */\n readonly catalog?: number | undefined;\n /** Safety margin in `(0, 1]`. Codex uses 0.95 (`model_info.rs:158`). */\n readonly margin: number;\n /** Conservative floor used ONLY when neither `override` nor `catalog` is available. */\n readonly floor?: number | undefined;\n}\n\n/** Result of {@link resolveEffectiveContextWindow}. */\nexport interface EffectiveContextWindow {\n /** The window to budget against, after clamp and margin. */\n readonly window: number;\n /** Which input won — `\"fallback\"` means neither override nor catalog was available. */\n readonly source: ContextWindowSource;\n /** `true` when an `override` above the catalog window was clamped down to it. */\n readonly clamped: boolean;\n}\n\n/**\n * Resolve the window to budget against — the fail-SAFE replacement for reading the catalog directly.\n *\n * Today `post-run-lifecycle.ts` reads `getCatalogModelInfo(model)?.limit?.context` and, when that is\n * `undefined`, auto-compaction simply never fires. That is fail-OPEN: the context grows until the\n * provider rejects the request. (The comment there calls it \"fail-safe\" — M77 corrects it.)\n *\n * Three techniques, two of them borrowed from the single reference:\n *\n * 1. **Override, CLAMPED by the catalog** — Codex `models-manager/src/model_info.rs:26-31` lets\n * config override the window but limits it with `context_window.min(max_context_window)`.\n * Without the clamp, declaring 999k on a 200k model reopens the overflow through another door.\n * 2. **Multiplicative margin** — Codex `model_info.rs:158` (`effective_context_window_percent: 95`)\n * never budgets against 100% of the window. Being multiplicative, it is conservative for ANY\n * window size.\n * 3. **Floor, only when nothing is known** — deliberately NOT a blanket default. A fixed floor is\n * conservative only upward: applied to a small model it would inflate the assumed window and\n * reproduce the very fail-open this function exists to close. Hence the floor never competes\n * with a known catalog value.\n *\n * Pure — no catalog lookup, no I/O. The caller supplies the numbers, mirroring `shouldCompact`.\n */\n/**\n * Teto absoluto de janela declarada, usado quando não há entrada de catálogo para comparar.\n *\n * 2M tokens — acima da maior janela publicada por qualquer provider hoje com folga larga, então\n * não recusa nada legítimo; e bem abaixo de um erro de digitação típico (um zero a mais em 400k dá\n * 4M). O teto existe para transformar um typo em orçamento conservador em vez de em fail-OPEN.\n */\nexport const TETO_ABSOLUTO_DE_JANELA = 2_000_000;\n\nexport function resolveEffectiveContextWindow(\n input: EffectiveContextWindowInput,\n): EffectiveContextWindow {\n if (!(input.margin > 0) || input.margin > 1) {\n throw new ContextWindowMarginError(input.margin);\n }\n\n const withMargin = (raw: number): number => Math.floor(raw * input.margin);\n\n if (input.override !== undefined) {\n // O catálogo é o teto preferido; sem ele vale o TETO ABSOLUTO.\n //\n // M95 (revisão adversarial do M94) — a versão anterior clampeava **apenas** quando havia\n // entrada de catálogo, e a razão de ser da chave `contextWindow` é justamente o modelo que\n // NÃO tem entrada (OpenRouter tem zero). Ou seja: o clamp faltava exatamente no caso que\n // justifica a feature, enquanto a documentação — inclusive um CHANGELOG já publicado —\n // afirmava sem condicional que \"declarar 10M não estoura o provider\".\n //\n // O cenário concreto é um zero a mais: `context_window = 4000000`. O único guarda era um\n // `.positive().int()`, que não limita para cima. O agente nunca compactaria até o provider\n // recusar o turno — o fail-OPEN silencioso que o M77 existe para impedir.\n const teto = input.catalog ?? TETO_ABSOLUTO_DE_JANELA;\n const clamped = input.override > teto;\n return { window: withMargin(clamped ? teto : input.override), source: \"override\", clamped };\n }\n\n if (input.catalog !== undefined) {\n return { window: withMargin(input.catalog), source: \"catalog\", clamped: false };\n }\n\n return { window: withMargin(input.floor ?? 0), source: \"fallback\", clamped: false };\n}\n\n/** Input to {@link shouldCompact}: an estimate, the model's window, and reserved headroom. */\nexport interface ShouldCompactInput {\n /** Estimated token count of the next request (e.g. from {@link estimateTokens}). */\n readonly estimated: number;\n /** The model's total context window, in tokens. */\n readonly contextWindow: number;\n /** Tokens to reserve as headroom (output + safety margin). */\n readonly buffer: number;\n /**\n * Tokens reserved for the model's response generation, SEPARATE from `buffer`.\n * Default 0 — omitting it preserves the legacy\n * `estimated >= contextWindow - buffer` result.\n */\n readonly maxOutput?: number;\n}\n\n/**\n * Tokenizer-free token estimate via the conventional ~4-chars-per-token\n * heuristic: `ceil(text.length / 4)`. `\"\"` → 0; any non-empty text → ≥ 1.\n * A cheap PRE-CALL gate for {@link shouldCompact} — NOT exact tokenization\n * (a consumer needing exactness supplies their own tokenizer). Uses UTF-16\n * `.length` (code units), so multibyte text is approximate.\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Decide BEFORE sending whether to compact: `true` when the `estimated` token\n * count leaves less than `buffer` headroom in the `contextWindow`\n * (`estimated >= contextWindow - buffer`). A `buffer >= contextWindow`\n * (non-positive threshold) always returns `true`. Pure — the caller supplies\n * the window (e.g. from `resolveModelCapabilities`), keeping this decoupled\n * from the per-model catalog.\n */\nexport function shouldCompact(input: ShouldCompactInput): boolean {\n return input.estimated >= input.contextWindow - input.buffer - (input.maxOutput ?? 0);\n}\n"]}
@@ -128,15 +128,16 @@ var ContextWindowMarginError = class extends TheokitAgentError {
128
128
  };
129
129
  var CONTEXT_WINDOW_MARGIN = 0.95;
130
130
  var CONTEXT_WINDOW_FLOOR = 128e3;
131
+ var TETO_ABSOLUTO_DE_JANELA = 2e6;
131
132
  function resolveEffectiveContextWindow(input) {
132
133
  if (!(input.margin > 0) || input.margin > 1) {
133
134
  throw new ContextWindowMarginError(input.margin);
134
135
  }
135
136
  const withMargin = (raw) => Math.floor(raw * input.margin);
136
137
  if (input.override !== void 0) {
137
- const clamped = input.catalog !== void 0 && input.override > input.catalog;
138
- const raw = clamped ? input.catalog : input.override;
139
- return { window: withMargin(raw), source: "override", clamped };
138
+ const teto = input.catalog ?? TETO_ABSOLUTO_DE_JANELA;
139
+ const clamped = input.override > teto;
140
+ return { window: withMargin(clamped ? teto : input.override), source: "override", clamped };
140
141
  }
141
142
  if (input.catalog !== void 0) {
142
143
  return { window: withMargin(input.catalog), source: "catalog", clamped: false };
@@ -150,6 +151,6 @@ function shouldCompact(input) {
150
151
  return input.estimated >= input.contextWindow - input.buffer - (input.maxOutput ?? 0);
151
152
  }
152
153
 
153
- export { CHECKPOINT_MARKER, CONTEXT_WINDOW_FLOOR, CONTEXT_WINDOW_MARGIN, ContextWindowMarginError, SUMMARY_TEMPLATE, buildCheckpoint, compactTranscript, estimateTokens, filterFromLatestCheckpoint, isContextOverflowError, resolveEffectiveContextWindow, shouldCompact };
154
- //# sourceMappingURL=chunk-WA3FO4R7.js.map
155
- //# sourceMappingURL=chunk-WA3FO4R7.js.map
154
+ export { CHECKPOINT_MARKER, CONTEXT_WINDOW_FLOOR, CONTEXT_WINDOW_MARGIN, ContextWindowMarginError, SUMMARY_TEMPLATE, TETO_ABSOLUTO_DE_JANELA, buildCheckpoint, compactTranscript, estimateTokens, filterFromLatestCheckpoint, isContextOverflowError, resolveEffectiveContextWindow, shouldCompact };
155
+ //# sourceMappingURL=chunk-GBCQ5742.js.map
156
+ //# sourceMappingURL=chunk-GBCQ5742.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/runtime/compression/compression-helpers.ts","../src/compaction.ts"],"names":[],"mappings":"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","file":"chunk-GBCQ5742.js","sourcesContent":["/**\n * Compression helpers (T2.3, ADR D92).\n *\n * Scaffold for future compression LLM integration:\n * - `selectCompressionWindow` — splits messages into compress/preserve halves\n * - `assertCompressionReduced` — 10% reduction floor to detect \"compression placebo\"\n *\n * The compression LLM call itself is out of scope for this plan (requires\n * an auxiliary-model ADR). These helpers are used by `Agent.send` when a\n * future iteration adds compression.\n *\n * @internal\n */\n\nexport interface CompressionWindow<M> {\n toCompress: M[];\n toPreserve: M[];\n}\n\n/**\n * Split `messages` into the half to compress (older) and the half to\n * preserve verbatim (recent). When `messages.length <= preserveLast`,\n * everything is preserved.\n *\n * @internal\n */\nexport function selectCompressionWindow<M>(\n messages: readonly M[],\n preserveLast = 6,\n): CompressionWindow<M> {\n if (messages.length <= preserveLast) {\n return { toCompress: [], toPreserve: [...messages] };\n }\n return {\n toCompress: messages.slice(0, -preserveLast),\n toPreserve: messages.slice(-preserveLast),\n };\n}\n\nexport interface CompressionCheck {\n reduced: boolean;\n reductionPct: number;\n reason?: string;\n}\n\n/**\n * Check that compression actually reduced token count by at least `minPct`\n * (default 10%). Returns `{ reduced: false }` for spirals-in-formation\n * (compression LLM outputs that grow or barely shrink).\n *\n * @internal\n */\nexport function assertCompressionReduced(\n before: number,\n after: number,\n minPct = 10,\n): CompressionCheck {\n if (before <= 0) {\n return { reduced: false, reductionPct: 0, reason: \"before count was zero\" };\n }\n const reductionPct = ((before - after) / before) * 100;\n if (reductionPct >= minPct) {\n return { reduced: true, reductionPct };\n }\n return {\n reduced: false,\n reductionPct,\n reason: `compression reduced ${reductionPct.toFixed(1)}% (< ${minPct}% min). Spiral likely.`,\n };\n}\n","/**\n * Public compaction / context-management helpers (M2-1, extended V3-3).\n *\n * Promotes the SDK's compaction capability to a public surface so consumers can\n * compact a transcript, mark/filter conversation checkpoints, and detect\n * context-overflow — without reaching into `internal/`.\n *\n * Two recent-window modes (V3-3):\n * - `keepRecent` (turn-count, default) — keeps the last N turns verbatim and\n * always preserves leading system PROMPTS; reuses the internal\n * `selectCompressionWindow` (no second algorithm).\n * - `keepTokens` (token-budget) — keeps the trailing turns whose accumulated\n * `estimateTokens` fits the budget (theocode `splitTranscript` semantics). In\n * this mode leading system prompts are NOT special-cased (D6).\n *\n * Summarization is delegated to a caller-supplied callback (which receives the\n * older window + the summary template). With `failSafe`, a thrown summarizer\n * returns the ORIGINAL transcript + a structured warn (compaction is an\n * optimization, never a cause of data loss); without it, the error propagates.\n *\n * Public from the `@theokit/sdk/compaction` sub-path.\n */\n\nimport { TheokitAgentError } from \"./errors.js\";\nimport { selectCompressionWindow } from \"./internal/runtime/compression/compression-helpers.js\";\nimport { redactSecrets } from \"./internal/security/redact.js\";\n\n/**\n * Minimal message shape for compaction/compression input. THE canonical public origin (leaf type —\n * rollup-plugin-dts cannot re-export types from internal modules into entry bundles; M42 lesson).\n *\n * @public\n */\nexport interface CompressibleMessage {\n role: \"user\" | \"assistant\" | \"system\";\n content: string;\n}\n\n/**\n * Sentinel prefix marking a conversation checkpoint turn. A visible, structured,\n * prose-unlikely token (no invisible/control bytes — safe to persist and to read\n * in source). Only {@link buildCheckpoint} should produce content beginning with it.\n */\nexport const CHECKPOINT_MARKER = \"[[theokit:checkpoint]] \";\n\n/**\n * The 7-section summary template handed to the `summarize` callback (theocode\n * parity shape). Every header is always present so the summarizer cannot silently\n * drop a category; the model is told to preserve file paths, commands, and error\n * text verbatim. Override per-call via {@link CompactTranscriptOptions.summaryTemplate}.\n */\nexport const SUMMARY_TEMPLATE = `Summarize the conversation so far into these sections (keep every header even if empty):\n\n## Goal\nWhat the user is ultimately trying to achieve.\n\n## Constraints\nHard requirements, conventions, and rules stated.\n\n## Progress\nWhat has been done so far.\n\n## Decisions\nChoices made and their rationale.\n\n## Next\nThe immediate next steps.\n\n## Critical\nAnything that MUST NOT be forgotten (preserve verbatim: error messages, exact values).\n\n## Files\nFile paths touched or referenced (verbatim).`;\n\n/** Reject an empty marker — it would match every turn via `startsWith(\"\")` (EC-3). */\nfunction assertMarker(marker: string): void {\n if (marker === \"\") {\n throw new TheokitAgentError(\"compaction marker must be non-empty\", {\n code: \"invalid_argument\",\n });\n }\n}\n\n/** True for a real system prompt — a `system` turn that is NOT a checkpoint marker. */\nfunction isSystemPrompt(message: CompressibleMessage, marker: string): boolean {\n return message.role === \"system\" && !message.content.startsWith(marker);\n}\n\n/** Carried split: leading system prompts (preserved), the older window, the verbatim tail. */\ninterface TranscriptSplit {\n systemPrompts: CompressibleMessage[];\n head: CompressibleMessage[];\n recent: CompressibleMessage[];\n}\n\n/**\n * Token-budget split (theocode `splitTranscript`): walk from the END accumulating\n * `estimateTokens` until `keepTokens` is exceeded; everything older is the head.\n * Always keeps ≥ 1 recent turn. No system-prompt special-casing (D6).\n */\nfunction selectByTokenBudget(\n messages: CompressibleMessage[],\n keepTokens: number,\n): { head: CompressibleMessage[]; recent: CompressibleMessage[] } {\n let acc = 0;\n let splitIndex = messages.length;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n acc += estimateTokens(messages[i]?.content ?? \"\");\n if (acc > keepTokens && i < messages.length - 1) {\n splitIndex = i + 1;\n break;\n }\n splitIndex = i;\n }\n return { head: messages.slice(0, splitIndex), recent: messages.slice(splitIndex) };\n}\n\n/** Turn-count split (M2): preserve leading system prompts; window the rest by `keepRecent`. */\nfunction splitByRecent(\n messages: CompressibleMessage[],\n keepRecent: number,\n marker: string,\n): TranscriptSplit {\n const systemPrompts = messages.filter((m) => isSystemPrompt(m, marker));\n const rest = messages.filter((m) => !isSystemPrompt(m, marker));\n const { toCompress, toPreserve } = selectCompressionWindow(rest, keepRecent);\n return { systemPrompts, head: toCompress, recent: toPreserve };\n}\n\n/** Options for {@link compactTranscript}. */\nexport interface CompactTranscriptOptions {\n /** Trailing turns preserved verbatim by COUNT (default 6). Ignored when `keepTokens` is set. */\n keepRecent?: number;\n /**\n * Trailing turns preserved verbatim by TOKEN BUDGET (theocode mode). When set,\n * takes precedence over `keepRecent` and disables system-prompt preservation (D6).\n */\n keepTokens?: number;\n /** Checkpoint marker (default {@link CHECKPOINT_MARKER}). Must be non-empty. */\n marker?: string;\n /** Summary template passed to `summarize` (default {@link SUMMARY_TEMPLATE}). */\n summaryTemplate?: string;\n /** Summarize the older window into one turn; if omitted, the older window is dropped. */\n summarize?: (older: CompressibleMessage[], template: string) => Promise<CompressibleMessage>;\n /**\n * When true, a thrown `summarize` returns the ORIGINAL transcript + a structured\n * warn (compaction never loses data). Default false: the error propagates.\n */\n failSafe?: boolean;\n}\n\n/** Sentinel returned by {@link runSummarize} when fail-safe swallowed a throw. */\nconst FAILSAFE_ABORT = Symbol(\"failsafe-abort\");\n\n/** Run the summarizer; on throw, either propagate or (fail-safe) warn + signal abort. */\nasync function runSummarize(\n summarize: NonNullable<CompactTranscriptOptions[\"summarize\"]>,\n head: CompressibleMessage[],\n template: string,\n failSafe: boolean,\n): Promise<CompressibleMessage | typeof FAILSAFE_ABORT> {\n try {\n return await summarize(head, template);\n } catch (err) {\n if (!failSafe) throw err;\n // Unbreakable Rule 8 — never fail silently. The breadcrumb points at the root\n // cause when a summarizer fails every turn and context grows unchecked. The\n // summarizer is caller-supplied, so its error text is routed through\n // `redactSecrets` (ADR D68 — no unredacted output sink in src/).\n console.warn(\n `[compaction] summarizer failed — proceeding uncompacted: ${redactSecrets(err instanceof Error ? err.message : String(err))}`,\n );\n return FAILSAFE_ABORT;\n }\n}\n\n/**\n * Compact a transcript. In `keepRecent` mode (default) the last `keepRecent` turns\n * are kept verbatim and leading system PROMPTS preserved; in `keepTokens` mode the\n * trailing turns within the token budget are kept (no system special-casing, D6).\n * The older window is summarized (via `summarize`, receiving the template) or\n * dropped. Never mutates the input.\n */\nexport async function compactTranscript(\n messages: CompressibleMessage[],\n options: CompactTranscriptOptions = {},\n): Promise<CompressibleMessage[]> {\n const marker = options.marker ?? CHECKPOINT_MARKER;\n assertMarker(marker);\n const split =\n options.keepTokens != null\n ? { systemPrompts: [], ...selectByTokenBudget(messages, options.keepTokens) }\n : splitByRecent(messages, options.keepRecent ?? 6, marker);\n if (split.head.length === 0) {\n return [...messages];\n }\n if (!options.summarize) {\n return [...split.systemPrompts, ...split.recent];\n }\n const template = options.summaryTemplate ?? SUMMARY_TEMPLATE;\n const summary = await runSummarize(\n options.summarize,\n split.head,\n template,\n options.failSafe ?? false,\n );\n if (summary === FAILSAFE_ABORT) {\n return [...messages];\n }\n return [...split.systemPrompts, summary, ...split.recent];\n}\n\n/**\n * Build a checkpoint marker turn (a `system` turn whose content starts with\n * `marker`, default {@link CHECKPOINT_MARKER}). `marker` must be non-empty.\n */\nexport function buildCheckpoint(\n label?: string,\n marker: string = CHECKPOINT_MARKER,\n): CompressibleMessage {\n assertMarker(marker);\n return { role: \"system\", content: marker + (label ?? \"\") };\n}\n\n/** Options for {@link filterFromLatestCheckpoint}. */\nexport interface FilterCheckpointOptions {\n /** Marker to scan for (default {@link CHECKPOINT_MARKER}). */\n marker?: string;\n /**\n * `'after'` (default, M2) returns turns AFTER the latest marker (exclusive);\n * `'from'` (theocode) returns turns FROM the latest marker (inclusive).\n */\n include?: \"after\" | \"from\";\n}\n\n/**\n * Return the turns relative to the most recent checkpoint marker (all turns if\n * none). `include: 'after'` (default) excludes the checkpoint; `'from'` includes\n * it (the summary stands in for the pruned head). Never mutates the input.\n */\nexport function filterFromLatestCheckpoint(\n messages: CompressibleMessage[],\n options: FilterCheckpointOptions = {},\n): CompressibleMessage[] {\n const marker = options.marker ?? CHECKPOINT_MARKER;\n const offset = options.include === \"from\" ? 0 : 1;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n if (messages[i]?.content.startsWith(marker)) {\n return messages.slice(i + offset);\n }\n }\n return [...messages];\n}\n\n/**\n * True iff `err` is a {@link TheokitAgentError} (or subclass) reporting a\n * context-window-exceeded condition (the typed `context_too_long` code). Reads\n * both `code` (set by provider mappers) and `metadata.code` (the preferred field)\n * — never a brittle message regex.\n */\nexport function isContextOverflowError(err: unknown): boolean {\n return (\n err instanceof TheokitAgentError &&\n (err.code === \"context_too_long\" || err.metadata?.code === \"context_too_long\")\n );\n}\n\n/**\n * M77 — the margin is outside `(0, 1]`. Typed, because a margin > 1 would GROW the assumed window,\n * which is the unsafe direction: `shouldCompact` is monotonically decreasing in `contextWindow`, so\n * overestimating it makes the trigger fire too late and the context overflow.\n */\nexport class ContextWindowMarginError extends TheokitAgentError {\n constructor(readonly margin: number) {\n super(\n `context-window margin must be in (0, 1], got ${String(margin)}. ` +\n `A margin above 1 grows the assumed window and delays compaction past the real limit.`,\n { code: \"invalid_context_window_margin\" },\n );\n }\n}\n\n/**\n * M77 — default safety margin on the context window.\n *\n * `0.95` is not a guess: it is the single reference's value. Codex ships\n * `effective_context_window_percent: 95` (`models-manager/src/model_info.rs:158`) and never budgets\n * against 100% of a window. Being MULTIPLICATIVE, it stays conservative at any window size, which a\n * fixed subtraction would not.\n */\nexport const CONTEXT_WINDOW_MARGIN = 0.95;\n\n/**\n * M77 — the floor used ONLY when neither the catalog nor the caller knows the window.\n *\n * Honest about its own weakness. This number has **one** source (the M77 milestone text); the search\n * for a second one failed, because the reference has no fallback at all — Codex returns `Option` and\n * its callers early-return (`core/src/session/turn_context.rs:213`, `core/src/compact_remote.rs:374`).\n *\n * It is conservative only UPWARD. For a model whose real window is larger, budgeting against 128k\n * compacts early — wasteful but safe. For a model whose real window is SMALLER (an 8k or 32k model\n * absent from the catalog), it compacts too late and the context still overflows. That residual risk\n * is real and is why {@link resolveEffectiveContextWindow} never lets this floor compete with a known\n * catalog value, and why the `compaction_fallback` event exists: a surface can show that the budget is\n * a guess instead of the user finding out when the provider rejects the request.\n */\nexport const CONTEXT_WINDOW_FLOOR = 128_000;\n\n/** Where the effective window came from — carried into the M77 structured event. */\nexport type ContextWindowSource = \"override\" | \"catalog\" | \"fallback\";\n\n/** Input to {@link resolveEffectiveContextWindow}. */\nexport interface EffectiveContextWindowInput {\n /** Caller-supplied window, in tokens. Clamped by `catalog` when both are present. */\n readonly override?: number | undefined;\n /** The model's window from the catalog, in tokens. Absent when the model is unknown. */\n readonly catalog?: number | undefined;\n /** Safety margin in `(0, 1]`. Codex uses 0.95 (`model_info.rs:158`). */\n readonly margin: number;\n /** Conservative floor used ONLY when neither `override` nor `catalog` is available. */\n readonly floor?: number | undefined;\n}\n\n/** Result of {@link resolveEffectiveContextWindow}. */\nexport interface EffectiveContextWindow {\n /** The window to budget against, after clamp and margin. */\n readonly window: number;\n /** Which input won — `\"fallback\"` means neither override nor catalog was available. */\n readonly source: ContextWindowSource;\n /** `true` when an `override` above the catalog window was clamped down to it. */\n readonly clamped: boolean;\n}\n\n/**\n * Resolve the window to budget against — the fail-SAFE replacement for reading the catalog directly.\n *\n * Today `post-run-lifecycle.ts` reads `getCatalogModelInfo(model)?.limit?.context` and, when that is\n * `undefined`, auto-compaction simply never fires. That is fail-OPEN: the context grows until the\n * provider rejects the request. (The comment there calls it \"fail-safe\" — M77 corrects it.)\n *\n * Three techniques, two of them borrowed from the single reference:\n *\n * 1. **Override, CLAMPED by the catalog** — Codex `models-manager/src/model_info.rs:26-31` lets\n * config override the window but limits it with `context_window.min(max_context_window)`.\n * Without the clamp, declaring 999k on a 200k model reopens the overflow through another door.\n * 2. **Multiplicative margin** — Codex `model_info.rs:158` (`effective_context_window_percent: 95`)\n * never budgets against 100% of the window. Being multiplicative, it is conservative for ANY\n * window size.\n * 3. **Floor, only when nothing is known** — deliberately NOT a blanket default. A fixed floor is\n * conservative only upward: applied to a small model it would inflate the assumed window and\n * reproduce the very fail-open this function exists to close. Hence the floor never competes\n * with a known catalog value.\n *\n * Pure — no catalog lookup, no I/O. The caller supplies the numbers, mirroring `shouldCompact`.\n */\n/**\n * Teto absoluto de janela declarada, usado quando não há entrada de catálogo para comparar.\n *\n * 2M tokens — acima da maior janela publicada por qualquer provider hoje com folga larga, então\n * não recusa nada legítimo; e bem abaixo de um erro de digitação típico (um zero a mais em 400k dá\n * 4M). O teto existe para transformar um typo em orçamento conservador em vez de em fail-OPEN.\n */\nexport const TETO_ABSOLUTO_DE_JANELA = 2_000_000;\n\nexport function resolveEffectiveContextWindow(\n input: EffectiveContextWindowInput,\n): EffectiveContextWindow {\n if (!(input.margin > 0) || input.margin > 1) {\n throw new ContextWindowMarginError(input.margin);\n }\n\n const withMargin = (raw: number): number => Math.floor(raw * input.margin);\n\n if (input.override !== undefined) {\n // O catálogo é o teto preferido; sem ele vale o TETO ABSOLUTO.\n //\n // M95 (revisão adversarial do M94) — a versão anterior clampeava **apenas** quando havia\n // entrada de catálogo, e a razão de ser da chave `contextWindow` é justamente o modelo que\n // NÃO tem entrada (OpenRouter tem zero). Ou seja: o clamp faltava exatamente no caso que\n // justifica a feature, enquanto a documentação — inclusive um CHANGELOG já publicado —\n // afirmava sem condicional que \"declarar 10M não estoura o provider\".\n //\n // O cenário concreto é um zero a mais: `context_window = 4000000`. O único guarda era um\n // `.positive().int()`, que não limita para cima. O agente nunca compactaria até o provider\n // recusar o turno — o fail-OPEN silencioso que o M77 existe para impedir.\n const teto = input.catalog ?? TETO_ABSOLUTO_DE_JANELA;\n const clamped = input.override > teto;\n return { window: withMargin(clamped ? teto : input.override), source: \"override\", clamped };\n }\n\n if (input.catalog !== undefined) {\n return { window: withMargin(input.catalog), source: \"catalog\", clamped: false };\n }\n\n return { window: withMargin(input.floor ?? 0), source: \"fallback\", clamped: false };\n}\n\n/** Input to {@link shouldCompact}: an estimate, the model's window, and reserved headroom. */\nexport interface ShouldCompactInput {\n /** Estimated token count of the next request (e.g. from {@link estimateTokens}). */\n readonly estimated: number;\n /** The model's total context window, in tokens. */\n readonly contextWindow: number;\n /** Tokens to reserve as headroom (output + safety margin). */\n readonly buffer: number;\n /**\n * Tokens reserved for the model's response generation, SEPARATE from `buffer`.\n * Default 0 — omitting it preserves the legacy\n * `estimated >= contextWindow - buffer` result.\n */\n readonly maxOutput?: number;\n}\n\n/**\n * Tokenizer-free token estimate via the conventional ~4-chars-per-token\n * heuristic: `ceil(text.length / 4)`. `\"\"` → 0; any non-empty text → ≥ 1.\n * A cheap PRE-CALL gate for {@link shouldCompact} — NOT exact tokenization\n * (a consumer needing exactness supplies their own tokenizer). Uses UTF-16\n * `.length` (code units), so multibyte text is approximate.\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Decide BEFORE sending whether to compact: `true` when the `estimated` token\n * count leaves less than `buffer` headroom in the `contextWindow`\n * (`estimated >= contextWindow - buffer`). A `buffer >= contextWindow`\n * (non-positive threshold) always returns `true`. Pure — the caller supplies\n * the window (e.g. from `resolveModelCapabilities`), keeping this decoupled\n * from the per-model catalog.\n */\nexport function shouldCompact(input: ShouldCompactInput): boolean {\n return input.estimated >= input.contextWindow - input.buffer - (input.maxOutput ?? 0);\n}\n"]}
@@ -2,13 +2,13 @@
2
2
 
3
3
  var chunkBV2MWEMV_cjs = require('./chunk-BV2MWEMV.cjs');
4
4
  var chunkMZ5ZRORA_cjs = require('./chunk-MZ5ZRORA.cjs');
5
- var chunkI4QDIQ45_cjs = require('./chunk-I4QDIQ45.cjs');
6
- var chunkHCXDDR6P_cjs = require('./chunk-HCXDDR6P.cjs');
7
- var chunkCVSNCUBU_cjs = require('./chunk-CVSNCUBU.cjs');
5
+ var chunkE33A7YIR_cjs = require('./chunk-E33A7YIR.cjs');
6
+ var chunkFER7UMIC_cjs = require('./chunk-FER7UMIC.cjs');
7
+ var chunkFTRNHGAD_cjs = require('./chunk-FTRNHGAD.cjs');
8
8
  var chunkJLMXKTBX_cjs = require('./chunk-JLMXKTBX.cjs');
9
9
  var chunkN24XBYNX_cjs = require('./chunk-N24XBYNX.cjs');
10
10
  var chunkWPZTYOUX_cjs = require('./chunk-WPZTYOUX.cjs');
11
- var chunkOIYQBUW4_cjs = require('./chunk-OIYQBUW4.cjs');
11
+ var chunk6M6A6WWW_cjs = require('./chunk-6M6A6WWW.cjs');
12
12
  var chunk6JSIEDKL_cjs = require('./chunk-6JSIEDKL.cjs');
13
13
  var chunkG2F67XUR_cjs = require('./chunk-G2F67XUR.cjs');
14
14
  var chunkNINIJCHU_cjs = require('./chunk-NINIJCHU.cjs');
@@ -17,11 +17,11 @@ var chunkVJ26EKGJ_cjs = require('./chunk-VJ26EKGJ.cjs');
17
17
  var chunkGIW4L6HY_cjs = require('./chunk-GIW4L6HY.cjs');
18
18
  var chunkCJVMDRQB_cjs = require('./chunk-CJVMDRQB.cjs');
19
19
  var chunkYLQQX5W2_cjs = require('./chunk-YLQQX5W2.cjs');
20
- var chunkDQSILMWU_cjs = require('./chunk-DQSILMWU.cjs');
20
+ var chunk2DYI7MIF_cjs = require('./chunk-2DYI7MIF.cjs');
21
21
  var chunkWJVHMTKB_cjs = require('./chunk-WJVHMTKB.cjs');
22
22
  var chunkTIZ4TS5V_cjs = require('./chunk-TIZ4TS5V.cjs');
23
23
  var chunkRZQ6E5YZ_cjs = require('./chunk-RZQ6E5YZ.cjs');
24
- var chunkEVADEGM7_cjs = require('./chunk-EVADEGM7.cjs');
24
+ var chunkFX2DAR5R_cjs = require('./chunk-FX2DAR5R.cjs');
25
25
  var chunkVYHJZVL5_cjs = require('./chunk-VYHJZVL5.cjs');
26
26
  var chunkD42XHI4O_cjs = require('./chunk-D42XHI4O.cjs');
27
27
  var chunkDHLZIMP6_cjs = require('./chunk-DHLZIMP6.cjs');
@@ -514,7 +514,7 @@ function registryPath(cwd) {
514
514
  return path.join(cwd, REGISTRY_RELATIVE_PATH);
515
515
  }
516
516
  async function loadRegistry(cwd) {
517
- return chunkOIYQBUW4_cjs.readVersionedJson({
517
+ return chunk6M6A6WWW_cjs.readVersionedJson({
518
518
  path: registryPath(cwd),
519
519
  currentVersion: SCHEMA_VERSION,
520
520
  defaultValue: () => ({}),
@@ -538,7 +538,7 @@ async function saveRegistry(cwd, agents2) {
538
538
  }
539
539
  const path = registryPath(cwd);
540
540
  await chunkYLQQX5W2_cjs.withCwdMutex(`registry:${cwd}`, async () => {
541
- await chunkOIYQBUW4_cjs.writeVersionedJson(path, serialized, SCHEMA_VERSION);
541
+ await chunk6M6A6WWW_cjs.writeVersionedJson(path, serialized, SCHEMA_VERSION);
542
542
  });
543
543
  }
544
544
  function toSerialized(agent) {
@@ -1663,7 +1663,7 @@ var RealCloudRun = class extends FixtureRunBase {
1663
1663
  async consumeStream(response) {
1664
1664
  let finalStatus = "finished";
1665
1665
  let finalText = "";
1666
- for await (const record of chunkCVSNCUBU_cjs.parseSseStream(response.body, this.controller.signal)) {
1666
+ for await (const record of chunkFTRNHGAD_cjs.parseSseStream(response.body, this.controller.signal)) {
1667
1667
  const parsed = safeParse(record.data);
1668
1668
  if (parsed === void 0) continue;
1669
1669
  const update = this.applyRecord(record.event, parsed);
@@ -2238,7 +2238,7 @@ var PersonalityStore = class {
2238
2238
  });
2239
2239
  }
2240
2240
  #filePath() {
2241
- return path.join(chunkOIYQBUW4_cjs.getTheokitHome(this.#cwd), FILE_NAME);
2241
+ return path.join(chunk6M6A6WWW_cjs.getTheokitHome(this.#cwd), FILE_NAME);
2242
2242
  }
2243
2243
  };
2244
2244
 
@@ -2705,11 +2705,11 @@ function buildContextBudgetEvent(model, resolved) {
2705
2705
  // src/internal/runtime/lifecycle/post-run-lifecycle.ts
2706
2706
  function resolveWindowForRun(model, contextWindow) {
2707
2707
  const override = contextWindow !== void 0 && contextWindow > 0 ? contextWindow : void 0;
2708
- return chunkEVADEGM7_cjs.resolveEffectiveContextWindow({
2708
+ return chunkFX2DAR5R_cjs.resolveEffectiveContextWindow({
2709
2709
  ...override !== void 0 ? { override } : {},
2710
2710
  catalog: chunkD42XHI4O_cjs.getCatalogModelInfo(model)?.limit?.context,
2711
- margin: chunkEVADEGM7_cjs.CONTEXT_WINDOW_MARGIN,
2712
- floor: chunkEVADEGM7_cjs.CONTEXT_WINDOW_FLOOR
2711
+ margin: chunkFX2DAR5R_cjs.CONTEXT_WINDOW_MARGIN,
2712
+ floor: chunkFX2DAR5R_cjs.CONTEXT_WINDOW_FLOOR
2713
2713
  });
2714
2714
  }
2715
2715
  async function runPostRunLifecycle(inputs) {
@@ -2733,7 +2733,7 @@ async function runPostRunLifecycle(inputs) {
2733
2733
  try {
2734
2734
  const parcial = await safeConversation(run);
2735
2735
  if (parcial !== void 0) {
2736
- chunkI4QDIQ45_cjs.persistTurnToTranscript(sessionStore, { cwd: workspaceCwd, agentId, model }, agentId, {
2736
+ chunkE33A7YIR_cjs.persistTurnToTranscript(sessionStore, { cwd: workspaceCwd, agentId, model }, agentId, {
2737
2737
  userText,
2738
2738
  conversation: parcial
2739
2739
  });
@@ -2743,11 +2743,11 @@ async function runPostRunLifecycle(inputs) {
2743
2743
  process.stderr.write(`[theokit-sdk] partial transcript write failed (${agentId}): ${msg}
2744
2744
  `);
2745
2745
  }
2746
- await chunkI4QDIQ45_cjs.flushSessionWrites();
2746
+ await chunkE33A7YIR_cjs.flushSessionWrites();
2747
2747
  return;
2748
2748
  }
2749
2749
  if (result.result !== void 0) {
2750
- chunkI4QDIQ45_cjs.appendSessionMessage(agentId, { role: "assistant", text: result.result });
2750
+ chunkE33A7YIR_cjs.appendSessionMessage(agentId, { role: "assistant", text: result.result });
2751
2751
  }
2752
2752
  const conversation = await safeConversation(run);
2753
2753
  const resolvedWindow = resolveWindowForRun(model, contextWindow);
@@ -2758,7 +2758,7 @@ async function runPostRunLifecycle(inputs) {
2758
2758
  }
2759
2759
  const lastRequestUsage = result.usage?.requests?.at(-1)?.totalTokens;
2760
2760
  const usageForTrigger = lastRequestUsage ?? result.usage?.totalTokens;
2761
- chunkI4QDIQ45_cjs.persistTurnToTranscript(
2761
+ chunkE33A7YIR_cjs.persistTurnToTranscript(
2762
2762
  sessionStore,
2763
2763
  { cwd: workspaceCwd, agentId, model },
2764
2764
  agentId,
@@ -2770,7 +2770,7 @@ async function runPostRunLifecycle(inputs) {
2770
2770
  // A janela EFETIVA (após override, clamp e margem) — não a declarada. Trocar por
2771
2771
  // `contextWindow` aqui orçaria contra um número que o clamp já rejeitou.
2772
2772
  contextWindow: janelaEfetiva,
2773
- summarize: chunkCVSNCUBU_cjs.buildDefaultSummarizer({
2773
+ summarize: chunkFTRNHGAD_cjs.buildDefaultSummarizer({
2774
2774
  agentModel: model,
2775
2775
  ...inputs.apiKey !== void 0 ? { apiKey: inputs.apiKey } : {}
2776
2776
  })
@@ -2814,7 +2814,7 @@ async function runPostRunLifecycle(inputs) {
2814
2814
  agentId,
2815
2815
  runId: result.id
2816
2816
  });
2817
- await chunkI4QDIQ45_cjs.flushSessionWrites();
2817
+ await chunkE33A7YIR_cjs.flushSessionWrites();
2818
2818
  }
2819
2819
  async function safeConversation(run) {
2820
2820
  try {
@@ -3571,7 +3571,7 @@ var HISTOGRAM_NAMES = {
3571
3571
  };
3572
3572
  function safeRequire(moduleName) {
3573
3573
  try {
3574
- const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-JPG7NMNH.cjs', document.baseURI).href)));
3574
+ const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-HTO4C32Q.cjs', document.baseURI).href)));
3575
3575
  return r(moduleName);
3576
3576
  } catch {
3577
3577
  return void 0;
@@ -3796,7 +3796,7 @@ var cachedOtel;
3796
3796
  function loadOtel() {
3797
3797
  if (cachedOtel === void 0) {
3798
3798
  try {
3799
- const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-JPG7NMNH.cjs', document.baseURI).href)));
3799
+ const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-HTO4C32Q.cjs', document.baseURI).href)));
3800
3800
  const mod = r("@opentelemetry/api");
3801
3801
  cachedOtel = mod;
3802
3802
  } catch {
@@ -6225,7 +6225,7 @@ function applyToolResultGuard(parts, opts) {
6225
6225
  (p) => (
6226
6226
  // SE7 — guard the TEXT of a tool result (string or the text blocks of a
6227
6227
  // structured content); image blocks pass through untouched.
6228
- p.type === "tool_result" ? { ...p, content: chunkCVSNCUBU_cjs.renderToolResultContentText(p.content, (t) => guardText(t, opts)) } : p
6228
+ p.type === "tool_result" ? { ...p, content: chunkFTRNHGAD_cjs.renderToolResultContentText(p.content, (t) => guardText(t, opts)) } : p
6229
6229
  )
6230
6230
  );
6231
6231
  }
@@ -6880,12 +6880,12 @@ var FallbackLlmClient = class {
6880
6880
  let lastError;
6881
6881
  for (const client of this.clients) {
6882
6882
  if (signal.aborted) throw abortError(signal);
6883
- const attempt = await chunkCVSNCUBU_cjs.tryFirstEvent(client, request, signal, true);
6883
+ const attempt = await chunkFTRNHGAD_cjs.tryFirstEvent(client, request, signal, true);
6884
6884
  if (attempt.kind === "handshake_error") {
6885
6885
  lastError = attempt.error;
6886
6886
  continue;
6887
6887
  }
6888
- return yield* chunkCVSNCUBU_cjs.relayStream(attempt.generator, attempt.firstResult);
6888
+ return yield* chunkFTRNHGAD_cjs.relayStream(attempt.generator, attempt.firstResult);
6889
6889
  }
6890
6890
  if (lastError !== void 0) throw lastError;
6891
6891
  throw new chunkA44COQJJ_cjs.NetworkError("FallbackLlmClient has no providers configured", {
@@ -7392,8 +7392,8 @@ function resolveRunProvider(options) {
7392
7392
  }
7393
7393
  const parsedModel = chunkVYHJZVL5_cjs.parseModelId(options.model?.id);
7394
7394
  const modelInferredProvider = parsedModel.provider !== void 0 && chunkD42XHI4O_cjs.getProviderProfile(parsedModel.provider) !== void 0 ? parsedModel.provider : void 0;
7395
- const keyInferredProvider = chunkCVSNCUBU_cjs.inferProviderFromApiKey(options.agentOptions.apiKey);
7396
- const primary = options.agentOptions.providers?.routes?.[0]?.provider ?? keyInferredProvider ?? modelInferredProvider ?? chunkCVSNCUBU_cjs.detectPrimaryProvider();
7395
+ const keyInferredProvider = chunkFTRNHGAD_cjs.inferProviderFromApiKey(options.agentOptions.apiKey);
7396
+ const primary = options.agentOptions.providers?.routes?.[0]?.provider ?? keyInferredProvider ?? modelInferredProvider ?? chunkFTRNHGAD_cjs.detectPrimaryProvider();
7397
7397
  const effectiveModelId = modelInferredProvider !== void 0 && modelInferredProvider === primary ? parsedModel.name : options.model?.id ?? "claude-sonnet-4-6";
7398
7398
  return { primary, effectiveModelId };
7399
7399
  }
@@ -7422,7 +7422,7 @@ function buildLoopInputs(options, runId, userText, userImages) {
7422
7422
  const credentialPoolStrategy = options.agentOptions.providers?.credentialPoolStrategy;
7423
7423
  const extractToolCallsFromContent = options.agentOptions.providers?.routes?.[0]?.extractToolCallsFromContent;
7424
7424
  const rateLimitSink = options.sendOptions.onRunEvent;
7425
- const chain = chunkCVSNCUBU_cjs.resolveProviderChain({
7425
+ const chain = chunkFTRNHGAD_cjs.resolveProviderChain({
7426
7426
  primary,
7427
7427
  ...fallback !== void 0 ? { fallback } : {},
7428
7428
  ...apiKeys !== void 0 ? { apiKeys } : {},
@@ -7647,7 +7647,7 @@ function buildRealRunOptions(args) {
7647
7647
  };
7648
7648
  }
7649
7649
  async function createFixtureRunHelper(args) {
7650
- const sessionMessages = chunkI4QDIQ45_cjs.getSessionMessages(args.inputs.agentId);
7650
+ const sessionMessages = chunkE33A7YIR_cjs.getSessionMessages(args.inputs.agentId);
7651
7651
  const projectMcpServers = args.inputs.settingSourcesIncludeProject ? await readProjectMcpServers(args.inputs.workspaceCwd) : {};
7652
7652
  return createLocalRun({
7653
7653
  agentId: args.inputs.agentId,
@@ -8096,7 +8096,7 @@ async function embedBatch(opts) {
8096
8096
  body = JSON.parse(text);
8097
8097
  } catch {
8098
8098
  }
8099
- throw chunkCVSNCUBU_cjs.mapOpenAICompatibleError({
8099
+ throw chunkFTRNHGAD_cjs.mapOpenAICompatibleError({
8100
8100
  providerId: opts.providerId,
8101
8101
  status: response.status,
8102
8102
  body,
@@ -8647,7 +8647,7 @@ var LocalAgentMemory = class {
8647
8647
  async runActiveMemoryIfEnabled(userText, priorMessages, telemetry) {
8648
8648
  const cfg = this.options.memory?.activeRecall;
8649
8649
  if (cfg?.enabled !== true || this.index === void 0) return void 0;
8650
- if (this.breaker === void 0) this.breaker = new chunkCVSNCUBU_cjs.CircuitBreaker();
8650
+ if (this.breaker === void 0) this.breaker = new chunkFTRNHGAD_cjs.CircuitBreaker();
8651
8651
  if (this.cache === void 0) this.cache = new ActiveMemoryCache();
8652
8652
  const result = await runActiveMemory({
8653
8653
  userText,
@@ -9051,8 +9051,8 @@ async function localAgentUsePersonality(args) {
9051
9051
  registry,
9052
9052
  store: args.personalityStore,
9053
9053
  invalidateCache: (reason) => args.invalidateCache(reason),
9054
- appendSessionMessage: (msg) => chunkI4QDIQ45_cjs.appendSessionMessage(args.agentId, msg),
9055
- clearSession: () => chunkI4QDIQ45_cjs.clearSession(args.agentId),
9054
+ appendSessionMessage: (msg) => chunkE33A7YIR_cjs.appendSessionMessage(args.agentId, msg),
9055
+ clearSession: () => chunkE33A7YIR_cjs.clearSession(args.agentId),
9056
9056
  opts: args.opts ?? {}
9057
9057
  })
9058
9058
  );
@@ -9400,7 +9400,7 @@ async function executeSendLocked(inputs, message, options) {
9400
9400
  if (inputs.options.onBeforeSend !== void 0) {
9401
9401
  await inputs.options.onBeforeSend({
9402
9402
  conversationId: inputs.agentId,
9403
- previousMessageCount: chunkI4QDIQ45_cjs.getSessionMessages(inputs.agentId).length
9403
+ previousMessageCount: chunkE33A7YIR_cjs.getSessionMessages(inputs.agentId).length
9404
9404
  });
9405
9405
  }
9406
9406
  await inputs.runPreHook(userText);
@@ -9412,8 +9412,8 @@ async function executeSendLocked(inputs, message, options) {
9412
9412
  userText,
9413
9413
  sendOptions: options
9414
9414
  });
9415
- const priorMessages = [...chunkI4QDIQ45_cjs.getSessionMessages(inputs.agentId)];
9416
- chunkI4QDIQ45_cjs.appendSessionMessage(inputs.agentId, { role: "user", text: userText });
9415
+ const priorMessages = [...chunkE33A7YIR_cjs.getSessionMessages(inputs.agentId)];
9416
+ chunkE33A7YIR_cjs.appendSessionMessage(inputs.agentId, { role: "user", text: userText });
9417
9417
  await persistMemoryFactIfWritePrompt(inputs.workspaceCwd, inputs.options.memory, userText);
9418
9418
  const memoryFacts = await readMemoryForSend(inputs.workspaceCwd, inputs.options.memory);
9419
9419
  const portPathActive = shouldUsePortMemoryPath();
@@ -9512,6 +9512,10 @@ function registerRunAsTask(run, agentId, taskOpt, userText) {
9512
9512
  }
9513
9513
 
9514
9514
  // src/internal/local-agent/local-agent.ts
9515
+ async function disposeSessionStore(store) {
9516
+ const d = store.dispose;
9517
+ if (typeof d === "function") await d.call(store);
9518
+ }
9515
9519
  var LocalAgent = class {
9516
9520
  agentId;
9517
9521
  model;
@@ -9575,7 +9579,7 @@ var LocalAgent = class {
9575
9579
  this.options = options;
9576
9580
  this.workspaceCwd = resolveCwd(options.local?.cwd);
9577
9581
  this.transcriptBaseDir = resolveBaseDir(options.local?.baseDir);
9578
- this.sessionStore = options.local?.sessionStore ?? new chunkHCXDDR6P_cjs.FsSessionStore({ baseDir: this.transcriptBaseDir, cwd: this.workspaceCwd });
9582
+ this.sessionStore = options.local?.sessionStore ?? new chunkFER7UMIC_cjs.FsSessionStore({ baseDir: this.transcriptBaseDir, cwd: this.workspaceCwd });
9579
9583
  this.settingSourcesIncludeProject = includesSetting(options, "project");
9580
9584
  this.settingSourcesIncludePlugins = includesSetting(options, "plugins");
9581
9585
  const sub = bootstrapSubmanagers({
@@ -9623,7 +9627,7 @@ var LocalAgent = class {
9623
9627
  this.settingSourcesIncludeProject,
9624
9628
  this.options.agents
9625
9629
  );
9626
- await chunkI4QDIQ45_cjs.hydrateSession(this.agentId, { store: this.sessionStore, cwd: this.workspaceCwd });
9630
+ await chunkE33A7YIR_cjs.hydrateSession(this.agentId, { store: this.sessionStore, cwd: this.workspaceCwd });
9627
9631
  await this.personalityStore.hydrate(this.agentId);
9628
9632
  }
9629
9633
  /** T4.2 — expose PluginManager so agent-loop can fire pre_tool_call hooks. @internal */
@@ -9816,8 +9820,10 @@ var LocalAgent = class {
9816
9820
  this.lifecycleAbortController.abort();
9817
9821
  await chunkYLQQX5W2_cjs.withCwdMutex(`agent-send:${this.agentId}`, () => Promise.resolve());
9818
9822
  disposeSessionMcpClients(this.agentId);
9819
- await chunkI4QDIQ45_cjs.flushSessionWrites();
9823
+ await chunkE33A7YIR_cjs.flushSessionWrites();
9820
9824
  await flushRegistrySaves(this.workspaceCwd);
9825
+ await disposeSessionStore(this.sessionStore);
9826
+ chunkE33A7YIR_cjs.descartarSessao(this.workspaceCwd, this.agentId);
9821
9827
  }
9822
9828
  [Symbol.asyncDispose]() {
9823
9829
  return this.dispose();
@@ -9884,7 +9890,7 @@ function resolveCwd(cwd) {
9884
9890
  return (Array.isArray(cwd) ? cwd[0] : cwd) ?? process.cwd();
9885
9891
  }
9886
9892
  function resolveBaseDir(baseDir) {
9887
- return baseDir === void 0 ? chunkDQSILMWU_cjs.defaultBaseDir() : chunkDQSILMWU_cjs.expandTilde(baseDir);
9893
+ return baseDir === void 0 ? chunk2DYI7MIF_cjs.defaultBaseDir() : chunk2DYI7MIF_cjs.expandTilde(baseDir);
9888
9894
  }
9889
9895
  function includesSetting(options, source) {
9890
9896
  const sources = options.local?.settingSources;
@@ -10024,7 +10030,7 @@ function resolveAgentPersistenceCwd(options) {
10024
10030
  return process.cwd();
10025
10031
  }
10026
10032
  async function rehydrateExistingAgent(agentId, existing, options) {
10027
- await chunkCVSNCUBU_cjs.discoverProviderPlugins();
10033
+ await chunkFTRNHGAD_cjs.discoverProviderPlugins();
10028
10034
  await validateRehydratedAgent(agentId, existing);
10029
10035
  const mergedLocal = options.local !== void 0 && existing.options.local !== void 0 ? { ...existing.options.local, ...options.local } : options.local ?? existing.options.local;
10030
10036
  const mergedOptions = {
@@ -10152,7 +10158,7 @@ var Agent = class _Agent {
10152
10158
  pluginCount: enabledPluginNames(options.plugins).length
10153
10159
  });
10154
10160
  try {
10155
- await chunkCVSNCUBU_cjs.discoverProviderPlugins();
10161
+ await chunkFTRNHGAD_cjs.discoverProviderPlugins();
10156
10162
  const agent = await runCreateUnderSpan(options, span);
10157
10163
  return agent;
10158
10164
  } catch (err) {
@@ -10421,9 +10427,9 @@ var Agent = class _Agent {
10421
10427
  `No local agent "${agentId}" registered \u2014 compact targets local sessions.`
10422
10428
  );
10423
10429
  }
10424
- const { compactSessionTranscript, buildDefaultSummarizer: buildDefaultSummarizer2 } = await import('./compact-session-OKXLKJIS.cjs');
10430
+ const { compactSessionTranscript, buildDefaultSummarizer: buildDefaultSummarizer2 } = await import('./compact-session-24PK2G4M.cjs');
10425
10431
  const { cwd, model, store } = await abrirStoreLocal(reg);
10426
- return chunkI4QDIQ45_cjs.enqueueSessionWrite(
10432
+ return chunkE33A7YIR_cjs.enqueueSessionWrite(
10427
10433
  cwd,
10428
10434
  agentId,
10429
10435
  () => compactSessionTranscript({
@@ -10457,7 +10463,7 @@ var Agent = class _Agent {
10457
10463
  `No local agent "${agentId}" registered \u2014 injectSessionTurn targets local sessions.`
10458
10464
  );
10459
10465
  }
10460
- const { injectSessionTurn } = await import('./inject-session-24FJ65LP.cjs');
10466
+ const { injectSessionTurn } = await import('./inject-session-343WIDCM.cjs');
10461
10467
  const { cwd, model, store } = await abrirStoreLocal(reg);
10462
10468
  await injectSessionTurn({
10463
10469
  store,
@@ -10504,8 +10510,8 @@ async function abrirStoreLocal(reg) {
10504
10510
  const cwd = reg.cwd ?? process.cwd();
10505
10511
  const optModel = reg.options.model;
10506
10512
  const model = reg.model?.id ?? (typeof optModel === "string" ? optModel : optModel?.id) ?? "unknown";
10507
- const { FsSessionStore: FsSessionStore2 } = await import('./fs-session-store-DNAJ6RQG.cjs');
10508
- const { defaultBaseDir: defaultBaseDir2, expandTilde: expandTilde2 } = await import('./session-transcript-F5OXXO6G.cjs');
10513
+ const { FsSessionStore: FsSessionStore2 } = await import('./fs-session-store-YMBSJ5Y7.cjs');
10514
+ const { defaultBaseDir: defaultBaseDir2, expandTilde: expandTilde2 } = await import('./session-transcript-JXFMPLOT.cjs');
10509
10515
  const baseDir = reg.options.local?.baseDir !== void 0 ? expandTilde2(reg.options.local.baseDir) : defaultBaseDir2();
10510
10516
  return { cwd, model, store: new FsSessionStore2({ baseDir, cwd }) };
10511
10517
  }
@@ -10525,5 +10531,5 @@ exports.isFixtureApiKey = isFixtureApiKey;
10525
10531
  exports.openRouterMemoryEmbeddingProviderAdapter = openRouterMemoryEmbeddingProviderAdapter;
10526
10532
  exports.resolveApiKey = resolveApiKey;
10527
10533
  exports.shouldUseFixtureMode = shouldUseFixtureMode;
10528
- //# sourceMappingURL=chunk-JPG7NMNH.cjs.map
10529
- //# sourceMappingURL=chunk-JPG7NMNH.cjs.map
10534
+ //# sourceMappingURL=chunk-HTO4C32Q.cjs.map
10535
+ //# sourceMappingURL=chunk-HTO4C32Q.cjs.map