@cosmicstack/mercury-agent 1.0.5 → 1.1.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/README.md +74 -3
- package/dist/index.js +199 -129
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -1535,9 +1535,9 @@ var OpenAICompatProvider = class extends BaseProvider {
|
|
|
1535
1535
|
});
|
|
1536
1536
|
return {
|
|
1537
1537
|
text: result.text,
|
|
1538
|
-
inputTokens: result.usage?.
|
|
1539
|
-
outputTokens: result.usage?.
|
|
1540
|
-
totalTokens: (result.usage?.
|
|
1538
|
+
inputTokens: result.usage?.inputTokens ?? 0,
|
|
1539
|
+
outputTokens: result.usage?.outputTokens ?? 0,
|
|
1540
|
+
totalTokens: (result.usage?.inputTokens ?? 0) + (result.usage?.outputTokens ?? 0),
|
|
1541
1541
|
model: this.model,
|
|
1542
1542
|
provider: this.name
|
|
1543
1543
|
};
|
|
@@ -1585,9 +1585,9 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
1585
1585
|
});
|
|
1586
1586
|
return {
|
|
1587
1587
|
text: result.text,
|
|
1588
|
-
inputTokens: result.usage?.
|
|
1589
|
-
outputTokens: result.usage?.
|
|
1590
|
-
totalTokens: (result.usage?.
|
|
1588
|
+
inputTokens: result.usage?.inputTokens ?? 0,
|
|
1589
|
+
outputTokens: result.usage?.outputTokens ?? 0,
|
|
1590
|
+
totalTokens: (result.usage?.inputTokens ?? 0) + (result.usage?.outputTokens ?? 0),
|
|
1591
1591
|
model: this.model,
|
|
1592
1592
|
provider: this.name
|
|
1593
1593
|
};
|
|
@@ -1611,6 +1611,38 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
1611
1611
|
}
|
|
1612
1612
|
};
|
|
1613
1613
|
|
|
1614
|
+
// src/providers/deepseek.ts
|
|
1615
|
+
import { createDeepSeek } from "@ai-sdk/deepseek";
|
|
1616
|
+
var DeepSeekProvider = class extends BaseProvider {
|
|
1617
|
+
name;
|
|
1618
|
+
model;
|
|
1619
|
+
modelInstance;
|
|
1620
|
+
isReasoner;
|
|
1621
|
+
constructor(config) {
|
|
1622
|
+
super(config);
|
|
1623
|
+
this.name = config.name;
|
|
1624
|
+
this.model = config.model;
|
|
1625
|
+
this.isReasoner = config.model === "deepseek-reasoner";
|
|
1626
|
+
const client = createDeepSeek({
|
|
1627
|
+
apiKey: config.apiKey,
|
|
1628
|
+
baseURL: config.baseUrl
|
|
1629
|
+
});
|
|
1630
|
+
this.modelInstance = client(config.model);
|
|
1631
|
+
}
|
|
1632
|
+
async generateText(_prompt, _systemPrompt) {
|
|
1633
|
+
throw new Error("Use getModelInstance() with the AI SDK agent loop");
|
|
1634
|
+
}
|
|
1635
|
+
async *streamText(_prompt, _systemPrompt) {
|
|
1636
|
+
throw new Error("Use getModelInstance() with the AI SDK agent loop");
|
|
1637
|
+
}
|
|
1638
|
+
isAvailable() {
|
|
1639
|
+
return this.config.apiKey.length > 0;
|
|
1640
|
+
}
|
|
1641
|
+
getModelInstance() {
|
|
1642
|
+
return this.modelInstance;
|
|
1643
|
+
}
|
|
1644
|
+
};
|
|
1645
|
+
|
|
1614
1646
|
// src/providers/ollama.ts
|
|
1615
1647
|
import { createOllama } from "ollama-ai-provider";
|
|
1616
1648
|
var OllamaProvider = class extends BaseProvider {
|
|
@@ -1668,6 +1700,8 @@ var ProviderRegistry = class {
|
|
|
1668
1700
|
let provider;
|
|
1669
1701
|
if (pc.name === "anthropic") {
|
|
1670
1702
|
provider = new AnthropicProvider(pc);
|
|
1703
|
+
} else if (pc.name === "deepseek") {
|
|
1704
|
+
provider = new DeepSeekProvider(pc);
|
|
1671
1705
|
} else if (pc.name === "ollamaCloud" || pc.name === "ollamaLocal") {
|
|
1672
1706
|
provider = new OllamaProvider(pc);
|
|
1673
1707
|
} else {
|
|
@@ -1720,7 +1754,7 @@ var ProviderRegistry = class {
|
|
|
1720
1754
|
};
|
|
1721
1755
|
|
|
1722
1756
|
// src/core/agent.ts
|
|
1723
|
-
import { generateText as generateText3, streamText as streamText3 } from "ai";
|
|
1757
|
+
import { generateText as generateText3, streamText as streamText3, stepCountIs } from "ai";
|
|
1724
1758
|
|
|
1725
1759
|
// src/core/lifecycle.ts
|
|
1726
1760
|
var VALID_TRANSITIONS = [
|
|
@@ -2409,27 +2443,53 @@ var CLIChannel = class extends BaseChannel {
|
|
|
2409
2443
|
this.endOutput();
|
|
2410
2444
|
return full2;
|
|
2411
2445
|
}
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2446
|
+
const startTime = Date.now();
|
|
2447
|
+
const headerLines = ["", chalk3.cyan(` ${this.agentName}:`), ""];
|
|
2448
|
+
for (const line of headerLines) {
|
|
2449
|
+
console.log(line);
|
|
2450
|
+
}
|
|
2451
|
+
const indent = " ";
|
|
2452
|
+
const cols = process.stdout.columns || 80;
|
|
2453
|
+
const contentCols = Math.max(1, cols - indent.length);
|
|
2454
|
+
let visualLines = headerLines.length;
|
|
2455
|
+
let pendingIndent = true;
|
|
2456
|
+
let lineLen = 0;
|
|
2416
2457
|
let full = "";
|
|
2417
2458
|
for await (const chunk of content) {
|
|
2418
|
-
process.stdout.write(chunk);
|
|
2419
2459
|
full += chunk;
|
|
2460
|
+
for (let i = 0; i < chunk.length; i++) {
|
|
2461
|
+
const ch = chunk[i];
|
|
2462
|
+
if (ch === "\n") {
|
|
2463
|
+
visualLines += Math.max(1, Math.ceil((lineLen + indent.length) / cols));
|
|
2464
|
+
process.stdout.write("\n");
|
|
2465
|
+
lineLen = 0;
|
|
2466
|
+
pendingIndent = true;
|
|
2467
|
+
} else {
|
|
2468
|
+
if (pendingIndent) {
|
|
2469
|
+
process.stdout.write(indent);
|
|
2470
|
+
pendingIndent = false;
|
|
2471
|
+
}
|
|
2472
|
+
process.stdout.write(ch);
|
|
2473
|
+
lineLen++;
|
|
2474
|
+
}
|
|
2475
|
+
}
|
|
2420
2476
|
}
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
process.stdout.write("\
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
return full;
|
|
2477
|
+
if (lineLen > 0) {
|
|
2478
|
+
visualLines += Math.max(1, Math.ceil((lineLen + indent.length) / cols));
|
|
2479
|
+
process.stdout.write("\n");
|
|
2480
|
+
} else {
|
|
2481
|
+
visualLines += 1;
|
|
2427
2482
|
}
|
|
2428
|
-
|
|
2483
|
+
this.streamActive = false;
|
|
2484
|
+
process.stdout.write(`\x1B[${visualLines}A`);
|
|
2429
2485
|
process.stdout.write("\x1B[J");
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2486
|
+
if (full.trim()) {
|
|
2487
|
+
const block = this.formatBlock(this.agentName, "", full);
|
|
2488
|
+
for (const line of block) {
|
|
2489
|
+
console.log(line);
|
|
2490
|
+
}
|
|
2491
|
+
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
2492
|
+
console.log(chalk3.dim(" " + "\u2500".repeat(50 - elapsed.length - 4) + " " + elapsed + "s"));
|
|
2433
2493
|
}
|
|
2434
2494
|
this.endOutput();
|
|
2435
2495
|
return full;
|
|
@@ -3859,6 +3919,7 @@ You can override this:
|
|
|
3859
3919
|
}
|
|
3860
3920
|
for (const provider of fallbackIterator) {
|
|
3861
3921
|
try {
|
|
3922
|
+
const deepseekProviderOptions = provider instanceof DeepSeekProvider && provider.isReasoner ? { deepseek: { thinking: { type: "enabled" } } } : void 0;
|
|
3862
3923
|
logger.info({ provider: provider.name, model: provider.getModel(), steps: MAX_STEPS, stream: canStream }, "Generating agentic response");
|
|
3863
3924
|
if (canStream && channel) {
|
|
3864
3925
|
const streamResult = streamText3({
|
|
@@ -3866,8 +3927,9 @@ You can override this:
|
|
|
3866
3927
|
system: systemPrompt,
|
|
3867
3928
|
messages,
|
|
3868
3929
|
tools: this.capabilities.getTools(),
|
|
3869
|
-
|
|
3930
|
+
stopWhen: stepCountIs(MAX_STEPS),
|
|
3870
3931
|
abortSignal: loopAbortController.signal,
|
|
3932
|
+
...deepseekProviderOptions ? { providerOptions: deepseekProviderOptions } : {},
|
|
3871
3933
|
onStepFinish: async ({ toolCalls, toolResults }) => {
|
|
3872
3934
|
if (toolCalls && toolResults && toolCalls.length > 0) {
|
|
3873
3935
|
const names = toolCalls.map((tc) => tc.toolName).join(", ");
|
|
@@ -3877,7 +3939,7 @@ You can override this:
|
|
|
3877
3939
|
const tr = toolResults[i];
|
|
3878
3940
|
const resultStr = typeof tr?.result === "string" ? tr.result : JSON.stringify(tr?.result ?? "");
|
|
3879
3941
|
const failed = resultStr.length < 5e3 && (resultStr.startsWith("Error:") || resultStr.startsWith("\u26A0") || resultStr.includes("exited with code") || resultStr.includes("Command failed") || resultStr.startsWith("Command exited with code"));
|
|
3880
|
-
loopDetector.record(tc.toolName, tc.
|
|
3942
|
+
loopDetector.record(tc.toolName, tc.input, failed);
|
|
3881
3943
|
}
|
|
3882
3944
|
if (loopDetector.detectAbsoluteLimit()) {
|
|
3883
3945
|
logger.warn("Absolute tool call limit reached \u2014 aborting");
|
|
@@ -3935,7 +3997,7 @@ You can override this:
|
|
|
3935
3997
|
if (channel && msg.channelType !== "internal") {
|
|
3936
3998
|
if (channel instanceof CLIChannel) {
|
|
3937
3999
|
for (const tc of toolCalls) {
|
|
3938
|
-
await channel.sendToolFeedback(tc.toolName, tc.
|
|
4000
|
+
await channel.sendToolFeedback(tc.toolName, tc.input).catch(() => {
|
|
3939
4001
|
});
|
|
3940
4002
|
}
|
|
3941
4003
|
if (toolResults) {
|
|
@@ -3950,7 +4012,7 @@ You can override this:
|
|
|
3950
4012
|
} else if (channel instanceof TelegramChannel) {
|
|
3951
4013
|
const tgCh = channel;
|
|
3952
4014
|
for (const tc of toolCalls) {
|
|
3953
|
-
await tgCh.sendToolFeedback(tc.toolName, tc.
|
|
4015
|
+
await tgCh.sendToolFeedback(tc.toolName, tc.input, msg.channelId).catch(() => {
|
|
3954
4016
|
});
|
|
3955
4017
|
}
|
|
3956
4018
|
if (toolResults) {
|
|
@@ -4016,7 +4078,8 @@ You can override this:
|
|
|
4016
4078
|
const [usage] = await Promise.all([
|
|
4017
4079
|
streamResult.usage
|
|
4018
4080
|
]);
|
|
4019
|
-
|
|
4081
|
+
const streamReasoning = await streamResult.reasoning;
|
|
4082
|
+
result = { text: fullText, usage, reasoning: streamReasoning };
|
|
4020
4083
|
streamedText = fullText;
|
|
4021
4084
|
loopDetector.recordStepText(fullText);
|
|
4022
4085
|
} else {
|
|
@@ -4025,8 +4088,9 @@ You can override this:
|
|
|
4025
4088
|
system: systemPrompt,
|
|
4026
4089
|
messages,
|
|
4027
4090
|
tools: this.capabilities.getTools(),
|
|
4028
|
-
|
|
4091
|
+
stopWhen: stepCountIs(MAX_STEPS),
|
|
4029
4092
|
abortSignal: loopAbortController.signal,
|
|
4093
|
+
...deepseekProviderOptions ? { providerOptions: deepseekProviderOptions } : {},
|
|
4030
4094
|
onStepFinish: async ({ toolCalls, toolResults }) => {
|
|
4031
4095
|
if (toolCalls && toolResults && toolCalls.length > 0) {
|
|
4032
4096
|
const names = toolCalls.map((tc) => tc.toolName).join(", ");
|
|
@@ -4036,7 +4100,7 @@ You can override this:
|
|
|
4036
4100
|
const tr = toolResults[i];
|
|
4037
4101
|
const resultStr = typeof tr?.result === "string" ? tr.result : JSON.stringify(tr?.result ?? "");
|
|
4038
4102
|
const failed = resultStr.length < 5e3 && (resultStr.startsWith("Error:") || resultStr.startsWith("\u26A0") || resultStr.includes("exited with code") || resultStr.includes("Command failed") || resultStr.startsWith("Command exited with code"));
|
|
4039
|
-
loopDetector.record(tc.toolName, tc.
|
|
4103
|
+
loopDetector.record(tc.toolName, tc.input, failed);
|
|
4040
4104
|
}
|
|
4041
4105
|
if (loopDetector.detectAbsoluteLimit()) {
|
|
4042
4106
|
logger.warn("Absolute tool call limit reached \u2014 aborting");
|
|
@@ -4094,7 +4158,7 @@ You can override this:
|
|
|
4094
4158
|
if (channel && msg.channelType !== "internal") {
|
|
4095
4159
|
if (channel instanceof CLIChannel) {
|
|
4096
4160
|
for (const tc of toolCalls) {
|
|
4097
|
-
await channel.sendToolFeedback(tc.toolName, tc.
|
|
4161
|
+
await channel.sendToolFeedback(tc.toolName, tc.input).catch(() => {
|
|
4098
4162
|
});
|
|
4099
4163
|
}
|
|
4100
4164
|
if (toolResults) {
|
|
@@ -4109,7 +4173,7 @@ You can override this:
|
|
|
4109
4173
|
} else if (channel instanceof TelegramChannel) {
|
|
4110
4174
|
const tgCh = channel;
|
|
4111
4175
|
for (const tc of toolCalls) {
|
|
4112
|
-
await tgCh.sendToolFeedback(tc.toolName, tc.
|
|
4176
|
+
await tgCh.sendToolFeedback(tc.toolName, tc.input, msg.channelId).catch(() => {
|
|
4113
4177
|
});
|
|
4114
4178
|
}
|
|
4115
4179
|
if (toolResults) {
|
|
@@ -4195,9 +4259,9 @@ You can override this:
|
|
|
4195
4259
|
this.tokenBudget.recordUsage({
|
|
4196
4260
|
provider: usedProvider.name,
|
|
4197
4261
|
model: usedProvider.model,
|
|
4198
|
-
inputTokens: result.usage?.
|
|
4199
|
-
outputTokens: result.usage?.
|
|
4200
|
-
totalTokens: (result.usage?.
|
|
4262
|
+
inputTokens: result.usage?.inputTokens ?? 0,
|
|
4263
|
+
outputTokens: result.usage?.outputTokens ?? 0,
|
|
4264
|
+
totalTokens: (result.usage?.inputTokens ?? 0) + (result.usage?.outputTokens ?? 0),
|
|
4201
4265
|
channelType: msg.channelType
|
|
4202
4266
|
});
|
|
4203
4267
|
this.shortTerm.add(msg.channelId, {
|
|
@@ -4211,7 +4275,8 @@ You can override this:
|
|
|
4211
4275
|
timestamp: Date.now(),
|
|
4212
4276
|
role: "assistant",
|
|
4213
4277
|
content: finalText,
|
|
4214
|
-
tokenCount: (result.usage?.
|
|
4278
|
+
tokenCount: (result.usage?.inputTokens ?? 0) + (result.usage?.outputTokens ?? 0),
|
|
4279
|
+
reasoning: result.reasoning || void 0
|
|
4215
4280
|
});
|
|
4216
4281
|
this.episodic.record({
|
|
4217
4282
|
type: "message",
|
|
@@ -4407,14 +4472,14 @@ All actions auto-approved for this run.`,
|
|
|
4407
4472
|
{ role: "user", content: `User: ${userMessage}
|
|
4408
4473
|
Assistant: ${agentResponse}` }
|
|
4409
4474
|
],
|
|
4410
|
-
|
|
4475
|
+
maxOutputTokens: 400
|
|
4411
4476
|
});
|
|
4412
4477
|
this.tokenBudget.recordUsage({
|
|
4413
4478
|
provider: provider.name,
|
|
4414
4479
|
model: provider.getModel(),
|
|
4415
|
-
inputTokens: result.usage?.
|
|
4416
|
-
outputTokens: result.usage?.
|
|
4417
|
-
totalTokens: (result.usage?.
|
|
4480
|
+
inputTokens: result.usage?.inputTokens ?? 0,
|
|
4481
|
+
outputTokens: result.usage?.outputTokens ?? 0,
|
|
4482
|
+
totalTokens: (result.usage?.inputTokens ?? 0) + (result.usage?.outputTokens ?? 0),
|
|
4418
4483
|
channelType: "internal"
|
|
4419
4484
|
});
|
|
4420
4485
|
const text = result.text.trim();
|
|
@@ -4511,6 +4576,11 @@ Or use /budget override, /budget reset, /budget set <number> anytime.`,
|
|
|
4511
4576
|
await channel.send(ctx.manual(), channelId);
|
|
4512
4577
|
return true;
|
|
4513
4578
|
}
|
|
4579
|
+
if (cmd === "/exit" || cmd === "/quit") {
|
|
4580
|
+
await channel.send("Goodbye! Shutting down Mercury...", channelId);
|
|
4581
|
+
this.shutdown();
|
|
4582
|
+
return true;
|
|
4583
|
+
}
|
|
4514
4584
|
if (cmd === "/status") {
|
|
4515
4585
|
const config = ctx.config();
|
|
4516
4586
|
const budget = ctx.tokenBudget();
|
|
@@ -5816,16 +5886,16 @@ Allow access?`;
|
|
|
5816
5886
|
};
|
|
5817
5887
|
|
|
5818
5888
|
// src/capabilities/filesystem/read-file.ts
|
|
5819
|
-
import { tool } from "ai";
|
|
5889
|
+
import { tool, zodSchema } from "ai";
|
|
5820
5890
|
import { z } from "zod";
|
|
5821
5891
|
import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
|
|
5822
5892
|
import { resolve as resolve4, isAbsolute } from "path";
|
|
5823
5893
|
function createReadFileTool(permissions, getCwd) {
|
|
5824
5894
|
return tool({
|
|
5825
5895
|
description: "Read the contents of a file. The path must be within an allowed scope.",
|
|
5826
|
-
|
|
5896
|
+
inputSchema: zodSchema(z.object({
|
|
5827
5897
|
path: z.string().describe("Absolute or relative path to the file")
|
|
5828
|
-
}),
|
|
5898
|
+
})),
|
|
5829
5899
|
execute: async ({ path: path3 }) => {
|
|
5830
5900
|
const resolved = isAbsolute(path3) ? resolve4(path3) : resolve4(getCwd(), path3);
|
|
5831
5901
|
const check = await permissions.checkFsAccess(resolved, "read");
|
|
@@ -5853,17 +5923,17 @@ function createReadFileTool(permissions, getCwd) {
|
|
|
5853
5923
|
}
|
|
5854
5924
|
|
|
5855
5925
|
// src/capabilities/filesystem/write-file.ts
|
|
5856
|
-
import { tool as tool2 } from "ai";
|
|
5926
|
+
import { tool as tool2, zodSchema as zodSchema2 } from "ai";
|
|
5857
5927
|
import { z as z2 } from "zod";
|
|
5858
5928
|
import { existsSync as existsSync9, writeFileSync as writeFileSync7 } from "fs";
|
|
5859
5929
|
import { resolve as resolve5, isAbsolute as isAbsolute2 } from "path";
|
|
5860
5930
|
function createWriteFileTool(permissions, getCwd) {
|
|
5861
5931
|
return tool2({
|
|
5862
5932
|
description: "Write content to an existing file. The path must be within a writable scope.",
|
|
5863
|
-
|
|
5933
|
+
inputSchema: zodSchema2(z2.object({
|
|
5864
5934
|
path: z2.string().describe("Absolute or relative path to the file"),
|
|
5865
5935
|
content: z2.string().describe("The content to write to the file")
|
|
5866
|
-
}),
|
|
5936
|
+
})),
|
|
5867
5937
|
execute: async ({ path: path3, content }) => {
|
|
5868
5938
|
const resolved = isAbsolute2(path3) ? resolve5(path3) : resolve5(getCwd(), path3);
|
|
5869
5939
|
const check = await permissions.checkFsAccess(resolved, "write");
|
|
@@ -5885,17 +5955,17 @@ function createWriteFileTool(permissions, getCwd) {
|
|
|
5885
5955
|
}
|
|
5886
5956
|
|
|
5887
5957
|
// src/capabilities/filesystem/create-file.ts
|
|
5888
|
-
import { tool as tool3 } from "ai";
|
|
5958
|
+
import { tool as tool3, zodSchema as zodSchema3 } from "ai";
|
|
5889
5959
|
import { z as z3 } from "zod";
|
|
5890
5960
|
import { existsSync as existsSync10, writeFileSync as writeFileSync8, mkdirSync as mkdirSync8 } from "fs";
|
|
5891
5961
|
import { resolve as resolve6, dirname as dirname3, isAbsolute as isAbsolute3 } from "path";
|
|
5892
5962
|
function createCreateFileTool(permissions, getCwd) {
|
|
5893
5963
|
return tool3({
|
|
5894
5964
|
description: "Create a new file with the given content. Also creates parent directories if needed. The path must be within a writable scope.",
|
|
5895
|
-
|
|
5965
|
+
inputSchema: zodSchema3(z3.object({
|
|
5896
5966
|
path: z3.string().describe("Absolute or relative path for the new file"),
|
|
5897
5967
|
content: z3.string().describe("The content of the new file")
|
|
5898
|
-
}),
|
|
5968
|
+
})),
|
|
5899
5969
|
execute: async ({ path: path3, content }) => {
|
|
5900
5970
|
const resolved = isAbsolute3(path3) ? resolve6(path3) : resolve6(getCwd(), path3);
|
|
5901
5971
|
const check = await permissions.checkFsAccess(resolved, "write");
|
|
@@ -5921,16 +5991,16 @@ function createCreateFileTool(permissions, getCwd) {
|
|
|
5921
5991
|
}
|
|
5922
5992
|
|
|
5923
5993
|
// src/capabilities/filesystem/list-dir.ts
|
|
5924
|
-
import { tool as tool4 } from "ai";
|
|
5994
|
+
import { tool as tool4, zodSchema as zodSchema4 } from "ai";
|
|
5925
5995
|
import { z as z4 } from "zod";
|
|
5926
5996
|
import { existsSync as existsSync11, readdirSync as readdirSync2, statSync } from "fs";
|
|
5927
5997
|
import { resolve as resolve7, isAbsolute as isAbsolute4, join as join9 } from "path";
|
|
5928
5998
|
function createListDirTool(permissions, getCwd) {
|
|
5929
5999
|
return tool4({
|
|
5930
6000
|
description: "List the contents of a directory. Shows file names, types, and sizes.",
|
|
5931
|
-
|
|
6001
|
+
inputSchema: zodSchema4(z4.object({
|
|
5932
6002
|
path: z4.string().describe("Absolute or relative path to the directory")
|
|
5933
|
-
}),
|
|
6003
|
+
})),
|
|
5934
6004
|
execute: async ({ path: path3 }) => {
|
|
5935
6005
|
const resolved = isAbsolute4(path3) ? resolve7(path3) : resolve7(getCwd(), path3);
|
|
5936
6006
|
const check = await permissions.checkFsAccess(resolved, "read");
|
|
@@ -5976,16 +6046,16 @@ function formatSize(bytes) {
|
|
|
5976
6046
|
}
|
|
5977
6047
|
|
|
5978
6048
|
// src/capabilities/filesystem/delete-file.ts
|
|
5979
|
-
import { tool as tool5 } from "ai";
|
|
6049
|
+
import { tool as tool5, zodSchema as zodSchema5 } from "ai";
|
|
5980
6050
|
import { z as z5 } from "zod";
|
|
5981
6051
|
import { existsSync as existsSync12, unlinkSync as unlinkSync2 } from "fs";
|
|
5982
6052
|
import { resolve as resolve8, isAbsolute as isAbsolute5 } from "path";
|
|
5983
6053
|
function createDeleteFileTool(permissions, getCwd) {
|
|
5984
6054
|
return tool5({
|
|
5985
6055
|
description: "Delete a file. This action cannot be undone. The path must be within a writable scope. Always asks for confirmation.",
|
|
5986
|
-
|
|
6056
|
+
inputSchema: zodSchema5(z5.object({
|
|
5987
6057
|
path: z5.string().describe("Absolute or relative path to the file to delete")
|
|
5988
|
-
}),
|
|
6058
|
+
})),
|
|
5989
6059
|
execute: async ({ path: path3 }) => {
|
|
5990
6060
|
const resolved = isAbsolute5(path3) ? resolve8(path3) : resolve8(getCwd(), path3);
|
|
5991
6061
|
const check = await permissions.checkFsAccess(resolved, "write");
|
|
@@ -6011,18 +6081,18 @@ function createDeleteFileTool(permissions, getCwd) {
|
|
|
6011
6081
|
}
|
|
6012
6082
|
|
|
6013
6083
|
// src/capabilities/filesystem/edit-file.ts
|
|
6014
|
-
import { tool as tool6 } from "ai";
|
|
6084
|
+
import { tool as tool6, zodSchema as zodSchema6 } from "ai";
|
|
6015
6085
|
import { z as z6 } from "zod";
|
|
6016
6086
|
import { readFileSync as readFileSync9, writeFileSync as writeFileSync9 } from "fs";
|
|
6017
6087
|
import { resolve as resolve9, isAbsolute as isAbsolute6 } from "path";
|
|
6018
6088
|
function createEditFileTool(permissions, getCwd) {
|
|
6019
6089
|
return tool6({
|
|
6020
6090
|
description: "Edit a file by replacing an exact string match with new content. Use this instead of write_file when you only need to change part of a file. The old_string must match exactly (including whitespace and indentation). Fails if old_string is not found or found multiple times.",
|
|
6021
|
-
|
|
6091
|
+
inputSchema: zodSchema6(z6.object({
|
|
6022
6092
|
path: z6.string().describe("Absolute or relative path to the file"),
|
|
6023
6093
|
old_string: z6.string().describe("The exact text to find in the file (must match exactly)"),
|
|
6024
6094
|
new_string: z6.string().describe("The text to replace it with")
|
|
6025
|
-
}),
|
|
6095
|
+
})),
|
|
6026
6096
|
execute: async ({ path: path3, old_string, new_string }) => {
|
|
6027
6097
|
const resolved = isAbsolute6(path3) ? resolve9(path3) : resolve9(getCwd(), path3);
|
|
6028
6098
|
const fsCheck = await permissions.checkFsAccess(resolved, "write");
|
|
@@ -6055,16 +6125,16 @@ function createEditFileTool(permissions, getCwd) {
|
|
|
6055
6125
|
}
|
|
6056
6126
|
|
|
6057
6127
|
// src/capabilities/filesystem/send-file.ts
|
|
6058
|
-
import { tool as tool7 } from "ai";
|
|
6128
|
+
import { tool as tool7, zodSchema as zodSchema7 } from "ai";
|
|
6059
6129
|
import { z as z7 } from "zod";
|
|
6060
6130
|
import { existsSync as existsSync13, statSync as statSync2 } from "fs";
|
|
6061
6131
|
import { resolve as resolve10, basename as basename2, isAbsolute as isAbsolute7 } from "path";
|
|
6062
6132
|
function createSendFileTool(permissions, getCwd, sendFile) {
|
|
6063
6133
|
return tool7({
|
|
6064
6134
|
description: "Send a file to the user. On Telegram the file is uploaded as an attachment to the relevant approved recipients. On CLI the file path and size are displayed. The path must be within an allowed read scope.",
|
|
6065
|
-
|
|
6135
|
+
inputSchema: zodSchema7(z7.object({
|
|
6066
6136
|
path: z7.string().describe("Absolute or relative path to the file to send")
|
|
6067
|
-
}),
|
|
6137
|
+
})),
|
|
6068
6138
|
execute: async ({ path: path3 }) => {
|
|
6069
6139
|
const resolved = isAbsolute7(path3) ? resolve10(path3) : resolve10(getCwd(), path3);
|
|
6070
6140
|
const check = await permissions.checkFsAccess(resolved, "read");
|
|
@@ -6095,14 +6165,14 @@ function createSendFileTool(permissions, getCwd, sendFile) {
|
|
|
6095
6165
|
}
|
|
6096
6166
|
|
|
6097
6167
|
// src/capabilities/messaging/send-message.ts
|
|
6098
|
-
import { tool as tool8 } from "ai";
|
|
6168
|
+
import { tool as tool8, zodSchema as zodSchema8 } from "ai";
|
|
6099
6169
|
import { z as z8 } from "zod";
|
|
6100
6170
|
function createSendMessageTool(sendMessage) {
|
|
6101
6171
|
return tool8({
|
|
6102
6172
|
description: "Send a message through the configured outbound channel. For Telegram this sends to the approved Telegram recipients. Use this only when the user explicitly asks you to send something to Telegram or asks for scheduled results to be sent there.",
|
|
6103
|
-
|
|
6173
|
+
inputSchema: zodSchema8(z8.object({
|
|
6104
6174
|
content: z8.string().describe("The message content to send to the approved Telegram recipients")
|
|
6105
|
-
}),
|
|
6175
|
+
})),
|
|
6106
6176
|
execute: async ({ content }) => {
|
|
6107
6177
|
const trimmed = content.trim();
|
|
6108
6178
|
if (!trimmed) {
|
|
@@ -6119,16 +6189,16 @@ function createSendMessageTool(sendMessage) {
|
|
|
6119
6189
|
}
|
|
6120
6190
|
|
|
6121
6191
|
// src/capabilities/filesystem/approve-scope.ts
|
|
6122
|
-
import { tool as tool9 } from "ai";
|
|
6192
|
+
import { tool as tool9, zodSchema as zodSchema9 } from "ai";
|
|
6123
6193
|
import { z as z9 } from "zod";
|
|
6124
6194
|
import { resolve as resolve11, isAbsolute as isAbsolute8 } from "path";
|
|
6125
6195
|
function createApproveScopeTool(permissions, getCwd) {
|
|
6126
6196
|
return tool9({
|
|
6127
6197
|
description: 'Request user approval to access a directory outside current scopes. Use this when a file tool returns a permission denied error. The user gets an approval prompt (Allow/Always/Deny buttons on Telegram, yes/always/no on CLI). "Allow" grants session-only access. "Always" persists to disk. After approval, retry the original file operation.',
|
|
6128
|
-
|
|
6198
|
+
inputSchema: zodSchema9(z9.object({
|
|
6129
6199
|
path: z9.string().describe("The directory path to request access to"),
|
|
6130
6200
|
mode: z9.enum(["read", "write"]).describe("The access mode needed")
|
|
6131
|
-
}),
|
|
6201
|
+
})),
|
|
6132
6202
|
execute: async ({ path: path3, mode }) => {
|
|
6133
6203
|
const resolved = isAbsolute8(path3) ? resolve11(path3) : resolve11(getCwd(), path3);
|
|
6134
6204
|
const result = await permissions.requestScopeExternal(resolved, mode);
|
|
@@ -6141,7 +6211,7 @@ function createApproveScopeTool(permissions, getCwd) {
|
|
|
6141
6211
|
}
|
|
6142
6212
|
|
|
6143
6213
|
// src/capabilities/shell/run-command.ts
|
|
6144
|
-
import { tool as tool10 } from "ai";
|
|
6214
|
+
import { tool as tool10, zodSchema as zodSchema10 } from "ai";
|
|
6145
6215
|
import { z as z10 } from "zod";
|
|
6146
6216
|
import { execSync } from "child_process";
|
|
6147
6217
|
import { resolve as resolve12, isAbsolute as isAbsolute9 } from "path";
|
|
@@ -6153,9 +6223,9 @@ function createRunCommandTool(permissions, getCwd, setCwd) {
|
|
|
6153
6223
|
Blocked commands (sudo, rm -rf /, etc.) are never executed.
|
|
6154
6224
|
Auto-approved commands (ls, cat, git status, curl, etc.) run without asking.
|
|
6155
6225
|
Other commands require user approval.`,
|
|
6156
|
-
|
|
6226
|
+
inputSchema: zodSchema10(z10.object({
|
|
6157
6227
|
command: z10.string().describe("The shell command to execute")
|
|
6158
|
-
}),
|
|
6228
|
+
})),
|
|
6159
6229
|
execute: async ({ command }) => {
|
|
6160
6230
|
const check = await permissions.checkShellCommand(command);
|
|
6161
6231
|
if (!check.allowed) {
|
|
@@ -6219,16 +6289,16 @@ function detectCd(command, currentCwd, setCwd) {
|
|
|
6219
6289
|
}
|
|
6220
6290
|
|
|
6221
6291
|
// src/capabilities/shell/cd.ts
|
|
6222
|
-
import { tool as tool11 } from "ai";
|
|
6292
|
+
import { tool as tool11, zodSchema as zodSchema11 } from "ai";
|
|
6223
6293
|
import { z as z11 } from "zod";
|
|
6224
6294
|
import { resolve as resolve13, isAbsolute as isAbsolute10 } from "path";
|
|
6225
6295
|
import { existsSync as existsSync15, statSync as statSync3 } from "fs";
|
|
6226
6296
|
function createCdTool(getCwd, setCwd) {
|
|
6227
6297
|
return tool11({
|
|
6228
6298
|
description: "Change the current working directory. All subsequent file operations, shell commands, and git operations will use this directory. Use this before running commands in a specific project folder.",
|
|
6229
|
-
|
|
6299
|
+
inputSchema: zodSchema11(z11.object({
|
|
6230
6300
|
path: z11.string().describe("The directory to change to. Can be absolute or relative to the current directory.")
|
|
6231
|
-
}),
|
|
6301
|
+
})),
|
|
6232
6302
|
execute: async ({ path: path3 }) => {
|
|
6233
6303
|
const cwd = getCwd();
|
|
6234
6304
|
const resolved = isAbsolute10(path3) ? resolve13(path3) : resolve13(cwd, path3);
|
|
@@ -6250,14 +6320,14 @@ function createCdTool(getCwd, setCwd) {
|
|
|
6250
6320
|
}
|
|
6251
6321
|
|
|
6252
6322
|
// src/capabilities/shell/approve-command.ts
|
|
6253
|
-
import { tool as tool12 } from "ai";
|
|
6323
|
+
import { tool as tool12, zodSchema as zodSchema12 } from "ai";
|
|
6254
6324
|
import { z as z12 } from "zod";
|
|
6255
6325
|
function createApproveCommandTool(permissions) {
|
|
6256
6326
|
return tool12({
|
|
6257
6327
|
description: 'Permanently approve a command type so it runs without asking in the future. Use this when the user says "always" or "always approve" for a command. For example, if the user says "always approve curl", call this with command="curl".',
|
|
6258
|
-
|
|
6328
|
+
inputSchema: zodSchema12(z12.object({
|
|
6259
6329
|
command: z12.string().describe('The base command to permanently approve (e.g. "curl", "docker", "npm")')
|
|
6260
|
-
}),
|
|
6330
|
+
})),
|
|
6261
6331
|
execute: async ({ command }) => {
|
|
6262
6332
|
const baseCmd = command.trim().split(/\s+/)[0];
|
|
6263
6333
|
permissions.addApprovedCommand(baseCmd);
|
|
@@ -6267,16 +6337,16 @@ function createApproveCommandTool(permissions) {
|
|
|
6267
6337
|
}
|
|
6268
6338
|
|
|
6269
6339
|
// src/capabilities/skills/install-skill.ts
|
|
6270
|
-
import { tool as tool13 } from "ai";
|
|
6340
|
+
import { tool as tool13, zodSchema as zodSchema13 } from "ai";
|
|
6271
6341
|
import { z as z13 } from "zod";
|
|
6272
6342
|
import { parse as parseYaml4 } from "yaml";
|
|
6273
6343
|
function createInstallSkillTool(skillLoader) {
|
|
6274
6344
|
return tool13({
|
|
6275
6345
|
description: "Install a new skill by providing SKILL.md markdown content or a URL. The content must have YAML frontmatter (---) with at least name and description fields.",
|
|
6276
|
-
|
|
6346
|
+
inputSchema: zodSchema13(z13.object({
|
|
6277
6347
|
content: z13.string().optional().describe("Raw SKILL.md markdown content with YAML frontmatter"),
|
|
6278
6348
|
url: z13.string().optional().describe("URL to fetch a SKILL.md from")
|
|
6279
|
-
}),
|
|
6349
|
+
})),
|
|
6280
6350
|
execute: async ({ content, url }) => {
|
|
6281
6351
|
let skillContent;
|
|
6282
6352
|
if (url && !content) {
|
|
@@ -6315,12 +6385,12 @@ function createInstallSkillTool(skillLoader) {
|
|
|
6315
6385
|
}
|
|
6316
6386
|
|
|
6317
6387
|
// src/capabilities/skills/list-skills.ts
|
|
6318
|
-
import { tool as tool14 } from "ai";
|
|
6388
|
+
import { tool as tool14, zodSchema as zodSchema14 } from "ai";
|
|
6319
6389
|
import { z as z14 } from "zod";
|
|
6320
6390
|
function createListSkillsTool(skillLoader) {
|
|
6321
6391
|
return tool14({
|
|
6322
6392
|
description: "List all installed skills with their names and descriptions.",
|
|
6323
|
-
|
|
6393
|
+
inputSchema: zodSchema14(z14.object({})),
|
|
6324
6394
|
execute: async () => {
|
|
6325
6395
|
const skills = skillLoader.getDiscovered();
|
|
6326
6396
|
if (skills.length === 0) {
|
|
@@ -6332,14 +6402,14 @@ function createListSkillsTool(skillLoader) {
|
|
|
6332
6402
|
}
|
|
6333
6403
|
|
|
6334
6404
|
// src/capabilities/skills/use-skill.ts
|
|
6335
|
-
import { tool as tool15 } from "ai";
|
|
6405
|
+
import { tool as tool15, zodSchema as zodSchema15 } from "ai";
|
|
6336
6406
|
import { z as z15 } from "zod";
|
|
6337
6407
|
function createUseSkillTool(skillLoader, permissions) {
|
|
6338
6408
|
return tool15({
|
|
6339
6409
|
description: "Load and invoke a skill by name. Returns the skill's full instructions which should be followed as guidance for the current task.",
|
|
6340
|
-
|
|
6410
|
+
inputSchema: zodSchema15(z15.object({
|
|
6341
6411
|
name: z15.string().describe("Name of the skill to invoke")
|
|
6342
|
-
}),
|
|
6412
|
+
})),
|
|
6343
6413
|
execute: async ({ name }) => {
|
|
6344
6414
|
const skill = skillLoader.load(name);
|
|
6345
6415
|
if (!skill) {
|
|
@@ -6365,19 +6435,19 @@ Allowed tools: ${skill["allowed-tools"].join(", ")}`;
|
|
|
6365
6435
|
}
|
|
6366
6436
|
|
|
6367
6437
|
// src/capabilities/scheduler/schedule-task.ts
|
|
6368
|
-
import { tool as tool16 } from "ai";
|
|
6438
|
+
import { tool as tool16, zodSchema as zodSchema16 } from "ai";
|
|
6369
6439
|
import { z as z16 } from "zod";
|
|
6370
6440
|
import cron2 from "node-cron";
|
|
6371
6441
|
function createScheduleTaskTool(scheduler, getContext) {
|
|
6372
6442
|
return tool16({
|
|
6373
6443
|
description: 'Schedule a task. Use "cron" for recurring tasks (e.g. "0 9 * * *" for daily at 9am) or "delay_seconds" for one-shot delayed tasks (e.g. 15 for "remind me in 15 seconds"). Provide exactly one of cron or delay_seconds.',
|
|
6374
|
-
|
|
6444
|
+
inputSchema: zodSchema16(z16.object({
|
|
6375
6445
|
cron: z16.string().optional().describe('Cron expression for recurring tasks (e.g. "0 9 * * *" for daily at 9am)'),
|
|
6376
6446
|
delay_seconds: z16.number().optional().describe('Delay in seconds for one-shot tasks (e.g. 15 for "remind me in 15 seconds")'),
|
|
6377
6447
|
description: z16.string().describe("Human-readable description of what this task does"),
|
|
6378
6448
|
prompt: z16.string().optional().describe("Prompt to send to the agent when the task fires"),
|
|
6379
6449
|
skill_name: z16.string().optional().describe("Name of a skill to invoke when the task fires")
|
|
6380
|
-
}),
|
|
6450
|
+
})),
|
|
6381
6451
|
execute: async ({ cron: cronExpr, delay_seconds, description, prompt, skill_name }) => {
|
|
6382
6452
|
if (!cronExpr && !delay_seconds) {
|
|
6383
6453
|
return "Either cron or delay_seconds must be provided.";
|
|
@@ -6429,12 +6499,12 @@ function createScheduleTaskTool(scheduler, getContext) {
|
|
|
6429
6499
|
}
|
|
6430
6500
|
|
|
6431
6501
|
// src/capabilities/scheduler/list-tasks.ts
|
|
6432
|
-
import { tool as tool17 } from "ai";
|
|
6502
|
+
import { tool as tool17, zodSchema as zodSchema17 } from "ai";
|
|
6433
6503
|
import { z as z17 } from "zod";
|
|
6434
6504
|
function createListTasksTool(scheduler) {
|
|
6435
6505
|
return tool17({
|
|
6436
6506
|
description: "List all scheduled tasks with their cron expressions and descriptions.",
|
|
6437
|
-
|
|
6507
|
+
inputSchema: zodSchema17(z17.object({})),
|
|
6438
6508
|
execute: async () => {
|
|
6439
6509
|
const manifests = scheduler.getManifests();
|
|
6440
6510
|
if (manifests.length === 0) {
|
|
@@ -6449,14 +6519,14 @@ function createListTasksTool(scheduler) {
|
|
|
6449
6519
|
}
|
|
6450
6520
|
|
|
6451
6521
|
// src/capabilities/scheduler/cancel-task.ts
|
|
6452
|
-
import { tool as tool18 } from "ai";
|
|
6522
|
+
import { tool as tool18, zodSchema as zodSchema18 } from "ai";
|
|
6453
6523
|
import { z as z18 } from "zod";
|
|
6454
6524
|
function createCancelTaskTool(scheduler) {
|
|
6455
6525
|
return tool18({
|
|
6456
6526
|
description: "Cancel and remove a scheduled task by its ID.",
|
|
6457
|
-
|
|
6527
|
+
inputSchema: zodSchema18(z18.object({
|
|
6458
6528
|
id: z18.string().describe("ID of the scheduled task to cancel")
|
|
6459
|
-
}),
|
|
6529
|
+
})),
|
|
6460
6530
|
execute: async ({ id }) => {
|
|
6461
6531
|
const manifests = scheduler.getManifests();
|
|
6462
6532
|
const exists = manifests.some((m) => m.id === id);
|
|
@@ -6471,12 +6541,12 @@ function createCancelTaskTool(scheduler) {
|
|
|
6471
6541
|
}
|
|
6472
6542
|
|
|
6473
6543
|
// src/capabilities/system/budget-status.ts
|
|
6474
|
-
import { tool as tool19 } from "ai";
|
|
6544
|
+
import { tool as tool19, zodSchema as zodSchema19 } from "ai";
|
|
6475
6545
|
import { z as z19 } from "zod";
|
|
6476
6546
|
function createBudgetStatusTool(tokenBudget) {
|
|
6477
6547
|
return tool19({
|
|
6478
6548
|
description: "Check the current token budget status \u2014 how many tokens have been used today, how many remain, and what percentage is consumed.",
|
|
6479
|
-
|
|
6549
|
+
inputSchema: zodSchema19(z19.object({})),
|
|
6480
6550
|
execute: async () => {
|
|
6481
6551
|
return tokenBudget.getStatusText();
|
|
6482
6552
|
}
|
|
@@ -6484,15 +6554,15 @@ function createBudgetStatusTool(tokenBudget) {
|
|
|
6484
6554
|
}
|
|
6485
6555
|
|
|
6486
6556
|
// src/capabilities/git/git-status.ts
|
|
6487
|
-
import { tool as tool20 } from "ai";
|
|
6557
|
+
import { tool as tool20, zodSchema as zodSchema20 } from "ai";
|
|
6488
6558
|
import { z as z20 } from "zod";
|
|
6489
6559
|
import { execSync as execSync2 } from "child_process";
|
|
6490
6560
|
function createGitStatusTool(getCwd) {
|
|
6491
6561
|
return tool20({
|
|
6492
6562
|
description: "Show the working tree status. Returns staged, unstaged, and untracked files.",
|
|
6493
|
-
|
|
6563
|
+
inputSchema: zodSchema20(z20.object({
|
|
6494
6564
|
path: z20.string().optional().describe("Path to check (defaults to current directory)")
|
|
6495
|
-
}),
|
|
6565
|
+
})),
|
|
6496
6566
|
execute: async ({ path: path3 }) => {
|
|
6497
6567
|
try {
|
|
6498
6568
|
const cmd = path3 ? `git -C "${path3}" status --porcelain` : "git status --porcelain";
|
|
@@ -6507,16 +6577,16 @@ function createGitStatusTool(getCwd) {
|
|
|
6507
6577
|
}
|
|
6508
6578
|
|
|
6509
6579
|
// src/capabilities/git/git-diff.ts
|
|
6510
|
-
import { tool as tool21 } from "ai";
|
|
6580
|
+
import { tool as tool21, zodSchema as zodSchema21 } from "ai";
|
|
6511
6581
|
import { z as z21 } from "zod";
|
|
6512
6582
|
import { execSync as execSync3 } from "child_process";
|
|
6513
6583
|
function createGitDiffTool(getCwd) {
|
|
6514
6584
|
return tool21({
|
|
6515
6585
|
description: "Show changes between commits, commit and working tree, etc. Shows what has been modified.",
|
|
6516
|
-
|
|
6586
|
+
inputSchema: zodSchema21(z21.object({
|
|
6517
6587
|
path: z21.string().optional().describe("File or directory to diff"),
|
|
6518
6588
|
staged: z21.boolean().optional().describe("Show staged changes (cached) instead of unstaged")
|
|
6519
|
-
}),
|
|
6589
|
+
})),
|
|
6520
6590
|
execute: async ({ path: path3, staged }) => {
|
|
6521
6591
|
try {
|
|
6522
6592
|
let cmd = "git diff";
|
|
@@ -6534,16 +6604,16 @@ function createGitDiffTool(getCwd) {
|
|
|
6534
6604
|
}
|
|
6535
6605
|
|
|
6536
6606
|
// src/capabilities/git/git-log.ts
|
|
6537
|
-
import { tool as tool22 } from "ai";
|
|
6607
|
+
import { tool as tool22, zodSchema as zodSchema22 } from "ai";
|
|
6538
6608
|
import { z as z22 } from "zod";
|
|
6539
6609
|
import { execSync as execSync4 } from "child_process";
|
|
6540
6610
|
function createGitLogTool(getCwd) {
|
|
6541
6611
|
return tool22({
|
|
6542
6612
|
description: "Show commit logs. Returns recent commit history with hash, author, date, and message.",
|
|
6543
|
-
|
|
6613
|
+
inputSchema: zodSchema22(z22.object({
|
|
6544
6614
|
count: z22.number().optional().describe("Number of commits to show (default 10)"),
|
|
6545
6615
|
path: z22.string().optional().describe("File or directory to show log for")
|
|
6546
|
-
}),
|
|
6616
|
+
})),
|
|
6547
6617
|
execute: async ({ count, path: path3 }) => {
|
|
6548
6618
|
try {
|
|
6549
6619
|
const n = count ?? 10;
|
|
@@ -6560,15 +6630,15 @@ function createGitLogTool(getCwd) {
|
|
|
6560
6630
|
}
|
|
6561
6631
|
|
|
6562
6632
|
// src/capabilities/git/git-add.ts
|
|
6563
|
-
import { tool as tool23 } from "ai";
|
|
6633
|
+
import { tool as tool23, zodSchema as zodSchema23 } from "ai";
|
|
6564
6634
|
import { z as z23 } from "zod";
|
|
6565
6635
|
import { execSync as execSync5 } from "child_process";
|
|
6566
6636
|
function createGitAddTool(getCwd) {
|
|
6567
6637
|
return tool23({
|
|
6568
6638
|
description: "Add file contents to the index (staging area). Prepares files for commit.",
|
|
6569
|
-
|
|
6639
|
+
inputSchema: zodSchema23(z23.object({
|
|
6570
6640
|
paths: z23.array(z23.string()).describe("File paths to stage")
|
|
6571
|
-
}),
|
|
6641
|
+
})),
|
|
6572
6642
|
execute: async ({ paths }) => {
|
|
6573
6643
|
try {
|
|
6574
6644
|
const fileArgs = paths.map((p) => `"${p}"`).join(" ");
|
|
@@ -6582,7 +6652,7 @@ function createGitAddTool(getCwd) {
|
|
|
6582
6652
|
}
|
|
6583
6653
|
|
|
6584
6654
|
// src/capabilities/git/git-commit.ts
|
|
6585
|
-
import { tool as tool24 } from "ai";
|
|
6655
|
+
import { tool as tool24, zodSchema as zodSchema24 } from "ai";
|
|
6586
6656
|
import { z as z24 } from "zod";
|
|
6587
6657
|
import { execSync as execSync6 } from "child_process";
|
|
6588
6658
|
import { writeFileSync as writeFileSync10, unlinkSync as unlinkSync3 } from "fs";
|
|
@@ -6591,9 +6661,9 @@ var CO_AUTHOR = "Mercury <mercury@cosmicstack.org>";
|
|
|
6591
6661
|
function createGitCommitTool(getCwd) {
|
|
6592
6662
|
return tool24({
|
|
6593
6663
|
description: "Record changes to the repository. Creates a new commit with staged changes. Automatically includes a Co-authored-by trailer for attribution.",
|
|
6594
|
-
|
|
6664
|
+
inputSchema: zodSchema24(z24.object({
|
|
6595
6665
|
message: z24.string().describe("Commit message")
|
|
6596
|
-
}),
|
|
6666
|
+
})),
|
|
6597
6667
|
execute: async ({ message }) => {
|
|
6598
6668
|
try {
|
|
6599
6669
|
const fullMessage = `${message}
|
|
@@ -6628,16 +6698,16 @@ Co-authored-by: ${CO_AUTHOR}`;
|
|
|
6628
6698
|
}
|
|
6629
6699
|
|
|
6630
6700
|
// src/capabilities/git/git-push.ts
|
|
6631
|
-
import { tool as tool25 } from "ai";
|
|
6701
|
+
import { tool as tool25, zodSchema as zodSchema25 } from "ai";
|
|
6632
6702
|
import { z as z25 } from "zod";
|
|
6633
6703
|
import { execSync as execSync7 } from "child_process";
|
|
6634
6704
|
function createGitPushTool(permissions, getCwd) {
|
|
6635
6705
|
return tool25({
|
|
6636
6706
|
description: "Push commits to a remote repository. This modifies a remote and requires approval.",
|
|
6637
|
-
|
|
6707
|
+
inputSchema: zodSchema25(z25.object({
|
|
6638
6708
|
remote: z25.string().optional().describe("Remote name (default: origin)"),
|
|
6639
6709
|
branch: z25.string().optional().describe("Branch name (default: current branch)")
|
|
6640
|
-
}),
|
|
6710
|
+
})),
|
|
6641
6711
|
execute: async ({ remote, branch }) => {
|
|
6642
6712
|
const cmd = `git push ${remote || "origin"} ${branch || ""}`.trim();
|
|
6643
6713
|
const check = await permissions.checkShellCommand(cmd);
|
|
@@ -6661,7 +6731,7 @@ Ask the user for permission. If they approve, try again. If they say "always", u
|
|
|
6661
6731
|
}
|
|
6662
6732
|
|
|
6663
6733
|
// src/capabilities/github/create-pr.ts
|
|
6664
|
-
import { tool as tool26 } from "ai";
|
|
6734
|
+
import { tool as tool26, zodSchema as zodSchema26 } from "ai";
|
|
6665
6735
|
import { z as z26 } from "zod";
|
|
6666
6736
|
|
|
6667
6737
|
// src/utils/github.ts
|
|
@@ -6719,7 +6789,7 @@ async function githubRequest(path3, options = {}) {
|
|
|
6719
6789
|
function createCreatePrTool() {
|
|
6720
6790
|
return tool26({
|
|
6721
6791
|
description: "Create a pull request on GitHub. Requires GITHUB_TOKEN to be configured.",
|
|
6722
|
-
|
|
6792
|
+
inputSchema: zodSchema26(z26.object({
|
|
6723
6793
|
owner: z26.string().describe("Repository owner (username or org)"),
|
|
6724
6794
|
repo: z26.string().describe("Repository name"),
|
|
6725
6795
|
title: z26.string().describe("PR title"),
|
|
@@ -6727,7 +6797,7 @@ function createCreatePrTool() {
|
|
|
6727
6797
|
head: z26.string().describe("The branch containing the changes"),
|
|
6728
6798
|
base: z26.string().describe("The branch to merge into").default("main"),
|
|
6729
6799
|
draft: z26.boolean().describe("Create as draft PR").default(false)
|
|
6730
|
-
}),
|
|
6800
|
+
})),
|
|
6731
6801
|
execute: async ({ owner, repo, title, body, head, base, draft }) => {
|
|
6732
6802
|
try {
|
|
6733
6803
|
const result = await githubRequest(`/repos/${owner}/${repo}/pulls`, {
|
|
@@ -6745,17 +6815,17 @@ ${draft ? "(draft)" : ""} ${result.state}`;
|
|
|
6745
6815
|
}
|
|
6746
6816
|
|
|
6747
6817
|
// src/capabilities/github/review-pr.ts
|
|
6748
|
-
import { tool as tool27 } from "ai";
|
|
6818
|
+
import { tool as tool27, zodSchema as zodSchema27 } from "ai";
|
|
6749
6819
|
import { z as z27 } from "zod";
|
|
6750
6820
|
function createReviewPrTool() {
|
|
6751
6821
|
return tool27({
|
|
6752
6822
|
description: "Get details of a pull request including the diff. Reviews the PR and returns the title, body, changed files, and diff. Optionally post a review comment.",
|
|
6753
|
-
|
|
6823
|
+
inputSchema: zodSchema27(z27.object({
|
|
6754
6824
|
owner: z27.string().describe("Repository owner (username or org)"),
|
|
6755
6825
|
repo: z27.string().describe("Repository name"),
|
|
6756
6826
|
number: z27.number().describe("PR number"),
|
|
6757
6827
|
comment: z27.string().describe("Review comment to post on the PR (optional)").optional()
|
|
6758
|
-
}),
|
|
6828
|
+
})),
|
|
6759
6829
|
execute: async ({ owner, repo, number, comment }) => {
|
|
6760
6830
|
try {
|
|
6761
6831
|
const pr = await githubRequest(`/repos/${owner}/${repo}/pulls/${number}`);
|
|
@@ -6820,18 +6890,18 @@ Failed to post review comment: ${err.message}`;
|
|
|
6820
6890
|
}
|
|
6821
6891
|
|
|
6822
6892
|
// src/capabilities/github/list-issues.ts
|
|
6823
|
-
import { tool as tool28 } from "ai";
|
|
6893
|
+
import { tool as tool28, zodSchema as zodSchema28 } from "ai";
|
|
6824
6894
|
import { z as z28 } from "zod";
|
|
6825
6895
|
function createListIssuesTool() {
|
|
6826
6896
|
return tool28({
|
|
6827
6897
|
description: "List GitHub issues for a repository. Requires GITHUB_TOKEN.",
|
|
6828
|
-
|
|
6898
|
+
inputSchema: zodSchema28(z28.object({
|
|
6829
6899
|
owner: z28.string().describe("Repository owner (username or org)"),
|
|
6830
6900
|
repo: z28.string().describe("Repository name"),
|
|
6831
6901
|
state: z28.enum(["open", "closed", "all"]).describe("Filter by issue state").default("open"),
|
|
6832
6902
|
labels: z28.string().describe("Comma-separated label names to filter by (optional)").optional(),
|
|
6833
6903
|
limit: z28.number().describe("Maximum number of issues to return").default(10)
|
|
6834
|
-
}),
|
|
6904
|
+
})),
|
|
6835
6905
|
execute: async ({ owner, repo, state, labels, limit }) => {
|
|
6836
6906
|
try {
|
|
6837
6907
|
const params = new URLSearchParams();
|
|
@@ -6858,18 +6928,18 @@ ${lines.join("\n")}`;
|
|
|
6858
6928
|
}
|
|
6859
6929
|
|
|
6860
6930
|
// src/capabilities/github/create-issue.ts
|
|
6861
|
-
import { tool as tool29 } from "ai";
|
|
6931
|
+
import { tool as tool29, zodSchema as zodSchema29 } from "ai";
|
|
6862
6932
|
import { z as z29 } from "zod";
|
|
6863
6933
|
function createCreateIssueTool() {
|
|
6864
6934
|
return tool29({
|
|
6865
6935
|
description: "Create a new GitHub issue in a repository. Requires GITHUB_TOKEN.",
|
|
6866
|
-
|
|
6936
|
+
inputSchema: zodSchema29(z29.object({
|
|
6867
6937
|
owner: z29.string().describe("Repository owner (username or org)"),
|
|
6868
6938
|
repo: z29.string().describe("Repository name"),
|
|
6869
6939
|
title: z29.string().describe("Issue title"),
|
|
6870
6940
|
body: z29.string().describe("Issue description (markdown supported)").default(""),
|
|
6871
6941
|
labels: z29.array(z29.string()).describe("Label names to apply").optional()
|
|
6872
|
-
}),
|
|
6942
|
+
})),
|
|
6873
6943
|
execute: async ({ owner, repo, title, body, labels }) => {
|
|
6874
6944
|
try {
|
|
6875
6945
|
const payload = { title, body };
|
|
@@ -6888,7 +6958,7 @@ function createCreateIssueTool() {
|
|
|
6888
6958
|
}
|
|
6889
6959
|
|
|
6890
6960
|
// src/capabilities/github/github-api.ts
|
|
6891
|
-
import { tool as tool30 } from "ai";
|
|
6961
|
+
import { tool as tool30, zodSchema as zodSchema30 } from "ai";
|
|
6892
6962
|
import { z as z30 } from "zod";
|
|
6893
6963
|
var CO_AUTHOR_NAME = "Mercury";
|
|
6894
6964
|
var CO_AUTHOR_EMAIL = "mercury@cosmicstack.org";
|
|
@@ -6924,11 +6994,11 @@ Common operations you can perform:
|
|
|
6924
6994
|
- Any other GitHub API v3 endpoint.
|
|
6925
6995
|
|
|
6926
6996
|
IMPORTANT: When the user wants to push code or files to GitHub and git push fails (auth issues, no SSH key, etc.), use PUT /repos/{owner}/{repo}/contents/{path} to create or update files directly through the API. This bypasses local git and creates a commit with Mercury as co-author.`,
|
|
6927
|
-
|
|
6997
|
+
inputSchema: zodSchema30(z30.object({
|
|
6928
6998
|
path: z30.string().describe("Full API path (e.g., /repos/owner/repo/issues or /repos/owner/repo/contents/path/to/file)"),
|
|
6929
6999
|
method: z30.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).describe("HTTP method").default("GET"),
|
|
6930
7000
|
body: z30.string().describe("JSON body for write requests (as a JSON string)").optional()
|
|
6931
|
-
}),
|
|
7001
|
+
})),
|
|
6932
7002
|
execute: async ({ path: path3, method, body }) => {
|
|
6933
7003
|
try {
|
|
6934
7004
|
let parsedBody;
|
|
@@ -6957,7 +7027,7 @@ IMPORTANT: When the user wants to push code or files to GitHub and git push fail
|
|
|
6957
7027
|
}
|
|
6958
7028
|
|
|
6959
7029
|
// src/capabilities/web/fetch-url.ts
|
|
6960
|
-
import { tool as tool31 } from "ai";
|
|
7030
|
+
import { tool as tool31, zodSchema as zodSchema31 } from "ai";
|
|
6961
7031
|
import { z as z31 } from "zod";
|
|
6962
7032
|
var MAX_CONTENT_LENGTH = 15e3;
|
|
6963
7033
|
function stripHtml(html) {
|
|
@@ -6993,10 +7063,10 @@ function stripHtml(html) {
|
|
|
6993
7063
|
function createFetchUrlTool() {
|
|
6994
7064
|
return tool31({
|
|
6995
7065
|
description: "Fetch a URL and return its content as text. Strips HTML to readable markdown-like format. Useful for reading documentation, APIs, or web pages.",
|
|
6996
|
-
|
|
7066
|
+
inputSchema: zodSchema31(z31.object({
|
|
6997
7067
|
url: z31.string().describe("The URL to fetch"),
|
|
6998
7068
|
format: z31.enum(["text", "markdown"]).optional().describe("Output format (default: markdown)")
|
|
6999
|
-
}),
|
|
7069
|
+
})),
|
|
7000
7070
|
execute: async ({ url, format }) => {
|
|
7001
7071
|
const outputFormat = format ?? "markdown";
|
|
7002
7072
|
try {
|