agentool 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -21
- package/dist/ask-user/index.cjs +5 -2
- package/dist/ask-user/index.d.cts +10 -1
- package/dist/ask-user/index.d.ts +10 -1
- package/dist/ask-user/index.js +5 -2
- package/dist/bash/index.cjs +5 -2
- package/dist/bash/index.d.cts +14 -1
- package/dist/bash/index.d.ts +14 -1
- package/dist/bash/index.js +5 -2
- package/dist/chunk-2JBLVFB7.cjs +74 -0
- package/dist/{chunk-K77GC2QI.js → chunk-2JF3ZF2J.js} +32 -2
- package/dist/{chunk-XKG2A3EW.js → chunk-2WSZCOJP.js} +54 -18
- package/dist/chunk-3FT4ZPB2.cjs +65 -0
- package/dist/{chunk-VLNDEVKS.js → chunk-3LGXZLBH.js} +46 -8
- package/dist/{chunk-G3ITTPGX.js → chunk-4MXDQEPA.js} +12 -1
- package/dist/{chunk-CGTPF6IS.js → chunk-4UUSERSH.js} +31 -7
- package/dist/{chunk-I6KFFQPV.cjs → chunk-5T3SQYI4.cjs} +34 -4
- package/dist/chunk-6ULQG2W2.cjs +99 -0
- package/dist/chunk-ABXTBB2N.cjs +67 -0
- package/dist/{chunk-CAEVLIQB.cjs → chunk-BIAODQ2P.cjs} +17 -1
- package/dist/chunk-CJA76MKM.js +59 -0
- package/dist/chunk-CM3VRCNX.cjs +59 -0
- package/dist/{chunk-SUSAPI5W.cjs → chunk-CXBWF5ON.cjs} +51 -4
- package/dist/{chunk-U2YMJM25.cjs → chunk-G6ZVJA4V.cjs} +31 -8
- package/dist/chunk-GPHCXS2S.js +99 -0
- package/dist/chunk-HG5T47NA.cjs +77 -0
- package/dist/chunk-HO4NIRU5.js +65 -0
- package/dist/{chunk-HZAQRHBT.js → chunk-IBC4QCGR.js} +27 -2
- package/dist/chunk-JYTOARJV.cjs +69 -0
- package/dist/chunk-KONXT2SF.cjs +8 -0
- package/dist/chunk-KUFZFNPT.cjs +61 -0
- package/dist/chunk-L7R4UZSK.js +61 -0
- package/dist/{chunk-FV2R5FFQ.cjs → chunk-LNAR3NJQ.cjs} +47 -9
- package/dist/chunk-M74OQYNK.js +69 -0
- package/dist/{chunk-IMZQ7ELK.cjs → chunk-NQIV6LBH.cjs} +51 -14
- package/dist/chunk-NTGDU5X3.js +67 -0
- package/dist/{chunk-ONBH74ZV.cjs → chunk-OYLTQJXT.cjs} +32 -8
- package/dist/{chunk-6PQLFDGT.js → chunk-PWBVB6MN.js} +17 -1
- package/dist/{chunk-QEJV2KZ4.cjs → chunk-RIGL3JTS.cjs} +55 -19
- package/dist/chunk-SFDZRLSX.cjs +91 -0
- package/dist/chunk-T6STO7PS.cjs +126 -0
- package/dist/{chunk-LPV5CN2K.js → chunk-TI4ZZ3IJ.js} +32 -2
- package/dist/chunk-TM5L4HA5.js +126 -0
- package/dist/{chunk-4YI2H55A.js → chunk-TXZ3BMMR.js} +49 -2
- package/dist/chunk-UCA6LURO.js +74 -0
- package/dist/{chunk-EA3YV7ZG.js → chunk-VE4U27HI.js} +35 -15
- package/dist/chunk-VHLY7LQE.js +53 -0
- package/dist/{chunk-FW3UJ622.cjs → chunk-VPRUYL4T.cjs} +34 -4
- package/dist/{chunk-3VO6NETR.cjs → chunk-VPV6WG5V.cjs} +41 -21
- package/dist/chunk-VQSWMGG7.cjs +53 -0
- package/dist/{chunk-Y7KOKDFP.js → chunk-VZRXTFS4.js} +29 -6
- package/dist/chunk-WCR62UZ3.js +67 -0
- package/dist/chunk-X6ZY2KFU.js +8 -0
- package/dist/chunk-XGDE7S2D.cjs +67 -0
- package/dist/chunk-XPTW45XY.js +77 -0
- package/dist/{chunk-YPPPGGLA.cjs → chunk-YCWJVQYO.cjs} +28 -3
- package/dist/chunk-YGXLT6SS.js +91 -0
- package/dist/{chunk-5NW4OGRI.cjs → chunk-YTPZHJDC.cjs} +12 -1
- package/dist/{chunk-6MDPYALY.js → chunk-ZHVRP3EH.js} +49 -12
- package/dist/context-compaction/index.cjs +5 -2
- package/dist/context-compaction/index.d.cts +11 -1
- package/dist/context-compaction/index.d.ts +11 -1
- package/dist/context-compaction/index.js +5 -2
- package/dist/diff/index.cjs +6 -2
- package/dist/diff/index.d.cts +12 -2
- package/dist/diff/index.d.ts +12 -2
- package/dist/diff/index.js +7 -3
- package/dist/edit/index.cjs +7 -3
- package/dist/edit/index.d.cts +15 -5
- package/dist/edit/index.d.ts +15 -5
- package/dist/edit/index.js +8 -4
- package/dist/glob/index.cjs +5 -2
- package/dist/glob/index.d.cts +13 -3
- package/dist/glob/index.d.ts +13 -3
- package/dist/glob/index.js +5 -2
- package/dist/grep/index.cjs +6 -2
- package/dist/grep/index.d.cts +13 -3
- package/dist/grep/index.d.ts +13 -3
- package/dist/grep/index.js +6 -2
- package/dist/http-request/index.cjs +5 -2
- package/dist/http-request/index.d.cts +11 -1
- package/dist/http-request/index.d.ts +11 -1
- package/dist/http-request/index.js +5 -2
- package/dist/index.cjs +93 -19
- package/dist/index.d.cts +21 -16
- package/dist/index.d.ts +21 -16
- package/dist/index.js +113 -39
- package/dist/lsp/index.cjs +6 -2
- package/dist/lsp/index.d.cts +16 -10
- package/dist/lsp/index.d.ts +16 -10
- package/dist/lsp/index.js +6 -2
- package/dist/memory/index.cjs +6 -2
- package/dist/memory/index.d.cts +10 -1
- package/dist/memory/index.d.ts +10 -1
- package/dist/memory/index.js +6 -2
- package/dist/multi-edit/index.cjs +7 -4
- package/dist/multi-edit/index.d.cts +12 -2
- package/dist/multi-edit/index.d.ts +12 -2
- package/dist/multi-edit/index.js +7 -4
- package/dist/read/index.cjs +6 -3
- package/dist/read/index.d.cts +11 -1
- package/dist/read/index.d.ts +11 -1
- package/dist/read/index.js +6 -3
- package/dist/sleep/index.cjs +5 -2
- package/dist/sleep/index.d.cts +11 -1
- package/dist/sleep/index.d.ts +11 -1
- package/dist/sleep/index.js +5 -2
- package/dist/task-create/index.cjs +13 -0
- package/dist/task-create/index.d.cts +28 -0
- package/dist/task-create/index.d.ts +28 -0
- package/dist/task-create/index.js +13 -0
- package/dist/task-get/index.cjs +13 -0
- package/dist/task-get/index.d.cts +24 -0
- package/dist/task-get/index.d.ts +24 -0
- package/dist/task-get/index.js +13 -0
- package/dist/task-list/index.cjs +13 -0
- package/dist/task-list/index.d.cts +20 -0
- package/dist/task-list/index.d.ts +20 -0
- package/dist/task-list/index.js +13 -0
- package/dist/task-update/index.cjs +13 -0
- package/dist/task-update/index.d.cts +40 -0
- package/dist/task-update/index.d.ts +40 -0
- package/dist/task-update/index.js +13 -0
- package/dist/tool-search/index.cjs +11 -0
- package/dist/tool-search/index.d.cts +27 -0
- package/dist/tool-search/index.d.ts +27 -0
- package/dist/tool-search/index.js +11 -0
- package/dist/web-fetch/index.cjs +5 -2
- package/dist/web-fetch/index.d.cts +11 -3
- package/dist/web-fetch/index.d.ts +11 -3
- package/dist/web-fetch/index.js +5 -2
- package/dist/web-search/index.cjs +11 -0
- package/dist/web-search/index.d.cts +30 -0
- package/dist/web-search/index.d.ts +30 -0
- package/dist/web-search/index.js +11 -0
- package/dist/write/index.cjs +6 -3
- package/dist/write/index.d.cts +13 -3
- package/dist/write/index.d.ts +13 -3
- package/dist/write/index.js +6 -3
- package/package.json +31 -6
- package/dist/chunk-3EPGFWZV.cjs +0 -30
- package/dist/chunk-7QL4BQCH.js +0 -40
- package/dist/chunk-FAEGCFTO.js +0 -136
- package/dist/chunk-HDKXSKMO.js +0 -30
- package/dist/chunk-JCTBB7H2.cjs +0 -40
- package/dist/chunk-MF7CJVIZ.js +0 -40
- package/dist/chunk-MXFW3XY6.cjs +0 -73
- package/dist/chunk-OXLQ7QVL.cjs +0 -40
- package/dist/chunk-S6QEY7UY.js +0 -73
- package/dist/chunk-TBVHHF3H.cjs +0 -47
- package/dist/chunk-XLD2Y3SS.cjs +0 -136
- package/dist/chunk-ZHCMEQJJ.js +0 -47
- package/dist/task/index.cjs +0 -8
- package/dist/task/index.d.cts +0 -67
- package/dist/task/index.d.ts +0 -67
- package/dist/task/index.js +0 -8
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
var _chunkKONXT2SFcjs = require('./chunk-KONXT2SF.cjs');
|
|
4
|
+
|
|
5
|
+
// src/bash/index.ts
|
|
2
6
|
var _ai = require('ai');
|
|
3
7
|
var _zod = require('zod');
|
|
4
8
|
|
|
@@ -103,12 +107,54 @@ async function executeShell(command, options) {
|
|
|
103
107
|
});
|
|
104
108
|
}
|
|
105
109
|
|
|
110
|
+
// src/bash/prompt.ts
|
|
111
|
+
function getPrompt(config = {}) {
|
|
112
|
+
const timeout = _nullishCoalesce(config.timeout, () => ( 12e4));
|
|
113
|
+
const timeoutMin = timeout / 6e4;
|
|
114
|
+
const shell = _nullishCoalesce(config.shell, () => ( "$SHELL or /bin/bash"));
|
|
115
|
+
return `Execute a shell command and return its output (stdout, stderr, exit code).
|
|
116
|
+
|
|
117
|
+
Runs the command in ${shell} with \`-c\`. The working directory persists between calls.
|
|
118
|
+
|
|
119
|
+
## When to Use
|
|
120
|
+
- Build commands, git operations, system administration, installing packages
|
|
121
|
+
- Running scripts, compiling code, process management
|
|
122
|
+
- Any shell task that doesn't have a dedicated tool available
|
|
123
|
+
|
|
124
|
+
## When NOT to Use
|
|
125
|
+
- Reading file contents \u2014 use the dedicated file reading tool instead
|
|
126
|
+
- Searching file contents \u2014 use the dedicated content search tool instead
|
|
127
|
+
- Finding files by name/pattern \u2014 use the dedicated file search tool instead
|
|
128
|
+
- Editing files \u2014 use the dedicated file editing tool instead
|
|
129
|
+
- Writing new files \u2014 use the dedicated file writing tool instead
|
|
130
|
+
Prefer dedicated tools over shell equivalents (e.g., don't use cat, head, tail, sed, awk, grep, find, or echo when a dedicated tool exists). Dedicated tools provide better output formatting and permission handling.
|
|
131
|
+
|
|
132
|
+
## Usage Guidelines
|
|
133
|
+
- Default timeout: ${timeout}ms (${timeoutMin} minutes). Override with the timeout parameter.
|
|
134
|
+
- Timeout escalation: SIGTERM first, then SIGKILL after 5-second grace period.
|
|
135
|
+
- Output is capped at 10 MB per stream (stdout/stderr).
|
|
136
|
+
- Always quote file paths containing spaces with double quotes.
|
|
137
|
+
- When issuing multiple commands:
|
|
138
|
+
- Independent commands: make separate tool calls in parallel.
|
|
139
|
+
- Sequential with dependency: chain with \`&&\`.
|
|
140
|
+
- Sequential ignoring failures: chain with \`;\`.
|
|
141
|
+
- Do NOT use newlines to separate commands.
|
|
142
|
+
- Avoid unnecessary \`sleep\` commands:
|
|
143
|
+
- Don't sleep between commands that can run immediately.
|
|
144
|
+
- Don't retry failing commands in a sleep loop \u2014 diagnose the root cause.
|
|
145
|
+
- If you must sleep, keep it short (1-5 seconds).
|
|
146
|
+
- For git commands:
|
|
147
|
+
- Prefer creating new commits rather than amending existing ones.
|
|
148
|
+
- Never skip hooks (--no-verify) unless the user explicitly requests it.
|
|
149
|
+
- Before destructive operations (reset --hard, push --force), consider safer alternatives.`;
|
|
150
|
+
}
|
|
151
|
+
|
|
106
152
|
// src/bash/index.ts
|
|
107
153
|
function createBash(config = {}) {
|
|
108
154
|
const cwd = _nullishCoalesce(config.cwd, () => ( process.cwd()));
|
|
109
155
|
const timeout = _nullishCoalesce(config.timeout, () => ( 12e4));
|
|
110
156
|
return _ai.tool.call(void 0, {
|
|
111
|
-
description:
|
|
157
|
+
description: _nullishCoalesce(config.description, () => ( getPrompt(config))),
|
|
112
158
|
inputSchema: _zod.z.object({
|
|
113
159
|
command: _zod.z.string().describe("The shell command to execute"),
|
|
114
160
|
timeout: _zod.z.number().optional().describe("Timeout in milliseconds (default: 120000)"),
|
|
@@ -128,7 +174,7 @@ ${result.stderr}`);
|
|
|
128
174
|
if (result.exitCode !== 0) parts.push(`Exit code: ${result.exitCode}`);
|
|
129
175
|
return parts.length > 0 ? parts.join("\n") : `Command completed with exit code ${result.exitCode}`;
|
|
130
176
|
} catch (error) {
|
|
131
|
-
const msg =
|
|
177
|
+
const msg = _chunkKONXT2SFcjs.extractErrorMessage.call(void 0, error);
|
|
132
178
|
return `Error [bash]: Failed to execute command: ${msg}`;
|
|
133
179
|
}
|
|
134
180
|
}
|
|
@@ -139,4 +185,5 @@ var bash = createBash();
|
|
|
139
185
|
|
|
140
186
|
|
|
141
187
|
|
|
142
|
-
|
|
188
|
+
|
|
189
|
+
exports.getPrompt = getPrompt; exports.createBash = createBash; exports.bash = bash;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
var _chunkKONXT2SFcjs = require('./chunk-KONXT2SF.cjs');
|
|
4
|
+
|
|
5
|
+
// src/web-fetch/index.ts
|
|
2
6
|
var _ai = require('ai');
|
|
3
7
|
var _zod = require('zod');
|
|
4
8
|
|
|
@@ -73,15 +77,33 @@ async function fetchUrl(url, options) {
|
|
|
73
77
|
};
|
|
74
78
|
}
|
|
75
79
|
|
|
80
|
+
// src/web-fetch/prompt.ts
|
|
81
|
+
function getPrompt(config = {}) {
|
|
82
|
+
const timeout = _nullishCoalesce(config.timeout, () => ( 3e4));
|
|
83
|
+
return `Fetch a URL and return its content. HTML pages are automatically converted to markdown for easier reading. JSON and other text content is returned as-is.
|
|
84
|
+
|
|
85
|
+
## When to Use
|
|
86
|
+
- To retrieve and read web page content, documentation, or articles
|
|
87
|
+
- To fetch API responses, JSON data, or raw text from URLs
|
|
88
|
+
- To check what a web page contains
|
|
89
|
+
|
|
90
|
+
## When NOT to Use
|
|
91
|
+
- For API interactions that need custom HTTP methods (POST, PUT, DELETE) \u2014 use the dedicated HTTP request tool instead
|
|
92
|
+
- For searching the web \u2014 use the dedicated web search tool instead
|
|
93
|
+
|
|
94
|
+
## Usage Guidelines
|
|
95
|
+
- Content is truncated at 100,000 characters to manage context size
|
|
96
|
+
- The URL must be a fully-formed valid URL (e.g., https://example.com)
|
|
97
|
+
- Timeout: ${timeout}ms
|
|
98
|
+
- This tool is read-only \u2014 it does not modify any files or state`;
|
|
99
|
+
}
|
|
100
|
+
|
|
76
101
|
// src/web-fetch/index.ts
|
|
77
102
|
function createWebFetch(config = {}) {
|
|
78
103
|
return _ai.tool.call(void 0, {
|
|
79
|
-
description:
|
|
104
|
+
description: _nullishCoalesce(config.description, () => ( getPrompt(config))),
|
|
80
105
|
inputSchema: _zod.z.object({
|
|
81
|
-
url: _zod.z.string().describe("The URL to fetch")
|
|
82
|
-
prompt: _zod.z.string().optional().describe(
|
|
83
|
-
"Optional context about what to extract from the page"
|
|
84
|
-
)
|
|
106
|
+
url: _zod.z.string().url().describe("The URL to fetch")
|
|
85
107
|
}),
|
|
86
108
|
execute: async ({ url }) => {
|
|
87
109
|
try {
|
|
@@ -101,7 +123,7 @@ function createWebFetch(config = {}) {
|
|
|
101
123
|
parts.push(result.content);
|
|
102
124
|
return parts.join("\n");
|
|
103
125
|
} catch (error) {
|
|
104
|
-
const msg =
|
|
126
|
+
const msg = _chunkKONXT2SFcjs.extractErrorMessage.call(void 0, error);
|
|
105
127
|
return `Error [web-fetch]: Failed to fetch ${url}: ${msg}`;
|
|
106
128
|
}
|
|
107
129
|
}
|
|
@@ -112,4 +134,5 @@ var webFetch = createWebFetch();
|
|
|
112
134
|
|
|
113
135
|
|
|
114
136
|
|
|
115
|
-
|
|
137
|
+
|
|
138
|
+
exports.getPrompt = getPrompt; exports.createWebFetch = createWebFetch; exports.webFetch = webFetch;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import {
|
|
2
|
+
applyEditToFile,
|
|
3
|
+
countOccurrences,
|
|
4
|
+
findActualString,
|
|
5
|
+
preserveQuoteStyle
|
|
6
|
+
} from "./chunk-4MXDQEPA.js";
|
|
7
|
+
import {
|
|
8
|
+
readTextContent,
|
|
9
|
+
writeTextContent
|
|
10
|
+
} from "./chunk-PWBVB6MN.js";
|
|
11
|
+
import {
|
|
12
|
+
expandPath
|
|
13
|
+
} from "./chunk-I3ONDY7P.js";
|
|
14
|
+
import {
|
|
15
|
+
extractErrorMessage
|
|
16
|
+
} from "./chunk-X6ZY2KFU.js";
|
|
17
|
+
|
|
18
|
+
// src/edit/index.ts
|
|
19
|
+
import { tool } from "ai";
|
|
20
|
+
import { z } from "zod";
|
|
21
|
+
|
|
22
|
+
// src/edit/prompt.ts
|
|
23
|
+
function getPrompt() {
|
|
24
|
+
return `Perform an exact string replacement in a file. Locates old_string and replaces it with new_string.
|
|
25
|
+
|
|
26
|
+
Supports absolute paths, relative paths, and tilde (~) expansion. Includes curly-quote fallback matching and quote-style preservation.
|
|
27
|
+
|
|
28
|
+
## When to Use
|
|
29
|
+
- To make targeted changes to existing files
|
|
30
|
+
- To rename variables, update configuration values, or fix bugs
|
|
31
|
+
- Prefer this over the file writing tool for modifying existing files \u2014 it only changes what you specify
|
|
32
|
+
|
|
33
|
+
## When NOT to Use
|
|
34
|
+
- To create a new file from scratch \u2014 use the file writing tool instead
|
|
35
|
+
- To make many changes at once \u2014 consider the multi-edit tool for batch operations
|
|
36
|
+
|
|
37
|
+
## Usage Guidelines
|
|
38
|
+
- The edit will fail if \`old_string\` is not found in the file
|
|
39
|
+
- When \`replace_all\` is false (default), \`old_string\` must appear exactly once in the file. If it appears multiple times, provide more surrounding context to make it unique, or set \`replace_all: true\`
|
|
40
|
+
- Use \`replace_all: true\` for renaming a variable or string across the entire file
|
|
41
|
+
- Preserve exact indentation (tabs/spaces) from the original file in both old_string and new_string
|
|
42
|
+
- old_string and new_string must be different`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// src/edit/index.ts
|
|
46
|
+
function createEdit(config = {}) {
|
|
47
|
+
return tool({
|
|
48
|
+
description: config.description ?? getPrompt(),
|
|
49
|
+
inputSchema: z.object({
|
|
50
|
+
file_path: z.string().describe("The absolute path to the file to modify"),
|
|
51
|
+
old_string: z.string().describe("The exact string to find and replace"),
|
|
52
|
+
new_string: z.string().describe("The replacement string"),
|
|
53
|
+
replace_all: z.boolean().default(false).optional().describe("Replace all occurrences (default: false)")
|
|
54
|
+
}),
|
|
55
|
+
execute: async ({ file_path, old_string, new_string, replace_all }) => {
|
|
56
|
+
try {
|
|
57
|
+
const resolved = expandPath(file_path, config.cwd);
|
|
58
|
+
let content;
|
|
59
|
+
try {
|
|
60
|
+
content = await readTextContent(resolved);
|
|
61
|
+
} catch (err) {
|
|
62
|
+
const msg = extractErrorMessage(err);
|
|
63
|
+
return `Error [edit]: Cannot read file "${resolved}": ${msg}`;
|
|
64
|
+
}
|
|
65
|
+
if (old_string === new_string) {
|
|
66
|
+
return "Error [edit]: old_string and new_string are identical \u2014 nothing to change.";
|
|
67
|
+
}
|
|
68
|
+
const actualOld = findActualString(content, old_string);
|
|
69
|
+
if (actualOld === null) {
|
|
70
|
+
const preview = content.slice(0, 200);
|
|
71
|
+
return `Error [edit]: old_string not found in "${resolved}". File starts with:
|
|
72
|
+
${preview}`;
|
|
73
|
+
}
|
|
74
|
+
if (!replace_all) {
|
|
75
|
+
const count = countOccurrences(content, actualOld);
|
|
76
|
+
if (count > 1) {
|
|
77
|
+
return `Error [edit]: old_string appears ${count} times in "${resolved}". Use replace_all to replace every occurrence, or provide a more specific string.`;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const styledNew = preserveQuoteStyle(old_string, actualOld, new_string);
|
|
81
|
+
const updated = applyEditToFile(content, actualOld, styledNew, replace_all);
|
|
82
|
+
await writeTextContent(resolved, updated);
|
|
83
|
+
const snippet = styledNew.length > 0 ? styledNew.slice(0, 200) : "(deletion)";
|
|
84
|
+
return `Successfully edited "${resolved}". Replacement snippet:
|
|
85
|
+
${snippet}`;
|
|
86
|
+
} catch (error) {
|
|
87
|
+
const msg = extractErrorMessage(error);
|
|
88
|
+
return `Error [edit]: ${msg}`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
var edit = createEdit();
|
|
94
|
+
|
|
95
|
+
export {
|
|
96
|
+
getPrompt,
|
|
97
|
+
createEdit,
|
|
98
|
+
edit
|
|
99
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var _chunkBIAODQ2Pcjs = require('./chunk-BIAODQ2P.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
var _chunkQZ5GS6HWcjs = require('./chunk-QZ5GS6HW.cjs');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
var _chunkKONXT2SFcjs = require('./chunk-KONXT2SF.cjs');
|
|
11
|
+
|
|
12
|
+
// src/read/index.ts
|
|
13
|
+
var _ai = require('ai');
|
|
14
|
+
var _zod = require('zod');
|
|
15
|
+
|
|
16
|
+
// src/read/prompt.ts
|
|
17
|
+
function getPrompt(config = {}) {
|
|
18
|
+
const maxLines = _nullishCoalesce(config.maxLines, () => ( 2e3));
|
|
19
|
+
return `Read a file and return its contents with line numbers.
|
|
20
|
+
|
|
21
|
+
Supports absolute paths, relative paths (resolved against the working directory), and tilde (~) home directory expansion. Returns numbered lines in "lineNumber\\tcontent" format.
|
|
22
|
+
|
|
23
|
+
## When to Use
|
|
24
|
+
- To examine source code, configuration files, or any text file
|
|
25
|
+
- Before editing a file \u2014 read it first to understand its current content
|
|
26
|
+
- To check specific sections of large files using offset and limit
|
|
27
|
+
|
|
28
|
+
## When NOT to Use
|
|
29
|
+
- To list directory contents \u2014 use a shell command instead
|
|
30
|
+
- To search across many files \u2014 use the dedicated content search tool instead
|
|
31
|
+
- To find files by name \u2014 use the dedicated file search tool instead
|
|
32
|
+
|
|
33
|
+
## Usage Guidelines
|
|
34
|
+
- By default, reads up to ${maxLines} lines from the start of the file
|
|
35
|
+
- Use \`offset\` and \`limit\` to read specific ranges of large files rather than reading the entire file
|
|
36
|
+
- When you already know which part of the file you need, read only that part to save context
|
|
37
|
+
- Results use cat -n style line numbering starting at 1`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/read/index.ts
|
|
41
|
+
function createRead(config = {}) {
|
|
42
|
+
const cwd = _nullishCoalesce(config.cwd, () => ( process.cwd()));
|
|
43
|
+
const defaultMaxLines = _nullishCoalesce(config.maxLines, () => ( 2e3));
|
|
44
|
+
return _ai.tool.call(void 0, {
|
|
45
|
+
description: _nullishCoalesce(config.description, () => ( getPrompt(config))),
|
|
46
|
+
inputSchema: _zod.z.object({
|
|
47
|
+
file_path: _zod.z.string().describe("The absolute path to the file to read"),
|
|
48
|
+
offset: _zod.z.number().int().nonnegative().optional().describe("The line number to start reading from (default: 0)"),
|
|
49
|
+
limit: _zod.z.number().int().positive().optional().describe("The number of lines to read (default: 2000)")
|
|
50
|
+
}),
|
|
51
|
+
execute: async ({ file_path, offset, limit }) => {
|
|
52
|
+
try {
|
|
53
|
+
const absolutePath = _chunkQZ5GS6HWcjs.expandPath.call(void 0, file_path, cwd);
|
|
54
|
+
const result = await _chunkBIAODQ2Pcjs.readFileInRange.call(void 0,
|
|
55
|
+
absolutePath,
|
|
56
|
+
_nullishCoalesce(offset, () => ( 0)),
|
|
57
|
+
_nullishCoalesce(limit, () => ( defaultMaxLines))
|
|
58
|
+
);
|
|
59
|
+
const numbered = _chunkBIAODQ2Pcjs.addLineNumbers.call(void 0, {
|
|
60
|
+
content: result.content,
|
|
61
|
+
startLine: (_nullishCoalesce(offset, () => ( 0))) + 1
|
|
62
|
+
});
|
|
63
|
+
return numbered;
|
|
64
|
+
} catch (error) {
|
|
65
|
+
const msg = _chunkKONXT2SFcjs.extractErrorMessage.call(void 0, error);
|
|
66
|
+
return `Error [read]: ${msg}`;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
var read = createRead();
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
exports.getPrompt = getPrompt; exports.createRead = createRead; exports.read = read;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatTaskSummary,
|
|
3
|
+
loadTasks
|
|
4
|
+
} from "./chunk-VHLY7LQE.js";
|
|
5
|
+
import {
|
|
6
|
+
extractErrorMessage
|
|
7
|
+
} from "./chunk-X6ZY2KFU.js";
|
|
8
|
+
|
|
9
|
+
// src/task-list/index.ts
|
|
10
|
+
import { tool } from "ai";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
import { join } from "path";
|
|
13
|
+
|
|
14
|
+
// src/task-list/prompt.ts
|
|
15
|
+
function getPrompt() {
|
|
16
|
+
return `List all tasks with their status, owner, and dependencies.
|
|
17
|
+
|
|
18
|
+
## When to Use
|
|
19
|
+
- To see what tasks are available to work on (status: pending, not blocked)
|
|
20
|
+
- To check overall progress on the current work
|
|
21
|
+
- To find tasks that are blocked and need dependencies resolved
|
|
22
|
+
- After completing a task \u2014 check for newly unblocked work
|
|
23
|
+
- Before creating new tasks \u2014 check for duplicates
|
|
24
|
+
|
|
25
|
+
## Output Format
|
|
26
|
+
Returns a summary of each non-deleted task:
|
|
27
|
+
- **id**: Task identifier (use with task-get or task-update)
|
|
28
|
+
- **status**: pending, in_progress, or completed
|
|
29
|
+
- **subject**: Brief description of the task
|
|
30
|
+
- **owner**: Who is assigned (if set)
|
|
31
|
+
- **blockedBy**: Tasks that must complete before this one can start
|
|
32
|
+
|
|
33
|
+
## Tips
|
|
34
|
+
- Tasks with non-empty \`blockedBy\` lists cannot be started until their dependencies are resolved
|
|
35
|
+
- Use task-get with a specific ID to see full details including description and metadata
|
|
36
|
+
- After marking a task completed, call this tool to find the next available task`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/task-list/index.ts
|
|
40
|
+
function createTaskList(config = {}) {
|
|
41
|
+
const cwd = config.cwd ?? process.cwd();
|
|
42
|
+
const tasksFile = config.tasksFile ?? join(cwd, ".agentool", "tasks.json");
|
|
43
|
+
return tool({
|
|
44
|
+
description: config.description ?? getPrompt(),
|
|
45
|
+
inputSchema: z.object({}),
|
|
46
|
+
execute: async () => {
|
|
47
|
+
try {
|
|
48
|
+
const tasks = await loadTasks(tasksFile);
|
|
49
|
+
const visible = tasks.filter((t) => t.status !== "deleted");
|
|
50
|
+
if (visible.length === 0) return "No tasks found.";
|
|
51
|
+
return visible.map(formatTaskSummary).join("\n");
|
|
52
|
+
} catch (error) {
|
|
53
|
+
const msg = extractErrorMessage(error);
|
|
54
|
+
return `Error [task-list]: ${msg}`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
var taskList = createTaskList();
|
|
60
|
+
|
|
61
|
+
export {
|
|
62
|
+
getPrompt,
|
|
63
|
+
createTaskList,
|
|
64
|
+
taskList
|
|
65
|
+
};
|
|
@@ -4,6 +4,9 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
expandPath
|
|
6
6
|
} from "./chunk-I3ONDY7P.js";
|
|
7
|
+
import {
|
|
8
|
+
extractErrorMessage
|
|
9
|
+
} from "./chunk-X6ZY2KFU.js";
|
|
7
10
|
|
|
8
11
|
// src/glob/index.ts
|
|
9
12
|
import { tool } from "ai";
|
|
@@ -65,11 +68,32 @@ async function glob(pattern, cwd, options) {
|
|
|
65
68
|
return { files, truncated };
|
|
66
69
|
}
|
|
67
70
|
|
|
71
|
+
// src/glob/prompt.ts
|
|
72
|
+
function getPrompt() {
|
|
73
|
+
return `Find files matching a glob pattern. Returns absolute file paths sorted by modification time (newest first).
|
|
74
|
+
|
|
75
|
+
Fast file pattern matching powered by ripgrep. Supports patterns like "**/*.ts", "src/**/*.js", or "*.json".
|
|
76
|
+
|
|
77
|
+
## When to Use
|
|
78
|
+
- To find files by name or extension across a codebase
|
|
79
|
+
- To locate configuration files, test files, or specific file types
|
|
80
|
+
- To discover project structure and file organization
|
|
81
|
+
|
|
82
|
+
## When NOT to Use
|
|
83
|
+
- To search file *contents* \u2014 use the dedicated content search tool instead
|
|
84
|
+
- To read a specific file whose path you already know \u2014 use the file reading tool directly
|
|
85
|
+
|
|
86
|
+
## Usage Guidelines
|
|
87
|
+
- Results are sorted by modification time (most recently modified first)
|
|
88
|
+
- The optional \`path\` parameter lets you narrow the search to a specific directory
|
|
89
|
+
- Results may be truncated for very large result sets`;
|
|
90
|
+
}
|
|
91
|
+
|
|
68
92
|
// src/glob/index.ts
|
|
69
93
|
function createGlob(config = {}) {
|
|
70
94
|
const cwd = config.cwd ?? process.cwd();
|
|
71
95
|
return tool({
|
|
72
|
-
description:
|
|
96
|
+
description: config.description ?? getPrompt(),
|
|
73
97
|
inputSchema: z.object({
|
|
74
98
|
pattern: z.string().describe("Glob pattern to match files against"),
|
|
75
99
|
path: z.string().optional().describe("Directory to search in. Defaults to the working directory.")
|
|
@@ -85,7 +109,7 @@ function createGlob(config = {}) {
|
|
|
85
109
|
return `${header}
|
|
86
110
|
${files.join("\n")}`;
|
|
87
111
|
} catch (error) {
|
|
88
|
-
const message =
|
|
112
|
+
const message = extractErrorMessage(error);
|
|
89
113
|
return `Error [glob]: Failed to search for files: ${message}`;
|
|
90
114
|
}
|
|
91
115
|
}
|
|
@@ -94,6 +118,7 @@ ${files.join("\n")}`;
|
|
|
94
118
|
var glob2 = createGlob();
|
|
95
119
|
|
|
96
120
|
export {
|
|
121
|
+
getPrompt,
|
|
97
122
|
createGlob,
|
|
98
123
|
glob2 as glob
|
|
99
124
|
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
|
|
2
|
+
|
|
3
|
+
var _chunkKONXT2SFcjs = require('./chunk-KONXT2SF.cjs');
|
|
4
|
+
|
|
5
|
+
// src/sleep/index.ts
|
|
6
|
+
var _ai = require('ai');
|
|
7
|
+
var _zod = require('zod');
|
|
8
|
+
|
|
9
|
+
// src/sleep/prompt.ts
|
|
10
|
+
function getPrompt(config = {}) {
|
|
11
|
+
const maxDuration = _nullishCoalesce(config.maxDuration, () => ( 3e5));
|
|
12
|
+
const maxSec = maxDuration / 1e3;
|
|
13
|
+
return `Pause execution for a specified duration. Maximum duration: ${maxSec} seconds (${maxDuration}ms).
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
- When rate-limited by an external API and need to wait before retrying
|
|
17
|
+
- When waiting for an external process to complete
|
|
18
|
+
- Prefer this over shell sleep commands \u2014 it doesn't hold a shell process
|
|
19
|
+
|
|
20
|
+
## When NOT to Use
|
|
21
|
+
- Don't sleep between commands that can run immediately \u2014 just run them
|
|
22
|
+
- Don't retry failing commands in a sleep loop \u2014 diagnose the root cause first
|
|
23
|
+
- Avoid long sleeps that block the user \u2014 keep durations short when possible
|
|
24
|
+
|
|
25
|
+
## Usage Guidelines
|
|
26
|
+
- Durations exceeding the maximum are automatically clamped to ${maxDuration}ms
|
|
27
|
+
- Provide a \`reason\` parameter to document why the sleep is needed
|
|
28
|
+
- Each sleep costs an API turn \u2014 use judiciously`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/sleep/index.ts
|
|
32
|
+
function createSleep(config = {}) {
|
|
33
|
+
const maxDuration = _nullishCoalesce(config.maxDuration, () => ( 3e5));
|
|
34
|
+
return _ai.tool.call(void 0, {
|
|
35
|
+
description: _nullishCoalesce(config.description, () => ( getPrompt(config))),
|
|
36
|
+
inputSchema: _ai.zodSchema.call(void 0,
|
|
37
|
+
_zod.z.object({
|
|
38
|
+
durationMs: _zod.z.number().describe("Duration to sleep in milliseconds"),
|
|
39
|
+
reason: _zod.z.string().optional().describe("Optional reason for the sleep")
|
|
40
|
+
})
|
|
41
|
+
),
|
|
42
|
+
execute: async ({ durationMs, reason }) => {
|
|
43
|
+
try {
|
|
44
|
+
const clamped = Math.max(0, Math.min(durationMs, maxDuration));
|
|
45
|
+
const start = Date.now();
|
|
46
|
+
await new Promise((resolve) => setTimeout(resolve, clamped));
|
|
47
|
+
const elapsed = Date.now() - start;
|
|
48
|
+
const parts = [`Slept for ${elapsed}ms`];
|
|
49
|
+
if (reason) parts.push(`Reason: ${reason}`);
|
|
50
|
+
if (clamped !== durationMs) {
|
|
51
|
+
parts.push(
|
|
52
|
+
`(clamped from ${durationMs}ms to ${clamped}ms, max: ${maxDuration}ms)`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return parts.join(". ");
|
|
56
|
+
} catch (error) {
|
|
57
|
+
const message = _chunkKONXT2SFcjs.extractErrorMessage.call(void 0, error);
|
|
58
|
+
return `Sleep failed: ${message}`;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
var sleep = createSleep();
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
exports.getPrompt = getPrompt; exports.createSleep = createSleep; exports.sleep = sleep;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
|
|
2
|
+
|
|
3
|
+
var _chunkKONXT2SFcjs = require('./chunk-KONXT2SF.cjs');
|
|
4
|
+
|
|
5
|
+
// src/ask-user/index.ts
|
|
6
|
+
var _ai = require('ai');
|
|
7
|
+
var _zod = require('zod');
|
|
8
|
+
|
|
9
|
+
// src/ask-user/prompt.ts
|
|
10
|
+
function getPrompt() {
|
|
11
|
+
return `Ask the user a question and wait for their response. Pauses execution until the user replies.
|
|
12
|
+
|
|
13
|
+
Requires an onQuestion callback to be configured \u2014 the application provides the user interaction mechanism.
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
- When you need clarification about ambiguous requirements before proceeding
|
|
17
|
+
- When you need the user to choose between multiple valid approaches
|
|
18
|
+
- When you need confirmation before taking a potentially destructive action
|
|
19
|
+
- When missing critical information that cannot be reasonably inferred
|
|
20
|
+
|
|
21
|
+
## When NOT to Use
|
|
22
|
+
- When you can make a reasonable decision autonomously
|
|
23
|
+
- For trivial confirmations that slow down workflow
|
|
24
|
+
- When the answer is clearly implied by the user's request
|
|
25
|
+
|
|
26
|
+
## Usage Guidelines
|
|
27
|
+
- Ask clear, specific questions \u2014 avoid vague or overly broad queries
|
|
28
|
+
- Provide options when there are a small number of valid choices
|
|
29
|
+
- Batch related questions together rather than asking one at a time
|
|
30
|
+
- Prefer making progress autonomously when the right course of action is clear`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/ask-user/index.ts
|
|
34
|
+
function createAskUser(config = {}) {
|
|
35
|
+
return _ai.tool.call(void 0, {
|
|
36
|
+
description: _nullishCoalesce(config.description, () => ( getPrompt())),
|
|
37
|
+
inputSchema: _zod.z.object({
|
|
38
|
+
question: _zod.z.string().describe("The question to ask the user"),
|
|
39
|
+
options: _zod.z.array(_zod.z.string()).optional().describe("Optional list of suggested response options")
|
|
40
|
+
}),
|
|
41
|
+
execute: async ({ question, options }) => {
|
|
42
|
+
if (!config.onQuestion) {
|
|
43
|
+
return "Error [ask-user]: No onQuestion callback configured. Provide an onQuestion function in the tool config to enable user interaction.";
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const response = await config.onQuestion(question, options);
|
|
47
|
+
return response;
|
|
48
|
+
} catch (error) {
|
|
49
|
+
const msg = _chunkKONXT2SFcjs.extractErrorMessage.call(void 0, error);
|
|
50
|
+
return `Error [ask-user]: Failed to get user response: ${msg}`;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
var askUser = createAskUser();
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
exports.getPrompt = getPrompt; exports.createAskUser = createAskUser; exports.askUser = askUser;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import {
|
|
2
|
+
extractErrorMessage
|
|
3
|
+
} from "./chunk-X6ZY2KFU.js";
|
|
4
|
+
|
|
5
|
+
// src/ask-user/index.ts
|
|
6
|
+
import { tool } from "ai";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
|
|
9
|
+
// src/ask-user/prompt.ts
|
|
10
|
+
function getPrompt() {
|
|
11
|
+
return `Ask the user a question and wait for their response. Pauses execution until the user replies.
|
|
12
|
+
|
|
13
|
+
Requires an onQuestion callback to be configured \u2014 the application provides the user interaction mechanism.
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
- When you need clarification about ambiguous requirements before proceeding
|
|
17
|
+
- When you need the user to choose between multiple valid approaches
|
|
18
|
+
- When you need confirmation before taking a potentially destructive action
|
|
19
|
+
- When missing critical information that cannot be reasonably inferred
|
|
20
|
+
|
|
21
|
+
## When NOT to Use
|
|
22
|
+
- When you can make a reasonable decision autonomously
|
|
23
|
+
- For trivial confirmations that slow down workflow
|
|
24
|
+
- When the answer is clearly implied by the user's request
|
|
25
|
+
|
|
26
|
+
## Usage Guidelines
|
|
27
|
+
- Ask clear, specific questions \u2014 avoid vague or overly broad queries
|
|
28
|
+
- Provide options when there are a small number of valid choices
|
|
29
|
+
- Batch related questions together rather than asking one at a time
|
|
30
|
+
- Prefer making progress autonomously when the right course of action is clear`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/ask-user/index.ts
|
|
34
|
+
function createAskUser(config = {}) {
|
|
35
|
+
return tool({
|
|
36
|
+
description: config.description ?? getPrompt(),
|
|
37
|
+
inputSchema: z.object({
|
|
38
|
+
question: z.string().describe("The question to ask the user"),
|
|
39
|
+
options: z.array(z.string()).optional().describe("Optional list of suggested response options")
|
|
40
|
+
}),
|
|
41
|
+
execute: async ({ question, options }) => {
|
|
42
|
+
if (!config.onQuestion) {
|
|
43
|
+
return "Error [ask-user]: No onQuestion callback configured. Provide an onQuestion function in the tool config to enable user interaction.";
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const response = await config.onQuestion(question, options);
|
|
47
|
+
return response;
|
|
48
|
+
} catch (error) {
|
|
49
|
+
const msg = extractErrorMessage(error);
|
|
50
|
+
return `Error [ask-user]: Failed to get user response: ${msg}`;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
var askUser = createAskUser();
|
|
56
|
+
|
|
57
|
+
export {
|
|
58
|
+
getPrompt,
|
|
59
|
+
createAskUser,
|
|
60
|
+
askUser
|
|
61
|
+
};
|