@log0u7/opencode-memory 0.5.1 → 0.6.1
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/CHANGELOG.md +35 -1
- package/README.md +45 -4
- package/dist/compaction.d.ts +34 -0
- package/dist/compaction.d.ts.map +1 -0
- package/dist/compaction.js +100 -0
- package/dist/compaction.js.map +1 -0
- package/dist/options.d.ts +14 -0
- package/dist/options.d.ts.map +1 -1
- package/dist/options.js +21 -2
- package/dist/options.js.map +1 -1
- package/dist/plugin-v2.d.ts.map +1 -1
- package/dist/plugin-v2.js +186 -2
- package/dist/plugin-v2.js.map +1 -1
- package/dist/session-search.d.ts +17 -0
- package/dist/session-search.d.ts.map +1 -0
- package/dist/session-search.js +167 -0
- package/dist/session-search.js.map +1 -0
- package/dist/transcripts.d.ts +22 -0
- package/dist/transcripts.d.ts.map +1 -0
- package/dist/transcripts.js +131 -0
- package/dist/transcripts.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,41 @@ All notable changes to this project are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [
|
|
8
|
+
## [0.6.1] - 2026-11-04
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- `memory_session_search` and `memory_session_read` no longer follow symlinks
|
|
13
|
+
planted in the transcripts directory: only regular files are read.
|
|
14
|
+
- Tool output cap lowered from 1 MB to 100 KB per call (default still 20000).
|
|
15
|
+
- README note: if the transcript export fails, compaction falls back to the
|
|
16
|
+
model-written summary silently; the cause is environmental, check disk space
|
|
17
|
+
and write access on the transcripts directory.
|
|
18
|
+
|
|
19
|
+
## [0.6.0] - 2026-11-04
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Context retrieval: compaction no longer pays for a model-written summary. A
|
|
24
|
+
compaction hook exports the exact transcript being summarized to
|
|
25
|
+
`~/.local/share/opencode-memory/transcripts/<scope>/<sessionID>.md`
|
|
26
|
+
(append-only markdown, `0700`/`0600`) and records a short pointer as the
|
|
27
|
+
compaction result, which skips the summary model call entirely. Two bounded
|
|
28
|
+
retrieval tools, `memory_session_search` and `memory_session_read`, let the
|
|
29
|
+
agent pull exact lines (errors, paths, numbers, decisions) from any exported
|
|
30
|
+
transcript of the project, when it needs them.
|
|
31
|
+
- Cross-scope search: `memory_session_search` accepts `all: true` to search
|
|
32
|
+
every project's exported transcripts on the machine.
|
|
33
|
+
- On-demand export: naming a session that has no transcript yet (in
|
|
34
|
+
`memory_session_search` or `memory_session_read`) exports it from the host's
|
|
35
|
+
session store first, under that session's own scope.
|
|
36
|
+
- `/memory-continue <sessionID>` command: exports the session's transcript if
|
|
37
|
+
needed and injects the retrieval pointer into the current session.
|
|
38
|
+
- Approach inspired by Mainplane's context retrieval
|
|
39
|
+
(https://github.com/mainplane-ai/mainplane).
|
|
40
|
+
- Plugin options `retrieval.enabled` (default `true`), `retrieval.dir`,
|
|
41
|
+
`retrieval.inlineOutputMaxBytes` (default 50000). Disabling restores the
|
|
42
|
+
plain summary flow and hides the retrieval tools.
|
|
9
43
|
|
|
10
44
|
## [0.5.1] - 2026-10-24
|
|
11
45
|
|
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# opencode-memory
|
|
2
2
|
|
|
3
3
|
[](https://github.com/log0u7/opencode-memory/actions/workflows/ci.yml)
|
|
4
|
-
[](LICENSE)
|
|
5
|
+
[](https://www.typescriptlang.org)
|
|
5
6
|
[](https://www.npmjs.com/package/@log0u7/opencode-memory)
|
|
6
|
-
[](LICENSE)
|
|
7
|
+
[](https://www.npmjs.com/package/@log0u7/opencode-memory)
|
|
8
8
|
|
|
9
9
|
Working memory for [OpenCode](https://opencode.ai): a shared SQLite store that all sessions on a machine read and write, so decisions, facts, and compaction summaries survive session boundaries.
|
|
10
10
|
|
|
@@ -61,6 +61,8 @@ memory_stats()
|
|
|
61
61
|
| `memory_forget` | `id` or `query` | Trash one entry by id, or all matching a query. |
|
|
62
62
|
| `memory_stats` | `scope?` | Count entries by kind (plus global) with a total, plus the store size and oldest entry. |
|
|
63
63
|
| `memory_restore` | `id` | Put a trashed entry back, wherever it lived. |
|
|
64
|
+
| `memory_session_search` | `query`, `sessionID?`, `contextLines?`, `maxBytes?` | Search exported session transcripts for exact lines (case-insensitive), with line numbers and surrounding context. |
|
|
65
|
+
| `memory_session_read` | `sessionID`, `offset?`, `limit?`, `maxBytes?` | Read a numbered window of one exported transcript by 1-based line. |
|
|
64
66
|
|
|
65
67
|
Entry `kind` is free-form; conventions that work well: `decision`, `fact`, `preference`, `gotcha`, `lesson`, `compaction`.
|
|
66
68
|
|
|
@@ -82,6 +84,45 @@ Options: `enabled` (default `false`), `model` (`"provider/model"`, default: the
|
|
|
82
84
|
|
|
83
85
|
Cost per reflection: ~2k input tokens (the bounded transcript) and at most ~300 output tokens, at most once per session: roughly $0.001 with a small model, $0.01 with a frontier model (indicative). The nudges and injections are plain text: they cost nothing.
|
|
84
86
|
|
|
87
|
+
### Context retrieval
|
|
88
|
+
|
|
89
|
+
Compaction normally asks a model to summarise the session: one expensive call over the whole history (measured on a live ~40k-token session with GLM-5.3-Flash: 39,620 input tokens, $0.0018, tens of seconds), and the summary is lossy. With context retrieval the plugin replaces that summary with a pointer and keeps the record:
|
|
90
|
+
|
|
91
|
+
The approach follows Mainplane's context retrieval (https://github.com/mainplane-ai/mainplane, MIT): keep the full record, let the agent retrieve what it needs instead of summarising.
|
|
92
|
+
|
|
93
|
+
1. When a compaction runs (automatic, on context overflow, or manual), the plugin exports the exact transcript being summarized to `~/.local/share/opencode-memory/transcripts/<scope>/<sessionID>.md` before anything is discarded.
|
|
94
|
+
2. The compaction result becomes a short pointer (~120 tokens): the transcript path, the last user request, and the working rule to retrieve details with `memory_session_search` / `memory_session_read` instead of guessing. The summary model call is skipped entirely: measured live, the compaction completes with no model cost.
|
|
95
|
+
3. Later, the agent searches the transcript and copies the exact lines it needs, when it needs them: nothing is paraphrased, and the result does not depend on a prompt cache.
|
|
96
|
+
|
|
97
|
+
The compaction prompt still asks for durable knowledge to be saved with `memory_save`; that instruction moves into the pointer text so it survives the skipped call.
|
|
98
|
+
|
|
99
|
+
Options (under the plugin options object):
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
["@log0u7/opencode-memory", { "retrieval": { "enabled": true } }]
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
- `enabled` (default `true`): `false` restores the plain summary flow and hides the two retrieval tools.
|
|
106
|
+
- `dir` (default `~/.local/share/opencode-memory/transcripts`): where transcripts are exported.
|
|
107
|
+
- `inlineOutputMaxBytes` (default 50000): tool output above this size is truncated head+tail in the transcript, with the tool call id kept in the marker so the full output stays recoverable from OpenCode's tool-output store.
|
|
108
|
+
|
|
109
|
+
This feature is V2-only (it hooks the V2 compaction request). The transcript holds the full session history, which can include secrets typed or read during the session: the directory is created `0700` and files `0600` regardless of umask, and the store never leaves the machine.
|
|
110
|
+
|
|
111
|
+
If the export fails (disk full or permission error), compaction falls back to the model-written summary silently. The failure is environmental, not a logic bug: check disk space and write access on the transcripts directory.
|
|
112
|
+
|
|
113
|
+
`memory_session_search` accepts `all: true` to search every project's transcripts on the machine, not just the current scope's. A session whose transcript is not on disk yet is exported on demand (from the host's session store) the first time a tool names it: old sessions work without pre-exporting everything.
|
|
114
|
+
|
|
115
|
+
The `/memory-continue <sessionID>` command brings a past session into the current one: it exports the transcript if needed and injects the retrieval pointer (path, last request, working rule) as a prompt.
|
|
116
|
+
|
|
117
|
+
Measured on a live ~40k-token session with GLM-5.3-Flash (openrouter): the model-written summary cost 39,620 input tokens and $0.0018; the retrieval pointer compaction completed with no model call at all. The agent then recovered an exact value planted in the compacted session from a fresh session via `memory_session_search`. Live measurement on the local 30k-context model was not possible: a fresh session already overflows its window before any history exists, so compaction cannot run on it (model limitation, unrelated to this feature).
|
|
118
|
+
|
|
119
|
+
### Design decisions
|
|
120
|
+
|
|
121
|
+
- **Why a file, not SQLite.** The session record already lives in OpenCode's own SQLite database; the plugin must not duplicate it there, and OpenCode's DB is internal (no stable external schema). What the agent needs is not storage but a greppable projection: line-numbered plain text that `memory_session_search` and `memory_session_read` address with `path:line`, one append-only file per session (no write contention), readable with `less`/`diff` by humans. The plugin's own SQLite keeps only a lightweight index (one row per transcript); a second full-text copy of every transcript body in the store would add megabytes per session for a search grep already answers in milliseconds at this scale.
|
|
122
|
+
- **Why skip the summary model call.** The summary is the most expensive call of a session (full re-tokenization at once) and the lossiest step (exact errors, paths, numbers get paraphrased away). The pointer replaces it with a fixed ~120-token text: cheaper, cache-independent, lossless.
|
|
123
|
+
- **Provider state trade-off.** A synthetic compaction result does not carry provider cache state, so the next request re-prefills a small prefix. Accepted: it is the same trade the retrieval approach makes everywhere, and the post-compaction context is small anyway.
|
|
124
|
+
- **Why the pointer injects in place.** A server-side plugin command cannot switch the TUI to another session, so `/memory-continue` brings the old session's pointer into the current session instead of spawning a new one. `/fork` first if a separate session is wanted.
|
|
125
|
+
|
|
85
126
|
### Notes
|
|
86
127
|
|
|
87
128
|
- All sessions on the machine share one store (WAL mode, concurrent-safe).
|
|
@@ -92,7 +133,7 @@ Cost per reflection: ~2k input tokens (the bounded transcript) and at most ~300
|
|
|
92
133
|
- `memory_stats` reports the store size on disk and the oldest live entry next to the kind counts. The store has no size cap and no eviction, so this is the only growth signal.
|
|
93
134
|
- Every entry records the agent that wrote it (`source`; distilled lessons carry `reflection`), and the session inventory names the writer, so knowledge from a sibling session or from reflection is distinguishable from what this session wrote.
|
|
94
135
|
- On the first request of a session, the most recent entries are injected into the system prompt as a bounded list (titles only), so the model does not have to remember to search. `memory_search` remains the tool for deeper lookups.
|
|
95
|
-
- On session compaction, the plugin lists the stored entries in the compaction context and asks the compaction prompt to emit durable decisions, so the model summarises from an inventory instead of recall.
|
|
136
|
+
- On session compaction, the plugin lists the stored entries in the compaction context and asks the compaction prompt to emit durable decisions, so the model summarises from an inventory instead of recall. With context retrieval enabled (default), the summary call is replaced entirely: see "Context retrieval" above.
|
|
96
137
|
- Injections stay bounded (~1200 characters worst case) and nothing is injected, nor any store file created, when memory is unused.
|
|
97
138
|
|
|
98
139
|
## Development
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { TranscriptMessage } from "./transcripts.js";
|
|
2
|
+
export type CompactionInput = {
|
|
3
|
+
sessionID: string;
|
|
4
|
+
model?: string;
|
|
5
|
+
messages?: ReadonlyArray<TranscriptMessage>;
|
|
6
|
+
};
|
|
7
|
+
export type RetrievalRuntime = {
|
|
8
|
+
dir: string;
|
|
9
|
+
scope: string;
|
|
10
|
+
};
|
|
11
|
+
/** The most recent user request, one line, capped: the anchor the compacted session starts from. */
|
|
12
|
+
export declare function lastUserExcerpt(messages: ReadonlyArray<TranscriptMessage>, max?: number): string;
|
|
13
|
+
/** One directory per project scope (percent-encoded: 1:1, filesystem-safe), one file per
|
|
14
|
+
* session. The session id is percent-encoded too: real ids are unchanged by it, and a
|
|
15
|
+
* hostile id cannot escape the transcripts directory. */
|
|
16
|
+
export declare function transcriptFilePath(dir: string, scope: string, sessionID: string): string;
|
|
17
|
+
/** Atomic, idempotent write. Modes are enforced explicitly (not left to the umask): the
|
|
18
|
+
* transcript holds the full session history, so 0700/0600 always. */
|
|
19
|
+
export declare function writeTranscriptFile(path: string, content: string): void;
|
|
20
|
+
/** The last user request as recorded in an exported transcript file: the first non-empty
|
|
21
|
+
* line after the final "## user" heading, collapsed to one line. Used to anchor pointers
|
|
22
|
+
* (compaction result, /memory-continue) without keeping messages in memory. */
|
|
23
|
+
export declare function transcriptExcerpt(path: string, max?: number): string;
|
|
24
|
+
export declare function compactionSummary(path: string | null, excerpt: string): string;
|
|
25
|
+
/** Export the transcript and return the pointer summary. Idempotent: the same messages always
|
|
26
|
+
* produce the same file bytes and the same summary. Returns no path when there is nothing to
|
|
27
|
+
* export (missing sessionID or empty message list), with a summary that still points forward. */
|
|
28
|
+
export declare function handleCompaction(input: CompactionInput, runtime: RetrievalRuntime, options?: {
|
|
29
|
+
inlineOutputMaxBytes?: number;
|
|
30
|
+
}): {
|
|
31
|
+
summary: string;
|
|
32
|
+
path: string | null;
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=compaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../src/compaction.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAkB,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAW1E,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,oGAAoG;AACpG,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,aAAa,CAAC,iBAAiB,CAAC,EAC1C,GAAG,GAAE,MAAoB,GACxB,MAAM,CAaR;AAED;;yDAEyD;AACzD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAExF;AAED;qEACqE;AACrE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAYvE;AAED;;+EAE+E;AAC/E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAY,GAAG,MAAM,CAmBzE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAgB9E;AAED;;iGAEiG;AACjG,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,eAAe,EACtB,OAAO,EAAE,gBAAgB,EACzB,OAAO,CAAC,EAAE;IAAE,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAiB1C"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { chmodSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { renderTranscript } from "./transcripts.js";
|
|
4
|
+
// Retrieval replaces the lossy compaction summary: the transcript is exported verbatim to a
|
|
5
|
+
// greppable file and the compaction result becomes a short pointer instead of a model-written
|
|
6
|
+
// summary. The model call for the summary is skipped entirely (event.result), which is the
|
|
7
|
+
// whole point: no re-tokenization of the full history, nothing paraphrased.
|
|
8
|
+
const EXCERPT_MAX = 200;
|
|
9
|
+
const POSIX = process.platform !== "win32";
|
|
10
|
+
/** The most recent user request, one line, capped: the anchor the compacted session starts from. */
|
|
11
|
+
export function lastUserExcerpt(messages, max = EXCERPT_MAX) {
|
|
12
|
+
const last = [...messages].reverse().find((message) => message.role === "user");
|
|
13
|
+
if (!last) {
|
|
14
|
+
return "";
|
|
15
|
+
}
|
|
16
|
+
const text = typeof last.content === "string"
|
|
17
|
+
? last.content
|
|
18
|
+
: last.content
|
|
19
|
+
.filter((part) => part.type === "text")
|
|
20
|
+
.map((part) => String(part.text ?? ""))
|
|
21
|
+
.join(" ");
|
|
22
|
+
return text.replace(/\s+/g, " ").trim().slice(0, max);
|
|
23
|
+
}
|
|
24
|
+
/** One directory per project scope (percent-encoded: 1:1, filesystem-safe), one file per
|
|
25
|
+
* session. The session id is percent-encoded too: real ids are unchanged by it, and a
|
|
26
|
+
* hostile id cannot escape the transcripts directory. */
|
|
27
|
+
export function transcriptFilePath(dir, scope, sessionID) {
|
|
28
|
+
return join(dir, encodeURIComponent(scope), `${encodeURIComponent(sessionID)}.md`);
|
|
29
|
+
}
|
|
30
|
+
/** Atomic, idempotent write. Modes are enforced explicitly (not left to the umask): the
|
|
31
|
+
* transcript holds the full session history, so 0700/0600 always. */
|
|
32
|
+
export function writeTranscriptFile(path, content) {
|
|
33
|
+
const scopeDir = dirname(path);
|
|
34
|
+
mkdirSync(scopeDir, { recursive: true, mode: 0o700 });
|
|
35
|
+
if (POSIX) {
|
|
36
|
+
chmodSync(scopeDir, 0o700);
|
|
37
|
+
}
|
|
38
|
+
const tmp = `${path}.tmp`;
|
|
39
|
+
writeFileSync(tmp, content, { mode: 0o600 });
|
|
40
|
+
if (POSIX) {
|
|
41
|
+
chmodSync(tmp, 0o600);
|
|
42
|
+
}
|
|
43
|
+
renameSync(tmp, path);
|
|
44
|
+
}
|
|
45
|
+
/** The last user request as recorded in an exported transcript file: the first non-empty
|
|
46
|
+
* line after the final "## user" heading, collapsed to one line. Used to anchor pointers
|
|
47
|
+
* (compaction result, /memory-continue) without keeping messages in memory. */
|
|
48
|
+
export function transcriptExcerpt(path, max = 200) {
|
|
49
|
+
const lines = readFileSync(path, "utf8").split("\n");
|
|
50
|
+
let heading = -1;
|
|
51
|
+
for (let index = lines.length - 1; index >= 0; index--) {
|
|
52
|
+
if (lines[index] === "## user") {
|
|
53
|
+
heading = index;
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (heading < 0) {
|
|
58
|
+
return "";
|
|
59
|
+
}
|
|
60
|
+
for (let index = heading + 1; index < lines.length; index++) {
|
|
61
|
+
const line = (lines[index] ?? "").trim();
|
|
62
|
+
if (line.length > 0 && !line.startsWith("## ")) {
|
|
63
|
+
return line.replace(/\s+/g, " ").slice(0, max);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return "";
|
|
67
|
+
}
|
|
68
|
+
export function compactionSummary(path, excerpt) {
|
|
69
|
+
if (path === null) {
|
|
70
|
+
return ("Context compacted; the full transcript is unavailable (no messages to export). " +
|
|
71
|
+
"memory_session_search has no transcript for this session. " +
|
|
72
|
+
"Save durable knowledge with memory_save (kind=decision, fact, or lesson).");
|
|
73
|
+
}
|
|
74
|
+
return (`Context compacted. Full verbatim transcript of this session: ${path}.\n` +
|
|
75
|
+
`Last user request: ${excerpt.length > 0 ? excerpt : "(none captured)"}.\n` +
|
|
76
|
+
"Working rule: retrieve exact details (errors, paths, numbers, decisions) from the transcript " +
|
|
77
|
+
"with memory_session_search and memory_session_read as you go. Never guess: retrieve.\n" +
|
|
78
|
+
"Also save durable knowledge from before this point with memory_save (kind=decision, fact, or lesson) " +
|
|
79
|
+
"so other sessions keep it.");
|
|
80
|
+
}
|
|
81
|
+
/** Export the transcript and return the pointer summary. Idempotent: the same messages always
|
|
82
|
+
* produce the same file bytes and the same summary. Returns no path when there is nothing to
|
|
83
|
+
* export (missing sessionID or empty message list), with a summary that still points forward. */
|
|
84
|
+
export function handleCompaction(input, runtime, options) {
|
|
85
|
+
const messages = Array.isArray(input.messages) ? input.messages : [];
|
|
86
|
+
if (typeof input.sessionID !== "string" ||
|
|
87
|
+
input.sessionID.length === 0 ||
|
|
88
|
+
messages.length === 0) {
|
|
89
|
+
return { summary: compactionSummary(null, ""), path: null };
|
|
90
|
+
}
|
|
91
|
+
const meta = {
|
|
92
|
+
sessionID: input.sessionID,
|
|
93
|
+
scope: runtime.scope,
|
|
94
|
+
...(input.model ? { model: input.model } : {}),
|
|
95
|
+
};
|
|
96
|
+
const path = transcriptFilePath(runtime.dir, runtime.scope, input.sessionID);
|
|
97
|
+
writeTranscriptFile(path, renderTranscript(messages, meta, options));
|
|
98
|
+
return { summary: compactionSummary(path, lastUserExcerpt(messages)), path };
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=compaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compaction.js","sourceRoot":"","sources":["../src/compaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAG1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,4FAA4F;AAC5F,8FAA8F;AAC9F,2FAA2F;AAC3F,4EAA4E;AAE5E,MAAM,WAAW,GAAG,GAAG,CAAC;AACxB,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;AAa3C,oGAAoG;AACpG,MAAM,UAAU,eAAe,CAC7B,QAA0C,EAC1C,GAAG,GAAW,WAAW;IAEzB,MAAM,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;IAChF,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,IAAI,GACR,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ;QAC9B,CAAC,CAAC,IAAI,CAAC,OAAO;QACd,CAAC,CAAC,IAAI,CAAC,OAAO;aACT,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;aACtC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;aACtC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACxD,CAAC;AAED;;yDAEyD;AACzD,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,KAAa,EAAE,SAAiB;IAC9E,OAAO,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,KAAK,CAAC,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AACrF,CAAC;AAED;qEACqE;AACrE,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,OAAe;IAC/D,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,IAAI,KAAK,EAAE,CAAC;QACV,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;IACD,MAAM,GAAG,GAAG,GAAG,IAAI,MAAM,CAAC;IAC1B,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7C,IAAI,KAAK,EAAE,CAAC;QACV,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACxB,CAAC;IACD,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACxB,CAAC;AAED;;+EAE+E;AAC/E,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,GAAG,GAAW,GAAG;IAC/D,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrD,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC;IACjB,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QACvD,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,GAAG,KAAK,CAAC;YAChB,MAAM;QACR,CAAC;IACH,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,KAAK,IAAI,KAAK,GAAG,OAAO,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAC5D,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/C,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAmB,EAAE,OAAe;IACpE,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO,CACL,iFAAiF;YACjF,4DAA4D;YAC5D,2EAA2E,CAC5E,CAAC;IACJ,CAAC;IACD,OAAO,CACL,gEAAgE,IAAI,KAAK;QACzE,sBAAsB,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,KAAK;QAC3E,+FAA+F;QAC/F,wFAAwF;QACxF,uGAAuG;QACvG,4BAA4B,CAC7B,CAAC;AACJ,CAAC;AAED;;iGAEiG;AACjG,MAAM,UAAU,gBAAgB,CAC9B,KAAsB,EACtB,OAAyB,EACzB,OAA2C;IAE3C,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IACrE,IACE,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ;QACnC,KAAK,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;QAC5B,QAAQ,CAAC,MAAM,KAAK,CAAC,EACrB,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC9D,CAAC;IACD,MAAM,IAAI,GAAmB;QAC3B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/C,CAAC;IACF,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC7E,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACrE,OAAO,EAAE,OAAO,EAAE,iBAAiB,CAAC,IAAI,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;AAC/E,CAAC"}
|
package/dist/options.d.ts
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
|
+
export type RetrievalOptions = {
|
|
2
|
+
enabled?: boolean;
|
|
3
|
+
dir?: string;
|
|
4
|
+
inlineOutputMaxBytes?: number;
|
|
5
|
+
};
|
|
1
6
|
export type PluginOptions = {
|
|
2
7
|
dbPath?: string;
|
|
3
8
|
reflection?: unknown;
|
|
9
|
+
retrieval?: RetrievalOptions;
|
|
4
10
|
};
|
|
5
11
|
export declare const SYSTEM_GUIDANCE = "You have persistent working memory shared with all OpenCode sessions on this machine.\nRecent entries are listed above when present; run memory_search for anything older or more specific.\nWhen you make a durable decision or learn a lasting fact, call memory_save (kinds: decision, fact, preference, gotcha).\nWhen a non-obvious approach clearly fails or succeeds, save the lesson (kind=lesson) as soon as it is confirmed, and check stored lessons before retrying a failed approach.\nNever store credentials, tokens, or API keys in memory; the store refuses them.";
|
|
6
12
|
export declare const COMPACTION_CONTEXT: string;
|
|
13
|
+
export declare function defaultDataHome(): string;
|
|
7
14
|
export declare function defaultDbPath(options?: PluginOptions): string;
|
|
15
|
+
export declare function defaultTranscriptsDir(options?: PluginOptions): string;
|
|
16
|
+
export type RetrievalConfig = {
|
|
17
|
+
enabled: boolean;
|
|
18
|
+
dir: string;
|
|
19
|
+
inlineOutputMaxBytes: number;
|
|
20
|
+
};
|
|
21
|
+
export declare function parseRetrievalConfig(options?: PluginOptions): RetrievalConfig;
|
|
8
22
|
/**
|
|
9
23
|
* Scope of a session: the v1 tool context carries a worktree, so that is the canonical
|
|
10
24
|
* key. `directory` is the fallback so the same project does not get two scopes.
|
package/dist/options.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,gBAAgB,CAAC;CAC9B,CAAC;AAEF,eAAO,MAAM,eAAe,wjBAIoD,CAAC;AAEjF,eAAO,MAAM,kBAAkB,QAG0B,CAAC;AAE1D,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CAK7D;AAED,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CAMrE;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,eAAe,CAS7E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1E"}
|
package/dist/options.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { canonicalScope } from "./lib/store.js";
|
|
2
|
+
import { INLINE_OUTPUT_MAX_BYTES } from "./transcripts.js";
|
|
2
3
|
export const SYSTEM_GUIDANCE = `You have persistent working memory shared with all OpenCode sessions on this machine.
|
|
3
4
|
Recent entries are listed above when present; run memory_search for anything older or more specific.
|
|
4
5
|
When you make a durable decision or learn a lasting fact, call memory_save (kinds: decision, fact, preference, gotcha).
|
|
@@ -7,12 +8,30 @@ Never store credentials, tokens, or API keys in memory; the store refuses them.`
|
|
|
7
8
|
export const COMPACTION_CONTEXT = "The session is being compacted. After compaction, call memory_save for every durable decision still relevant " +
|
|
8
9
|
"(kind=decision), any newly learned facts (kind=fact), and every reusable lesson confirmed this session " +
|
|
9
10
|
"(kind=lesson), so other sessions keep this knowledge.";
|
|
11
|
+
export function defaultDataHome() {
|
|
12
|
+
return process.env.XDG_DATA_HOME ?? `${process.env.HOME ?? ""}/.local/share`;
|
|
13
|
+
}
|
|
10
14
|
export function defaultDbPath(options) {
|
|
11
15
|
if (typeof options?.dbPath === "string" && options.dbPath.length > 0) {
|
|
12
16
|
return options.dbPath;
|
|
13
17
|
}
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
return `${defaultDataHome()}/opencode-memory/memory.db`;
|
|
19
|
+
}
|
|
20
|
+
export function defaultTranscriptsDir(options) {
|
|
21
|
+
const configured = options?.retrieval?.dir;
|
|
22
|
+
if (typeof configured === "string" && configured.length > 0) {
|
|
23
|
+
return configured;
|
|
24
|
+
}
|
|
25
|
+
return `${defaultDataHome()}/opencode-memory/transcripts`;
|
|
26
|
+
}
|
|
27
|
+
export function parseRetrievalConfig(options) {
|
|
28
|
+
const bytes = options?.retrieval?.inlineOutputMaxBytes;
|
|
29
|
+
return {
|
|
30
|
+
enabled: options?.retrieval?.enabled !== false,
|
|
31
|
+
dir: defaultTranscriptsDir(options),
|
|
32
|
+
// 128 keeps the truncation marker smaller than the cap for degenerate configs.
|
|
33
|
+
inlineOutputMaxBytes: typeof bytes === "number" && bytes > 0 ? Math.max(128, bytes) : INLINE_OUTPUT_MAX_BYTES,
|
|
34
|
+
};
|
|
16
35
|
}
|
|
17
36
|
/**
|
|
18
37
|
* Scope of a session: the v1 tool context carries a worktree, so that is the canonical
|
package/dist/options.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAmB3D,MAAM,CAAC,MAAM,eAAe,GAAG;;;;gFAIiD,CAAC;AAEjF,MAAM,CAAC,MAAM,kBAAkB,GAC7B,+GAA+G;IAC/G,yGAAyG;IACzG,uDAAuD,CAAC;AAE1D,MAAM,UAAU,eAAe;IAC7B,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,eAAe,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAuB;IACnD,IAAI,OAAO,OAAO,EAAE,MAAM,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrE,OAAO,OAAO,CAAC,MAAM,CAAC;IACxB,CAAC;IACD,OAAO,GAAG,eAAe,EAAE,4BAA4B,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAuB;IAC3D,MAAM,UAAU,GAAG,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC;IAC3C,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5D,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,OAAO,GAAG,eAAe,EAAE,8BAA8B,CAAC;AAC5D,CAAC;AAQD,MAAM,UAAU,oBAAoB,CAAC,OAAuB;IAC1D,MAAM,KAAK,GAAG,OAAO,EAAE,SAAS,EAAE,oBAAoB,CAAC;IACvD,OAAO;QACL,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,KAAK,KAAK;QAC9C,GAAG,EAAE,qBAAqB,CAAC,OAAO,CAAC;QACnC,+EAA+E;QAC/E,oBAAoB,EAClB,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,uBAAuB;KAC1F,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,QAAiB,EAAE,SAAkB;IAChE,OAAO,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AAC7C,CAAC"}
|
package/dist/plugin-v2.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-v2.d.ts","sourceRoot":"","sources":["../src/plugin-v2.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin-v2.d.ts","sourceRoot":"","sources":["../src/plugin-v2.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAyD1C,eAAO,MAAM,QAAQ,eAgcnB,CAAC"}
|
package/dist/plugin-v2.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
1
2
|
import { Plugin } from "@opencode/plugin";
|
|
2
3
|
import { openMemoryDb } from "./lib/db.js";
|
|
3
4
|
import { TOOL_DESCRIPTIONS, createMemoryOps, memoryInventory, oncePerSession, } from "./lib/memory-ops.js";
|
|
4
5
|
import { createReflection, parseReflectionConfig } from "./lib/reflection.js";
|
|
5
|
-
import { SYSTEM_GUIDANCE, COMPACTION_CONTEXT, defaultScope, defaultDbPath, } from "./options.js";
|
|
6
|
+
import { SYSTEM_GUIDANCE, COMPACTION_CONTEXT, defaultScope, defaultDbPath, parseRetrievalConfig, } from "./options.js";
|
|
7
|
+
import { canonicalScope } from "./lib/store.js";
|
|
8
|
+
import { compactionSummary, handleCompaction, transcriptExcerpt, transcriptFilePath, writeTranscriptFile, } from "./compaction.js";
|
|
9
|
+
import { renderTranscript, sessionInfoToMessages } from "./transcripts.js";
|
|
10
|
+
import { readTranscript, searchTranscripts } from "./session-search.js";
|
|
6
11
|
const textPart = (text) => ({ type: "text", text });
|
|
7
12
|
/** Reconnect backoff for the v2 event stream: short first retry, capped growth. */
|
|
8
13
|
const RECONNECT_MIN_MS = 250;
|
|
@@ -47,7 +52,77 @@ export const MemoryV2 = Plugin.define({
|
|
|
47
52
|
const ops = createMemoryOps(getDb);
|
|
48
53
|
// Request and compaction hooks carry no directory: the instance scope is the project.
|
|
49
54
|
const projectScope = defaultScope(undefined, ctx.location.directory);
|
|
55
|
+
const retrieval = parseRetrievalConfig(options);
|
|
50
56
|
const injected = oncePerSession();
|
|
57
|
+
/** Scope that holds the transcript for `sessionID`: the project scope when the file is
|
|
58
|
+
* already there, otherwise the session's own scope after an on-demand export (lazy, so
|
|
59
|
+
* old sessions work without pre-exporting everything). Null: unknown session or empty
|
|
60
|
+
* history. */
|
|
61
|
+
const ensureTranscript = async (sessionID) => {
|
|
62
|
+
if (disposed) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
if (existsSync(transcriptFilePath(retrieval.dir, projectScope, sessionID))) {
|
|
66
|
+
return projectScope;
|
|
67
|
+
}
|
|
68
|
+
// An unknown session id is an expected miss here, not an exceptional failure.
|
|
69
|
+
let info;
|
|
70
|
+
try {
|
|
71
|
+
info = await ctx.session.get({ sessionID });
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
const directory = info?.location
|
|
77
|
+
?.directory;
|
|
78
|
+
if (typeof directory !== "string" || directory.length === 0) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const scope = canonicalScope(undefined, directory);
|
|
82
|
+
if (existsSync(transcriptFilePath(retrieval.dir, scope, sessionID))) {
|
|
83
|
+
return scope;
|
|
84
|
+
}
|
|
85
|
+
const context = await ctx.session.context({ sessionID });
|
|
86
|
+
const messages = sessionInfoToMessages(context);
|
|
87
|
+
if (messages.length === 0) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const path = transcriptFilePath(retrieval.dir, scope, sessionID);
|
|
91
|
+
writeTranscriptFile(path, renderTranscript(messages, { sessionID, scope }, {
|
|
92
|
+
inlineOutputMaxBytes: retrieval.inlineOutputMaxBytes,
|
|
93
|
+
}));
|
|
94
|
+
return scope;
|
|
95
|
+
};
|
|
96
|
+
const unexportable = (sessionID) => `no transcript for session ${sessionID}; it could not be exported (unknown session or empty history)`;
|
|
97
|
+
if (retrieval.enabled) {
|
|
98
|
+
await ctx.command.transform((editor) => {
|
|
99
|
+
editor.add({
|
|
100
|
+
name: "memory-continue",
|
|
101
|
+
description: "Continue a past session in this one: export its transcript if needed and inject the retrieval pointer",
|
|
102
|
+
execute: async ({ sessionID, prompt, delivery }) => {
|
|
103
|
+
const target = prompt.text.trim();
|
|
104
|
+
if (target.length === 0) {
|
|
105
|
+
await ctx.session.prompt({
|
|
106
|
+
sessionID,
|
|
107
|
+
text: "Pass the session id to continue: /memory-continue <sessionID>. The session's transcript is exported on demand and the retrieval pointer lands here.",
|
|
108
|
+
delivery,
|
|
109
|
+
});
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const scope = await ensureTranscript(target);
|
|
113
|
+
let text;
|
|
114
|
+
if (scope === null) {
|
|
115
|
+
text = unexportable(target);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
const path = transcriptFilePath(retrieval.dir, scope, target);
|
|
119
|
+
text = compactionSummary(path, transcriptExcerpt(path));
|
|
120
|
+
}
|
|
121
|
+
await ctx.session.prompt({ sessionID, text, delivery });
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
}
|
|
51
126
|
await ctx.tool.transform((editor) => {
|
|
52
127
|
editor.add({
|
|
53
128
|
name: "memory_save",
|
|
@@ -160,6 +235,92 @@ export const MemoryV2 = Plugin.define({
|
|
|
160
235
|
return { content: ops.restore(a) };
|
|
161
236
|
},
|
|
162
237
|
});
|
|
238
|
+
if (!retrieval.enabled) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
editor.add({
|
|
242
|
+
name: "memory_session_search",
|
|
243
|
+
description: "Search past session transcripts (verbatim compaction exports) for exact lines: " +
|
|
244
|
+
"errors, paths, numbers, decisions. Returns matching lines with line numbers and " +
|
|
245
|
+
"surrounding context. After a compaction, retrieve facts here instead of guessing.",
|
|
246
|
+
input: {
|
|
247
|
+
type: "object",
|
|
248
|
+
properties: {
|
|
249
|
+
query: { type: "string", description: "Exact text to find, case-insensitive" },
|
|
250
|
+
sessionID: {
|
|
251
|
+
type: "string",
|
|
252
|
+
description: "Limit to one session; it is exported on demand if not on disk yet",
|
|
253
|
+
},
|
|
254
|
+
all: {
|
|
255
|
+
type: "boolean",
|
|
256
|
+
description: "Search every project's transcripts on this machine, not just this project's",
|
|
257
|
+
},
|
|
258
|
+
contextLines: {
|
|
259
|
+
type: "number",
|
|
260
|
+
description: "Context lines around each match (default 3, max 10)",
|
|
261
|
+
},
|
|
262
|
+
maxBytes: { type: "number", description: "Output byte cap (default 20000)" },
|
|
263
|
+
},
|
|
264
|
+
required: ["query"],
|
|
265
|
+
additionalProperties: false,
|
|
266
|
+
},
|
|
267
|
+
async execute(args) {
|
|
268
|
+
const a = args;
|
|
269
|
+
if (a.sessionID !== undefined) {
|
|
270
|
+
const scope = await ensureTranscript(a.sessionID);
|
|
271
|
+
if (scope === null) {
|
|
272
|
+
return { content: unexportable(a.sessionID) };
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
content: searchTranscripts(retrieval.dir, scope, {
|
|
276
|
+
query: a.query,
|
|
277
|
+
sessionID: a.sessionID,
|
|
278
|
+
...(a.contextLines !== undefined ? { contextLines: a.contextLines } : {}),
|
|
279
|
+
...(a.maxBytes !== undefined ? { maxBytes: a.maxBytes } : {}),
|
|
280
|
+
}),
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
content: searchTranscripts(retrieval.dir, projectScope, {
|
|
285
|
+
query: a.query,
|
|
286
|
+
all: a.all === true,
|
|
287
|
+
...(a.contextLines !== undefined ? { contextLines: a.contextLines } : {}),
|
|
288
|
+
...(a.maxBytes !== undefined ? { maxBytes: a.maxBytes } : {}),
|
|
289
|
+
}),
|
|
290
|
+
};
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
editor.add({
|
|
294
|
+
name: "memory_session_read",
|
|
295
|
+
description: "Read a numbered window of a past session transcript by 1-based line number. Use it " +
|
|
296
|
+
"after memory_session_search to pull the exact block around a match.",
|
|
297
|
+
input: {
|
|
298
|
+
type: "object",
|
|
299
|
+
properties: {
|
|
300
|
+
sessionID: { type: "string", description: "Session whose transcript to read" },
|
|
301
|
+
offset: { type: "number", description: "1-based starting line (default 1)" },
|
|
302
|
+
limit: { type: "number", description: "Max lines (default 200, max 500)" },
|
|
303
|
+
maxBytes: { type: "number", description: "Output byte cap (default 20000)" },
|
|
304
|
+
},
|
|
305
|
+
required: ["sessionID"],
|
|
306
|
+
additionalProperties: false,
|
|
307
|
+
},
|
|
308
|
+
async execute(args) {
|
|
309
|
+
const a = args;
|
|
310
|
+
const scope = await ensureTranscript(a.sessionID);
|
|
311
|
+
if (scope === null) {
|
|
312
|
+
return { content: unexportable(a.sessionID) };
|
|
313
|
+
}
|
|
314
|
+
return {
|
|
315
|
+
content: readTranscript(retrieval.dir, scope, {
|
|
316
|
+
sessionID: a.sessionID,
|
|
317
|
+
...(a.offset !== undefined ? { offset: a.offset } : {}),
|
|
318
|
+
...(a.limit !== undefined ? { limit: a.limit } : {}),
|
|
319
|
+
...(a.maxBytes !== undefined ? { maxBytes: a.maxBytes } : {}),
|
|
320
|
+
}),
|
|
321
|
+
};
|
|
322
|
+
},
|
|
323
|
+
});
|
|
163
324
|
});
|
|
164
325
|
// The v1 system transform maps to the v2 context hook: guidance first, then the
|
|
165
326
|
// once-per-session inventory.
|
|
@@ -173,7 +334,9 @@ export const MemoryV2 = Plugin.define({
|
|
|
173
334
|
event.system.push(textPart(inventory));
|
|
174
335
|
}
|
|
175
336
|
});
|
|
176
|
-
// experimental.session.compacting -> compaction hook
|
|
337
|
+
// experimental.session.compacting -> compaction hook. When retrieval is enabled the
|
|
338
|
+
// transcript is exported verbatim and event.result replaces the model-written summary:
|
|
339
|
+
// the summary model call is skipped entirely.
|
|
177
340
|
await ctx.session.hook("compaction", (event) => {
|
|
178
341
|
event.system.push(textPart(COMPACTION_CONTEXT));
|
|
179
342
|
if (disposed) {
|
|
@@ -183,6 +346,27 @@ export const MemoryV2 = Plugin.define({
|
|
|
183
346
|
if (inventory !== null) {
|
|
184
347
|
event.system.push(textPart(inventory));
|
|
185
348
|
}
|
|
349
|
+
if (!retrieval.enabled) {
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
// Host Message instances viewed structurally here: this hook is the boundary where
|
|
353
|
+
// the host's shape is parsed once into the renderer's input type.
|
|
354
|
+
const messages = (event.messages ?? []);
|
|
355
|
+
const model = event.model;
|
|
356
|
+
// An export failure must not kill compaction: leave event.result unset and the host
|
|
357
|
+
// falls back to the model-written summary. Expected failures are environmental
|
|
358
|
+
// (ENOSPC, EACCES on the data dir), not logic bugs.
|
|
359
|
+
try {
|
|
360
|
+
const { summary } = handleCompaction({
|
|
361
|
+
sessionID: event.sessionID,
|
|
362
|
+
...(model ? { model: `${model.providerID}/${model.id}` } : {}),
|
|
363
|
+
messages,
|
|
364
|
+
}, { dir: retrieval.dir, scope: projectScope }, { inlineOutputMaxBytes: retrieval.inlineOutputMaxBytes });
|
|
365
|
+
event.result = { summary };
|
|
366
|
+
}
|
|
367
|
+
catch {
|
|
368
|
+
// Silent fallback to the documented summary flow.
|
|
369
|
+
}
|
|
186
370
|
});
|
|
187
371
|
const cleanup = async () => {
|
|
188
372
|
disposed = true;
|
package/dist/plugin-v2.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-v2.js","sourceRoot":"","sources":["../src/plugin-v2.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin-v2.js","sourceRoot":"","sources":["../src/plugin-v2.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type SearchInput = {
|
|
2
|
+
query: string;
|
|
3
|
+
sessionID?: string;
|
|
4
|
+
/** Search every project's transcripts on this machine, not just this scope's. */
|
|
5
|
+
all?: boolean;
|
|
6
|
+
contextLines?: number;
|
|
7
|
+
maxBytes?: number;
|
|
8
|
+
};
|
|
9
|
+
export type ReadInput = {
|
|
10
|
+
sessionID: string;
|
|
11
|
+
offset?: number;
|
|
12
|
+
limit?: number;
|
|
13
|
+
maxBytes?: number;
|
|
14
|
+
};
|
|
15
|
+
export declare function searchTranscripts(dir: string, scope: string, input: SearchInput): string;
|
|
16
|
+
export declare function readTranscript(dir: string, scope: string, input: ReadInput): string;
|
|
17
|
+
//# sourceMappingURL=session-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-search.d.ts","sourceRoot":"","sources":["../src/session-search.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AA8EF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,CAwDxF;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAkCnF"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { lstatSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
// Bounded retrieval over exported session transcripts. Everything returns plain text with
|
|
4
|
+
// line numbers so the agent can cite `file:line` back into the transcript and read a wider
|
|
5
|
+
// window with readTranscript. Output is byte-capped: a retrieval tool that dumps 2 MB into
|
|
6
|
+
// the context defeats its own purpose.
|
|
7
|
+
const DEFAULT_CONTEXT_LINES = 3;
|
|
8
|
+
const MAX_CONTEXT_LINES = 10;
|
|
9
|
+
const DEFAULT_MAX_BYTES = 20_000;
|
|
10
|
+
const MAX_MAX_BYTES = 100_000;
|
|
11
|
+
const DEFAULT_READ_LIMIT = 200;
|
|
12
|
+
const MAX_READ_LIMIT = 500;
|
|
13
|
+
function scopeDir(dir, scope) {
|
|
14
|
+
return join(dir, encodeURIComponent(scope));
|
|
15
|
+
}
|
|
16
|
+
function isRegularFile(path) {
|
|
17
|
+
try {
|
|
18
|
+
return lstatSync(path).isFile();
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function filesInDir(scopeDirPath, scope) {
|
|
25
|
+
return readdirSync(scopeDirPath)
|
|
26
|
+
.filter((name) => name.endsWith(".md"))
|
|
27
|
+
.flatMap((name) => {
|
|
28
|
+
const path = join(scopeDirPath, name);
|
|
29
|
+
if (!isRegularFile(path)) {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
return [
|
|
33
|
+
{
|
|
34
|
+
name,
|
|
35
|
+
path,
|
|
36
|
+
mtime: statSync(path).mtimeMs,
|
|
37
|
+
...(scope !== undefined ? { scope } : {}),
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/** Newest first, so the sessions the agent most likely continues from come first. */
|
|
43
|
+
function listSessionFiles(dir, scope, all = false) {
|
|
44
|
+
if (all) {
|
|
45
|
+
let scopeDirs;
|
|
46
|
+
try {
|
|
47
|
+
scopeDirs = readdirSync(dir, { withFileTypes: true })
|
|
48
|
+
.filter((entry) => entry.isDirectory())
|
|
49
|
+
.map((entry) => entry.name);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
return scopeDirs
|
|
55
|
+
.flatMap((encoded) => {
|
|
56
|
+
try {
|
|
57
|
+
return filesInDir(join(dir, encoded), decodeURIComponent(encoded));
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
return filesInDir(scopeDir(dir, scope));
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function availableList(files) {
|
|
73
|
+
return files.length > 0 ? files.map((file) => file.name).join(", ") : "none";
|
|
74
|
+
}
|
|
75
|
+
function missingSession(sessionID, files) {
|
|
76
|
+
return `no transcript for session ${sessionID}; available: ${availableList(files)}`;
|
|
77
|
+
}
|
|
78
|
+
function clampInt(value, fallback, max, min = 1) {
|
|
79
|
+
if (typeof value !== "number" || Number.isNaN(value)) {
|
|
80
|
+
return fallback;
|
|
81
|
+
}
|
|
82
|
+
return Math.min(Math.max(Math.floor(value), min), max);
|
|
83
|
+
}
|
|
84
|
+
export function searchTranscripts(dir, scope, input) {
|
|
85
|
+
const needle = input.query.toLowerCase();
|
|
86
|
+
const context = clampInt(input.contextLines, DEFAULT_CONTEXT_LINES, MAX_CONTEXT_LINES, 0);
|
|
87
|
+
const budget = clampInt(input.maxBytes, DEFAULT_MAX_BYTES, MAX_MAX_BYTES, 200);
|
|
88
|
+
const files = listSessionFiles(dir, scope, input.all === true);
|
|
89
|
+
if (files.length === 0) {
|
|
90
|
+
return "no transcript for this scope yet: compaction exports land here";
|
|
91
|
+
}
|
|
92
|
+
const wanted = input.sessionID;
|
|
93
|
+
const targets = typeof wanted === "string" && wanted.length > 0
|
|
94
|
+
? files.filter((file) => file.name === `${encodeURIComponent(wanted)}.md`)
|
|
95
|
+
: files;
|
|
96
|
+
if (targets.length === 0) {
|
|
97
|
+
return missingSession(String(input.sessionID), files);
|
|
98
|
+
}
|
|
99
|
+
const blocks = [];
|
|
100
|
+
let size = 0;
|
|
101
|
+
let hits = 0;
|
|
102
|
+
for (const file of targets) {
|
|
103
|
+
const lines = readFileSync(file.path, "utf8").split("\n");
|
|
104
|
+
for (let index = 0; index < lines.length; index++) {
|
|
105
|
+
const line = lines[index] ?? "";
|
|
106
|
+
if (!line.toLowerCase().includes(needle)) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
hits++;
|
|
110
|
+
const label = file.scope !== undefined ? `${file.scope}/${file.name}` : file.name;
|
|
111
|
+
const numbered = [` ${index + 1}: ${line}`];
|
|
112
|
+
for (let j = Math.max(0, index - context); j <= Math.min(lines.length - 1, index + context); j++) {
|
|
113
|
+
if (j !== index) {
|
|
114
|
+
numbered.push(` ${j + 1}: ${lines[j] ?? ""}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
let block = `${label}:${index + 1}: ${line}\n${numbered.join("\n")}\n`;
|
|
118
|
+
if (block.length > budget) {
|
|
119
|
+
block = `${block.slice(0, budget)}\n[output capped at ${budget} bytes]\n`;
|
|
120
|
+
}
|
|
121
|
+
if (size + block.length > budget) {
|
|
122
|
+
blocks.push(`[output capped at ${budget} bytes]`);
|
|
123
|
+
return blocks.join("\n");
|
|
124
|
+
}
|
|
125
|
+
blocks.push(block);
|
|
126
|
+
size += block.length;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (hits === 0) {
|
|
130
|
+
return `no match for ${JSON.stringify(input.query)} in ${targets.length} transcript(s)`;
|
|
131
|
+
}
|
|
132
|
+
return blocks.join("\n");
|
|
133
|
+
}
|
|
134
|
+
export function readTranscript(dir, scope, input) {
|
|
135
|
+
const files = listSessionFiles(dir, scope);
|
|
136
|
+
const file = files.find((entry) => entry.name === `${encodeURIComponent(input.sessionID)}.md`);
|
|
137
|
+
if (!file) {
|
|
138
|
+
return missingSession(input.sessionID, files);
|
|
139
|
+
}
|
|
140
|
+
const lines = readFileSync(file.path, "utf8").split("\n");
|
|
141
|
+
const total = lines.length;
|
|
142
|
+
const offset = typeof input.offset === "number" && Number.isFinite(input.offset)
|
|
143
|
+
? Math.max(1, Math.floor(input.offset))
|
|
144
|
+
: 1;
|
|
145
|
+
const requestedLimit = input.limit;
|
|
146
|
+
const limit = clampInt(requestedLimit, DEFAULT_READ_LIMIT, MAX_READ_LIMIT);
|
|
147
|
+
const budget = clampInt(input.maxBytes, DEFAULT_MAX_BYTES, MAX_MAX_BYTES, 200);
|
|
148
|
+
if (offset > total) {
|
|
149
|
+
return `offset ${offset} is past the end of transcript (${total} lines)`;
|
|
150
|
+
}
|
|
151
|
+
const window = [];
|
|
152
|
+
let size = 0;
|
|
153
|
+
for (let index = offset - 1; index < Math.min(offset - 1 + limit, total); index++) {
|
|
154
|
+
const rendered = `${index + 1}: ${lines[index] ?? ""}`;
|
|
155
|
+
if (size + rendered.length + 1 > budget) {
|
|
156
|
+
window.push(`[output capped at ${budget} bytes]`);
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
window.push(rendered);
|
|
160
|
+
size += rendered.length + 1;
|
|
161
|
+
}
|
|
162
|
+
if (typeof requestedLimit === "number" && requestedLimit > MAX_READ_LIMIT) {
|
|
163
|
+
window.push(`[window capped at ${MAX_READ_LIMIT} lines]`);
|
|
164
|
+
}
|
|
165
|
+
return window.join("\n");
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=session-search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-search.js","sourceRoot":"","sources":["../src/session-search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type TranscriptMeta = {
|
|
2
|
+
sessionID: string;
|
|
3
|
+
scope: string;
|
|
4
|
+
model?: string;
|
|
5
|
+
};
|
|
6
|
+
export interface TranscriptMessage {
|
|
7
|
+
role: string;
|
|
8
|
+
content: string | ReadonlyArray<Record<string, unknown>>;
|
|
9
|
+
}
|
|
10
|
+
/** Tool output up to this size renders inline; larger output is head+tail truncated. */
|
|
11
|
+
export declare const INLINE_OUTPUT_MAX_BYTES = 50000;
|
|
12
|
+
/** Map host session messages (SessionMessageInfo shape: user carries `text`, assistant
|
|
13
|
+
* carries `content` parts) into renderer input. Unknown shapes become marked parts, never
|
|
14
|
+
* silent drops. */
|
|
15
|
+
export declare function sessionInfoToMessages(infos: ReadonlyArray<unknown>): TranscriptMessage[];
|
|
16
|
+
/** Full verbatim transcript of the given model messages as one greppable markdown file body.
|
|
17
|
+
* Deterministic: the same messages always render to the same bytes (no timestamps), so
|
|
18
|
+
* re-running a compaction export cannot produce a different file. */
|
|
19
|
+
export declare function renderTranscript(messages: ReadonlyArray<TranscriptMessage>, meta: TranscriptMeta, options?: {
|
|
20
|
+
inlineOutputMaxBytes?: number;
|
|
21
|
+
}): string;
|
|
22
|
+
//# sourceMappingURL=transcripts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcripts.d.ts","sourceRoot":"","sources":["../src/transcripts.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC1D;AAED,wFAAwF;AACxF,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAwG9C;;mBAEmB;AACnB,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,iBAAiB,EAAE,CAYxF;AAED;;qEAEqE;AACrE,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,aAAa,CAAC,iBAAiB,CAAC,EAC1C,IAAI,EAAE,cAAc,EACpB,OAAO,CAAC,EAAE;IAAE,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1C,MAAM,CASR"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// Verbatim transcript renderer for the retrieval flow. The input shape mirrors the host's
|
|
2
|
+
// model messages (@opencode/ai `Message`), kept structural and local so the static import
|
|
3
|
+
// graph never pulls a host-provided package (see the note in options.ts).
|
|
4
|
+
// Losslessness rule: text and tool payloads are rendered verbatim; oversized tool output is
|
|
5
|
+
// truncated head+tail with the tool call id kept in the marker, so the exact bytes stay
|
|
6
|
+
// recoverable through OpenCode's tool-output spool. Nothing is paraphrased; part types this
|
|
7
|
+
// renderer does not understand are marked, never silently dropped.
|
|
8
|
+
/** Tool output up to this size renders inline; larger output is head+tail truncated. */
|
|
9
|
+
export const INLINE_OUTPUT_MAX_BYTES = 50_000;
|
|
10
|
+
const HEAD_BYTES = 2048;
|
|
11
|
+
const TAIL_BYTES = 2048;
|
|
12
|
+
const FENCE = "~~~";
|
|
13
|
+
const isRecord = (value) => typeof value === "object" && value !== null;
|
|
14
|
+
function json(value) {
|
|
15
|
+
try {
|
|
16
|
+
return JSON.stringify(value, null, 2) ?? "null";
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
// BigInt or cyclic structures are the realistic throwers here; the fallback keeps the
|
|
20
|
+
// transcript renderable without pretending the JSON is exact.
|
|
21
|
+
return String(value);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function truncate(body, id, max) {
|
|
25
|
+
if (body.length <= max) {
|
|
26
|
+
return body;
|
|
27
|
+
}
|
|
28
|
+
const idLabel = typeof id === "string" ? id : "unknown";
|
|
29
|
+
if (max <= HEAD_BYTES + TAIL_BYTES + 64) {
|
|
30
|
+
// A cap too small for the head+tail window degrades to a single head slice.
|
|
31
|
+
return `${body.slice(0, Math.max(0, max - 48))}\n... [truncated; tool call id: ${idLabel}]`;
|
|
32
|
+
}
|
|
33
|
+
const omitted = body.length - HEAD_BYTES - TAIL_BYTES;
|
|
34
|
+
return `${body.slice(0, HEAD_BYTES)}\n... [truncated ${omitted} chars; tool call id: ${idLabel}] ...\n${body.slice(-TAIL_BYTES)}`;
|
|
35
|
+
}
|
|
36
|
+
function fence(body) {
|
|
37
|
+
return `${FENCE}\n${body}\n${FENCE}`;
|
|
38
|
+
}
|
|
39
|
+
function renderContentValue(value) {
|
|
40
|
+
return value
|
|
41
|
+
.map((item) => {
|
|
42
|
+
if (item.type === "text") {
|
|
43
|
+
return String(item.text ?? "");
|
|
44
|
+
}
|
|
45
|
+
if (item.type === "file") {
|
|
46
|
+
const name = typeof item.name === "string" ? ` name=${item.name}` : "";
|
|
47
|
+
return `[file ${String(item.uri ?? "")} ${String(item.mime ?? "")}${name}]`;
|
|
48
|
+
}
|
|
49
|
+
return `[unrendered content part: ${String(item.type ?? "unknown")}]`;
|
|
50
|
+
})
|
|
51
|
+
.join("\n");
|
|
52
|
+
}
|
|
53
|
+
function renderResult(result, id, max) {
|
|
54
|
+
if (!isRecord(result)) {
|
|
55
|
+
return fence(truncate(String(result ?? ""), id, max));
|
|
56
|
+
}
|
|
57
|
+
if (result.type === "text") {
|
|
58
|
+
return fence(truncate(String(result.value ?? ""), id, max));
|
|
59
|
+
}
|
|
60
|
+
if (result.type === "error") {
|
|
61
|
+
return fence(`[error]\n${truncate(String(result.value ?? ""), id, max)}`);
|
|
62
|
+
}
|
|
63
|
+
if (result.type === "json") {
|
|
64
|
+
return fence(truncate(json(result.value), id, max));
|
|
65
|
+
}
|
|
66
|
+
if (result.type === "content") {
|
|
67
|
+
const value = Array.isArray(result.value) ? result.value : [];
|
|
68
|
+
return renderContentValue(value);
|
|
69
|
+
}
|
|
70
|
+
return fence(truncate(json(result), id, max));
|
|
71
|
+
}
|
|
72
|
+
function renderPart(part, max) {
|
|
73
|
+
if (part.type === "text") {
|
|
74
|
+
return String(part.text ?? "");
|
|
75
|
+
}
|
|
76
|
+
if (part.type === "tool-call") {
|
|
77
|
+
return `### tool-call ${String(part.name ?? "unknown")} (id ${String(part.id ?? "unknown")})\n${fence(json(part.input ?? null))}`;
|
|
78
|
+
}
|
|
79
|
+
if (part.type === "tool-result") {
|
|
80
|
+
return `### tool-result ${String(part.name ?? "unknown")} (id ${String(part.id ?? "unknown")})\n${renderResult(part.result, part.id, max)}`;
|
|
81
|
+
}
|
|
82
|
+
if (part.type === "media") {
|
|
83
|
+
return "[media omitted]";
|
|
84
|
+
}
|
|
85
|
+
// Unknown or non-text part types (reasoning, compaction, effort, future additions) must
|
|
86
|
+
// not vanish silently: reasoning noise is skipped, anything else gets a marker line.
|
|
87
|
+
if (part.type === "reasoning" || part.type === "compaction" || part.type === "effort") {
|
|
88
|
+
return "";
|
|
89
|
+
}
|
|
90
|
+
return `[unrendered part type: ${String(part.type ?? "unknown")}]`;
|
|
91
|
+
}
|
|
92
|
+
function renderMessage(message, max) {
|
|
93
|
+
const content = typeof message.content === "string"
|
|
94
|
+
? [{ type: "text", text: message.content }]
|
|
95
|
+
: message.content;
|
|
96
|
+
const body = content
|
|
97
|
+
.map((part) => (isRecord(part) ? renderPart(part, max) : "[unrendered part]"))
|
|
98
|
+
.filter((section) => section.length > 0)
|
|
99
|
+
.join("\n");
|
|
100
|
+
return `## ${message.role}\n${body}`;
|
|
101
|
+
}
|
|
102
|
+
/** Map host session messages (SessionMessageInfo shape: user carries `text`, assistant
|
|
103
|
+
* carries `content` parts) into renderer input. Unknown shapes become marked parts, never
|
|
104
|
+
* silent drops. */
|
|
105
|
+
export function sessionInfoToMessages(infos) {
|
|
106
|
+
return infos.flatMap((info) => {
|
|
107
|
+
if (!isRecord(info)) {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
const content = Array.isArray(info.content)
|
|
111
|
+
? info.content
|
|
112
|
+
: typeof info.text === "string"
|
|
113
|
+
? info.text
|
|
114
|
+
: "";
|
|
115
|
+
return [{ role: String(info.type ?? "unknown"), content }];
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/** Full verbatim transcript of the given model messages as one greppable markdown file body.
|
|
119
|
+
* Deterministic: the same messages always render to the same bytes (no timestamps), so
|
|
120
|
+
* re-running a compaction export cannot produce a different file. */
|
|
121
|
+
export function renderTranscript(messages, meta, options) {
|
|
122
|
+
const max = options?.inlineOutputMaxBytes ?? INLINE_OUTPUT_MAX_BYTES;
|
|
123
|
+
const header = [
|
|
124
|
+
`# Transcript ${meta.sessionID}`,
|
|
125
|
+
`scope: ${meta.scope}`,
|
|
126
|
+
`model: ${meta.model ?? "unknown"}`,
|
|
127
|
+
].join("\n");
|
|
128
|
+
const body = messages.map((message) => renderMessage(message, max)).join("\n\n");
|
|
129
|
+
return `${header}\n\n${body}\n`;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=transcripts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcripts.js","sourceRoot":"","sources":["../src/transcripts.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED