@letta-ai/letta-code 0.14.13 → 0.14.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/letta.js +976 -510
- package/package.json +1 -1
- package/scripts/postinstall-patches.js +1 -0
- package/skills/defragmenting-memory/SKILL.md +4 -1
- package/vendor/ink/build/log-update.js +63 -0
package/package.json
CHANGED
|
@@ -100,6 +100,7 @@ await copyToResolved(
|
|
|
100
100
|
"ink/build/hooks/use-input.js",
|
|
101
101
|
);
|
|
102
102
|
await copyToResolved("vendor/ink/build/devtools.js", "ink/build/devtools.js");
|
|
103
|
+
await copyToResolved("vendor/ink/build/log-update.js", "ink/build/log-update.js");
|
|
103
104
|
|
|
104
105
|
// ink-text-input (optional vendor with externalCursorOffset support)
|
|
105
106
|
await copyToResolved(
|
|
@@ -49,6 +49,7 @@ The memory subagent works directly on the memfs `system/` directory. After it fi
|
|
|
49
49
|
```typescript
|
|
50
50
|
Task({
|
|
51
51
|
subagent_type: "memory",
|
|
52
|
+
run_in_background: true,
|
|
52
53
|
description: "Decompose and reorganize memory files",
|
|
53
54
|
prompt: `You are decomposing and reorganizing memory files in ~/.letta/agents/${LETTA_AGENT_ID}/memory/system/ to improve clarity and focus.
|
|
54
55
|
|
|
@@ -162,14 +163,16 @@ Bash({
|
|
|
162
163
|
description: "Backup memfs directory before defrag"
|
|
163
164
|
})
|
|
164
165
|
|
|
165
|
-
// Step 2: Spawn subagent to decompose and reorganize
|
|
166
|
+
// Step 2: Spawn subagent to decompose and reorganize (runs async in background)
|
|
166
167
|
Task({
|
|
167
168
|
subagent_type: "memory",
|
|
169
|
+
run_in_background: true,
|
|
168
170
|
description: "Decompose and reorganize memory files",
|
|
169
171
|
prompt: "Decompose and reorganize memory files in ~/.letta/agents/$LETTA_AGENT_ID/memory/system/. These files sync directly to API blocks via memfs. Be aggressive about splitting large multi-section blocks into many smaller, single-purpose blocks using hierarchical / naming. Skip memory_filesystem.md and .sync-state.json. Structure with markdown headers and bullets. Remove redundancy and speculation. Resolve contradictions. Organize logically. Each block should have ONE clear purpose. Report files created, modified, deleted, before/after character counts, and rationale for changes."
|
|
170
172
|
})
|
|
171
173
|
|
|
172
174
|
// No Step 3 needed — memfs sync handles propagation to API blocks
|
|
175
|
+
// Check progress with /task <task_id>, restart CLI to sync when done
|
|
173
176
|
```
|
|
174
177
|
|
|
175
178
|
## Rollback
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import ansiEscapes from 'ansi-escapes';
|
|
2
|
+
import cliCursor from 'cli-cursor';
|
|
3
|
+
|
|
4
|
+
const create = (stream, { showCursor = false } = {}) => {
|
|
5
|
+
let previousLineCount = 0;
|
|
6
|
+
let previousOutput = '';
|
|
7
|
+
let hasHiddenCursor = false;
|
|
8
|
+
|
|
9
|
+
const renderWithClearedLineEnds = (output) => {
|
|
10
|
+
const lines = output.split('\n');
|
|
11
|
+
return lines.map((line) => line + ansiEscapes.eraseEndLine).join('\n');
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const render = (str) => {
|
|
15
|
+
if (!showCursor && !hasHiddenCursor) {
|
|
16
|
+
cliCursor.hide();
|
|
17
|
+
hasHiddenCursor = true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const output = str + '\n';
|
|
21
|
+
if (output === previousOutput) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Keep existing line-count semantics used by Ink's bundled log-update.
|
|
26
|
+
const nextLineCount = output.split('\n').length;
|
|
27
|
+
|
|
28
|
+
// Avoid eraseLines() pre-clear flashes by repainting in place:
|
|
29
|
+
// move to start of previous frame, rewrite each line while erasing EOL,
|
|
30
|
+
// then clear any trailing old lines if the frame got shorter.
|
|
31
|
+
if (previousLineCount > 1) {
|
|
32
|
+
stream.write(ansiEscapes.cursorUp(previousLineCount - 1));
|
|
33
|
+
}
|
|
34
|
+
stream.write(renderWithClearedLineEnds(output));
|
|
35
|
+
if (nextLineCount < previousLineCount) {
|
|
36
|
+
stream.write(ansiEscapes.eraseDown);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
previousOutput = output;
|
|
40
|
+
previousLineCount = nextLineCount;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
render.clear = () => {
|
|
44
|
+
stream.write(ansiEscapes.eraseLines(previousLineCount));
|
|
45
|
+
previousOutput = '';
|
|
46
|
+
previousLineCount = 0;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
render.done = () => {
|
|
50
|
+
previousOutput = '';
|
|
51
|
+
previousLineCount = 0;
|
|
52
|
+
if (!showCursor) {
|
|
53
|
+
cliCursor.show();
|
|
54
|
+
hasHiddenCursor = false;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
return render;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const logUpdate = { create };
|
|
62
|
+
export default logUpdate;
|
|
63
|
+
|