@nexrall/code-core 1.4.12 → 1.4.14
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/loop.d.ts +13 -0
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +204 -16
- package/dist/agent/memory.d.ts +45 -0
- package/dist/agent/memory.d.ts.map +1 -0
- package/dist/agent/memory.js +243 -0
- package/dist/agent/skills.d.ts +35 -0
- package/dist/agent/skills.d.ts.map +1 -0
- package/dist/agent/skills.js +253 -0
- package/dist/api/client.d.ts +33 -1
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +559 -57
- package/dist/commands/loader.d.ts +7 -3
- package/dist/commands/loader.d.ts.map +1 -1
- package/dist/commands/loader.js +13 -6
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/plugins/index.d.ts +1 -1
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/tools/executor.d.ts.map +1 -1
- package/dist/tools/executor.js +46 -23
- package/dist/types.d.ts +111 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +44 -0
- package/package.json +1 -1
|
@@ -10,9 +10,13 @@ export interface SlashCommand {
|
|
|
10
10
|
export declare function loadSlashCommands(workDir: string): SlashCommand[];
|
|
11
11
|
export declare function findSlashCommand(cmds: SlashCommand[], name: string): SlashCommand | undefined;
|
|
12
12
|
/**
|
|
13
|
-
* Expand a command body into a final prompt: argument substitution,
|
|
14
|
-
* inlining, and !`cmd` shell capture. Shell/file errors are inlined as
|
|
15
|
-
* rather than thrown so the prompt is always produced.
|
|
13
|
+
* Expand a command/skill body into a final prompt: argument substitution,
|
|
14
|
+
* @file inlining, and !`cmd` shell capture. Shell/file errors are inlined as
|
|
15
|
+
* notes rather than thrown so the prompt is always produced. Shared by both
|
|
16
|
+
* SlashCommand (this file) and Skill (agent/skills.ts) — they have the same
|
|
17
|
+
* `body` shape, just a richer frontmatter set on the Skill side.
|
|
16
18
|
*/
|
|
19
|
+
export declare function expandBody(body: string, argString: string, workDir: string): string;
|
|
20
|
+
/** @deprecated kept for backward compatibility — use expandBody(cmd.body, ...) directly. */
|
|
17
21
|
export declare function expandCommand(cmd: SlashCommand, argString: string, workDir: string): string;
|
|
18
22
|
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/commands/loader.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,OAAO,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;CACrD;AAiFD,uFAAuF;AACvF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CASjE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAG7F;AAED
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/commands/loader.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,OAAO,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;CACrD;AAiFD,uFAAuF;AACvF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CASjE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAG7F;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAuCnF;AAED,4FAA4F;AAC5F,wBAAgB,aAAa,CAAC,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3F"}
|
package/dist/commands/loader.js
CHANGED
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.loadSlashCommands = loadSlashCommands;
|
|
37
37
|
exports.findSlashCommand = findSlashCommand;
|
|
38
|
+
exports.expandBody = expandBody;
|
|
38
39
|
exports.expandCommand = expandCommand;
|
|
39
40
|
const fs = __importStar(require("fs"));
|
|
40
41
|
const path = __importStar(require("path"));
|
|
@@ -140,14 +141,16 @@ function findSlashCommand(cmds, name) {
|
|
|
140
141
|
return cmds.find((c) => c.name === want);
|
|
141
142
|
}
|
|
142
143
|
/**
|
|
143
|
-
* Expand a command body into a final prompt: argument substitution,
|
|
144
|
-
* inlining, and !`cmd` shell capture. Shell/file errors are inlined as
|
|
145
|
-
* rather than thrown so the prompt is always produced.
|
|
144
|
+
* Expand a command/skill body into a final prompt: argument substitution,
|
|
145
|
+
* @file inlining, and !`cmd` shell capture. Shell/file errors are inlined as
|
|
146
|
+
* notes rather than thrown so the prompt is always produced. Shared by both
|
|
147
|
+
* SlashCommand (this file) and Skill (agent/skills.ts) — they have the same
|
|
148
|
+
* `body` shape, just a richer frontmatter set on the Skill side.
|
|
146
149
|
*/
|
|
147
|
-
function
|
|
150
|
+
function expandBody(body, argString, workDir) {
|
|
148
151
|
const args = argString.trim();
|
|
149
152
|
const positional = args ? args.split(/\s+/) : [];
|
|
150
|
-
let out =
|
|
153
|
+
let out = body;
|
|
151
154
|
// !`shell command` → captured stdout
|
|
152
155
|
out = out.replace(/!`([^`]+)`/g, (_m, c) => {
|
|
153
156
|
try {
|
|
@@ -175,9 +178,13 @@ function expandCommand(cmd, argString, workDir) {
|
|
|
175
178
|
const hadArgsToken = /\$ARGUMENTS/.test(out);
|
|
176
179
|
out = out.replace(/\$ARGUMENTS/g, args);
|
|
177
180
|
// If the template never referenced its args, append them so they aren't lost.
|
|
178
|
-
if (!hadArgsToken && !/\$\d+/.test(
|
|
181
|
+
if (!hadArgsToken && !/\$\d+/.test(body) && args) {
|
|
179
182
|
out = `${out}\n\n${args}`;
|
|
180
183
|
}
|
|
181
184
|
return out.trim();
|
|
182
185
|
}
|
|
186
|
+
/** @deprecated kept for backward compatibility — use expandBody(cmd.body, ...) directly. */
|
|
187
|
+
function expandCommand(cmd, argString, workDir) {
|
|
188
|
+
return expandBody(cmd.body, argString, workDir);
|
|
189
|
+
}
|
|
183
190
|
//# sourceMappingURL=loader.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export * from './agent/editCompleteness';
|
|
|
8
8
|
export * from './agent/crossFile';
|
|
9
9
|
export * from './agent/flaky';
|
|
10
10
|
export * from './agent/claimEvidence';
|
|
11
|
+
export * from './agent/memory';
|
|
12
|
+
export * from './agent/skills';
|
|
11
13
|
export * from './mcp/client';
|
|
12
14
|
export * from './mcp/httpClient';
|
|
13
15
|
export * from './mcp/manager';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,8 @@ __exportStar(require("./agent/editCompleteness"), exports);
|
|
|
24
24
|
__exportStar(require("./agent/crossFile"), exports);
|
|
25
25
|
__exportStar(require("./agent/flaky"), exports);
|
|
26
26
|
__exportStar(require("./agent/claimEvidence"), exports);
|
|
27
|
+
__exportStar(require("./agent/memory"), exports);
|
|
28
|
+
__exportStar(require("./agent/skills"), exports);
|
|
27
29
|
__exportStar(require("./mcp/client"), exports);
|
|
28
30
|
__exportStar(require("./mcp/httpClient"), exports);
|
|
29
31
|
__exportStar(require("./mcp/manager"), exports);
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export interface PluginInfo {
|
|
|
10
10
|
/** Discover installed plugins (project scope shadows global on name clash). */
|
|
11
11
|
export declare function loadPlugins(workDir: string): PluginInfo[];
|
|
12
12
|
/** Subdirectories of every installed plugin that hold `kind` assets (existing only). */
|
|
13
|
-
export declare function pluginAssetDirs(workDir: string, kind: 'commands' | 'agents'): string[];
|
|
13
|
+
export declare function pluginAssetDirs(workDir: string, kind: 'commands' | 'agents' | 'skills'): string[];
|
|
14
14
|
/** Merge hooks.json from every plugin into a single hooks config (arrays concatenated). */
|
|
15
15
|
export declare function pluginHooks(workDir: string): Record<string, unknown[]>;
|
|
16
16
|
/** MCP server maps declared by plugins: { serverName → config } (first plugin wins on clash). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,UAAU;IACzB,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,SAAS,GAAG,QAAQ,CAAC;CAC7B;AAsCD,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAKzD;AAED,wFAAwF;AACxF,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,EAAE,CAMjG;AAED,2FAA2F;AAC3F,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAetE;AAED,iGAAiG;AACjG,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAazE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/tools/executor.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAyB,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/tools/executor.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAyB,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAkkEtE,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,WAAW,CAAC,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,EAClC,OAAO,CAAC,EAAE,aAAa,EACvB,OAAO,CAAC,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,UAAU,CAAC,CAiBrB"}
|
package/dist/tools/executor.js
CHANGED
|
@@ -44,6 +44,8 @@ const child_process_1 = require("child_process");
|
|
|
44
44
|
const sandbox_1 = require("./sandbox");
|
|
45
45
|
const auth_1 = require("../auth");
|
|
46
46
|
const editCompleteness_1 = require("../agent/editCompleteness");
|
|
47
|
+
const memory_1 = require("../agent/memory");
|
|
48
|
+
const skills_1 = require("../agent/skills");
|
|
47
49
|
const testIntegrity_1 = require("../agent/testIntegrity");
|
|
48
50
|
const crossFile_1 = require("../agent/crossFile");
|
|
49
51
|
const client_1 = require("../api/client");
|
|
@@ -2028,39 +2030,58 @@ async function stockPhoto(input, workDir) {
|
|
|
2028
2030
|
return { output: `Found ${photos.length} photo(s) for "${query}":\n${lines.join('\n')}` };
|
|
2029
2031
|
}
|
|
2030
2032
|
// ─── Memory tools ─────────────────────────────────────────────────────────────
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
+
// Implementation lives in agent/memory.ts (project vs global scope, size caps,
|
|
2034
|
+
// LLM-summarizing compaction, file locking) — this is just the tool-call glue.
|
|
2035
|
+
function memoryScopeOf(input) {
|
|
2036
|
+
return input.scope === 'global' ? 'global' : 'project';
|
|
2037
|
+
}
|
|
2038
|
+
async function memoryWrite(input, workDir) {
|
|
2033
2039
|
const content = typeof input.content === 'string' ? input.content.trim() : '';
|
|
2034
2040
|
if (!content)
|
|
2035
2041
|
return { error: 'content is required' };
|
|
2036
|
-
const
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
if (fs.existsSync(MEMORY_FILE)) {
|
|
2042
|
-
const existing = fs.readFileSync(MEMORY_FILE, 'utf-8').toLowerCase();
|
|
2043
|
-
const fingerprint = content.toLowerCase().slice(0, 60);
|
|
2044
|
-
if (existing.includes(fingerprint)) {
|
|
2045
|
-
return { output: `Memory already recorded (skipped duplicate): ${content}` };
|
|
2046
|
-
}
|
|
2047
|
-
}
|
|
2048
|
-
const timestamp = new Date().toISOString().slice(0, 10);
|
|
2049
|
-
const entry = `\n- [${timestamp}] ${content}`;
|
|
2050
|
-
fs.appendFileSync(MEMORY_FILE, entry, 'utf-8');
|
|
2051
|
-
return { output: `Memory saved: ${content}` };
|
|
2042
|
+
const scope = memoryScopeOf(input);
|
|
2043
|
+
const r = await (0, memory_1.writeMemory)(content, scope, workDir);
|
|
2044
|
+
if (!r.ok)
|
|
2045
|
+
return { error: 'failed to save memory' };
|
|
2046
|
+
return { output: r.already ? `Memory already recorded (skipped duplicate): ${content}` : `Memory saved (${scope}): ${content}` };
|
|
2052
2047
|
}
|
|
2053
|
-
async function memoryRead(
|
|
2048
|
+
async function memoryRead(input, workDir) {
|
|
2054
2049
|
try {
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2050
|
+
// No explicit scope requested → merge both (what the model actually needs
|
|
2051
|
+
// when re-orienting mid-conversation); an explicit scope narrows to just that file.
|
|
2052
|
+
if (input && (input.scope === 'project' || input.scope === 'global')) {
|
|
2053
|
+
const mem = (0, memory_1.readMemory)(input.scope, workDir);
|
|
2054
|
+
return { output: mem || 'No memories saved yet.' };
|
|
2055
|
+
}
|
|
2056
|
+
const mem = (0, memory_1.readAllMemory)(workDir);
|
|
2057
|
+
return { output: mem || 'No memories saved yet.' };
|
|
2059
2058
|
}
|
|
2060
2059
|
catch (err) {
|
|
2061
2060
|
return { error: err.message };
|
|
2062
2061
|
}
|
|
2063
2062
|
}
|
|
2063
|
+
// ─── Skills ───────────────────────────────────────────────────────────────────
|
|
2064
|
+
//
|
|
2065
|
+
// use_skill loads a skill's playbook into context so the model can follow it —
|
|
2066
|
+
// same idea as memory_read returning saved notes, just for a named, reusable
|
|
2067
|
+
// procedure instead of accumulated learnings. The expanded body (with
|
|
2068
|
+
// $ARGUMENTS/@file/!`cmd` substitution already applied) comes back as the tool
|
|
2069
|
+
// result; the model then proceeds using its normal tools to carry it out.
|
|
2070
|
+
async function useSkill(input, workDir) {
|
|
2071
|
+
const name = typeof input.name === 'string' ? input.name.trim() : '';
|
|
2072
|
+
if (!name)
|
|
2073
|
+
return { error: 'name is required (the skill to invoke)' };
|
|
2074
|
+
const dir = workDir ?? process.cwd();
|
|
2075
|
+
const skills = (0, skills_1.loadSkills)(dir);
|
|
2076
|
+
const skill = (0, skills_1.findSkill)(skills, name);
|
|
2077
|
+
if (!skill) {
|
|
2078
|
+
const known = skills.map((s) => s.name).join(', ') || '(none defined)';
|
|
2079
|
+
return { error: `Unknown skill "${name}". Available: ${known}.` };
|
|
2080
|
+
}
|
|
2081
|
+
const args = typeof input.args === 'string' ? input.args : '';
|
|
2082
|
+
const expanded = (0, skills_1.expandSkill)(skill, args, dir);
|
|
2083
|
+
return { output: `[Skill "${skill.name}" loaded — follow these instructions:]\n\n${expanded}` };
|
|
2084
|
+
}
|
|
2064
2085
|
function semanticPreamble(input, workDir) {
|
|
2065
2086
|
const p = typeof input.path === 'string' ? input.path : '';
|
|
2066
2087
|
const line = typeof input.line === 'number' ? Math.floor(input.line) : 0;
|
|
@@ -2123,6 +2144,7 @@ const TOOL_MAP = {
|
|
|
2123
2144
|
notebook_edit: notebookEdit,
|
|
2124
2145
|
memory_write: memoryWrite,
|
|
2125
2146
|
memory_read: memoryRead,
|
|
2147
|
+
use_skill: useSkill,
|
|
2126
2148
|
bash_output: bashOutput,
|
|
2127
2149
|
kill_shell: killShell,
|
|
2128
2150
|
// LSP-lite fallback (regex-based). In VS Code these names are intercepted by
|
|
@@ -2144,6 +2166,7 @@ const WORKDIR_TOOLS = new Set([
|
|
|
2144
2166
|
'generate_image', 'stock_photo',
|
|
2145
2167
|
'get_symbols', 'get_workspace_symbols',
|
|
2146
2168
|
'go_to_definition', 'find_references', 'get_hover',
|
|
2169
|
+
'memory_write', 'memory_read', 'use_skill',
|
|
2147
2170
|
]);
|
|
2148
2171
|
async function executeTool(name, input, abortSignal, sandbox, workDir, agentScope) {
|
|
2149
2172
|
if (!TOOL_MAP[name])
|
package/dist/types.d.ts
CHANGED
|
@@ -46,6 +46,24 @@ export interface SSEMessageCompleteEvent {
|
|
|
46
46
|
export interface SSEUsageEvent {
|
|
47
47
|
type: 'usage';
|
|
48
48
|
usage: UsageInfo;
|
|
49
|
+
/**
|
|
50
|
+
* True when these tokens belong to an attempt that was CUT SHORT (the client
|
|
51
|
+
* disconnected or the turn was restarted) rather than to the turn's completed
|
|
52
|
+
* response. They were still billed — the upstream vendor charged for every token
|
|
53
|
+
* generated before the cut — so this is real spend, but a UI that shows "this
|
|
54
|
+
* turn's output" should not add it to the successful attempt's count or it will
|
|
55
|
+
* appear to double-report. Sum it for COST, keep it out of a single turn's token
|
|
56
|
+
* total. Absent/false for an ordinary completed turn.
|
|
57
|
+
*/
|
|
58
|
+
partial?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* True when this usage is a RE-REPORT of a turn that was already billed. The previous
|
|
61
|
+
* attempt completed and was charged, but its `done` never reached the client, so the
|
|
62
|
+
* client retried and the backend served the stored answer from its turn-idempotency
|
|
63
|
+
* cache instead of re-invoking the model. No new charge occurred — a cost display must
|
|
64
|
+
* not add these tokens again. Mutually exclusive with `partial`.
|
|
65
|
+
*/
|
|
66
|
+
replayed?: boolean;
|
|
49
67
|
}
|
|
50
68
|
export interface SSEDoneEvent {
|
|
51
69
|
type: 'done';
|
|
@@ -97,7 +115,40 @@ export interface SSEBalanceStatusEvent {
|
|
|
97
115
|
balance: number;
|
|
98
116
|
zero: boolean;
|
|
99
117
|
}
|
|
100
|
-
|
|
118
|
+
/**
|
|
119
|
+
* Emitted when a stream attempt died AFTER partial output had already been
|
|
120
|
+
* rendered, and the network layer is restarting the SAME turn from scratch.
|
|
121
|
+
*
|
|
122
|
+
* Unlike `retry` (which only ever fires when nothing was shown yet, so the UI
|
|
123
|
+
* merely needs a "reconnecting…" hint), this one carries a hard requirement:
|
|
124
|
+
* the consumer MUST discard the partial assistant output it has rendered for
|
|
125
|
+
* this turn — the text/thinking streamed so far will be re-sent in full by the
|
|
126
|
+
* new attempt, so keeping it would duplicate it on screen.
|
|
127
|
+
*
|
|
128
|
+
* LOCAL side effects are safe: tool calls are dispatched by the agent loop from
|
|
129
|
+
* the COMPLETED message, after `streamChat` returns, and a restart means it threw
|
|
130
|
+
* instead — so no tool ran, no file changed, no checkpoint or hook fired.
|
|
131
|
+
*
|
|
132
|
+
* BILLING IS NOT ROLLED BACK, and callers should not assume otherwise. The
|
|
133
|
+
* backend charges whatever tokens the model produced before the cut (its stream
|
|
134
|
+
* `abort` handler), because the upstream vendor charged us for them. A restarted
|
|
135
|
+
* turn therefore costs more than one attempt's worth of tokens — bounded by the
|
|
136
|
+
* reconnect budget, but real. The backend emits a `usage` event tagged
|
|
137
|
+
* `partial: true` for the discarded attempt so a cost display can stay accurate.
|
|
138
|
+
*/
|
|
139
|
+
export interface SSEStreamRestartEvent {
|
|
140
|
+
type: 'stream_restart';
|
|
141
|
+
/** Human-readable cause, for an optional dim status line. */
|
|
142
|
+
reason: string;
|
|
143
|
+
/**
|
|
144
|
+
* How many characters of rendered output this attempt had already emitted — counting
|
|
145
|
+
* both visible text AND streamed thinking, since consumers display both and both must
|
|
146
|
+
* be discarded. Only ever 0 when the attempt rendered nothing at all, in which case a
|
|
147
|
+
* plain `retry` is emitted instead of this event.
|
|
148
|
+
*/
|
|
149
|
+
discardedChars: number;
|
|
150
|
+
}
|
|
151
|
+
export type SSEEvent = SSETextEvent | SSEToolUseEvent | SSEMessageCompleteEvent | SSEUsageEvent | SSEDoneEvent | SSEErrorEvent | SSEThinkingEvent | SSEThinkingProgressEvent | SSEThinkingDeltaEvent | SSERetryEvent | SSERetryResolvedEvent | SSEStreamRestartEvent | SSEBalanceStatusEvent;
|
|
101
152
|
export interface UsageInfo {
|
|
102
153
|
input_tokens: number;
|
|
103
154
|
output_tokens: number;
|
|
@@ -173,7 +224,13 @@ export interface AgentLoopOptions {
|
|
|
173
224
|
onThinkingProgress?: (tokens: number) => void;
|
|
174
225
|
onToolUse: (name: string, input: Record<string, unknown>, isSubTask?: boolean) => void;
|
|
175
226
|
onToolResult: (name: string, result: ToolResult, isSubTask?: boolean) => void;
|
|
176
|
-
|
|
227
|
+
/**
|
|
228
|
+
* Token usage for a model call. `partial` marks tokens from an attempt that was cut
|
|
229
|
+
* short and restarted — real, already-billed spend that should be counted toward
|
|
230
|
+
* COST, but kept out of any "tokens this turn produced" display (see SSEUsageEvent).
|
|
231
|
+
* Optional second argument, so existing implementations keep compiling unchanged.
|
|
232
|
+
*/
|
|
233
|
+
onUsage: (u: UsageInfo, partial?: boolean) => void;
|
|
177
234
|
/**
|
|
178
235
|
* Fired when the network layer is about to transparently retry a turn after
|
|
179
236
|
* a transient disconnect (network drop, machine sleep/wake, overloaded
|
|
@@ -184,6 +241,17 @@ export interface AgentLoopOptions {
|
|
|
184
241
|
onRetry?: (attempt: number, maxAttempts: number, reason: string) => void;
|
|
185
242
|
/** Fired once a retried attempt starts receiving data again — clear any "reconnecting…" UI. */
|
|
186
243
|
onRetryResolved?: () => void;
|
|
244
|
+
/**
|
|
245
|
+
* Fired when a stream died mid-render and the SAME turn is being restarted.
|
|
246
|
+
* The consumer MUST discard whatever partial assistant text/thinking it has
|
|
247
|
+
* already displayed for this turn — the new attempt re-sends it in full, so
|
|
248
|
+
* keeping the old fragment would duplicate it. No tool has executed at this
|
|
249
|
+
* point (tools only run after `message_complete`), so nothing beyond the
|
|
250
|
+
* rendered output needs undoing. If a caller does not implement this, the
|
|
251
|
+
* loop falls back to NOT retrying post-render failures, preserving the old
|
|
252
|
+
* (safe but turn-killing) behaviour.
|
|
253
|
+
*/
|
|
254
|
+
onStreamRestart?: (reason: string, discardedChars: number) => void;
|
|
187
255
|
/**
|
|
188
256
|
* Fired when the backend reports the wallet balance dropped under the
|
|
189
257
|
* low-balance threshold ($5) after billing a turn, or when a turn couldn't
|
|
@@ -270,4 +338,45 @@ export interface AgentLoopOptions {
|
|
|
270
338
|
*/
|
|
271
339
|
_agentScope?: string;
|
|
272
340
|
}
|
|
341
|
+
/**
|
|
342
|
+
* Thrown by `runAgentLoop` when a turn cannot continue (stream died, upstream
|
|
343
|
+
* error, etc.) but real work HAS already been completed in this turn.
|
|
344
|
+
*
|
|
345
|
+
* Why this exists: the loop operates on its own copy of the history
|
|
346
|
+
* (`[...initialMessages]`), so a plain `throw` used to leave the CALLER's array
|
|
347
|
+
* still holding only the original user message. An agent that had already run
|
|
348
|
+
* 25 tool calls over eight minutes would lose every one of them — the user was
|
|
349
|
+
* billed for the work, then had to start from scratch because "continue" had no
|
|
350
|
+
* memory of it. Carrying the partial history on the error lets the caller
|
|
351
|
+
* salvage it, so the very next "continue" resumes exactly where it stopped.
|
|
352
|
+
*
|
|
353
|
+
* `messages` is always a VALID history to resend: the loop only ever appends in
|
|
354
|
+
* complete (assistant → tool_result) pairs, so it never ends on an assistant
|
|
355
|
+
* turn with unanswered tool_use blocks.
|
|
356
|
+
*/
|
|
357
|
+
export declare class AgentTurnError extends Error {
|
|
358
|
+
/** The turn's history up to the point of failure — safe to resend to the API. */
|
|
359
|
+
readonly messages: Message[];
|
|
360
|
+
/**
|
|
361
|
+
* How many turn steps completed before the failure (0 = nothing salvageable).
|
|
362
|
+
*
|
|
363
|
+
* Supplied by the loop as an explicit counter rather than derived from array
|
|
364
|
+
* lengths: auto-compaction SPLICES the history down mid-turn, so a long run that
|
|
365
|
+
* compacted and then died can end up SHORTER than it started. A length delta would
|
|
366
|
+
* read as "no progress" and discard exactly the expensive, long-running sessions
|
|
367
|
+
* this class exists to protect.
|
|
368
|
+
*/
|
|
369
|
+
readonly progressCount: number;
|
|
370
|
+
/** The original underlying error, if any. */
|
|
371
|
+
readonly cause?: unknown;
|
|
372
|
+
constructor(message: string, messages: Message[], progressCount: number, cause?: unknown);
|
|
373
|
+
}
|
|
374
|
+
/** Type guard — narrows an unknown catch binding to an AgentTurnError. */
|
|
375
|
+
export declare function isAgentTurnError(err: unknown): err is AgentTurnError;
|
|
376
|
+
/**
|
|
377
|
+
* Salvage a partial history out of a failed turn. Returns the partial history
|
|
378
|
+
* when the error carried one AND real progress was made, otherwise `null`.
|
|
379
|
+
* Callers use it as: `messages = salvageHistory(err) ?? messages;`
|
|
380
|
+
*/
|
|
381
|
+
export declare function salvageHistory(err: unknown): Message[] | null;
|
|
273
382
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,YAAY,GAAG,eAAe,CAAC;AAItE,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAID,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
CHANGED
|
@@ -1,4 +1,48 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// ─── Content Blocks ───────────────────────────────────────────────────────────
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.AgentTurnError = void 0;
|
|
5
|
+
exports.isAgentTurnError = isAgentTurnError;
|
|
6
|
+
exports.salvageHistory = salvageHistory;
|
|
7
|
+
// ─── Turn failure that preserves work already done ───────────────────────────
|
|
8
|
+
/**
|
|
9
|
+
* Thrown by `runAgentLoop` when a turn cannot continue (stream died, upstream
|
|
10
|
+
* error, etc.) but real work HAS already been completed in this turn.
|
|
11
|
+
*
|
|
12
|
+
* Why this exists: the loop operates on its own copy of the history
|
|
13
|
+
* (`[...initialMessages]`), so a plain `throw` used to leave the CALLER's array
|
|
14
|
+
* still holding only the original user message. An agent that had already run
|
|
15
|
+
* 25 tool calls over eight minutes would lose every one of them — the user was
|
|
16
|
+
* billed for the work, then had to start from scratch because "continue" had no
|
|
17
|
+
* memory of it. Carrying the partial history on the error lets the caller
|
|
18
|
+
* salvage it, so the very next "continue" resumes exactly where it stopped.
|
|
19
|
+
*
|
|
20
|
+
* `messages` is always a VALID history to resend: the loop only ever appends in
|
|
21
|
+
* complete (assistant → tool_result) pairs, so it never ends on an assistant
|
|
22
|
+
* turn with unanswered tool_use blocks.
|
|
23
|
+
*/
|
|
24
|
+
class AgentTurnError extends Error {
|
|
25
|
+
constructor(message, messages, progressCount, cause) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.name = 'AgentTurnError';
|
|
28
|
+
this.messages = messages;
|
|
29
|
+
this.progressCount = Math.max(0, progressCount);
|
|
30
|
+
this.cause = cause;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.AgentTurnError = AgentTurnError;
|
|
34
|
+
/** Type guard — narrows an unknown catch binding to an AgentTurnError. */
|
|
35
|
+
function isAgentTurnError(err) {
|
|
36
|
+
return err instanceof AgentTurnError;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Salvage a partial history out of a failed turn. Returns the partial history
|
|
40
|
+
* when the error carried one AND real progress was made, otherwise `null`.
|
|
41
|
+
* Callers use it as: `messages = salvageHistory(err) ?? messages;`
|
|
42
|
+
*/
|
|
43
|
+
function salvageHistory(err) {
|
|
44
|
+
if (!isAgentTurnError(err))
|
|
45
|
+
return null;
|
|
46
|
+
return err.progressCount > 0 ? err.messages : null;
|
|
47
|
+
}
|
|
4
48
|
//# sourceMappingURL=types.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nexrall/code-core",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.14",
|
|
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)",
|