@burtson-labs/agent-core 1.6.13

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 (195) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +88 -0
  3. package/dist/index.d.ts +16 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +52 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/mcp/activation.d.ts +60 -0
  8. package/dist/mcp/activation.d.ts.map +1 -0
  9. package/dist/mcp/activation.js +139 -0
  10. package/dist/mcp/activation.js.map +1 -0
  11. package/dist/mcp/clientPool.d.ts +202 -0
  12. package/dist/mcp/clientPool.d.ts.map +1 -0
  13. package/dist/mcp/clientPool.js +469 -0
  14. package/dist/mcp/clientPool.js.map +1 -0
  15. package/dist/mcp/index.d.ts +18 -0
  16. package/dist/mcp/index.d.ts.map +1 -0
  17. package/dist/mcp/index.js +28 -0
  18. package/dist/mcp/index.js.map +1 -0
  19. package/dist/mcp/server.d.ts +43 -0
  20. package/dist/mcp/server.d.ts.map +1 -0
  21. package/dist/mcp/server.js +130 -0
  22. package/dist/mcp/server.js.map +1 -0
  23. package/dist/mcp/toolAdapter.d.ts +57 -0
  24. package/dist/mcp/toolAdapter.d.ts.map +1 -0
  25. package/dist/mcp/toolAdapter.js +223 -0
  26. package/dist/mcp/toolAdapter.js.map +1 -0
  27. package/dist/mcp/types.d.ts +122 -0
  28. package/dist/mcp/types.d.ts.map +1 -0
  29. package/dist/mcp/types.js +15 -0
  30. package/dist/mcp/types.js.map +1 -0
  31. package/dist/providers/deterministic-provider.d.ts +21 -0
  32. package/dist/providers/deterministic-provider.d.ts.map +1 -0
  33. package/dist/providers/deterministic-provider.js +80 -0
  34. package/dist/providers/deterministic-provider.js.map +1 -0
  35. package/dist/providers/provider-client.d.ts +12 -0
  36. package/dist/providers/provider-client.d.ts.map +1 -0
  37. package/dist/providers/provider-client.js +11 -0
  38. package/dist/providers/provider-client.js.map +1 -0
  39. package/dist/runtime/AgentRuntime.d.ts +67 -0
  40. package/dist/runtime/AgentRuntime.d.ts.map +1 -0
  41. package/dist/runtime/AgentRuntime.js +382 -0
  42. package/dist/runtime/AgentRuntime.js.map +1 -0
  43. package/dist/security/secretPatterns.d.ts +76 -0
  44. package/dist/security/secretPatterns.d.ts.map +1 -0
  45. package/dist/security/secretPatterns.js +290 -0
  46. package/dist/security/secretPatterns.js.map +1 -0
  47. package/dist/tools/ask-user-tool.d.ts +19 -0
  48. package/dist/tools/ask-user-tool.d.ts.map +1 -0
  49. package/dist/tools/ask-user-tool.js +148 -0
  50. package/dist/tools/ask-user-tool.js.map +1 -0
  51. package/dist/tools/compactMessages.d.ts +52 -0
  52. package/dist/tools/compactMessages.d.ts.map +1 -0
  53. package/dist/tools/compactMessages.js +158 -0
  54. package/dist/tools/compactMessages.js.map +1 -0
  55. package/dist/tools/core-tools.d.ts +29 -0
  56. package/dist/tools/core-tools.d.ts.map +1 -0
  57. package/dist/tools/core-tools.js +2214 -0
  58. package/dist/tools/core-tools.js.map +1 -0
  59. package/dist/tools/git-tools.d.ts +32 -0
  60. package/dist/tools/git-tools.d.ts.map +1 -0
  61. package/dist/tools/git-tools.js +330 -0
  62. package/dist/tools/git-tools.js.map +1 -0
  63. package/dist/tools/index.d.ts +15 -0
  64. package/dist/tools/index.d.ts.map +1 -0
  65. package/dist/tools/index.js +31 -0
  66. package/dist/tools/index.js.map +1 -0
  67. package/dist/tools/language-adapters.d.ts +48 -0
  68. package/dist/tools/language-adapters.d.ts.map +1 -0
  69. package/dist/tools/language-adapters.js +299 -0
  70. package/dist/tools/language-adapters.js.map +1 -0
  71. package/dist/tools/loop/compactionTrigger.d.ts +47 -0
  72. package/dist/tools/loop/compactionTrigger.d.ts.map +1 -0
  73. package/dist/tools/loop/compactionTrigger.js +32 -0
  74. package/dist/tools/loop/compactionTrigger.js.map +1 -0
  75. package/dist/tools/loop/finalAnswerNudges.d.ts +68 -0
  76. package/dist/tools/loop/finalAnswerNudges.d.ts.map +1 -0
  77. package/dist/tools/loop/finalAnswerNudges.js +87 -0
  78. package/dist/tools/loop/finalAnswerNudges.js.map +1 -0
  79. package/dist/tools/loop/goalAnchor.d.ts +72 -0
  80. package/dist/tools/loop/goalAnchor.d.ts.map +1 -0
  81. package/dist/tools/loop/goalAnchor.js +76 -0
  82. package/dist/tools/loop/goalAnchor.js.map +1 -0
  83. package/dist/tools/loop/llmStream.d.ts +70 -0
  84. package/dist/tools/loop/llmStream.d.ts.map +1 -0
  85. package/dist/tools/loop/llmStream.js +181 -0
  86. package/dist/tools/loop/llmStream.js.map +1 -0
  87. package/dist/tools/loop/parallelExecute.d.ts +57 -0
  88. package/dist/tools/loop/parallelExecute.d.ts.map +1 -0
  89. package/dist/tools/loop/parallelExecute.js +54 -0
  90. package/dist/tools/loop/parallelExecute.js.map +1 -0
  91. package/dist/tools/loop/singleToolExecute.d.ts +71 -0
  92. package/dist/tools/loop/singleToolExecute.d.ts.map +1 -0
  93. package/dist/tools/loop/singleToolExecute.js +139 -0
  94. package/dist/tools/loop/singleToolExecute.js.map +1 -0
  95. package/dist/tools/loop/toolCallNormalize.d.ts +57 -0
  96. package/dist/tools/loop/toolCallNormalize.d.ts.map +1 -0
  97. package/dist/tools/loop/toolCallNormalize.js +99 -0
  98. package/dist/tools/loop/toolCallNormalize.js.map +1 -0
  99. package/dist/tools/loop/turnSetup.d.ts +43 -0
  100. package/dist/tools/loop/turnSetup.d.ts.map +1 -0
  101. package/dist/tools/loop/turnSetup.js +48 -0
  102. package/dist/tools/loop/turnSetup.js.map +1 -0
  103. package/dist/tools/ocr.d.ts +52 -0
  104. package/dist/tools/ocr.d.ts.map +1 -0
  105. package/dist/tools/ocr.js +238 -0
  106. package/dist/tools/ocr.js.map +1 -0
  107. package/dist/tools/post-edit-checks.d.ts +46 -0
  108. package/dist/tools/post-edit-checks.d.ts.map +1 -0
  109. package/dist/tools/post-edit-checks.js +236 -0
  110. package/dist/tools/post-edit-checks.js.map +1 -0
  111. package/dist/tools/skill-loader.d.ts +94 -0
  112. package/dist/tools/skill-loader.d.ts.map +1 -0
  113. package/dist/tools/skill-loader.js +422 -0
  114. package/dist/tools/skill-loader.js.map +1 -0
  115. package/dist/tools/skill-registry.d.ts +44 -0
  116. package/dist/tools/skill-registry.d.ts.map +1 -0
  117. package/dist/tools/skill-registry.js +118 -0
  118. package/dist/tools/skill-registry.js.map +1 -0
  119. package/dist/tools/skill-types.d.ts +38 -0
  120. package/dist/tools/skill-types.d.ts.map +1 -0
  121. package/dist/tools/skill-types.js +10 -0
  122. package/dist/tools/skill-types.js.map +1 -0
  123. package/dist/tools/skills/code-review-skill.d.ts +9 -0
  124. package/dist/tools/skills/code-review-skill.d.ts.map +1 -0
  125. package/dist/tools/skills/code-review-skill.js +66 -0
  126. package/dist/tools/skills/code-review-skill.js.map +1 -0
  127. package/dist/tools/skills/core-skill.d.ts +13 -0
  128. package/dist/tools/skills/core-skill.d.ts.map +1 -0
  129. package/dist/tools/skills/core-skill.js +23 -0
  130. package/dist/tools/skills/core-skill.js.map +1 -0
  131. package/dist/tools/skills/git-skill.d.ts +10 -0
  132. package/dist/tools/skills/git-skill.d.ts.map +1 -0
  133. package/dist/tools/skills/git-skill.js +30 -0
  134. package/dist/tools/skills/git-skill.js.map +1 -0
  135. package/dist/tools/skills/index.d.ts +17 -0
  136. package/dist/tools/skills/index.d.ts.map +1 -0
  137. package/dist/tools/skills/index.js +49 -0
  138. package/dist/tools/skills/index.js.map +1 -0
  139. package/dist/tools/skills/interaction-skill.d.ts +14 -0
  140. package/dist/tools/skills/interaction-skill.d.ts.map +1 -0
  141. package/dist/tools/skills/interaction-skill.js +24 -0
  142. package/dist/tools/skills/interaction-skill.js.map +1 -0
  143. package/dist/tools/skills/mail-search-skill.d.ts +25 -0
  144. package/dist/tools/skills/mail-search-skill.d.ts.map +1 -0
  145. package/dist/tools/skills/mail-search-skill.js +343 -0
  146. package/dist/tools/skills/mail-search-skill.js.map +1 -0
  147. package/dist/tools/skills/plan-skill.d.ts +10 -0
  148. package/dist/tools/skills/plan-skill.d.ts.map +1 -0
  149. package/dist/tools/skills/plan-skill.js +126 -0
  150. package/dist/tools/skills/plan-skill.js.map +1 -0
  151. package/dist/tools/skills/semantic-search-skill.d.ts +22 -0
  152. package/dist/tools/skills/semantic-search-skill.d.ts.map +1 -0
  153. package/dist/tools/skills/semantic-search-skill.js +244 -0
  154. package/dist/tools/skills/semantic-search-skill.js.map +1 -0
  155. package/dist/tools/skills/test-gen-skill.d.ts +9 -0
  156. package/dist/tools/skills/test-gen-skill.d.ts.map +1 -0
  157. package/dist/tools/skills/test-gen-skill.js +123 -0
  158. package/dist/tools/skills/test-gen-skill.js.map +1 -0
  159. package/dist/tools/tool-registry.d.ts +60 -0
  160. package/dist/tools/tool-registry.d.ts.map +1 -0
  161. package/dist/tools/tool-registry.js +200 -0
  162. package/dist/tools/tool-registry.js.map +1 -0
  163. package/dist/tools/tool-types.d.ts +281 -0
  164. package/dist/tools/tool-types.d.ts.map +1 -0
  165. package/dist/tools/tool-types.js +10 -0
  166. package/dist/tools/tool-types.js.map +1 -0
  167. package/dist/tools/tool-use-loop.d.ts +231 -0
  168. package/dist/tools/tool-use-loop.d.ts.map +1 -0
  169. package/dist/tools/tool-use-loop.js +2057 -0
  170. package/dist/tools/tool-use-loop.js.map +1 -0
  171. package/dist/tools/tool-use-parser.d.ts +78 -0
  172. package/dist/tools/tool-use-parser.d.ts.map +1 -0
  173. package/dist/tools/tool-use-parser.js +427 -0
  174. package/dist/tools/tool-use-parser.js.map +1 -0
  175. package/dist/tools/toolAvailabilityDetector.d.ts +48 -0
  176. package/dist/tools/toolAvailabilityDetector.d.ts.map +1 -0
  177. package/dist/tools/toolAvailabilityDetector.js +156 -0
  178. package/dist/tools/toolAvailabilityDetector.js.map +1 -0
  179. package/dist/tools/unified-patch.d.ts +87 -0
  180. package/dist/tools/unified-patch.d.ts.map +1 -0
  181. package/dist/tools/unified-patch.js +217 -0
  182. package/dist/tools/unified-patch.js.map +1 -0
  183. package/dist/types/agent.d.ts +69 -0
  184. package/dist/types/agent.d.ts.map +1 -0
  185. package/dist/types/agent.js +54 -0
  186. package/dist/types/agent.js.map +1 -0
  187. package/dist/types/tasks.d.ts +22 -0
  188. package/dist/types/tasks.d.ts.map +1 -0
  189. package/dist/types/tasks.js +3 -0
  190. package/dist/types/tasks.js.map +1 -0
  191. package/dist/utils/event-emitter.d.ts +13 -0
  192. package/dist/utils/event-emitter.d.ts.map +1 -0
  193. package/dist/utils/event-emitter.js +54 -0
  194. package/dist/utils/event-emitter.js.map +1 -0
  195. package/package.json +33 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-registry.js","sourceRoot":"","sources":["../../src/tools/tool-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,281 @@
