mirror of
https://github.com/sdwolf4103/opencode-working-memory.git
synced 2026-07-17 12:56:42 +02:00
chore(release): prepare v1.5.0
This commit is contained in:
+41
-11
@@ -10,7 +10,7 @@ OpenCode Working Memory implements a **three-layer memory architecture** designe
|
||||
│ • Persistent storage: ~/.local/share/opencode-working-... │
|
||||
│ • Types: feedback | project | decision | reference │
|
||||
│ • Sources: explicit | compaction | manual │
|
||||
│ • Limits: 5200 chars / 28 entries │
|
||||
│ • Render limits: 3600 chars / 28 entries │
|
||||
│ • Survives: session reset, compaction (same workspace) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
@@ -48,8 +48,9 @@ Long-term memory that persists across sessions within the same workspace. Perfec
|
||||
{
|
||||
version: 1,
|
||||
workspace: { root: string, key: string },
|
||||
limits: { maxRenderedChars: 5200, maxEntries: 28 },
|
||||
limits: { maxRenderedChars: 3600, maxEntries: 28 },
|
||||
entries: LongTermMemoryEntry[],
|
||||
lastActivityAt?: string,
|
||||
updatedAt: string
|
||||
}
|
||||
```
|
||||
@@ -90,18 +91,47 @@ Memory candidates:
|
||||
- Path-heavy facts (>50% paths)
|
||||
- Very short text (<20 chars)
|
||||
|
||||
### Consolidation and Deduplication
|
||||
### Consolidation, Deduplication, and Retention
|
||||
|
||||
Memories are deduplicated and consolidated with accounting:
|
||||
|
||||
1. Normalize exact text: lowercase, strip punctuation, collapse whitespace.
|
||||
2. Group project/reference entries by identity where possible.
|
||||
3. Group decisions and feedback by topic where possible.
|
||||
4. Keep the best surviving entry by source, confidence, type, and freshness rules.
|
||||
3. Keep decision and feedback entries on exact canonical matching to avoid broad semantic merges.
|
||||
4. Keep the best surviving entry by source, confidence, specificity, and freshness tie-breakers.
|
||||
5. Emit accounting events so pending memories can be classified as promoted, absorbed, superseded, or rejected.
|
||||
|
||||
This prevents absorbed or superseded pending memories from retrying forever while still preserving the active surviving memory.
|
||||
|
||||
Retention then decides which active memories are rendered into prompt context. It does not hard-delete old memories by age.
|
||||
|
||||
```typescript
|
||||
strength = initialStrength * 2 ** (-effectiveAgeDays / effectiveHalfLifeDays)
|
||||
```
|
||||
|
||||
Initial strength is based on memory type, source, optional user importance, and safety-critical status. Confidence remains stored for compatibility but is not part of retention scoring.
|
||||
|
||||
Rendered candidates are selected in this order:
|
||||
|
||||
1. Exclude `status: "superseded"` entries.
|
||||
2. Compute current retention strength.
|
||||
3. Sort by strength descending.
|
||||
4. Apply per-type caps, with safety-critical entries exempt from type caps.
|
||||
5. Keep the top 28 rendered entries under the workspace memory character budget.
|
||||
|
||||
Default type caps:
|
||||
|
||||
| Type | Rendered cap |
|
||||
|------|--------------|
|
||||
| `feedback` | 10 |
|
||||
| `decision` | 10 |
|
||||
| `project` | 8 |
|
||||
| `reference` | 6 |
|
||||
|
||||
The type-cap total is 34, intentionally above the global 28-entry cap. These are maximums, not quotas.
|
||||
|
||||
Dormant workspaces age more slowly: after 14 inactive days, additional dormant time counts at 0.25x for retention decay. Repeated duplicate memories reinforce the surviving entry and slow future decay, but same-session and under-one-hour repeats do not stack reinforcement.
|
||||
|
||||
### System Prompt Injection
|
||||
|
||||
Workspace memory is injected at the top of every message:
|
||||
@@ -241,7 +271,7 @@ Applies quality gate, redaction, migration, consolidation accounting, deduplicat
|
||||
- `session.compacted`: Promote session decisions to workspace memory
|
||||
- `session.deleted`: Clean up session state files
|
||||
|
||||
Promotion uses accounting results from workspace memory normalization. Pending memories that are kept are promoted; duplicate memories are absorbed; obsolete same-topic memories are superseded; stale or over-capacity compaction memories are rejected.
|
||||
Promotion uses accounting results from workspace memory normalization. Pending memories that are kept are promoted; duplicate memories are absorbed; exact decision replacements can be superseded; over-capacity compaction memories are rejected. Stale-marked memories are not hard-pruned by age; they lose rendered space through retention strength and cap competition.
|
||||
|
||||
## Quality Guarantees
|
||||
|
||||
@@ -319,14 +349,14 @@ const workspaceKey = sha256(realpath(workspaceRoot)).slice(0, 16)
|
||||
|
||||
| Layer | Max Chars | Max Entries |
|
||||
|-------|-----------|-------------|
|
||||
| Workspace Memory | 5200 | 28 |
|
||||
| Hot Session State | 1200 | 8 files, 3 errors |
|
||||
| Workspace Memory | 3600 | 28 |
|
||||
| Hot Session State | 700 | 8 files, 3 errors |
|
||||
|
||||
### Injection Overhead
|
||||
|
||||
- Workspace memory: ~200-500 chars per message
|
||||
- Hot session state: ~200-400 chars per message
|
||||
- Total: ~400-900 chars per message (minimal)
|
||||
- Workspace memory: usually under ~2000 chars in observed rendered output
|
||||
- Hot session state: usually under ~500 chars in observed rendered output
|
||||
- Total: typically well below the configured maximums
|
||||
|
||||
### Storage Footprint
|
||||
|
||||
|
||||
+48
-11
@@ -8,8 +8,8 @@ OpenCode Working Memory works out-of-the-box with sensible defaults. Configurati
|
||||
|
||||
```typescript
|
||||
const LONG_TERM_LIMITS = {
|
||||
maxRenderedChars: 5200, // Maximum characters in system prompt
|
||||
targetRenderedChars: 4200, // Target characters (leave buffer)
|
||||
maxRenderedChars: 3600, // Maximum characters in system prompt
|
||||
targetRenderedChars: 3000, // Target characters (leave buffer)
|
||||
maxEntries: 28, // Maximum number of entries
|
||||
maxEntryTextChars: 260, // Maximum characters per entry text
|
||||
maxRationaleChars: 180, // Maximum characters per entry rationale
|
||||
@@ -18,14 +18,40 @@ const LONG_TERM_LIMITS = {
|
||||
|
||||
**Recommendations**:
|
||||
- Keep `maxRenderedChars` under 5500 to avoid context bloat
|
||||
- Defaults are calibrated from observed rendered usage that was typically under ~2000 characters
|
||||
- `maxEntries` of 28 provides good coverage without overwhelming
|
||||
- Entry text limits ensure entries stay concise
|
||||
|
||||
## Retention Model Defaults
|
||||
|
||||
Workspace memory retention uses strength-based decay. These constants live in `src/workspace-memory.ts`:
|
||||
|
||||
```typescript
|
||||
const BASE_HALF_LIFE_DAYS = 45;
|
||||
const REINFORCEMENT_HALFLIFE_FACTOR = 0.85;
|
||||
const REINFORCEMENT_MAX_COUNT = 6;
|
||||
const WORKSPACE_DORMANT_AFTER_DAYS = 14;
|
||||
const DORMANT_DECAY_MULTIPLIER = 0.25;
|
||||
```
|
||||
|
||||
Initial strength uses type, source, user importance, and safety-critical factors. Confidence is stored for compatibility but is not used for retention scoring.
|
||||
|
||||
Rendered type caps prevent one type from filling all workspace memory slots:
|
||||
|
||||
| Type | Rendered cap |
|
||||
|------|--------------|
|
||||
| `feedback` | 10 |
|
||||
| `decision` | 10 |
|
||||
| `project` | 8 |
|
||||
| `reference` | 6 |
|
||||
|
||||
Safety-critical memories are exempt from type caps but still compete under the global `maxEntries` limit. Old or stale-marked memories are not hard-pruned by age; they lose rendered space through strength and cap competition.
|
||||
|
||||
## Hot Session State Limits
|
||||
|
||||
```typescript
|
||||
const HOT_STATE_LIMITS = {
|
||||
maxRenderedChars: 1200, // Maximum characters in system prompt
|
||||
maxRenderedChars: 700, // Maximum characters in system prompt
|
||||
maxActiveFilesStored: 20, // Maximum files tracked in state
|
||||
maxActiveFilesRendered: 8, // Maximum files shown in prompt
|
||||
maxOpenErrorsStored: 5, // Maximum errors tracked
|
||||
@@ -36,6 +62,7 @@ const HOT_STATE_LIMITS = {
|
||||
|
||||
**Recommendations**:
|
||||
- Keep `maxRenderedChars` under 1500 for fast prompts
|
||||
- Defaults are calibrated from observed rendered usage around ~500 characters or less
|
||||
- `maxActiveFilesRendered` of 8 provides good context coverage
|
||||
- `maxOpenErrorsRendered` of 3 avoids overwhelming error lists
|
||||
|
||||
@@ -43,12 +70,12 @@ const HOT_STATE_LIMITS = {
|
||||
|
||||
### Long-Term Memory Types
|
||||
|
||||
| Type | Purpose | Stale After (days) |
|
||||
|------|---------|---------------------|
|
||||
| `feedback` | User preferences for workspace | 90 |
|
||||
| `project` | Project-level information | 60 |
|
||||
| `decision` | Important decisions | 45 |
|
||||
| `reference` | Key references | 90 |
|
||||
| Type | Purpose | Rendered cap |
|
||||
|------|---------|--------------|
|
||||
| `feedback` | User preferences for workspace | 10 |
|
||||
| `project` | Project-level information | 8 |
|
||||
| `decision` | Important decisions | 10 |
|
||||
| `reference` | Key references | 6 |
|
||||
|
||||
### Memory Sources
|
||||
|
||||
@@ -114,7 +141,7 @@ To customize limits, edit the constants in `src/types.ts`:
|
||||
```typescript
|
||||
// Example: Increase workspace memory limit
|
||||
export const LONG_TERM_LIMITS = {
|
||||
maxRenderedChars: 6000, // Increased from 5200
|
||||
maxRenderedChars: 6000, // Increased from 3600
|
||||
maxEntries: 35, // Increased from 28
|
||||
// ...
|
||||
};
|
||||
@@ -144,7 +171,7 @@ const HOT_STATE_LIMITS = {
|
||||
// Preserve more context
|
||||
const LONG_TERM_LIMITS = {
|
||||
maxEntries: 40, // Increased
|
||||
targetRenderedChars: 5000, // Increased
|
||||
targetRenderedChars: 5000, // Increased
|
||||
};
|
||||
```
|
||||
|
||||
@@ -175,6 +202,16 @@ cat ~/.local/share/opencode-working-memory/workspaces/*/workspace-memory.json |
|
||||
cat ~/.local/share/opencode-working-memory/workspaces/*/sessions/*.json | jq
|
||||
```
|
||||
|
||||
### Inspect Retention Health
|
||||
|
||||
From a source checkout, maintainers can inspect stored vs rendered memory behavior:
|
||||
|
||||
```bash
|
||||
bun scripts/memory-diag.ts health
|
||||
```
|
||||
|
||||
The health output includes stored active memories, rendered candidates, type caps, global cap overflow, dormancy status, retention monitoring alerts, and strength-ranked top/weakest entries.
|
||||
|
||||
### Clear Workspace Memory
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user