@cortexkit/opencode-magic-context 0.3.2 → 0.3.3
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/agents/magic-context-prompt.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-prompt.d.ts +1 -1
- package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-formatting.d.ts +3 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/index.js +85 -3
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"magic-context-prompt.d.ts","sourceRoot":"","sources":["../../src/agents/magic-context-prompt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,KAAK,SAAS,GACR,UAAU,GACV,OAAO,GACP,YAAY,GACZ,iBAAiB,GACjB,QAAQ,GACR,QAAQ,GACR,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"magic-context-prompt.d.ts","sourceRoot":"","sources":["../../src/agents/magic-context-prompt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,KAAK,SAAS,GACR,UAAU,GACV,OAAO,GACP,YAAY,GACZ,iBAAiB,GACjB,QAAQ,GACR,QAAQ,GACR,eAAe,CAAC;AA4LtB;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAOlF;AAED,wBAAgB,wBAAwB,CACpC,KAAK,EAAE,SAAS,GAAG,IAAI,EACvB,aAAa,EAAE,MAAM,EACrB,gBAAgB,UAAO,EACvB,cAAc,UAAQ,GACvB,MAAM,CAUR"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const COMPARTMENT_AGENT_SYSTEM_PROMPT = "You condense long AI coding sessions into two outputs:\n\n1. compartments: completed logical work units\n2. facts: persistent cross-cutting information for future work\n\nCompartment rules:\n- A compartment is one contiguous completed work unit: investigation, fix, refactor, docs update, feature, or decision.\n- Start a new compartment only when the work clearly pivots to a different objective.\n- Do not create compartments for magic-context commands or tool-only noise.\n- If the input ends mid-topic, leave it out and report its first message index in <unprocessed_from>.\n- All compartment start/end ordinals and <unprocessed_from> must use the absolute raw message numbers shown in the input. Never renumber relative to this chunk.\n- Only emit NEW compartments for the new messages. Do not re-emit existing compartments from the existing state.\n- Write comprehensive, detailed compartments. Include file paths, function names, commit hashes, config keys, and values when they matter.\n- Do not list every changed file. Do not narrate tool calls. Do not preserve dead-end exploration beyond a brief clause when needed.\n\nUser message preservation:\n- Include high-signal user messages verbatim inside compartments, prefixed with U:.\n- A high-signal user message states a goal, constraint, design decision, direction, preference, or rationale.\n- Drop trivial messages: yes, continue, I agree, thanks, looks good, go ahead, and similar low-signal steering.\n- Drop large pasted text unless it contains durable rules or requirements; summarize its gist instead.\n- Place U: lines at the point in the summary where the user's direction changed the work.\n- Limit to 3-5 U: lines per compartment \u2014 keep only the most important ones.\n\nCompartment example:\n<compartment start=\"50\" end=\"120\" title=\"Built the LSP stack\">\nU: We need inline diagnostics on every edit, not just on-demand\nImplemented in-process LSP client with per-server reader threads and crossbeam-channel delivery. Added inline edit diagnostics to write, edit, and apply_patch. commits: a3f891, b22c4e\nU: Ship this as 0.2.0\nUpdated docs and publish automation, released v0.2.0.\n</compartment>\n\nFact rules:\n- Facts are editable state, not append-only notes. Rewrite, normalize, deduplicate, or drop existing facts whenever needed.\n- Before emitting any fact, check all existing facts in the same category for semantic duplicates. If two facts describe the same decision, constraint, or default with different wording, merge them into one canonical statement. Never emit two facts that could be answered by the same question.\n- When project memories are provided as read-only reference, drop any session fact that is already covered by a project memory. Project memories are the canonical cross-session source; session facts must not duplicate them.\n- Facts must be durable and actionable after the conversation ends.\n- A fact is either a stable invariant/default or a reusable operating rule. If it mainly explains what happened, it belongs in a compartment, not a fact.\n- Facts belong only in these categories when relevant: WORKFLOW_RULES, ARCHITECTURE_DECISIONS, CONSTRAINTS, CONFIG_DEFAULTS, KNOWN_ISSUES, ENVIRONMENT, NAMING, USER_PREFERENCES, USER_DIRECTIVES.\n- Keep only high-signal facts. Omit greetings, acknowledgements, temporary status, one-off sequencing, branch-local tactics, and task-local cleanup notes.\n- When a user message carries durable goals, constraints, preferences, or decision rationale, add a USER_DIRECTIVES fact when future agents should follow it after the session is compacted.\n- Do not turn task-local details into facts.\n- Do not keep stale facts. Rewrite or drop them even if the new input only implies they are obsolete.\n- Keep existing ARCHITECTURE_DECISIONS and CONSTRAINTS facts when they are still valid and uncontradicted; rewrite them into canonical form instead of dropping them.\n- Facts must be present tense and operational. Do not use chronology or provenance wording such as: initially, currently, remained, previously, later, then, was implemented, we changed, used to.\n- One fact bullet must contain exactly one rule/default/constraint/preference. If a candidate fact mixes history with guidance, keep the guidance and drop the history.\n- Durability test: a future agent should still act correctly on the fact next session, after merge/restart, without rereading the conversation.\n- Category guide:\n - WORKFLOW_RULES: standing repeatable process only. Prefer Do/When form: When <condition>, <action>. Do not store one-off branch strategy or task-specific sequencing unless it is standing policy.\n - ARCHITECTURE_DECISIONS: stable design choice. Use: <component> uses <choice> because <reason>.\n - CONSTRAINTS: hard must/must-not rule or invariant. Use: <thing> must/must not <action> because <reason>.\n - CONFIG_DEFAULTS: stable default only. Use: <key>=<value>.\n - KNOWN_ISSUES: unresolved recurring problem only. Do not store solved-issue stories.\n - ENVIRONMENT: stable setup fact that affects future work.\n - NAMING: canonical term choice. Use: Use <term>; avoid <term>.\n - USER_PREFERENCES: durable user preference. Prefer Do/When form.\n - USER_DIRECTIVES: durable user-stated goal, constraint, preference, or rationale. Keep the user's wording when it carries meaning, but narrow it to 1-3 sentences and remove filler.\n- Fact dedup examples:\n - These are DUPLICATES (merge into one): \"Plugin config uses layered JSONC files\" and \"AFT plugin config uses layered JSONC files at ~/.config/opencode/aft.jsonc and <project>/.opencode/aft.jsonc, with project values deep-merging over user values.\" \u2192 keep the longer, more specific version only.\n - These are NOT duplicates (keep both): \"AFT uses 1-based line numbers\" and \"AFT converts to LSP 0-based UTF-16 at the protocol boundary\" \u2192 different aspects of the same system.\n- Fact rewrite examples:\n - Bad ARCHITECTURE_DECISIONS: The new tool-heavy `ctx_reduce` reminder was initially implemented as a hidden instruction appended to the latest user message in `transform`.\n - Good ARCHITECTURE_DECISIONS: `ctx_reduce` turn reminders are injected into the latest user message in `transform`.\n - Bad WORKFLOW_RULES: Current local workflow remained feat -> integrate -> build for code changes.\n - Good WORKFLOW_RULES (only if this is standing policy): For magic-context changes, commit on `feat/magic-context`, cherry-pick to `integrate/athena-magic-context`, run `bun run build` on integrate, then return to `feat/magic-context`.\n\nInput notes:\n- [N] or [N-M] is a stable raw OpenCode message range.\n- U: means user.\n- A: means assistant.\n- commits: ... on an assistant block lists commit hashes mentioned in that work unit; keep the relevant ones in the compartment summary when they matter.\n
|
|
1
|
+
export declare const COMPARTMENT_AGENT_SYSTEM_PROMPT = "You condense long AI coding sessions into two outputs:\n\n1. compartments: completed logical work units\n2. facts: persistent cross-cutting information for future work\n\nCompartment rules:\n- A compartment is one contiguous completed work unit: investigation, fix, refactor, docs update, feature, or decision.\n- Start a new compartment only when the work clearly pivots to a different objective.\n- Do not create compartments for magic-context commands or tool-only noise.\n- If the input ends mid-topic, leave it out and report its first message index in <unprocessed_from>.\n- All compartment start/end ordinals and <unprocessed_from> must use the absolute raw message numbers shown in the input. Never renumber relative to this chunk.\n- Only emit NEW compartments for the new messages. Do not re-emit existing compartments from the existing state.\n- Write comprehensive, detailed compartments. Include file paths, function names, commit hashes, config keys, and values when they matter.\n- Do not list every changed file. Do not narrate tool calls. Do not preserve dead-end exploration beyond a brief clause when needed.\n\nUser message preservation:\n- Include high-signal user messages verbatim inside compartments, prefixed with U:.\n- A high-signal user message states a goal, constraint, design decision, direction, preference, or rationale.\n- Drop trivial messages: yes, continue, I agree, thanks, looks good, go ahead, and similar low-signal steering.\n- Drop large pasted text unless it contains durable rules or requirements; summarize its gist instead.\n- Place U: lines at the point in the summary where the user's direction changed the work.\n- Limit to 3-5 U: lines per compartment \u2014 keep only the most important ones.\n\nCompartment example:\n<compartment start=\"50\" end=\"120\" title=\"Built the LSP stack\">\nU: We need inline diagnostics on every edit, not just on-demand\nImplemented in-process LSP client with per-server reader threads and crossbeam-channel delivery. Added inline edit diagnostics to write, edit, and apply_patch. commits: a3f891, b22c4e\nU: Ship this as 0.2.0\nUpdated docs and publish automation, released v0.2.0.\n</compartment>\n\nFact rules:\n- Facts are editable state, not append-only notes. Rewrite, normalize, deduplicate, or drop existing facts whenever needed.\n- Before emitting any fact, check all existing facts in the same category for semantic duplicates. If two facts describe the same decision, constraint, or default with different wording, merge them into one canonical statement. Never emit two facts that could be answered by the same question.\n- When project memories are provided as read-only reference, drop any session fact that is already covered by a project memory. Project memories are the canonical cross-session source; session facts must not duplicate them.\n- Facts must be durable and actionable after the conversation ends.\n- A fact is either a stable invariant/default or a reusable operating rule. If it mainly explains what happened, it belongs in a compartment, not a fact.\n- Facts belong only in these categories when relevant: WORKFLOW_RULES, ARCHITECTURE_DECISIONS, CONSTRAINTS, CONFIG_DEFAULTS, KNOWN_ISSUES, ENVIRONMENT, NAMING, USER_PREFERENCES, USER_DIRECTIVES.\n- Keep only high-signal facts. Omit greetings, acknowledgements, temporary status, one-off sequencing, branch-local tactics, and task-local cleanup notes.\n- When a user message carries durable goals, constraints, preferences, or decision rationale, add a USER_DIRECTIVES fact when future agents should follow it after the session is compacted.\n- Do not turn task-local details into facts.\n- Do not keep stale facts. Rewrite or drop them even if the new input only implies they are obsolete.\n- Keep existing ARCHITECTURE_DECISIONS and CONSTRAINTS facts when they are still valid and uncontradicted; rewrite them into canonical form instead of dropping them.\n- Facts must be present tense and operational. Do not use chronology or provenance wording such as: initially, currently, remained, previously, later, then, was implemented, we changed, used to.\n- One fact bullet must contain exactly one rule/default/constraint/preference. If a candidate fact mixes history with guidance, keep the guidance and drop the history.\n- Durability test: a future agent should still act correctly on the fact next session, after merge/restart, without rereading the conversation.\n- Category guide:\n - WORKFLOW_RULES: standing repeatable process only. Prefer Do/When form: When <condition>, <action>. Do not store one-off branch strategy or task-specific sequencing unless it is standing policy.\n - ARCHITECTURE_DECISIONS: stable design choice. Use: <component> uses <choice> because <reason>.\n - CONSTRAINTS: hard must/must-not rule or invariant. Use: <thing> must/must not <action> because <reason>.\n - CONFIG_DEFAULTS: stable default only. Use: <key>=<value>.\n - KNOWN_ISSUES: unresolved recurring problem only. Do not store solved-issue stories.\n - ENVIRONMENT: stable setup fact that affects future work.\n - NAMING: canonical term choice. Use: Use <term>; avoid <term>.\n - USER_PREFERENCES: durable user preference. Prefer Do/When form.\n - USER_DIRECTIVES: durable user-stated goal, constraint, preference, or rationale. Keep the user's wording when it carries meaning, but narrow it to 1-3 sentences and remove filler.\n- Fact dedup examples:\n - These are DUPLICATES (merge into one): \"Plugin config uses layered JSONC files\" and \"AFT plugin config uses layered JSONC files at ~/.config/opencode/aft.jsonc and <project>/.opencode/aft.jsonc, with project values deep-merging over user values.\" \u2192 keep the longer, more specific version only.\n - These are NOT duplicates (keep both): \"AFT uses 1-based line numbers\" and \"AFT converts to LSP 0-based UTF-16 at the protocol boundary\" \u2192 different aspects of the same system.\n- Fact rewrite examples:\n - Bad ARCHITECTURE_DECISIONS: The new tool-heavy `ctx_reduce` reminder was initially implemented as a hidden instruction appended to the latest user message in `transform`.\n - Good ARCHITECTURE_DECISIONS: `ctx_reduce` turn reminders are injected into the latest user message in `transform`.\n - Bad WORKFLOW_RULES: Current local workflow remained feat -> integrate -> build for code changes.\n - Good WORKFLOW_RULES (only if this is standing policy): For magic-context changes, commit on `feat/magic-context`, cherry-pick to `integrate/athena-magic-context`, run `bun run build` on integrate, then return to `feat/magic-context`.\n\nInput notes:\n- [N] or [N-M] is a stable raw OpenCode message range.\n- U: means user.\n- A: means assistant.\n- TC: means tool call \u2014 a compact summary of what the agent did (e.g., \"TC: Fix lint errors\", \"TC: read(src/index.ts)\", \"TC: grep(ctx_memory)\"). TC lines appear when there is no text describing the action. Use them to understand what happened between text blocks, but do not copy them verbatim into compartments \u2014 incorporate their meaning into the narrative.\n- commits: ... on an assistant block lists commit hashes mentioned in that work unit; keep the relevant ones in the compartment summary when they matter.\n\nOutput valid XML only in this shape:\n<output>\n<compartments>\n<compartment start=\"FIRST\" end=\"LAST\" title=\"short title\">\nU: Verbatim high-signal user message\nSummary text describing what was done and why.\nU: Another high-signal user message if applicable\nMore summary text.\n</compartment>\n</compartments>\n<facts>\n<WORKFLOW_RULES>\n* Fact text\n</WORKFLOW_RULES>\n</facts>\n<meta>\n<messages_processed>FIRST-LAST</messages_processed>\n<unprocessed_from>INDEX</unprocessed_from>\n</meta>\n</output>\n\nOmit empty fact categories. Compartments must be ordered, contiguous for the ranges they cover, and non-overlapping.";
|
|
2
2
|
export declare const COMPRESSOR_AGENT_SYSTEM_PROMPT = "You compress older compartments from a long AI coding session to fit within a token budget.\n\nYou receive a set of compartments that are over budget. Your job is to merge and shorten them so the total output is approximately the target token count.\n\nRules:\n- You have full authority over which compartments to merge and which to keep separate.\n- Merged compartments must cover the same start-to-end range as the originals they replace.\n- Drop verbatim U: (user message) lines from merged compartments. Instead, summarize the user's key intent in the prose: \"User directed X. Implemented Y.\"\n- Keep summaries outcome-focused. Mention file paths, function names, commit hashes, and config keys only when they matter conceptually.\n- You may merge 2-5 adjacent compartments into one broader compartment when they share a theme or phase of work.\n- You may keep a compartment separate but shorten its summary.\n- Do not add new information. Do not invent details not present in the input.\n- Compartments must remain ordered and non-overlapping.\n- Preserve the start and end ordinals exactly from the original compartments.\n\nOutput valid XML only in this shape:\n<output>\n<compartments>\n<compartment start=\"FIRST\" end=\"LAST\" title=\"short title\">Compressed summary text.</compartment>\n</compartments>\n</output>";
|
|
3
3
|
export declare function buildCompressorPrompt(compartments: Array<{
|
|
4
4
|
startMessage: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compartment-prompt.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/compartment-prompt.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,+BAA+B,
|
|
1
|
+
{"version":3,"file":"compartment-prompt.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/compartment-prompt.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,+BAA+B,4rPA6FyE,CAAC;AAEtH,eAAO,MAAM,8BAA8B,ozCAoBjC,CAAC;AAEX,wBAAgB,qBAAqB,CACjC,YAAY,EAAE,KAAK,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC,EACF,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,GACrB,MAAM,CAgBR;AAED,wBAAgB,2BAA2B,CAAC,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAiB9F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-session-chunk.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/read-session-chunk.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"read-session-chunk.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/read-session-chunk.ts"],"names":[],"mappings":"AAGA,OAAO,EAWH,KAAK,gBAAgB,EACxB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,KAAK,UAAU,EAAgC,MAAM,oBAAoB,CAAC;AAGnF,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAIhF,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,MAAM,WAAW,YAAY;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,4GAA4G;IAC5G,kBAAkB,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAgB,0BAA0B,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAa5D;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE,CAatE;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBjG;AAID,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAStE;AAED,wBAAgB,gBAAgB,CAC5B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,GAAE,MAAU,EAClB,kBAAkB,CAAC,EAAE,MAAM,GAC5B,YAAY,CAmJd;AAED,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAK9F"}
|
|
@@ -12,6 +12,9 @@ export interface ChunkBlock {
|
|
|
12
12
|
}
|
|
13
13
|
export declare function hasMeaningfulUserText(parts: unknown[]): boolean;
|
|
14
14
|
export declare function extractTexts(parts: unknown[]): string[];
|
|
15
|
+
/** Extract compact tool-call summaries from message parts.
|
|
16
|
+
* Returns lines like "TC: Fix lint errors" or "TC: read(src/index.ts)". */
|
|
17
|
+
export declare function extractToolCallSummaries(parts: unknown[]): string[];
|
|
15
18
|
export declare function estimateTokens(text: string): number;
|
|
16
19
|
export declare function normalizeText(text: string): string;
|
|
17
20
|
export declare function compactRole(role: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-session-formatting.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/read-session-formatting.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;CAC1B;AAMD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAiB/D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,CAUvD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIhD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAQrD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAW1D;AAED,wBAAgB,qBAAqB,CACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACb;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,CAmB1C;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAS9E"}
|
|
1
|
+
{"version":3,"file":"read-session-formatting.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/read-session-formatting.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;CAC1B;AAMD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAiB/D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,CAUvD;AAED;4EAC4E;AAC5E,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,CA2BnE;AAwBD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIhD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAQrD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAW1D;AAED,wBAAgB,qBAAqB,CACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACb;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,CAmB1C;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAS9E"}
|
package/dist/index.js
CHANGED
|
@@ -14879,8 +14879,8 @@ Input notes:
|
|
|
14879
14879
|
- [N] or [N-M] is a stable raw OpenCode message range.
|
|
14880
14880
|
- U: means user.
|
|
14881
14881
|
- A: means assistant.
|
|
14882
|
+
- TC: means tool call \u2014 a compact summary of what the agent did (e.g., "TC: Fix lint errors", "TC: read(src/index.ts)", "TC: grep(ctx_memory)"). TC lines appear when there is no text describing the action. Use them to understand what happened between text blocks, but do not copy them verbatim into compartments \u2014 incorporate their meaning into the narrative.
|
|
14882
14883
|
- commits: ... on an assistant block lists commit hashes mentioned in that work unit; keep the relevant ones in the compartment summary when they matter.
|
|
14883
|
-
- Tool-only noise is already stripped before you see the input.
|
|
14884
14884
|
|
|
14885
14885
|
Output valid XML only in this shape:
|
|
14886
14886
|
<output>
|
|
@@ -15666,6 +15666,54 @@ function extractTexts(parts) {
|
|
|
15666
15666
|
}
|
|
15667
15667
|
return texts;
|
|
15668
15668
|
}
|
|
15669
|
+
function extractToolCallSummaries(parts) {
|
|
15670
|
+
const summaries = [];
|
|
15671
|
+
for (const part of parts) {
|
|
15672
|
+
if (part === null || typeof part !== "object")
|
|
15673
|
+
continue;
|
|
15674
|
+
const p = part;
|
|
15675
|
+
if (p.type !== "tool" || typeof p.tool !== "string")
|
|
15676
|
+
continue;
|
|
15677
|
+
const state = p.state;
|
|
15678
|
+
if (!state || typeof state !== "object")
|
|
15679
|
+
continue;
|
|
15680
|
+
const input = state.input;
|
|
15681
|
+
const metadata = state.metadata;
|
|
15682
|
+
const description = input && typeof input.description === "string" && input.description || metadata && typeof metadata.description === "string" && metadata.description;
|
|
15683
|
+
if (description) {
|
|
15684
|
+
summaries.push(`TC: ${description}`);
|
|
15685
|
+
continue;
|
|
15686
|
+
}
|
|
15687
|
+
const toolName = p.tool;
|
|
15688
|
+
const keyArg = extractKeyArg(toolName, input);
|
|
15689
|
+
summaries.push(keyArg ? `TC: ${toolName}(${keyArg})` : `TC: ${toolName}`);
|
|
15690
|
+
}
|
|
15691
|
+
return summaries;
|
|
15692
|
+
}
|
|
15693
|
+
function extractKeyArg(_toolName, input) {
|
|
15694
|
+
if (!input)
|
|
15695
|
+
return null;
|
|
15696
|
+
if (typeof input.filePath === "string")
|
|
15697
|
+
return truncateArg(input.filePath);
|
|
15698
|
+
if (typeof input.path === "string")
|
|
15699
|
+
return truncateArg(input.path);
|
|
15700
|
+
if (typeof input.pattern === "string")
|
|
15701
|
+
return truncateArg(input.pattern);
|
|
15702
|
+
if (typeof input.query === "string")
|
|
15703
|
+
return truncateArg(input.query);
|
|
15704
|
+
if (typeof input.symbol === "string")
|
|
15705
|
+
return input.symbol;
|
|
15706
|
+
if (typeof input.module === "string")
|
|
15707
|
+
return input.module;
|
|
15708
|
+
if (typeof input.action === "string")
|
|
15709
|
+
return input.action;
|
|
15710
|
+
return null;
|
|
15711
|
+
}
|
|
15712
|
+
function truncateArg(value, maxLen = 60) {
|
|
15713
|
+
if (value.length <= maxLen)
|
|
15714
|
+
return value;
|
|
15715
|
+
return `${value.slice(0, maxLen)}\u2026`;
|
|
15716
|
+
}
|
|
15669
15717
|
function estimateTokens(text) {
|
|
15670
15718
|
return Math.ceil(text.length / 3.5);
|
|
15671
15719
|
}
|
|
@@ -15922,11 +15970,37 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
15922
15970
|
continue;
|
|
15923
15971
|
const meta3 = { ordinal: msg.ordinal, messageId: msg.id };
|
|
15924
15972
|
if (msg.role === "user" && !hasMeaningfulUserText(msg.parts)) {
|
|
15925
|
-
|
|
15973
|
+
const tcSummaries = extractToolCallSummaries(msg.parts);
|
|
15974
|
+
if (tcSummaries.length === 0) {
|
|
15975
|
+
pendingNoiseMeta.push(meta3);
|
|
15976
|
+
continue;
|
|
15977
|
+
}
|
|
15978
|
+
const tcText = tcSummaries.join(" / ");
|
|
15979
|
+
if (currentBlock && currentBlock.role === "A") {
|
|
15980
|
+
currentBlock.endOrdinal = msg.ordinal;
|
|
15981
|
+
currentBlock.parts.push(tcText);
|
|
15982
|
+
currentBlock.meta.push(...pendingNoiseMeta, meta3);
|
|
15983
|
+
pendingNoiseMeta = [];
|
|
15984
|
+
} else {
|
|
15985
|
+
if (!flushCurrentBlock())
|
|
15986
|
+
break;
|
|
15987
|
+
currentBlock = {
|
|
15988
|
+
role: "A",
|
|
15989
|
+
startOrdinal: pendingNoiseMeta[0]?.ordinal ?? msg.ordinal,
|
|
15990
|
+
endOrdinal: msg.ordinal,
|
|
15991
|
+
parts: [tcText],
|
|
15992
|
+
meta: [...pendingNoiseMeta, meta3],
|
|
15993
|
+
commitHashes: []
|
|
15994
|
+
};
|
|
15995
|
+
pendingNoiseMeta = [];
|
|
15996
|
+
}
|
|
15926
15997
|
continue;
|
|
15927
15998
|
}
|
|
15928
15999
|
const role = compactRole(msg.role);
|
|
15929
|
-
const
|
|
16000
|
+
const textParts = extractTexts(msg.parts).map((t) => msg.role === "user" ? cleanUserText(t) : t).map(normalizeText).filter((value) => value.length > 0);
|
|
16001
|
+
const toolSummaries = textParts.length === 0 ? extractToolCallSummaries(msg.parts) : [];
|
|
16002
|
+
const allParts = [...textParts, ...toolSummaries];
|
|
16003
|
+
const compacted = compactTextForSummary(allParts.join(" / "), msg.role);
|
|
15930
16004
|
const text = compacted.text;
|
|
15931
16005
|
if (!text) {
|
|
15932
16006
|
pendingNoiseMeta.push(meta3);
|
|
@@ -22237,6 +22311,10 @@ Use \`ctx_reduce\` to manage context size. It supports one operation:
|
|
|
22237
22311
|
Syntax: "3-5", "1,2,9", or "1-5,8,12-15". Last ${protectedTags} tags are protected.
|
|
22238
22312
|
Use \`ctx_note\` for deferred intentions \u2014 things to tackle later, not right now. NOT for task tracking (use todos). Notes survive context compression and you'll be reminded at natural work boundaries (after commits, historian runs, todo completion).
|
|
22239
22313
|
Use \`ctx_memory\` to manage cross-session project memories. Write new memories or delete stale ones. Memories persist across sessions and are automatically injected into new sessions.
|
|
22314
|
+
**Save to memory proactively**: If you spent multiple turns finding something (a file path, a DB location, a config pattern, a workaround), save it with \`ctx_memory\` so future sessions don't repeat the search. Examples:
|
|
22315
|
+
- Found a project's source code path after searching \u2192 \`ctx_memory(action="write", category="ENVIRONMENT", content="OpenCode source is at ~/Work/OSS/opencode")\`
|
|
22316
|
+
- Discovered a non-obvious build/test command \u2192 \`ctx_memory(action="write", category="WORKFLOW_RULES", content="Always use scripts/release.sh for releases")\`
|
|
22317
|
+
- Learned a constraint the hard way \u2192 \`ctx_memory(action="write", category="CONSTRAINTS", content="Dashboard Tauri build needs RGBA PNGs, not grayscale")\`
|
|
22240
22318
|
Use \`ctx_search\` to search across project memories, session facts, and conversation history from one query.
|
|
22241
22319
|
Use \`ctx_expand\` to decompress a compartment range to see the original conversation transcript. Use \`start\`/\`end\` from \`<compartment start=N end=M>\` attributes. Returns the compacted U:/A: transcript for that message range, capped at ~15K tokens.
|
|
22242
22320
|
**Search before asking the user**: If you can't remember or don't know something that might have been discussed before or stored in project memory, use \`ctx_search\` before asking the user. Examples:
|
|
@@ -22253,6 +22331,10 @@ Before your turn finishes, consider using \`ctx_reduce\` to drop large tool outp
|
|
|
22253
22331
|
var BASE_INTRO_NO_REDUCE = `Messages and tool outputs are tagged with \xA7N\xA7 identifiers (e.g., \xA71\xA7, \xA742\xA7).
|
|
22254
22332
|
Use \`ctx_note\` for deferred intentions \u2014 things to tackle later, not right now. NOT for task tracking (use todos). Notes survive context compression and you'll be reminded at natural work boundaries (after commits, historian runs, todo completion).
|
|
22255
22333
|
Use \`ctx_memory\` to manage cross-session project memories. Write new memories or delete stale ones. Memories persist across sessions and are automatically injected into new sessions.
|
|
22334
|
+
**Save to memory proactively**: If you spent multiple turns finding something (a file path, a DB location, a config pattern, a workaround), save it with \`ctx_memory\` so future sessions don't repeat the search. Examples:
|
|
22335
|
+
- Found a project's source code path after searching \u2192 \`ctx_memory(action="write", category="ENVIRONMENT", content="OpenCode source is at ~/Work/OSS/opencode")\`
|
|
22336
|
+
- Discovered a non-obvious build/test command \u2192 \`ctx_memory(action="write", category="WORKFLOW_RULES", content="Always use scripts/release.sh for releases")\`
|
|
22337
|
+
- Learned a constraint the hard way \u2192 \`ctx_memory(action="write", category="CONSTRAINTS", content="Dashboard Tauri build needs RGBA PNGs, not grayscale")\`
|
|
22256
22338
|
Use \`ctx_search\` to search across project memories, session facts, and conversation history from one query.
|
|
22257
22339
|
Use \`ctx_expand\` to decompress a compartment range to see the original conversation transcript. Use \`start\`/\`end\` from \`<compartment start=N end=M>\` attributes. Returns the compacted U:/A: transcript for that message range, capped at ~15K tokens.
|
|
22258
22340
|
**Search before asking the user**: If you can't remember or don't know something that might have been discussed before or stored in project memory, use \`ctx_search\` before asking the user. Examples:
|
package/package.json
CHANGED