@nexrall/code-core 1.4.28 → 1.4.30
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/agentTypes.d.ts +32 -0
- package/dist/agent/agentTypes.d.ts.map +1 -1
- package/dist/agent/agentTypes.js +74 -0
- package/dist/agent/loop.d.ts +65 -1
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +304 -18
- package/dist/agent/memory.d.ts +44 -0
- package/dist/agent/memory.d.ts.map +1 -1
- package/dist/agent/memory.js +117 -1
- package/dist/api/client.d.ts +11 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +2 -2
- package/dist/types.d.ts +19 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -19,7 +19,39 @@ export interface AgentType {
|
|
|
19
19
|
* permission gate, where it is a real refusal rather than a request.
|
|
20
20
|
*/
|
|
21
21
|
testFilesOnly?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Opt-in per-agent persistent notes: `memory: project | user | local`.
|
|
24
|
+
*
|
|
25
|
+
* Distinct from the SHARED memory store that memory_read/memory_write use. This
|
|
26
|
+
* gives one named agent its own file that only it reads and writes, so a
|
|
27
|
+
* repeatedly-invoked agent (a reviewer that keeps meeting the same anti-pattern)
|
|
28
|
+
* accumulates expertise without polluting — or being drowned out by — the main
|
|
29
|
+
* agent's memory. The trade-off is deliberate and worth stating: these stores are
|
|
30
|
+
* ISOLATED, so two agents learn nothing from each other.
|
|
31
|
+
*
|
|
32
|
+
* Scopes mirror the shared store's own split plus a not-committed variant:
|
|
33
|
+
* project — .nexrall/agent-memory/<name>.md (shareable via git)
|
|
34
|
+
* local — .nexrall/agent-memory-local/<name>.md (gitignored)
|
|
35
|
+
* user — ~/.nexrall/agent-memory/<name>.md (follows you everywhere)
|
|
36
|
+
*/
|
|
37
|
+
memory?: AgentMemoryScope;
|
|
38
|
+
/**
|
|
39
|
+
* Skip the project's nexrall.md for this agent, keeping its prompt lean.
|
|
40
|
+
*
|
|
41
|
+
* Claude Code does the same for its two research builtins (Explore and Plan skip
|
|
42
|
+
* CLAUDE.md and git status to stay fast and cheap), and the reasoning transfers: a
|
|
43
|
+
* search-and-report agent re-reads the entire project instruction file on EVERY
|
|
44
|
+
* invocation, on the tier chosen for being cheap, to produce output the main agent
|
|
45
|
+
* then interprets WITH that context anyway. The rules that must reach it belong in the
|
|
46
|
+
* delegation prompt instead.
|
|
47
|
+
*
|
|
48
|
+
* Only for agents that neither write files nor make judgement calls about conventions
|
|
49
|
+
* — a reviewer or test-writer needs the project's rules, an explorer does not.
|
|
50
|
+
*/
|
|
51
|
+
lightPrompt?: boolean;
|
|
22
52
|
}
|
|
53
|
+
/** Where a sub-agent's own persistent notes live. */
|
|
54
|
+
export type AgentMemoryScope = 'project' | 'user' | 'local';
|
|
23
55
|
/**
|
|
24
56
|
* A problem found while loading an agent definition.
|
|
25
57
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentTypes.d.ts","sourceRoot":"","sources":["../../src/agent/agentTypes.ts"],"names":[],"mappings":"AAiCA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,iDAAiD;IACjD,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,OAAO,CAAC;IAClC,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACpD;;;;;;;;;OASG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"agentTypes.d.ts","sourceRoot":"","sources":["../../src/agent/agentTypes.ts"],"names":[],"mappings":"AAiCA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,iDAAiD;IACjD,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,OAAO,CAAC;IAClC,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACpD;;;;;;;;;OASG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B;;;;;;;;;;;;OAYG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,qDAAqD;AACrD,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AA4U5D;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAyKD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,CAE3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;CAAE,CAqB5G;AAED,yFAAyF;AACzF,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAEzC;AAED,2FAA2F;AAC3F,wBAAgB,aAAa,IAAI,SAAS,EAAE,CAE3C;AACD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,MAAM,CAY1D;AAQD,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAIjG"}
|
package/dist/agent/agentTypes.js
CHANGED
|
@@ -43,6 +43,11 @@ const fs = __importStar(require("fs"));
|
|
|
43
43
|
const path = __importStar(require("path"));
|
|
44
44
|
const os = __importStar(require("os"));
|
|
45
45
|
const index_1 = require("../plugins/index");
|
|
46
|
+
const VALID_MEMORY_SCOPES = ['project', 'user', 'local'];
|
|
47
|
+
function parseMemoryScope(v) {
|
|
48
|
+
const s = (v ?? '').trim().toLowerCase();
|
|
49
|
+
return VALID_MEMORY_SCOPES.includes(s) ? s : undefined;
|
|
50
|
+
}
|
|
46
51
|
// ── Built-in agent types ──────────────────────────────────────────────────────
|
|
47
52
|
// Shipped defaults; lowest precedence (project > global > builtin), so a user
|
|
48
53
|
// can override any of them with a same-name .nexrall/agents/<name>.md file.
|
|
@@ -65,6 +70,22 @@ const READ_ONLY_TOOLS = [
|
|
|
65
70
|
// lifetime. Stopping a shell you started is not a write to the repo.
|
|
66
71
|
'kill_shell',
|
|
67
72
|
'notebook_read', 'todo_write', 'todo_read',
|
|
73
|
+
// memory_READ, deliberately without memory_write.
|
|
74
|
+
//
|
|
75
|
+
// Reading is free capability: a sub-agent that knows "tests run with X" or "never
|
|
76
|
+
// edit Z directly" does better work, and withholding it meant every sub-agent
|
|
77
|
+
// rediscovered project conventions from scratch. Writing is a different thing
|
|
78
|
+
// entirely — memory is durable, cross-session, SHARED state, while sub-agents run
|
|
79
|
+
// up to 4-wide in parallel with their reasoning hidden from the user. A wrong fact
|
|
80
|
+
// written there is invisible and permanent, and it competes for a capped, shared
|
|
81
|
+
// budget that gets periodically condensed.
|
|
82
|
+
//
|
|
83
|
+
// So the parent owns writes: a sub-agent that learns something durable says so in
|
|
84
|
+
// its report, and the main agent — the one actually talking to the user — decides.
|
|
85
|
+
// A sub-agent that needs its own persistent notes gets the per-agent store instead
|
|
86
|
+
// (see `memory:` in the frontmatter), which is scoped to itself and cannot pollute
|
|
87
|
+
// the shared file.
|
|
88
|
+
'memory_read',
|
|
68
89
|
// Skills are reusable prompt playbooks, and loop.ts advertises the skills
|
|
69
90
|
// catalogue to sub-agents at EVERY depth — so withholding the tool that loads
|
|
70
91
|
// one meant showing every sub-agent a menu it could not order from.
|
|
@@ -94,6 +115,37 @@ const WRITE_TOOLS = [
|
|
|
94
115
|
'notebook_edit',
|
|
95
116
|
];
|
|
96
117
|
const BUILTIN_AGENTS = [
|
|
118
|
+
{
|
|
119
|
+
// The catch-all, matching Claude Code's `general-purpose`.
|
|
120
|
+
//
|
|
121
|
+
// This capability already existed — omitting `subagent_type` gives an unrestricted
|
|
122
|
+
// sub-agent — but it had no NAME, and that had two consequences worth fixing:
|
|
123
|
+
//
|
|
124
|
+
// 1. `permissions.deny: ["task(...)"]` matches on the agent name, so the ONE
|
|
125
|
+
// sub-agent that can write files and run bash was the one variant a project
|
|
126
|
+
// could not disable individually. Only a blanket `deny: ["task"]` reached it.
|
|
127
|
+
// 2. The model had to infer that leaving the field blank was even an option, so
|
|
128
|
+
// it would sometimes pick a specialist that fitted badly (an unrestricted
|
|
129
|
+
// explorer) rather than the general worker it actually wanted.
|
|
130
|
+
//
|
|
131
|
+
// `tools` is deliberately UNDEFINED, which means "no allowlist" — full access,
|
|
132
|
+
// inheriting whatever the session permits. That is the same power an unnamed
|
|
133
|
+
// sub-task always had; naming it changes only who can see and deny it. The safety
|
|
134
|
+
// properties elsewhere still apply: plan mode is inherited, the user's permission
|
|
135
|
+
// gate still runs on every call, and it cannot spawn further sub-agents.
|
|
136
|
+
name: 'general-purpose',
|
|
137
|
+
description: 'General-purpose worker for a multi-step task that needs BOTH exploration and changes ' +
|
|
138
|
+
'(edit files, run commands) and that no specialist above fits. Inherits the session model ' +
|
|
139
|
+
'and full tool access, so prefer a narrower agent when one matches.',
|
|
140
|
+
prompt: 'You are a general-purpose engineering sub-agent. Work the task end to end: explore what you ' +
|
|
141
|
+
'need, make the changes, and verify them with the project\'s own build/test commands.\n\n' +
|
|
142
|
+
'Rules:\n' +
|
|
143
|
+
'- Mirror existing conventions; make the smallest correct change.\n' +
|
|
144
|
+
'- Verify before you claim success. If you could not verify, say so explicitly.\n' +
|
|
145
|
+
'- Your FINAL MESSAGE is the only thing that reaches the main agent: state what you changed ' +
|
|
146
|
+
'(with file paths), what you ran and its outcome, and anything you deliberately left undone.',
|
|
147
|
+
source: 'builtin',
|
|
148
|
+
},
|
|
97
149
|
{
|
|
98
150
|
name: 'reviewer',
|
|
99
151
|
description: 'Read-only code reviewer — finds correctness bugs, edge cases, and security issues in a diff or file set. Cannot modify files.',
|
|
@@ -156,6 +208,9 @@ const BUILTIN_AGENTS = [
|
|
|
156
208
|
// frontier model, and this is the agent most likely to be spawned in bulk.
|
|
157
209
|
{
|
|
158
210
|
name: 'explorer',
|
|
211
|
+
// Lean prompt: this agent exists to keep bulk searching cheap, and it reports
|
|
212
|
+
// findings for the MAIN agent to interpret with full project context.
|
|
213
|
+
lightPrompt: true,
|
|
159
214
|
description: 'Fast read-only codebase explorer — locates files, symbols, and call sites and reports concise findings. Use to keep bulk searching out of the main context. Cannot modify files.',
|
|
160
215
|
tools: READ_ONLY_TOOLS,
|
|
161
216
|
model: 'turbo',
|
|
@@ -289,12 +344,16 @@ const KNOWN_TOOL_NAMES = new Set([
|
|
|
289
344
|
'todo_write', 'todo_read', 'memory_write', 'memory_read', 'use_skill',
|
|
290
345
|
'fetch_url', 'web_search', 'generate_image', 'stock_photo', 'open_in_browser',
|
|
291
346
|
'task',
|
|
347
|
+
// Granted by a `memory:` scope rather than listed in a `tools:` line, but a user may
|
|
348
|
+
// still name it explicitly — so it must validate rather than be flagged as a typo.
|
|
349
|
+
'agent_memory_write',
|
|
292
350
|
'get_symbols', 'get_workspace_symbols', 'find_references', 'go_to_definition',
|
|
293
351
|
'get_hover', 'get_diagnostics',
|
|
294
352
|
]);
|
|
295
353
|
/** Frontmatter keys this parser understands, for typo detection. */
|
|
296
354
|
const KNOWN_META_KEYS = new Set([
|
|
297
355
|
'name', 'description', 'tools', 'model', 'test_files_only', 'testfilesonly',
|
|
356
|
+
'memory',
|
|
298
357
|
]);
|
|
299
358
|
const VALID_MODELS = ['turbo', 'pro', 'ultra'];
|
|
300
359
|
function parseFrontmatter(raw) {
|
|
@@ -391,6 +450,15 @@ function loadDir(dir, source, into, warnings) {
|
|
|
391
450
|
message: 'has no `description:` — that text is the ONLY thing the model uses to decide when to delegate to this agent, so it will rarely be picked.',
|
|
392
451
|
});
|
|
393
452
|
}
|
|
453
|
+
// Same class of mistake as an invalid model: silently ignoring it would leave
|
|
454
|
+
// the agent with no memory while its prompt tells it to keep notes.
|
|
455
|
+
if (meta.memory !== undefined && parseMemoryScope(meta.memory) === undefined) {
|
|
456
|
+
warnings.push({
|
|
457
|
+
file: full,
|
|
458
|
+
agent: name,
|
|
459
|
+
message: `has memory: "${meta.memory}", which is not a valid scope — use one of ${VALID_MEMORY_SCOPES.join(', ')}, or omit the line to give this agent no persistent notes.`,
|
|
460
|
+
});
|
|
461
|
+
}
|
|
394
462
|
if (meta.model !== undefined && parseModel(meta.model) === undefined) {
|
|
395
463
|
warnings.push({
|
|
396
464
|
file: full,
|
|
@@ -438,6 +506,12 @@ function loadDir(dir, source, into, warnings) {
|
|
|
438
506
|
// cannot touch production source, rather than only the builtin getting
|
|
439
507
|
// that guarantee.
|
|
440
508
|
...(parseBool(meta.test_files_only ?? meta.testfilesonly) ? { testFilesOnly: true } : {}),
|
|
509
|
+
// The `ok &&` is defensive, not load-bearing: parseFrontmatter already returns an
|
|
510
|
+
// EMPTY meta when it cannot find a `---` block, so `meta.memory` is undefined on
|
|
511
|
+
// that path regardless. It stays because the guarantee we want — an unreadable
|
|
512
|
+
// definition never receives a writable store — should survive parseFrontmatter
|
|
513
|
+
// being changed to salvage partial metadata, which is a plausible future edit.
|
|
514
|
+
...(ok && parseMemoryScope(meta.memory) ? { memory: parseMemoryScope(meta.memory) } : {}),
|
|
441
515
|
});
|
|
442
516
|
}
|
|
443
517
|
}
|
package/dist/agent/loop.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { Message, AgentLoopOptions, EnvContext } from '../types';
|
|
1
|
+
import type { Message, ToolResult, AgentLoopOptions, EnvContext } from '../types';
|
|
2
|
+
import { type AgentMemoryScope } from './agentTypes';
|
|
2
3
|
/**
|
|
3
4
|
* Fingerprint one round's tool failures, for the repeated-failure runaway guard.
|
|
4
5
|
*
|
|
@@ -19,6 +20,47 @@ export declare const _stallLimits: {
|
|
|
19
20
|
STALL_LIMIT: number;
|
|
20
21
|
REPEAT_STALL_LIMIT: number;
|
|
21
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* The single tool granted by a `memory:` frontmatter scope.
|
|
25
|
+
*
|
|
26
|
+
* Named distinctly from `memory_write` on purpose: they write to DIFFERENT stores, and
|
|
27
|
+
* a model that saw one name for both would reasonably assume its notes were visible to
|
|
28
|
+
* the main agent. They are not.
|
|
29
|
+
*/
|
|
30
|
+
export declare const AGENT_MEMORY_TOOL = "agent_memory_write";
|
|
31
|
+
/**
|
|
32
|
+
* Schema advertised to the model, only for a sub-agent with a declared memory scope.
|
|
33
|
+
*
|
|
34
|
+
* The description does the load-bearing work of keeping the two stores apart in the
|
|
35
|
+
* model's head: it must not believe these notes reach the user or the main agent.
|
|
36
|
+
*/
|
|
37
|
+
export declare const AGENT_MEMORY_TOOL_SCHEMA: {
|
|
38
|
+
readonly name: "agent_memory_write";
|
|
39
|
+
readonly description: string;
|
|
40
|
+
readonly input_schema: {
|
|
41
|
+
readonly type: "object";
|
|
42
|
+
readonly properties: {
|
|
43
|
+
readonly content: {
|
|
44
|
+
readonly type: "string";
|
|
45
|
+
readonly description: "The single fact to remember, 1-2 sentences.";
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
readonly required: readonly ["content"];
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
/** Identifies whose notes an agent_memory_write call may touch. */
|
|
52
|
+
export interface AgentMemoryBinding {
|
|
53
|
+
agentName: string;
|
|
54
|
+
scope: AgentMemoryScope;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Execute an `agent_memory_write` call.
|
|
58
|
+
*
|
|
59
|
+
* Pure-ish and exported so the refusal paths are testable without spawning a real
|
|
60
|
+
* sub-agent: the binding is data, so "no binding" and "unsafe agent name" can both be
|
|
61
|
+
* exercised directly.
|
|
62
|
+
*/
|
|
63
|
+
export declare function executeAgentMemoryWrite(input: Record<string, unknown>, binding: AgentMemoryBinding | undefined, workDir?: string): Promise<ToolResult>;
|
|
22
64
|
/**
|
|
23
65
|
* Why an agent run stopped.
|
|
24
66
|
*
|
|
@@ -49,6 +91,18 @@ export declare function resolveMaxIterations(optionValue: number | undefined, se
|
|
|
49
91
|
* dozen lines.
|
|
50
92
|
*/
|
|
51
93
|
export declare function createLimiter(max: number): <T>(fn: () => Promise<T>) => Promise<T>;
|
|
94
|
+
/**
|
|
95
|
+
* How long a sub-agent may make NO progress before it is stopped.
|
|
96
|
+
*
|
|
97
|
+
* Precedence matches every other tunable in this file
|
|
98
|
+
* (env → settings.json → default) — it used to be env-ONLY, which meant a project that
|
|
99
|
+
* legitimately needed longer sub-tasks had no way to say so in the file where every
|
|
100
|
+
* other such preference lives, and the limit was invisible to anyone reading settings.
|
|
101
|
+
*
|
|
102
|
+
* Exported for tests: the behaviour that matters (a long-but-productive sub-agent is
|
|
103
|
+
* NOT killed) takes minutes of wall clock to exercise through the real loop.
|
|
104
|
+
*/
|
|
105
|
+
export declare function resolveSubtaskTimeoutMs(settingsRaw: Record<string, unknown>): number;
|
|
52
106
|
/**
|
|
53
107
|
* Thrown by a sub-agent's permission gate when the AGENT DEFINITION forbids a
|
|
54
108
|
* tool — as opposed to the user declining it.
|
|
@@ -93,6 +147,16 @@ export declare function capSubTaskText(text: string, max?: number): string;
|
|
|
93
147
|
* had already been billed in full.
|
|
94
148
|
*/
|
|
95
149
|
export declare function summariseSubTaskProgress(messages: Message[]): string;
|
|
150
|
+
/**
|
|
151
|
+
* The last N tool results from a transcript, newest last, each truncated.
|
|
152
|
+
*
|
|
153
|
+
* Pure + exported so the salvage rules are testable without a real sub-agent.
|
|
154
|
+
*
|
|
155
|
+
* Truncation keeps the HEAD of each result: tool output is overwhelmingly
|
|
156
|
+
* front-loaded (a file starts with its imports, a failing command starts with its
|
|
157
|
+
* error), and a head slice is the half that identifies what was found.
|
|
158
|
+
*/
|
|
159
|
+
export declare function lastToolResults(messages: Message[], count: number, maxChars: number): string;
|
|
96
160
|
/** The context window (tokens) for a model alias — the same lookup runAgentLoop uses internally. */
|
|
97
161
|
export declare function contextWindowFor(model?: 'turbo' | 'pro' | 'ultra'): number;
|
|
98
162
|
/** Auto-prune / auto-compact thresholds as fractions of the context window — for UI display (e.g. `/context`). */
|
package/dist/agent/loop.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/agent/loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,
|
|
1
|
+
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/agent/loop.ts"],"names":[],"mappings":"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"}
|
package/dist/agent/loop.js
CHANGED
|
@@ -33,14 +33,17 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.VERIFY_CMD_RE = exports.WRITE_TOOL_NAMES = exports.ToolNotAllowedError = exports._stallLimits = void 0;
|
|
36
|
+
exports.VERIFY_CMD_RE = exports.WRITE_TOOL_NAMES = exports.ToolNotAllowedError = exports.AGENT_MEMORY_TOOL_SCHEMA = exports.AGENT_MEMORY_TOOL = exports._stallLimits = void 0;
|
|
37
37
|
exports.errorRoundSignature = errorRoundSignature;
|
|
38
|
+
exports.executeAgentMemoryWrite = executeAgentMemoryWrite;
|
|
38
39
|
exports.stopReasonNotice = stopReasonNotice;
|
|
39
40
|
exports.resolveMaxIterations = resolveMaxIterations;
|
|
40
41
|
exports.createLimiter = createLimiter;
|
|
42
|
+
exports.resolveSubtaskTimeoutMs = resolveSubtaskTimeoutMs;
|
|
41
43
|
exports.extractSubTaskText = extractSubTaskText;
|
|
42
44
|
exports.capSubTaskText = capSubTaskText;
|
|
43
45
|
exports.summariseSubTaskProgress = summariseSubTaskProgress;
|
|
46
|
+
exports.lastToolResults = lastToolResults;
|
|
44
47
|
exports.contextWindowFor = contextWindowFor;
|
|
45
48
|
exports.compactionThresholds = compactionThresholds;
|
|
46
49
|
exports.estimateBodyBytes = estimateBodyBytes;
|
|
@@ -215,6 +218,72 @@ function errorRoundSignature(errored) {
|
|
|
215
218
|
}
|
|
216
219
|
/** Runaway-guard limits, exposed for tests. */
|
|
217
220
|
exports._stallLimits = { STALL_LIMIT, REPEAT_STALL_LIMIT };
|
|
221
|
+
/**
|
|
222
|
+
* The single tool granted by a `memory:` frontmatter scope.
|
|
223
|
+
*
|
|
224
|
+
* Named distinctly from `memory_write` on purpose: they write to DIFFERENT stores, and
|
|
225
|
+
* a model that saw one name for both would reasonably assume its notes were visible to
|
|
226
|
+
* the main agent. They are not.
|
|
227
|
+
*/
|
|
228
|
+
exports.AGENT_MEMORY_TOOL = 'agent_memory_write';
|
|
229
|
+
/**
|
|
230
|
+
* Schema advertised to the model, only for a sub-agent with a declared memory scope.
|
|
231
|
+
*
|
|
232
|
+
* The description does the load-bearing work of keeping the two stores apart in the
|
|
233
|
+
* model's head: it must not believe these notes reach the user or the main agent.
|
|
234
|
+
*/
|
|
235
|
+
exports.AGENT_MEMORY_TOOL_SCHEMA = {
|
|
236
|
+
name: exports.AGENT_MEMORY_TOOL,
|
|
237
|
+
description: 'Save a durable note to YOUR OWN persistent notes, which are injected into your prompt on ' +
|
|
238
|
+
'future runs. Use this for lessons that will still be true next time — a convention this repo ' +
|
|
239
|
+
'follows, a recurring bug pattern, a command that works, a dead end not worth retrying. ' +
|
|
240
|
+
'These notes are PRIVATE to you: they are NOT shown to the user and NOT read by the main agent, ' +
|
|
241
|
+
'so anything the user or the main agent needs to know must still go in your final message. ' +
|
|
242
|
+
'One self-contained fact per call, a sentence or two. Do not save transient task details.',
|
|
243
|
+
input_schema: {
|
|
244
|
+
type: 'object',
|
|
245
|
+
properties: {
|
|
246
|
+
content: { type: 'string', description: 'The single fact to remember, 1-2 sentences.' },
|
|
247
|
+
},
|
|
248
|
+
required: ['content'],
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
/**
|
|
252
|
+
* Execute an `agent_memory_write` call.
|
|
253
|
+
*
|
|
254
|
+
* Pure-ish and exported so the refusal paths are testable without spawning a real
|
|
255
|
+
* sub-agent: the binding is data, so "no binding" and "unsafe agent name" can both be
|
|
256
|
+
* exercised directly.
|
|
257
|
+
*/
|
|
258
|
+
async function executeAgentMemoryWrite(input, binding, workDir) {
|
|
259
|
+
// Belt-and-braces: the permission gate already refuses this tool without a binding.
|
|
260
|
+
// Re-checked because this is the function that actually touches the filesystem, and
|
|
261
|
+
// it must not depend on a caller elsewhere having got the check right.
|
|
262
|
+
if (!binding) {
|
|
263
|
+
return {
|
|
264
|
+
error: `${exports.AGENT_MEMORY_TOOL} is only available to a sub-agent whose definition declares a \`memory:\` ` +
|
|
265
|
+
'scope. Put anything worth remembering in your final message instead.',
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
const content = typeof input.content === 'string' ? input.content.trim() : '';
|
|
269
|
+
if (!content)
|
|
270
|
+
return { error: `${exports.AGENT_MEMORY_TOOL} requires a non-empty \`content\` string.` };
|
|
271
|
+
const res = await (0, memory_1.writeAgentMemory)(binding.agentName, binding.scope, content, workDir);
|
|
272
|
+
if (!res.ok) {
|
|
273
|
+
// The realistic cause is a repo-scoped store with no workDir, or an agent name that
|
|
274
|
+
// is not a safe single path segment. Say which, rather than a bare failure.
|
|
275
|
+
return {
|
|
276
|
+
error: `Could not save to the "${binding.agentName}" agent's ${binding.scope} notes. ` +
|
|
277
|
+
'Either this scope needs a project directory (use `memory: user` for a store that ' +
|
|
278
|
+
'works anywhere) or the agent name is not usable as a filename.',
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
return {
|
|
282
|
+
output: res.already
|
|
283
|
+
? 'Already saved (a near-identical note exists) — nothing added.'
|
|
284
|
+
: `Saved to your ${binding.scope} notes. It will be in your prompt on your next run.`,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
218
287
|
/**
|
|
219
288
|
* The message shown when a run ends for any reason other than a clean finish.
|
|
220
289
|
*
|
|
@@ -472,9 +541,28 @@ let _subTaskCounter = 0; // unique per-process id → per-sub-agent todo scope
|
|
|
472
541
|
// pointing at it specifically. Give every sub-task an explicit wall-clock cap:
|
|
473
542
|
// if it hasn't finished by then, fail it clearly instead of hanging the parent
|
|
474
543
|
// turn indefinitely. Overridable via env for slow CI machines / huge sub-tasks.
|
|
475
|
-
const
|
|
476
|
-
|
|
477
|
-
|
|
544
|
+
const DEFAULT_SUBTASK_TIMEOUT_MS = 10 * 60 * 1000; // 10 min of NO PROGRESS (see the watchdog)
|
|
545
|
+
/**
|
|
546
|
+
* How long a sub-agent may make NO progress before it is stopped.
|
|
547
|
+
*
|
|
548
|
+
* Precedence matches every other tunable in this file
|
|
549
|
+
* (env → settings.json → default) — it used to be env-ONLY, which meant a project that
|
|
550
|
+
* legitimately needed longer sub-tasks had no way to say so in the file where every
|
|
551
|
+
* other such preference lives, and the limit was invisible to anyone reading settings.
|
|
552
|
+
*
|
|
553
|
+
* Exported for tests: the behaviour that matters (a long-but-productive sub-agent is
|
|
554
|
+
* NOT killed) takes minutes of wall clock to exercise through the real loop.
|
|
555
|
+
*/
|
|
556
|
+
function resolveSubtaskTimeoutMs(settingsRaw) {
|
|
557
|
+
const fromEnv = Number(process.env.NEXRALL_SUBTASK_TIMEOUT_MS);
|
|
558
|
+
if (Number.isFinite(fromEnv) && fromEnv > 0)
|
|
559
|
+
return Math.floor(fromEnv);
|
|
560
|
+
const raw = settingsRaw.subtaskTimeoutMs;
|
|
561
|
+
const fromSettings = Number(raw);
|
|
562
|
+
if (Number.isFinite(fromSettings) && fromSettings > 0)
|
|
563
|
+
return Math.floor(fromSettings);
|
|
564
|
+
return DEFAULT_SUBTASK_TIMEOUT_MS;
|
|
565
|
+
}
|
|
478
566
|
/** Cap on the text a sub-task hands back, so one verbose sub-agent can't blow up
|
|
479
567
|
* the PARENT's context in a single tool_result. */
|
|
480
568
|
const SUBTASK_MAX = 48000; // chars (~12k tokens)
|
|
@@ -581,6 +669,14 @@ function summariseSubTaskProgress(messages) {
|
|
|
581
669
|
}
|
|
582
670
|
if (toolNames.length === 0)
|
|
583
671
|
return '';
|
|
672
|
+
// The FINDINGS, not just the activity log.
|
|
673
|
+
//
|
|
674
|
+
// An inventory of tool names ("read_file ×9, bash ×14") tells the parent that work
|
|
675
|
+
// happened but nothing about what was learned, so it re-derives everything. A stalled
|
|
676
|
+
// research agent's value is almost entirely in what its last few tool calls RETURNED
|
|
677
|
+
// — the file it had just read, the command output it was about to interpret — because
|
|
678
|
+
// its own prose summary is exactly the thing it never got to write.
|
|
679
|
+
const recentFindings = lastToolResults(messages, SALVAGE_RESULT_COUNT, SALVAGE_RESULT_CHARS);
|
|
584
680
|
// Collapse to "name ×N" so a 40-call run reads as a short inventory rather
|
|
585
681
|
// than forty repeated lines of the same tool name.
|
|
586
682
|
const counts = new Map();
|
|
@@ -590,7 +686,71 @@ function summariseSubTaskProgress(messages) {
|
|
|
590
686
|
.sort((a, b) => b[1] - a[1])
|
|
591
687
|
.map(([name, n]) => (n > 1 ? `${name} ×${n}` : name))
|
|
592
688
|
.join(', ');
|
|
593
|
-
|
|
689
|
+
const header = `Tool calls completed before it was stopped (${toolNames.length} total): ${inventory}.`;
|
|
690
|
+
return recentFindings
|
|
691
|
+
? `${header}\n\nWhat its most recent tool calls actually returned (use this instead of repeating them):\n${recentFindings}`
|
|
692
|
+
: header;
|
|
693
|
+
}
|
|
694
|
+
/** How many trailing tool results to salvage, and how much of each. */
|
|
695
|
+
const SALVAGE_RESULT_COUNT = 4;
|
|
696
|
+
const SALVAGE_RESULT_CHARS = 2000;
|
|
697
|
+
/**
|
|
698
|
+
* The last N tool results from a transcript, newest last, each truncated.
|
|
699
|
+
*
|
|
700
|
+
* Pure + exported so the salvage rules are testable without a real sub-agent.
|
|
701
|
+
*
|
|
702
|
+
* Truncation keeps the HEAD of each result: tool output is overwhelmingly
|
|
703
|
+
* front-loaded (a file starts with its imports, a failing command starts with its
|
|
704
|
+
* error), and a head slice is the half that identifies what was found.
|
|
705
|
+
*/
|
|
706
|
+
function lastToolResults(messages, count, maxChars) {
|
|
707
|
+
// Map tool_use id → tool name, so a salvaged result can say WHICH tool produced it.
|
|
708
|
+
const nameById = new Map();
|
|
709
|
+
for (const m of messages) {
|
|
710
|
+
if (m.role !== 'assistant' || !Array.isArray(m.content))
|
|
711
|
+
continue;
|
|
712
|
+
for (const b of m.content) {
|
|
713
|
+
if (b?.type === 'tool_use' && b.id && typeof b.name === 'string')
|
|
714
|
+
nameById.set(b.id, b.name);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
const out = [];
|
|
718
|
+
// Walk backwards and stop early: only the most recent results are worth the tokens,
|
|
719
|
+
// and a long research run may hold hundreds.
|
|
720
|
+
for (let i = messages.length - 1; i >= 0 && out.length < count; i--) {
|
|
721
|
+
const m = messages[i];
|
|
722
|
+
if (m.role !== 'user' || !Array.isArray(m.content))
|
|
723
|
+
continue;
|
|
724
|
+
for (const b of [...m.content].reverse()) {
|
|
725
|
+
if (out.length >= count)
|
|
726
|
+
break;
|
|
727
|
+
if (b?.type !== 'tool_result')
|
|
728
|
+
continue;
|
|
729
|
+
const text = toolResultText(b);
|
|
730
|
+
if (!text)
|
|
731
|
+
continue;
|
|
732
|
+
const name = nameById.get(String(b.tool_use_id ?? '')) ?? 'tool';
|
|
733
|
+
const body = text.length > maxChars
|
|
734
|
+
? `${sliceSafeEnd(text, maxChars)}\n… [truncated]`
|
|
735
|
+
: text;
|
|
736
|
+
out.push(`• ${name}:\n${body}`);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
return out.reverse().join('\n\n');
|
|
740
|
+
}
|
|
741
|
+
/** Extract readable text from a tool_result block, whose content may be string or blocks. */
|
|
742
|
+
function toolResultText(block) {
|
|
743
|
+
const c = block.content;
|
|
744
|
+
if (typeof c === 'string')
|
|
745
|
+
return c.trim();
|
|
746
|
+
if (Array.isArray(c)) {
|
|
747
|
+
return c
|
|
748
|
+
.filter((x) => x?.type === 'text' && typeof x.text === 'string')
|
|
749
|
+
.map((x) => x.text)
|
|
750
|
+
.join('\n')
|
|
751
|
+
.trim();
|
|
752
|
+
}
|
|
753
|
+
return '';
|
|
594
754
|
}
|
|
595
755
|
async function runSubTask(input, options, agentTypes) {
|
|
596
756
|
const prompt = typeof input.prompt === 'string' ? input.prompt.trim() : '';
|
|
@@ -673,9 +833,29 @@ async function runSubTask(input, options, agentTypes) {
|
|
|
673
833
|
// A custom agent's persona is delivered through the project-instructions
|
|
674
834
|
// channel (authoritative in the system prompt), layered above the project's
|
|
675
835
|
// own nexrall.md so it keeps project conventions.
|
|
836
|
+
// ── Per-agent memory (`memory:` frontmatter) ────────────────────────────────
|
|
837
|
+
//
|
|
838
|
+
// When an agent declares a memory scope, its own notes from previous runs are
|
|
839
|
+
// injected ahead of its role prompt, and it gains ONE extra tool to append to them.
|
|
840
|
+
//
|
|
841
|
+
// Claude Code implements the equivalent by auto-enabling Read/Write/Edit "regardless
|
|
842
|
+
// of what the tools allowlist says". We deliberately do NOT copy that: silently
|
|
843
|
+
// widening a declared allowlist is fail-OPEN, and this repo already fixed the
|
|
844
|
+
// mirror-image bug (an unparseable agent file used to receive FULL access). So the
|
|
845
|
+
// grant here is a single purpose-built tool that can only ever touch this agent's
|
|
846
|
+
// own notes file — declaring `memory:` cannot hand anything write access to the repo.
|
|
847
|
+
const memoryScope = agent?.memory;
|
|
848
|
+
const agentMemoryNotes = agent && memoryScope
|
|
849
|
+
? (0, memory_1.agentMemoryPreamble)(agent.name, memoryScope, options.workDir)
|
|
850
|
+
: '';
|
|
851
|
+
// `lightPrompt` agents skip the project's nexrall.md — see AgentType.lightPrompt for
|
|
852
|
+
// why. The role prompt and any private notes still apply; only the (potentially very
|
|
853
|
+
// large) project instruction file is dropped.
|
|
854
|
+
const inheritedMd = agent?.lightPrompt ? '' : (options.nexrallMd ?? '');
|
|
676
855
|
const subNexrallMd = agent
|
|
677
856
|
? `# Sub-agent role: ${agent.name}\n${agent.prompt}` +
|
|
678
|
-
(
|
|
857
|
+
(agentMemoryNotes ? `\n\n---\n\n${agentMemoryNotes}` : '') +
|
|
858
|
+
(inheritedMd ? `\n\n---\n\n${inheritedMd}` : '')
|
|
679
859
|
: options.nexrallMd;
|
|
680
860
|
// Optional tool allowlist — deny anything outside it for this sub-agent.
|
|
681
861
|
//
|
|
@@ -684,7 +864,19 @@ async function runSubTask(input, options, agentTypes) {
|
|
|
684
864
|
// nothing, and a model told that will re-ask for approval instead of noticing
|
|
685
865
|
// that the agent's own allowlist (often a typo'd tool name) is what stopped it.
|
|
686
866
|
const allowed = agent?.tools ? new Set(agent.tools) : null;
|
|
867
|
+
// The ONE capability `memory:` grants. Added to the allowlist rather than bypassing
|
|
868
|
+
// it, so the allowlist stays the single source of truth for what this agent can do.
|
|
869
|
+
if (allowed && memoryScope)
|
|
870
|
+
allowed.add(exports.AGENT_MEMORY_TOOL);
|
|
687
871
|
const gatedPermission = async (req) => {
|
|
872
|
+
// Guard against the tool being reachable without a declared scope — e.g. an agent
|
|
873
|
+
// that lists it in `tools:` by hand, or a general-purpose sub-task with no
|
|
874
|
+
// allowlist at all (`allowed === null` permits everything).
|
|
875
|
+
if (req.tool === exports.AGENT_MEMORY_TOOL && !(agent && memoryScope)) {
|
|
876
|
+
throw new ToolNotAllowedError(`\`${exports.AGENT_MEMORY_TOOL}\` is only available to a sub-agent whose definition declares a ` +
|
|
877
|
+
'`memory:` scope (project, user or local). Report anything worth remembering in your final ' +
|
|
878
|
+
'message instead — the main agent decides what to persist.');
|
|
879
|
+
}
|
|
688
880
|
if (allowed && !allowed.has(req.tool)) {
|
|
689
881
|
throw new ToolNotAllowedError(`The "${agent.name}" sub-agent is not allowed to use \`${req.tool}\` — it is not in that agent's ` +
|
|
690
882
|
'tool allowlist. This is a restriction of the agent definition, NOT a user decision: do not ask ' +
|
|
@@ -714,7 +906,34 @@ async function runSubTask(input, options, agentTypes) {
|
|
|
714
906
|
// runAgentLoop already checks abortSignal.aborted at every iteration boundary,
|
|
715
907
|
// so this is enough to make it stop promptly without a forceful kill.
|
|
716
908
|
const subAbort = { aborted: false };
|
|
717
|
-
const
|
|
909
|
+
const subtaskTimeoutMs = resolveSubtaskTimeoutMs((0, rules_1.loadSettings)(options.workDir).raw);
|
|
910
|
+
// ── Stall watchdog, NOT a total-runtime deadline ─────────────────────────────
|
|
911
|
+
//
|
|
912
|
+
// This used to be a single setTimeout armed once and never refreshed. Its own
|
|
913
|
+
// comment called it a "stalled-agent cutoff", but it measured TOTAL LIFETIME: a
|
|
914
|
+
// sub-agent working hard and calling a tool every few seconds was killed at ten
|
|
915
|
+
// minutes exactly like one that had hung. That is not a hypothetical — auditing a
|
|
916
|
+
// handful of 600-2800 line files legitimately exceeds it, and when it fired the
|
|
917
|
+
// parent got back a fragment ("I'll start by reading the files…") after paying for
|
|
918
|
+
// 23 tool calls, then typically re-ran the whole thing.
|
|
919
|
+
//
|
|
920
|
+
// The main loop already draws this distinction correctly (client.ts's heartbeat vs
|
|
921
|
+
// progress watchdogs, where only real events bump lastProgressAt). Sub-agents now do
|
|
922
|
+
// too: the clock resets on every completed tool round, so the cap means "no progress
|
|
923
|
+
// for N minutes" — which is what catches a genuine hang — while useful work can run
|
|
924
|
+
// as long as it keeps being useful.
|
|
925
|
+
//
|
|
926
|
+
// `stalled` is tracked separately from `subAbort.aborted` because the parent's Ctrl+C
|
|
927
|
+
// also sets the latter, and the two must be reported differently.
|
|
928
|
+
let lastProgressAt = Date.now();
|
|
929
|
+
let stalled = false;
|
|
930
|
+
const bumpProgress = () => { lastProgressAt = Date.now(); };
|
|
931
|
+
const stallWatchdog = setInterval(() => {
|
|
932
|
+
if (Date.now() - lastProgressAt > subtaskTimeoutMs) {
|
|
933
|
+
stalled = true;
|
|
934
|
+
subAbort.aborted = true;
|
|
935
|
+
}
|
|
936
|
+
}, 1000);
|
|
718
937
|
// Mirror the parent's own abort into the sub-agent's signal so Ctrl+C during
|
|
719
938
|
// a running sub-task still stops it (previously this worked implicitly by
|
|
720
939
|
// sharing the same object via `...options` — now that we own a distinct
|
|
@@ -728,6 +947,27 @@ async function runSubTask(input, options, agentTypes) {
|
|
|
728
947
|
...options,
|
|
729
948
|
_depth: depth + 1,
|
|
730
949
|
_agentScope: `sub_${++_subTaskCounter}`, // isolated todo store per sub-agent
|
|
950
|
+
// ── Assigned UNCONDITIONALLY, never by conditional spread ────────────────
|
|
951
|
+
//
|
|
952
|
+
// These two were previously spread in only when set:
|
|
953
|
+
//
|
|
954
|
+
// ...(agent && memoryScope ? { _agentMemory: … } : {}),
|
|
955
|
+
//
|
|
956
|
+
// which does NOT clear the key — it leaves whatever `...options` already had.
|
|
957
|
+
// So a child WITHOUT its own `memory:` inherited its PARENT's binding and would
|
|
958
|
+
// have appended to another agent's private notes; likewise an agent with no
|
|
959
|
+
// `tools:` line inherited the parent's allowlist, making the prompt's capability
|
|
960
|
+
// claim disagree with its real one.
|
|
961
|
+
//
|
|
962
|
+
// MAX_TASK_DEPTH === 1 means no nested spawn can reach this today, so it is
|
|
963
|
+
// latent rather than live — but the limiter comment below explicitly contemplates
|
|
964
|
+
// raising that depth, and this is exactly the kind of leak that would come back
|
|
965
|
+
// as a security bug rather than a visible error. Explicit undefined makes the
|
|
966
|
+
// child's identity independent of the parent's by construction.
|
|
967
|
+
_agentMemory: agent && memoryScope ? { agentName: agent.name, scope: memoryScope } : undefined,
|
|
968
|
+
// The same set `gatedPermission` enforces above, so prompt and permission agree
|
|
969
|
+
// by construction instead of by two people remembering to update both.
|
|
970
|
+
_allowedTools: allowed ?? undefined,
|
|
731
971
|
editorContext: null, // fresh isolated context for sub-agent
|
|
732
972
|
model: agent?.model ?? options.model,
|
|
733
973
|
// Plan mode is inherited, never relaxed. If the main agent could spawn a
|
|
@@ -756,13 +996,20 @@ async function runSubTask(input, options, agentTypes) {
|
|
|
756
996
|
// Forward tool events with isSubTask=true so the UI can render a badge
|
|
757
997
|
// instead of prepending "[sub-task]" to the tool name (which caused double-prefix
|
|
758
998
|
// when the name was already labelled, and mixed display concerns into the data layer).
|
|
759
|
-
|
|
760
|
-
|
|
999
|
+
// Every tool event is PROGRESS: it proves the sub-agent is still doing work, which
|
|
1000
|
+
// is what the stall watchdog above measures. Bumping on both use and result means a
|
|
1001
|
+
// single very slow tool (a long test run) resets the clock when it starts AND when
|
|
1002
|
+
// it finishes, so it cannot be mistaken for a hang.
|
|
1003
|
+
onToolUse: (n, i) => { bumpProgress(); options.onToolUse(n, i, true); },
|
|
1004
|
+
onToolResult: (n, r) => { bumpProgress(); options.onToolResult(n, r, true); },
|
|
761
1005
|
onToolStreamChunk: (n, c) => options.onToolStreamChunk?.(n, c, true),
|
|
762
1006
|
// Forward thinking so the UI shows the indicator while sub-agent reasons
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
1007
|
+
// Thinking is progress too — a model reasoning for minutes on a hard problem is
|
|
1008
|
+
// working, not stalled. Without this, deep reasoning on an expensive tier would
|
|
1009
|
+
// trip the watchdog precisely when the sub-agent was most valuable.
|
|
1010
|
+
onThinking: (text) => { bumpProgress(); options.onThinking?.(text); },
|
|
1011
|
+
onThinkingDelta: (text) => { bumpProgress(); options.onThinkingDelta?.(text); },
|
|
1012
|
+
onThinkingProgress: (tok) => { bumpProgress(); options.onThinkingProgress?.(tok); },
|
|
766
1013
|
});
|
|
767
1014
|
// ── Stall timeout: SALVAGE, don't discard ────────────────────────────────
|
|
768
1015
|
//
|
|
@@ -777,15 +1024,29 @@ async function runSubTask(input, options, agentTypes) {
|
|
|
777
1024
|
// whatever was actually accomplished, not instead of it. `preferLast: false`
|
|
778
1025
|
// because a killed sub-agent rarely has a closing summary — its useful output
|
|
779
1026
|
// is spread across the assistant turns it did manage to produce.
|
|
780
|
-
if (
|
|
781
|
-
const mins = Math.round(
|
|
1027
|
+
if (stalled && !options.abortSignal?.aborted) {
|
|
1028
|
+
const mins = Math.round(subtaskTimeoutMs / 60000);
|
|
782
1029
|
const partial = capSubTaskText(extractSubTaskText(result, false));
|
|
783
1030
|
const progress = summariseSubTaskProgress(result);
|
|
1031
|
+
// Keep the transcript so the parent can CONTINUE this run instead of redoing it.
|
|
1032
|
+
//
|
|
1033
|
+
// Previously only a cleanly-finished sub-agent was remembered, on the reasoning
|
|
1034
|
+
// that a transcript ending mid-thought is unsafe to build on. The reasoning is
|
|
1035
|
+
// sound; the conclusion was too strong. Refusing to store it meant a stalled
|
|
1036
|
+
// sub-agent's entire body of work — dozens of tool calls, already billed — was
|
|
1037
|
+
// unreachable, so the parent's only option was the very thing we tell it not to
|
|
1038
|
+
// do: run the whole task again. Resuming is now POSSIBLE but never implied to be
|
|
1039
|
+
// safe: the text below states plainly that the work is unverified, and resumption
|
|
1040
|
+
// re-authorises against current permissions exactly as it does for a clean run.
|
|
1041
|
+
const partialId = (0, agentRegistry_1.rememberAgent)(agent?.name ?? null, (typeof input.description === 'string' && input.description.trim()) || prompt.slice(0, 80), result);
|
|
784
1042
|
const sections = [
|
|
785
|
-
`Sub-task STOPPED after ${mins} minutes
|
|
1043
|
+
`Sub-task STOPPED after ${mins} minutes with NO PROGRESS (it was not making tool calls or ` +
|
|
1044
|
+
'producing output) — treat everything below as PARTIAL, unverified work, not a finished answer.',
|
|
786
1045
|
progress,
|
|
787
1046
|
partial ? `Partial output before it was stopped:\n\n${partial}` : '',
|
|
788
|
-
|
|
1047
|
+
`Do NOT re-run the same sub-task from scratch. Either build on what is above, or continue THIS ` +
|
|
1048
|
+
`run with resume_agent_id="${partialId}" (it still has everything it read), or split the ` +
|
|
1049
|
+
'remaining work into smaller, more focused sub-tasks.',
|
|
789
1050
|
].filter(Boolean);
|
|
790
1051
|
// Returned as `error` (not `output`) on purpose: the loop's ledger counts an
|
|
791
1052
|
// errored call as a non-effect, which is right — nothing here is verified —
|
|
@@ -834,7 +1095,7 @@ async function runSubTask(input, options, agentTypes) {
|
|
|
834
1095
|
return { error: `Sub-task failed: ${err.message}` };
|
|
835
1096
|
}
|
|
836
1097
|
finally {
|
|
837
|
-
|
|
1098
|
+
clearInterval(stallWatchdog);
|
|
838
1099
|
clearInterval(parentAbortPoll);
|
|
839
1100
|
}
|
|
840
1101
|
}
|
|
@@ -1850,7 +2111,23 @@ async function runAgentLoop(initialMessages, options) {
|
|
|
1850
2111
|
nexrallMd: planAwareNexrallMd,
|
|
1851
2112
|
clientType: options.clientType,
|
|
1852
2113
|
abortSignal: options.abortSignal,
|
|
1853
|
-
|
|
2114
|
+
// MCP tools, plus the per-agent memory tool when (and only when) this run
|
|
2115
|
+
// is a sub-agent that declared a `memory:` scope. Declaring it through
|
|
2116
|
+
// extraTools rather than the backend's static catalogue keeps it invisible
|
|
2117
|
+
// to every other run: a tool the model cannot see is one it cannot try,
|
|
2118
|
+
// which is better than advertising it everywhere and refusing it at the gate.
|
|
2119
|
+
extraTools: [
|
|
2120
|
+
...(options.mcpManager?.getAnthropicTools() ?? []),
|
|
2121
|
+
...(options._agentMemory ? [exports.AGENT_MEMORY_TOOL_SCHEMA] : []),
|
|
2122
|
+
],
|
|
2123
|
+
// Derived from the run's ACTUAL allowlist rather than asserted separately,
|
|
2124
|
+
// so the prompt's memory instructions cannot drift from what is permitted.
|
|
2125
|
+
// That drift is the bug being fixed: sub-agents were told they MUST call
|
|
2126
|
+
// memory_write, which no sub-agent allowlist contains.
|
|
2127
|
+
canWriteSharedMemory: options._allowedTools
|
|
2128
|
+
? options._allowedTools.has('memory_write')
|
|
2129
|
+
: true, // no allowlist = main agent = may write
|
|
2130
|
+
hasOwnAgentStore: !!options._agentMemory,
|
|
1854
2131
|
agents: agentsCatalogue || undefined,
|
|
1855
2132
|
skills: skillsCatalogue || undefined,
|
|
1856
2133
|
// Only allow a post-render restart when the caller actually implements the
|
|
@@ -2160,6 +2437,15 @@ async function runAgentLoop(initialMessages, options) {
|
|
|
2160
2437
|
}
|
|
2161
2438
|
else {
|
|
2162
2439
|
try {
|
|
2440
|
+
// 0. Per-agent memory append. Handled HERE rather than in the executor
|
|
2441
|
+
// because only this loop knows which agent is running and what scope it
|
|
2442
|
+
// declared — the executor's TOOL_MAP is keyed by tool name alone, so it
|
|
2443
|
+
// could not tell whose notes to write to (and must not be able to).
|
|
2444
|
+
if (name === exports.AGENT_MEMORY_TOOL) {
|
|
2445
|
+
result = await executeAgentMemoryWrite(input, options._agentMemory, options.workDir);
|
|
2446
|
+
options.onToolResult(name, result);
|
|
2447
|
+
return { block: { ...block, id }, result };
|
|
2448
|
+
}
|
|
2163
2449
|
// 1. Try platform-specific tools (e.g. VS Code semantic tools)
|
|
2164
2450
|
const external = options.executeExternalTool
|
|
2165
2451
|
? await options.executeExternalTool(name, input)
|
package/dist/agent/memory.d.ts
CHANGED
|
@@ -41,5 +41,49 @@ export declare function memoryStats(scope: MemoryScope, workDir?: string): {
|
|
|
41
41
|
* pulling api/client.ts's network/auth machinery into every consumer of this
|
|
42
42
|
* module and to keep this file trivially unit-testable.
|
|
43
43
|
*/
|
|
44
|
+
/** Max chars injected into a sub-agent's prompt from its own notes. */
|
|
45
|
+
export declare const AGENT_MEMORY_INJECT_MAX = 8000;
|
|
46
|
+
/** Hard cap on one agent's notes file. Same eviction-on-overflow rule as above. */
|
|
47
|
+
export declare const AGENT_MEMORY_MAX_BYTES = 24000;
|
|
48
|
+
/**
|
|
49
|
+
* Reject anything that isn't a plain, single-segment agent name.
|
|
50
|
+
*
|
|
51
|
+
* The name reaches this module from a FILENAME or a `name:` frontmatter field, and it
|
|
52
|
+
* is about to become a path segment — so `../../.ssh/authorized_keys` as an agent name
|
|
53
|
+
* would otherwise let a checked-in repo file choose where we write. Allowing only
|
|
54
|
+
* [A-Za-z0-9._-] and rejecting any form of separator or `..` makes traversal
|
|
55
|
+
* impossible rather than merely unlikely; the containment assertion in
|
|
56
|
+
* agentMemoryPath is the second line of defence.
|
|
57
|
+
*/
|
|
58
|
+
export declare function isSafeAgentName(name: string): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Resolve where one agent's notes live, or null if the name is unsafe.
|
|
61
|
+
*
|
|
62
|
+
* `project` and `local` live under the repo (only `project` is meant to be committed);
|
|
63
|
+
* `user` follows the person across every checkout.
|
|
64
|
+
*/
|
|
65
|
+
export declare function agentMemoryPath(agentName: string, scope: 'project' | 'user' | 'local', workDir?: string): string | null;
|
|
66
|
+
/** Read an agent's own notes (empty string when it has none). */
|
|
67
|
+
export declare function readAgentMemory(agentName: string, scope: 'project' | 'user' | 'local', workDir?: string): string;
|
|
68
|
+
/**
|
|
69
|
+
* Append a fact to an agent's own notes.
|
|
70
|
+
*
|
|
71
|
+
* Same shape as writeMemory (dated bullets, per-entry cap, near-duplicate skip, file
|
|
72
|
+
* lock) so behaviour is predictable across both stores — but bounded by simple
|
|
73
|
+
* eviction rather than LLM compaction: this file is small, per-agent, and not worth a
|
|
74
|
+
* model call to condense.
|
|
75
|
+
*/
|
|
76
|
+
export declare function writeAgentMemory(agentName: string, scope: 'project' | 'user' | 'local', content: string, workDir?: string): Promise<{
|
|
77
|
+
ok: boolean;
|
|
78
|
+
already: boolean;
|
|
79
|
+
file: string;
|
|
80
|
+
}>;
|
|
81
|
+
/**
|
|
82
|
+
* The block prepended to a sub-agent's instructions, or '' when it has no notes.
|
|
83
|
+
*
|
|
84
|
+
* Truncated from the TAIL: the newest entries are the ones worth keeping when a store
|
|
85
|
+
* outgrows the injection budget.
|
|
86
|
+
*/
|
|
87
|
+
export declare function agentMemoryPreamble(agentName: string, scope: 'project' | 'user' | 'local', workDir?: string): string;
|
|
44
88
|
export declare function compactMemoryIfNeeded(scope: MemoryScope, workDir: string | undefined, summarize: (prompt: string) => Promise<string>): Promise<boolean>;
|
|
45
89
|
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/agent/memory.ts"],"names":[],"mappings":"AAiCA,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE/C;;;sDAGsD;AACtD,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAI3E;AAED,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAC1C,eAAO,MAAM,gBAAgB,QAAS,CAAC;AACvC,eAAO,MAAM,4BAA4B,QAAS,CAAC;AAMnD,eAAO,MAAM,qBAAqB,QAAmC,CAAC;AA4CtE,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAuBnH;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAGvE;AAED;gFACgF;AAChF,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAStD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAGtE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAKlH;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAC7C,OAAO,CAAC,OAAO,CAAC,CA+BlB"}
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/agent/memory.ts"],"names":[],"mappings":"AAiCA,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE/C;;;sDAGsD;AACtD,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAI3E;AAED,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAC1C,eAAO,MAAM,gBAAgB,QAAS,CAAC;AACvC,eAAO,MAAM,4BAA4B,QAAS,CAAC;AAMnD,eAAO,MAAM,qBAAqB,QAAmC,CAAC;AA4CtE,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAuBnH;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAGvE;AAED;gFACgF;AAChF,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAStD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAGtE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAKlH;AAED;;;;;;;;;;;;;;;GAeG;AAUH,uEAAuE;AACvE,eAAO,MAAM,uBAAuB,OAAQ,CAAC;AAC7C,mFAAmF;AACnF,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAE7C;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,EACnC,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAqBf;AAED,iEAAiE;AACjE,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,EACnC,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAIR;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,EACnC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAuB1D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,EACnC,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAYR;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAC7C,OAAO,CAAC,OAAO,CAAC,CA+BlB"}
|
package/dist/agent/memory.js
CHANGED
|
@@ -33,13 +33,18 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.MEMORY_HARD_CAP_BYTES = exports.MEMORY_COMPACT_TRIGGER_BYTES = exports.MEMORY_MAX_BYTES = exports.MEMORY_ENTRY_MAX_CHARS = void 0;
|
|
36
|
+
exports.AGENT_MEMORY_MAX_BYTES = exports.AGENT_MEMORY_INJECT_MAX = exports.MEMORY_HARD_CAP_BYTES = exports.MEMORY_COMPACT_TRIGGER_BYTES = exports.MEMORY_MAX_BYTES = exports.MEMORY_ENTRY_MAX_CHARS = void 0;
|
|
37
37
|
exports.memoryFilePath = memoryFilePath;
|
|
38
38
|
exports.writeMemory = writeMemory;
|
|
39
39
|
exports.readMemory = readMemory;
|
|
40
40
|
exports.readAllMemory = readAllMemory;
|
|
41
41
|
exports.clearMemory = clearMemory;
|
|
42
42
|
exports.memoryStats = memoryStats;
|
|
43
|
+
exports.isSafeAgentName = isSafeAgentName;
|
|
44
|
+
exports.agentMemoryPath = agentMemoryPath;
|
|
45
|
+
exports.readAgentMemory = readAgentMemory;
|
|
46
|
+
exports.writeAgentMemory = writeAgentMemory;
|
|
47
|
+
exports.agentMemoryPreamble = agentMemoryPreamble;
|
|
43
48
|
exports.compactMemoryIfNeeded = compactMemoryIfNeeded;
|
|
44
49
|
const fs = __importStar(require("fs"));
|
|
45
50
|
const os = __importStar(require("os"));
|
|
@@ -209,6 +214,117 @@ function memoryStats(scope, workDir) {
|
|
|
209
214
|
* pulling api/client.ts's network/auth machinery into every consumer of this
|
|
210
215
|
* module and to keep this file trivially unit-testable.
|
|
211
216
|
*/
|
|
217
|
+
// ─── Per-agent memory (the `memory:` frontmatter field) ──────────────────────
|
|
218
|
+
//
|
|
219
|
+
// A SEPARATE store from the shared global/project memory above. The shared store is
|
|
220
|
+
// the main agent's, written while the user watches; this one belongs to a single
|
|
221
|
+
// named sub-agent so a repeatedly-invoked agent can accumulate its own expertise
|
|
222
|
+
// without polluting the shared file (and without 4 parallel sub-agents fighting over
|
|
223
|
+
// it). The cost, stated plainly: these stores are ISOLATED — two agents learn nothing
|
|
224
|
+
// from one another.
|
|
225
|
+
/** Max chars injected into a sub-agent's prompt from its own notes. */
|
|
226
|
+
exports.AGENT_MEMORY_INJECT_MAX = 8000;
|
|
227
|
+
/** Hard cap on one agent's notes file. Same eviction-on-overflow rule as above. */
|
|
228
|
+
exports.AGENT_MEMORY_MAX_BYTES = 24000;
|
|
229
|
+
/**
|
|
230
|
+
* Reject anything that isn't a plain, single-segment agent name.
|
|
231
|
+
*
|
|
232
|
+
* The name reaches this module from a FILENAME or a `name:` frontmatter field, and it
|
|
233
|
+
* is about to become a path segment — so `../../.ssh/authorized_keys` as an agent name
|
|
234
|
+
* would otherwise let a checked-in repo file choose where we write. Allowing only
|
|
235
|
+
* [A-Za-z0-9._-] and rejecting any form of separator or `..` makes traversal
|
|
236
|
+
* impossible rather than merely unlikely; the containment assertion in
|
|
237
|
+
* agentMemoryPath is the second line of defence.
|
|
238
|
+
*/
|
|
239
|
+
function isSafeAgentName(name) {
|
|
240
|
+
return /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name) && !name.includes('..');
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Resolve where one agent's notes live, or null if the name is unsafe.
|
|
244
|
+
*
|
|
245
|
+
* `project` and `local` live under the repo (only `project` is meant to be committed);
|
|
246
|
+
* `user` follows the person across every checkout.
|
|
247
|
+
*/
|
|
248
|
+
function agentMemoryPath(agentName, scope, workDir) {
|
|
249
|
+
if (!isSafeAgentName(agentName))
|
|
250
|
+
return null;
|
|
251
|
+
const file = `${agentName}.md`;
|
|
252
|
+
let dir;
|
|
253
|
+
if (scope === 'user') {
|
|
254
|
+
dir = path.join(MEMORY_ROOT, 'agent-memory');
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
// Repo-scoped stores need a workDir; without one there is no repo to scope to.
|
|
258
|
+
if (!workDir)
|
|
259
|
+
return null;
|
|
260
|
+
dir = path.join(path.resolve(workDir), '.nexrall', scope === 'local' ? 'agent-memory-local' : 'agent-memory');
|
|
261
|
+
}
|
|
262
|
+
const full = path.join(dir, file);
|
|
263
|
+
// Defence in depth: even if the name check above were ever loosened, the resolved
|
|
264
|
+
// path must still sit inside the directory we intended.
|
|
265
|
+
const rel = path.relative(dir, full);
|
|
266
|
+
if (rel.startsWith('..') || path.isAbsolute(rel))
|
|
267
|
+
return null;
|
|
268
|
+
return full;
|
|
269
|
+
}
|
|
270
|
+
/** Read an agent's own notes (empty string when it has none). */
|
|
271
|
+
function readAgentMemory(agentName, scope, workDir) {
|
|
272
|
+
const file = agentMemoryPath(agentName, scope, workDir);
|
|
273
|
+
if (!file)
|
|
274
|
+
return '';
|
|
275
|
+
return readMemoryFile(file).trim();
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Append a fact to an agent's own notes.
|
|
279
|
+
*
|
|
280
|
+
* Same shape as writeMemory (dated bullets, per-entry cap, near-duplicate skip, file
|
|
281
|
+
* lock) so behaviour is predictable across both stores — but bounded by simple
|
|
282
|
+
* eviction rather than LLM compaction: this file is small, per-agent, and not worth a
|
|
283
|
+
* model call to condense.
|
|
284
|
+
*/
|
|
285
|
+
async function writeAgentMemory(agentName, scope, content, workDir) {
|
|
286
|
+
let trimmed = content.trim();
|
|
287
|
+
if (!trimmed)
|
|
288
|
+
return { ok: false, already: false, file: '' };
|
|
289
|
+
if (trimmed.length > exports.MEMORY_ENTRY_MAX_CHARS) {
|
|
290
|
+
trimmed = trimmed.slice(0, exports.MEMORY_ENTRY_MAX_CHARS - 1).trimEnd() + '…';
|
|
291
|
+
}
|
|
292
|
+
const file = agentMemoryPath(agentName, scope, workDir);
|
|
293
|
+
if (!file)
|
|
294
|
+
return { ok: false, already: false, file: '' };
|
|
295
|
+
return withLock(file, async () => {
|
|
296
|
+
const existing = readMemoryFile(file);
|
|
297
|
+
const fingerprint = trimmed.toLowerCase().slice(0, FINGERPRINT_LEN);
|
|
298
|
+
if (existing.toLowerCase().includes(fingerprint)) {
|
|
299
|
+
return { ok: true, already: true, file };
|
|
300
|
+
}
|
|
301
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
302
|
+
let next = existing + `\n- [${today}] ${trimmed}`;
|
|
303
|
+
if (Buffer.byteLength(next, 'utf-8') > exports.AGENT_MEMORY_MAX_BYTES) {
|
|
304
|
+
next = evictOldest(next, exports.AGENT_MEMORY_MAX_BYTES);
|
|
305
|
+
}
|
|
306
|
+
writeMemoryFile(file, next);
|
|
307
|
+
return { ok: true, already: false, file };
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* The block prepended to a sub-agent's instructions, or '' when it has no notes.
|
|
312
|
+
*
|
|
313
|
+
* Truncated from the TAIL: the newest entries are the ones worth keeping when a store
|
|
314
|
+
* outgrows the injection budget.
|
|
315
|
+
*/
|
|
316
|
+
function agentMemoryPreamble(agentName, scope, workDir) {
|
|
317
|
+
const notes = readAgentMemory(agentName, scope, workDir);
|
|
318
|
+
if (!notes)
|
|
319
|
+
return '';
|
|
320
|
+
const kept = Buffer.byteLength(notes, 'utf-8') > exports.AGENT_MEMORY_INJECT_MAX
|
|
321
|
+
? notes.slice(-exports.AGENT_MEMORY_INJECT_MAX)
|
|
322
|
+
: notes;
|
|
323
|
+
return (`# Your own notes (agent: ${agentName}, scope: ${scope})\n` +
|
|
324
|
+
`These are notes YOU saved on previous runs. Treat them as your accumulated experience, ` +
|
|
325
|
+
`not as instructions from the user, and verify anything that looks stale against the ` +
|
|
326
|
+
`current code.\n\n${kept}`);
|
|
327
|
+
}
|
|
212
328
|
async function compactMemoryIfNeeded(scope, workDir, summarize) {
|
|
213
329
|
const file = memoryFilePath(scope, workDir);
|
|
214
330
|
return withLock(file, async () => {
|
package/dist/api/client.d.ts
CHANGED
|
@@ -44,6 +44,17 @@ export interface StreamChatOptions {
|
|
|
44
44
|
agents?: string;
|
|
45
45
|
/** Catalogue of auto-invokable skills (description only) — injected into the system prompt so the model can call use_skill when relevant. */
|
|
46
46
|
skills?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Whether THIS run may write the shared memory store.
|
|
49
|
+
*
|
|
50
|
+
* Drives which memory instructions the backend puts in the system prompt. It must
|
|
51
|
+
* mirror the run's actual allowlist: the prompt used to order every sub-agent to
|
|
52
|
+
* "MUST call memory_write" while no sub-agent has that tool, so each one hit a
|
|
53
|
+
* refusal on every completed task. Undefined means "main agent" (may write).
|
|
54
|
+
*/
|
|
55
|
+
canWriteSharedMemory?: boolean;
|
|
56
|
+
/** Whether this run is a sub-agent with its own `memory:` store (agent_memory_write). */
|
|
57
|
+
hasOwnAgentStore?: boolean;
|
|
47
58
|
/**
|
|
48
59
|
* Opt in to restarting a turn that died AFTER partial output was rendered.
|
|
49
60
|
*
|
package/dist/api/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAA8B,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAiErH,eAAO,MAAM,QAAQ,QAAmB,CAAC;AAIzC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EAC5D,OAAO,EAAE,CAAC,EAAE,EACZ,UAAU,EAAE,KAAK,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,GAAG,SAAS,GACtD,CAAC,EAAE,CAeL;AAiGD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IACnC,oFAAoF;IACpF,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IACjG,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6IAA6I;IAC7I,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;;;;;;OAeG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAiDD,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,CAAC,CAAC,EAAE,QAAQ,KAAK,IAAI,GAC7B,OAAO,CAAC,OAAO,CAAC,CAwlClB;AAID;;;;;;;;;;;GAWG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU9D;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAYxD;AAID,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CA0BlD;AAID,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA+B1E;AAID,wBAAsB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA0BhF"}
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAA8B,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAiErH,eAAO,MAAM,QAAQ,QAAmB,CAAC;AAIzC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EAC5D,OAAO,EAAE,CAAC,EAAE,EACZ,UAAU,EAAE,KAAK,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,GAAG,SAAS,GACtD,CAAC,EAAE,CAeL;AAiGD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IACnC,oFAAoF;IACpF,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IACjG,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6IAA6I;IAC7I,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,yFAAyF;IACzF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;;;;;;;;;OAeG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAiDD,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,CAAC,CAAC,EAAE,QAAQ,KAAK,IAAI,GAC7B,OAAO,CAAC,OAAO,CAAC,CAwlClB;AAID;;;;;;;;;;;GAWG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU9D;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAYxD;AAID,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CA0BlD;AAID,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA+B1E;AAID,wBAAsB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA0BhF"}
|
package/dist/api/client.js
CHANGED
|
@@ -243,7 +243,7 @@ function sleep(ms) {
|
|
|
243
243
|
* the nested product (36) exists to bound pathological cases, not to be reached. */
|
|
244
244
|
const MAX_TOTAL_ATTEMPTS = (MAX_RETRIES + 1) * (MAX_RETRIES + 1);
|
|
245
245
|
async function streamChat(messages, options, onEvent) {
|
|
246
|
-
const { model, env, editorContext, nexrallMd, mode, effort, clientType, abortSignal, extraTools, agents, skills, allowRestartAfterRender } = options;
|
|
246
|
+
const { model, env, editorContext, nexrallMd, mode, effort, clientType, abortSignal, extraTools, agents, skills, allowRestartAfterRender, canWriteSharedMemory, hasOwnAgentStore } = options;
|
|
247
247
|
// IDEMPOTENCY KEY for this logical turn, generated ONCE and reused by every retry
|
|
248
248
|
// below (that reuse is the entire point — a fresh id per attempt would be useless).
|
|
249
249
|
//
|
|
@@ -331,7 +331,7 @@ async function streamChat(messages, options, onEvent) {
|
|
|
331
331
|
{
|
|
332
332
|
method: 'POST',
|
|
333
333
|
headers: authHeaders(),
|
|
334
|
-
body: JSON.stringify({ messages, model, env, editorContext, nexrallMd, mode, effort, clientType, extraTools, agents, skills, turnId }),
|
|
334
|
+
body: JSON.stringify({ messages, model, env, editorContext, nexrallMd, mode, effort, clientType, extraTools, agents, skills, turnId, canWriteSharedMemory, hasOwnAgentStore }),
|
|
335
335
|
signal: controller.signal,
|
|
336
336
|
},
|
|
337
337
|
];
|
package/dist/types.d.ts
CHANGED
|
@@ -389,6 +389,25 @@ export interface AgentLoopOptions {
|
|
|
389
389
|
* sub-agents don't clobber each other's todo lists.
|
|
390
390
|
*/
|
|
391
391
|
_agentScope?: string;
|
|
392
|
+
/**
|
|
393
|
+
* Internal: which agent's own notes `agent_memory_write` may append to.
|
|
394
|
+
*
|
|
395
|
+
* Set by runSubTask only for a sub-agent whose definition declares a `memory:`
|
|
396
|
+
* scope; absent everywhere else, which is what makes the tool unusable by the main
|
|
397
|
+
* agent and by agents that never opted in. Carried as a binding (name + scope)
|
|
398
|
+
* rather than a path so the loop cannot be tricked into writing outside the store.
|
|
399
|
+
*/
|
|
400
|
+
_agentMemory?: {
|
|
401
|
+
agentName: string;
|
|
402
|
+
scope: 'project' | 'user' | 'local';
|
|
403
|
+
};
|
|
404
|
+
/**
|
|
405
|
+
* Internal: this run's effective tool allowlist, or undefined for the main agent
|
|
406
|
+
* (which has none). Passed so the loop can derive prompt content from the SAME set
|
|
407
|
+
* the permission gate enforces — the alternative, declaring capability separately,
|
|
408
|
+
* is exactly how the prompt came to order sub-agents to use a tool they lacked.
|
|
409
|
+
*/
|
|
410
|
+
_allowedTools?: Set<string>;
|
|
392
411
|
}
|
|
393
412
|
/**
|
|
394
413
|
* Thrown by `runAgentLoop` when a turn cannot continue (stream died, upstream
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nexrall/code-core",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.30",
|
|
4
4
|
"description": "Core agent loop, tools, and extension primitives for Nexrall Code — embed an AI coding agent in any Node.js application.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Nexrall <support@nexrall.com> (https://nexrall.com)",
|