jiva-core 0.3.3-dev.dc3cf03 → 0.3.4-dev.3c78d8b

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.
Files changed (118) hide show
  1. package/README.md +232 -570
  2. package/dist/code/agent.d.ts +105 -0
  3. package/dist/code/agent.d.ts.map +1 -0
  4. package/dist/code/agent.js +697 -0
  5. package/dist/code/agent.js.map +1 -0
  6. package/dist/code/file-lock.d.ts +15 -0
  7. package/dist/code/file-lock.d.ts.map +1 -0
  8. package/dist/code/file-lock.js +36 -0
  9. package/dist/code/file-lock.js.map +1 -0
  10. package/dist/code/lsp/client.d.ts +30 -0
  11. package/dist/code/lsp/client.d.ts.map +1 -0
  12. package/dist/code/lsp/client.js +181 -0
  13. package/dist/code/lsp/client.js.map +1 -0
  14. package/dist/code/lsp/language.d.ts +12 -0
  15. package/dist/code/lsp/language.d.ts.map +1 -0
  16. package/dist/code/lsp/language.js +145 -0
  17. package/dist/code/lsp/language.js.map +1 -0
  18. package/dist/code/lsp/manager.d.ts +39 -0
  19. package/dist/code/lsp/manager.d.ts.map +1 -0
  20. package/dist/code/lsp/manager.js +108 -0
  21. package/dist/code/lsp/manager.js.map +1 -0
  22. package/dist/code/lsp/server.d.ts +15 -0
  23. package/dist/code/lsp/server.d.ts.map +1 -0
  24. package/dist/code/lsp/server.js +78 -0
  25. package/dist/code/lsp/server.js.map +1 -0
  26. package/dist/code/tools/bash.d.ts +3 -0
  27. package/dist/code/tools/bash.d.ts.map +1 -0
  28. package/dist/code/tools/bash.js +110 -0
  29. package/dist/code/tools/bash.js.map +1 -0
  30. package/dist/code/tools/edit.d.ts +11 -0
  31. package/dist/code/tools/edit.d.ts.map +1 -0
  32. package/dist/code/tools/edit.js +459 -0
  33. package/dist/code/tools/edit.js.map +1 -0
  34. package/dist/code/tools/glob.d.ts +3 -0
  35. package/dist/code/tools/glob.d.ts.map +1 -0
  36. package/dist/code/tools/glob.js +62 -0
  37. package/dist/code/tools/glob.js.map +1 -0
  38. package/dist/code/tools/grep.d.ts +3 -0
  39. package/dist/code/tools/grep.d.ts.map +1 -0
  40. package/dist/code/tools/grep.js +147 -0
  41. package/dist/code/tools/grep.js.map +1 -0
  42. package/dist/code/tools/index.d.ts +31 -0
  43. package/dist/code/tools/index.d.ts.map +1 -0
  44. package/dist/code/tools/index.js +9 -0
  45. package/dist/code/tools/index.js.map +1 -0
  46. package/dist/code/tools/read.d.ts +3 -0
  47. package/dist/code/tools/read.d.ts.map +1 -0
  48. package/dist/code/tools/read.js +120 -0
  49. package/dist/code/tools/read.js.map +1 -0
  50. package/dist/code/tools/spawn.d.ts +3 -0
  51. package/dist/code/tools/spawn.d.ts.map +1 -0
  52. package/dist/code/tools/spawn.js +49 -0
  53. package/dist/code/tools/spawn.js.map +1 -0
  54. package/dist/code/tools/write.d.ts +3 -0
  55. package/dist/code/tools/write.d.ts.map +1 -0
  56. package/dist/code/tools/write.js +82 -0
  57. package/dist/code/tools/write.js.map +1 -0
  58. package/dist/core/agent-interface.d.ts +54 -0
  59. package/dist/core/agent-interface.d.ts.map +1 -0
  60. package/dist/core/agent-interface.js +8 -0
  61. package/dist/core/agent-interface.js.map +1 -0
  62. package/dist/core/client-agent.d.ts.map +1 -1
  63. package/dist/core/client-agent.js +26 -3
  64. package/dist/core/client-agent.js.map +1 -1
  65. package/dist/core/config.d.ts +144 -17
  66. package/dist/core/config.d.ts.map +1 -1
  67. package/dist/core/config.js +25 -1
  68. package/dist/core/config.js.map +1 -1
  69. package/dist/core/conversation-manager.d.ts +4 -1
  70. package/dist/core/conversation-manager.d.ts.map +1 -1
  71. package/dist/core/conversation-manager.js +47 -17
  72. package/dist/core/conversation-manager.js.map +1 -1
  73. package/dist/core/dual-agent.d.ts +3 -10
  74. package/dist/core/dual-agent.d.ts.map +1 -1
  75. package/dist/core/dual-agent.js +53 -119
  76. package/dist/core/dual-agent.js.map +1 -1
  77. package/dist/core/manager-agent.d.ts +30 -0
  78. package/dist/core/manager-agent.d.ts.map +1 -1
  79. package/dist/core/manager-agent.js +114 -14
  80. package/dist/core/manager-agent.js.map +1 -1
  81. package/dist/core/worker-agent.d.ts +12 -2
  82. package/dist/core/worker-agent.d.ts.map +1 -1
  83. package/dist/core/worker-agent.js +254 -67
  84. package/dist/core/worker-agent.js.map +1 -1
  85. package/dist/index.d.ts +3 -0
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +2 -0
  88. package/dist/index.js.map +1 -1
  89. package/dist/interfaces/cli/index.js +146 -25
  90. package/dist/interfaces/cli/index.js.map +1 -1
  91. package/dist/interfaces/cli/repl.d.ts +8 -2
  92. package/dist/interfaces/cli/repl.d.ts.map +1 -1
  93. package/dist/interfaces/cli/repl.js +39 -3
  94. package/dist/interfaces/cli/repl.js.map +1 -1
  95. package/dist/interfaces/cli/setup-wizard.d.ts.map +1 -1
  96. package/dist/interfaces/cli/setup-wizard.js +92 -0
  97. package/dist/interfaces/cli/setup-wizard.js.map +1 -1
  98. package/dist/interfaces/http/routes/chat.js +2 -2
  99. package/dist/interfaces/http/routes/chat.js.map +1 -1
  100. package/dist/interfaces/http/session-manager.d.ts +7 -4
  101. package/dist/interfaces/http/session-manager.d.ts.map +1 -1
  102. package/dist/interfaces/http/session-manager.js +56 -15
  103. package/dist/interfaces/http/session-manager.js.map +1 -1
  104. package/dist/models/base.d.ts +8 -0
  105. package/dist/models/base.d.ts.map +1 -1
  106. package/dist/models/harmony.d.ts +7 -1
  107. package/dist/models/harmony.d.ts.map +1 -1
  108. package/dist/models/harmony.js +21 -3
  109. package/dist/models/harmony.js.map +1 -1
  110. package/dist/models/krutrim.d.ts +31 -1
  111. package/dist/models/krutrim.d.ts.map +1 -1
  112. package/dist/models/krutrim.js +55 -11
  113. package/dist/models/krutrim.js.map +1 -1
  114. package/dist/models/orchestrator.d.ts +24 -0
  115. package/dist/models/orchestrator.d.ts.map +1 -1
  116. package/dist/models/orchestrator.js +40 -6
  117. package/dist/models/orchestrator.js.map +1 -1
  118. package/package.json +8 -5
