@letta-ai/letta-code 0.30.32 → 0.31.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/dist/agent-presets-agent-presets.js +11 -0
- package/dist/agent-presets-agent-presets.js.map +9 -0
- package/dist/agent-presets-personality-asset-content.js +42 -0
- package/dist/agent-presets-personality-asset-content.js.map +10 -0
- package/dist/agent-presets.js +17 -2
- package/dist/agent-presets.js.map +3 -3
- package/dist/channels-public.js +16 -1
- package/dist/channels-public.js.map +5 -4
- package/dist/gateway-core.js +5 -4
- package/dist/gateway-core.js.map +3 -3
- package/dist/mcp-client.js +2 -2
- package/dist/mcp-client.js.map +1 -1
- package/dist/types/agent/create-agent-request.d.ts +3 -0
- package/dist/types/agent/create-agent-request.d.ts.map +1 -1
- package/dist/types/agent/model.d.ts.map +1 -1
- package/dist/types/agent/personality-asset-content.d.ts +3 -0
- package/dist/types/agent/personality-asset-content.d.ts.map +1 -0
- package/dist/types/agent/skills.d.ts.map +1 -1
- package/dist/types/agent/subagents/manager.d.ts.map +1 -1
- package/dist/types/channels/gateway-core.d.ts.map +1 -1
- package/dist/types/channels/route-thread-key.d.ts +20 -0
- package/dist/types/channels/route-thread-key.d.ts.map +1 -0
- package/dist/types/channels-public.d.ts +1 -0
- package/dist/types/channels-public.d.ts.map +1 -1
- package/dist/types/tools/impl/shell-runner.d.ts.map +1 -1
- package/dist/types/tools/impl/skill.d.ts.map +1 -1
- package/dist/types/types/protocol_v2.d.ts +3 -144
- package/dist/types/types/protocol_v2.d.ts.map +1 -1
- package/dist/types/types/schedule-protocol.d.ts +151 -1
- package/dist/types/types/schedule-protocol.d.ts.map +1 -1
- package/dist/types/utils/frontmatter.d.ts.map +1 -1
- package/dist/types/utils/systemd-workload-scope.d.ts +15 -0
- package/dist/types/utils/systemd-workload-scope.d.ts.map +1 -0
- package/dist/types/websocket/listener/cwd-change.d.ts.map +1 -1
- package/letta.js +275 -94
- package/package.json +4 -2
- package/scripts/builtin-skills-watch/agent-watch.test.ts +104 -0
- package/scripts/builtin-skills-watch/agent-watch.ts +337 -0
- package/scripts/builtin-skills-watch/aggregate-results.test.ts +79 -0
- package/scripts/builtin-skills-watch/aggregate-results.ts +326 -0
- package/scripts/builtin-skills-watch/analysis.test.ts +70 -0
- package/scripts/builtin-skills-watch/analysis.ts +228 -0
- package/scripts/builtin-skills-watch/evidence.test.ts +114 -0
- package/scripts/builtin-skills-watch/evidence.ts +145 -0
- package/scripts/builtin-skills-watch/github.ts +161 -0
- package/scripts/builtin-skills-watch/tracker.test.ts +249 -0
- package/scripts/builtin-skills-watch/tracker.ts +506 -0
- package/scripts/builtin-skills-watch/update-tracker.test.ts +234 -0
- package/scripts/builtin-skills-watch/update-tracker.ts +508 -0
- package/scripts/claude-watch/release-source.test.ts +16 -4
- package/scripts/claude-watch/release-source.ts +41 -2
- package/scripts/codex-watch/agent-watch.ts +8 -5
- package/scripts/codex-watch/release-analysis.test.ts +18 -16
- package/scripts/codex-watch/release-analysis.ts +31 -9
- package/scripts/codex-watch/tracker.test.ts +5 -5
- package/scripts/codex-watch/tracker.ts +7 -8
- package/scripts/pi-ai-watch/agent-watch.ts +9 -14
- package/scripts/pi-ai-watch/release-analysis.test.ts +24 -18
- package/scripts/pi-ai-watch/release-analysis.ts +85 -45
- package/scripts/pi-ai-watch/tracker.test.ts +25 -18
- package/scripts/pi-ai-watch/tracker.ts +7 -19
- package/scripts/pi-ai-watch/update-tracker.ts +2 -2
- package/scripts/source-file-size-baseline.json +2 -2
- package/skills/dispatching-coding-agents/SKILL.md +16 -7
- package/skills/syncing-memory-filesystem/SKILL.md +118 -226
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
import type { PiAiWatchAnalysis } from "./release-analysis.ts";
|
|
3
3
|
import {
|
|
4
|
-
advanceMergedPr,
|
|
5
4
|
getPendingPrForCursor,
|
|
6
5
|
hasCompletedRange,
|
|
7
6
|
hasRecordedOutcome,
|
|
@@ -19,17 +18,18 @@ describe("pi-ai watch tracker", () => {
|
|
|
19
18
|
|
|
20
19
|
test("advances after a no-upgrade decision", () => {
|
|
21
20
|
const state = recordAnalysis(initialTrackerState("0.82.1"), {
|
|
22
|
-
analysis: analysis("0.82.1", "0.
|
|
21
|
+
analysis: analysis("0.82.1", "0.84.0"),
|
|
23
22
|
outcome: "no_upgrade",
|
|
24
23
|
notes: "upstream-only provider change",
|
|
25
24
|
processedAt: "2026-08-21T00:00:00Z",
|
|
26
25
|
});
|
|
27
|
-
expect(state.audit_cursor_version).toBe("0.
|
|
28
|
-
expect(hasCompletedRange(state, "0.82.1", "0.
|
|
29
|
-
expect(hasRecordedOutcome(state, "0.82.1", "0.
|
|
26
|
+
expect(state.audit_cursor_version).toBe("0.84.0");
|
|
27
|
+
expect(hasCompletedRange(state, "0.82.1", "0.84.0")).toBe(true);
|
|
28
|
+
expect(hasRecordedOutcome(state, "0.82.1", "0.84.0")).toBe(true);
|
|
29
|
+
expect(renderTrackerBody(state)).toContain("[0.82.1...0.84.0]");
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
test("
|
|
32
|
+
test("advances a created PR and keeps it pending at the cursor", () => {
|
|
33
33
|
const pending = recordAnalysis(initialTrackerState("0.82.1"), {
|
|
34
34
|
analysis: analysis("0.82.1", "0.83.0"),
|
|
35
35
|
outcome: "pr_created",
|
|
@@ -37,14 +37,18 @@ describe("pi-ai watch tracker", () => {
|
|
|
37
37
|
prUrl: "https://github.com/letta-ai/letta-code/pull/123",
|
|
38
38
|
processedAt: "2026-08-21T00:00:00Z",
|
|
39
39
|
});
|
|
40
|
-
expect(pending.audit_cursor_version).toBe("0.
|
|
40
|
+
expect(pending.audit_cursor_version).toBe("0.83.0");
|
|
41
41
|
expect(getPendingPrForCursor(pending)?.version).toBe("0.83.0");
|
|
42
|
-
expect(hasCompletedRange(pending, "0.82.1", "0.83.0")).toBe(
|
|
42
|
+
expect(hasCompletedRange(pending, "0.82.1", "0.83.0")).toBe(true);
|
|
43
43
|
expect(hasRecordedOutcome(pending, "0.82.1", "0.83.0")).toBe(true);
|
|
44
44
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
const later = recordAnalysis(pending, {
|
|
46
|
+
analysis: analysis("0.83.0", "0.84.0"),
|
|
47
|
+
outcome: "no_upgrade",
|
|
48
|
+
notes: "later release range",
|
|
49
|
+
});
|
|
50
|
+
expect(later.audit_cursor_version).toBe("0.84.0");
|
|
51
|
+
expect(getPendingPrForCursor(later)).toBeNull();
|
|
48
52
|
});
|
|
49
53
|
|
|
50
54
|
test("keeps errors retryable and replaces them with a later outcome", () => {
|
|
@@ -68,16 +72,16 @@ describe("pi-ai watch tracker", () => {
|
|
|
68
72
|
expect(retried.processed[0]?.outcome).toBe("no_upgrade");
|
|
69
73
|
});
|
|
70
74
|
|
|
71
|
-
test("advances
|
|
75
|
+
test("advances cumulative reviews but not replays behind the cursor", () => {
|
|
72
76
|
const human = recordAnalysis(initialTrackerState("0.82.1"), {
|
|
73
|
-
analysis: analysis("0.82.1", "0.
|
|
77
|
+
analysis: analysis("0.82.1", "0.84.0"),
|
|
74
78
|
outcome: "needs_human_review",
|
|
75
79
|
notes: "product decision",
|
|
76
80
|
});
|
|
77
|
-
expect(human.audit_cursor_version).toBe("0.
|
|
81
|
+
expect(human.audit_cursor_version).toBe("0.84.0");
|
|
78
82
|
|
|
79
83
|
const replay = recordAnalysis(initialTrackerState("0.82.1"), {
|
|
80
|
-
analysis: analysis("0.82.1", "0.
|
|
84
|
+
analysis: analysis("0.82.1", "0.83.0", false),
|
|
81
85
|
outcome: "no_upgrade",
|
|
82
86
|
notes: "explicit replay",
|
|
83
87
|
});
|
|
@@ -101,7 +105,7 @@ describe("pi-ai watch tracker", () => {
|
|
|
101
105
|
const previous = `0.${index}.0`;
|
|
102
106
|
const current = `0.${index}.1`;
|
|
103
107
|
state = recordAnalysis(state, {
|
|
104
|
-
analysis: analysis(previous, current
|
|
108
|
+
analysis: analysis(previous, current),
|
|
105
109
|
outcome: "error",
|
|
106
110
|
notes: `attempt ${index}`,
|
|
107
111
|
processedAt: `2026-08-21T00:${String(index).padStart(2, "0")}:00Z`,
|
|
@@ -115,18 +119,21 @@ describe("pi-ai watch tracker", () => {
|
|
|
115
119
|
function analysis(
|
|
116
120
|
previousVersion: string,
|
|
117
121
|
currentVersion: string,
|
|
118
|
-
|
|
122
|
+
isLatestRelease = true,
|
|
119
123
|
): PiAiWatchAnalysis {
|
|
120
124
|
return {
|
|
121
125
|
package: "@earendil-works/pi-ai",
|
|
122
126
|
installed_version: "0.82.1",
|
|
123
127
|
previous_version: previousVersion,
|
|
124
128
|
current_version: currentVersion,
|
|
125
|
-
|
|
129
|
+
is_latest_release: isLatestRelease,
|
|
126
130
|
published_at: "2026-08-14T00:00:00Z",
|
|
127
131
|
integrity: "sha512-test",
|
|
128
132
|
tarball_url: "https://example.test/pi-ai.tgz",
|
|
133
|
+
previous_git_head: "previous123",
|
|
129
134
|
git_head: "abc123",
|
|
135
|
+
previous_tag_commit: "previous123",
|
|
136
|
+
current_tag_commit: "abc123",
|
|
130
137
|
release_url: `https://github.com/earendil-works/pi/releases/tag/v${currentVersion}`,
|
|
131
138
|
compare_url: `https://github.com/earendil-works/pi/compare/v${previousVersion}...v${currentVersion}`,
|
|
132
139
|
changelog_md: "## Added",
|
|
@@ -87,9 +87,9 @@ export function recordAnalysis(
|
|
|
87
87
|
].slice(0, HISTORY_LIMIT);
|
|
88
88
|
|
|
89
89
|
const advancesCursor =
|
|
90
|
-
options.analysis.
|
|
90
|
+
options.analysis.is_latest_release &&
|
|
91
91
|
entry.previous_version === state.audit_cursor_version &&
|
|
92
|
-
|
|
92
|
+
entry.outcome !== "error";
|
|
93
93
|
|
|
94
94
|
return {
|
|
95
95
|
audit_cursor_version: advancesCursor
|
|
@@ -123,8 +123,7 @@ export function hasCompletedRange(
|
|
|
123
123
|
(entry) =>
|
|
124
124
|
entry.previous_version === previousVersion &&
|
|
125
125
|
entry.version === currentVersion &&
|
|
126
|
-
|
|
127
|
-
entry.outcome === "needs_human_review"),
|
|
126
|
+
entry.outcome !== "error",
|
|
128
127
|
);
|
|
129
128
|
}
|
|
130
129
|
|
|
@@ -134,24 +133,13 @@ export function getPendingPrForCursor(
|
|
|
134
133
|
return (
|
|
135
134
|
state.processed.find(
|
|
136
135
|
(entry) =>
|
|
137
|
-
entry.
|
|
136
|
+
entry.version === state.audit_cursor_version &&
|
|
138
137
|
entry.outcome === "pr_created" &&
|
|
139
138
|
entry.pr_url,
|
|
140
139
|
) ?? null
|
|
141
140
|
);
|
|
142
141
|
}
|
|
143
142
|
|
|
144
|
-
export function advanceMergedPr(
|
|
145
|
-
state: TrackerState,
|
|
146
|
-
currentVersion: string,
|
|
147
|
-
): TrackerState {
|
|
148
|
-
const pending = getPendingPrForCursor(state);
|
|
149
|
-
if (!pending || pending.version !== currentVersion) {
|
|
150
|
-
throw new Error(`No pending pi-ai PR for ${currentVersion}`);
|
|
151
|
-
}
|
|
152
|
-
return { ...state, audit_cursor_version: currentVersion };
|
|
153
|
-
}
|
|
154
|
-
|
|
155
143
|
export function renderTrackerBody(state: TrackerState): string {
|
|
156
144
|
const normalized = normalizeState(state);
|
|
157
145
|
return `${[
|
|
@@ -166,7 +154,7 @@ export function renderTrackerBody(state: TrackerState): string {
|
|
|
166
154
|
"",
|
|
167
155
|
"## Hidden state",
|
|
168
156
|
"",
|
|
169
|
-
"The workflow uses the hidden JSON block below for
|
|
157
|
+
"The workflow uses the hidden JSON block below for cumulative release processing and dedupe.",
|
|
170
158
|
"",
|
|
171
159
|
serializeTrackerState(normalized),
|
|
172
160
|
].join("\n")}\n`;
|
|
@@ -193,12 +181,12 @@ function renderTable(state: TrackerState): string {
|
|
|
193
181
|
if (entries.length === 0) return "_No pi-ai releases reviewed yet._";
|
|
194
182
|
|
|
195
183
|
const rows = [
|
|
196
|
-
"|
|
|
184
|
+
"| Range | Installed | Outcome | PR | Notes |",
|
|
197
185
|
"|---|---|---|---|---|",
|
|
198
186
|
];
|
|
199
187
|
for (const entry of entries) {
|
|
200
188
|
rows.push(
|
|
201
|
-
`| [${entry.version}](${entry.compare_url}) | ${entry.installed_version} | ${entry.outcome} | ${renderPr(entry.pr_url)} | ${escapeTable(entry.notes)} |`,
|
|
189
|
+
`| [${entry.previous_version}...${entry.version}](${entry.compare_url}) | ${entry.installed_version} | ${entry.outcome} | ${renderPr(entry.pr_url)} | ${escapeTable(entry.notes)} |`,
|
|
202
190
|
);
|
|
203
191
|
}
|
|
204
192
|
return rows.join("\n");
|
|
@@ -202,13 +202,13 @@ function parseOutcome(value: string | undefined): TrackerOutcome {
|
|
|
202
202
|
function defaultNotes(outcome: TrackerOutcome): string {
|
|
203
203
|
switch (outcome) {
|
|
204
204
|
case "no_upgrade":
|
|
205
|
-
return "reviewed; no upgrade needed for this release";
|
|
205
|
+
return "reviewed; no upgrade needed for this release range";
|
|
206
206
|
case "pr_created":
|
|
207
207
|
return "opened pi-ai dependency upgrade PR";
|
|
208
208
|
case "needs_human_review":
|
|
209
209
|
return "needs human review";
|
|
210
210
|
case "error":
|
|
211
|
-
return "automation hit an error; retry this release";
|
|
211
|
+
return "automation hit an error; retry this release range";
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
214
|
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
"src/settings-manager.ts": 2102,
|
|
38
38
|
"src/tools/manager.ts": 2993,
|
|
39
39
|
"src/tools/tool-execution-context.test.ts": 1138,
|
|
40
|
-
"src/types/protocol_v2.ts":
|
|
40
|
+
"src/types/protocol_v2.ts": 2666,
|
|
41
41
|
"src/websocket/listen-client-concurrency.test.ts": 2686,
|
|
42
42
|
"src/websocket/listen-client-protocol.test.ts": 5819,
|
|
43
43
|
"src/websocket/listener/commands/memory.ts": 1114,
|
|
44
44
|
"src/websocket/listener/file-commands.ts": 1053,
|
|
45
45
|
"src/websocket/listener/lifecycle.ts": 1048,
|
|
46
|
-
"src/websocket/listener/protocol-inbound.ts":
|
|
46
|
+
"src/websocket/listener/protocol-inbound.ts": 2227,
|
|
47
47
|
"src/websocket/listener/protocol-outbound.ts": 1047,
|
|
48
48
|
"src/websocket/listener/turn.ts": 1058
|
|
49
49
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dispatching-coding-agents
|
|
3
|
-
description: Dispatch stateless coding agents
|
|
3
|
+
description: Dispatch stateless coding agents through Claude Code or Codex. Model catalog checked 2026-08-25: Claude Code includes Sonnet 5, Opus 5, and Fable 5; Codex includes GPT-5.6 Luna, Terra, and Sol. Use when you're stuck, need a second opinion, or need parallel research on a hard problem. They have no memory, so you must provide all context.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Dispatching Coding Agents
|
|
@@ -43,14 +43,23 @@ Different agents have different strengths. Track what works in your memory over
|
|
|
43
43
|
|
|
44
44
|
### Categories
|
|
45
45
|
|
|
46
|
-
**Codex:**
|
|
47
|
-
-
|
|
46
|
+
**Codex (catalog checked 2026-08-25):**
|
|
47
|
+
- `gpt-5.6-luna`: high-throughput, lower-latency work
|
|
48
|
+
- `gpt-5.6-terra`: strong performance with a balance of intelligence and cost
|
|
49
|
+
- `gpt-5.6-sol`: quality-first flagship for difficult coding and reasoning
|
|
50
|
+
- Use the configured default unless the user requests a model. Pass a requested model with `-m`, for example `codex exec "YOUR PROMPT" -m gpt-5.6-sol --sandbox workspace-write`.
|
|
48
51
|
- If a requested model is rejected, inspect the installed CLI and account configuration rather than guessing another model name.
|
|
49
52
|
|
|
50
|
-
**Claude Code:**
|
|
51
|
-
-
|
|
52
|
-
|
|
53
|
-
-
|
|
53
|
+
**Claude Code (catalog checked 2026-08-25):**
|
|
54
|
+
- The current flagship models are Sonnet 5, Opus 5, and Fable 5. Use the configured default unless the user requests a model.
|
|
55
|
+
- Claude Code's stable aliases follow its current catalog:
|
|
56
|
+
- `best`: highest-capability model available to the account, using Fable 5 when available
|
|
57
|
+
- `fable`: Fable 5 for the hardest, longest-running tasks
|
|
58
|
+
- `opus`: Opus 5 for complex reasoning, docs, refactors, and open-ended tasks
|
|
59
|
+
- `sonnet`: Sonnet 5 for everyday coding
|
|
60
|
+
- `haiku`: fast, simple tasks
|
|
61
|
+
- Pass an alias with `--model`, for example `claude -p "YOUR PROMPT" --model fable --dangerously-skip-permissions`.
|
|
62
|
+
- Aliases update as Claude Code's catalog changes. If an alias is rejected, inspect the installed CLI version and account access rather than guessing a versioned model name.
|
|
54
63
|
|
|
55
64
|
### Cost and speed tradeoffs
|
|
56
65
|
- Use each CLI's configured default model unless the task requires a model the user explicitly requested
|