@gugacoder/agentic-sdk 0.2.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.
- package/dist/agent.d.ts +2 -0
- package/dist/agent.js +463 -0
- package/dist/context/compaction.d.ts +27 -0
- package/dist/context/compaction.js +219 -0
- package/dist/context/models.d.ts +6 -0
- package/dist/context/models.js +41 -0
- package/dist/context/tokenizer.d.ts +5 -0
- package/dist/context/tokenizer.js +11 -0
- package/dist/context/usage.d.ts +11 -0
- package/dist/context/usage.js +49 -0
- package/dist/display-schemas.d.ts +1865 -0
- package/dist/display-schemas.js +219 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +28 -0
- package/dist/middleware/logging.d.ts +2 -0
- package/dist/middleware/logging.js +32 -0
- package/dist/prompts/assembly.d.ts +13 -0
- package/dist/prompts/assembly.js +229 -0
- package/dist/providers.d.ts +19 -0
- package/dist/providers.js +44 -0
- package/dist/proxy.d.ts +2 -0
- package/dist/proxy.js +103 -0
- package/dist/schemas.d.ts +228 -0
- package/dist/schemas.js +51 -0
- package/dist/session.d.ts +7 -0
- package/dist/session.js +102 -0
- package/dist/structured.d.ts +18 -0
- package/dist/structured.js +38 -0
- package/dist/tool-repair.d.ts +21 -0
- package/dist/tool-repair.js +72 -0
- package/dist/tools/api-spec.d.ts +4 -0
- package/dist/tools/api-spec.js +123 -0
- package/dist/tools/apply-patch.d.ts +484 -0
- package/dist/tools/apply-patch.js +157 -0
- package/dist/tools/ask-user.d.ts +14 -0
- package/dist/tools/ask-user.js +27 -0
- package/dist/tools/bash.d.ts +550 -0
- package/dist/tools/bash.js +43 -0
- package/dist/tools/batch.d.ts +13 -0
- package/dist/tools/batch.js +84 -0
- package/dist/tools/brave-search.d.ts +6 -0
- package/dist/tools/brave-search.js +19 -0
- package/dist/tools/code-search.d.ts +20 -0
- package/dist/tools/code-search.js +42 -0
- package/dist/tools/diagnostics.d.ts +4 -0
- package/dist/tools/diagnostics.js +69 -0
- package/dist/tools/display.d.ts +483 -0
- package/dist/tools/display.js +77 -0
- package/dist/tools/edit.d.ts +682 -0
- package/dist/tools/edit.js +47 -0
- package/dist/tools/glob.d.ts +4 -0
- package/dist/tools/glob.js +42 -0
- package/dist/tools/grep.d.ts +6 -0
- package/dist/tools/grep.js +69 -0
- package/dist/tools/http-request.d.ts +7 -0
- package/dist/tools/http-request.js +98 -0
- package/dist/tools/index.d.ts +1611 -0
- package/dist/tools/index.js +46 -0
- package/dist/tools/job-tools.d.ts +24 -0
- package/dist/tools/job-tools.js +67 -0
- package/dist/tools/list-dir.d.ts +5 -0
- package/dist/tools/list-dir.js +79 -0
- package/dist/tools/multi-edit.d.ts +814 -0
- package/dist/tools/multi-edit.js +57 -0
- package/dist/tools/read.d.ts +5 -0
- package/dist/tools/read.js +33 -0
- package/dist/tools/task.d.ts +21 -0
- package/dist/tools/task.js +51 -0
- package/dist/tools/todo.d.ts +14 -0
- package/dist/tools/todo.js +60 -0
- package/dist/tools/web-fetch.d.ts +4 -0
- package/dist/tools/web-fetch.js +126 -0
- package/dist/tools/web-search.d.ts +22 -0
- package/dist/tools/web-search.js +48 -0
- package/dist/tools/write.d.ts +550 -0
- package/dist/tools/write.js +30 -0
- package/dist/types.d.ts +201 -0
- package/dist/types.js +1 -0
- package/package.json +43 -0
- package/src/agent.ts +520 -0
- package/src/context/compaction.ts +265 -0
- package/src/context/models.ts +42 -0
- package/src/context/tokenizer.ts +12 -0
- package/src/context/usage.ts +65 -0
- package/src/display-schemas.ts +276 -0
- package/src/index.ts +43 -0
- package/src/middleware/logging.ts +37 -0
- package/src/prompts/assembly.ts +263 -0
- package/src/prompts/identity.md +10 -0
- package/src/prompts/patterns.md +7 -0
- package/src/prompts/safety.md +7 -0
- package/src/prompts/tool-guide.md +9 -0
- package/src/prompts/tools/bash.md +7 -0
- package/src/prompts/tools/edit.md +7 -0
- package/src/prompts/tools/glob.md +7 -0
- package/src/prompts/tools/grep.md +7 -0
- package/src/prompts/tools/read.md +7 -0
- package/src/prompts/tools/write.md +7 -0
- package/src/providers.ts +58 -0
- package/src/proxy.ts +101 -0
- package/src/schemas.ts +58 -0
- package/src/session.ts +110 -0
- package/src/structured.ts +65 -0
- package/src/tool-repair.ts +92 -0
- package/src/tools/api-spec.ts +158 -0
- package/src/tools/apply-patch.ts +188 -0
- package/src/tools/ask-user.ts +40 -0
- package/src/tools/bash.ts +51 -0
- package/src/tools/batch.ts +103 -0
- package/src/tools/brave-search.ts +24 -0
- package/src/tools/code-search.ts +69 -0
- package/src/tools/diagnostics.ts +93 -0
- package/src/tools/display.ts +105 -0
- package/src/tools/edit.ts +55 -0
- package/src/tools/glob.ts +46 -0
- package/src/tools/grep.ts +68 -0
- package/src/tools/http-request.ts +103 -0
- package/src/tools/index.ts +48 -0
- package/src/tools/job-tools.ts +84 -0
- package/src/tools/list-dir.ts +102 -0
- package/src/tools/multi-edit.ts +65 -0
- package/src/tools/read.ts +40 -0
- package/src/tools/task.ts +71 -0
- package/src/tools/todo.ts +82 -0
- package/src/tools/web-fetch.ts +155 -0
- package/src/tools/web-search.ts +75 -0
- package/src/tools/write.ts +34 -0
- package/src/types.ts +145 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { tool } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
4
|
+
export function createEditTool(opts) {
|
|
5
|
+
const baseTool = tool({
|
|
6
|
+
description: "Performs exact string replacement in a file. The old_string must be unique in the file unless replace_all is true.",
|
|
7
|
+
inputSchema: z.object({
|
|
8
|
+
file_path: z.string().describe("Absolute path to the file to edit"),
|
|
9
|
+
old_string: z.string().describe("The exact text to find and replace"),
|
|
10
|
+
new_string: z.string().describe("The replacement text"),
|
|
11
|
+
replace_all: z
|
|
12
|
+
.boolean()
|
|
13
|
+
.optional()
|
|
14
|
+
.default(false)
|
|
15
|
+
.describe("Replace all occurrences instead of just the first"),
|
|
16
|
+
}),
|
|
17
|
+
execute: async ({ file_path, old_string, new_string, replace_all }) => {
|
|
18
|
+
try {
|
|
19
|
+
const content = await readFile(file_path, "utf-8");
|
|
20
|
+
if (!content.includes(old_string)) {
|
|
21
|
+
return `Error: old_string not found in ${file_path}`;
|
|
22
|
+
}
|
|
23
|
+
if (!replace_all) {
|
|
24
|
+
const count = content.split(old_string).length - 1;
|
|
25
|
+
if (count > 1) {
|
|
26
|
+
return `Error: old_string appears ${count} times in the file. Provide more context to make it unique, or set replace_all to true.`;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const updated = replace_all
|
|
30
|
+
? content.replaceAll(old_string, new_string)
|
|
31
|
+
: content.replace(old_string, new_string);
|
|
32
|
+
await writeFile(file_path, updated, "utf-8");
|
|
33
|
+
return `File edited successfully: ${file_path}`;
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
return `Error editing file: ${err.message}`;
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
if (opts?.autoApprove === false) {
|
|
41
|
+
return Object.assign(baseTool, {
|
|
42
|
+
needsApproval: async () => true,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return baseTool;
|
|
46
|
+
}
|
|
47
|
+
export const editTool = createEditTool();
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { tool } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import fg from "fast-glob";
|
|
4
|
+
import { stat } from "node:fs/promises";
|
|
5
|
+
export const globTool = tool({
|
|
6
|
+
description: "Fast file pattern matching. Supports glob patterns like '**/*.ts'. Returns matching file paths sorted by modification time.",
|
|
7
|
+
inputSchema: z.object({
|
|
8
|
+
pattern: z.string().describe("Glob pattern to match files against"),
|
|
9
|
+
path: z
|
|
10
|
+
.string()
|
|
11
|
+
.optional()
|
|
12
|
+
.describe("Directory to search in. Defaults to cwd."),
|
|
13
|
+
}),
|
|
14
|
+
execute: async ({ pattern, path }) => {
|
|
15
|
+
try {
|
|
16
|
+
const cwd = path ?? process.cwd();
|
|
17
|
+
const files = await fg(pattern, {
|
|
18
|
+
cwd,
|
|
19
|
+
absolute: true,
|
|
20
|
+
dot: false,
|
|
21
|
+
onlyFiles: true,
|
|
22
|
+
});
|
|
23
|
+
// Sort by mtime (most recent first)
|
|
24
|
+
const withStats = await Promise.all(files.map(async (f) => {
|
|
25
|
+
try {
|
|
26
|
+
const s = await stat(f);
|
|
27
|
+
return { file: f, mtime: s.mtimeMs };
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return { file: f, mtime: 0 };
|
|
31
|
+
}
|
|
32
|
+
}));
|
|
33
|
+
withStats.sort((a, b) => b.mtime - a.mtime);
|
|
34
|
+
if (withStats.length === 0)
|
|
35
|
+
return "No files matched the pattern.";
|
|
36
|
+
return withStats.map((w) => w.file).join("\n");
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
return `Error: ${err.message}`;
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { tool } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { execFile } from "node:child_process";
|
|
4
|
+
const MAX_OUTPUT = 30_000;
|
|
5
|
+
export const grepTool = tool({
|
|
6
|
+
description: "Searches file contents using ripgrep (rg) with regex support. Falls back to grep if rg is unavailable.",
|
|
7
|
+
inputSchema: z.object({
|
|
8
|
+
pattern: z.string().describe("Regex pattern to search for"),
|
|
9
|
+
path: z
|
|
10
|
+
.string()
|
|
11
|
+
.optional()
|
|
12
|
+
.describe("File or directory to search in. Defaults to cwd."),
|
|
13
|
+
glob: z
|
|
14
|
+
.string()
|
|
15
|
+
.optional()
|
|
16
|
+
.describe("Glob pattern to filter files (e.g. '*.ts')"),
|
|
17
|
+
output_mode: z
|
|
18
|
+
.enum(["content", "files_with_matches", "count"])
|
|
19
|
+
.optional()
|
|
20
|
+
.default("files_with_matches")
|
|
21
|
+
.describe("Output mode"),
|
|
22
|
+
}),
|
|
23
|
+
execute: async ({ pattern, path, glob: globFilter, output_mode }) => {
|
|
24
|
+
const searchPath = path ?? ".";
|
|
25
|
+
// Build rg args array (no shell quoting needed with execFile)
|
|
26
|
+
const args = [];
|
|
27
|
+
if (output_mode === "files_with_matches")
|
|
28
|
+
args.push("-l");
|
|
29
|
+
else if (output_mode === "count")
|
|
30
|
+
args.push("-c");
|
|
31
|
+
else
|
|
32
|
+
args.push("-n"); // content mode: show line numbers
|
|
33
|
+
if (globFilter)
|
|
34
|
+
args.push("--glob", globFilter);
|
|
35
|
+
args.push(pattern, searchPath);
|
|
36
|
+
return new Promise((resolve) => {
|
|
37
|
+
execFile("rg", args, { timeout: 30_000, maxBuffer: 10 * 1024 * 1024 }, (err, stdout) => {
|
|
38
|
+
if (stdout) {
|
|
39
|
+
const output = stdout.length > MAX_OUTPUT
|
|
40
|
+
? stdout.slice(0, MAX_OUTPUT) + "\n...[truncated]"
|
|
41
|
+
: stdout;
|
|
42
|
+
resolve(output.trim());
|
|
43
|
+
}
|
|
44
|
+
else if (err) {
|
|
45
|
+
// rg returns exit code 1 for no matches
|
|
46
|
+
if (err.code === 1) {
|
|
47
|
+
resolve("No matches found.");
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
// Try grep fallback
|
|
51
|
+
const grepArgs = ["-rn"];
|
|
52
|
+
if (globFilter)
|
|
53
|
+
grepArgs.push(`--include=${globFilter}`);
|
|
54
|
+
grepArgs.push(pattern, searchPath);
|
|
55
|
+
execFile("grep", grepArgs, { timeout: 30_000 }, (gErr, gOut) => {
|
|
56
|
+
if (gOut)
|
|
57
|
+
resolve(gOut.trim());
|
|
58
|
+
else
|
|
59
|
+
resolve("No matches found.");
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
resolve("No matches found.");
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
});
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { tool } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
const MAX_RESPONSE_SIZE = 50 * 1024; // 50KB
|
|
4
|
+
const MAX_TIMEOUT = 60_000;
|
|
5
|
+
export const httpRequestTool = tool({
|
|
6
|
+
description: "Sends an HTTP request to a URL. Supports all methods, custom headers, and JSON/text bodies. Use for REST API interactions.",
|
|
7
|
+
inputSchema: z.object({
|
|
8
|
+
method: z
|
|
9
|
+
.enum(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"])
|
|
10
|
+
.describe("HTTP method"),
|
|
11
|
+
url: z.string().url().describe("Target URL"),
|
|
12
|
+
headers: z
|
|
13
|
+
.record(z.string())
|
|
14
|
+
.optional()
|
|
15
|
+
.describe("Custom headers (e.g. Authorization, Content-Type)"),
|
|
16
|
+
body: z
|
|
17
|
+
.string()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe("Request body (JSON string or plain text)"),
|
|
20
|
+
timeout: z
|
|
21
|
+
.number()
|
|
22
|
+
.optional()
|
|
23
|
+
.default(30_000)
|
|
24
|
+
.describe("Timeout in ms (max 60000)"),
|
|
25
|
+
}),
|
|
26
|
+
execute: async ({ method, url, headers, body, timeout }) => {
|
|
27
|
+
const effectiveTimeout = Math.min(timeout ?? 30_000, MAX_TIMEOUT);
|
|
28
|
+
const controller = new AbortController();
|
|
29
|
+
const timer = setTimeout(() => controller.abort(), effectiveTimeout);
|
|
30
|
+
try {
|
|
31
|
+
const fetchHeaders = { ...headers };
|
|
32
|
+
// Auto-set Content-Type for JSON bodies if not specified
|
|
33
|
+
if (body && !fetchHeaders["Content-Type"] && !fetchHeaders["content-type"]) {
|
|
34
|
+
try {
|
|
35
|
+
JSON.parse(body);
|
|
36
|
+
fetchHeaders["Content-Type"] = "application/json";
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Not JSON — leave Content-Type unset
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const response = await fetch(url, {
|
|
43
|
+
method,
|
|
44
|
+
headers: fetchHeaders,
|
|
45
|
+
body: method !== "GET" && method !== "HEAD" ? body : undefined,
|
|
46
|
+
signal: controller.signal,
|
|
47
|
+
});
|
|
48
|
+
// Collect response headers (subset)
|
|
49
|
+
const responseHeaders = {};
|
|
50
|
+
for (const key of ["content-type", "location", "x-request-id", "retry-after"]) {
|
|
51
|
+
const val = response.headers.get(key);
|
|
52
|
+
if (val)
|
|
53
|
+
responseHeaders[key] = val;
|
|
54
|
+
}
|
|
55
|
+
// Read response body
|
|
56
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
57
|
+
let responseBody;
|
|
58
|
+
if (method === "HEAD") {
|
|
59
|
+
responseBody = null;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const text = await response.text();
|
|
63
|
+
const truncated = text.length > MAX_RESPONSE_SIZE;
|
|
64
|
+
const bodyText = truncated ? text.slice(0, MAX_RESPONSE_SIZE) : text;
|
|
65
|
+
// Try JSON parse if content-type indicates JSON
|
|
66
|
+
if (contentType.includes("json")) {
|
|
67
|
+
try {
|
|
68
|
+
responseBody = JSON.parse(bodyText);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
responseBody = bodyText;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
responseBody = bodyText;
|
|
76
|
+
}
|
|
77
|
+
if (truncated) {
|
|
78
|
+
responseHeaders["x-truncated"] = `true (${text.length} bytes, showing first ${MAX_RESPONSE_SIZE})`;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return JSON.stringify({
|
|
82
|
+
status: response.status,
|
|
83
|
+
statusText: response.statusText,
|
|
84
|
+
headers: responseHeaders,
|
|
85
|
+
body: responseBody,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
if (err.name === "AbortError") {
|
|
90
|
+
return `Error: Request timed out after ${effectiveTimeout}ms`;
|
|
91
|
+
}
|
|
92
|
+
return `Error: ${err.message}`;
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
clearTimeout(timer);
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
});
|