tandem-mode 0.4.0 → 0.5.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 +257 -233
- package/dist/agent/clipboard.js +37 -37
- package/dist/agent/clipboard.js.map +1 -1
- package/dist/agent/loop.js +52 -16
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/session.js +2 -2
- package/dist/agent/session.js.map +1 -1
- package/dist/agent/tools/edit.js +1 -1
- package/dist/agent/tools/edit.js.map +1 -1
- package/dist/agent/tools/listDir.js +49 -6
- package/dist/agent/tools/listDir.js.map +1 -1
- package/dist/agent/tools/safeCommand.js +70 -0
- package/dist/agent/tools/safeCommand.js.map +1 -0
- package/dist/agent/tools/search.js +5 -6
- package/dist/agent/tools/search.js.map +1 -1
- package/dist/agent/tools/searchFallback.js +162 -0
- package/dist/agent/tools/searchFallback.js.map +1 -0
- package/dist/agent/tools/shell.js +3 -13
- package/dist/agent/tools/shell.js.map +1 -1
- package/dist/agent/tools/viewImage.js +2 -2
- package/dist/agent/tools/viewImage.js.map +1 -1
- package/dist/agent/tools/webSearch.js +2 -2
- package/dist/agent/tools/webSearch.js.map +1 -1
- package/dist/agent/usage.js +2 -2
- package/dist/agent/usage.js.map +1 -1
- package/dist/benchmark/runner.js +8 -8
- package/dist/benchmark/runner.js.map +1 -1
- package/dist/cli.js +118 -19
- package/dist/cli.js.map +1 -1
- package/dist/config/credentials.js +37 -37
- package/dist/config/credentials.js.map +1 -1
- package/dist/config/env.js +1 -1
- package/dist/config/schema.js +1 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/config/store.js +1 -1
- package/dist/config/store.js.map +1 -1
- package/dist/deepseek/client.js +7 -2
- package/dist/deepseek/client.js.map +1 -1
- package/dist/deepseek/errors.js +101 -0
- package/dist/deepseek/errors.js.map +1 -0
- package/dist/deepseek/webSearch.js +3 -3
- package/dist/deepseek/webSearch.js.map +1 -1
- package/dist/i18n/en.js +30 -19
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/sr.js +30 -19
- package/dist/i18n/sr.js.map +1 -1
- package/dist/orchestrator/planner.js +14 -14
- package/dist/orchestrator/repoMap.js +1 -1
- package/dist/orchestrator/reviewer.js +14 -14
- package/dist/orchestrator/reviewer.js.map +1 -1
- package/dist/repl/commands.js +1 -0
- package/dist/repl/commands.js.map +1 -1
- package/dist/ui/status.js +37 -0
- package/dist/ui/status.js.map +1 -0
- package/dist/ui/toolFormat.js +95 -0
- package/dist/ui/toolFormat.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clipboard.js","sourceRoot":"","sources":["../../src/agent/clipboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,CAAC,EAAE,MAAM,kBAAkB,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,KAAK,UAAU,yBAAyB,CAAC,QAAgB;IACvD,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG;;;;;eAKF,WAAW;;;;EAIxB,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,gBAAgB,EAAE,CAAC,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;IAChH,OAAO,MAAM,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC;AAChC,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,qBAAqB,CAAC,QAAgB;IACnD,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,GAAG,QAAQ,WAAW,CAAC;IACvC,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG;;;gDAG+B,WAAW;;;;;;;;kDAQT,cAAc;;;;;;;;QAQxD,CAAC;IAEP,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,MAAM,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,aAAa,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjF,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAID,
|
|
1
|
+
{"version":3,"file":"clipboard.js","sourceRoot":"","sources":["../../src/agent/clipboard.ts"],"names":[],"mappings":"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"}
|
package/dist/agent/loop.js
CHANGED
|
@@ -1,23 +1,37 @@
|
|
|
1
1
|
import { streamChatCompletion } from "../deepseek/client.js";
|
|
2
|
+
import { MAX_RETRIES, describeError, isTransientError, retryDelayMs, sleep } from "../deepseek/errors.js";
|
|
2
3
|
import { findTool, toolSpecs } from "./tools/index.js";
|
|
3
4
|
import { appendSessionMessage } from "./session.js";
|
|
4
5
|
function isAbortError(err) {
|
|
5
6
|
return err instanceof Error && err.name === "AbortError";
|
|
6
7
|
}
|
|
7
|
-
// Reasoning
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
8
|
+
// Reasoning models (especially reasoningEffort: "max") can fall into a long thinking
|
|
9
|
+
// loop and generate hundreds of thousands of tokens before the final answer.
|
|
10
|
+
// Without this cap `reasoning += ev.delta` grows without bound, token by token, and
|
|
11
|
+
// exhausts the heap even on small projects, regardless of tool output.
|
|
11
12
|
const MAX_REASONING_CHARS = 200_000;
|
|
12
13
|
/**
|
|
13
|
-
* `messages`
|
|
14
|
-
*
|
|
15
|
-
*
|
|
14
|
+
* `messages` must already contain the system message + the initial user request (and the
|
|
15
|
+
* history when a session is resumed); the caller is responsible for writing THOSE messages
|
|
16
|
+
* to the session before calling. The loop persists only the messages it generates itself
|
|
17
|
+
* (assistant/tool).
|
|
16
18
|
*/
|
|
17
19
|
export async function* runAgentLoop(messages, opts) {
|
|
18
20
|
const ctx = { cwd: opts.cwd, env: opts.env, usage: opts.usage, ...(opts.signal ? { signal: opts.signal } : {}) };
|
|
19
21
|
const maxIterations = opts.maxIterations ?? 25;
|
|
20
|
-
|
|
22
|
+
// The limit moves by another "chunk" each time the user (or autoContinue) allows continuing.
|
|
23
|
+
let limit = maxIterations;
|
|
24
|
+
// Consecutive failed attempts of the current model call; reset once a call succeeds.
|
|
25
|
+
let retryAttempt = 0;
|
|
26
|
+
for (let iteration = 0;; iteration++) {
|
|
27
|
+
if (iteration >= limit) {
|
|
28
|
+
const proceed = opts.onIterationLimit ? await opts.onIterationLimit({ iterations: iteration }) : false;
|
|
29
|
+
if (!proceed) {
|
|
30
|
+
yield { type: "max_iterations_reached" };
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
limit += maxIterations;
|
|
34
|
+
}
|
|
21
35
|
if (opts.signal?.aborted) {
|
|
22
36
|
yield { type: "interrupted" };
|
|
23
37
|
return;
|
|
@@ -29,9 +43,12 @@ export async function* runAgentLoop(messages, opts) {
|
|
|
29
43
|
return;
|
|
30
44
|
}
|
|
31
45
|
}
|
|
46
|
+
yield { type: "iteration", n: iteration + 1, max: limit };
|
|
32
47
|
let reasoning = "";
|
|
33
48
|
let content = "";
|
|
34
49
|
const toolCallBuf = new Map();
|
|
50
|
+
// Once anything has streamed in, a failed call cannot be repeated without duplicating output.
|
|
51
|
+
let received = false;
|
|
35
52
|
try {
|
|
36
53
|
for await (const ev of streamChatCompletion(opts.env, {
|
|
37
54
|
model: opts.model,
|
|
@@ -42,16 +59,19 @@ export async function* runAgentLoop(messages, opts) {
|
|
|
42
59
|
})) {
|
|
43
60
|
switch (ev.type) {
|
|
44
61
|
case "reasoning_delta":
|
|
62
|
+
received = true;
|
|
45
63
|
if (reasoning.length < MAX_REASONING_CHARS) {
|
|
46
64
|
reasoning += ev.delta;
|
|
47
65
|
}
|
|
48
66
|
yield { type: "reasoning_delta", delta: ev.delta };
|
|
49
67
|
break;
|
|
50
68
|
case "content_delta":
|
|
69
|
+
received = true;
|
|
51
70
|
content += ev.delta;
|
|
52
71
|
yield { type: "content_delta", delta: ev.delta };
|
|
53
72
|
break;
|
|
54
73
|
case "tool_call_delta": {
|
|
74
|
+
received = true;
|
|
55
75
|
const buf = toolCallBuf.get(ev.index) ?? { args: "" };
|
|
56
76
|
if (ev.id)
|
|
57
77
|
buf.id = ev.id;
|
|
@@ -72,10 +92,26 @@ export async function* runAgentLoop(messages, opts) {
|
|
|
72
92
|
}
|
|
73
93
|
}
|
|
74
94
|
catch (err) {
|
|
75
|
-
if (!isAbortError(err))
|
|
95
|
+
if (!isAbortError(err)) {
|
|
96
|
+
// A dropped connection or a 429/5xx before any output: wait and repeat this same call.
|
|
97
|
+
if (!received && retryAttempt < MAX_RETRIES && isTransientError(err)) {
|
|
98
|
+
const delayMs = retryDelayMs(retryAttempt);
|
|
99
|
+
retryAttempt++;
|
|
100
|
+
yield { type: "retrying", attempt: retryAttempt, max: MAX_RETRIES, delayMs, reason: describeError(err) };
|
|
101
|
+
try {
|
|
102
|
+
await sleep(delayMs, opts.signal);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
yield { type: "interrupted" };
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
iteration--;
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
76
111
|
throw err;
|
|
77
|
-
|
|
78
|
-
//
|
|
112
|
+
}
|
|
113
|
+
// Aborted mid-stream: keep whatever has arrived so far as a message, but without
|
|
114
|
+
// tool_calls (incomplete arguments cannot be executed reliably).
|
|
79
115
|
if (content || reasoning) {
|
|
80
116
|
const partialMessage = {
|
|
81
117
|
role: "assistant",
|
|
@@ -88,6 +124,7 @@ export async function* runAgentLoop(messages, opts) {
|
|
|
88
124
|
yield { type: "interrupted" };
|
|
89
125
|
return;
|
|
90
126
|
}
|
|
127
|
+
retryAttempt = 0;
|
|
91
128
|
const toolCalls = [...toolCallBuf.entries()]
|
|
92
129
|
.sort(([a], [b]) => a - b)
|
|
93
130
|
.map(([, v]) => ({
|
|
@@ -95,9 +132,9 @@ export async function* runAgentLoop(messages, opts) {
|
|
|
95
132
|
type: "function",
|
|
96
133
|
function: { name: v.name ?? "", arguments: v.args },
|
|
97
134
|
}));
|
|
98
|
-
// `tools`
|
|
99
|
-
//
|
|
100
|
-
//
|
|
135
|
+
// `tools` is sent on EVERY call in this loop, so the docs require returning the
|
|
136
|
+
// reasoning_content of every previous turn, not only the ones that called a tool
|
|
137
|
+
// (otherwise a documented 400, see docs/api-notes.md #2).
|
|
101
138
|
const assistantMessage = {
|
|
102
139
|
role: "assistant",
|
|
103
140
|
content: content || null,
|
|
@@ -120,7 +157,7 @@ export async function* runAgentLoop(messages, opts) {
|
|
|
120
157
|
args = JSON.parse(call.function.arguments || "{}");
|
|
121
158
|
}
|
|
122
159
|
catch {
|
|
123
|
-
//
|
|
160
|
+
// Stays {}: the tool will report missing/invalid arguments.
|
|
124
161
|
}
|
|
125
162
|
const tool = findTool(call.function.name);
|
|
126
163
|
if (!tool) {
|
|
@@ -159,6 +196,5 @@ export async function* runAgentLoop(messages, opts) {
|
|
|
159
196
|
await appendSessionMessage(opts.session, toolMsg);
|
|
160
197
|
}
|
|
161
198
|
}
|
|
162
|
-
yield { type: "max_iterations_reached" };
|
|
163
199
|
}
|
|
164
200
|
//# sourceMappingURL=loop.js.map
|
package/dist/agent/loop.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/agent/loop.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/agent/loop.ts"],"names":[],"mappings":"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"}
|
package/dist/agent/session.js
CHANGED
|
@@ -16,8 +16,8 @@ export async function appendSessionMessage(session, message) {
|
|
|
16
16
|
await appendFile(session.filePath, line, "utf8");
|
|
17
17
|
}
|
|
18
18
|
catch (err) {
|
|
19
|
-
//
|
|
20
|
-
// "
|
|
19
|
+
// The file/directory vanished from under us (e.g. the agent deleted it as
|
|
20
|
+
// "unnecessary"): recreate it and retry once instead of crashing the loop.
|
|
21
21
|
if (err.code !== "ENOENT")
|
|
22
22
|
throw err;
|
|
23
23
|
await mkdir(path.dirname(session.filePath), { recursive: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/agent/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,YAAY,GAAG,kBAAkB,CAAC;AAOxC,SAAS,WAAW,CAAC,GAAW;IAC9B,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAW;IAC7C,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzG,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC;AACzD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAAgB,EAAE,OAAoB;IAC/E,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5C,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/agent/session.ts"],"names":[],"mappings":"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"}
|
package/dist/agent/tools/edit.js
CHANGED
|
@@ -27,7 +27,7 @@ export const editTool = {
|
|
|
27
27
|
},
|
|
28
28
|
required: ["path", "oldString", "newString"],
|
|
29
29
|
},
|
|
30
|
-
//
|
|
30
|
+
// Always modifies a file on disk.
|
|
31
31
|
isDestructive: () => true,
|
|
32
32
|
async execute(args, ctx) {
|
|
33
33
|
const filePath = String(args["path"] ?? "");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../../src/agent/tools/edit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,SAAS,gBAAgB,CAAC,QAAgB,EAAE,MAAc;IACxD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAClC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,SAAS,CAAC;QACR,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACpC,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,MAAM;QACtB,KAAK,EAAE,CAAC;QACR,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAmB;IACtC,IAAI,EAAE,MAAM;IACZ,WAAW,EACT,yKAAyK;IAC3K,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mBAAmB,EAAE;YAC1D,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2DAA2D,EAAE;YACvG,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mBAAmB,EAAE;YAC/D,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,0DAA0D,EAAE;SACzG;QACD,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC;KAC7C;IACD,
|
|
1
|
+
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../../src/agent/tools/edit.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,50 @@
|
|
|
1
1
|
import { readdir } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
const MAX_DEPTH = 3;
|
|
4
|
+
const MAX_ENTRIES = 500;
|
|
5
|
+
// Folders that are almost never what the agent is looking for and can hold thousands of entries.
|
|
6
|
+
// Only skipped below the top level, so listing one of them directly still works.
|
|
7
|
+
const NOISE_DIRS = new Set([".git", "node_modules", "bin", "obj", "dist", ".vs", ".idea", ".tandem", "packages"]);
|
|
8
|
+
async function walk(dir, level, maxDepth, state) {
|
|
9
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
10
|
+
// Same ordering as the flat listing: sorted by the rendered "d name" / "- name" key.
|
|
11
|
+
const sorted = entries
|
|
12
|
+
.map((e) => ({ e, key: `${e.isDirectory() ? "d" : "-"} ${e.name}` }))
|
|
13
|
+
.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0));
|
|
14
|
+
for (const { e, key } of sorted) {
|
|
15
|
+
if (state.lines.length >= MAX_ENTRIES) {
|
|
16
|
+
state.more++;
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
state.lines.push(`${" ".repeat(level)}${key}`);
|
|
20
|
+
if (!e.isDirectory() || level + 1 >= maxDepth)
|
|
21
|
+
continue;
|
|
22
|
+
if (NOISE_DIRS.has(e.name)) {
|
|
23
|
+
state.skipped.add(e.name);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
await walk(path.join(dir, e.name), level + 1, maxDepth, state);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// An unreadable subfolder (permissions, broken link) must not fail the whole listing.
|
|
31
|
+
state.lines.push(`${" ".repeat(level + 1)}(cannot read)`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
3
35
|
export const listDirTool = {
|
|
4
36
|
name: "list_dir",
|
|
5
|
-
description:
|
|
37
|
+
description: `List the contents of a directory. By default only that directory (depth 1). Pass depth 2 or 3 to get a nested tree in ONE call ` +
|
|
38
|
+
`(indented, "d" = directory, "-" = file) instead of listing folder by folder; prefer that for getting an overview of a project. ` +
|
|
39
|
+
`At depth > 1, ${[...NOISE_DIRS].join(", ")} are shown but not entered.`,
|
|
6
40
|
parameters: {
|
|
7
41
|
type: "object",
|
|
8
42
|
properties: {
|
|
9
43
|
path: { type: "string", description: "Path to the directory. Defaults to the working directory." },
|
|
44
|
+
depth: {
|
|
45
|
+
type: "integer",
|
|
46
|
+
description: `How many levels to list, 1 to ${MAX_DEPTH}. Defaults to 1.`,
|
|
47
|
+
},
|
|
10
48
|
},
|
|
11
49
|
required: [],
|
|
12
50
|
},
|
|
@@ -14,12 +52,17 @@ export const listDirTool = {
|
|
|
14
52
|
async execute(args, ctx) {
|
|
15
53
|
const dirPath = String(args["path"] ?? ".");
|
|
16
54
|
const resolved = path.resolve(ctx.cwd, dirPath);
|
|
55
|
+
const requested = Number(args["depth"] ?? 1);
|
|
56
|
+
const depth = Number.isFinite(requested) ? Math.min(MAX_DEPTH, Math.max(1, Math.floor(requested))) : 1;
|
|
17
57
|
try {
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
58
|
+
const state = { lines: [], skipped: new Set(), more: 0 };
|
|
59
|
+
await walk(resolved, 0, depth, state);
|
|
60
|
+
const out = [...state.lines];
|
|
61
|
+
if (state.more > 0)
|
|
62
|
+
out.push(`... (${state.more} more entries not shown; list a subfolder or lower the depth)`);
|
|
63
|
+
if (depth > 1 && state.skipped.size > 0)
|
|
64
|
+
out.push(`(not entered: ${[...state.skipped].sort().join(", ")})`);
|
|
65
|
+
return { output: out.join("\n") || "(empty)", isError: false };
|
|
23
66
|
}
|
|
24
67
|
catch (err) {
|
|
25
68
|
return { output: `Error listing ${resolved}: ${err.message}`, isError: true };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listDir.js","sourceRoot":"","sources":["../../../src/agent/tools/listDir.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,CAAC,MAAM,WAAW,GAAmB;IACzC,IAAI,EAAE,UAAU;IAChB,WAAW,
|
|
1
|
+
{"version":3,"file":"listDir.js","sourceRoot":"","sources":["../../../src/agent/tools/listDir.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decides whether a shell command is read-only and may run without asking.
|
|
3
|
+
*
|
|
4
|
+
* A command is safe only if EVERY part of it is safe. The command is split on `;`, `&&`, `||`
|
|
5
|
+
* and `|`, and each part must start with a known read-only command. Anything that could write
|
|
6
|
+
* or run something hidden makes the whole command "not safe": redirections, backticks,
|
|
7
|
+
* `$(...)`, `{ ... }` blocks, a bare `&`, newlines. Being wrong in this direction only costs an
|
|
8
|
+
* extra approval prompt; being wrong in the other direction would run something silently.
|
|
9
|
+
*/
|
|
10
|
+
// Read-only commands allowed at the start of a segment.
|
|
11
|
+
const SAFE_START = [
|
|
12
|
+
// git: inspection only. `branch` only in its listing forms, never with a name (which creates/deletes).
|
|
13
|
+
/^git\s+(status|log|diff|show|ls-files|rev-parse)\b/i,
|
|
14
|
+
/^git\s+branch(\s+(-a|-r|-v|-vv|--list|--show-current|--all|--remotes))*$/i,
|
|
15
|
+
/^git\s+remote(\s+-v)?$/i,
|
|
16
|
+
// Unix-style and cmd-style listing/reading.
|
|
17
|
+
/^(ls|dir)\b/i,
|
|
18
|
+
/^pwd$/i,
|
|
19
|
+
/^(cat|type|head|tail|wc|grep|findstr)\s+\S/i,
|
|
20
|
+
/^echo\b/i,
|
|
21
|
+
/^(which|where)\s+\S/i,
|
|
22
|
+
/^(php|node|npm|pnpm|npx|python|python3)\s+(-v|--version|-l)\b/i,
|
|
23
|
+
// PowerShell read-only cmdlets and their aliases.
|
|
24
|
+
/^(Get-ChildItem|gci|Get-Content|gc|Select-String|sls|Get-Item|gi|Get-Location|gl|Test-Path|Resolve-Path|Measure-Object|measure|Get-FileHash)\b/i,
|
|
25
|
+
];
|
|
26
|
+
// Allowed after a `|`: filters that only reshape their input. (`ForEach-Object` is not here on
|
|
27
|
+
// purpose: it needs a `{ }` script block, which is rejected outright.)
|
|
28
|
+
const SAFE_PIPE = [
|
|
29
|
+
...SAFE_START,
|
|
30
|
+
/^(head|tail|wc|uniq|sort)\b/i,
|
|
31
|
+
/^(Select-Object|select|Sort-Object|Format-Table|ft|Format-List|fl|Out-String|Get-Unique|Group-Object|group|Where-Object|where)\b/i,
|
|
32
|
+
];
|
|
33
|
+
// `2>&1` just merges stderr into stdout; it is the one redirection that is harmless.
|
|
34
|
+
const MERGE_STDERR = /\s*2>&1/g;
|
|
35
|
+
// Redirections (> <), backticks, `$(`, braces, and newlines can write files or hide a second command.
|
|
36
|
+
// `--output` makes git diff/log/show write a file.
|
|
37
|
+
const FORBIDDEN = /[<>`{}\r\n]|\$\(|--output\b/;
|
|
38
|
+
export function isReadOnlyCommand(command) {
|
|
39
|
+
const cleaned = command.replace(MERGE_STDERR, "").trim();
|
|
40
|
+
if (cleaned === "" || FORBIDDEN.test(cleaned))
|
|
41
|
+
return false;
|
|
42
|
+
// Split while keeping the separators, so we know which segments follow a pipe.
|
|
43
|
+
const parts = cleaned.split(/(\|\||&&|;|\|)/);
|
|
44
|
+
let afterPipe = false;
|
|
45
|
+
let sawCommand = false;
|
|
46
|
+
for (const part of parts) {
|
|
47
|
+
const token = part.trim();
|
|
48
|
+
if (token === "|") {
|
|
49
|
+
afterPipe = true;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (token === "||" || token === "&&" || token === ";") {
|
|
53
|
+
afterPipe = false;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (token === "") {
|
|
57
|
+
// An empty piece is fine at the very end ("cmd;"), but not between pipes ("a | | b").
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
// A lone `&` (background / PowerShell call operator) is never safe.
|
|
61
|
+
if (/(^|[^&])&([^&]|$)/.test(token))
|
|
62
|
+
return false;
|
|
63
|
+
const allowed = afterPipe ? SAFE_PIPE : SAFE_START;
|
|
64
|
+
if (!allowed.some((p) => p.test(token)))
|
|
65
|
+
return false;
|
|
66
|
+
sawCommand = true;
|
|
67
|
+
}
|
|
68
|
+
return sawCommand;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=safeCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safeCommand.js","sourceRoot":"","sources":["../../../src/agent/tools/safeCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,wDAAwD;AACxD,MAAM,UAAU,GAAa;IAC3B,uGAAuG;IACvG,qDAAqD;IACrD,2EAA2E;IAC3E,yBAAyB;IACzB,4CAA4C;IAC5C,cAAc;IACd,QAAQ;IACR,6CAA6C;IAC7C,UAAU;IACV,sBAAsB;IACtB,gEAAgE;IAChE,kDAAkD;IAClD,iJAAiJ;CAClJ,CAAC;AAEF,+FAA+F;AAC/F,uEAAuE;AACvE,MAAM,SAAS,GAAa;IAC1B,GAAG,UAAU;IACb,8BAA8B;IAC9B,mIAAmI;CACpI,CAAC;AAEF,qFAAqF;AACrF,MAAM,YAAY,GAAG,UAAU,CAAC;AAEhC,sGAAsG;AACtG,mDAAmD;AACnD,MAAM,SAAS,GAAG,6BAA6B,CAAC;AAEhD,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACzD,IAAI,OAAO,KAAK,EAAE,IAAI,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IAE5D,+EAA+E;IAC/E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC9C,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,UAAU,GAAG,KAAK,CAAC;IAEvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1B,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YAClB,SAAS,GAAG,IAAI,CAAC;YACjB,SAAS;QACX,CAAC;QACD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YACtD,SAAS,GAAG,KAAK,CAAC;YAClB,SAAS;QACX,CAAC;QACD,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YACjB,sFAAsF;YACtF,SAAS;QACX,CAAC;QACD,oEAAoE;QACpE,IAAI,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAClD,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACtD,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { execFile } from "node:child_process";
|
|
2
2
|
import { promisify } from "node:util";
|
|
3
|
+
import { searchFallback } from "./searchFallback.js";
|
|
3
4
|
const execFileAsync = promisify(execFile);
|
|
4
5
|
const MAX_OUTPUT_CHARS = 20_000;
|
|
5
6
|
export const searchTool = {
|
|
6
7
|
name: "search",
|
|
7
|
-
description: "Search file contents with a regex pattern
|
|
8
|
+
description: "Search file contents with a regex pattern. Uses ripgrep (rg) when it is installed, otherwise a built-in search with the same parameters.",
|
|
8
9
|
parameters: {
|
|
9
10
|
type: "object",
|
|
10
11
|
properties: {
|
|
@@ -35,12 +36,10 @@ export const searchTool = {
|
|
|
35
36
|
catch (err) {
|
|
36
37
|
const e = err;
|
|
37
38
|
if (e.code === "ENOENT") {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
isError: true,
|
|
41
|
-
};
|
|
39
|
+
// No ripgrep on this machine: fall back to the built-in search instead of failing.
|
|
40
|
+
return searchFallback({ cwd: ctx.cwd, searchPath, pattern, glob, caseInsensitive, signal: ctx.signal });
|
|
42
41
|
}
|
|
43
|
-
// rg
|
|
42
|
+
// rg exits with code 1 when there are no matches. That is not a tool error.
|
|
44
43
|
if (e.code === 1) {
|
|
45
44
|
return { output: "(no matches)", isError: false };
|
|
46
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/agent/tools/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/agent/tools/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { open, readdir, readFile, stat } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Built-in content search, used when ripgrep (`rg`) is not installed. It covers what the agent
|
|
5
|
+
* needs (regex, glob filter, case folding, line numbers) with no external dependency, but it is
|
|
6
|
+
* simpler than ripgrep: only a fixed list of folders is skipped, `.gitignore` is not read.
|
|
7
|
+
*/
|
|
8
|
+
const SKIP_DIRS = new Set([".git", "node_modules", "bin", "obj", "dist", ".vs", ".idea", ".tandem", "packages", ".next", "build"]);
|
|
9
|
+
const MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
10
|
+
const MAX_MATCHES_PER_FILE = 200;
|
|
11
|
+
const MAX_MATCHES_TOTAL = 500;
|
|
12
|
+
const MAX_LINE_CHARS = 300;
|
|
13
|
+
const DEADLINE_MS = 25_000;
|
|
14
|
+
/** Expands `{a,b}` groups (not nested), so `*.{ts,tsx}` becomes two patterns. */
|
|
15
|
+
function expandBraces(glob) {
|
|
16
|
+
const m = /\{([^{}]*)\}/.exec(glob);
|
|
17
|
+
if (!m)
|
|
18
|
+
return [glob];
|
|
19
|
+
const [whole, inner] = [m[0], m[1] ?? ""];
|
|
20
|
+
return inner.split(",").flatMap((alt) => expandBraces(glob.replace(whole, alt)));
|
|
21
|
+
}
|
|
22
|
+
function globToRegExp(glob) {
|
|
23
|
+
let re = "";
|
|
24
|
+
for (let i = 0; i < glob.length; i++) {
|
|
25
|
+
const c = glob[i];
|
|
26
|
+
if (c === "*") {
|
|
27
|
+
if (glob[i + 1] === "*") {
|
|
28
|
+
// `**/` matches any number of folders, including none; a bare `**` matches anything.
|
|
29
|
+
if (glob[i + 2] === "/") {
|
|
30
|
+
re += "(?:.*/)?";
|
|
31
|
+
i += 2;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
re += ".*";
|
|
35
|
+
i += 1;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
re += "[^/]*";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (c === "?") {
|
|
43
|
+
re += "[^/]";
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
re += c.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return new RegExp(`^${re}$`, "i");
|
|
50
|
+
}
|
|
51
|
+
/** A glob without a slash matches the file name anywhere (like ripgrep); one with a slash matches the relative path. */
|
|
52
|
+
function buildGlobMatcher(glob) {
|
|
53
|
+
if (!glob)
|
|
54
|
+
return () => true;
|
|
55
|
+
const matchers = expandBraces(glob).map((g) => ({ re: globToRegExp(g.replace(/^\.\//, "")), hasSlash: g.includes("/") }));
|
|
56
|
+
return (relPath) => {
|
|
57
|
+
const base = relPath.slice(relPath.lastIndexOf("/") + 1);
|
|
58
|
+
return matchers.some((m) => m.re.test(m.hasSlash ? relPath : base));
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
async function looksBinary(file) {
|
|
62
|
+
const handle = await open(file, "r");
|
|
63
|
+
try {
|
|
64
|
+
const buf = Buffer.alloc(8000);
|
|
65
|
+
const { bytesRead } = await handle.read(buf, 0, buf.length, 0);
|
|
66
|
+
return buf.subarray(0, bytesRead).includes(0);
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
await handle.close();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export async function searchFallback(opts) {
|
|
73
|
+
let regex;
|
|
74
|
+
try {
|
|
75
|
+
regex = new RegExp(opts.pattern, opts.caseInsensitive ? "i" : "");
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
return { output: `Invalid regex: ${err.message}`, isError: true };
|
|
79
|
+
}
|
|
80
|
+
const root = path.resolve(opts.cwd, opts.searchPath);
|
|
81
|
+
let rootStat;
|
|
82
|
+
try {
|
|
83
|
+
rootStat = await stat(root);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
return { output: `Search error: ${err.message}`, isError: true };
|
|
87
|
+
}
|
|
88
|
+
const matchesGlob = buildGlobMatcher(opts.glob);
|
|
89
|
+
const deadline = Date.now() + DEADLINE_MS;
|
|
90
|
+
const out = [];
|
|
91
|
+
let timedOut = false;
|
|
92
|
+
let capped = false;
|
|
93
|
+
const rel = (file) => path.relative(opts.cwd, file).split(path.sep).join("/");
|
|
94
|
+
async function searchFile(file) {
|
|
95
|
+
const relPath = rel(file);
|
|
96
|
+
if (!matchesGlob(relPath))
|
|
97
|
+
return;
|
|
98
|
+
try {
|
|
99
|
+
const size = (await stat(file)).size;
|
|
100
|
+
if (size > MAX_FILE_BYTES || (await looksBinary(file)))
|
|
101
|
+
return;
|
|
102
|
+
const text = await readFile(file, "utf8");
|
|
103
|
+
const lines = text.split(/\r\n|\n/);
|
|
104
|
+
let inFile = 0;
|
|
105
|
+
for (let i = 0; i < lines.length; i++) {
|
|
106
|
+
if (!regex.test(lines[i]))
|
|
107
|
+
continue;
|
|
108
|
+
const line = lines[i].trim();
|
|
109
|
+
out.push(`${relPath}:${i + 1}:${line.length > MAX_LINE_CHARS ? `${line.slice(0, MAX_LINE_CHARS)}…` : line}`);
|
|
110
|
+
if (++inFile >= MAX_MATCHES_PER_FILE)
|
|
111
|
+
break;
|
|
112
|
+
if (out.length >= MAX_MATCHES_TOTAL) {
|
|
113
|
+
capped = true;
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// Unreadable or vanished file: skip it, the same as ripgrep does.
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async function walk(dir) {
|
|
123
|
+
if (capped || timedOut)
|
|
124
|
+
return;
|
|
125
|
+
let entries;
|
|
126
|
+
try {
|
|
127
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
entries.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
133
|
+
for (const e of entries) {
|
|
134
|
+
if (opts.signal?.aborted || capped)
|
|
135
|
+
return;
|
|
136
|
+
if (Date.now() > deadline) {
|
|
137
|
+
timedOut = true;
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const full = path.join(dir, e.name);
|
|
141
|
+
if (e.isDirectory()) {
|
|
142
|
+
if (!SKIP_DIRS.has(e.name))
|
|
143
|
+
await walk(full);
|
|
144
|
+
}
|
|
145
|
+
else if (e.isFile()) {
|
|
146
|
+
await searchFile(full);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (rootStat.isFile())
|
|
151
|
+
await searchFile(root);
|
|
152
|
+
else
|
|
153
|
+
await walk(root);
|
|
154
|
+
const notes = [
|
|
155
|
+
"(ripgrep is not installed; used the built-in search: .gitignore is not applied)",
|
|
156
|
+
...(capped ? [`(stopped after ${MAX_MATCHES_TOTAL} matches; narrow the pattern, path or glob)`] : []),
|
|
157
|
+
...(timedOut ? ["(stopped after 25s; narrow the path or glob)"] : []),
|
|
158
|
+
];
|
|
159
|
+
const body = out.length > 0 ? out.join("\n") : "(no matches)";
|
|
160
|
+
return { output: `${body}\n${notes.join("\n")}`, isError: false };
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=searchFallback.js.map
|