@@ -0,0 +1,147 @@
1
+ import path from 'path';
2
+ import fs from 'fs';
3
+ const MAX_MATCHES = 100;
4
+ const MAX_FILE_SIZE = 1 * 1024 * 1024; // 1MB per file
5
+ const IGNORE_DIRS = new Set([
6
+ 'node_modules', '.git', 'dist', '.next', 'build', '.cache',
7
+ '__pycache__', '.mypy_cache', 'target', 'vendor',
8
+ ]);
9
+ export const GrepTool = {
10
+ name: 'grep',
11
+ description: `Search for a regex pattern across files in the workspace.
12
+
13
+ REQUIRED parameter: "pattern" (string) — the regex to search for.
14
+ Example: {"pattern": "class UserService"}
15
+ Example: {"pattern": "TODO|FIXME", "include": "*.ts"}
16
+
17
+ Returns matches in the format: file:line: content`,
18
+ parameters: {
19
+ type: 'object',
20
+ properties: {
21
+ pattern: {
22
+ type: 'string',
23
+ description: 'Regular expression pattern to search for',
24
+ },
25
+ path: {
26
+ type: 'string',
27
+ description: 'File or directory to search in (default: workspace root)',
28
+ },
29
+ include: {
30
+ type: 'string',
31
+ description: 'Glob pattern to filter files (e.g. "*.ts", "*.py")',
32
+ },
33
+ case_insensitive: {
34
+ type: 'boolean',
35
+ description: 'Case-insensitive search (default: false)',
36
+ },
37
+ },
38
+ required: ['pattern'],
39
+ },
40
+ async execute(args, ctx) {
41
+ const patternStr = args.pattern;
42
+ const searchPath = args.path
43
+ ? (path.isAbsolute(args.path) ? args.path : path.resolve(ctx.workspaceDir, args.path))
44
+ : ctx.workspaceDir;
45
+ const includePattern = args.include;
46
+ const caseInsensitive = args.case_insensitive ?? false;
47
+ let regex;
48
+ try {
49
+ regex = new RegExp(patternStr, caseInsensitive ? 'i' : '');
50
+ }
51
+ catch (e) {
52
+ return `Error: Invalid regex pattern: ${e instanceof Error ? e.message : String(e)}`;
53
+ }
54
+ const results = [];
55
+ let truncated = false;
56
+ try {
57
+ const stat = fs.statSync(searchPath);
58
+ if (stat.isFile()) {
59
+ searchFile(searchPath, regex, ctx.workspaceDir, results, { max: MAX_MATCHES });
60
+ }
61
+ else {
62
+ searchDir(searchPath, regex, ctx.workspaceDir, results, includePattern, {
63
+ max: MAX_MATCHES,
64
+ truncated: () => { truncated = true; },
65
+ });
66
+ }
67
+ }
68
+ catch (e) {
69
+ return `Error: ${e instanceof Error ? e.message : String(e)}`;
70
+ }
71
+ if (results.length === 0) {
72
+ return `No matches found for: ${patternStr}`;
73
+ }
74
+ let output = results.join('\n');
75
+ if (truncated) {
76
+ output += `\n\n[Results truncated at ${MAX_MATCHES} matches. Narrow the search path or pattern.]`;
77
+ }
78
+ return output;
79
+ },
80
+ };
81
+ function matchesInclude(filename, include) {
82
+ if (!include)
83
+ return true;
84
+ // Simple glob matching: support *.ext patterns
85
+ if (include.startsWith('*.')) {
86
+ const ext = include.slice(1);
87
+ return filename.endsWith(ext);
88
+ }
89
+ return filename.includes(include);
90
+ }
91
+ function searchFile(filePath, regex, workspaceDir, results, opts) {
92
+ if (results.length >= opts.max)
93
+ return;
94
+ let stat;
95
+ try {
96
+ stat = fs.statSync(filePath);
97
+ }
98
+ catch {
99
+ return;
100
+ }
101
+ if (stat.size > MAX_FILE_SIZE)
102
+ return;
103
+ let content;
104
+ try {
105
+ content = fs.readFileSync(filePath, 'utf-8');
106
+ }
107
+ catch {
108
+ return;
109
+ }
110
+ const relPath = path.relative(workspaceDir, filePath);
111
+ const lines = content.split('\n');
112
+ for (let i = 0; i < lines.length && results.length < opts.max; i++) {
113
+ if (regex.test(lines[i])) {
114
+ results.push(`${relPath}:${i + 1}: ${lines[i].trim()}`);
115
+ }
116
+ }
117
+ }
118
+ function searchDir(dirPath, regex, workspaceDir, results, include, opts) {
119
+ if (results.length >= opts.max) {
120
+ opts.truncated();
121
+ return;
122
+ }
123
+ let entries;
124
+ try {
125
+ entries = fs.readdirSync(dirPath, { withFileTypes: true });
126
+ }
127
+ catch {
128
+ return;
129
+ }
130
+ for (const entry of entries) {
131
+ if (results.length >= opts.max) {
132
+ opts.truncated();
133
+ return;
134
+ }
135
+ if (entry.isDirectory()) {
136
+ if (IGNORE_DIRS.has(entry.name) || entry.name.startsWith('.'))
137
+ continue;
138
+ searchDir(path.join(dirPath, entry.name), regex, workspaceDir, results, include, opts);
139
+ }
140
+ else if (entry.isFile()) {
141
+ if (!matchesInclude(entry.name, include))
142
+ continue;
143
+ searchFile(path.join(dirPath, entry.name), regex, workspaceDir, results, opts);
144
+ }
145
+ }
146
+ }
147
+ //# sourceMappingURL=grep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grep.js","sourceRoot":"","sources":["../../../src/code/tools/grep.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { LspManager } from '../lsp/manager.js';
2
+ export interface CodeToolContext {
3
+ workspaceDir: string;
4
+ lsp: LspManager;
5
+ signal?: AbortSignal;
6
+ /** Current agent depth — used by spawn tool to limit recursion */
7
+ depth?: number;
8
+ /** Max allowed depth */
9
+ maxDepth?: number;
10
+ /** Callback to spawn a child CodeAgent (injected by CodeAgent) */
11
+ spawnChildAgent?: (task: string, context?: string) => Promise<string>;
12
+ }
13
+ export interface ICodeTool {
14
+ name: string;
15
+ description: string;
16
+ /** JSON Schema object for tool parameters */
17
+ parameters: {
18
+ type: 'object';
19
+ properties: Record<string, unknown>;
20
+ required?: string[];
21
+ };
22
+ execute(args: Record<string, unknown>, ctx: CodeToolContext): Promise<string>;
23
+ }
24
+ export { ReadFileTool } from './read.js';
25
+ export { EditFileTool } from './edit.js';
26
+ export { WriteFileTool } from './write.js';
27
+ export { GlobTool } from './glob.js';
28
+ export { GrepTool } from './grep.js';
29
+ export { BashTool } from './bash.js';
30
+ export { SpawnCodeAgentTool } from './spawn.js';
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/code/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,UAAU,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC/E;AAGD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,9 @@
1
+ // Re-export all tools
2
+ export { ReadFileTool } from './read.js';
3
+ export { EditFileTool } from './edit.js';
4
+ export { WriteFileTool } from './write.js';
5
+ export { GlobTool } from './glob.js';
6
+ export { GrepTool } from './grep.js';
7
+ export { BashTool } from './bash.js';
8
+ export { SpawnCodeAgentTool } from './spawn.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/code/tools/index.ts"],"names":[],"mappings":"AA0BA,sBAAsB;AACtB,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ICodeTool } from './index.js';
2
+ export declare const ReadFileTool: ICodeTool;
3
+ //# sourceMappingURL=read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../src/code/tools/read.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,YAAY,CAAC;AAK7D,eAAO,MAAM,YAAY,EAAE,SAuD1B,CAAC"}
@@ -0,0 +1,120 @@
1
+ import path from 'path';
2
+ import fs from 'fs';
3
+ const MAX_LINES = 2000;
4
+ const MAX_BYTES = 50 * 1024; // 50KB
5
+ export const ReadFileTool = {
6
+ name: 'read_file',
7
+ description: `Read the contents of a file or list a directory.
8
+
9
+ REQUIRED parameter: "path" (string) — absolute path to file or directory.
10
+ Example: {"path": "/workspace/src/index.ts"}
11
+ Example: {"path": "/workspace/src/index.ts", "offset": 100, "limit": 50}
12
+
13
+ Do NOT pass "command", "query", or "pattern" to this tool — use bash or grep for those.
14
+
15
+ For files:
16
+ - Returns file content with line numbers (cat -n style)
17
+ - Limits to ${MAX_LINES} lines and ${MAX_BYTES / 1024}KB
18
+ - Use offset and limit to paginate large files
19
+ - Binary files return "[binary file, cannot display]"
20
+
21
+ For directories:
22
+ - Returns a listing with [FILE] and [DIR] prefixes`,
23
+ parameters: {
24
+ type: 'object',
25
+ properties: {
26
+ path: {
27
+ type: 'string',
28
+ description: 'Absolute path to the file or directory to read',
29
+ },
30
+ offset: {
31
+ type: 'number',
32
+ description: 'Line number to start reading from (1-indexed, default: 1)',
33
+ },
34
+ limit: {
35
+ type: 'number',
36
+ description: `Max lines to read (default: ${MAX_LINES})`,
37
+ },
38
+ },
39
+ required: ['path'],
40
+ },
41
+ async execute(args, ctx) {
42
+ const rawPath = args.path;
43
+ const filePath = path.isAbsolute(rawPath) ? rawPath : path.resolve(ctx.workspaceDir, rawPath);
44
+ let stat;
45
+ try {
46
+ stat = fs.statSync(filePath);
47
+ }
48
+ catch {
49
+ return `Error: Path not found: ${filePath}`;
50
+ }
51
+ if (stat.isDirectory()) {
52
+ return listDirectory(filePath);
53
+ }
54
+ return readFile(filePath, args.offset, args.limit);
55
+ },
56
+ };
57
+ function listDirectory(dirPath) {
58
+ let entries;
59
+ try {
60
+ entries = fs.readdirSync(dirPath, { withFileTypes: true });
61
+ }
62
+ catch (e) {
63
+ return `Error reading directory: ${e instanceof Error ? e.message : String(e)}`;
64
+ }
65
+ const lines = [`Directory: ${dirPath}`, ''];
66
+ entries.sort((a, b) => {
67
+ // Dirs first, then files, alphabetically
68
+ if (a.isDirectory() !== b.isDirectory())
69
+ return a.isDirectory() ? -1 : 1;
70
+ return a.name.localeCompare(b.name);
71
+ });
72
+ for (const entry of entries) {
73
+ const tag = entry.isDirectory() ? '[DIR] ' : '[FILE]';
74
+ lines.push(`${tag} ${entry.name}`);
75
+ }
76
+ return lines.join('\n');
77
+ }
78
+ function readFile(filePath, offset, limit) {
79
+ let buffer;
80
+ try {
81
+ buffer = fs.readFileSync(filePath);
82
+ }
83
+ catch (e) {
84
+ return `Error reading file: ${e instanceof Error ? e.message : String(e)}`;
85
+ }
86
+ // Binary detection: look for null bytes in the first 8KB
87
+ if (isBinary(buffer)) {
88
+ return `[binary file: ${filePath}]`;
89
+ }
90
+ // Enforce byte limit
91
+ let text = buffer.slice(0, MAX_BYTES).toString('utf-8');
92
+ const wasTruncatedByBytes = buffer.length > MAX_BYTES;
93
+ const allLines = text.split('\n');
94
+ const startLine = Math.max(1, (offset ?? 1));
95
+ const maxLines = Math.min(limit ?? MAX_LINES, MAX_LINES);
96
+ const slice = allLines.slice(startLine - 1, startLine - 1 + maxLines);
97
+ const truncatedByLines = startLine - 1 + maxLines < allLines.length;
98
+ const numbered = slice.map((line, i) => {
99
+ const lineNo = String(startLine + i).padStart(6);
100
+ return `${lineNo}\t${line}`;
101
+ });
102
+ let result = numbered.join('\n');
103
+ if (wasTruncatedByBytes) {
104
+ result += `\n\n[File truncated at ${MAX_BYTES / 1024}KB. Use offset/limit to read more.]`;
105
+ }
106
+ else if (truncatedByLines) {
107
+ const remaining = allLines.length - (startLine - 1 + maxLines);
108
+ result += `\n\n[${remaining} more line(s). Use offset=${startLine + maxLines} to continue.]`;
109
+ }
110
+ return result;
111
+ }
112
+ function isBinary(buffer) {
113
+ const checkLength = Math.min(8192, buffer.length);
114
+ for (let i = 0; i < checkLength; i++) {
115
+ if (buffer[i] === 0)
116
+ return true;
117
+ }
118
+ return false;
119
+ }
120
+ //# sourceMappingURL=read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../../src/code/tools/read.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ICodeTool } from './index.js';
2
+ export declare const SpawnCodeAgentTool: ICodeTool;
3
+ //# sourceMappingURL=spawn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/code/tools/spawn.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,YAAY,CAAC;AAE7D,eAAO,MAAM,kBAAkB,EAAE,SAoDhC,CAAC"}
@@ -0,0 +1,49 @@
1
+ export const SpawnCodeAgentTool = {
2
+ name: 'spawn_code_agent',
3
+ description: `Spawn a child code agent to handle a focused sub-task.
4
+
5
+ Use when you need to delegate a specific, well-scoped coding task to a focused sub-agent.
6
+ The child agent has access to the same tools (read, edit, write, glob, grep, bash).
7
+
8
+ Examples:
9
+ - "Write unit tests for the authentication module in src/auth/"
10
+ - "Refactor the UserService class to use dependency injection"
11
+ - "Fix all TypeScript errors in the src/models/ directory"
12
+
13
+ The child agent completes its task and returns a summary of what it did.
14
+ Depth is limited to prevent infinite nesting.`,
15
+ parameters: {
16
+ type: 'object',
17
+ properties: {
18
+ task: {
19
+ type: 'string',
20
+ description: 'The specific coding task for the child agent to complete',
21
+ },
22
+ context: {
23
+ type: 'string',
24
+ description: 'Additional context or constraints for the child agent',
25
+ },
26
+ },
27
+ required: ['task'],
28
+ },
29
+ async execute(args, ctx) {
30
+ const task = args.task;
31
+ const context = args.context;
32
+ if (!ctx.spawnChildAgent) {
33
+ return 'Error: Sub-agent spawning is not available in this context.';
34
+ }
35
+ const currentDepth = ctx.depth ?? 0;
36
+ const maxDepth = ctx.maxDepth ?? 2;
37
+ if (currentDepth >= maxDepth) {
38
+ return `Error: Maximum agent depth (${maxDepth}) reached. Cannot spawn further sub-agents.`;
39
+ }
40
+ try {
41
+ const result = await ctx.spawnChildAgent(task, context);
42
+ return `Sub-agent completed task.\n\nResult:\n${result}`;
43
+ }
44
+ catch (e) {
45
+ return `Sub-agent failed: ${e instanceof Error ? e.message : String(e)}`;
46
+ }
47
+ },
48
+ };
49
+ //# sourceMappingURL=spawn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../../src/code/tools/spawn.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAc;IAC3C,IAAI,EAAE,kBAAkB;IACxB,WAAW,EAAE;;;;;;;;;;;8CAW+B;IAE5C,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,0DAA0D;aACxE;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,uDAAuD;aACrE;SACF;QACD,QAAQ,EAAE,CAAC,MAAM,CAAC;KACnB;IAED,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAoB;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAc,CAAC;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,OAA6B,CAAC;QAEnD,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;YACzB,OAAO,6DAA6D,CAAC;QACvE,CAAC;QAED,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC;QACpC,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,CAAC,CAAC;QAEnC,IAAI,YAAY,IAAI,QAAQ,EAAE,CAAC;YAC7B,OAAO,+BAA+B,QAAQ,6CAA6C,CAAC;QAC9F,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACxD,OAAO,yCAAyC,MAAM,EAAE,CAAC;QAC3D,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,qBAAqB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3E,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ICodeTool } from './index.js';
2
+ export declare const WriteFileTool: ICodeTool;
3
+ //# sourceMappingURL=write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../src/code/tools/write.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,YAAY,CAAC;AAE7D,eAAO,MAAM,aAAa,EAAE,SA+E3B,CAAC"}
@@ -0,0 +1,82 @@
1
+ import path from 'path';
2
+ import fs from 'fs';
3
+ import { diffLines } from 'diff';
4
+ import { fileLock } from '../file-lock.js';
5
+ export const WriteFileTool = {
6
+ name: 'write_file',
7
+ description: `Create a new file or completely overwrite an existing file with new content.
8
+
9
+ Use this when:
10
+ - Creating a new file from scratch
11
+ - Rewriting an entire file
12
+
13
+ Prefer edit_file for partial edits. write_file is for when you need to replace the whole file.
14
+
15
+ Returns a summary of changes and LSP diagnostics (if any errors).`,
16
+ parameters: {
17
+ type: 'object',
18
+ properties: {
19
+ file_path: {
20
+ type: 'string',
21
+ description: 'Absolute path to the file to write',
22
+ },
23
+ content: {
24
+ type: 'string',
25
+ description: 'The full content to write to the file',
26
+ },
27
+ },
28
+ required: ['file_path', 'content'],
29
+ },
30
+ async execute(args, ctx) {
31
+ const rawPath = args.file_path;
32
+ const filePath = path.isAbsolute(rawPath) ? rawPath : path.resolve(ctx.workspaceDir, rawPath);
33
+ const content = args.content;
34
+ return fileLock.withLock(filePath, async () => {
35
+ // Read existing content for diff
36
+ let before = '';
37
+ const existed = fs.existsSync(filePath);
38
+ if (existed) {
39
+ try {
40
+ before = fs.readFileSync(filePath, 'utf-8');
41
+ }
42
+ catch {
43
+ before = '';
44
+ }
45
+ }
46
+ // Write the file
47
+ try {
48
+ const dir = path.dirname(filePath);
49
+ fs.mkdirSync(dir, { recursive: true });
50
+ fs.writeFileSync(filePath, content, 'utf-8');
51
+ }
52
+ catch (e) {
53
+ return `Error writing file: ${e instanceof Error ? e.message : String(e)}`;
54
+ }
55
+ // Count changes
56
+ let additions = 0;
57
+ let deletions = 0;
58
+ for (const change of diffLines(before, content)) {
59
+ if (change.added)
60
+ additions += change.count ?? 0;
61
+ if (change.removed)
62
+ deletions += change.count ?? 0;
63
+ }
64
+ const relPath = path.relative(ctx.workspaceDir, filePath);
65
+ const action = existed ? 'Updated' : 'Created';
66
+ // LSP diagnostics
67
+ let diagnosticsOutput = '';
68
+ try {
69
+ await ctx.lsp.touchFile(filePath);
70
+ const errors = ctx.lsp.getErrorsForFile(filePath);
71
+ if (errors) {
72
+ diagnosticsOutput = `\n\nLSP errors detected — please fix:\n<diagnostics file="${filePath}">\n${errors}\n</diagnostics>`;
73
+ }
74
+ }
75
+ catch {
76
+ // LSP should not block the write result
77
+ }
78
+ return `${action} ${relPath} (+${additions}/-${deletions} lines).${diagnosticsOutput}`;
79
+ });
80
+ },
81
+ };
82
+ //# sourceMappingURL=write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../../../src/code/tools/write.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * IAgent - Shared interface implemented by both DualAgent and CodeAgent.
3
+ *
4
+ * Placing this in src/core/ allows both the CLI and HTTP layers to import
5
+ * it without creating circular dependencies.
6
+ */
7
+ import type { WorkspaceManager } from './workspace.js';
8
+ import type { ConversationManager } from './conversation-manager.js';
9
+ import type { Message } from '../models/base.js';
10
+ export interface AgentChatResponse {
11
+ content: string;
12
+ toolsUsed: string[];
13
+ iterations: number;
14
+ /**
15
+ * Present only in DualAgent responses (contains the plan produced by the manager).
16
+ * Absent in CodeAgent responses.
17
+ */
18
+ plan?: {
19
+ subtasks: string[];
20
+ reasoning: string;
21
+ };
22
+ }
23
+ export interface IAgent {
24
+ chat(message: string): Promise<AgentChatResponse>;
25
+ cleanup(): Promise<void>;
26
+ getWorkspace(): WorkspaceManager;
27
+ getMCPManager(): {
28
+ getServerStatus(): Array<{
29
+ name: string;
30
+ connected: boolean;
31
+ enabled: boolean;
32
+ toolCount: number;
33
+ }>;
34
+ getClient(): {
35
+ getAllTools(): Array<{
36
+ name: string;
37
+ description: string;
38
+ }>;
39
+ };
40
+ };
41
+ resetConversation(): void;
42
+ getConversationHistory(): Message[];
43
+ getConversationManager(): ConversationManager | null | undefined;
44
+ saveConversation(): Promise<string | null>;
45
+ loadConversation(id: string): Promise<void>;
46
+ listConversations(): Promise<Array<{
47
+ id: string;
48
+ title?: string;
49
+ updated: string | number;
50
+ messageCount: number;
51
+ workspace?: string;
52
+ }>>;
53
+ }
54
+ //# sourceMappingURL=agent-interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-interface.d.ts","sourceRoot":"","sources":["../../src/core/agent-interface.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,IAAI,CAAC,EAAE;QACL,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAClD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,YAAY,IAAI,gBAAgB,CAAC;IACjC,aAAa,IAAI;QACf,eAAe,IAAI,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,OAAO,CAAC;YAAC,OAAO,EAAE,OAAO,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACpG,SAAS,IAAI;YAAE,WAAW,IAAI,KAAK,CAAC;gBAAE,IAAI,EAAE,MAAM,CAAC;gBAAC,WAAW,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,CAAC;KAC9E,CAAC;IACF,iBAAiB,IAAI,IAAI,CAAC;IAC1B,sBAAsB,IAAI,OAAO,EAAE,CAAC;IACpC,sBAAsB,IAAI,mBAAmB,GAAG,IAAI,GAAG,SAAS,CAAC;IACjE,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3C,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,iBAAiB,IAAI,OAAO,CAAC,KAAK,CAAC;QACjC,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;QACzB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC,CAAC;CACL"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * IAgent - Shared interface implemented by both DualAgent and CodeAgent.
3
+ *
4
+ * Placing this in src/core/ allows both the CLI and HTTP layers to import
5
+ * it without creating circular dependencies.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=agent-interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-interface.js","sourceRoot":"","sources":["../../src/core/agent-interface.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -1 +1 @@
1
- {"version":3,"file":"client-agent.d.ts","sourceRoot":"","sources":["../../src/core/client-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAKhE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAgBjD,oBAAY,gBAAgB;IAC1B,OAAO,YAAY,CAAM,0BAA0B;IACnD,QAAQ,aAAa,CAAI,mCAAmC;IAC5D,QAAQ,aAAa;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,GAAG,mBAAmB,GAAG,SAAS,GAAG,cAAc,GAAG,aAAa,GAAG,OAAO,CAAC;IACnG,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAYD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,YAAY,CAAa;IAGjC,OAAO,CAAC,eAAe,CAAyB;gBAEpC,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,gBAAgB;IAQzE;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAQzB,+DAA+D;IAC/D,cAAc,IAAI,IAAI;IAItB;;;OAGG;IACH,OAAO,CAAC,QAAQ;IAShB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAmBjC;;;;;;;;OAQG;YACW,uBAAuB;IAmHrC;;OAEG;IACG,QAAQ,CACZ,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,YAAY,EAAE,YAAY,EAC1B,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,gBAAgB,CAAC;IA8G5B;;;OAGG;YACW,4BAA4B;IAkE1C;;;;;OAKG;YACW,sBAAsB;IAgFpC;;OAEG;IACH,OAAO,CAAC,eAAe;IA+CvB;;OAEG;YACW,eAAe;IAsC7B;;;OAGG;YACW,UAAU;IA2BxB;;;;OAIG;YACW,6BAA6B;IAuD3C;;OAEG;YACW,oBAAoB;IAoDlC;;;;OAIG;YACW,iBAAiB;IA+C/B;;;OAGG;YACW,uBAAuB;IA+ErC;;;;OAIG;IACH,iBAAiB,IAAI,IAAI;IAIzB;;OAEG;IACH,oBAAoB,IAAI,IAAI;CAG7B"}
1
+ {"version":3,"file":"client-agent.d.ts","sourceRoot":"","sources":["../../src/core/client-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAKhE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAgBjD,oBAAY,gBAAgB;IAC1B,OAAO,YAAY,CAAM,0BAA0B;IACnD,QAAQ,aAAa,CAAI,mCAAmC;IAC5D,QAAQ,aAAa;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,GAAG,mBAAmB,GAAG,SAAS,GAAG,cAAc,GAAG,aAAa,GAAG,OAAO,CAAC;IACnG,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAYD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,YAAY,CAAa;IAGjC,OAAO,CAAC,eAAe,CAAyB;gBAEpC,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,gBAAgB;IAQzE;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAQzB,+DAA+D;IAC/D,cAAc,IAAI,IAAI;IAItB;;;OAGG;IACH,OAAO,CAAC,QAAQ;IAShB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAmBjC;;;;;;;;OAQG;YACW,uBAAuB;IAmHrC;;OAEG;IACG,QAAQ,CACZ,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,YAAY,EAAE,YAAY,EAC1B,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,gBAAgB,CAAC;IA8G5B;;;OAGG;YACW,4BAA4B;IAkE1C;;;;;OAKG;YACW,sBAAsB;IAgFpC;;OAEG;IACH,OAAO,CAAC,eAAe;IAsDvB;;OAEG;YACW,eAAe;IAsC7B;;;OAGG;YACW,UAAU;IA2BxB;;;;OAIG;YACW,6BAA6B;IAuD3C;;OAEG;YACW,oBAAoB;IAoDlC;;;;OAIG;YACW,iBAAiB;IA+C/B;;;OAGG;YACW,uBAAuB;IAgGrC;;;;OAIG;IACH,iBAAiB,IAAI,IAAI;IAIzB;;OAEG;IACH,oBAAoB,IAAI,IAAI;CAG7B"}
@@ -423,7 +423,10 @@ Respond ONLY with valid JSON:
423
423
  const issues = [];
424
424
  // Zero-tools guard: if Worker used no tools at all and this is not a purely
425
425
  // informational/conversational task, reject immediately
426
- if (workerResult.toolsUsed.length === 0 && involvementLevel !== InvolvementLevel.MINIMAL) {
426
+ // Exception: if the Worker has structured failedTools, it DID try — the
427
+ // tools simply errored. Raising a "no tools used" issue on top of real
428
+ // failures creates a misleading retry loop rather than an honest exit.
429
+ if (workerResult.toolsUsed.length === 0 && workerResult.failedTools.length === 0 && involvementLevel !== InvolvementLevel.MINIMAL) {
427
430
  const isConversational = requirements.every(r => r.type === 'information' || r.type === 'other');
428
431
  if (!isConversational) {
429
432
  issues.push('Worker completed the task without using any tools. ' +
@@ -442,8 +445,12 @@ Respond ONLY with valid JSON:
442
445
  }
443
446
  }
444
447
  }
445
- // Check if Worker succeeded
446
- if (!workerResult.success) {
448
+ // Check if Worker succeeded.
449
+ // If failedTools is non-empty the Worker already proved it tried — the failure
450
+ // is evidence-backed. Raising a generic "retry with appropriate tool usage"
451
+ // issue would just queue another pointless attempt. Let it through; synthesis
452
+ // will report the specific failures to the user.
453
+ if (!workerResult.success && workerResult.failedTools.length === 0) {
447
454
  issues.push('Worker did not complete the task successfully. The task needs to be retried with appropriate tool usage.');
448
455
  }
449
456
  return { issues };
@@ -667,6 +674,22 @@ Respond ONLY with the correction instruction text, nothing else.`;
667
674
  if (issues.length === 0) {
668
675
  return { confidence: 'high', progressMade: true };
669
676
  }
677
+ // Data-driven short-circuit: if the Worker reported structured tool failures,
678
+ // we know exactly what happened — no LLM inference needed.
679
+ // suggestedStrategy is 'escalate' because rephrasing the instruction cannot
680
+ // fix a tool that is fundamentally erroring (wrong path, permissions, etc.).
681
+ if (workerResult.failedTools.length > 0) {
682
+ const failureSummary = workerResult.failedTools
683
+ .map(f => `${f.toolName} (${f.attempts} attempt${f.attempts !== 1 ? 's' : ''}) — ${f.lastError}`)
684
+ .join('; ');
685
+ logger.info(`[Client] Data-driven CompletionSignal: tool_failure — ${failureSummary}`);
686
+ return {
687
+ confidence: 'none',
688
+ progressMade: false,
689
+ blockerType: 'tool_failure',
690
+ suggestedStrategy: 'escalate',
691
+ };
692
+ }
670
693
  const contextBlock = agentContext ? `\n${serializeAgentContext(agentContext, 'client')}` : '';
671
694
  const signalPrompt = `You are analyzing a subtask execution to produce a CompletionSignal.
672
695