byterover-cli 1.7.2 → 1.8.0

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 (66) hide show
  1. package/README.md +17 -3
  2. package/dist/agent/core/domain/tools/constants.d.ts +0 -15
  3. package/dist/agent/core/domain/tools/constants.js +0 -15
  4. package/dist/agent/core/interfaces/i-cipher-agent.d.ts +6 -0
  5. package/dist/agent/core/interfaces/i-curate-service.d.ts +12 -0
  6. package/dist/agent/infra/llm/internal-llm-service.d.ts +13 -0
  7. package/dist/agent/infra/llm/internal-llm-service.js +61 -21
  8. package/dist/agent/infra/tools/implementations/curate-tool.d.ts +133 -0
  9. package/dist/agent/infra/tools/implementations/curate-tool.js +14 -0
  10. package/dist/agent/infra/tools/implementations/search-knowledge-service.js +91 -14
  11. package/dist/agent/infra/tools/index.d.ts +0 -4
  12. package/dist/agent/infra/tools/index.js +0 -4
  13. package/dist/agent/infra/tools/tool-registry.js +0 -113
  14. package/dist/agent/resources/prompts/curate-detail-preservation.yml +73 -0
  15. package/dist/agent/resources/prompts/system-prompt.yml +69 -3
  16. package/dist/server/core/domain/knowledge/markdown-writer.d.ts +13 -0
  17. package/dist/server/core/domain/knowledge/markdown-writer.js +116 -8
  18. package/dist/server/infra/executor/curate-executor.js +1 -1
  19. package/dist/server/infra/executor/direct-search-responder.d.ts +45 -0
  20. package/dist/server/infra/executor/direct-search-responder.js +86 -0
  21. package/dist/server/infra/executor/folder-pack-executor.d.ts +13 -5
  22. package/dist/server/infra/executor/folder-pack-executor.js +739 -39
  23. package/dist/server/infra/executor/query-executor.d.ts +49 -3
  24. package/dist/server/infra/executor/query-executor.js +194 -9
  25. package/dist/server/infra/executor/query-result-cache.d.ts +87 -0
  26. package/dist/server/infra/executor/query-result-cache.js +127 -0
  27. package/dist/server/infra/executor/query-similarity.d.ts +28 -0
  28. package/dist/server/infra/executor/query-similarity.js +41 -0
  29. package/dist/server/infra/process/agent-worker.js +9 -2
  30. package/dist/server/infra/process/inline-agent-executor.js +16 -5
  31. package/dist/server/infra/usecase/curate-use-case.js +6 -1
  32. package/dist/server/infra/usecase/query-use-case.js +10 -0
  33. package/dist/server/utils/file-validator.js +78 -1
  34. package/dist/tui/hooks/use-slash-completion.js +25 -4
  35. package/oclif.manifest.json +1 -1
  36. package/package.json +1 -1
  37. package/dist/agent/infra/tools/implementations/bash-exec-tool.d.ts +0 -13
  38. package/dist/agent/infra/tools/implementations/bash-exec-tool.js +0 -110
  39. package/dist/agent/infra/tools/implementations/bash-output-tool.d.ts +0 -12
  40. package/dist/agent/infra/tools/implementations/bash-output-tool.js +0 -43
  41. package/dist/agent/infra/tools/implementations/batch-tool.d.ts +0 -12
  42. package/dist/agent/infra/tools/implementations/batch-tool.js +0 -142
  43. package/dist/agent/infra/tools/implementations/create-knowledge-topic-tool.d.ts +0 -11
  44. package/dist/agent/infra/tools/implementations/create-knowledge-topic-tool.js +0 -149
  45. package/dist/agent/infra/tools/implementations/delete-memory-tool.d.ts +0 -12
  46. package/dist/agent/infra/tools/implementations/delete-memory-tool.js +0 -37
  47. package/dist/agent/infra/tools/implementations/edit-file-tool.d.ts +0 -13
  48. package/dist/agent/infra/tools/implementations/edit-file-tool.js +0 -50
  49. package/dist/agent/infra/tools/implementations/edit-memory-tool.d.ts +0 -13
  50. package/dist/agent/infra/tools/implementations/edit-memory-tool.js +0 -53
  51. package/dist/agent/infra/tools/implementations/kill-process-tool.d.ts +0 -12
  52. package/dist/agent/infra/tools/implementations/kill-process-tool.js +0 -55
  53. package/dist/agent/infra/tools/implementations/list-memories-tool.d.ts +0 -12
  54. package/dist/agent/infra/tools/implementations/list-memories-tool.js +0 -63
  55. package/dist/agent/infra/tools/implementations/read-memory-tool.d.ts +0 -12
  56. package/dist/agent/infra/tools/implementations/read-memory-tool.js +0 -39
  57. package/dist/agent/infra/tools/implementations/read-todos-tool.d.ts +0 -11
  58. package/dist/agent/infra/tools/implementations/read-todos-tool.js +0 -39
  59. package/dist/agent/infra/tools/implementations/search-history-tool.d.ts +0 -10
  60. package/dist/agent/infra/tools/implementations/search-history-tool.js +0 -36
  61. package/dist/agent/infra/tools/implementations/spec-analyze-tool.d.ts +0 -7
  62. package/dist/agent/infra/tools/implementations/spec-analyze-tool.js +0 -78
  63. package/dist/agent/infra/tools/implementations/write-memory-tool.d.ts +0 -13
  64. package/dist/agent/infra/tools/implementations/write-memory-tool.js +0 -52
  65. package/dist/agent/infra/tools/implementations/write-todos-tool.d.ts +0 -13
  66. package/dist/agent/infra/tools/implementations/write-todos-tool.js +0 -121
