@x-otto/memory 0.1.0-alpha.13 → 0.1.0-alpha.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
- import{createLogger as e}from"@x-otto/shared";import{normalizeEnvFraction as t}from"@x-otto/env";import{CONVERSATION_SUMMARY_PREFIX as n}from"@x-otto/interchange";import{existsSync as r,statSync as i}from"node:fs";import{basename as a,dirname as o,extname as s,join as c,relative as l}from"node:path";import{readdir as u,stat as d}from"node:fs/promises";import{FileAppendLog as f,createPersistence as p,saveDocument as m}from"@x-otto/persistence";const h=8e3;function g(e){let t=0;for(let n of e)/[\u3000-\u9fff\uff00-\uffef]/.test(n)&&t++;return Math.ceil(t+(e.length-t)/4)}function _(e,t){if(t<=0)return``;if(g(e)<=t)return e;let n=Array.from(e),r=0,i=n.length,a=``;for(;r<=i;){let e=Math.floor((r+i)/2),o=n.slice(0,e).join(``);g(o)<=t?(a=o,r=e+1):i=e-1}return a}function v(e){return e.endsWith(`/MEMORY.md`)}function y(e,t,n){if(!t||t.size===0)return{text:e,folded:0};let r=[],i=0,a=n-12096e5;for(let n of e.split(`
1
+ import{createLogger as e}from"@x-otto/shared";import{normalizeEnvFraction as t}from"@x-otto/env";import{CONVERSATION_SUMMARY_PREFIX as n}from"@x-otto/interchange";import{existsSync as r,statSync as i}from"node:fs";import{basename as a,dirname as o,extname as s,join as c,relative as l}from"node:path";import{readdir as u,stat as d}from"node:fs/promises";import{createPersistence as f,saveDocument as p}from"@x-otto/persistence";const m=8e3;function h(e){let t=0;for(let n of e)/[\u3000-\u9fff\uff00-\uffef]/.test(n)&&t++;return Math.ceil(t+(e.length-t)/4)}function g(e,t){if(t<=0)return``;if(h(e)<=t)return e;let n=Array.from(e),r=0,i=n.length,a=``;for(;r<=i;){let e=Math.floor((r+i)/2),o=n.slice(0,e).join(``);h(o)<=t?(a=o,r=e+1):i=e-1}return a}function _(e){return e.endsWith(`/MEMORY.md`)}function v(e,t,n){if(!t||t.size===0)return{text:e,folded:0};let r=[],i=0,a=n-12096e5;for(let n of e.split(`
2
2
  `)){let e=n.match(/^-\s*\[[^\]]+\]\(memory\/([^)]+\.md)\)/);if(!e){r.push(n);continue}let o=t.get(`memory/${e[1]}`);o!==void 0&&o>=a?r.push(n):i++}return i>0&&r.push(`+ ${i} older entr${i>1?`ies`:`y`} — use memory_read to list/fetch`),{text:r.join(`
3
- `),folded:i}}function b(e,t=h,n,r=Date.now()){if(e.size===0)return``;let i=[`<agent_memory>`],a=0,o=0;for(let[s,c]of e){let e=(v(s)?y(c,n,r).text:c).trim();if(!e)continue;let l=t-a;if(l<=0){o++;continue}let u=g(e);if(u<=l)i.push(`# ${s}`),i.push(e),i.push(``),a+=u;else{let n=_(e,l);i.push(`# ${s}`),i.push(n),i.push(`\n> ⚠ [truncated — content exceeded the memory injection budget (${t} tokens); remainder omitted]`),i.push(``),a=t}}return o>0&&(i.push(`> ⚠ [${o} additional memory source(s) omitted — total injection budget (${t} tokens) reached]`),i.push(``)),i.push(`</agent_memory>`),i.push(``),i.push(`<memory_guidelines>
3
+ `),folded:i}}function y(e,t=m,n,r=Date.now()){if(e.size===0)return``;let i=[`<agent_memory>`],a=0,o=0;for(let[s,c]of e){let e=(_(s)?v(c,n,r).text:c).trim();if(!e)continue;let l=t-a;if(l<=0){o++;continue}let u=h(e);if(u<=l)i.push(`# ${s}`),i.push(e),i.push(``),a+=u;else{let n=g(e,l);i.push(`# ${s}`),i.push(n),i.push(`\n> ⚠ [truncated — content exceeded the memory injection budget (${t} tokens); remainder omitted]`),i.push(``),a=t}}return o>0&&(i.push(`> ⚠ [${o} additional memory source(s) omitted — total injection budget (${t} tokens) reached]`),i.push(``)),i.push(`</agent_memory>`),i.push(``),i.push(`<memory_guidelines>
4
4
  Persist durable facts via the memory_record tool — never edit/write .otto state files directly (protected; RFC-228). Scopes: 'workspace' (default, portable facts), 'local' (machine-specific, never synced), 'project-shared' (team-visible AGENTS.md conventions).
5
5
 
6
6
  Remember: user preferences and constraints; patterns learned from feedback; key non-sensitive tool parameters; project-specific build/test commands.
7
7
  Do NOT remember: temporary task details; one-off Q&A; API keys, passwords, or sensitive information; casual conversation.
8
8
  </memory_guidelines>`),i.join(`
9
- `)}const x=`## Goal
9
+ `)}const b=`## Goal
10
10
  [What is the user trying to accomplish?]
11
11
 
12
12
  ## Constraints & Preferences
@@ -34,17 +34,17 @@ Do NOT remember: temporary task details; one-off Q&A; API keys, passwords, or se
34
34
  - [Files that were modified]
35
35
 
36
36
  ## Critical Context
37
- - [Any critical context needed to continue the work]`,S=`IMPORTANT:
37
+ - [Any critical context needed to continue the work]`,x=`IMPORTANT:
38
38
  - Preserve exact file paths, function names, error messages, and code snippets
39
39
  - Keep technical details precise — do not generalize
40
40
  - Include all tool call results that affect the current state
41
- - Note any pending or failed operations`,C=`You are a conversation summarizer for an AI coding assistant. Your task is to create a structured summary of the conversation that preserves all information needed to continue the work.
41
+ - Note any pending or failed operations`,S=`You are a conversation summarizer for an AI coding assistant. Your task is to create a structured summary of the conversation that preserves all information needed to continue the work.
42
42
 
43
43
  Create the summary in the following format:
44
44
 
45
- ${x}
45
+ ${b}
46
46
 
47
- ${S}`,w=`You are updating an existing conversation summary with new information. The existing summary and new messages are provided below.
47
+ ${x}`,C=`You are updating an existing conversation summary with new information. The existing summary and new messages are provided below.
48
48
 
49
49
  Produce a single UPDATED summary that stays BOUNDED — a summary that grows without limit across rounds eventually gets hard-truncated by the output cap, silently losing whatever fell past the limit. Keep it tight by actively triaging, not by appending.
50
50
 
@@ -63,7 +63,7 @@ Rules:
63
63
  - Move completed "In Progress" items to "Done", then compress "Done" per the above
64
64
  - Merge new work items, decisions, and context; do not simply append
65
65
  - Keep the same structured format (including "All User Requests")
66
- - If any information conflicts, use the newer version`,ee=`You are summarizing the FIRST PART of an assistant turn that was split during conversation compaction. The remaining part of this turn is still in the conversation.
66
+ - If any information conflicts, use the newer version`,w=`You are summarizing the FIRST PART of an assistant turn that was split during conversation compaction. The remaining part of this turn is still in the conversation.
67
67
 
68
68
  Create a brief summary in this format:
69
69
 
@@ -76,38 +76,38 @@ Create a brief summary in this format:
76
76
  ## Context for Remaining Messages
77
77
  - [Information needed to understand the remaining suffix messages]
78
78
 
79
- Keep it concise — this will be prepended to the remaining messages of this turn.`,te=`You are a conversation summarizer for an AI coding assistant. You are summarizing the EARLIER portion of a conversation. The most recent messages are kept verbatim and will follow your summary unchanged — they are shown to you below in <preserved_tail_context> FOR REFERENCE ONLY.
79
+ Keep it concise — this will be prepended to the remaining messages of this turn.`,ee=`You are a conversation summarizer for an AI coding assistant. You are summarizing the EARLIER portion of a conversation. The most recent messages are kept verbatim and will follow your summary unchanged — they are shown to you below in <preserved_tail_context> FOR REFERENCE ONLY.
80
80
 
81
81
  Your summary and those preserved recent messages together become the assistant's full context going forward.
82
82
 
83
83
  Create the summary in the following format:
84
84
 
85
- ${x}
85
+ ${b}
86
86
 
87
87
  ## Context the Preserved Tail Depends On
88
88
  - [Facts a reader MUST know to correctly understand the preserved recent messages shown in <preserved_tail_context>: decisions already made, file paths and their current state, conventions/constraints agreed earlier, mistakes already corrected, and any partially-done work those recent messages continue. Read the preserved tail, then look BACK through the earlier conversation for what it silently relies on. This section is the whole point of this summary — be specific.]
89
89
 
90
- ${S}
90
+ ${x}
91
91
  - Do NOT summarize the content of <preserved_tail_context> — it is kept verbatim after your summary and re-describing it wastes your budget. Use it ONLY to work out which parts of the EARLIER conversation it depends on.
92
- - Summarize ONLY the conversation inside <conversation>.`,ne=`You are summarizing ONE SEGMENT of a longer conversation for an AI coding assistant. This is a partial view — you are NOT seeing the whole conversation, and other segments are being summarized separately. Your segment summary will later be merged with the others.
92
+ - Summarize ONLY the conversation inside <conversation>.`,te=`You are summarizing ONE SEGMENT of a longer conversation for an AI coding assistant. This is a partial view — you are NOT seeing the whole conversation, and other segments are being summarized separately. Your segment summary will later be merged with the others.
93
93
 
94
94
  Create a concise summary of THIS SEGMENT in the following format:
95
95
 
96
- ${x}
96
+ ${b}
97
97
 
98
- ${S}
98
+ ${x}
99
99
  - Do NOT emit conclusions that require seeing the whole conversation (e.g. a single global "next step"). Report only what THIS segment establishes; the merge step will reconcile across segments.
100
- - If <preserved_tail_context> is present, it holds the most recent messages, kept verbatim outside this compaction. Do NOT summarize it — use it ONLY to judge which parts of THIS segment it depends on, and make sure those parts survive into your summary. Summarize ONLY the content inside <conversation>.`,re=`You are merging several segment summaries of one conversation into a single coherent summary for an AI coding assistant. Each input below is a summary of a different (chronological) segment of the same conversation.
100
+ - If <preserved_tail_context> is present, it holds the most recent messages, kept verbatim outside this compaction. Do NOT summarize it — use it ONLY to judge which parts of THIS segment it depends on, and make sure those parts survive into your summary. Summarize ONLY the content inside <conversation>.`,ne=`You are merging several segment summaries of one conversation into a single coherent summary for an AI coding assistant. Each input below is a summary of a different (chronological) segment of the same conversation.
101
101
 
102
102
  Reconcile them into one summary in the following format:
103
103
 
104
- ${x}
104
+ ${b}
105
105
 
106
- ${S}
106
+ ${x}
107
107
  - Resolve conflicts in favour of the LATER segment.
108
- - Merge duplicate items; do not simply concatenate.`;function T(e,t,n,r){let i=[];return r?.variant===`segment`?i.push(ne):t?(i.push(w),i.push(`\n<existing_summary>\n${t}\n</existing_summary>`),r?.preservedCount&&r.preservedCount>0&&i.push(ie(r.preservedCount))):r?.variant===`preserved-tail`?i.push(te):i.push(C),n&&i.push(`\n<additional_instructions>\n${n}\n</additional_instructions>`),r?.preservedTailReference&&i.push(`\n<preserved_tail_context>\n${r.preservedTailReference}\n</preserved_tail_context>`),r?.omitConversation||i.push(`\n<conversation>\n${e}\n</conversation>`),i.join(`
109
- `)}function ie(e){return`\nNOTE: The ${e} most recent message(s) are kept verbatim and will follow your summary — do NOT re-summarize them; focus on the earlier conversation and what those recent messages depend on.`}function ae(e,t,n){let r=[re];return t&&r.push(`\n<existing_summary>\n${t}\n</existing_summary>`),n&&r.push(`\n<additional_instructions>\n${n}\n</additional_instructions>`),r.push(`\n<segment_summaries>\n${e}\n</segment_summaries>`),r.join(`
110
- `)}function oe(e){return`${ee}\n\n<turn_prefix>\n${e}\n</turn_prefix>`}const se=`You are a learning extractor for an AI coding assistant. Read the conversation below and extract durable, cross-session "lessons" — operational knowledge that will help the assistant do better on FUTURE, unrelated sessions in this project.
108
+ - Merge duplicate items; do not simply concatenate.`;function T(e,t,n,r){let i=[];return r?.variant===`segment`?i.push(te):t?(i.push(C),i.push(`\n<existing_summary>\n${t}\n</existing_summary>`),r?.preservedCount&&r.preservedCount>0&&i.push(re(r.preservedCount))):r?.variant===`preserved-tail`?i.push(ee):i.push(S),n&&i.push(`\n<additional_instructions>\n${n}\n</additional_instructions>`),r?.preservedTailReference&&i.push(`\n<preserved_tail_context>\n${r.preservedTailReference}\n</preserved_tail_context>`),r?.omitConversation||i.push(`\n<conversation>\n${e}\n</conversation>`),i.join(`
109
+ `)}function re(e){return`\nNOTE: The ${e} most recent message(s) are kept verbatim and will follow your summary — do NOT re-summarize them; focus on the earlier conversation and what those recent messages depend on.`}function ie(e,t,n){let r=[ne];return t&&r.push(`\n<existing_summary>\n${t}\n</existing_summary>`),n&&r.push(`\n<additional_instructions>\n${n}\n</additional_instructions>`),r.push(`\n<segment_summaries>\n${e}\n</segment_summaries>`),r.join(`
110
+ `)}function ae(e){return`${w}\n\n<turn_prefix>\n${e}\n</turn_prefix>`}const oe=`You are a learning extractor for an AI coding assistant. Read the conversation below and extract durable, cross-session "lessons" — operational knowledge that will help the assistant do better on FUTURE, unrelated sessions in this project.
111
111
 
112
112
  A lesson captures a reusable cause→action:
113
113
  - "trigger": the situation/context that should recall this lesson (when it applies)
@@ -127,41 +127,41 @@ DO NOT save these (they pollute recall):
127
127
  - Secrets, API keys, passwords, tokens, or any sensitive value
128
128
 
129
129
  Output ONLY a JSON array, nothing else. Each element: {"trigger": string, "insight": string, "tags": string[]}.
130
- If there is nothing durable worth saving, output exactly: []`;function ce(e){return`${se}\n\n<conversation>\n${e}\n</conversation>`}function le(e,t){return`Earlier conversation history has been compacted into the summary below. If you need details the summary does not cover, call the memory_archive_read tool with archive id "${e}" to pull back the original messages.
130
+ If there is nothing durable worth saving, output exactly: []`;function se(e){return`${oe}\n\n<conversation>\n${e}\n</conversation>`}function ce(e,t){return`Earlier conversation history has been compacted into the summary below. If you need details the summary does not cover, call the memory_archive_read tool with archive id "${e}" to pull back the original messages.
131
131
 
132
132
  <summary>
133
133
  ${t}
134
- </summary>`}function ue(e){return`[Low-fidelity summary — only about ${Math.max(0,Math.round(e*100))}% of the original history could be fed into summarization. Significant details are missing. Treat this summary as incomplete: if you need details it does not cover, call memory_archive_read with the archive id below to pull back the original messages, rather than guessing or asking the user to repeat themselves.]`}const E=e(`@x-otto/memory:persistent`),de=[{path:`~/.otto/AGENTS.md`,writable:!0},{path:`./.otto/AGENTS.md`,writable:!0},{path:`./AGENTS.md`,writable:!1}],fe=new Set([`## 代码风格与命名约定`,`## 发布与包管理注意事项`,`## 安全与配置建议`]);function pe(e){let t=e.split(`
135
- `),n=[],r=!1;for(let e of t){if(e.match(/^## (.+)/)){r=fe.has(e.trim()),r||n.push(e);continue}r||n.push(e)}return n.join(`
136
- `)}const me=/<!-- otto-memory:start slug="([^"]+)" -->/g;function he(e){let t=new Set;for(let n of e.matchAll(me))t.add(n[1]??``);return t}function ge(e){let t=new Set;for(let n of e.matchAll(/<!-- otto-memory:start slug="[^"]+" -->\n## ([^\n]+)/g))t.add((n[1]??``).trim());return t}function _e(e){return e.replace(/[^a-z0-9一-鿿]+/gi,``).toLowerCase()}function ve(e,t){if(!t||!e)return e;let n=he(t),r=new Set([...ge(t)].map(e=>_e(e)));if(n.size===0&&r.size===0)return e;let i=e.replace(/<!-- otto-memory:start slug="([^"]+)" -->[\s\S]*?<!-- otto-memory:end slug="\1" -->\n?/g,(e,t)=>n.has(t)?``:e).split(`
137
- `),a=[],o=!1;for(let e of i){let t=e.match(/^\s*-\s+\*\*([^*]+)\*\*/);if(t&&r.has(_e(t[1]??``))){o=!0;continue}if(o){(e.trim()===``||/^\s*- /.test(e)||e.startsWith(`## `))&&(o=!1,a.push(e));continue}a.push(e)}return a.join(`
138
- `)}var ye=class{memories=new Map;unwatch;constructor(e,t=de,n){this.store=e,this.sources=t,this.entryMtimes=n}async load(){this.memories=await this.store.load(this.sources);let e=this.memories.get(`./.otto/AGENTS.md`),t=this.sources.find(e=>e.path===`./AGENTS.md`)?.path;if(t&&e&&this.memories.has(t)){let n=this.memories.get(t)??``,r=ve(n,e);r!==n&&this.memories.set(t,r)}if(t&&this.memories.has(t)){let e=this.memories.get(t)??``,n=pe(e);n!==e&&this.memories.set(t,n)}E.info(`Loaded ${this.memories.size} memory source(s)`)}async reload(){await this.load()}getInjection(){return b(this.memories,h,this.entryMtimes)}getMemories(){return this.memories}async write(e,t){let n=this.sources.find(t=>t.path===e);if(!n)throw Error(`Unknown memory source: ${e}`);if(!n.writable)throw Error(`Memory source is read-only: ${e}`);await this.store.write(e,t),this.memories.set(e,t),E.info(`Memory source written: ${e}`)}watching(){this.unwatch||!this.store.watch||(this.unwatch=this.store.watch(this.sources,e=>{E.info(`Memory source changed: ${e}, reloading...`),this.reload()}))}stop(){this.unwatch?.(),this.unwatch=void 0}dispose(){this.stop(),this.memories.clear()}},be=class{data=new Map;set(e,t){this.data.set(e,t)}async load(e){let t=new Map;for(let n of e){let e=this.data.get(n.path);e!==void 0&&t.set(n.path,e)}return t}async write(e,t){this.data.set(e,t)}},xe=class{cwd;homeDirOverride;constructor(e=process.cwd(),t){this.cwd=e,this.homeDirOverride=t}async load(e){let{readFile:t}=await import(`node:fs/promises`),{resolve:n,isAbsolute:r}=await import(`node:path`),{homedir:i}=await import(`node:os`),a=new Map;for(let o of e){let e=this.resolvePath(o.path,n,r,i);try{let n=await t(e,`utf-8`);a.set(o.path,n)}catch{}}return a}async write(e,t){let{mkdir:n}=await import(`node:fs/promises`),{resolve:r,dirname:i,isAbsolute:a}=await import(`node:path`),{homedir:o}=await import(`node:os`),{atomicWriteFile:s}=await import(`@x-otto/persistence`),c=this.resolvePath(e,r,a,o);await n(i(c),{recursive:!0}),await s(c,t)}resolvePath(e,t,n,r){let i=this.homeDirOverride??r(),a=e.startsWith(`~/`)?e.replace(`~/`,`${i}/`):e;return n(a)?a:t(this.cwd,a)}};const Se=e(`@x-otto/memory:token-estimator`);let D=null,O=null;async function Ce(){if(!D){if(O){await O;return}O=(async()=>{try{let{getEncoding:e}=await import(`js-tiktoken`),t=e(`cl100k_base`);D={encode:e=>typeof e!=`string`||e.length===0?[]:t.encode(e)},Se.info(`Tokenizer loaded: cl100k_base`)}catch(e){Se.warn(`Failed to load js-tiktoken, falling back to heuristic: %s`,e.message),D=null}finally{O=null}})(),await O}}const we=2e3;function Te(e){return e>=33&&e<=47||e>=58&&e<=64||e>=91&&e<=96||e>=123&&e<=126}function Ee(e){return e>=12352&&e<=12543||e>=13312&&e<=19903||e>=19968&&e<=40959||e>=63744&&e<=64255||e>=44032&&e<=55203||e>=65280&&e<=65519||e>=131072&&e<=191471}function k(e){let t=0,n=0,r=0;for(let i of e){let e=i.codePointAt(0)??0;Ee(e)?t+=1:Te(e)?n+=1:r+=1}return Math.ceil(t*1+n*.5+r*.25)}function De(e,t){let n=1;for(let r=1;r<e.length;r++)if(e.charCodeAt(r)===e.charCodeAt(r-1)){if(n++,n>=t)return!0}else n=1;return!1}function A(e){if(D){if(e.length>1e5||De(e,64))return k(e);try{return D.encode(e).length}catch{return k(e)}}return O||Ce().catch(()=>{}),k(e)}function Oe(e){return e?e.length<=6?e:e.slice(-6):`?`}function j(e){return typeof e.content==`string`?e.content:Array.isArray(e.content)?e.content.map(e=>{switch(e.type){case`text`:return e.text;case`thinking`:return e.text;case`tool_call`:return`[call#${Oe(e.id)} ${e.name}](${JSON.stringify(e.arguments)})`;case`image`:return`[image]`;default:return``}}).filter(Boolean).join(`
139
- `):JSON.stringify(e)}const ke=new WeakMap;function M(e,t=A){let n=t===A&&D!==null&&typeof e==`object`&&!!e;if(n){let t=ke.get(e);if(t!==void 0)return t}let r;if(Array.isArray(e.content)){r=4;for(let n of e.content)switch(n.type){case`text`:case`thinking`:r+=t(n.text);break;case`tool_call`:r+=t(`${n.name}(${JSON.stringify(n.arguments)})`);break;case`image`:r+=we;break;default:break}}else r=4+t(j(e));return n&&ke.set(e,r),r}function N(e,t=A){let n=0;for(let r of e)n+=M(r,t);return n}function Ae(e){return e.role===`assistant`}function P(e,t=A){let n=-1,r=0;for(let t=e.length-1;t>=0;t--){let i=e[t];if(Ae(i)&&i.usage){n=t,r=(i.usage.cacheReadTokens??0)+(i.usage.cacheWriteTokens??0)+i.usage.inputTokens+i.usage.outputTokens;break}}let i=0,a=0;if(n>=0){for(let r=0;r<=n;r++)a+=M(e[r],t);for(let r=n+1;r<e.length;r++)i+=M(e[r],t)}else i=N(e,t);let o=r+i,s=n>=0?Math.max(0,r-a):0,c=Math.max(0,o-s);return{total:o,fromUsage:r,fromEstimate:i,lastUsageIndex:n,derivedPrefix:s,bodyAfterPrefix:c}}const je=.1,F=16384,Me=t(process.env.OTTO_MEMORY_COMPACTION_HARD_CEILING_FRACTION,.9),Ne=24e3,Pe=.6,Fe=.15,Ie=2e4,Le=2e3,Re=`write`,ze=`edit`,Be=`read`,Ve=`grep`,He=`find`,Ue=`read_file`,We=`grep_search`,Ge=`file_search`,Ke=t(process.env.OTTO_MEMORY_COVERAGE_WARN_THRESHOLD,.7),qe=t(process.env.OTTO_MEMORY_COVERAGE_ERROR_THRESHOLD,.5),Je=t(process.env.OTTO_MEMORY_COVERAGE_FLOOR_THRESHOLD,.3),Ye=[Re,ze],I=[Be,Ve,He,Ue,We,Ge,`bash`,`bash_output`,`web_search`,`web_fetch`];function L(e){return{compaction:{enabled:!0,trigger:[`headroom`,Math.min(F,e.maxOutput)+Ne],keepRecent:[`fraction`,je],reserveTokens:Math.min(F,e.maxOutput)},prune:{trigger:[`fraction`,Pe],protect:[`fraction`,Fe],minimum:Ie,regenerableTools:[...I],protectedTools:[],truncateTools:[...Ye],truncateMaxLength:Le}}}const R={enabled:!0,trigger:[`headroom`,F+Ne],keepRecent:[`fraction`,je],reserveTokens:F,cacheRetention:`long`},z={trigger:[`fraction`,Pe],protect:[`fraction`,Fe],minimum:Ie,regenerableTools:[...I],protectedTools:[],truncateTools:[...Ye],truncateMaxLength:Le,timeBased:{enabled:!1,gapThresholdMs:60*6e4,keepRecent:5}};function B(e,t){let[n,r]=e;switch(n){case`tokens`:return r;case`fraction`:return Math.floor(t*r);case`headroom`:{let e=Math.floor(t*.5);return Math.max(e,t-r)}}}const Xe=e(`@x-otto/memory:prune`);function Ze(e,t,n={},r=A,i={}){let a={...z,...n},o=B(a.trigger,t),s=N(e,r),c=i.currentTokens??s,l=a.timeBased,u=l?.enabled===!0&&i.timeGapMs!==void 0&&i.timeGapMs>(l.gapThresholdMs??36e5);if(!i.force&&!u&&c<o)return{messages:[...e],prunedCount:0,tokensSaved:0,changed:!1};let d=new Set([...a.regenerableTools,...a.regenerableToolNames?.()??[]]),f=u?Qe(e,a,r,l.keepRecent??5,d):$e(e,a,t,r,d),p=s-N(f,r);if(p<a.minimum)return Xe.debug(`Prune skipped: savings ${p} < minimum ${a.minimum}`),{messages:[...e],prunedCount:0,tokensSaved:0,changed:!1};let m=f.filter((t,n)=>t!==e[n]).length;return Xe.info(`Pruned ${m} messages, saved ~${p} tokens`),{messages:f,prunedCount:m,tokensSaved:p,changed:!0}}function Qe(e,t,n,r,i){let a=i,o=new Set(t.protectedTools),s=e=>{if(e.role!==`tool_result`)return!1;let t=e;return a.has(t.toolName)&&!o.has(t.toolName)},c=0,l=0;for(let t=e.length-1;t>=0;t--){let n=e[t];if(n&&s(n)&&(c++,c===r)){l=t;break}}return e.map((e,t)=>t>=l||!s(e)?e:et(e,n))}function $e(e,t,n,r,i){let a=B(t.protect,n),o=new Set(t.truncateTools),s=i,c=new Set(t.protectedTools),l=0,u=e.length;for(let t=e.length-1;t>=0;t--){let n=e[t],i=M(n,r);if(l+=i,l>=a){u=t+1;break}}return e.map((e,n)=>{if(n>=u)return e;if(e.role===`tool_result`){let t=e;return!s.has(t.toolName)||c.has(t.toolName)?e:et(t,r)}return e.role===`assistant`&&n<u?nt(e,o,t.truncateMaxLength):e})}function et(e,t){let n=e.content.map(e=>e.type===`text`?e.text:``).join(``),r=t(n);if(r<100)return e;let i=n.split(`
140
- `).find(e=>e.startsWith(`[tool result stored to `)),a=i?` ${i}`:``;return{...e,content:[{type:`text`,text:`[output pruned — ${r} tokens]${a}`}]}}function tt(e,t){let n=typeof t.path==`string`?t.path:void 0;if(n===void 0)return null;if(e===`write`)return{path:n,content:`[content omitted by context pruning — ${(typeof t.content==`string`?t.content:``).length} chars. The file was already written to disk; read it if needed.]`};if(e===`edit`){let e=typeof t.oldContent==`string`?t.oldContent:``,r=typeof t.newContent==`string`?t.newContent:``;return{path:n,oldContent:`[omitted by context pruning — ${e.length} chars]`,newContent:`[omitted by context pruning — ${r.length} chars. The edit was already applied to the file on disk; read it if needed.]`}}return null}function nt(e,t,n){if(!Array.isArray(e.content))return e;let r=!1,i=e.content.map(e=>{if(e.type!==`tool_call`||!t.has(e.name)||JSON.stringify(e.arguments).length<=n)return e;let i=tt(e.name,e.arguments);return i===null?e:(r=!0,{...e,arguments:i})});return r?{...e,content:i}:e}function V(e){return`${e.role===`user`?`Human`:e.role===`assistant`?`Assistant`:e.role===`tool_result`?`Tool[result#${Oe(e.toolCallId)} ${e.toolName}]${e.isError?`{error}`:``}`:`System`}: ${j(e)}`}function H(e,t){if(e.length<=t)return e;let n=e=>`\n\n…[${e} chars omitted to fit the summarization window]…\n\n`,r=Math.max(0,t-n(e.length).length),i=Math.floor(r/2);if(i<=0)return n(e.length).slice(0,t);let a=e.length-i*2;return`${e.slice(0,i)}${n(a)}${e.slice(-i)}`}function rt(e,t,n){if(n(e)<=t)return e;let r=0,i=e.length,a=``;for(;r<=i;){let o=Math.floor((r+i)/2),s=H(e,o);n(s)<=t?(a=s,r=o+1):i=o-1}return a}function U(e){return e.role===`user`?0:e.role===`assistant`?1:e.role===`tool_result`?it.has(e.toolName)?3:2:1}const it=new Set(I);async function at(e,t){if(!t)return[...e];let n=!1,r=[];for(let i of e){if(i.role!==`tool_result`||U(i)!==3){r.push(i);continue}let e=i,a=j(i);if(a.length<4096){r.push(i);continue}let o=await t(e.toolCallId??``,a).catch(()=>void 0);o?(n=!0,r.push({...e,content:[{type:`text`,text:`[tool result stored to ${o} (${a.length} chars). Use the read tool on that path to recover the full output.]`}]})):r.push(i)}return n?r:[...e]}function ot(e,t){let n=e.map(e=>({msg:e,prio:U(e),text:V(e)})),r=n.reduce((e,t)=>e+t.text.length,0);if(r<=t)return{texts:n.map(e=>e.text),sourceChars:r,fedChars:r,truncated:!1};let i=!1,a=e=>n.filter(t=>t.prio===e),o=a(0),s=a(1),c=a(2),l=a(3),u=e=>e.reduce((e,t)=>e+t.text.length,0),d=[{msgs:l,share:.1},{msgs:c,share:.2},{msgs:s,share:.35}],f=t;for(let{msgs:e,share:n}of d){if(e.length===0)continue;let r=u(e),a=Math.floor(t*n),o=Math.min(r,a);ct(e,o),o<r&&(i=!0),f-=u(e)}o.length>0&&u(o)>f&&(ct(o,Math.max(0,f)),i=!0);let p=n.reduce((e,t)=>e+t.text.length,0);return{texts:n.map(e=>e.text),sourceChars:r,fedChars:p,truncated:i}}function st(e,t){if(e.length===0||t<=0)return{text:``,chars:0,truncated:!1};let n=ot(e,t),r=n.texts.filter(e=>e.length>0).join(`
134
+ </summary>`}function le(e){return`[Low-fidelity summary — only about ${Math.max(0,Math.round(e*100))}% of the original history could be fed into summarization. Significant details are missing. Treat this summary as incomplete: if you need details it does not cover, call memory_archive_read with the archive id below to pull back the original messages, rather than guessing or asking the user to repeat themselves.]`}const E=e(`@x-otto/memory:persistent`),ue=[{path:`~/.otto/AGENTS.md`,writable:!0},{path:`./.otto/AGENTS.md`,writable:!0},{path:`./AGENTS.md`,writable:!1}],de=new Set([`## 代码风格与命名约定`,`## 发布与包管理注意事项`,`## 安全与配置建议`]);function fe(e){let t=e.split(`
135
+ `),n=[],r=!1;for(let e of t){if(e.match(/^## (.+)/)){r=de.has(e.trim()),r||n.push(e);continue}r||n.push(e)}return n.join(`
136
+ `)}const pe=/<!-- otto-memory:start slug="([^"]+)" -->/g;function me(e){let t=new Set;for(let n of e.matchAll(pe))t.add(n[1]??``);return t}function he(e){let t=new Set;for(let n of e.matchAll(/<!-- otto-memory:start slug="[^"]+" -->\n## ([^\n]+)/g))t.add((n[1]??``).trim());return t}function ge(e){return e.replace(/[^a-z0-9一-鿿]+/gi,``).toLowerCase()}function _e(e,t){if(!t||!e)return e;let n=me(t),r=new Set([...he(t)].map(e=>ge(e)));if(n.size===0&&r.size===0)return e;let i=e.replace(/<!-- otto-memory:start slug="([^"]+)" -->[\s\S]*?<!-- otto-memory:end slug="\1" -->\n?/g,(e,t)=>n.has(t)?``:e).split(`
137
+ `),a=[],o=!1;for(let e of i){let t=e.match(/^\s*-\s+\*\*([^*]+)\*\*/);if(t&&r.has(ge(t[1]??``))){o=!0;continue}if(o){(e.trim()===``||/^\s*- /.test(e)||e.startsWith(`## `))&&(o=!1,a.push(e));continue}a.push(e)}return a.join(`
138
+ `)}var ve=class{memories=new Map;unwatch;constructor(e,t=ue,n){this.store=e,this.sources=t,this.entryMtimes=n}async load(){this.memories=await this.store.load(this.sources);let e=this.memories.get(`./.otto/AGENTS.md`),t=this.sources.find(e=>e.path===`./AGENTS.md`)?.path;if(t&&e&&this.memories.has(t)){let n=this.memories.get(t)??``,r=_e(n,e);r!==n&&this.memories.set(t,r)}if(t&&this.memories.has(t)){let e=this.memories.get(t)??``,n=fe(e);n!==e&&this.memories.set(t,n)}E.info(`Loaded ${this.memories.size} memory source(s)`)}async reload(){await this.load()}getInjection(){return y(this.memories,m,this.entryMtimes)}getMemories(){return this.memories}async write(e,t){let n=this.sources.find(t=>t.path===e);if(!n)throw Error(`Unknown memory source: ${e}`);if(!n.writable)throw Error(`Memory source is read-only: ${e}`);await this.store.write(e,t),this.memories.set(e,t),E.info(`Memory source written: ${e}`)}watching(){this.unwatch||!this.store.watch||(this.unwatch=this.store.watch(this.sources,e=>{E.info(`Memory source changed: ${e}, reloading...`),this.reload()}))}stop(){this.unwatch?.(),this.unwatch=void 0}dispose(){this.stop(),this.memories.clear()}},ye=class{data=new Map;set(e,t){this.data.set(e,t)}async load(e){let t=new Map;for(let n of e){let e=this.data.get(n.path);e!==void 0&&t.set(n.path,e)}return t}async write(e,t){this.data.set(e,t)}},D=class{cwd;homeDirOverride;constructor(e=process.cwd(),t){this.cwd=e,this.homeDirOverride=t}async load(e){let{readFile:t}=await import(`node:fs/promises`),{resolve:n,isAbsolute:r}=await import(`node:path`),{homedir:i}=await import(`node:os`),a=new Map;for(let o of e){let e=this.resolvePath(o.path,n,r,i);try{let n=await t(e,`utf-8`);a.set(o.path,n)}catch{}}return a}async write(e,t){let{mkdir:n}=await import(`node:fs/promises`),{resolve:r,dirname:i,isAbsolute:a}=await import(`node:path`),{homedir:o}=await import(`node:os`),{atomicWriteFile:s}=await import(`@x-otto/persistence`),c=this.resolvePath(e,r,a,o);await n(i(c),{recursive:!0}),await s(c,t)}resolvePath(e,t,n,r){let i=this.homeDirOverride??r(),a=e.startsWith(`~/`)?e.replace(`~/`,`${i}/`):e;return n(a)?a:t(this.cwd,a)}};const be=e(`@x-otto/memory:token-estimator`);let O=null,k=null;async function xe(){if(!O){if(k){await k;return}k=(async()=>{try{let{getEncoding:e}=await import(`js-tiktoken`),t=e(`cl100k_base`);O={encode:e=>typeof e!=`string`||e.length===0?[]:t.encode(e)},be.info(`Tokenizer loaded: cl100k_base`)}catch(e){be.warn(`Failed to load js-tiktoken, falling back to heuristic: %s`,e.message),O=null}finally{k=null}})(),await k}}const Se=2e3;function Ce(e){return e>=33&&e<=47||e>=58&&e<=64||e>=91&&e<=96||e>=123&&e<=126}function we(e){return e>=12352&&e<=12543||e>=13312&&e<=19903||e>=19968&&e<=40959||e>=63744&&e<=64255||e>=44032&&e<=55203||e>=65280&&e<=65519||e>=131072&&e<=191471}function A(e){let t=0,n=0,r=0;for(let i of e){let e=i.codePointAt(0)??0;we(e)?t+=1:Ce(e)?n+=1:r+=1}return Math.ceil(t*1+n*.5+r*.25)}function Te(e,t){let n=1;for(let r=1;r<e.length;r++)if(e.charCodeAt(r)===e.charCodeAt(r-1)){if(n++,n>=t)return!0}else n=1;return!1}function j(e){if(O){if(e.length>1e5||Te(e,64))return A(e);try{return O.encode(e).length}catch{return A(e)}}return k||xe().catch(()=>{}),A(e)}function Ee(e){return e?e.length<=6?e:e.slice(-6):`?`}function M(e){return typeof e.content==`string`?e.content:Array.isArray(e.content)?e.content.map(e=>{switch(e.type){case`text`:return e.text;case`thinking`:return e.text;case`tool_call`:return`[call#${Ee(e.id)} ${e.name}](${JSON.stringify(e.arguments)})`;case`image`:return`[image]`;default:return``}}).filter(Boolean).join(`
139
+ `):JSON.stringify(e)}const De=new WeakMap;function N(e,t=j){let n=t===j&&O!==null&&typeof e==`object`&&!!e;if(n){let t=De.get(e);if(t!==void 0)return t}let r;if(Array.isArray(e.content)){r=4;for(let n of e.content)switch(n.type){case`text`:case`thinking`:r+=t(n.text);break;case`tool_call`:r+=t(`${n.name}(${JSON.stringify(n.arguments)})`);break;case`image`:r+=Se;break;default:break}}else r=4+t(M(e));return n&&De.set(e,r),r}function P(e,t=j){let n=0;for(let r of e)n+=N(r,t);return n}function Oe(e){return e.role===`assistant`}function F(e,t=j){let n=-1,r=0;for(let t=e.length-1;t>=0;t--){let i=e[t];if(Oe(i)&&i.usage){n=t,r=(i.usage.cacheReadTokens??0)+(i.usage.cacheWriteTokens??0)+i.usage.inputTokens+i.usage.outputTokens;break}}let i=0,a=0;if(n>=0){for(let r=0;r<=n;r++)a+=N(e[r],t);for(let r=n+1;r<e.length;r++)i+=N(e[r],t)}else i=P(e,t);let o=r+i,s=n>=0?Math.max(0,r-a):0,c=Math.max(0,o-s);return{total:o,fromUsage:r,fromEstimate:i,lastUsageIndex:n,derivedPrefix:s,bodyAfterPrefix:c}}const ke=.1,I=16384,Ae=t(process.env.OTTO_MEMORY_COMPACTION_HARD_CEILING_FRACTION,.9),je=24e3,Me=.6,Ne=.15,Pe=2e4,Fe=2e3,Ie=`write`,Le=`edit`,Re=`read`,ze=`grep`,Be=`find`,Ve=`read_file`,He=`grep_search`,Ue=`file_search`,We=t(process.env.OTTO_MEMORY_COVERAGE_WARN_THRESHOLD,.7),Ge=t(process.env.OTTO_MEMORY_COVERAGE_ERROR_THRESHOLD,.5),Ke=t(process.env.OTTO_MEMORY_COVERAGE_FLOOR_THRESHOLD,.3),qe=[Ie,Le],L=[Re,ze,Be,Ve,He,Ue,`bash`,`bash_output`,`web_search`,`web_fetch`];function Je(e){return{compaction:{enabled:!0,trigger:[`headroom`,Math.min(I,e.maxOutput)+je],keepRecent:[`fraction`,ke],reserveTokens:Math.min(I,e.maxOutput)},prune:{trigger:[`fraction`,Me],protect:[`fraction`,Ne],minimum:Pe,regenerableTools:[...L],protectedTools:[],truncateTools:[...qe],truncateMaxLength:Fe}}}const R={enabled:!0,trigger:[`headroom`,I+je],keepRecent:[`fraction`,ke],reserveTokens:I,cacheRetention:`long`},z={trigger:[`fraction`,Me],protect:[`fraction`,Ne],minimum:Pe,regenerableTools:[...L],protectedTools:[],truncateTools:[...qe],truncateMaxLength:Fe,timeBased:{enabled:!1,gapThresholdMs:60*6e4,keepRecent:5}};function B(e,t){let[n,r]=e;switch(n){case`tokens`:return r;case`fraction`:return Math.floor(t*r);case`headroom`:{let e=Math.floor(t*.5);return Math.max(e,t-r)}}}const Ye=e(`@x-otto/memory:prune`);function Xe(e,t,n={},r=j,i={}){let a={...z,...n},o=B(a.trigger,t),s=P(e,r),c=i.currentTokens??s,l=a.timeBased,u=l?.enabled===!0&&i.timeGapMs!==void 0&&i.timeGapMs>(l.gapThresholdMs??36e5);if(!i.force&&!u&&c<o)return{messages:[...e],prunedCount:0,tokensSaved:0,changed:!1};let d=new Set([...a.regenerableTools,...a.regenerableToolNames?.()??[]]),f=u?Ze(e,a,r,l.keepRecent??5,d):Qe(e,a,t,r,d),p=s-P(f,r);if(p<a.minimum)return Ye.debug(`Prune skipped: savings ${p} < minimum ${a.minimum}`),{messages:[...e],prunedCount:0,tokensSaved:0,changed:!1};let m=f.filter((t,n)=>t!==e[n]).length;return Ye.info(`Pruned ${m} messages, saved ~${p} tokens`),{messages:f,prunedCount:m,tokensSaved:p,changed:!0}}function Ze(e,t,n,r,i){let a=i,o=new Set(t.protectedTools),s=e=>{if(e.role!==`tool_result`)return!1;let t=e;return a.has(t.toolName)&&!o.has(t.toolName)},c=0,l=0;for(let t=e.length-1;t>=0;t--){let n=e[t];if(n&&s(n)&&(c++,c===r)){l=t;break}}return e.map((e,t)=>t>=l||!s(e)?e:$e(e,n))}function Qe(e,t,n,r,i){let a=B(t.protect,n),o=new Set(t.truncateTools),s=i,c=new Set(t.protectedTools),l=0,u=e.length;for(let t=e.length-1;t>=0;t--){let n=e[t],i=N(n,r);if(l+=i,l>=a){u=t+1;break}}return e.map((e,n)=>{if(n>=u)return e;if(e.role===`tool_result`){let t=e;return!s.has(t.toolName)||c.has(t.toolName)?e:$e(t,r)}return e.role===`assistant`&&n<u?tt(e,o,t.truncateMaxLength):e})}function $e(e,t){let n=e.content.map(e=>e.type===`text`?e.text:``).join(``),r=t(n);if(r<100)return e;let i=n.split(`
140
+ `).find(e=>e.startsWith(`[tool result stored to `)),a=i?` ${i}`:``;return{...e,content:[{type:`text`,text:`[output pruned — ${r} tokens]${a}`}]}}function et(e,t){let n=typeof t.path==`string`?t.path:void 0;if(n===void 0)return null;if(e===`write`)return{path:n,content:`[content omitted by context pruning — ${(typeof t.content==`string`?t.content:``).length} chars. The file was already written to disk; read it if needed.]`};if(e===`edit`){let e=typeof t.oldContent==`string`?t.oldContent:``,r=typeof t.newContent==`string`?t.newContent:``;return{path:n,oldContent:`[omitted by context pruning — ${e.length} chars]`,newContent:`[omitted by context pruning — ${r.length} chars. The edit was already applied to the file on disk; read it if needed.]`}}return null}function tt(e,t,n){if(!Array.isArray(e.content))return e;let r=!1,i=e.content.map(e=>{if(e.type!==`tool_call`||!t.has(e.name)||JSON.stringify(e.arguments).length<=n)return e;let i=et(e.name,e.arguments);return i===null?e:(r=!0,{...e,arguments:i})});return r?{...e,content:i}:e}function V(e){return`${e.role===`user`?`Human`:e.role===`assistant`?`Assistant`:e.role===`tool_result`?`Tool[result#${Ee(e.toolCallId)} ${e.toolName}]${e.isError?`{error}`:``}`:`System`}: ${M(e)}`}function H(e,t){if(e.length<=t)return e;let n=e=>`\n\n…[${e} chars omitted to fit the summarization window]…\n\n`,r=Math.max(0,t-n(e.length).length),i=Math.floor(r/2);if(i<=0)return n(e.length).slice(0,t);let a=e.length-i*2;return`${e.slice(0,i)}${n(a)}${e.slice(-i)}`}function nt(e,t,n){if(n(e)<=t)return e;let r=0,i=e.length,a=``;for(;r<=i;){let o=Math.floor((r+i)/2),s=H(e,o);n(s)<=t?(a=s,r=o+1):i=o-1}return a}function rt(e){return e.role===`user`?0:e.role===`assistant`?1:e.role===`tool_result`?it.has(e.toolName)?3:2:1}const it=new Set(L);async function at(e,t){if(!t)return[...e];let n=!1,r=[];for(let i of e){if(i.role!==`tool_result`||rt(i)!==3){r.push(i);continue}let e=i,a=M(i);if(a.length<4096){r.push(i);continue}let o=await t(e.toolCallId??``,a).catch(()=>void 0);o?(n=!0,r.push({...e,content:[{type:`text`,text:`[tool result stored to ${o} (${a.length} chars). Use the read tool on that path to recover the full output.]`}]})):r.push(i)}return n?r:[...e]}function ot(e,t){let n=e.map(e=>({msg:e,prio:rt(e),text:V(e)})),r=n.reduce((e,t)=>e+t.text.length,0);if(r<=t)return{texts:n.map(e=>e.text),sourceChars:r,fedChars:r,truncated:!1};let i=!1,a=e=>n.filter(t=>t.prio===e),o=a(0),s=a(1),c=a(2),l=a(3),u=e=>e.reduce((e,t)=>e+t.text.length,0),d=[{msgs:l,share:.1},{msgs:c,share:.2},{msgs:s,share:.35}],f=t;for(let{msgs:e,share:n}of d){if(e.length===0)continue;let r=u(e),a=Math.floor(t*n),o=Math.min(r,a);ct(e,o),o<r&&(i=!0),f-=u(e)}o.length>0&&u(o)>f&&(ct(o,Math.max(0,f)),i=!0);let p=n.reduce((e,t)=>e+t.text.length,0);return{texts:n.map(e=>e.text),sourceChars:r,fedChars:p,truncated:i}}function st(e,t){if(e.length===0||t<=0)return{text:``,chars:0,truncated:!1};let n=ot(e,t),r=n.texts.filter(e=>e.length>0).join(`
141
141
 
142
- `);return{text:r,chars:r.length,truncated:n.truncated}}function ct(e,t){if(e.length===0)return;let n=Math.max(0,Math.floor(t/e.length));for(let t of e)t.text.length>n&&(t.text=n<=0?``:H(t.text,n))}var lt=class{boostedBySession=new Map;get(e){return this.boostedBySession.get(e)??0}record(e,t,n,r,i){e<r?this.boostedBySession.set(n,Math.max(t*2,16)):e<i&&this.boostedBySession.set(n,t+2)}consume(e){let t=this.boostedBySession.get(e)??0;return t>0&&this.boostedBySession.delete(e),t}forget(e){this.boostedBySession.delete(e)}};function ut(e){return e.role===`user`&&j(e).startsWith(n)}function dt(e){return e.startsWith(n)?e.slice(n.length).trimStart():e}const ft=new Set([Be,Ve,He,Ue,We,Ge]),pt=new Set([Re,ze,`write_file`,`edit_file`,`replace_string_in_file`]);function mt(e,t,n=A){let r=0,i=0;for(let a=e.length-1;a>=0;a--){let o=M(e[a],n);if(r+=o,r>=t){i=a+1;break}}i=Math.max(0,Math.min(i,e.length-1));let a=i;for(;a<e.length;){let t=e[a];if(t.role===`user`||t.role===`assistant`)break;a++}let o=!1,s=a;if(a>0&&a<e.length&&e[a].role===`assistant`){let t=a-1;for(;t>=0&&e[t].role===`tool_result`;)t--;t>=0&&e[t].role===`assistant`&&(o=!0,s=t)}return{firstKeptIndex:a,turnStartIndex:s,isSplitTurn:o}}function ht(e){let t=new Set,n=new Set;for(let r of e){if(r.role!==`tool_result`)continue;let e=r.toolName,i=j(r).match(/(?:^|\s)(\/[^\s]+\.[a-z]+)/i);i?.[1]&&(ft.has(e)?t.add(i[1]):pt.has(e)&&n.add(i[1]))}return{read:[...t],modified:[...n]}}function gt(e){let t=[`## File Operations`];if(e.read.length>0){t.push(`### Read`);for(let n of e.read)t.push(`- ${n}`)}if(e.modified.length>0){t.push(`### Modified`);for(let n of e.modified)t.push(`- ${n}`)}return t.join(`
143
- `)}const W=e(`@x-otto/memory:compaction-backend`);var _t=class{summarize;estimateTokens;getConfig;governor;spill;constructor(e){this.summarize=e.summarize,this.estimateTokens=e.estimateTokens,this.getConfig=e.getConfig,this.governor=e.governor,this.spill=e.spill}effectiveConfig(){return{...R,...this.getConfig()}}isEligibleForManualCompact(e,t){let n=B(this.effectiveConfig().trigger,t);return N(e,this.estimateTokens)>=n*.5}prepare(e,t,n,r){let i=B(this.effectiveConfig().keepRecent,t),a=N(e,this.estimateTokens);if(e.length<=2)return W.debug(`Too few messages to compact`),null;let o=mt(e,r?.force===!0?Math.max(1,Math.min(i,Math.floor(a/2))):i,this.estimateTokens);if(o.firstKeptIndex<=0)return W.debug(`Cut point at beginning, nothing to compact`),null;let s=e.slice(0,o.firstKeptIndex),c=e.slice(o.firstKeptIndex),l=s.filter(e=>!ut(e));if(l.length===0)return W.debug(`Compaction window only contains prior summaries, nothing new to summarize`),null;let u=n;if(!u){for(let e=s.length-1;e>=0;e--)if(ut(s[e])){u=dt(j(s[e]));break}}let d=[];o.isSplitTurn&&(d=e.slice(o.turnStartIndex,o.firstKeptIndex));let f=ht(l);return{messagesToSummarize:[...l],turnPrefixMessages:d,preservedMessages:[...c],isSplitTurn:o.isSplitTurn,tokensBefore:a,previousSummary:u,fileOps:f}}batchMessagesByTokenBudget(e,t){let n=this.estimateTokens,r=[],i=[],a=0;for(let o of e){let e=M(o,n);i.length>0&&a+e>t&&(r.push(i),i=[],a=0),i.push(o),a+=e}return i.length>0&&r.push(i),r}async compact(e,t,n){let r=this.effectiveConfig(),i=this.estimateTokens;W.info(`Compacting ${e.messagesToSummarize.length} messages`);let a=r.contextWindow==null?0:i(T(``,void 0,r.customInstructions,{variant:`segment`})),o=r.contextWindow==null?void 0:Math.max(1,Math.floor(r.contextWindow*.6)-a),s=o==null?0:Math.floor(o*.2),c=o==null?void 0:o-s,l=o==null?{text:``,chars:0,truncated:!1}:st(e.preservedMessages??[],s*4),u,d=1,f=this.spill?await at(e.messagesToSummarize,this.spill):e.messagesToSummarize,p=c==null?[f]:this.batchMessagesByTokenBudget(f,c);if(p.length<=1){let i=f.map(V).join(`
142
+ `);return{text:r,chars:r.length,truncated:n.truncated}}function ct(e,t){if(e.length===0)return;let n=Math.max(0,Math.floor(t/e.length));for(let t of e)t.text.length>n&&(t.text=n<=0?``:H(t.text,n))}var lt=class{boostedBySession=new Map;get(e){return this.boostedBySession.get(e)??0}record(e,t,n,r,i){e<r?this.boostedBySession.set(n,Math.max(t*2,16)):e<i&&this.boostedBySession.set(n,t+2)}consume(e){let t=this.boostedBySession.get(e)??0;return t>0&&this.boostedBySession.delete(e),t}forget(e){this.boostedBySession.delete(e)}};function ut(e){return e.role===`user`&&M(e).startsWith(n)}function dt(e){return e.startsWith(n)?e.slice(n.length).trimStart():e}const ft=new Set([Re,ze,Be,Ve,He,Ue]),pt=new Set([Ie,Le,`write_file`,`edit_file`,`replace_string_in_file`]);function mt(e,t,n=j){let r=0,i=0;for(let a=e.length-1;a>=0;a--){let o=N(e[a],n);if(r+=o,r>=t){i=a+1;break}}i=Math.max(0,Math.min(i,e.length-1));let a=i;for(;a<e.length;){let t=e[a];if(t.role===`user`||t.role===`assistant`)break;a++}let o=!1,s=a;if(a>0&&a<e.length&&e[a].role===`assistant`){let t=a-1;for(;t>=0&&e[t].role===`tool_result`;)t--;t>=0&&e[t].role===`assistant`&&(o=!0,s=t)}return{firstKeptIndex:a,turnStartIndex:s,isSplitTurn:o}}function ht(e){let t=new Set,n=new Set;for(let r of e){if(r.role!==`tool_result`)continue;let e=r.toolName,i=M(r).match(/(?:^|\s)(\/[^\s]+\.[a-z]+)/i);i?.[1]&&(ft.has(e)?t.add(i[1]):pt.has(e)&&n.add(i[1]))}return{read:[...t],modified:[...n]}}function gt(e){let t=[`## File Operations`];if(e.read.length>0){t.push(`### Read`);for(let n of e.read)t.push(`- ${n}`)}if(e.modified.length>0){t.push(`### Modified`);for(let n of e.modified)t.push(`- ${n}`)}return t.join(`
143
+ `)}const U=e(`@x-otto/memory:compaction-backend`);var _t=class{summarize;estimateTokens;getConfig;governor;spill;constructor(e){this.summarize=e.summarize,this.estimateTokens=e.estimateTokens,this.getConfig=e.getConfig,this.governor=e.governor,this.spill=e.spill}effectiveConfig(){return{...R,...this.getConfig()}}isEligibleForManualCompact(e,t){let n=B(this.effectiveConfig().trigger,t);return P(e,this.estimateTokens)>=n*.5}prepare(e,t,n,r){let i=B(this.effectiveConfig().keepRecent,t),a=P(e,this.estimateTokens);if(e.length<=2)return U.debug(`Too few messages to compact`),null;let o=mt(e,r?.force===!0?Math.max(1,Math.min(i,Math.floor(a/2))):i,this.estimateTokens);if(o.firstKeptIndex<=0)return U.debug(`Cut point at beginning, nothing to compact`),null;let s=e.slice(0,o.firstKeptIndex),c=e.slice(o.firstKeptIndex),l=s.filter(e=>!ut(e));if(l.length===0)return U.debug(`Compaction window only contains prior summaries, nothing new to summarize`),null;let u=n;if(!u){for(let e=s.length-1;e>=0;e--)if(ut(s[e])){u=dt(M(s[e]));break}}let d=[];o.isSplitTurn&&(d=e.slice(o.turnStartIndex,o.firstKeptIndex));let f=ht(l);return{messagesToSummarize:[...l],turnPrefixMessages:d,preservedMessages:[...c],isSplitTurn:o.isSplitTurn,tokensBefore:a,previousSummary:u,fileOps:f}}batchMessagesByTokenBudget(e,t){let n=this.estimateTokens,r=[],i=[],a=0;for(let o of e){let e=N(o,n);i.length>0&&a+e>t&&(r.push(i),i=[],a=0),i.push(o),a+=e}return i.length>0&&r.push(i),r}async compact(e,t,n){let r=this.effectiveConfig(),i=this.estimateTokens;U.info(`Compacting ${e.messagesToSummarize.length} messages`);let a=r.contextWindow==null?0:i(T(``,void 0,r.customInstructions,{variant:`segment`})),o=r.contextWindow==null?void 0:Math.max(1,Math.floor(r.contextWindow*.6)-a),s=o==null?0:Math.floor(o*.2),c=o==null?void 0:o-s,l=o==null?{text:``,chars:0,truncated:!1}:st(e.preservedMessages??[],s*4),u,d=1,f=this.spill?await at(e.messagesToSummarize,this.spill):e.messagesToSummarize,p=c==null?[f]:this.batchMessagesByTokenBudget(f,c);if(p.length<=1){let i=f.map(V).join(`
144
144
 
145
- `),a=e.preservedMessages?.length??0,o={variant:a>0?`preserved-tail`:`full`,preservedCount:a,...l.text?{preservedTailReference:l.text}:{}};if(r.prefixReuse){let a=T(i,e.previousSummary,r.customInstructions,{...o,omitConversation:!0});u=await this.summarize(a,{maxTokens:r.reserveTokens,signal:n,prefix:{sessionId:t,messages:f,cacheRetention:r.cacheRetention}})}else{let t=T(i,e.previousSummary,r.customInstructions,o);u=await this.summarize(t,{maxTokens:r.reserveTokens,signal:n})}W.info({batches:1,sourceChars:i.length,fedChars:i.length,coverage:1,truncated:!1,preservedTailChars:l.chars,preservedTailTruncated:l.truncated},`[compaction] summarization coverage`)}else{let a=t??`__default__`,o=this.governor.get(a),s=o>0?o:8;o>0&&this.governor.consume(a);let f=p.length<=s?p:[...p.slice(0,s-1),p.slice(s-1).flat()];W.info(`RFC-321 M6: summarization input exceeds window budget; map-reduce over ${f.length} batches`);let m=c*4,h=[],g=0,_=0,v=!1,y=[0,0,0,0],b=[0,0,0,0];for(let e of f){if(n?.aborted)break;let a=ot(e,m),o=a.texts.join(`
145
+ `),a=e.preservedMessages?.length??0,o={variant:a>0?`preserved-tail`:`full`,preservedCount:a,...l.text?{preservedTailReference:l.text}:{}};if(r.prefixReuse){let a=T(i,e.previousSummary,r.customInstructions,{...o,omitConversation:!0});u=await this.summarize(a,{maxTokens:r.reserveTokens,signal:n,prefix:{sessionId:t,messages:f,cacheRetention:r.cacheRetention}})}else{let t=T(i,e.previousSummary,r.customInstructions,o);u=await this.summarize(t,{maxTokens:r.reserveTokens,signal:n})}U.info({batches:1,sourceChars:i.length,fedChars:i.length,coverage:1,truncated:!1,preservedTailChars:l.chars,preservedTailTruncated:l.truncated},`[compaction] summarization coverage`)}else{let a=t??`__default__`,o=this.governor.get(a),s=o>0?o:8;o>0&&this.governor.consume(a);let f=p.length<=s?p:[...p.slice(0,s-1),p.slice(s-1).flat()];U.info(`RFC-321 M6: summarization input exceeds window budget; map-reduce over ${f.length} batches`);let m=c*4,h=[],g=0,_=0,v=!1,y=[0,0,0,0],b=[0,0,0,0];for(let e of f){if(n?.aborted)break;let a=ot(e,m),o=a.texts.join(`
146
146
 
147
- `),s=o;s.length>m&&(s=H(s,m)),s=rt(s,c,i),g+=a.sourceChars,_+=Math.min(a.fedChars,s.length),(a.truncated||s.length<o.length)&&(v=!0),e.forEach((e,t)=>{let n=U(e);y[n]=(y[n]??0)+V(e).length,b[n]=(b[n]??0)+(a.texts[t]?.length??0)});let u=T(s,void 0,r.customInstructions,{variant:`segment`,...l.text?{preservedTailReference:l.text}:{}});h.push(await this.summarize(u,{maxTokens:r.reserveTokens,signal:n,...r.prefixReuse?{prefix:{sessionId:t,cacheRetention:r.cacheRetention}}:{}}))}let x=H(h.map((e,t)=>`### Segment ${t+1}\n\n${e}`).join(`
147
+ `),s=o;s.length>m&&(s=H(s,m)),s=nt(s,c,i),g+=a.sourceChars,_+=Math.min(a.fedChars,s.length),(a.truncated||s.length<o.length)&&(v=!0),e.forEach((e,t)=>{let n=rt(e);y[n]=(y[n]??0)+V(e).length,b[n]=(b[n]??0)+(a.texts[t]?.length??0)});let u=T(s,void 0,r.customInstructions,{variant:`segment`,...l.text?{preservedTailReference:l.text}:{}});h.push(await this.summarize(u,{maxTokens:r.reserveTokens,signal:n,...r.prefixReuse?{prefix:{sessionId:t,cacheRetention:r.cacheRetention}}:{}}))}let x=H(h.map((e,t)=>`### Segment ${t+1}\n\n${e}`).join(`
148
148
 
149
- `),m);u=await this.summarize(ae(x,e.previousSummary,r.customInstructions),{maxTokens:r.reserveTokens,signal:n,...r.prefixReuse?{prefix:{sessionId:t,cacheRetention:r.cacheRetention}}:{}});let S=g>0?_/g:1;d=S,W.info({batches:f.length,sourceChars:g,fedChars:_,coverage:Number(S.toFixed(4)),truncated:v,preservedTailChars:l.chars,preservedTailTruncated:l.truncated,byPriority:{p0:{src:y[0],fed:b[0]},p1:{src:y[1],fed:b[1]},p2:{src:y[2],fed:b[2]},p3:{src:y[3],fed:b[3]}}},`[compaction] summarization coverage`);let C=r.coverageWarnThreshold??Ke,w=Math.min(r.coverageErrorThreshold??qe,C);S<w&&W.warn({coverage:Number(S.toFixed(4)),sourceChars:g,fedChars:_,batches:f.length,errorThreshold:w},`[compaction] low summarization coverage — large portion of history not represented in summary (RFC-321 C1)`),this.governor.record(S,f.length,t??`__default__`,w,C)}if(e.fileOps.read.length>0||e.fileOps.modified.length>0){let t=gt(e.fileOps);u.includes(`## File Operations`)||(u+=`\n\n${t}`)}if(e.isSplitTurn&&e.turnPrefixMessages.length>0){let i=oe(e.turnPrefixMessages.map(V).join(`
149
+ `),m);u=await this.summarize(ie(x,e.previousSummary,r.customInstructions),{maxTokens:r.reserveTokens,signal:n,...r.prefixReuse?{prefix:{sessionId:t,cacheRetention:r.cacheRetention}}:{}});let S=g>0?_/g:1;d=S,U.info({batches:f.length,sourceChars:g,fedChars:_,coverage:Number(S.toFixed(4)),truncated:v,preservedTailChars:l.chars,preservedTailTruncated:l.truncated,byPriority:{p0:{src:y[0],fed:b[0]},p1:{src:y[1],fed:b[1]},p2:{src:y[2],fed:b[2]},p3:{src:y[3],fed:b[3]}}},`[compaction] summarization coverage`);let C=r.coverageWarnThreshold??We,w=Math.min(r.coverageErrorThreshold??Ge,C);S<w&&U.warn({coverage:Number(S.toFixed(4)),sourceChars:g,fedChars:_,batches:f.length,errorThreshold:w},`[compaction] low summarization coverage — large portion of history not represented in summary (RFC-321 C1)`),this.governor.record(S,f.length,t??`__default__`,w,C)}if(e.fileOps.read.length>0||e.fileOps.modified.length>0){let t=gt(e.fileOps);u.includes(`## File Operations`)||(u+=`\n\n${t}`)}if(e.isSplitTurn&&e.turnPrefixMessages.length>0){let i=ae(e.turnPrefixMessages.map(V).join(`
150
150
 
151
- `)),a=await this.summarize(i,{signal:n,...r.prefixReuse?{prefix:{sessionId:t,cacheRetention:r.cacheRetention}}:{}});u=`${u}\n\n---\n\n${a}`}return W.info(`Compaction complete: summary ${u.length} chars`),{summary:u,firstKeptIndex:e.messagesToSummarize.length,tokensBefore:e.tokensBefore,coverage:d}}},vt=class{name=`token-pressure`;evaluate(e){let t=B(e.compactionConfig.trigger,e.effectiveWindow),n=e.compactionConfig.hardCeilingFraction??Me,r=yt(e.effectiveWindow,n);return e.estimate.bodyAfterPrefix>=t||e.estimate.total>=r}};function yt(e,t){return Math.floor(e*t)}var bt=class{name=`real-input`;evaluate(e){if(e.realInputTokens===void 0)return!1;let t=e.compactionConfig.hardCeilingFraction??Me;return e.realInputTokens>=yt(e.effectiveWindow,t)}},xt=class{name=`residency`;evaluate(e){if(e.estimatedBytes===void 0)return!1;let t=e.maxContentBytes;return t===void 0?!1:e.estimatedBytes>=t*.9}};const St=[new vt,new bt,new xt];var Ct=class{name=`prune-token`;evaluate(e){let t=B(e.pruneConfig.trigger,e.effectiveWindow);return e.estimate.bodyAfterPrefix>=t}},wt=class{name=`prune-time-gap`;evaluate(e){let t=e.pruneConfig.timeBased;return t?.enabled!==!0||e.timeGapMs===void 0?!1:e.timeGapMs>(t.gapThresholdMs??60*6e4)}};const Tt=[new Ct,new wt],Et=e(`@x-otto/memory:archive`);var G=class{type=`memory`;archives=new Map;sessionIndex=new Map;async archive(e,t,n){let r=Date.now(),i=`memory://archives/${e}/compaction-${r}.md`,a=K(t,n,r);this.archives.set(i,{content:a,entry:{path:i,timestamp:r,summary:n.slice(0,200),messageCount:t.length}});let o=this.sessionIndex.get(e)??[];return o.push(i),this.sessionIndex.set(e,o),Et.info(`Archived ${t.length} messages for session ${e}`),i}async read(e){let t=this.archives.get(e);if(!t)throw Error(`Archive not found: ${e}`);return t.content}async list(e){return(this.sessionIndex.get(e)??[]).map(e=>this.archives.get(e)?.entry).filter(e=>e!==void 0)}forgetSession(e){let t=this.sessionIndex.get(e);if(t){for(let e of t)this.archives.delete(e);this.sessionIndex.delete(e)}}};function K(e,t,n){let r=[`## Compacted at ${new Date(n).toISOString()}`,``,`### Summary`,t,``,`### Original Messages (${e.length} messages)`];for(let t of e){let e=t.role===`user`?`Human`:t.role===`assistant`?`Assistant`:t.role===`tool_result`?`Tool[${t.toolName}]`:`System`,n=j(t),i=n.length>2e3?`${n.slice(0,2e3)}\n...(truncated, ${n.length} chars total)`:n;r.push(`\n**${e}**: ${i}`)}return r.join(`
152
- `)}const Dt=e(`@x-otto/memory:archive-source`);var Ot=class{archiveIdCounter=new Map;constructor(e,t,n,r=new G){this.loadSessionEntries=e,this.messageFromEntry=t,this.clock=n,this.fallback=r}async record(e,t,n){let r=(this.archiveIdCounter.get(e)??0)+1;return this.archiveIdCounter.set(e,r),`archive:${e}:${r}`}async list(e){try{return await this.listFromEntries(e)}catch(t){return Dt.warn({error:t},`listArchives from session entries failed, falling back`),this.fallback.list(e)}}async read(e){try{let t=await this.readFromEntries(e);if(t!==null)return t}catch(e){Dt.warn({error:e},`readArchive from session entries failed, falling back`)}return this.fallback.read(e)}forgetSession(e){this.archiveIdCounter.delete(e),this.fallback.forgetSession?.(e)}async listFromEntries(e){let t=await this.loadSessionEntries(e),n=this.messageFromEntry,r=[],i=0;for(let a=0;a<t.length;a++){let o=t[a];if(o.type!==`compaction`)continue;let s=o.data;i++;let c=0,l=0;for(let e=a-1;e>=0;e--){let r=t[e];if(r.type===`compaction`)break;let i=n(r);i&&(c++,l=i.timestamp??l)}r.push({path:`archive:${e}:${i}`,timestamp:l||o.seq||0,messageCount:s.compactedCount,summary:s.summary.slice(0,200)})}return r}async readFromEntries(e){let t=e.match(/^archive:(.+):(\d+)$/);if(!t)return null;let n=t[1],r=parseInt(t[2],10),i=await this.loadSessionEntries(n),a=this.messageFromEntry,o=0,s=-1;for(let e=0;e<i.length;e++)if(i[e].type===`compaction`&&(o++,o===r)){s=e;break}if(s<0)return null;let c=i[s].data,l=-1;for(let e=s-1;e>=0;e--)if(i[e].type===`compaction`){l=e;break}let u=l+1,d=[];for(let e=u;e<s;e++){let t=a(i[e]);t&&d.push(t)}let f=this.clock.now();return K(d.filter(e=>e!==null),c.summary,f)}},kt=class{storage;constructor(e){this.storage=e??new G}async record(e,t,n){return this.storage.archive(e,t,n)}async list(e){return this.storage.list(e)}async read(e){return this.storage.read(e)}forgetSession(e){this.storage.forgetSession?.(e)}};function At(e,t,n,r){return e&&t?new Ot(e,t,n,r):new kt(r)}function jt(e){if(e.role===`assistant`&&e.usage){let{usage:t,...n}=e;return n}return e}const q=e(`@x-otto/memory`),Mt=`__default__`;function J(e){return e?.trim()||Mt}var Nt=class{persistent;archiveSource;estimateTokens;rawConfig;contextWindow;getContextWindow;compactionConfig;pruneConfig;maxContentBytes;getMaxContentBytes;getEstimatedBytes;getRealInputTokens;previousSummaries=new Map;compactionInFlight=new Set;compactionLock;compactionSpill;coverageGovernor;compactionBackend;compactionPolicies;prunePolicies;clock;constructor(e){let t=e.model?L(e.model):{compaction:R,prune:z};this.compactionConfig={...t.compaction,...e.compaction},this.pruneConfig={...t.prune,...e.prune},this.contextWindow=e.model?.contextWindow??2e5,this.getContextWindow=e.getContextWindow,this.maxContentBytes=e.maxContentBytes,this.getMaxContentBytes=e.getMaxContentBytes,this.getEstimatedBytes=e.getEstimatedBytes,this.getRealInputTokens=e.getRealInputTokens,this.rawConfig=e,this.estimateTokens=e.estimateTokens??A,this.compactionLock=e.compactionLock,this.compactionSpill=e.compactionSpill,this.coverageGovernor=e.coverageGovernor??new lt,this.compactionBackend=new _t({summarize:e.summarize,estimateTokens:this.estimateTokens,getConfig:()=>this.effectiveCompactionConfig(),governor:this.coverageGovernor,spill:e.compactionSpill}),this.clock=e.clock??{now:()=>Date.now()},this.compactionPolicies=St,this.prunePolicies=Tt,this.archiveSource=At(e.loadSessionEntries,e.messageFromEntry,this.clock,e.archiveStorage),this.persistent=new ye(e.memoryStore??new xe,e.sources,e.entryMtimes)}clearSession(e){this.previousSummaries.delete(J(e))}forgetSession(e){this.previousSummaries.delete(J(e)),this.coverageGovernor.forget(e),this.archiveSource.forgetSession?.(e)}reconfigure(e){let t=L(e);this.contextWindow=e.contextWindow,this.compactionConfig={...t.compaction,...this.rawConfig.compaction},this.pruneConfig={...t.prune,...this.rawConfig.prune}}effectiveContextWindow(){return this.getContextWindow?.()??this.contextWindow}effectiveCompactionConfig(){return{...this.compactionConfig,contextWindow:this.effectiveContextWindow(),...(()=>{let e=this.rawConfig.getCoverageThresholds?.();return{...e?.warn===void 0?{}:{coverageWarnThreshold:e.warn},...e?.error===void 0?{}:{coverageErrorThreshold:e.error},...e?.floor===void 0?{}:{coverageFloorThreshold:e.floor}}})()}}async ensureFitsWindow(e,t,n){if(!this.needsCompaction(e))return{messages:[...e],compacted:!1};let r=await this.process(e,t,n,{force:!0});return{messages:r.messages,compacted:r.compacted,summary:r.summary,replacement:r.replacement}}async loadMemory(){await this.persistent.load()}getMemoryPrompt(){return this.persistent.getInjection()}async reloadMemory(){await this.persistent.reload()}getMemories(){return this.persistent.getMemories()}needsPrune(e){return this.needsPruneWith(P(e,this.estimateTokens),e)}needsPruneWith(e,t){let n=this.buildTriggerContext(e,t);return this.prunePolicies.some(e=>e.evaluate(n))}prune(e,t=!1){return this.pruneWith(e,P(e,this.estimateTokens),t)}pruneWith(e,t,n){let r=this.computeTimeGapMs(e);return Ze(e,this.effectiveContextWindow(),this.pruneConfig,this.estimateTokens,{currentTokens:t.total,force:n,timeGapMs:r})}needsCompaction(e){if(this.compactionConfig.enabled===!1)return!1;let t=this.buildTriggerContext(P(e,this.estimateTokens),e);return this.compactionPolicies.some(e=>e.evaluate(t))}isResidencyPressureActive(){let e=this.compactionPolicies.find(e=>e.name===`residency`);if(!e)return!1;let t=this.getMaxContentBytes?.()??this.maxContentBytes,n=this.getEstimatedBytes?.();return e.evaluate({estimate:{total:0,fromUsage:0,fromEstimate:0,lastUsageIndex:-1,derivedPrefix:0,bodyAfterPrefix:0},effectiveWindow:this.effectiveContextWindow(),compactionConfig:this.compactionConfig,pruneConfig:this.pruneConfig,clock:this.clock,...t===void 0?{}:{maxContentBytes:t},...n===void 0?{}:{estimatedBytes:n}})}buildTriggerContext(e,t){let n=this.getMaxContentBytes?.()??this.maxContentBytes,r=this.getEstimatedBytes?.();return{estimate:e,effectiveWindow:this.effectiveContextWindow(),compactionConfig:this.compactionConfig,pruneConfig:this.pruneConfig,clock:this.clock,...this.getRealInputTokens===void 0?{}:{realInputTokens:this.getRealInputTokens()},...n===void 0?{}:{maxContentBytes:n},...r===void 0?{}:{estimatedBytes:r},...t===void 0?{}:{timeGapMs:this.computeTimeGapMs(t)}}}computeTimeGapMs(e){if(this.pruneConfig.timeBased?.enabled!==!0)return;let t;for(let n=e.length-1;n>=0;n--){let r=e[n];if(r&&`timestamp`in r&&typeof r.timestamp==`number`){t=r.timestamp;break}}return t===void 0?void 0:this.clock.now()-t}isEligibleForManualCompact(e){return this.compactionBackend.isEligibleForManualCompact(e,this.effectiveContextWindow())}prepareCompaction(e,t,n){return this.compactionBackend.prepare(e,this.effectiveContextWindow(),this.previousSummaries.get(J(t)),n)}async compact(e,t,n){let r=await this.compactionBackend.compact(e,t,n),i=Math.min(this.compactionConfig.coverageFloorThreshold??this.rawConfig.getCoverageThresholds?.()?.floor??Je,this.compactionConfig.coverageErrorThreshold??qe);if(r.coverage<i&&(q.warn({sessionId:t,coverage:Number(r.coverage.toFixed(4)),floorThreshold:i},`[compaction] coverage below floor — boundary established WITH an explicit low-fidelity notice; a large portion of history is not represented in this summary (RFC-340 D1)`),r.summary=`${ue(r.coverage)}\n\n${r.summary}`),t)try{await this.recordCompactionArchive(t,r,e.messagesToSummarize),q.info(`Compaction recorded at ${r.archivePath}`)}catch(e){q.warn({error:e},`Failed to record compaction archive`)}return this.previousSummaries.set(J(t),r.summary),r}async recordCompactionArchive(e,t,n){t.archivePath=await this.archiveSource.record(e,n,t.summary)}async process(e,t,r,i){let a=[...e],o=!1,s=!1,c,l,u,d,f=i?.force===!0,p=i?.skipPrune===!0,m=P(a,this.estimateTokens);if(!p&&(f||this.needsPruneWith(m,a))){let e=a.length,t=this.pruneWith(a,m,f);t.changed&&(a=t.messages,o=!0,d={prunedCount:t.prunedCount,tokensSaved:t.tokensSaved,messagesBefore:e,messagesAfter:a.length},q.info(`Prune: removed ${t.prunedCount} tool outputs, saved ~${t.tokensSaved} tokens`))}let h=this.compactionConfig.enabled!==!1;if(f?h:this.needsCompaction(a)){let e=J(t),i=`${process.pid}:${this.clock.now()}`;if(!(this.compactionLock?await this.compactionLock.acquire(t??Mt,i):!this.compactionInFlight.has(e)))q.info({sessionId:t},`Compaction already in flight for this session, skipping this round (will retry next round)`);else{this.compactionLock||this.compactionInFlight.add(e);try{let e=this.isResidencyPressureActive(),i=this.prepareCompaction(a,t,{force:f||e});if(i)try{let o=await this.compact(i,t,r);s=!0,c=o.summary,u=o.archivePath;let d={role:`user`,content:[{type:`text`,text:`${n}\n\n${u?le(u,o.summary):o.summary}`}],timestamp:this.clock.now()};l=i.preservedMessages.map(jt),a=[d,...l],q.info({sessionId:t,trigger:f?`force`:e?`residency`:`token`},`Compaction: ${i.messagesToSummarize.length} messages → summary, kept ${i.preservedMessages.length}`)}catch(e){q.warn({error:e},`Compaction failed (LLM/summarizer error?), skipping compaction for this turn`)}}finally{this.compactionLock?await this.compactionLock.release(t??Mt,i).catch(()=>{}):this.compactionInFlight.delete(e)}}}return{messages:a,summary:c,replacement:l,archivePath:u,pruned:o,compacted:s,pruneMetrics:d}}async listArchives(e){return this.archiveSource.list(e)}async readArchive(e){return this.archiveSource.read(e)}dispose(){this.persistent.dispose()}};function Pt(e){return new Nt(e)}var Ft=class{baseUrl;userId;workspaceKeyGetter;isWorkspaceSyncEnabled;getAuth;fetchImpl;timeoutMs;local;onConflict;conflictCounters=new Map;knownVersions=new Map;constructor(e){this.baseUrl=e.baseUrl.replace(/\/+$/,``),this.userId=e.userId,this.workspaceKeyGetter=e.workspaceKey,this.isWorkspaceSyncEnabled=e.isWorkspaceSyncEnabled??(()=>!1),this.getAuth=e.getAuth,this.fetchImpl=e.fetch,this.timeoutMs=e.timeoutMs,this.local=new xe(e.localDir,e.homeDirOverride),this.onConflict=e.onConflict}async load(e){let t=new Map,n=[];for(let r of e)if(this.userId&&It(r.path)){let e=await this.loadRemoteUser(r.path);e===null?n.push(r):(t.set(r.path,e),this.local.write(r.path,e).catch(()=>{}))}else if(this.isWorkspaceSourceEnabled(r.path)){let e=await this.loadRemoteWorkspace(r.path);e===null?n.push(r):(t.set(r.path,e),this.local.write(r.path,e).catch(()=>{}))}else n.push(r);if(n.length>0){let e=await this.local.load(n);for(let[n,r]of e)t.set(n,r)}return t}async write(e,t){await this.local.write(e,t),this.userId&&It(e)?this.writeRemoteUser(e,t).catch(()=>{}):this.isWorkspaceSourceEnabled(e)&&await this.writeRemoteWorkspace(e,t)}watch(e,t){return()=>{}}isWorkspaceSourceEnabled(e){return Lt(e)&&this.isWorkspaceSyncEnabled()&&!!this.workspaceKeyGetter?.()}remoteKey(e){let t=e.startsWith(`~/.otto/`)?e.slice(8):e;return`user:${this.userId}:${t}`}remoteResourceId(e){let t=e.startsWith(`~/.otto/`)?e.slice(8):e;return encodeURIComponent(t)}workspaceResourceId(e){let t=e.startsWith(`./.otto/`)?e.slice(8):e;return encodeURIComponent(t)}async loadRemoteUser(e){try{let t={Authorization:`Bearer ${(await this.getAuth()).token}`,Accept:`application/json`,"X-Otto-User-Id":this.userId},n=new AbortController,r=setTimeout(()=>n.abort(),this.timeoutMs);try{let r=await this.fetchImpl(`${this.baseUrl}/memory/user/${this.remoteResourceId(e)}`,{method:`GET`,headers:t,signal:n.signal});if(r.ok){let e=await r.json();if(typeof e.content==`string`)return e.content}if(r.status===404){let r=await this.fetchImpl(`${this.baseUrl}/sessions/${encodeURIComponent(this.remoteKey(e))}`,{method:`GET`,headers:t,signal:n.signal});if(r.ok){let e=await r.json();if(typeof e.content==`string`)return e.content}}}finally{clearTimeout(r)}}catch{}return null}async writeRemoteUser(e,t){try{let n={Authorization:`Bearer ${(await this.getAuth()).token}`,"Content-Type":`application/json`,"X-Otto-User-Id":this.userId},r=new AbortController,i=setTimeout(()=>r.abort(),this.timeoutMs);try{await this.fetchImpl(`${this.baseUrl}/memory/user/${this.remoteResourceId(e)}`,{method:`PUT`,headers:n,body:JSON.stringify({content:t}),signal:r.signal})}finally{clearTimeout(i)}}catch{}}async loadRemoteWorkspace(e){let t=this.workspaceKeyGetter?.();if(!t)return null;try{let n={Authorization:`Bearer ${(await this.getAuth()).token}`,Accept:`application/json`},r=new AbortController,i=setTimeout(()=>r.abort(),this.timeoutMs);try{let i=await this.fetchImpl(`${this.baseUrl}/memory/workspace/${encodeURIComponent(t)}/${this.workspaceResourceId(e)}`,{method:`GET`,headers:n,signal:r.signal});if(i.ok){let t=await i.json();if(typeof t.content==`string`)return typeof t.version==`number`&&this.knownVersions.set(e,t.version),t.content}}finally{clearTimeout(i)}}catch{}return null}async writeRemoteWorkspace(e,t){let n=this.workspaceKeyGetter?.();if(n)try{let r={Authorization:`Bearer ${(await this.getAuth()).token}`,"Content-Type":`application/json`},i=new AbortController,a=setTimeout(()=>i.abort(),this.timeoutMs),o=this.knownVersions.get(e)??0,s=o+1;try{let a=await this.fetchImpl(`${this.baseUrl}/memory/workspace/${encodeURIComponent(n)}/${this.workspaceResourceId(e)}`,{method:`PUT`,headers:r,body:JSON.stringify({content:t,version:s,expectedVersion:o}),signal:i.signal});if(a.status===409){await this.writeConflictSidecar(e,t);return}a.ok&&this.knownVersions.set(e,s)}finally{clearTimeout(a)}}catch{}}async writeConflictSidecar(e,t){let n=this.conflictCounters.get(e)??0,r=n%5;this.conflictCounters.set(e,n+1);let i=`${e}.conflict-${r}`;try{await this.local.write(i,t),this.onConflict?.(e,i)}catch{}}};function It(e){return e===`~/.otto/AGENTS.md`||e===`~/.otto/MEMORY.md`||e.startsWith(`~/.otto/memory/`)}function Lt(e){return e===`./.otto/MEMORY.md`||e.startsWith(`./.otto/memory/`)&&!e.startsWith(`./.otto/local/`)||e===`./.otto/lessons.json`}function Rt(e){let t=new Map;return{async load(n){let r=n.filter(e=>!t.has(e.path)),i=r.length>0?await e.load(r):new Map;for(let e of n){let n=t.get(e.path);n!==void 0&&i.set(e.path,n)}return i},async write(e,n){t.set(e,n)}}}function zt(e,t={}){let n=t.fileName??`AGENTS.md`,a=t.rootMarkers??[`.git`],s=t.maxDepth??25,l=t.maxFiles??10,u=t.maxFileBytes??64*1024,d=[],f=e;for(let e=0;e<s;e++){let e=c(f,n);try{r(e)&&i(e).size<=u&&d.push(e)}catch{}let t=a.some(e=>r(c(f,e))),s=o(f);if(t||s===f)break;f=s}return d.reverse().slice(-l).map(e=>({path:e,writable:!1}))}const Y=e(`@x-otto/memory:auto`),X=`# MEMORY`,Bt=/^- \[(.+?)\]\(memory\/(.+?)\.md\)/,Vt=`./.otto/AGENTS.md`;function Ht(e,t,n){return`<!-- otto-memory:start slug="${e}" -->\n## ${t.replace(/[\r\n]+/g,` `).trim()}\n\n${n.trim()}\n<!-- otto-memory:end slug="${e}" -->`}function Ut(e){return RegExp(`<!-- otto-memory:start slug="${e}" -->[\\s\\S]*?<!-- otto-memory:end slug="${e}" -->`)}var Wt=class{store;baseDir;localBaseDir;index=``;localIndex=``;loaded=!1;localLoaded=!1;constructor(e){this.store=e.store,this.baseDir=(e.baseDir??`./.otto`).replace(/\/+$/,``),this.localBaseDir=(e.localBaseDir??`${this.baseDir}/local`).replace(/\/+$/,``)}get indexPath(){return`${this.baseDir}/MEMORY.md`}entryPathOf(e){return`${this.baseDir}/memory/${e}.md`}get localIndexPath(){return`${this.localBaseDir}/MEMORY.md`}localEntryPathOf(e){return`${this.localBaseDir}/memory/${e}.md`}asSource(){return{path:this.indexPath,writable:!0}}asLocalSource(){return{path:this.localIndexPath,writable:!0}}async load(){this.index=(await this.store.load([this.asSource()])).get(this.indexPath)??``,this.loaded=!0}async loadLocal(){this.localIndex=(await this.store.load([this.asLocalSource()])).get(this.localIndexPath)??``,this.localLoaded=!0}getInjection(){let e=this.index.trim();return e?`${e}\n\n> Auto-memory entries live in the memory store (\`${this.baseDir}/memory/\`), not workspace files — read them with the memory_read tool; record new durable facts with memory_record.`:``}getLocalInjection(){let e=this.localIndex.trim();return e?`${e}\n\n> Machine-specific memory entries live in \`${this.localBaseDir}/memory/\` — never synced to other devices. Read with memory_read; record with memory_record (scope: 'local').`:``}async record(e,t=`workspace`){if(t===`local`){await this.recordLocal(e);return}if(t===`project-shared`){await this.recordProjectShared(e);return}await this.ensureLoaded();let n=this.resolveSlug(e.name,this.indexLines());await this.store.write(this.entryPathOf(n),`# ${e.name}\n\n${e.content}\n`);let r=`- [${e.name}](memory/${n}.md) — ${e.description}`,i=this.indexLines().filter(e=>!e.includes(`(memory/${n}.md)`));i.some(e=>e.startsWith(X))||i.unshift(X),i.push(r),this.index=`${i.join(`
151
+ `)),a=await this.summarize(i,{signal:n,...r.prefixReuse?{prefix:{sessionId:t,cacheRetention:r.cacheRetention}}:{}});u=`${u}\n\n---\n\n${a}`}return U.info(`Compaction complete: summary ${u.length} chars`),{summary:u,firstKeptIndex:e.messagesToSummarize.length,tokensBefore:e.tokensBefore,coverage:d}}},vt=class{name=`token-pressure`;evaluate(e){let t=B(e.compactionConfig.trigger,e.effectiveWindow),n=e.compactionConfig.hardCeilingFraction??Ae,r=yt(e.effectiveWindow,n);return e.estimate.bodyAfterPrefix>=t||e.estimate.total>=r}};function yt(e,t){return Math.floor(e*t)}var bt=class{name=`real-input`;evaluate(e){if(e.realInputTokens===void 0)return!1;let t=e.compactionConfig.hardCeilingFraction??Ae;return e.realInputTokens>=yt(e.effectiveWindow,t)}},xt=class{name=`residency`;evaluate(e){if(e.estimatedBytes===void 0)return!1;let t=e.maxContentBytes;return t===void 0?!1:e.estimatedBytes>=t*.9}};const St=[new vt,new bt,new xt];var Ct=class{name=`prune-token`;evaluate(e){let t=B(e.pruneConfig.trigger,e.effectiveWindow);return e.estimate.bodyAfterPrefix>=t}},wt=class{name=`prune-time-gap`;evaluate(e){let t=e.pruneConfig.timeBased;return t?.enabled!==!0||e.timeGapMs===void 0?!1:e.timeGapMs>(t.gapThresholdMs??60*6e4)}};const Tt=[new Ct,new wt],Et=e(`@x-otto/memory:archive`);var W=class{type=`memory`;archives=new Map;sessionIndex=new Map;async archive(e,t,n){let r=Date.now(),i=`memory://archives/${e}/compaction-${r}.md`,a=G(t,n,r);this.archives.set(i,{content:a,entry:{path:i,timestamp:r,summary:n.slice(0,200),messageCount:t.length}});let o=this.sessionIndex.get(e)??[];return o.push(i),this.sessionIndex.set(e,o),Et.info(`Archived ${t.length} messages for session ${e}`),i}async read(e){let t=this.archives.get(e);if(!t)throw Error(`Archive not found: ${e}`);return t.content}async list(e){return(this.sessionIndex.get(e)??[]).map(e=>this.archives.get(e)?.entry).filter(e=>e!==void 0)}forgetSession(e){let t=this.sessionIndex.get(e);if(t){for(let e of t)this.archives.delete(e);this.sessionIndex.delete(e)}}};function G(e,t,n){let r=[`## Compacted at ${new Date(n).toISOString()}`,``,`### Summary`,t,``,`### Original Messages (${e.length} messages)`];for(let t of e){let e=t.role===`user`?`Human`:t.role===`assistant`?`Assistant`:t.role===`tool_result`?`Tool[${t.toolName}]`:`System`,n=M(t),i=n.length>2e3?`${n.slice(0,2e3)}\n...(truncated, ${n.length} chars total)`:n;r.push(`\n**${e}**: ${i}`)}return r.join(`
152
+ `)}const Dt=e(`@x-otto/memory:archive-source`);var Ot=class{archiveIdCounter=new Map;constructor(e,t,n,r=new W){this.loadSessionEntries=e,this.messageFromEntry=t,this.clock=n,this.fallback=r}async record(e,t,n){let r=(this.archiveIdCounter.get(e)??0)+1;return this.archiveIdCounter.set(e,r),`archive:${e}:${r}`}async list(e){try{return await this.listFromEntries(e)}catch(t){return Dt.warn({error:t},`listArchives from session entries failed, falling back`),this.fallback.list(e)}}async read(e){try{let t=await this.readFromEntries(e);if(t!==null)return t}catch(e){Dt.warn({error:e},`readArchive from session entries failed, falling back`)}return this.fallback.read(e)}forgetSession(e){this.archiveIdCounter.delete(e),this.fallback.forgetSession?.(e)}async listFromEntries(e){let t=await this.loadSessionEntries(e),n=this.messageFromEntry,r=[],i=0;for(let a=0;a<t.length;a++){let o=t[a];if(o.type!==`compaction`)continue;let s=o.data;i++;let c=0,l=0;for(let e=a-1;e>=0;e--){let r=t[e];if(r.type===`compaction`)break;let i=n(r);i&&(c++,l=i.timestamp??l)}r.push({path:`archive:${e}:${i}`,timestamp:l||o.seq||0,messageCount:s.compactedCount,summary:s.summary.slice(0,200)})}return r}async readFromEntries(e){let t=e.match(/^archive:(.+):(\d+)$/);if(!t)return null;let n=t[1],r=parseInt(t[2],10),i=await this.loadSessionEntries(n),a=this.messageFromEntry,o=0,s=-1;for(let e=0;e<i.length;e++)if(i[e].type===`compaction`&&(o++,o===r)){s=e;break}if(s<0)return null;let c=i[s].data,l=-1;for(let e=s-1;e>=0;e--)if(i[e].type===`compaction`){l=e;break}let u=l+1,d=[];for(let e=u;e<s;e++){let t=a(i[e]);t&&d.push(t)}let f=this.clock.now();return G(d.filter(e=>e!==null),c.summary,f)}},kt=class{storage;constructor(e){this.storage=e??new W}async record(e,t,n){return this.storage.archive(e,t,n)}async list(e){return this.storage.list(e)}async read(e){return this.storage.read(e)}forgetSession(e){this.storage.forgetSession?.(e)}};function At(e,t,n,r){return e&&t?new Ot(e,t,n,r):new kt(r)}function jt(e){if(e.role===`assistant`&&e.usage){let{usage:t,...n}=e;return n}return e}const K=e(`@x-otto/memory`),q=`__default__`;function J(e){return e?.trim()||q}var Mt=class{persistent;archiveSource;estimateTokens;rawConfig;contextWindow;getContextWindow;compactionConfig;pruneConfig;maxContentBytes;getMaxContentBytes;getEstimatedBytes;getRealInputTokens;previousSummaries=new Map;compactionInFlight=new Set;compactionLock;compactionSpill;coverageGovernor;compactionBackend;compactionPolicies;prunePolicies;clock;constructor(e){let t=e.model?Je(e.model):{compaction:R,prune:z};this.compactionConfig={...t.compaction,...e.compaction},this.pruneConfig={...t.prune,...e.prune},this.contextWindow=e.model?.contextWindow??2e5,this.getContextWindow=e.getContextWindow,this.maxContentBytes=e.maxContentBytes,this.getMaxContentBytes=e.getMaxContentBytes,this.getEstimatedBytes=e.getEstimatedBytes,this.getRealInputTokens=e.getRealInputTokens,this.rawConfig=e,this.estimateTokens=e.estimateTokens??j,this.compactionLock=e.compactionLock,this.compactionSpill=e.compactionSpill,this.coverageGovernor=e.coverageGovernor??new lt,this.compactionBackend=new _t({summarize:e.summarize,estimateTokens:this.estimateTokens,getConfig:()=>this.effectiveCompactionConfig(),governor:this.coverageGovernor,spill:e.compactionSpill}),this.clock=e.clock??{now:()=>Date.now()},this.compactionPolicies=St,this.prunePolicies=Tt,this.archiveSource=At(e.loadSessionEntries,e.messageFromEntry,this.clock,e.archiveStorage),this.persistent=new ve(e.memoryStore??new D,e.sources,e.entryMtimes)}clearSession(e){this.previousSummaries.delete(J(e))}forgetSession(e){this.previousSummaries.delete(J(e)),this.coverageGovernor.forget(e),this.archiveSource.forgetSession?.(e)}reconfigure(e){let t=Je(e);this.contextWindow=e.contextWindow,this.compactionConfig={...t.compaction,...this.rawConfig.compaction},this.pruneConfig={...t.prune,...this.rawConfig.prune}}effectiveContextWindow(){return this.getContextWindow?.()??this.contextWindow}effectiveCompactionConfig(){return{...this.compactionConfig,contextWindow:this.effectiveContextWindow(),...(()=>{let e=this.rawConfig.getCoverageThresholds?.();return{...e?.warn===void 0?{}:{coverageWarnThreshold:e.warn},...e?.error===void 0?{}:{coverageErrorThreshold:e.error},...e?.floor===void 0?{}:{coverageFloorThreshold:e.floor}}})()}}async ensureFitsWindow(e,t,n){if(!this.needsCompaction(e))return{messages:[...e],compacted:!1};let r=await this.process(e,t,n,{force:!0});return{messages:r.messages,compacted:r.compacted,summary:r.summary,replacement:r.replacement}}async loadMemory(){await this.persistent.load()}getMemoryPrompt(){return this.persistent.getInjection()}async reloadMemory(){await this.persistent.reload()}getMemories(){return this.persistent.getMemories()}needsPrune(e){return this.needsPruneWith(F(e,this.estimateTokens),e)}needsPruneWith(e,t){let n=this.buildTriggerContext(e,t);return this.prunePolicies.some(e=>e.evaluate(n))}prune(e,t=!1){return this.pruneWith(e,F(e,this.estimateTokens),t)}pruneWith(e,t,n){let r=this.computeTimeGapMs(e);return Xe(e,this.effectiveContextWindow(),this.pruneConfig,this.estimateTokens,{currentTokens:t.total,force:n,timeGapMs:r})}needsCompaction(e){if(this.compactionConfig.enabled===!1)return!1;let t=this.buildTriggerContext(F(e,this.estimateTokens),e);return this.compactionPolicies.some(e=>e.evaluate(t))}isResidencyPressureActive(){let e=this.compactionPolicies.find(e=>e.name===`residency`);if(!e)return!1;let t=this.getMaxContentBytes?.()??this.maxContentBytes,n=this.getEstimatedBytes?.();return e.evaluate({estimate:{total:0,fromUsage:0,fromEstimate:0,lastUsageIndex:-1,derivedPrefix:0,bodyAfterPrefix:0},effectiveWindow:this.effectiveContextWindow(),compactionConfig:this.compactionConfig,pruneConfig:this.pruneConfig,clock:this.clock,...t===void 0?{}:{maxContentBytes:t},...n===void 0?{}:{estimatedBytes:n}})}buildTriggerContext(e,t){let n=this.getMaxContentBytes?.()??this.maxContentBytes,r=this.getEstimatedBytes?.();return{estimate:e,effectiveWindow:this.effectiveContextWindow(),compactionConfig:this.compactionConfig,pruneConfig:this.pruneConfig,clock:this.clock,...this.getRealInputTokens===void 0?{}:{realInputTokens:this.getRealInputTokens()},...n===void 0?{}:{maxContentBytes:n},...r===void 0?{}:{estimatedBytes:r},...t===void 0?{}:{timeGapMs:this.computeTimeGapMs(t)}}}computeTimeGapMs(e){if(this.pruneConfig.timeBased?.enabled!==!0)return;let t;for(let n=e.length-1;n>=0;n--){let r=e[n];if(r&&`timestamp`in r&&typeof r.timestamp==`number`){t=r.timestamp;break}}return t===void 0?void 0:this.clock.now()-t}isEligibleForManualCompact(e){return this.compactionBackend.isEligibleForManualCompact(e,this.effectiveContextWindow())}prepareCompaction(e,t,n){return this.compactionBackend.prepare(e,this.effectiveContextWindow(),this.previousSummaries.get(J(t)),n)}async compact(e,t,n){let r=await this.compactionBackend.compact(e,t,n),i=Math.min(this.compactionConfig.coverageFloorThreshold??this.rawConfig.getCoverageThresholds?.()?.floor??Ke,this.compactionConfig.coverageErrorThreshold??Ge);if(r.coverage<i&&(K.warn({sessionId:t,coverage:Number(r.coverage.toFixed(4)),floorThreshold:i},`[compaction] coverage below floor — boundary established WITH an explicit low-fidelity notice; a large portion of history is not represented in this summary (RFC-340 D1)`),r.summary=`${le(r.coverage)}\n\n${r.summary}`),t)try{await this.recordCompactionArchive(t,r,e.messagesToSummarize),K.info(`Compaction recorded at ${r.archivePath}`)}catch(e){K.warn({error:e},`Failed to record compaction archive`)}return this.previousSummaries.set(J(t),r.summary),r}async recordCompactionArchive(e,t,n){t.archivePath=await this.archiveSource.record(e,n,t.summary)}async process(e,t,r,i){let a=[...e],o=!1,s=!1,c,l,u,d,f=i?.force===!0,p=i?.skipPrune===!0,m=F(a,this.estimateTokens);if(!p&&(f||this.needsPruneWith(m,a))){let e=a.length,t=this.pruneWith(a,m,f);t.changed&&(a=t.messages,o=!0,d={prunedCount:t.prunedCount,tokensSaved:t.tokensSaved,messagesBefore:e,messagesAfter:a.length},K.info(`Prune: removed ${t.prunedCount} tool outputs, saved ~${t.tokensSaved} tokens`))}let h=this.compactionConfig.enabled!==!1;if(f?h:this.needsCompaction(a)){let e=J(t),i=`${process.pid}:${this.clock.now()}`;if(!(this.compactionLock?await this.compactionLock.acquire(t??q,i):!this.compactionInFlight.has(e)))K.info({sessionId:t},`Compaction already in flight for this session, skipping this round (will retry next round)`);else{this.compactionLock||this.compactionInFlight.add(e);try{let e=this.isResidencyPressureActive(),i=this.prepareCompaction(a,t,{force:f||e});if(i)try{let o=await this.compact(i,t,r);s=!0,c=o.summary,u=o.archivePath;let d={role:`user`,content:[{type:`text`,text:`${n}\n\n${u?ce(u,o.summary):o.summary}`}],timestamp:this.clock.now()};l=i.preservedMessages.map(jt),a=[d,...l],K.info({sessionId:t,trigger:f?`force`:e?`residency`:`token`},`Compaction: ${i.messagesToSummarize.length} messages → summary, kept ${i.preservedMessages.length}`)}catch(e){K.warn({error:e},`Compaction failed (LLM/summarizer error?), skipping compaction for this turn`)}}finally{this.compactionLock?await this.compactionLock.release(t??q,i).catch(()=>{}):this.compactionInFlight.delete(e)}}}return{messages:a,summary:c,replacement:l,archivePath:u,pruned:o,compacted:s,pruneMetrics:d}}async listArchives(e){return this.archiveSource.list(e)}async readArchive(e){return this.archiveSource.read(e)}dispose(){this.persistent.dispose()}};function Nt(e){return new Mt(e)}var Pt=class{baseUrl;userId;workspaceKeyGetter;isWorkspaceSyncEnabled;getAuth;fetchImpl;timeoutMs;local;onConflict;conflictCounters=new Map;knownVersions=new Map;constructor(e){this.baseUrl=e.baseUrl.replace(/\/+$/,``),this.userId=e.userId,this.workspaceKeyGetter=e.workspaceKey,this.isWorkspaceSyncEnabled=e.isWorkspaceSyncEnabled??(()=>!1),this.getAuth=e.getAuth,this.fetchImpl=e.fetch,this.timeoutMs=e.timeoutMs,this.local=new D(e.localDir,e.homeDirOverride),this.onConflict=e.onConflict}async load(e){let t=new Map,n=[];for(let r of e)if(this.userId&&Ft(r.path)){let e=await this.loadRemoteUser(r.path);e===null?n.push(r):(t.set(r.path,e),this.local.write(r.path,e).catch(()=>{}))}else if(this.isWorkspaceSourceEnabled(r.path)){let e=await this.loadRemoteWorkspace(r.path);e===null?n.push(r):(t.set(r.path,e),this.local.write(r.path,e).catch(()=>{}))}else n.push(r);if(n.length>0){let e=await this.local.load(n);for(let[n,r]of e)t.set(n,r)}return t}async write(e,t){await this.local.write(e,t),this.userId&&Ft(e)?this.writeRemoteUser(e,t).catch(()=>{}):this.isWorkspaceSourceEnabled(e)&&await this.writeRemoteWorkspace(e,t)}watch(e,t){return()=>{}}isWorkspaceSourceEnabled(e){return It(e)&&this.isWorkspaceSyncEnabled()&&!!this.workspaceKeyGetter?.()}remoteKey(e){let t=e.startsWith(`~/.otto/`)?e.slice(8):e;return`user:${this.userId}:${t}`}remoteResourceId(e){let t=e.startsWith(`~/.otto/`)?e.slice(8):e;return encodeURIComponent(t)}workspaceResourceId(e){let t=e.startsWith(`./.otto/`)?e.slice(8):e;return encodeURIComponent(t)}async loadRemoteUser(e){try{let t={Authorization:`Bearer ${(await this.getAuth()).token}`,Accept:`application/json`,"X-Otto-User-Id":this.userId},n=new AbortController,r=setTimeout(()=>n.abort(),this.timeoutMs);try{let r=await this.fetchImpl(`${this.baseUrl}/memory/user/${this.remoteResourceId(e)}`,{method:`GET`,headers:t,signal:n.signal});if(r.ok){let e=await r.json();if(typeof e.content==`string`)return e.content}if(r.status===404){let r=await this.fetchImpl(`${this.baseUrl}/sessions/${encodeURIComponent(this.remoteKey(e))}`,{method:`GET`,headers:t,signal:n.signal});if(r.ok){let e=await r.json();if(typeof e.content==`string`)return e.content}}}finally{clearTimeout(r)}}catch{}return null}async writeRemoteUser(e,t){try{let n={Authorization:`Bearer ${(await this.getAuth()).token}`,"Content-Type":`application/json`,"X-Otto-User-Id":this.userId},r=new AbortController,i=setTimeout(()=>r.abort(),this.timeoutMs);try{await this.fetchImpl(`${this.baseUrl}/memory/user/${this.remoteResourceId(e)}`,{method:`PUT`,headers:n,body:JSON.stringify({content:t}),signal:r.signal})}finally{clearTimeout(i)}}catch{}}async loadRemoteWorkspace(e){let t=this.workspaceKeyGetter?.();if(!t)return null;try{let n={Authorization:`Bearer ${(await this.getAuth()).token}`,Accept:`application/json`},r=new AbortController,i=setTimeout(()=>r.abort(),this.timeoutMs);try{let i=await this.fetchImpl(`${this.baseUrl}/memory/workspace/${encodeURIComponent(t)}/${this.workspaceResourceId(e)}`,{method:`GET`,headers:n,signal:r.signal});if(i.ok){let t=await i.json();if(typeof t.content==`string`)return typeof t.version==`number`&&this.knownVersions.set(e,t.version),t.content}}finally{clearTimeout(i)}}catch{}return null}async writeRemoteWorkspace(e,t){let n=this.workspaceKeyGetter?.();if(n)try{let r={Authorization:`Bearer ${(await this.getAuth()).token}`,"Content-Type":`application/json`},i=new AbortController,a=setTimeout(()=>i.abort(),this.timeoutMs),o=this.knownVersions.get(e)??0,s=o+1;try{let a=await this.fetchImpl(`${this.baseUrl}/memory/workspace/${encodeURIComponent(n)}/${this.workspaceResourceId(e)}`,{method:`PUT`,headers:r,body:JSON.stringify({content:t,version:s,expectedVersion:o}),signal:i.signal});if(a.status===409){await this.writeConflictSidecar(e,t);return}a.ok&&this.knownVersions.set(e,s)}finally{clearTimeout(a)}}catch{}}async writeConflictSidecar(e,t){let n=this.conflictCounters.get(e)??0,r=n%5;this.conflictCounters.set(e,n+1);let i=`${e}.conflict-${r}`;try{await this.local.write(i,t),this.onConflict?.(e,i)}catch{}}};function Ft(e){return e===`~/.otto/AGENTS.md`||e===`~/.otto/MEMORY.md`||e.startsWith(`~/.otto/memory/`)}function It(e){return e===`./.otto/MEMORY.md`||e.startsWith(`./.otto/memory/`)&&!e.startsWith(`./.otto/local/`)||e===`./.otto/lessons.json`}function Lt(e){let t=new Map;return{async load(n){let r=n.filter(e=>!t.has(e.path)),i=r.length>0?await e.load(r):new Map;for(let e of n){let n=t.get(e.path);n!==void 0&&i.set(e.path,n)}return i},async write(e,n){t.set(e,n)}}}function Rt(e,t={}){let n=t.fileName??`AGENTS.md`,a=t.rootMarkers??[`.git`],s=t.maxDepth??25,l=t.maxFiles??10,u=t.maxFileBytes??64*1024,d=[],f=e;for(let e=0;e<s;e++){let e=c(f,n);try{r(e)&&i(e).size<=u&&d.push(e)}catch{}let t=a.some(e=>r(c(f,e))),s=o(f);if(t||s===f)break;f=s}return d.reverse().slice(-l).map(e=>({path:e,writable:!1}))}const Y=e(`@x-otto/memory:auto`),X=`# MEMORY`,zt=/^- \[(.+?)\]\(memory\/(.+?)\.md\)/,Z=`./.otto/AGENTS.md`;function Bt(e,t,n){return`<!-- otto-memory:start slug="${e}" -->\n## ${t.replace(/[\r\n]+/g,` `).trim()}\n\n${n.trim()}\n<!-- otto-memory:end slug="${e}" -->`}function Vt(e){return RegExp(`<!-- otto-memory:start slug="${e}" -->[\\s\\S]*?<!-- otto-memory:end slug="${e}" -->`)}var Ht=class{store;baseDir;localBaseDir;index=``;localIndex=``;loaded=!1;localLoaded=!1;constructor(e){this.store=e.store,this.baseDir=(e.baseDir??`./.otto`).replace(/\/+$/,``),this.localBaseDir=(e.localBaseDir??`${this.baseDir}/local`).replace(/\/+$/,``)}get indexPath(){return`${this.baseDir}/MEMORY.md`}entryPathOf(e){return`${this.baseDir}/memory/${e}.md`}get localIndexPath(){return`${this.localBaseDir}/MEMORY.md`}localEntryPathOf(e){return`${this.localBaseDir}/memory/${e}.md`}asSource(){return{path:this.indexPath,writable:!0}}asLocalSource(){return{path:this.localIndexPath,writable:!0}}async load(){this.index=(await this.store.load([this.asSource()])).get(this.indexPath)??``,this.loaded=!0}async loadLocal(){this.localIndex=(await this.store.load([this.asLocalSource()])).get(this.localIndexPath)??``,this.localLoaded=!0}getInjection(){let e=this.index.trim();return e?`${e}\n\n> Auto-memory entries live in the memory store (\`${this.baseDir}/memory/\`), not workspace files — read them with the memory_read tool; record new durable facts with memory_record.`:``}getLocalInjection(){let e=this.localIndex.trim();return e?`${e}\n\n> Machine-specific memory entries live in \`${this.localBaseDir}/memory/\` — never synced to other devices. Read with memory_read; record with memory_record (scope: 'local').`:``}async record(e,t=`workspace`){if(t===`local`){await this.recordLocal(e);return}if(t===`project-shared`){await this.recordProjectShared(e);return}await this.ensureLoaded();let n=this.resolveSlug(e.name,this.indexLines());await this.store.write(this.entryPathOf(n),`# ${e.name}\n\n${e.content}\n`);let r=`- [${e.name}](memory/${n}.md) — ${e.description}`,i=this.indexLines().filter(e=>!e.includes(`(memory/${n}.md)`));i.some(e=>e.startsWith(X))||i.unshift(X),i.push(r),this.index=`${i.join(`
153
153
  `)}\n`,await this.store.write(this.indexPath,this.index),Y.info(`Auto-memory recorded: ${n}`)}async recordLocal(e){await this.ensureLocalLoaded();let t=this.resolveSlug(e.name,this.localIndexLines());await this.store.write(this.localEntryPathOf(t),`# ${e.name}\n\n${e.content}\n`);let n=`- [${e.name}](memory/${t}.md) — ${e.description}`,r=this.localIndexLines().filter(e=>!e.includes(`(memory/${t}.md)`));r.some(e=>e.startsWith(X))||r.unshift(X),r.push(n),this.localIndex=`${r.join(`
154
- `)}\n`,await this.store.write(this.localIndexPath,this.localIndex),Y.info(`Auto-memory recorded (local scope): ${t}`)}async recordProjectShared(e){let t=(await this.store.load([{path:Vt,writable:!0}])).get(Vt)??``,n=e.name.replace(/[\r\n]+/g,` `).trim(),r=RegExp(`<!-- otto-memory:start slug="([^"]+)" -->\\n## ${Gt(n)}\\n`).exec(t)?.[1]??Z(e.name),i=Ht(r,e.name,e.content),a=Ut(r),o;o=a.test(t)?t.replace(a,i):t.trim()===``?`# 项目记忆(模型经 memory_record(scope: "project-shared") 写入,人工可编辑本文件任意内容)
155
- \n${i}\n`:`${t.trimEnd()}\n\n${i}\n`,await this.store.write(Vt,o),Y.info(`Auto-memory recorded (project-shared scope): ${r}`)}async read(e){await this.ensureLoaded();let t=this.slugByName(e,this.indexLines())??Z(e),n=this.entryPathOf(t),r=await this.readEntry(n);if(r!==null)return await this.withConflictLabel(n,r);await this.ensureLocalLoaded();let i=this.slugByName(e,this.localIndexLines())??Z(e),a=this.localEntryPathOf(i),o=await this.readEntry(a);return o===null?null:await this.withConflictLabel(a,o)}async withConflictLabel(e,t){for(let n=0;n<5;n++){let r=`${e}.conflict-${n}`;if(await this.readEntry(r)!==null)return`[CONFLICT] Concurrent edit detected for "${e}" — review "${r}" and reconcile manually.\n\n${t}`}return t}async readEntry(e){let t=(await this.store.load([{path:e,writable:!1}])).get(e);return t&&t.trim()!==``?t:null}async forget(e){await this.ensureLoaded(),await this.ensureLocalLoaded();let t=this.slugByName(e,this.indexLines())??Z(e);this.index=`${this.indexLines().filter(e=>!e.includes(`(memory/${t}.md)`)).join(`
154
+ `)}\n`,await this.store.write(this.localIndexPath,this.localIndex),Y.info(`Auto-memory recorded (local scope): ${t}`)}async recordProjectShared(e){let t=(await this.store.load([{path:Z,writable:!0}])).get(Z)??``,n=e.name.replace(/[\r\n]+/g,` `).trim(),r=RegExp(`<!-- otto-memory:start slug="([^"]+)" -->\\n## ${Ut(n)}\\n`).exec(t)?.[1]??Q(e.name),i=Bt(r,e.name,e.content),a=Vt(r),o;o=a.test(t)?t.replace(a,i):t.trim()===``?`# 项目记忆(模型经 memory_record(scope: "project-shared") 写入,人工可编辑本文件任意内容)
155
+ \n${i}\n`:`${t.trimEnd()}\n\n${i}\n`,await this.store.write(Z,o),Y.info(`Auto-memory recorded (project-shared scope): ${r}`)}async read(e){await this.ensureLoaded();let t=this.slugByName(e,this.indexLines())??Q(e),n=this.entryPathOf(t),r=await this.readEntry(n);if(r!==null)return await this.withConflictLabel(n,r);await this.ensureLocalLoaded();let i=this.slugByName(e,this.localIndexLines())??Q(e),a=this.localEntryPathOf(i),o=await this.readEntry(a);return o===null?null:await this.withConflictLabel(a,o)}async withConflictLabel(e,t){for(let n=0;n<5;n++){let r=`${e}.conflict-${n}`;if(await this.readEntry(r)!==null)return`[CONFLICT] Concurrent edit detected for "${e}" — review "${r}" and reconcile manually.\n\n${t}`}return t}async readEntry(e){let t=(await this.store.load([{path:e,writable:!1}])).get(e);return t&&t.trim()!==``?t:null}async forget(e){await this.ensureLoaded(),await this.ensureLocalLoaded();let t=this.slugByName(e,this.indexLines())??Q(e);this.index=`${this.indexLines().filter(e=>!e.includes(`(memory/${t}.md)`)).join(`
156
156
  `)}\n`,await this.store.write(this.indexPath,this.index),await this.store.write(this.entryPathOf(t),``);let n=this.slugByName(e,this.localIndexLines());n&&(this.localIndex=`${this.localIndexLines().filter(e=>!e.includes(`(memory/${n}.md)`)).join(`
157
157
  `)}\n`,await this.store.write(this.localIndexPath,this.localIndex),await this.store.write(this.localEntryPathOf(n),``))}async ensureLoaded(){this.loaded||await this.load()}async ensureLocalLoaded(){this.localLoaded||await this.loadLocal()}indexLines(){return this.index.split(`
158
158
  `).filter(e=>e.trim()!==``)}localIndexLines(){return this.localIndex.split(`
159
- `).filter(e=>e.trim()!==``)}slugByName(e,t){for(let n of t){let t=Bt.exec(n);if(t&&t[1]===e)return t[2]??null}return null}resolveSlug(e,t){let n=this.slugByName(e,t);if(n)return n;let r=new Map;for(let e of t){let t=Bt.exec(e);t&&t[1]!==void 0&&t[2]!==void 0&&r.set(t[2],t[1])}let i=Z(e),a=i,o=2;for(;r.has(a)&&r.get(a)!==e;)a=`${i}-${o}`,o+=1;return a}};function Z(e){return e.toLowerCase().replace(/[^a-z0-9一-鿿]+/g,`-`).replace(/^-+|-+$/g,``)}function Gt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}const Kt=e(`@x-otto/memory:extractor`);async function qt(e,t,n,r={}){let i=Yt(e);if(!i.trim())return[];let a;try{a=await n(ce(i),{maxTokens:r.maxTokens??2048,signal:r.signal})}catch(e){return Kt.debug(`extraction LLM call failed (fail-closed → []): ${String(e)}`),[]}let o=Xt(a);if(!o)return[];let s=r.maxLessons??5,c=[];for(let e of o){let n=Zt(e,t);if(n&&c.push(n),c.length>=s)break}return c}async function Jt(e,t,n={}){let r=[],i=0;for(let a of t){let{lesson:t,deduped:o}=await e.saveDeduped(a,n.similarityThreshold);o?i++:r.push(t)}return{saved:r,skippedSimilar:i}}function Yt(e){return e.map(e=>`${e.role===`user`?`Human`:e.role===`assistant`?`Assistant`:e.role===`tool_result`?`Tool[${e.toolName??`unknown`}]`:`System`}: ${j(e)}`).join(`
159
+ `).filter(e=>e.trim()!==``)}slugByName(e,t){for(let n of t){let t=zt.exec(n);if(t&&t[1]===e)return t[2]??null}return null}resolveSlug(e,t){let n=this.slugByName(e,t);if(n)return n;let r=new Map;for(let e of t){let t=zt.exec(e);t&&t[1]!==void 0&&t[2]!==void 0&&r.set(t[2],t[1])}let i=Q(e),a=i,o=2;for(;r.has(a)&&r.get(a)!==e;)a=`${i}-${o}`,o+=1;return a}};function Q(e){return e.toLowerCase().replace(/[^a-z0-9一-鿿]+/g,`-`).replace(/^-+|-+$/g,``)}function Ut(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}const Wt=e(`@x-otto/memory:extractor`);async function Gt(e,t,n,r={}){let i=qt(e);if(!i.trim())return[];let a;try{a=await n(se(i),{maxTokens:r.maxTokens??2048,signal:r.signal})}catch(e){return Wt.debug(`extraction LLM call failed (fail-closed → []): ${String(e)}`),[]}let o=Jt(a);if(!o)return[];let s=r.maxLessons??5,c=[];for(let e of o){let n=Yt(e,t);if(n&&c.push(n),c.length>=s)break}return c}async function Kt(e,t,n={}){let r=[],i=0;for(let a of t){let{lesson:t,deduped:o}=await e.saveDeduped(a,n.similarityThreshold);o?i++:r.push(t)}return{saved:r,skippedSimilar:i}}function qt(e){return e.map(e=>`${e.role===`user`?`Human`:e.role===`assistant`?`Assistant`:e.role===`tool_result`?`Tool[${e.toolName??`unknown`}]`:`System`}: ${M(e)}`).join(`
160
160
 
161
- `)}function Xt(e){let t=e.indexOf(`[`),n=e.lastIndexOf(`]`);if(t===-1||n===-1||n<t)return null;try{let r=JSON.parse(e.slice(t,n+1));return Array.isArray(r)?r:null}catch{return null}}function Zt(e,t){if(!e||typeof e!=`object`)return null;let n=typeof e.trigger==`string`?e.trigger.trim():``,r=typeof e.insight==`string`?e.insight.trim():``;if(!n||!r)return null;let i=Array.isArray(e.tags)?e.tags.filter(e=>typeof e==`string`&&e.trim().length>0).map(e=>e.trim().toLowerCase()).slice(0,5):[];return{trigger:n.slice(0,500),insight:r.slice(0,2e3),tags:i,sourceSessionId:t}}const Qt=e(`@x-otto/memory:auto-extract`);function $t(e){return e===`learn`||e===`memory_record`}function en(e,t){for(let n of e)if(n.role===`assistant`){for(let e of n.content)if(e.type===`tool_call`&&t(e.name))return!0}return!1}function tn(e){let t=new Map,n=e.isMemoryWriteTool??$t,r=()=>Math.max(1,e.config.everyNTurns??1);function i(e){let n=t.get(e);return n||(n={lastExtractedIndex:0,idleCount:0},t.set(e,n)),n}let a=(e=0,t=0,n)=>({ran:n===void 0,reason:n,saved:e,skippedSimilar:t});return{async onIdle(t,o,s){if(!e.config.enabled)return a(0,0,`disabled`);let c=i(t),l=o.slice(c.lastExtractedIndex);if(l.length===0)return a(0,0,`no-new-messages`);if(c.idleCount+=1,c.idleCount<r())return a(0,0,`throttled`);let u=e.config.minRelevantHits;if(u!==void 0&&(e.readRelevantHits?await e.readRelevantHits():-1)<u)return e.readRelevantHits||Qt.warn(`auto-extract minRelevantHits=${u} set but readRelevantHits port missing — failing closed (no extraction) to avoid bypassing the configured threshold`),a(0,0,`below-relevant-hits-low-water`);let d=()=>{c.lastExtractedIndex=o.length,c.idleCount=0};if(en(l,n))return d(),a(0,0,`main-agent-wrote`);try{let n=await qt(l,t,e.llm,{maxTokens:e.config.maxTokens,maxLessons:e.config.maxLessons,signal:s?.signal}),r=await Jt(e.store,n,{similarityThreshold:e.config.similarityThreshold});return d(),n.length>0&&Qt.info({sessionId:t,extracted:n.length,saved:r.saved.length,deduped:r.skippedSimilar},`memory-auto-extract`),a(r.saved.length,r.skippedSimilar)}catch(e){return Qt.warn(`auto-extract failed (fail-closed): ${String(e)}`),a(0,0,`error`)}},reset(e){t.delete(e)}}}const nn=new Set([`node_modules`,`.git`,`dist`,`.next`,`.turbo`,`coverage`,`.cache`,`__pycache__`,`.vscode`]);var rn=class{lastSnapshot=null;async capture(e){let[t,n]=await Promise.all([this.buildDirectoryTree(e.workspaceDir,0),this.checkRecentFiles(e.workspaceDir,e.recentFiles??[])]),r=[];n.length>0&&r.push(`${n.length} recently modified file(s) detected`);let i={timestamp:Date.now(),directoryTree:t,modifiedFiles:n,planStatus:e.planStatus,findings:r};return this.lastSnapshot=i,i}getLastSnapshot(){return this.lastSnapshot}formatSnapshot(e){let t=[`[File State Snapshot @ ${new Date(e.timestamp).toISOString()}]`];if(e.directoryTree&&t.push(`Directory:\n${e.directoryTree}`),e.modifiedFiles.length>0){let n=e.modifiedFiles.map(e=>` ${e.action}: ${e.path} — ${e.summary}`).join(`
161
+ `)}function Jt(e){let t=e.indexOf(`[`),n=e.lastIndexOf(`]`);if(t===-1||n===-1||n<t)return null;try{let r=JSON.parse(e.slice(t,n+1));return Array.isArray(r)?r:null}catch{return null}}function Yt(e,t){if(!e||typeof e!=`object`)return null;let n=typeof e.trigger==`string`?e.trigger.trim():``,r=typeof e.insight==`string`?e.insight.trim():``;if(!n||!r)return null;let i=Array.isArray(e.tags)?e.tags.filter(e=>typeof e==`string`&&e.trim().length>0).map(e=>e.trim().toLowerCase()).slice(0,5):[];return{trigger:n.slice(0,500),insight:r.slice(0,2e3),tags:i,sourceSessionId:t}}const Xt=e(`@x-otto/memory:auto-extract`);function Zt(e){return e===`learn`||e===`memory_record`}function Qt(e,t){for(let n of e)if(n.role===`assistant`){for(let e of n.content)if(e.type===`tool_call`&&t(e.name))return!0}return!1}function $t(e){let t=new Map,n=e.isMemoryWriteTool??Zt,r=()=>Math.max(1,e.config.everyNTurns??1);function i(e){let n=t.get(e);return n||(n={lastExtractedIndex:0,idleCount:0},t.set(e,n)),n}let a=(e=0,t=0,n)=>({ran:n===void 0,reason:n,saved:e,skippedSimilar:t});return{async onIdle(t,o,s){if(!e.config.enabled)return a(0,0,`disabled`);let c=i(t),l=o.slice(c.lastExtractedIndex);if(l.length===0)return a(0,0,`no-new-messages`);if(c.idleCount+=1,c.idleCount<r())return a(0,0,`throttled`);let u=e.config.minRelevantHits;if(u!==void 0&&(e.readRelevantHits?await e.readRelevantHits():-1)<u)return e.readRelevantHits||Xt.warn(`auto-extract minRelevantHits=${u} set but readRelevantHits port missing — failing closed (no extraction) to avoid bypassing the configured threshold`),a(0,0,`below-relevant-hits-low-water`);let d=()=>{c.lastExtractedIndex=o.length,c.idleCount=0};if(Qt(l,n))return d(),a(0,0,`main-agent-wrote`);try{let n=await Gt(l,t,e.llm,{maxTokens:e.config.maxTokens,maxLessons:e.config.maxLessons,signal:s?.signal}),r=await Kt(e.store,n,{similarityThreshold:e.config.similarityThreshold});return d(),n.length>0&&Xt.info({sessionId:t,extracted:n.length,saved:r.saved.length,deduped:r.skippedSimilar},`memory-auto-extract`),a(r.saved.length,r.skippedSimilar)}catch(e){return Xt.warn(`auto-extract failed (fail-closed): ${String(e)}`),a(0,0,`error`)}},reset(e){t.delete(e)}}}const en=new Set([`node_modules`,`.git`,`dist`,`.next`,`.turbo`,`coverage`,`.cache`,`__pycache__`,`.vscode`]);var tn=class{lastSnapshot=null;async capture(e){let[t,n]=await Promise.all([this.buildDirectoryTree(e.workspaceDir,0),this.checkRecentFiles(e.workspaceDir,e.recentFiles??[])]),r=[];n.length>0&&r.push(`${n.length} recently modified file(s) detected`);let i={timestamp:Date.now(),directoryTree:t,modifiedFiles:n,planStatus:e.planStatus,findings:r};return this.lastSnapshot=i,i}getLastSnapshot(){return this.lastSnapshot}formatSnapshot(e){let t=[`[File State Snapshot @ ${new Date(e.timestamp).toISOString()}]`];if(e.directoryTree&&t.push(`Directory:\n${e.directoryTree}`),e.modifiedFiles.length>0){let n=e.modifiedFiles.map(e=>` ${e.action}: ${e.path} — ${e.summary}`).join(`
162
162
  `);t.push(`Modified Files:\n${n}`)}return e.planStatus&&t.push(`Plan Status: ${e.planStatus}`),e.findings.length>0&&t.push(`Findings:\n${e.findings.map(e=>` - ${e}`).join(`
163
163
  `)}`),t.join(`
164
164
 
165
- `)}async buildDirectoryTree(e,t,n=``){if(t>=4)return n?`${n}...\n`:``;let r;try{r=(await u(e,{withFileTypes:!0})).filter(e=>!nn.has(e.name)&&!e.name.startsWith(`.`)).sort((e,t)=>e.isDirectory()===t.isDirectory()?e.name.localeCompare(t.name):e.isDirectory()?-1:1).slice(0,50).map(e=>e.name+(e.isDirectory()?`/`:``))}catch{return``}let i=[];for(let a of r){let r=a.endsWith(`/`);if(i.push(`${n}${a}`),r){let r=await this.buildDirectoryTree(c(e,a.slice(0,-1)),t+1,n+` `);r&&i.push(r.trimEnd())}}return i.join(`
166
- `)}async checkRecentFiles(e,t){let n=[],r=Date.now();for(let i of t){let t=i.startsWith(`/`)?i:c(e,i),a=l(e,t);try{let e=await d(t),i=r-e.mtimeMs,o=e.birthtimeMs>0&&e.mtimeMs-e.birthtimeMs<1e3?`created`:`modified`,s=`${(e.size/1024).toFixed(1)}KB, modified ${an(i)} ago`;n.push({path:a,action:o,summary:s})}catch{n.push({path:a,action:`deleted`,summary:`file not found`})}}return n}};function an(e){let t=Math.floor(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return n<60?`${n}m`:`${Math.floor(n/60)}h`}var on=class{records=[];now;persist;logWarn;constructor(e={}){this.now=e.now??(()=>Date.now()),this.persist=e.persist,this.logWarn=e.logWarn}append(e){let t={...e,at:this.now()};this.records.push(t),this.persist&&this.persist.append(t).catch(e=>{this.logWarn?.(`Failed to persist evolution signal`,e)})}projectRelevantHits(e){return e.map(e=>({kind:`relevant.hits`,key:e.id,value:e.relevantHitCount??0}))}appendRelevantHits(e){for(let t of this.projectRelevantHits(e))this.append(t)}list(){return this.records}counts(){let e=new Map;for(let t of this.records){let n=`${t.kind}:${t.key}`,r=e.get(n)??{kind:t.kind,key:t.key,total:0,records:0,lastAt:t.at};r.total+=t.value,r.records+=1,r.lastAt=t.at,e.set(n,r)}return[...e.values()]}async restoreFromLog(){if(!this.persist)return 0;try{let e=await this.persist.load();return this.records.length=0,this.records.push(...e),e.length}catch(e){return this.logWarn?.(`Failed to restore evolution signal log; starting empty`,e),0}}async close(){await this.persist?.close?.()}get size(){return this.records.length}};const sn=`signals`,cn={encode:e=>JSON.stringify(e),decode:e=>JSON.parse(e)};function ln(e){let t=new f({baseDir:e,extension:`.jsonl`,codec:cn});return{async append(e){return t.append(sn,e)},load:async()=>{let e=[];for await(let{entry:n}of t.read(sn))e.push(n);return e},async close(){await t.close?.()}}}const un=new Set([`archived`,`tombstone`]),dn=.6;function fn(e){return new Set(e.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter(e=>e.length>2))}function pn(e,t){if(e.size===0||t.size===0)return 0;let n=0;for(let r of e)t.has(r)&&n++;return n/(e.size+t.size-n)}const mn=new Set([1,2]);function hn(e){let t=`[${e.tags.join(`, `)}] ${e.trigger} → ${e.insight}`,n=0;for(let e of t)/[\u3000-\u9fff\uff00-\uffef]/.test(e)&&n++;return Math.ceil(n+(t.length-n)/4)}function gn(e){let t=JSON.stringify({tags:[...e.tags].sort(),trigger:e.trigger,insight:e.insight}),n=2166136261;for(let e=0;e<t.length;e++)n^=t.charCodeAt(e),n=Math.imul(n,16777619)>>>0;return n.toString(16).padStart(8,`0`)}function Q(e,t){let n=e,r=e.relevantHitCount??n.appliedCount??0,i={...n,scope:e.scope??t,state:e.state??`active`,contentHash:e.contentHash??gn(e),estimatedTokens:e.estimatedTokens??hn(e),relevantHitCount:r,coreInjectedCount:e.coreInjectedCount??0,hitCountTotal:e.hitCountTotal??r};return i.appliedCount===void 0&&delete i.appliedCount,i}function $(e){if(!e||typeof e!=`object`)return;let t=e;if(t.version!==void 0&&mn.has(t.version)&&t.data)return t.data;let n=e;if(n.version===void 0&&Array.isArray(n.lessons))return e}var _n=class{lessons=new Map;nextId=1;loaded=!1;governanceDirty=!1;snapshotId;persistence;store;storePath;logger;scope;ephemeral;now;constructor(e){if(this.logger=e?.logger,this.scope=e?.scope,this.ephemeral=e?.ephemeral??!1,this.now=e?.now??(()=>Date.now()),e?.store)this.store=e.store,this.storePath=e.storePath??e.path;else if(e?.path){let t=s(e.path)||`.json`;this.snapshotId=a(e.path,t),this.persistence=p({type:`file`,baseDir:o(e.path),extension:t})}}async save(e){await this.ensureLoaded();let t=`lesson_${this.nextId++}`,n=Q({...e,id:t,createdAt:this.now()},this.scope);return this.lessons.set(t,n),await this.persist(),n}async archiveLessons(e){await this.ensureLoaded();let t=[],n=[];for(let r of e){let e=this.lessons.get(r);if(!e){n.push({id:r,reason:`not found`});continue}if(e.pinned){n.push({id:r,reason:`pinned`});continue}if(e.state===`live`){n.push({id:r,reason:`live (referenced by current session stable snapshot)`});continue}e.state=`archived`,t.push(r)}return t.length>0&&(this.governanceDirty=!0,await this.persist()),{archived:t,skipped:n}}async search(e,t=5){await this.ensureLoaded();let n=e.toLowerCase(),r=[];for(let e of this.lessons.values()){let t=0;e.trigger.toLowerCase().includes(n)&&(t+=3),e.insight.toLowerCase().includes(n)&&(t+=2);for(let r of e.tags)r.toLowerCase().includes(n)&&(t+=1);t>0&&r.push({lesson:e,score:t})}let i=r.sort((e,t)=>t.score-e.score).slice(0,t).map(e=>(e.lesson.relevantHitCount=(e.lesson.relevantHitCount??0)+1,e.lesson.hitCountTotal=(e.lesson.hitCountTotal??0)+1,e.lesson.lastAccessedAt=this.now(),e.lesson));return await this.persist(),i}async findSimilar(e,t,n=dn){await this.ensureLoaded();let r=fn(`${e} ${t}`);if(r.size===0)return;let i;for(let e of this.lessons.values()){let t=pn(r,fn(`${e.trigger} ${e.insight}`));t>=n&&(!i||t>i.similarity)&&(i={lesson:e,similarity:t})}return i}async saveDeduped(e,t=dn){let n=await this.findSimilar(e.trigger,e.insight,t);return n?{lesson:n.lesson,deduped:!0}:{lesson:await this.save(e),deduped:!1}}async list(e){await this.ensureLoaded();let t=[...this.lessons.values()];if(e?.includeArchived||(t=t.filter(e=>!un.has(e.state??`active`))),e?.tags&&e.tags.length>0){let n=new Set(e.tags);t=t.filter(e=>e.tags.some(e=>n.has(e)))}if(e?.query){let n=e.query.toLowerCase();t=t.filter(e=>e.trigger.toLowerCase().includes(n)||e.insight.toLowerCase().includes(n))}return t}async get(e){return await this.ensureLoaded(),this.lessons.get(e)}async recordRelevantHits(e,t=this.now()){await this.ensureLoaded();let n=!1;for(let r of e){let e=this.lessons.get(r);e&&(e.relevantHitCount=(e.relevantHitCount??0)+1,e.hitCountTotal=(e.hitCountTotal??0)+1,e.lastAccessedAt=t,n=!0)}n&&await this.persist()}async delete(e){await this.ensureLoaded();let t=this.lessons.delete(e);return t&&await this.persist(),t}get size(){return this.lessons.size}async ensureLoaded(){if(!this.loaded){if(this.store&&this.storePath){await this.loadFromStore(),this.loaded=!0;return}if(!this.persistence||!this.snapshotId){this.loaded=!0;return}try{let e=$(await this.persistence.load(this.snapshotId));if(e){for(let t of e.lessons)this.lessons.set(t.id,Q(t,this.scope));this.nextId=e.nextId??this.lessons.size+1}}catch(e){this.logger?.warn(`Failed to load lessons from file persistence (snapshotId=${this.snapshotId}): ${String(e)}. Falling back to empty lessons — all previously learned lessons will be lost for this session.`)}this.loaded=!0}}async refresh(){!this.store||!this.storePath||(await this.loadFromStore(),this.loaded=!0)}async loadFromStore(){try{let e=(await this.store.load([{path:this.storePath,writable:!0}])).get(this.storePath);if(!e)return;let t=$(JSON.parse(e));if(t){for(let e of t.lessons)this.lessons.set(e.id,Q(e,this.scope));this.nextId=t.nextId??this.lessons.size+1}}catch(e){this.logger?.warn(`Failed to load lessons from MemoryStore (storePath=${this.storePath}): ${String(e)}. Falling back to empty lessons — all previously learned lessons will be lost for this session.`)}}async mergeGovernanceFieldsFromDisk(){let e=[...this.lessons.values()];if(this.governanceDirty)return e;let t;try{if(this.store&&this.storePath){let e=(await this.store.load([{path:this.storePath,writable:!0}])).get(this.storePath);if(e){let n=$(JSON.parse(e));n&&(t=new Map(n.lessons.map(e=>[e.id,e])))}}else if(this.persistence&&this.snapshotId){let e=$(await this.persistence.load(this.snapshotId));e&&(t=new Map(e.lessons.map(e=>[e.id,e])))}}catch{return e}return t?e.map(e=>{let n=t.get(e.id);if(!n)return e;let r={...e};return n.state!==void 0&&(r.state=n.state),n.pinned!==void 0&&(r.pinned=n.pinned),n.supersededBy!==void 0&&(r.supersededBy=n.supersededBy),n.class!==void 0&&(r.class=n.class),r}):e}async persist(){if(this.ephemeral)return;let e=await this.mergeGovernanceFieldsFromDisk();if(this.store&&this.storePath){let t={lessons:e,nextId:this.nextId};await this.store.write(this.storePath,JSON.stringify({version:2,data:t}));return}if(!this.persistence||!this.snapshotId)return;let t=this.now();await m(this.persistence,this.snapshotId,{lessons:e,nextId:this.nextId},{version:2,tags:[`operational-learning`],now:t,preserveCreatedAt:!1})}};export{Wt as AutoMemory,R as DEFAULT_COMPACTION_CONFIG,h as DEFAULT_MEMORY_INJECTION_BUDGET_TOKENS,de as DEFAULT_MEMORY_SOURCES,z as DEFAULT_PRUNE_CONFIG,dn as DEFAULT_SIMILARITY_THRESHOLD,on as EvolutionSignalStore,rn as FileStateManager,xe as FileSystemMemoryStore,Ft as HttpMemoryStore,we as IMAGE_BLOCK_TOKEN_ESTIMATE,G as InMemoryArchiveStorage,be as InMemoryMemoryStore,se as LESSON_EXTRACTION_PROMPT,Nt as MemoryManager,_n as OperationalLearningStore,ye as PersistentMemory,re as SEGMENT_MERGE_PROMPT,ne as SEGMENT_SUMMARIZATION_PROMPT,C as SUMMARIZATION_PROMPT,ee as TURN_PREFIX_SUMMARIZATION_PROMPT,w as UPDATE_SUMMARIZATION_PROMPT,te as WITH_PRESERVED_TAIL_PROMPT,le as buildArchiveReference,ce as buildExtractionPrompt,ue as buildLowCoverageNotice,b as buildMemoryInjection,ae as buildSegmentMergePrompt,T as buildSummarizationPrompt,oe as buildTurnPrefixPrompt,gn as computeLessonContentHash,L as computeMemoryDefaults,tn as createMemoryAutoExtractor,Pt as createMemoryManager,Rt as createOverlayMemoryStore,ln as createSignalLog,zt as discoverAgentsSources,Ce as ensureTokenizer,hn as estimateLessonTokens,M as estimateMessageTokens,N as estimateMessagesTokens,A as estimateTokens,k as estimateTokensHeuristic,qt as extractLessons,K as formatArchive,V as formatMessageForSummary,j as messageToText,Ze as prune,B as resolveContextSize,Jt as saveExtractedLessons};
165
+ `)}async buildDirectoryTree(e,t,n=``){if(t>=4)return n?`${n}...\n`:``;let r;try{r=(await u(e,{withFileTypes:!0})).filter(e=>!en.has(e.name)&&!e.name.startsWith(`.`)).sort((e,t)=>e.isDirectory()===t.isDirectory()?e.name.localeCompare(t.name):e.isDirectory()?-1:1).slice(0,50).map(e=>e.name+(e.isDirectory()?`/`:``))}catch{return``}let i=[];for(let a of r){let r=a.endsWith(`/`);if(i.push(`${n}${a}`),r){let r=await this.buildDirectoryTree(c(e,a.slice(0,-1)),t+1,n+` `);r&&i.push(r.trimEnd())}}return i.join(`
166
+ `)}async checkRecentFiles(e,t){let n=[],r=Date.now();for(let i of t){let t=i.startsWith(`/`)?i:c(e,i),a=l(e,t);try{let e=await d(t),i=r-e.mtimeMs,o=e.birthtimeMs>0&&e.mtimeMs-e.birthtimeMs<1e3?`created`:`modified`,s=`${(e.size/1024).toFixed(1)}KB, modified ${nn(i)} ago`;n.push({path:a,action:o,summary:s})}catch{n.push({path:a,action:`deleted`,summary:`file not found`})}}return n}};function nn(e){let t=Math.floor(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return n<60?`${n}m`:`${Math.floor(n/60)}h`}const rn=new Set([`archived`,`tombstone`]),an=.6;function on(e){return new Set(e.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter(e=>e.length>2))}function sn(e,t){if(e.size===0||t.size===0)return 0;let n=0;for(let r of e)t.has(r)&&n++;return n/(e.size+t.size-n)}const cn=new Set([1,2]);function ln(e){let t=`[${e.tags.join(`, `)}] ${e.trigger} → ${e.insight}`,n=0;for(let e of t)/[\u3000-\u9fff\uff00-\uffef]/.test(e)&&n++;return Math.ceil(n+(t.length-n)/4)}function un(e){let t=JSON.stringify({tags:[...e.tags].sort(),trigger:e.trigger,insight:e.insight}),n=2166136261;for(let e=0;e<t.length;e++)n^=t.charCodeAt(e),n=Math.imul(n,16777619)>>>0;return n.toString(16).padStart(8,`0`)}function dn(e,t){let n=e,r=e.relevantHitCount??n.appliedCount??0,i={...n,scope:e.scope??t,state:e.state??`active`,contentHash:e.contentHash??un(e),estimatedTokens:e.estimatedTokens??ln(e),relevantHitCount:r,coreInjectedCount:e.coreInjectedCount??0,hitCountTotal:e.hitCountTotal??r};return i.appliedCount===void 0&&delete i.appliedCount,i}function $(e){if(!e||typeof e!=`object`)return;let t=e;if(t.version!==void 0&&cn.has(t.version)&&t.data)return t.data;let n=e;if(n.version===void 0&&Array.isArray(n.lessons))return e}var fn=class{lessons=new Map;nextId=1;loaded=!1;governanceDirty=!1;snapshotId;persistence;store;storePath;logger;scope;ephemeral;now;constructor(e){if(this.logger=e?.logger,this.scope=e?.scope,this.ephemeral=e?.ephemeral??!1,this.now=e?.now??(()=>Date.now()),e?.store)this.store=e.store,this.storePath=e.storePath??e.path;else if(e?.path){let t=s(e.path)||`.json`;this.snapshotId=a(e.path,t),this.persistence=f({type:`file`,baseDir:o(e.path),extension:t})}}async save(e){await this.ensureLoaded();let t=`lesson_${this.nextId++}`,n=dn({...e,id:t,createdAt:this.now()},this.scope);return this.lessons.set(t,n),await this.persist(),n}async archiveLessons(e){await this.ensureLoaded();let t=[],n=[];for(let r of e){let e=this.lessons.get(r);if(!e){n.push({id:r,reason:`not found`});continue}if(e.pinned){n.push({id:r,reason:`pinned`});continue}if(e.state===`live`){n.push({id:r,reason:`live (referenced by current session stable snapshot)`});continue}e.state=`archived`,t.push(r)}return t.length>0&&(this.governanceDirty=!0,await this.persist()),{archived:t,skipped:n}}async search(e,t=5){await this.ensureLoaded();let n=e.toLowerCase(),r=[];for(let e of this.lessons.values()){let t=0;e.trigger.toLowerCase().includes(n)&&(t+=3),e.insight.toLowerCase().includes(n)&&(t+=2);for(let r of e.tags)r.toLowerCase().includes(n)&&(t+=1);t>0&&r.push({lesson:e,score:t})}let i=r.sort((e,t)=>t.score-e.score).slice(0,t).map(e=>(e.lesson.relevantHitCount=(e.lesson.relevantHitCount??0)+1,e.lesson.hitCountTotal=(e.lesson.hitCountTotal??0)+1,e.lesson.lastAccessedAt=this.now(),e.lesson));return await this.persist(),i}async findSimilar(e,t,n=an){await this.ensureLoaded();let r=on(`${e} ${t}`);if(r.size===0)return;let i;for(let e of this.lessons.values()){let t=sn(r,on(`${e.trigger} ${e.insight}`));t>=n&&(!i||t>i.similarity)&&(i={lesson:e,similarity:t})}return i}async saveDeduped(e,t=an){let n=await this.findSimilar(e.trigger,e.insight,t);return n?{lesson:n.lesson,deduped:!0}:{lesson:await this.save(e),deduped:!1}}async list(e){await this.ensureLoaded();let t=[...this.lessons.values()];if(e?.includeArchived||(t=t.filter(e=>!rn.has(e.state??`active`))),e?.tags&&e.tags.length>0){let n=new Set(e.tags);t=t.filter(e=>e.tags.some(e=>n.has(e)))}if(e?.query){let n=e.query.toLowerCase();t=t.filter(e=>e.trigger.toLowerCase().includes(n)||e.insight.toLowerCase().includes(n))}return t}async get(e){return await this.ensureLoaded(),this.lessons.get(e)}async recordRelevantHits(e,t=this.now()){await this.ensureLoaded();let n=!1;for(let r of e){let e=this.lessons.get(r);e&&(e.relevantHitCount=(e.relevantHitCount??0)+1,e.hitCountTotal=(e.hitCountTotal??0)+1,e.lastAccessedAt=t,n=!0)}n&&await this.persist()}async delete(e){await this.ensureLoaded();let t=this.lessons.delete(e);return t&&await this.persist(),t}get size(){return this.lessons.size}async ensureLoaded(){if(!this.loaded){if(this.store&&this.storePath){await this.loadFromStore(),this.loaded=!0;return}if(!this.persistence||!this.snapshotId){this.loaded=!0;return}try{let e=$(await this.persistence.load(this.snapshotId));if(e){for(let t of e.lessons)this.lessons.set(t.id,dn(t,this.scope));this.nextId=e.nextId??this.lessons.size+1}}catch(e){this.logger?.warn(`Failed to load lessons from file persistence (snapshotId=${this.snapshotId}): ${String(e)}. Falling back to empty lessons — all previously learned lessons will be lost for this session.`)}this.loaded=!0}}async refresh(){!this.store||!this.storePath||(await this.loadFromStore(),this.loaded=!0)}async loadFromStore(){try{let e=(await this.store.load([{path:this.storePath,writable:!0}])).get(this.storePath);if(!e)return;let t=$(JSON.parse(e));if(t){for(let e of t.lessons)this.lessons.set(e.id,dn(e,this.scope));this.nextId=t.nextId??this.lessons.size+1}}catch(e){this.logger?.warn(`Failed to load lessons from MemoryStore (storePath=${this.storePath}): ${String(e)}. Falling back to empty lessons — all previously learned lessons will be lost for this session.`)}}async mergeGovernanceFieldsFromDisk(){let e=[...this.lessons.values()];if(this.governanceDirty)return e;let t;try{if(this.store&&this.storePath){let e=(await this.store.load([{path:this.storePath,writable:!0}])).get(this.storePath);if(e){let n=$(JSON.parse(e));n&&(t=new Map(n.lessons.map(e=>[e.id,e])))}}else if(this.persistence&&this.snapshotId){let e=$(await this.persistence.load(this.snapshotId));e&&(t=new Map(e.lessons.map(e=>[e.id,e])))}}catch{return e}return t?e.map(e=>{let n=t.get(e.id);if(!n)return e;let r={...e};return n.state!==void 0&&(r.state=n.state),n.pinned!==void 0&&(r.pinned=n.pinned),n.supersededBy!==void 0&&(r.supersededBy=n.supersededBy),n.class!==void 0&&(r.class=n.class),r}):e}async persist(){if(this.ephemeral)return;let e=await this.mergeGovernanceFieldsFromDisk();if(this.store&&this.storePath){let t={lessons:e,nextId:this.nextId};await this.store.write(this.storePath,JSON.stringify({version:2,data:t}));return}if(!this.persistence||!this.snapshotId)return;let t=this.now();await p(this.persistence,this.snapshotId,{lessons:e,nextId:this.nextId},{version:2,tags:[`operational-learning`],now:t,preserveCreatedAt:!1})}};export{Ht as AutoMemory,R as DEFAULT_COMPACTION_CONFIG,m as DEFAULT_MEMORY_INJECTION_BUDGET_TOKENS,ue as DEFAULT_MEMORY_SOURCES,z as DEFAULT_PRUNE_CONFIG,an as DEFAULT_SIMILARITY_THRESHOLD,tn as FileStateManager,D as FileSystemMemoryStore,Pt as HttpMemoryStore,Se as IMAGE_BLOCK_TOKEN_ESTIMATE,W as InMemoryArchiveStorage,ye as InMemoryMemoryStore,oe as LESSON_EXTRACTION_PROMPT,Mt as MemoryManager,fn as OperationalLearningStore,ve as PersistentMemory,ne as SEGMENT_MERGE_PROMPT,te as SEGMENT_SUMMARIZATION_PROMPT,S as SUMMARIZATION_PROMPT,w as TURN_PREFIX_SUMMARIZATION_PROMPT,C as UPDATE_SUMMARIZATION_PROMPT,ee as WITH_PRESERVED_TAIL_PROMPT,ce as buildArchiveReference,se as buildExtractionPrompt,le as buildLowCoverageNotice,y as buildMemoryInjection,ie as buildSegmentMergePrompt,T as buildSummarizationPrompt,ae as buildTurnPrefixPrompt,un as computeLessonContentHash,Je as computeMemoryDefaults,$t as createMemoryAutoExtractor,Nt as createMemoryManager,Lt as createOverlayMemoryStore,Rt as discoverAgentsSources,xe as ensureTokenizer,ln as estimateLessonTokens,N as estimateMessageTokens,P as estimateMessagesTokens,j as estimateTokens,A as estimateTokensHeuristic,Gt as extractLessons,G as formatArchive,V as formatMessageForSummary,M as messageToText,Xe as prune,B as resolveContextSize,Kt as saveExtractedLessons};
167
167
  //# sourceMappingURL=index.js.map