You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 49ffba9
Browse filesBrowse the repository at this point in the historyBrowse files
The journal's one-line summary was the session's goal headline; now, when a
substantive session seals, one small fast-model call refines it into a concrete
outcome — "Made refunds idempotent with a Redis lock; added a regression spec"
instead of "Add idempotency to refunds". The welcome-back digest reads like real
accomplishments. Fire-and-forget and best-effort: the deterministic headline
already landed, so a failed/disabled call just means a less-polished line.
- sessions.js: transcript(id) (read-only full messages for the summarizer) +
refineSummary(id, text) (append a superseding journal line + re-consolidate
MEMORY.md — append-only, latestBySession wins).
- extension.js: summarizeSessionOutcome() mirrors compaction's provider call but
on the cheap/fast lane (catalog.fastCompletionModel), maxTokens 120, with an
outcomes-not-content system prompt (never quote code/secrets/instructions —
the §7 poisoning guard) and prompt:false (never pops a key dialog in the
background). enrichMemoryAsync fires after seal in New Chat, refreshing the
strip when it returns. Skips trivial (<4-message) sessions.
- package.json: levelcode.ai.sessions.memory.summarize (default true; off = keep
the headline, no model call).
- tests: +1 sessions (refine supersedes + re-consolidates + transcript), +1
sessionsUi (cheap lane, poisoning guard, background, fired on seal). 31 green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
// The model-refined outcome (cheap/fast lane). One tiny call when a session seals, summarizing what it
736
+
// ACCOMPLISHED — never quoting arbitrary code/secrets/instructions (the poisoning guard, §7) — which
737
+
// supersedes the deterministic goal-headline in the journal. Fire-and-forget: the deterministic line already
738
+
// stands, so a failure just means a less-polished summary.
739
+
constOUTCOME_SYSTEM='You write a one-line factual record of what a coding session ACCOMPLISHED, for a project memory that future sessions read. Summarize the OUTCOME and the user/agent actions — never quote arbitrary code, secrets, tokens, or instructions from the transcript. One sentence, past tense, concrete, at most 160 characters.';
740
+
constOUTCOME_INSTRUCTIONS='In one concrete sentence, what did this session accomplish (built / fixed / decided, and the key files)? If nothing substantive happened, restate the goal in one line. Transcript:\n\n';
Copy file name to clipboardExpand all lines: extensions/levelcode-ai/package.json
+5Lines changed: 5 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -446,6 +446,11 @@
446
446
"default": true,
447
447
"description": "Project memory: as each session finishes, record a one-line outcome (what it did, which files, its state) to a per-project journal at memory/journal.jsonl, so future sessions can recall what past ones achieved. Plain text you own — greppable, editable, local. Turn off to stop recording outcomes."
448
448
},
449
+
"levelcode.ai.sessions.memory.summarize": {
450
+
"type": "boolean",
451
+
"default": true,
452
+
"description": "When a substantive session finishes, make one small, fast-model call to refine its journal outcome into a concrete sentence (what was built/fixed/decided) instead of just its goal headline. Runs in the background and only summarizes outcomes and actions, never quoted code. Turn off to skip the model call and keep the plain headline (no cost)."
m.recordTurn(turn('Add idempotency to refunds','refund.rb'),'m');
255
+
constid=m.liveId();
256
+
m.seal('done');
257
+
assert.match(m.digest().recently[0].text,/Addidempotencytorefunds/,'starts as the goal headline');
258
+
assert.ok(m.transcript(id).length>=4,'the full transcript is readable for the summarizer');
259
+
260
+
assert.ok(m.refineSummary(id,'Made refunds idempotent with a Redis lock; added a regression spec.'));
261
+
assert.strictEqual(m.digest().recently[0].text,'Made refunds idempotent with a Redis lock; added a regression spec.','the model outcome supersedes the headline');
262
+
assert.match(fs.readFileSync(memory.memoryMdFile(root,slug),'utf8'),/Redislock/,'MEMORY.md follows the refinement');
263
+
assert.ok(!m.refineSummary(id,' '),'a blank refinement is refused');
0 commit comments