@@ -47,7 +47,12 @@ export class CurateUseCase {
47
47
  }
48
48
  return;
49
49
  }
50
- const resolvedContent = context?.trim() ? context : '';
50
+ // Provide default context for folder packing when none is provided
51
+ const resolvedContent = context?.trim()
52
+ ? context
53
+ : hasFolders
54
+ ? 'Analyze this folder and extract all relevant knowledge, patterns, and documentation.'
55
+ : '';
51
56
  let client;
52
57
  try {
53
58
  client = await this.createClient({ headless, verbose });
@@ -371,6 +371,16 @@ export class QueryUseCase {
371
371
  if (payload.taskId === taskId && !completed) {
372
372
  completed = true;
373
373
  cleanup();
374
+ // Fallback: use payload.result when llmservice:response wasn't received
375
+ // (e.g., Tier 2 direct search responses that bypass the LLM)
376
+ if (!resultPrinted && payload.result) {
377
+ finalResult = payload.result;
378
+ resultPrinted = true;
379
+ if (format === 'text') {
380
+ this.terminal.log('\nResult:');
381
+ this.terminal.log(payload.result);
382
+ }
383
+ }
374
384
  if (format === 'json') {
375
385
  this.outputJsonResult({
376
386
  result: finalResult,
@@ -1,7 +1,74 @@
1
1
  import fs from 'node:fs';
2
2
  import os from 'node:os';
3
3
  import path from 'node:path';
4
- import { isBinaryFile, isImageFile, isPdfFile } from '../../agent/infra/file-system/binary-utils.js';
4
+ import { isBinaryFile, isImageFile, isOfficeFile, isPdfFile } from '../../agent/infra/file-system/binary-utils.js';
5
+ /**
6
+ * Known text file extensions that should always be treated as text,
7
+ * bypassing binary content inspection. This prevents false positives
8
+ * from files with unusual encodings (e.g., UTF-16) or embedded
9
+ * special characters (e.g., box-drawing characters in .md files).
10
+ */
11
+ const KNOWN_TEXT_EXTENSIONS = new Set([
12
+ '.adoc',
13
+ '.c',
14
+ '.cfg',
15
+ '.clj',
16
+ '.cmake',
17
+ '.conf',
18
+ '.cpp',
19
+ '.cs',
20
+ '.css',
21
+ '.csv',
22
+ '.dart',
23
+ '.dockerfile',
24
+ '.env',
25
+ '.erl',
26
+ '.ex',
27
+ '.go',
28
+ '.graphql',
29
+ '.groovy',
30
+ '.h',
31
+ '.hpp',
32
+ '.html',
33
+ '.ini',
34
+ '.java',
35
+ '.js',
36
+ '.json',
37
+ '.jsonc',
38
+ '.jsx',
39
+ '.kt',
40
+ '.less',
41
+ '.lua',
42
+ '.makefile',
43
+ '.markdown',
44
+ '.md',
45
+ '.php',
46
+ '.pl',
47
+ '.proto',
48
+ '.py',
49
+ '.r',
50
+ '.rb',
51
+ '.rs',
52
+ '.rst',
53
+ '.sass',
54
+ '.scala',
55
+ '.scss',
56
+ '.sh',
57
+ '.sql',
58
+ '.svelte',
59
+ '.svg',
60
+ '.swift',
61
+ '.tf',
62
+ '.toml',
63
+ '.ts',
64
+ '.tsx',
65
+ '.txt',
66
+ '.vue',
67
+ '.xml',
68
+ '.yaml',
69
+ '.yml',
70
+ '.zsh',
71
+ ]);
5
72
  /**
6
73
  * Normalize file path - handles relative, absolute, tilde, symlinks
7
74
  * Returns absolute canonical path
@@ -65,6 +132,12 @@ export function validateFileForCurate(filePath, projectRoot) {
65
132
  return { error: `Cannot read file: ${filePath}`, valid: false };
66
133
  }
67
134
  const sampleBuffer = buffer.subarray(0, bytesRead);
135
+ const ext = path.extname(normalized).toLowerCase();
136
+ // Fast path: known text extensions bypass binary content inspection.
137
+ // This prevents false positives from files with unusual encodings (e.g., UTF-16 .md files)
138
+ if (KNOWN_TEXT_EXTENSIONS.has(ext)) {
139
+ return { normalizedPath: normalized, valid: true };
140
+ }
68
141
  // Check file type using binary-utils (same logic as read_file tool)
69
142
  // Allow image files - read_file returns them as base64 attachments
70
143
  if (isImageFile(normalized)) {
@@ -75,6 +148,10 @@ export function validateFileForCurate(filePath, projectRoot) {
75
148
  if (isPdfFile(normalized, sampleBuffer)) {
76
149
  return { normalizedPath: normalized, valid: true };
77
150
  }
151
+ // Allow Office documents - FileContentReader can parse these for text extraction
152
+ if (isOfficeFile(normalized)) {
153
+ return { normalizedPath: normalized, valid: true };
154
+ }
78
155
  // Check if it's a binary file (using same logic as read_file tool)
79
156
  if (isBinaryFile(normalized, sampleBuffer)) {
80
157
  return { error: `File type not supported: ${filePath}`, valid: false };
@@ -9,6 +9,20 @@ import { useCommands } from '../contexts/commands-context.js';
9
9
  function generateFileSuggestions(searchPattern) {
10
10
  try {
11
11
  const cwd = process.cwd();
12
+ const suggestions = [];
13
+ // Special case: Always suggest ./ as the first option when appropriate
14
+ // This allows users to curate the entire current directory
15
+ const normalizedPattern = searchPattern.toLowerCase();
16
+ const shouldShowCurrentDir = !searchPattern || // Just typed @
17
+ normalizedPattern === '.' || // Typing @.
18
+ './'.startsWith(normalizedPattern); // Typing @. (partial match)
19
+ if (shouldShowCurrentDir) {
20
+ suggestions.push({
21
+ description: 'Current directory (will pack all contents)',
22
+ label: './',
23
+ value: '@./',
24
+ });
25
+ }
12
26
  // If pattern ends with /, list contents of that directory
13
27
  let searchDir;
14
28
  let searchPrefix;
@@ -23,10 +37,9 @@ function generateFileSuggestions(searchPattern) {
23
37
  const fullSearchDir = path.resolve(cwd, searchDir);
24
38
  // Check if search directory exists and is within cwd
25
39
  if (!fs.existsSync(fullSearchDir) || !fullSearchDir.startsWith(cwd)) {
26
- return [];
40
+ return suggestions;
27
41
  }
28
42
  const entries = fs.readdirSync(fullSearchDir, { withFileTypes: true });
29
- const suggestions = [];
30
43
  for (const entry of entries) {
31
44
  // Skip hidden files
32
45
  if (entry.name.startsWith('.'))
@@ -43,14 +56,22 @@ function generateFileSuggestions(searchPattern) {
43
56
  }
44
57
  }
45
58
  // Sort: directories first, then alphabetically
46
- suggestions.sort((a, b) => {
59
+ // Note: ./ is already at the front, so we sort from index 1
60
+ const hasCurrentDir = suggestions[0]?.label === './';
61
+ const startIndex = hasCurrentDir ? 1 : 0;
62
+ const toSort = suggestions.slice(startIndex);
63
+ toSort.sort((a, b) => {
47
64
  const aIsDir = a.label.endsWith('/');
48
65
  const bIsDir = b.label.endsWith('/');
49
66
  if (aIsDir !== bIsDir)
50
67
  return aIsDir ? -1 : 1;
51
68
  return a.label.localeCompare(b.label);
52
69
  });
53
- return suggestions.slice(0, 20); // Limit to 20 suggestions
70
+ // Recombine: ./ stays at front, rest are sorted
71
+ const finalSuggestions = hasCurrentDir
72
+ ? [suggestions[0], ...toSort]
73
+ : toSort;
74
+ return finalSuggestions.slice(0, 20); // Limit to 20 suggestions
54
75
  }
55
76
  catch {
56
77
  return [];
@@ -499,5 +499,5 @@
499
499
  ]
500
500
  }
501
501
  },
502
- "version": "1.7.2"
502
+ "version": "1.8.0"
503
503
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "byterover-cli",
3
3
  "description": "ByteRover's CLI",
4
- "version": "1.7.2",
4
+ "version": "1.8.0",
5
5
  "author": "ByteRover",
6
6
  "bin": {
7
7
  "brv": "./bin/run.js"
@@ -1,13 +0,0 @@
1
- import type { Tool } from '../../../core/domain/tools/types.js';
2
- import type { IProcessService } from '../../../core/interfaces/i-process-service.js';
3
- /**
4
- * Create bash_exec tool.
5
- *
6
- * Executes shell commands with security validation and approval for dangerous commands.
7
- * Supports both foreground (wait for completion) and background (return immediately) execution.
8
- * When a metadata callback is provided, streams output updates in real-time.
9
- *
10
- * @param processService - Process service for command execution
11
- * @returns bash_exec tool instance
12
- */
13
- export declare function createBashExecTool(processService: IProcessService): Tool;
@@ -1,110 +0,0 @@
1
- import { z } from 'zod';
2
- import { ToolName } from '../../../core/domain/tools/constants.js';
3
- /**
4
- * Input schema for bash_exec tool.
5
- */
6
- const BashExecInputSchema = z
7
- .object({
8
- /**
9
- * Shell command to execute.
10
- */
11
- command: z.string().describe('Shell command to execute'),
12
- /**
13
- * Working directory for command execution (relative to configured base directory).
14
- */
15
- cwd: z.string().optional().describe('Working directory for command execution'),
16
- /**
17
- * Human-readable description of what the command does (5-10 words).
18
- */
19
- description: z.string().optional().describe('Description of what the command does (5-10 words)'),
20
- /**
21
- * Execute command in background (returns immediately with process handle).
22
- */
23
- runInBackground: z
24
- .boolean()
25
- .optional()
26
- .default(false)
27
- .describe('Execute command in background'),
28
- /**
29
- * Timeout in milliseconds (max: 600000, default: 300000 = 5 minutes).
30
- */
31
- timeout: z
32
- .number()
33
- .int()
34
- .positive()
35
- .max(600_000)
36
- .optional()
37
- .default(300_000)
38
- .describe('Timeout in milliseconds (default: 5 minutes)'),
39
- })
40
- .strict();
41
- /**
42
- * Create bash_exec tool.
43
- *
44
- * Executes shell commands with security validation and approval for dangerous commands.
45
- * Supports both foreground (wait for completion) and background (return immediately) execution.
46
- * When a metadata callback is provided, streams output updates in real-time.
47
- *
48
- * @param processService - Process service for command execution
49
- * @returns bash_exec tool instance
50
- */
51
- export function createBashExecTool(processService) {
52
- return {
53
- description: `Execute a shell command and return its output.`,
54
- async execute(input, context) {
55
- const { command, cwd, description, runInBackground, timeout } = input;
56
- // Stream initial status via metadata callback if available
57
- if (context?.metadata) {
58
- context.metadata({
59
- description: description ?? `Executing: ${command.slice(0, 50)}${command.length > 50 ? '...' : ''}`,
60
- output: '',
61
- progress: 0,
62
- });
63
- }
64
- // Execute command via process service
65
- const result = await processService.executeCommand(command, {
66
- cwd,
67
- description,
68
- runInBackground,
69
- timeout,
70
- });
71
- // Return based on execution mode
72
- if ('stdout' in result) {
73
- // Stream final output via metadata callback if available
74
- if (context?.metadata) {
75
- context.metadata({
76
- description: description ?? 'Command completed',
77
- output: result.stdout + (result.stderr ? `\n[stderr]\n${result.stderr}` : ''),
78
- progress: 100,
79
- });
80
- }
81
- // Foreground execution result
82
- return {
83
- duration: result.duration,
84
- exitCode: result.exitCode,
85
- stderr: result.stderr,
86
- stdout: result.stdout,
87
- };
88
- }
89
- // Stream background process info via metadata callback if available
90
- if (context?.metadata) {
91
- context.metadata({
92
- description: `Background process started: ${result.processId}`,
93
- output: `Process started with PID ${result.pid}`,
94
- progress: 100,
95
- });
96
- }
97
- // Background execution handle
98
- return {
99
- command: result.command,
100
- description: result.description,
101
- message: `Process started in background. Use bash_output with processId="${result.processId}" to retrieve output.`,
102
- pid: result.pid,
103
- processId: result.processId,
104
- startedAt: result.startedAt.toISOString(),
105
- };
106
- },
107
- id: ToolName.BASH_EXEC,
108
- inputSchema: BashExecInputSchema,
109
- };
110
- }
@@ -1,12 +0,0 @@
1
- import type { Tool } from '../../../core/domain/tools/types.js';
2
- import type { IProcessService } from '../../../core/interfaces/i-process-service.js';
3
- /**
4
- * Create bash_output tool.
5
- *
6
- * Retrieves output from a background process started by bash_exec.
7
- * Reading output clears the buffer (destructive read), so output is only returned once.
8
- *
9
- * @param processService - Process service for retrieving output
10
- * @returns bash_output tool instance
11
- */
12
- export declare function createBashOutputTool(processService: IProcessService): Tool;
@@ -1,43 +0,0 @@
1
- import { z } from 'zod';
2
- import { ToolName } from '../../../core/domain/tools/constants.js';
3
- /**
4
- * Input schema for bash_output tool.
5
- */
6
- const BashOutputInputSchema = z
7
- .object({
8
- /**
9
- * Unique process identifier from bash_exec.
10
- */
11
- processId: z.string().describe('Unique process identifier from bash_exec'),
12
- })
13
- .strict();
14
- /**
15
- * Create bash_output tool.
16
- *
17
- * Retrieves output from a background process started by bash_exec.
18
- * Reading output clears the buffer (destructive read), so output is only returned once.
19
- *
20
- * @param processService - Process service for retrieving output
21
- * @returns bash_output tool instance
22
- */
23
- export function createBashOutputTool(processService) {
24
- return {
25
- description: `Retrieve output from a background process started by bash_exec.`,
26
- async execute(input, _context) {
27
- const { processId } = input;
28
- // Get output from process service
29
- const output = await processService.getProcessOutput(processId);
30
- // Return output with status
31
- return {
32
- duration: output.duration,
33
- exitCode: output.exitCode,
34
- processId,
35
- status: output.status,
36
- stderr: output.stderr,
37
- stdout: output.stdout,
38
- };
39
- },
40
- id: ToolName.BASH_OUTPUT,
41
- inputSchema: BashOutputInputSchema,
42
- };
43
- }
@@ -1,12 +0,0 @@
1
- import type { Tool } from '../../../core/domain/tools/types.js';
2
- import type { ToolProviderGetter } from '../tool-provider-getter.js';
3
- /**
4
- * Create batch tool.
5
- *
6
- * Executes multiple independent tool calls concurrently to reduce latency.
7
- * Best used for gathering context (reads, searches, listings).
8
- *
9
- * @param getToolProvider - Lazy getter for tool provider (avoids circular dependency)
10
- * @returns batch tool instance
11
- */
12
- export declare function createBatchTool(getToolProvider: ToolProviderGetter): Tool;
@@ -1,142 +0,0 @@
1
- import { z } from 'zod';
2
- import { ToolName } from '../../../core/domain/tools/constants.js';
3
- /**
4
- * Tools that are not allowed in batch execution.
5
- * - batch: No nesting of batch calls
6
- * - edit_file: Sequential edits for proper conflict handling
7
- * - write_todos: Lightweight, call directly
8
- */
9
- const DISALLOWED_TOOLS = new Set(['batch', 'edit_file', 'write_todos']);
10
- /**
11
- * Maximum number of tool calls allowed in a single batch.
12
- */
13
- const MAX_BATCH_SIZE = 10;
14
- /**
15
- * Input schema for batch tool.
16
- */
17
- const BatchInputSchema = z
18
- .object({
19
- /**
20
- * Array of tool calls to execute in parallel.
21
- */
22
- toolCalls: z
23
- .array(z.object({
24
- /**
25
- * Parameters for the tool.
26
- */
27
- parameters: z.record(z.unknown()).describe('Parameters for the tool'),
28
- /**
29
- * The name of the tool to execute.
30
- */
31
- tool: z.string().describe('The name of the tool to execute'),
32
- }))
33
- .min(1, 'Provide at least one tool call')
34
- .describe('Array of tool calls to execute in parallel'),
35
- })
36
- .strict();
37
- /**
38
- * Create batch tool.
39
- *
40
- * Executes multiple independent tool calls concurrently to reduce latency.
41
- * Best used for gathering context (reads, searches, listings).
42
- *
43
- * @param getToolProvider - Lazy getter for tool provider (avoids circular dependency)
44
- * @returns batch tool instance
45
- */
46
- export function createBatchTool(getToolProvider) {
47
- return {
48
- description: 'Execute multiple independent tool calls concurrently.',
49
- async execute(input, context) {
50
- const { toolCalls } = input;
51
- const toolProvider = getToolProvider();
52
- // Limit to MAX_BATCH_SIZE
53
- const activeCalls = toolCalls.slice(0, MAX_BATCH_SIZE);
54
- const discardedCalls = toolCalls.slice(MAX_BATCH_SIZE);
55
- /**
56
- * Execute a single tool call and return the result.
57
- */
58
- const executeCall = async (call) => {
59
- const startTime = Date.now();
60
- // Check if tool is disallowed in batch
61
- if (DISALLOWED_TOOLS.has(call.tool)) {
62
- return {
63
- durationMs: Date.now() - startTime,
64
- error: `Tool '${call.tool}' is not allowed in batch. Disallowed tools: ${[...DISALLOWED_TOOLS].join(', ')}`,
65
- success: false,
66
- tool: call.tool,
67
- };
68
- }
69
- // Check if tool exists
70
- if (!toolProvider.hasTool(call.tool)) {
71
- const availableTools = toolProvider.getToolNames().filter((name) => !DISALLOWED_TOOLS.has(name));
72
- return {
73
- durationMs: Date.now() - startTime,
74
- error: `Tool '${call.tool}' not found. Available tools: ${availableTools.join(', ')}`,
75
- success: false,
76
- tool: call.tool,
77
- };
78
- }
79
- try {
80
- const result = await toolProvider.executeTool(call.tool, call.parameters, context?.sessionId, context);
81
- return {
82
- durationMs: Date.now() - startTime,
83
- result,
84
- success: true,
85
- tool: call.tool,
86
- };
87
- }
88
- catch (error) {
89
- return {
90
- durationMs: Date.now() - startTime,
91
- error: error instanceof Error ? error.message : String(error),
92
- success: false,
93
- tool: call.tool,
94
- };
95
- }
96
- };
97
- // Execute all calls in parallel
98
- const results = await Promise.all(activeCalls.map((call) => executeCall(call)));
99
- // Add discarded calls as errors
100
- for (const call of discardedCalls) {
101
- results.push({
102
- durationMs: 0,
103
- error: `Maximum of ${MAX_BATCH_SIZE} tools allowed in batch`,
104
- success: false,
105
- tool: call.tool,
106
- });
107
- }
108
- const successful = results.filter((r) => r.success).length;
109
- const failed = results.length - successful;
110
- // Stream progress update
111
- if (context?.metadata) {
112
- context.metadata({
113
- description: 'Batch execution complete',
114
- output: `${successful}/${results.length} tools executed successfully`,
115
- progress: 100,
116
- });
117
- }
118
- // Build output message
119
- const outputMessage = failed > 0
120
- ? `Executed ${successful}/${results.length} tools successfully. ${failed} failed.`
121
- : `All ${successful} tools executed successfully.\n\nKeep using the batch tool for optimal performance!`;
122
- return {
123
- metadata: {
124
- details: results.map((r) => ({ success: r.success, tool: r.tool })),
125
- failed,
126
- successful,
127
- tools: toolCalls.map((c) => c.tool),
128
- totalCalls: results.length,
129
- },
130
- results: results.map((r) => ({
131
- durationMs: r.durationMs,
132
- success: r.success,
133
- tool: r.tool,
134
- ...(r.success ? { result: r.result } : { error: r.error }),
135
- })),
136
- summary: outputMessage,
137
- };
138
- },
139
- id: ToolName.BATCH,
140
- inputSchema: BatchInputSchema,
141
- };
142
- }
@@ -1,11 +0,0 @@
1
- import type { Tool } from '../../../core/domain/tools/types.js';
2
- /**
3
- * Creates the create knowledge topic tool.
4
- *
5
- * Creates organized knowledge topics within domain folders, where each topic and subtopic
6
- * has its own folder containing a context.md file with relevant snippets. This tool should
7
- * be used after detecting domains to organize the extracted knowledge into a structured hierarchy.
8
- *
9
- * @returns Configured create knowledge topic tool
10
- */
11
- export declare function createCreateKnowledgeTopicTool(): Tool;