1
+ /**
2
+ * Core types for the Bandit agent tool system.
3
+ *
4
+ * ToolExecutionContext is a host-provided interface — it must be implemented
5
+ * by the VS Code extension, web host, or test harness. The tools themselves
6
+ * have no direct dependency on Node.js APIs or VS Code.
7
+ */
8
+ export interface ToolResult {
9
+ output: string;
10
+ /** True when the tool encountered an error (output contains the error message). */
11
+ isError?: boolean;
12
+ }
13
+ /**
14
+ * Host-provided execution environment for tools.
15
+ * All paths passed to these methods are absolute.
16
+ */
17
+ export interface ToolExecutionContext {
18
+ /** Absolute path to the workspace/repo root. */
19
+ workspaceRoot: string;
20
+ /** Read the full text content of a file. */
21
+ readFile(absolutePath: string): Promise<string>;
22
+ /** Write (create or overwrite) a file. */
23
+ writeFile(absolutePath: string, content: string): Promise<void>;
24
+ /**
25
+ * Permanently remove a file from disk. Optional — hosts that don't
26
+ * implement it cause `apply_patch` delete actions to fall back to
27
+ * blanking the file (`writeFile('')`) and emit a clear warning so
28
+ * the model knows a hard delete didn't happen.
29
+ *
30
+ * Why optional: there was no way to actually remove a
31
+ * file via the tool surface — `apply_patch` `kind: 'delete'` quietly
32
+ * left a 0-byte file behind. Adding a real primitive here without
33
+ * forcing every host (CLI, extension, future web host) to implement
34
+ * it on the same release lets the upgrade ride out gradually.
35
+ * Implementations should resolve relative paths against `workspaceRoot`
36
+ * and reject paths outside the workspace.
37
+ */
38
+ deleteFile?(absolutePath: string): Promise<void>;
39
+ /**
40
+ * List files matching a glob pattern.
41
+ * @param pattern Glob relative to cwd (e.g. "src/**\/*.ts")
42
+ * @param cwd Absolute directory to resolve the pattern from (default: workspaceRoot)
43
+ */
44
+ listFiles(pattern: string, cwd?: string): Promise<string[]>;
45
+ /**
46
+ * List direct children (files AND directories, non-recursive) of a
47
+ * directory. Separate from listFiles because listFiles is glob-based
48
+ * and file-only — it can't see subdirectories, only recurses into
49
+ * them. Used by the `ls` tool so "what's in ~/Desktop" returns both
50
+ * files and folders at that level. Hosts that don't implement it
51
+ * fall back to listFiles('*'), which misses folders entirely —
52
+ * when the CLI couldn't find "client engament
53
+ * drafts" on the user's Desktop because it's a directory.
54
+ *
55
+ * Entries end with `/` if the entry is a directory so the caller can
56
+ * distinguish without a follow-up stat. Symlinks are included and
57
+ * resolved against the target type.
58
+ */
59
+ listDirectoryEntries?(cwd: string): Promise<string[]>;
60
+ /**
61
+ * Search file contents for a regex pattern.
62
+ * Returns a human-readable matches string (path:line: content).
63
+ * @param pattern Regex or literal string to search for
64
+ * @param cwd Directory to search in (default: workspaceRoot)
65
+ * @param fileGlob Optional file filter, e.g. "*.ts"
66
+ */
67
+ searchCode(pattern: string, cwd?: string, fileGlob?: string): Promise<string>;
68
+ /** Run a shell command and capture stdout/stderr. */
69
+ runCommand(cmd: string, args: string[], cwd?: string): Promise<{
70
+ stdout: string;
71
+ stderr: string;
72
+ exitCode: number;
73
+ }>;
74
+ /**
75
+ * Spawn a process and capture its output for `durationMs`, then send
76
+ * SIGTERM if it's still running. Used by the `watch_command` tool so
77
+ * the agent can run a long-lived process (dev server, --watch test
78
+ * runner, log tail) for a bounded window and react to what came out.
79
+ * Distinct from runCommand — runCommand expects the process to exit
80
+ * on its own; watchCommand assumes it might not.
81
+ *
82
+ * Optional. Hosts that don't implement it cause watch_command to
83
+ * gracefully fall back to runCommand with a note in the result.
84
+ */
85
+ watchCommand?(cmd: string, args: string[], cwd: string | undefined, durationMs: number): Promise<{
86
+ stdout: string;
87
+ stderr: string;
88
+ exitCode: number | null;
89
+ /** True when the process exited on its own before the timer ran out. */
90
+ endedEarly: boolean;
91
+ }>;
92
+ /** Optional pre-write language validation. When present, write_file validates before touching disk. */
93
+ languageAdapters?: ILanguageAdapterRegistry;
94
+ /**
95
+ * Read-before-edit tracking. When present, read_file calls
96
+ * `markFileRead(path)` after a successful read; apply_edit,
97
+ * replace_range, and write_file (overwriting) call `hasFileBeenRead(path)` and reject
98
+ * with a clear error if the model is editing blind. Prevents the
99
+ * "model writes without reading first" failure mode where it
100
+ * fabricates content or breaks indentation it never inspected.
101
+ * Hosts that don't implement these methods skip the check (the
102
+ * tools fall through to current behavior).
103
+ */
104
+ markFileRead?(absolutePath: string): void;
105
+ hasFileBeenRead?(absolutePath: string): boolean;
106
+ /** User-configured extra locations the `find_directory` tool should
107
+ * scan in addition to the built-in clone parents (`~/Documents/GitHub`,
108
+ * `~/Projects`, `~/code`, …). Hosts populate this from their config
109
+ * surface (CLI: `repos.roots` in `~/.bandit/config.json`; extension:
110
+ * `banditStealth.repos.roots` workspace setting). Tilde-prefixed
111
+ * paths are expected — hosts that resolve them in `listDirectoryEntries`
112
+ * can leave them as-is. */
113
+ customRepoRoots?: string[];
114
+ /**
115
+ * Ask the user one or more clarifying questions mid-task and await their
116
+ * answer(s). Optional — hosts that can render an interactive prompt (the
117
+ * CLI's ink form, the extension's webview card) implement it. The
118
+ * `ask_user` tool is only offered to the model when a host provides this
119
+ * (and degrades to "ask in plain text" when it's absent), so a host with
120
+ * no interactive surface never strands the model on a question it can't
121
+ * answer. Implementations should resolve with the user's answers keyed by
122
+ * question id, or `{ answers: {}, cancelled: true }` if dismissed.
123
+ */
124
+ requestUserInput?(request: UserInputRequest): Promise<UserInputResponse>;
125
+ }
126
+ /** One question posed to the user by the `ask_user` tool. */
127
+ export interface UserInputQuestion {
128
+ /** Stable key the answer is returned under. */
129
+ id: string;
130
+ /** The question text shown to the user. */
131
+ question: string;
132
+ /** Short tab label (≈≤12 chars) shown when there are multiple questions. */
133
+ header?: string;
134
+ /** Suggested answers the user can pick from. */
135
+ options?: Array<{
136
+ label: string;
137
+ description?: string;
138
+ }>;
139
+ /** Whether the user may type a free-text answer instead of (or in
140
+ * addition to) picking an option. Defaults to true. */
141
+ allowFreeform?: boolean;
142
+ }
143
+ export interface UserInputRequest {
144
+ questions: UserInputQuestion[];
145
+ }
146
+ export interface UserInputResponse {
147
+ /** Map of question id → the user's answer. Skipped questions are omitted. */
148
+ answers: Record<string, string>;
149
+ /** True when the user dismissed the prompt without answering. */
150
+ cancelled?: boolean;
151
+ }
152
+ /**
153
+ * Optional JSON-Schema fragment describing the shape of an
154
+ * AgentToolParameter. Native (in-tree) tools historically declared
155
+ * every param as `type: string` because Bandit's tool-use loop hands
156
+ * arguments to `execute()` as `Record<string, string>` — fine for the
157
+ * read_file / apply_edit / run_command surface where all args are
158
+ * stringy. But MCP-bridged tools (Gmail filters, structured forms,
159
+ * batched operations) often need `object` or `array<string>` params
160
+ * to round-trip correctly: without a type hint, the model gets told
161
+ * every param is a string and emits strings, which the MCP server's
162
+ * zod validators reject with "expected object, received string."
163
+ *
164
+ * Adapters populate this field from the source schema (MCP's
165
+ * inputSchema, OpenAPI parameter type, etc.) and the registry plumbs
166
+ * it through to (a) the native-tools schema sent to providers that
167
+ * support function calling natively (Ollama, OpenAI, etc.), and (b)
168
+ * the system-prompt block rendered for providers that don't.
169
+ *
170
+ * Kept intentionally narrow — only the fields that materially change
171
+ * how the model serializes a value. Nested object properties /
172
+ * array item shapes / enums all matter; default values and exotic
173
+ * constraint keywords (multipleOf, etc.) don't.
174
+ */
175
+ export interface AgentToolParameterSchema {
176
+ /** JSON Schema "type" keyword: "object", "array", "string", "number",
177
+ * "boolean", "integer", or "null". Omitting it (or passing "string")
178
+ * preserves the legacy behavior. */
179
+ type?: 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null';
180
+ /** When type === "object": fields and their schemas. */
181
+ properties?: Record<string, AgentToolParameterSchema & {
182
+ description?: string;
183
+ }>;
184
+ /** When type === "object": required field names. */
185
+ required?: string[];
186
+ /** When type === "array": item shape. */
187
+ items?: AgentToolParameterSchema & {
188
+ description?: string;
189
+ };
190
+ /** Enum constraint — surfaces as a fixed-choice param when present. */
191
+ enum?: Array<string | number | boolean>;
192
+ /** Free-form description embedded in nested-property schemas. */
193
+ description?: string;
194
+ }
195
+ export interface AgentToolParameter {
196
+ name: string;
197
+ description: string;
198
+ required?: boolean;
199
+ /** Optional JSON-Schema-shaped type info. When omitted the param is
200
+ * treated as a string (the legacy default) — matches every in-tree
201
+ * tool today. Populated by adapter layers (e.g. the MCP→AgentTool
202
+ * bridge) when the source defines a richer shape. */
203
+ schema?: AgentToolParameterSchema;
204
+ }
205
+ export interface AgentTool {
206
+ name: string;
207
+ description: string;
208
+ parameters: AgentToolParameter[];
209
+ execute(params: Record<string, string>, ctx: ToolExecutionContext): Promise<ToolResult>;
210
+ }
211
+ /**
212
+ * A chat message as seen by the tool use loop.
213
+ * Intentionally minimal — adapters convert to/from provider-specific formats.
214
+ */
215
+ export interface ToolLoopMessage {
216
+ role: 'system' | 'user' | 'assistant';
217
+ content: string;
218
+ }
219
+ /**
220
+ * JSON-Schema-shaped tool definition used by Ollama's native tool-calling
221
+ * `tools: [...]` field. Matches what `ToolRegistry.buildNativeToolsSchema()`
222
+ * returns and what Ollama's OpenAPI contract expects. Declared here
223
+ * (rather than imported from stealth-core-runtime) so agent-core stays
224
+ * host-agnostic.
225
+ */
226
+ export interface NativeToolSchema {
227
+ type: 'function';
228
+ function: {
229
+ name: string;
230
+ description: string;
231
+ parameters: {
232
+ type: 'object';
233
+ properties: Record<string, Record<string, unknown>>;
234
+ required: string[];
235
+ };
236
+ };
237
+ }
238
+ /**
239
+ * Per-call chat options. Optional bag the loop may pass for specific
240
+ * iterations — the chat function should treat it as a soft override of
241
+ * its closure-captured defaults, NOT a permanent change.
242
+ */
243
+ export interface ChatCallOptions {
244
+ /**
245
+ * Per-call override for thinking mode. The loop sets `false` on the
246
+ * "thinking-off recovery" attempt — when reasoning-only retries have
247
+ * exhausted, we make ONE final attempt with thinking forced off so
248
+ * the model is collapsed into the regular content channel where its
249
+ * tool-call sampling is more deterministic. with
250
+ * qwen3.6:27b on a remote Ollama: with thinking ON, the model would
251
+ * sometimes get stuck emitting reasoning-only responses; flipping
252
+ * thinking off on retry consistently produced a real tool call.
253
+ */
254
+ think?: boolean;
255
+ }
256
+ /**
257
+ * Chat function signature accepted by ToolUseLoop.
258
+ * Returns an async iterable of text chunks (streaming). When `tools` is
259
+ * populated, the provider is expected to forward those schemas to
260
+ * Ollama's native `tools` field — any tool-call intents the model emits
261
+ * come back as structured data which the provider should translate back
262
+ * into inline `<tool_call>{...}</tool_call>` markup in the yielded text
263
+ * stream so the loop's existing parser keeps working. The optional
264
+ * `options` bag supports per-call overrides (see ChatCallOptions).
265
+ */
266
+ export type ChatFn = (messages: ToolLoopMessage[], tools?: NativeToolSchema[], options?: ChatCallOptions) => AsyncIterable<string>;
267
+ /** Result of a language adapter validation. */
268
+ export interface ValidationResult {
269
+ ok: boolean;
270
+ /** Human-readable error for the model to self-correct. Only set when ok is false. */
271
+ error?: string;
272
+ }
273
+ /**
274
+ * Minimal contract for a language adapter registry.
275
+ * Implemented by LanguageAdapterRegistry in language-adapters.ts.
276
+ * Declared here to allow ToolExecutionContext to reference it without a circular import.
277
+ */
278
+ export interface ILanguageAdapterRegistry {
279
+ validate(filePath: string, content: string, ctx: ToolExecutionContext): Promise<ValidationResult>;
280
+ }
281
+ //# sourceMappingURL=tool-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-types.d.ts","sourceRoot":"","sources":["../../src/tools/tool-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ /**
3
+ * Core types for the Bandit agent tool system.
4
+ *
5
+ * ToolExecutionContext is a host-provided interface — it must be implemented
6
+ * by the VS Code extension, web host, or test harness. The tools themselves
7
+ * have no direct dependency on Node.js APIs or VS Code.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ //# sourceMappingURL=tool-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-types.js","sourceRoot":"","sources":["../../src/tools/tool-types.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG"}
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Text-based tool use execution loop.
3
+ *
4
+ * Implements the observe → act → replan cycle for models that don't support
5
+ * native function calling (gemma3, bandit-core, qwen2.5-coder, etc.).
6
+ *
7
+ * Flow:
8
+ * 1. Build messages with tool definitions in system prompt
9
+ * 2. Stream response from LLM, aggregate full text
10
+ * 3. Parse <tool_call> blocks
11
+ * 4. Execute tools via ToolExecutionContext
12
+ * 5. Inject <tool_result> blocks as next user message
13
+ * 6. Repeat from step 2 until no tool calls, or max iterations reached
14
+ * 7. Return final model response (the one with no tool calls)
15
+ *
16
+ * For models WITH native tool calling (qwen2.5-coder:32b, llama3.1),
17
+ * the host should use the Ollama `tools: [...]` field instead.
18
+ */
19
+ import type { ToolExecutionContext, ChatFn, ToolLoopMessage } from './tool-types';
20
+ import { ToolRegistry } from './tool-registry';
21
+ export interface ToolUseLoopOptions {
22
+ /** Maximum number of tool call rounds before forcing a final answer. Default: 10. */
23
+ maxIterations?: number;
24
+ /**
25
+ * When true, the loop passes the registry's tool schemas to `chat()`
26
+ * via the native-tools channel and SKIPS injecting the XML-style tool
27
+ * block into the system prompt. The caller is responsible for only
28
+ * setting this when the target model advertises `supportsToolCalling`
29
+ * (Qwen2.5-Coder, Llama 3.1+, Devstral, DeepSeek-Coder-V2+, etc.).
30
+ * Saves ~1500-3000 tokens per turn — the schemas live in the model's
31
+ * own chat template instead of the content payload.
32
+ */
33
+ nativeTools?: boolean;
34
+ /**
35
+ * When nativeTools is enabled, retryable upstream failures can be
36
+ * degraded to Bandit's text-tool protocol for the current turn. This
37
+ * is useful for open-model native parsers that occasionally 500 on an
38
+ * incomplete tool envelope. Defaults to true.
39
+ */
40
+ nativeToolFailureFallback?: boolean;
41
+ /** Called on each event for external observability (streaming UI updates, telemetry). */
42
+ emitEvent?: (type: string, payload?: unknown) => void;
43
+ /**
44
+ * Called at the START of each iteration (before `tool_loop:llm_start`)
45
+ * to fetch any messages the host wants injected into the conversation
46
+ * before this iteration's LLM call. Returned messages are appended to
47
+ * the running conversation in order.
48
+ *
49
+ * The motivating use case (v1.7.336+) is mid-turn delivery of completed
50
+ * background subagent synopses: today the parent agent has to either
51
+ * (a) poll `check_task` in a tight loop wasting iterations, or (b) wait
52
+ * until the next user prompt for `drainBackgroundCompletions` to
53
+ * inject the synopsis. With this hook, the host's backgroundStore
54
+ * subscription pushes completed synopses into a queue, this callback
55
+ * drains the queue per iteration, and the parent sees completions
56
+ * AS THEY HAPPEN instead of after a multi-minute poll loop.
57
+ *
58
+ * Other valid uses: async-event interrupts (file watcher pushing a
59
+ * "file changed" notice into a long-running review turn), external
60
+ * signal injection (user types `/note <fact>` mid-turn — the note
61
+ * lands here before the next iteration sees it), etc.
62
+ *
63
+ * Empty array or `undefined` return = nothing to inject this tick.
64
+ * Cheap to call — runs once per iteration, no significant perf cost.
65
+ */
66
+ drainExternalMessages?: () => ToolLoopMessage[] | undefined;
67
+ /**
68
+ * Guard called immediately before a tool executes. Return `{ allow: false, reason }`
69
+ * to abort the call — the model sees the reason as the tool result and can replan.
70
+ * Used by hosts to enforce PreToolUse hooks / permission gates.
71
+ */
72
+ beforeToolExecute?: (call: {
73
+ name: string;
74
+ params: Record<string, string>;
75
+ }) => Promise<{
76
+ allow: boolean;
77
+ reason?: string;
78
+ }> | {
79
+ allow: boolean;
80
+ reason?: string;
81
+ };
82
+ /**
83
+ * Token budget for the chat messages passed to the provider on each
84
+ * iteration. When the accumulated tool-result history would exceed
85
+ * this, older tool results get collapsed to one-line placeholders.
86
+ * Defaults to ~75% of a 16k num_ctx (12000 tokens).
87
+ *
88
+ * Set higher on large models (e.g. 24000 for 32k num_ctx). Set to
89
+ * Infinity to disable compaction.
90
+ */
91
+ messageTokenBudget?: number;
92
+ /**
93
+ * Cooperative cancellation. When the host aborts this signal the loop
94
+ * stops streaming the current iteration, skips remaining iterations,
95
+ * and returns whatever has been gathered so far with `cancelled: true`
96
+ * on the result. The chat function should also honour the same signal
97
+ * to abort the underlying provider request — without that, the model
98
+ * keeps generating tokens server-side and the user pays for output
99
+ * they've already dismissed. Without a signal, cancel is best-effort
100
+ * (loop won't abort mid-stream).
101
+ */
102
+ signal?: AbortSignal;
103
+ /**
104
+ * Hard cap on tool calls executed in a single iteration. Models in a
105
+ * panic state ( with gpt-oss:120b on H100 against
106
+ * a real repo) emit 20+ tool calls in one parallel batch — most of
107
+ * them duplicate searches with slightly different globs. Capping
108
+ * forces the model to commit to its top N picks; the rest are
109
+ * dropped and the model is told to narrow its query. Default 8.
110
+ */
111
+ maxParallelTools?: number;
112
+ /**
113
+ * Hard cap on total tool calls executed across the full turn.
114
+ * Independent of `maxIterations` because a single iteration can fire
115
+ * many calls in parallel. Hitting this terminates the loop with
116
+ * `hitLimit: true`. Default 60.
117
+ */
118
+ maxTotalTools?: number;
119
+ /**
120
+ * Approximate per-turn output token budget for the model. When the
121
+ * combined estimated output of write/edit calls in a single batch
122
+ * exceeds `outputBudgetTokens * outputBudgetRatio`, the loop falls
123
+ * back to serial execution for that batch — one call at a time, in
124
+ * order — instead of `Promise.all`. Reads stay parallel because
125
+ * their contribution to the assistant turn's output is negligible.
126
+ *
127
+ * Why: smaller models (4B–12B) generate malformed JSON in the tail
128
+ * of a multi-file emission once their effective output budget is
129
+ * exhausted. on a portfolio build — even a
130
+ * strong model produced a malformed `todo_write` after writing four
131
+ * files of ~7 KB each in one assistant turn. Serialising lets the
132
+ * model react to each result before committing further output, and
133
+ * gives the user one approval at a time instead of a queued pile.
134
+ *
135
+ * Leave undefined or set to `Infinity` for capable hosted models —
136
+ * the gate won't trip and parallel writes go through unchanged.
137
+ */
138
+ outputBudgetTokens?: number;
139
+ /**
140
+ * Fraction of `outputBudgetTokens` the batch may occupy before
141
+ * serialisation kicks in. Default 0.6 — leaves 40% headroom for the
142
+ * surrounding reasoning/prose the model emits alongside the calls.
143
+ */
144
+ outputBudgetRatio?: number;
145
+ /**
146
+ * True when this loop instance is running a subagent (spawned via the
147
+ * `task` tool), rather than the user-facing parent agent. Subagents
148
+ * are spawned to GATHER information for a specific goal — they MUST
149
+ * call tools to make progress; producing prose-only output on the
150
+ * first iteration is always a stall, not a legitimate final answer.
151
+ *
152
+ * When set, an extra detector forces a tool call on iter 0: if the
153
+ * model's first response has no tool calls AND no other detector
154
+ * (announce-intent, narrate, etc.) caught the stall, push a corrective
155
+ * user message demanding a tool call before treating the response as
156
+ * final. bandit-logic emits reasoning + neutral
157
+ * prose on iter 0 of subagent runs, the existing detectors don't fire
158
+ * because the prose isn't forward-looking ("Let me X") and the verb
159
+ * whitelist doesn't match, and the loop returns a 0-iteration result
160
+ * that the parent can't use.
161
+ */
162
+ isSubagent?: boolean;
163
+ }
164
+ export declare function sleep(ms: number): Promise<void>;
165
+ export declare function isRetryableLlmError(error: unknown): boolean;
166
+ export declare function tagRetryableLlmError(error: unknown): void;
167
+ export declare function summarizeLlmError(error: unknown): string;
168
+ export declare function isContinuationPrompt(text: string): boolean;
169
+ /**
170
+ * "Noticing prompt" detector. Catches user messages that are asking
171
+ * about state ("are we using these?", "did you update X?", "where's
172
+ * the…?", "isn't Y supposed to be…?") rather than requesting new
173
+ * work. These signal that the user spotted a gap in the prior turn
174
+ * and wants the agent to address it — NOT continue the prior plan.
175
+ *
176
+ * Real failure mode captured 2026-05-25 on a Portfolio React refactor:
177
+ * user asked "I dont think we actually are using these new files are
178
+ * we?" after the agent wrote data files but never wired them into
179
+ * App.jsx. Bandit read the question as a generic "keep going" prompt,
180
+ * wrote 5 MORE new component files, still didn't touch App.jsx. The
181
+ * pivot signal was right there in the prompt shape and got missed.
182
+ *
183
+ * The check is conservative: short prompts only, must START with a
184
+ * recognizable question/concern stem (so "is X working?" matches but
185
+ * "is this the right approach to X" does not), no length cap above
186
+ * 220 chars since longer messages usually contain a real request
187
+ * rather than a pure noticing question.
188
+ */
189
+ export declare function isNoticingPrompt(text: string): boolean;
190
+ export interface ToolUseResult {
191
+ /** The model's final response (after all tool calls are resolved). */
192
+ finalResponse: string;
193
+ /** Number of tool call rounds executed. */
194
+ iterations: number;
195
+ /** All messages in the conversation including tool results. */
196
+ messages: ToolLoopMessage[];
197
+ /** Whether the loop ended due to reaching maxIterations. */
198
+ hitLimit: boolean;
199
+ /** Whether the loop terminated because options.signal was aborted. */
200
+ cancelled?: boolean;
201
+ }
202
+ export declare class ToolUseLoop {
203
+ private readonly registry;
204
+ private readonly ctx;
205
+ private readonly maxIterations;
206
+ private readonly defaultOptions;
207
+ private readonly defaultEmit;
208
+ private readonly defaultBeforeToolExecute;
209
+ constructor(registry: ToolRegistry, ctx: ToolExecutionContext, options?: ToolUseLoopOptions);
210
+ /**
211
+ * Run the tool use loop.
212
+ *
213
+ * @param userGoal The original user request (becomes the first user message).
214
+ * @param chat A streaming chat function — returns an async iterable of text chunks.
215
+ * @param systemPrompt Optional base system prompt. Tool definitions are appended to it.
216
+ * @param options Per-call options (emitEvent override, etc.)
217
+ */
218
+ run(userGoal: string, chat: ChatFn, systemPrompt?: string, options?: ToolUseLoopOptions): Promise<ToolUseResult>;
219
+ /**
220
+ * Run the tool use loop seeded with prior conversation messages.
221
+ * Use this for REPL-style hosts that want to preserve multi-turn context;
222
+ * the caller supplies the full user/assistant history (no system message —
223
+ * the loop prepends its own system prompt with tool definitions).
224
+ */
225
+ runWithMessages(seedMessages: ToolLoopMessage[], chat: ChatFn, systemPrompt?: string, options?: ToolUseLoopOptions): Promise<ToolUseResult>;
226
+ }
227
+ /**
228
+ * Convenience factory. Creates a loop with the given registry and context.
229
+ */
230
+ export declare function createToolUseLoop(registry: ToolRegistry, ctx: ToolExecutionContext, options?: ToolUseLoopOptions): ToolUseLoop;
231
+ //# sourceMappingURL=tool-use-loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-use-loop.d.ts","sourceRoot":"","sources":["../../src/tools/tool-use-loop.ts"],"names":[],"mappings":"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"}