@cosmicstack/mercury-agent 1.0.6 → 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 +158 -114
- 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 = [
|
|
@@ -3885,6 +3919,7 @@ You can override this:
|
|
|
3885
3919
|
}
|
|
3886
3920
|
for (const provider of fallbackIterator) {
|
|
3887
3921
|
try {
|
|
3922
|
+
const deepseekProviderOptions = provider instanceof DeepSeekProvider && provider.isReasoner ? { deepseek: { thinking: { type: "enabled" } } } : void 0;
|
|
3888
3923
|
logger.info({ provider: provider.name, model: provider.getModel(), steps: MAX_STEPS, stream: canStream }, "Generating agentic response");
|
|
3889
3924
|
if (canStream && channel) {
|
|
3890
3925
|
const streamResult = streamText3({
|
|
@@ -3892,8 +3927,9 @@ You can override this:
|
|
|
3892
3927
|
system: systemPrompt,
|
|
3893
3928
|
messages,
|
|
3894
3929
|
tools: this.capabilities.getTools(),
|
|
3895
|
-
|
|
3930
|
+
stopWhen: stepCountIs(MAX_STEPS),
|
|
3896
3931
|
abortSignal: loopAbortController.signal,
|
|
3932
|
+
...deepseekProviderOptions ? { providerOptions: deepseekProviderOptions } : {},
|
|
3897
3933
|
onStepFinish: async ({ toolCalls, toolResults }) => {
|
|
3898
3934
|
if (toolCalls && toolResults && toolCalls.length > 0) {
|
|
3899
3935
|
const names = toolCalls.map((tc) => tc.toolName).join(", ");
|
|
@@ -3903,7 +3939,7 @@ You can override this:
|
|
|
3903
3939
|
const tr = toolResults[i];
|
|
3904
3940
|
const resultStr = typeof tr?.result === "string" ? tr.result : JSON.stringify(tr?.result ?? "");
|
|
3905
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"));
|
|
3906
|
-
loopDetector.record(tc.toolName, tc.
|
|
3942
|
+
loopDetector.record(tc.toolName, tc.input, failed);
|
|
3907
3943
|
}
|
|
3908
3944
|
if (loopDetector.detectAbsoluteLimit()) {
|
|
3909
3945
|
logger.warn("Absolute tool call limit reached \u2014 aborting");
|
|
@@ -3961,7 +3997,7 @@ You can override this:
|
|
|
3961
3997
|
if (channel && msg.channelType !== "internal") {
|
|
3962
3998
|
if (channel instanceof CLIChannel) {
|
|
3963
3999
|
for (const tc of toolCalls) {
|
|
3964
|
-
await channel.sendToolFeedback(tc.toolName, tc.
|
|
4000
|
+
await channel.sendToolFeedback(tc.toolName, tc.input).catch(() => {
|
|
3965
4001
|
});
|
|
3966
4002
|
}
|
|
3967
4003
|
if (toolResults) {
|
|
@@ -3976,7 +4012,7 @@ You can override this:
|
|
|
3976
4012
|
} else if (channel instanceof TelegramChannel) {
|
|
3977
4013
|
const tgCh = channel;
|
|
3978
4014
|
for (const tc of toolCalls) {
|
|
3979
|
-
await tgCh.sendToolFeedback(tc.toolName, tc.
|
|
4015
|
+
await tgCh.sendToolFeedback(tc.toolName, tc.input, msg.channelId).catch(() => {
|
|
3980
4016
|
});
|
|
3981
4017
|
}
|
|
3982
4018
|
if (toolResults) {
|
|
@@ -4042,7 +4078,8 @@ You can override this:
|
|
|
4042
4078
|
const [usage] = await Promise.all([
|
|
4043
4079
|
streamResult.usage
|
|
4044
4080
|
]);
|
|
4045
|
-
|
|
4081
|
+
const streamReasoning = await streamResult.reasoning;
|
|
4082
|
+
result = { text: fullText, usage, reasoning: streamReasoning };
|
|
4046
4083
|
streamedText = fullText;
|
|
4047
4084
|
loopDetector.recordStepText(fullText);
|
|
4048
4085
|
} else {
|
|
@@ -4051,8 +4088,9 @@ You can override this:
|
|
|
4051
4088
|
system: systemPrompt,
|
|
4052
4089
|
messages,
|
|
4053
4090
|
tools: this.capabilities.getTools(),
|
|
4054
|
-
|
|
4091
|
+
stopWhen: stepCountIs(MAX_STEPS),
|
|
4055
4092
|
abortSignal: loopAbortController.signal,
|
|
4093
|
+
...deepseekProviderOptions ? { providerOptions: deepseekProviderOptions } : {},
|
|
4056
4094
|
onStepFinish: async ({ toolCalls, toolResults }) => {
|
|
4057
4095
|
if (toolCalls && toolResults && toolCalls.length > 0) {
|
|
4058
4096
|
const names = toolCalls.map((tc) => tc.toolName).join(", ");
|
|
@@ -4062,7 +4100,7 @@ You can override this:
|
|
|
4062
4100
|
const tr = toolResults[i];
|
|
4063
4101
|
const resultStr = typeof tr?.result === "string" ? tr.result : JSON.stringify(tr?.result ?? "");
|
|
4064
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"));
|
|
4065
|
-
loopDetector.record(tc.toolName, tc.
|
|
4103
|
+
loopDetector.record(tc.toolName, tc.input, failed);
|
|
4066
4104
|
}
|
|
4067
4105
|
if (loopDetector.detectAbsoluteLimit()) {
|
|
4068
4106
|
logger.warn("Absolute tool call limit reached \u2014 aborting");
|
|
@@ -4120,7 +4158,7 @@ You can override this:
|
|
|
4120
4158
|
if (channel && msg.channelType !== "internal") {
|
|
4121
4159
|
if (channel instanceof CLIChannel) {
|
|
4122
4160
|
for (const tc of toolCalls) {
|
|
4123
|
-
await channel.sendToolFeedback(tc.toolName, tc.
|
|
4161
|
+
await channel.sendToolFeedback(tc.toolName, tc.input).catch(() => {
|
|
4124
4162
|
});
|
|
4125
4163
|
}
|
|
4126
4164
|
if (toolResults) {
|
|
@@ -4135,7 +4173,7 @@ You can override this:
|
|
|
4135
4173
|
} else if (channel instanceof TelegramChannel) {
|
|
4136
4174
|
const tgCh = channel;
|
|
4137
4175
|
for (const tc of toolCalls) {
|
|
4138
|
-
await tgCh.sendToolFeedback(tc.toolName, tc.
|
|
4176
|
+
await tgCh.sendToolFeedback(tc.toolName, tc.input, msg.channelId).catch(() => {
|
|
4139
4177
|
});
|
|
4140
4178
|
}
|
|
4141
4179
|
if (toolResults) {
|
|
@@ -4221,9 +4259,9 @@ You can override this:
|
|
|
4221
4259
|
this.tokenBudget.recordUsage({
|
|
4222
4260
|
provider: usedProvider.name,
|
|
4223
4261
|
model: usedProvider.model,
|
|
4224
|
-
inputTokens: result.usage?.
|
|
4225
|
-
outputTokens: result.usage?.
|
|
4226
|
-
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),
|
|
4227
4265
|
channelType: msg.channelType
|
|
4228
4266
|
});
|
|
4229
4267
|
this.shortTerm.add(msg.channelId, {
|
|
@@ -4237,7 +4275,8 @@ You can override this:
|
|
|
4237
4275
|
timestamp: Date.now(),
|
|
4238
4276
|
role: "assistant",
|
|
4239
4277
|
content: finalText,
|
|
4240
|
-
tokenCount: (result.usage?.
|
|
4278
|
+
tokenCount: (result.usage?.inputTokens ?? 0) + (result.usage?.outputTokens ?? 0),
|
|
4279
|
+
reasoning: result.reasoning || void 0
|
|
4241
4280
|
});
|
|
4242
4281
|
this.episodic.record({
|
|
4243
4282
|
type: "message",
|
|
@@ -4433,14 +4472,14 @@ All actions auto-approved for this run.`,
|
|
|
4433
4472
|
{ role: "user", content: `User: ${userMessage}
|
|
4434
4473
|
Assistant: ${agentResponse}` }
|
|
4435
4474
|
],
|
|
4436
|
-
|
|
4475
|
+
maxOutputTokens: 400
|
|
4437
4476
|
});
|
|
4438
4477
|
this.tokenBudget.recordUsage({
|
|
4439
4478
|
provider: provider.name,
|
|
4440
4479
|
model: provider.getModel(),
|
|
4441
|
-
inputTokens: result.usage?.
|
|
4442
|
-
outputTokens: result.usage?.
|
|
4443
|
-
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),
|
|
4444
4483
|
channelType: "internal"
|
|
4445
4484
|
});
|
|
4446
4485
|
const text = result.text.trim();
|
|
@@ -4537,6 +4576,11 @@ Or use /budget override, /budget reset, /budget set <number> anytime.`,
|
|
|
4537
4576
|
await channel.send(ctx.manual(), channelId);
|
|
4538
4577
|
return true;
|
|
4539
4578
|
}
|
|
4579
|
+
if (cmd === "/exit" || cmd === "/quit") {
|
|
4580
|
+
await channel.send("Goodbye! Shutting down Mercury...", channelId);
|
|
4581
|
+
this.shutdown();
|
|
4582
|
+
return true;
|
|
4583
|
+
}
|
|
4540
4584
|
if (cmd === "/status") {
|
|
4541
4585
|
const config = ctx.config();
|
|
4542
4586
|
const budget = ctx.tokenBudget();
|
|
@@ -5842,16 +5886,16 @@ Allow access?`;
|
|
|
5842
5886
|
};
|
|
5843
5887
|
|
|
5844
5888
|
// src/capabilities/filesystem/read-file.ts
|
|
5845
|
-
import { tool } from "ai";
|
|
5889
|
+
import { tool, zodSchema } from "ai";
|
|
5846
5890
|
import { z } from "zod";
|
|
5847
5891
|
import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
|
|
5848
5892
|
import { resolve as resolve4, isAbsolute } from "path";
|
|
5849
5893
|
function createReadFileTool(permissions, getCwd) {
|
|
5850
5894
|
return tool({
|
|
5851
5895
|
description: "Read the contents of a file. The path must be within an allowed scope.",
|
|
5852
|
-
|
|
5896
|
+
inputSchema: zodSchema(z.object({
|
|
5853
5897
|
path: z.string().describe("Absolute or relative path to the file")
|
|
5854
|
-
}),
|
|
5898
|
+
})),
|
|
5855
5899
|
execute: async ({ path: path3 }) => {
|
|
5856
5900
|
const resolved = isAbsolute(path3) ? resolve4(path3) : resolve4(getCwd(), path3);
|
|
5857
5901
|
const check = await permissions.checkFsAccess(resolved, "read");
|
|
@@ -5879,17 +5923,17 @@ function createReadFileTool(permissions, getCwd) {
|
|
|
5879
5923
|
}
|
|
5880
5924
|
|
|
5881
5925
|
// src/capabilities/filesystem/write-file.ts
|
|
5882
|
-
import { tool as tool2 } from "ai";
|
|
5926
|
+
import { tool as tool2, zodSchema as zodSchema2 } from "ai";
|
|
5883
5927
|
import { z as z2 } from "zod";
|
|
5884
5928
|
import { existsSync as existsSync9, writeFileSync as writeFileSync7 } from "fs";
|
|
5885
5929
|
import { resolve as resolve5, isAbsolute as isAbsolute2 } from "path";
|
|
5886
5930
|
function createWriteFileTool(permissions, getCwd) {
|
|
5887
5931
|
return tool2({
|
|
5888
5932
|
description: "Write content to an existing file. The path must be within a writable scope.",
|
|
5889
|
-
|
|
5933
|
+
inputSchema: zodSchema2(z2.object({
|
|
5890
5934
|
path: z2.string().describe("Absolute or relative path to the file"),
|
|
5891
5935
|
content: z2.string().describe("The content to write to the file")
|
|
5892
|
-
}),
|
|
5936
|
+
})),
|
|
5893
5937
|
execute: async ({ path: path3, content }) => {
|
|
5894
5938
|
const resolved = isAbsolute2(path3) ? resolve5(path3) : resolve5(getCwd(), path3);
|
|
5895
5939
|
const check = await permissions.checkFsAccess(resolved, "write");
|
|
@@ -5911,17 +5955,17 @@ function createWriteFileTool(permissions, getCwd) {
|
|
|
5911
5955
|
}
|
|
5912
5956
|
|
|
5913
5957
|
// src/capabilities/filesystem/create-file.ts
|
|
5914
|
-
import { tool as tool3 } from "ai";
|
|
5958
|
+
import { tool as tool3, zodSchema as zodSchema3 } from "ai";
|
|
5915
5959
|
import { z as z3 } from "zod";
|
|
5916
5960
|
import { existsSync as existsSync10, writeFileSync as writeFileSync8, mkdirSync as mkdirSync8 } from "fs";
|
|
5917
5961
|
import { resolve as resolve6, dirname as dirname3, isAbsolute as isAbsolute3 } from "path";
|
|
5918
5962
|
function createCreateFileTool(permissions, getCwd) {
|
|
5919
5963
|
return tool3({
|
|
5920
5964
|
description: "Create a new file with the given content. Also creates parent directories if needed. The path must be within a writable scope.",
|
|
5921
|
-
|
|
5965
|
+
inputSchema: zodSchema3(z3.object({
|
|
5922
5966
|
path: z3.string().describe("Absolute or relative path for the new file"),
|
|
5923
5967
|
content: z3.string().describe("The content of the new file")
|
|
5924
|
-
}),
|
|
5968
|
+
})),
|
|
5925
5969
|
execute: async ({ path: path3, content }) => {
|
|
5926
5970
|
const resolved = isAbsolute3(path3) ? resolve6(path3) : resolve6(getCwd(), path3);
|
|
5927
5971
|
const check = await permissions.checkFsAccess(resolved, "write");
|
|
@@ -5947,16 +5991,16 @@ function createCreateFileTool(permissions, getCwd) {
|
|
|
5947
5991
|
}
|
|
5948
5992
|
|
|
5949
5993
|
// src/capabilities/filesystem/list-dir.ts
|
|
5950
|
-
import { tool as tool4 } from "ai";
|
|
5994
|
+
import { tool as tool4, zodSchema as zodSchema4 } from "ai";
|
|
5951
5995
|
import { z as z4 } from "zod";
|
|
5952
5996
|
import { existsSync as existsSync11, readdirSync as readdirSync2, statSync } from "fs";
|
|
5953
5997
|
import { resolve as resolve7, isAbsolute as isAbsolute4, join as join9 } from "path";
|
|
5954
5998
|
function createListDirTool(permissions, getCwd) {
|
|
5955
5999
|
return tool4({
|
|
5956
6000
|
description: "List the contents of a directory. Shows file names, types, and sizes.",
|
|
5957
|
-
|
|
6001
|
+
inputSchema: zodSchema4(z4.object({
|
|
5958
6002
|
path: z4.string().describe("Absolute or relative path to the directory")
|
|
5959
|
-
}),
|
|
6003
|
+
})),
|
|
5960
6004
|
execute: async ({ path: path3 }) => {
|
|
5961
6005
|
const resolved = isAbsolute4(path3) ? resolve7(path3) : resolve7(getCwd(), path3);
|
|
5962
6006
|
const check = await permissions.checkFsAccess(resolved, "read");
|
|
@@ -6002,16 +6046,16 @@ function formatSize(bytes) {
|
|
|
6002
6046
|
}
|
|
6003
6047
|
|
|
6004
6048
|
// src/capabilities/filesystem/delete-file.ts
|
|
6005
|
-
import { tool as tool5 } from "ai";
|
|
6049
|
+
import { tool as tool5, zodSchema as zodSchema5 } from "ai";
|
|
6006
6050
|
import { z as z5 } from "zod";
|
|
6007
6051
|
import { existsSync as existsSync12, unlinkSync as unlinkSync2 } from "fs";
|
|
6008
6052
|
import { resolve as resolve8, isAbsolute as isAbsolute5 } from "path";
|
|
6009
6053
|
function createDeleteFileTool(permissions, getCwd) {
|
|
6010
6054
|
return tool5({
|
|
6011
6055
|
description: "Delete a file. This action cannot be undone. The path must be within a writable scope. Always asks for confirmation.",
|
|
6012
|
-
|
|
6056
|
+
inputSchema: zodSchema5(z5.object({
|
|
6013
6057
|
path: z5.string().describe("Absolute or relative path to the file to delete")
|
|
6014
|
-
}),
|
|
6058
|
+
})),
|
|
6015
6059
|
execute: async ({ path: path3 }) => {
|
|
6016
6060
|
const resolved = isAbsolute5(path3) ? resolve8(path3) : resolve8(getCwd(), path3);
|
|
6017
6061
|
const check = await permissions.checkFsAccess(resolved, "write");
|
|
@@ -6037,18 +6081,18 @@ function createDeleteFileTool(permissions, getCwd) {
|
|
|
6037
6081
|
}
|
|
6038
6082
|
|
|
6039
6083
|
// src/capabilities/filesystem/edit-file.ts
|
|
6040
|
-
import { tool as tool6 } from "ai";
|
|
6084
|
+
import { tool as tool6, zodSchema as zodSchema6 } from "ai";
|
|
6041
6085
|
import { z as z6 } from "zod";
|
|
6042
6086
|
import { readFileSync as readFileSync9, writeFileSync as writeFileSync9 } from "fs";
|
|
6043
6087
|
import { resolve as resolve9, isAbsolute as isAbsolute6 } from "path";
|
|
6044
6088
|
function createEditFileTool(permissions, getCwd) {
|
|
6045
6089
|
return tool6({
|
|
6046
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.",
|
|
6047
|
-
|
|
6091
|
+
inputSchema: zodSchema6(z6.object({
|
|
6048
6092
|
path: z6.string().describe("Absolute or relative path to the file"),
|
|
6049
6093
|
old_string: z6.string().describe("The exact text to find in the file (must match exactly)"),
|
|
6050
6094
|
new_string: z6.string().describe("The text to replace it with")
|
|
6051
|
-
}),
|
|
6095
|
+
})),
|
|
6052
6096
|
execute: async ({ path: path3, old_string, new_string }) => {
|
|
6053
6097
|
const resolved = isAbsolute6(path3) ? resolve9(path3) : resolve9(getCwd(), path3);
|
|
6054
6098
|
const fsCheck = await permissions.checkFsAccess(resolved, "write");
|
|
@@ -6081,16 +6125,16 @@ function createEditFileTool(permissions, getCwd) {
|
|
|
6081
6125
|
}
|
|
6082
6126
|
|
|
6083
6127
|
// src/capabilities/filesystem/send-file.ts
|
|
6084
|
-
import { tool as tool7 } from "ai";
|
|
6128
|
+
import { tool as tool7, zodSchema as zodSchema7 } from "ai";
|
|
6085
6129
|
import { z as z7 } from "zod";
|
|
6086
6130
|
import { existsSync as existsSync13, statSync as statSync2 } from "fs";
|
|
6087
6131
|
import { resolve as resolve10, basename as basename2, isAbsolute as isAbsolute7 } from "path";
|
|
6088
6132
|
function createSendFileTool(permissions, getCwd, sendFile) {
|
|
6089
6133
|
return tool7({
|
|
6090
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.",
|
|
6091
|
-
|
|
6135
|
+
inputSchema: zodSchema7(z7.object({
|
|
6092
6136
|
path: z7.string().describe("Absolute or relative path to the file to send")
|
|
6093
|
-
}),
|
|
6137
|
+
})),
|
|
6094
6138
|
execute: async ({ path: path3 }) => {
|
|
6095
6139
|
const resolved = isAbsolute7(path3) ? resolve10(path3) : resolve10(getCwd(), path3);
|
|
6096
6140
|
const check = await permissions.checkFsAccess(resolved, "read");
|
|
@@ -6121,14 +6165,14 @@ function createSendFileTool(permissions, getCwd, sendFile) {
|
|
|
6121
6165
|
}
|
|
6122
6166
|
|
|
6123
6167
|
// src/capabilities/messaging/send-message.ts
|
|
6124
|
-
import { tool as tool8 } from "ai";
|
|
6168
|
+
import { tool as tool8, zodSchema as zodSchema8 } from "ai";
|
|
6125
6169
|
import { z as z8 } from "zod";
|
|
6126
6170
|
function createSendMessageTool(sendMessage) {
|
|
6127
6171
|
return tool8({
|
|
6128
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.",
|
|
6129
|
-
|
|
6173
|
+
inputSchema: zodSchema8(z8.object({
|
|
6130
6174
|
content: z8.string().describe("The message content to send to the approved Telegram recipients")
|
|
6131
|
-
}),
|
|
6175
|
+
})),
|
|
6132
6176
|
execute: async ({ content }) => {
|
|
6133
6177
|
const trimmed = content.trim();
|
|
6134
6178
|
if (!trimmed) {
|
|
@@ -6145,16 +6189,16 @@ function createSendMessageTool(sendMessage) {
|
|
|
6145
6189
|
}
|
|
6146
6190
|
|
|
6147
6191
|
// src/capabilities/filesystem/approve-scope.ts
|
|
6148
|
-
import { tool as tool9 } from "ai";
|
|
6192
|
+
import { tool as tool9, zodSchema as zodSchema9 } from "ai";
|
|
6149
6193
|
import { z as z9 } from "zod";
|
|
6150
6194
|
import { resolve as resolve11, isAbsolute as isAbsolute8 } from "path";
|
|
6151
6195
|
function createApproveScopeTool(permissions, getCwd) {
|
|
6152
6196
|
return tool9({
|
|
6153
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.',
|
|
6154
|
-
|
|
6198
|
+
inputSchema: zodSchema9(z9.object({
|
|
6155
6199
|
path: z9.string().describe("The directory path to request access to"),
|
|
6156
6200
|
mode: z9.enum(["read", "write"]).describe("The access mode needed")
|
|
6157
|
-
}),
|
|
6201
|
+
})),
|
|
6158
6202
|
execute: async ({ path: path3, mode }) => {
|
|
6159
6203
|
const resolved = isAbsolute8(path3) ? resolve11(path3) : resolve11(getCwd(), path3);
|
|
6160
6204
|
const result = await permissions.requestScopeExternal(resolved, mode);
|
|
@@ -6167,7 +6211,7 @@ function createApproveScopeTool(permissions, getCwd) {
|
|
|
6167
6211
|
}
|
|
6168
6212
|
|
|
6169
6213
|
// src/capabilities/shell/run-command.ts
|
|
6170
|
-
import { tool as tool10 } from "ai";
|
|
6214
|
+
import { tool as tool10, zodSchema as zodSchema10 } from "ai";
|
|
6171
6215
|
import { z as z10 } from "zod";
|
|
6172
6216
|
import { execSync } from "child_process";
|
|
6173
6217
|
import { resolve as resolve12, isAbsolute as isAbsolute9 } from "path";
|
|
@@ -6179,9 +6223,9 @@ function createRunCommandTool(permissions, getCwd, setCwd) {
|
|
|
6179
6223
|
Blocked commands (sudo, rm -rf /, etc.) are never executed.
|
|
6180
6224
|
Auto-approved commands (ls, cat, git status, curl, etc.) run without asking.
|
|
6181
6225
|
Other commands require user approval.`,
|
|
6182
|
-
|
|
6226
|
+
inputSchema: zodSchema10(z10.object({
|
|
6183
6227
|
command: z10.string().describe("The shell command to execute")
|
|
6184
|
-
}),
|
|
6228
|
+
})),
|
|
6185
6229
|
execute: async ({ command }) => {
|
|
6186
6230
|
const check = await permissions.checkShellCommand(command);
|
|
6187
6231
|
if (!check.allowed) {
|
|
@@ -6245,16 +6289,16 @@ function detectCd(command, currentCwd, setCwd) {
|
|
|
6245
6289
|
}
|
|
6246
6290
|
|
|
6247
6291
|
// src/capabilities/shell/cd.ts
|
|
6248
|
-
import { tool as tool11 } from "ai";
|
|
6292
|
+
import { tool as tool11, zodSchema as zodSchema11 } from "ai";
|
|
6249
6293
|
import { z as z11 } from "zod";
|
|
6250
6294
|
import { resolve as resolve13, isAbsolute as isAbsolute10 } from "path";
|
|
6251
6295
|
import { existsSync as existsSync15, statSync as statSync3 } from "fs";
|
|
6252
6296
|
function createCdTool(getCwd, setCwd) {
|
|
6253
6297
|
return tool11({
|
|
6254
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.",
|
|
6255
|
-
|
|
6299
|
+
inputSchema: zodSchema11(z11.object({
|
|
6256
6300
|
path: z11.string().describe("The directory to change to. Can be absolute or relative to the current directory.")
|
|
6257
|
-
}),
|
|
6301
|
+
})),
|
|
6258
6302
|
execute: async ({ path: path3 }) => {
|
|
6259
6303
|
const cwd = getCwd();
|
|
6260
6304
|
const resolved = isAbsolute10(path3) ? resolve13(path3) : resolve13(cwd, path3);
|
|
@@ -6276,14 +6320,14 @@ function createCdTool(getCwd, setCwd) {
|
|
|
6276
6320
|
}
|
|
6277
6321
|
|
|
6278
6322
|
// src/capabilities/shell/approve-command.ts
|
|
6279
|
-
import { tool as tool12 } from "ai";
|
|
6323
|
+
import { tool as tool12, zodSchema as zodSchema12 } from "ai";
|
|
6280
6324
|
import { z as z12 } from "zod";
|
|
6281
6325
|
function createApproveCommandTool(permissions) {
|
|
6282
6326
|
return tool12({
|
|
6283
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".',
|
|
6284
|
-
|
|
6328
|
+
inputSchema: zodSchema12(z12.object({
|
|
6285
6329
|
command: z12.string().describe('The base command to permanently approve (e.g. "curl", "docker", "npm")')
|
|
6286
|
-
}),
|
|
6330
|
+
})),
|
|
6287
6331
|
execute: async ({ command }) => {
|
|
6288
6332
|
const baseCmd = command.trim().split(/\s+/)[0];
|
|
6289
6333
|
permissions.addApprovedCommand(baseCmd);
|
|
@@ -6293,16 +6337,16 @@ function createApproveCommandTool(permissions) {
|
|
|
6293
6337
|
}
|
|
6294
6338
|
|
|
6295
6339
|
// src/capabilities/skills/install-skill.ts
|
|
6296
|
-
import { tool as tool13 } from "ai";
|
|
6340
|
+
import { tool as tool13, zodSchema as zodSchema13 } from "ai";
|
|
6297
6341
|
import { z as z13 } from "zod";
|
|
6298
6342
|
import { parse as parseYaml4 } from "yaml";
|
|
6299
6343
|
function createInstallSkillTool(skillLoader) {
|
|
6300
6344
|
return tool13({
|
|
6301
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.",
|
|
6302
|
-
|
|
6346
|
+
inputSchema: zodSchema13(z13.object({
|
|
6303
6347
|
content: z13.string().optional().describe("Raw SKILL.md markdown content with YAML frontmatter"),
|
|
6304
6348
|
url: z13.string().optional().describe("URL to fetch a SKILL.md from")
|
|
6305
|
-
}),
|
|
6349
|
+
})),
|
|
6306
6350
|
execute: async ({ content, url }) => {
|
|
6307
6351
|
let skillContent;
|
|
6308
6352
|
if (url && !content) {
|
|
@@ -6341,12 +6385,12 @@ function createInstallSkillTool(skillLoader) {
|
|
|
6341
6385
|
}
|
|
6342
6386
|
|
|
6343
6387
|
// src/capabilities/skills/list-skills.ts
|
|
6344
|
-
import { tool as tool14 } from "ai";
|
|
6388
|
+
import { tool as tool14, zodSchema as zodSchema14 } from "ai";
|
|
6345
6389
|
import { z as z14 } from "zod";
|
|
6346
6390
|
function createListSkillsTool(skillLoader) {
|
|
6347
6391
|
return tool14({
|
|
6348
6392
|
description: "List all installed skills with their names and descriptions.",
|
|
6349
|
-
|
|
6393
|
+
inputSchema: zodSchema14(z14.object({})),
|
|
6350
6394
|
execute: async () => {
|
|
6351
6395
|
const skills = skillLoader.getDiscovered();
|
|
6352
6396
|
if (skills.length === 0) {
|
|
@@ -6358,14 +6402,14 @@ function createListSkillsTool(skillLoader) {
|
|
|
6358
6402
|
}
|
|
6359
6403
|
|
|
6360
6404
|
// src/capabilities/skills/use-skill.ts
|
|
6361
|
-
import { tool as tool15 } from "ai";
|
|
6405
|
+
import { tool as tool15, zodSchema as zodSchema15 } from "ai";
|
|
6362
6406
|
import { z as z15 } from "zod";
|
|
6363
6407
|
function createUseSkillTool(skillLoader, permissions) {
|
|
6364
6408
|
return tool15({
|
|
6365
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.",
|
|
6366
|
-
|
|
6410
|
+
inputSchema: zodSchema15(z15.object({
|
|
6367
6411
|
name: z15.string().describe("Name of the skill to invoke")
|
|
6368
|
-
}),
|
|
6412
|
+
})),
|
|
6369
6413
|
execute: async ({ name }) => {
|
|
6370
6414
|
const skill = skillLoader.load(name);
|
|
6371
6415
|
if (!skill) {
|
|
@@ -6391,19 +6435,19 @@ Allowed tools: ${skill["allowed-tools"].join(", ")}`;
|
|
|
6391
6435
|
}
|
|
6392
6436
|
|
|
6393
6437
|
// src/capabilities/scheduler/schedule-task.ts
|
|
6394
|
-
import { tool as tool16 } from "ai";
|
|
6438
|
+
import { tool as tool16, zodSchema as zodSchema16 } from "ai";
|
|
6395
6439
|
import { z as z16 } from "zod";
|
|
6396
6440
|
import cron2 from "node-cron";
|
|
6397
6441
|
function createScheduleTaskTool(scheduler, getContext) {
|
|
6398
6442
|
return tool16({
|
|
6399
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.',
|
|
6400
|
-
|
|
6444
|
+
inputSchema: zodSchema16(z16.object({
|
|
6401
6445
|
cron: z16.string().optional().describe('Cron expression for recurring tasks (e.g. "0 9 * * *" for daily at 9am)'),
|
|
6402
6446
|
delay_seconds: z16.number().optional().describe('Delay in seconds for one-shot tasks (e.g. 15 for "remind me in 15 seconds")'),
|
|
6403
6447
|
description: z16.string().describe("Human-readable description of what this task does"),
|
|
6404
6448
|
prompt: z16.string().optional().describe("Prompt to send to the agent when the task fires"),
|
|
6405
6449
|
skill_name: z16.string().optional().describe("Name of a skill to invoke when the task fires")
|
|
6406
|
-
}),
|
|
6450
|
+
})),
|
|
6407
6451
|
execute: async ({ cron: cronExpr, delay_seconds, description, prompt, skill_name }) => {
|
|
6408
6452
|
if (!cronExpr && !delay_seconds) {
|
|
6409
6453
|
return "Either cron or delay_seconds must be provided.";
|
|
@@ -6455,12 +6499,12 @@ function createScheduleTaskTool(scheduler, getContext) {
|
|
|
6455
6499
|
}
|
|
6456
6500
|
|
|
6457
6501
|
// src/capabilities/scheduler/list-tasks.ts
|
|
6458
|
-
import { tool as tool17 } from "ai";
|
|
6502
|
+
import { tool as tool17, zodSchema as zodSchema17 } from "ai";
|
|
6459
6503
|
import { z as z17 } from "zod";
|
|
6460
6504
|
function createListTasksTool(scheduler) {
|
|
6461
6505
|
return tool17({
|
|
6462
6506
|
description: "List all scheduled tasks with their cron expressions and descriptions.",
|
|
6463
|
-
|
|
6507
|
+
inputSchema: zodSchema17(z17.object({})),
|
|
6464
6508
|
execute: async () => {
|
|
6465
6509
|
const manifests = scheduler.getManifests();
|
|
6466
6510
|
if (manifests.length === 0) {
|
|
@@ -6475,14 +6519,14 @@ function createListTasksTool(scheduler) {
|
|
|
6475
6519
|
}
|
|
6476
6520
|
|
|
6477
6521
|
// src/capabilities/scheduler/cancel-task.ts
|
|
6478
|
-
import { tool as tool18 } from "ai";
|
|
6522
|
+
import { tool as tool18, zodSchema as zodSchema18 } from "ai";
|
|
6479
6523
|
import { z as z18 } from "zod";
|
|
6480
6524
|
function createCancelTaskTool(scheduler) {
|
|
6481
6525
|
return tool18({
|
|
6482
6526
|
description: "Cancel and remove a scheduled task by its ID.",
|
|
6483
|
-
|
|
6527
|
+
inputSchema: zodSchema18(z18.object({
|
|
6484
6528
|
id: z18.string().describe("ID of the scheduled task to cancel")
|
|
6485
|
-
}),
|
|
6529
|
+
})),
|
|
6486
6530
|
execute: async ({ id }) => {
|
|
6487
6531
|
const manifests = scheduler.getManifests();
|
|
6488
6532
|
const exists = manifests.some((m) => m.id === id);
|
|
@@ -6497,12 +6541,12 @@ function createCancelTaskTool(scheduler) {
|
|
|
6497
6541
|
}
|
|
6498
6542
|
|
|
6499
6543
|
// src/capabilities/system/budget-status.ts
|
|
6500
|
-
import { tool as tool19 } from "ai";
|
|
6544
|
+
import { tool as tool19, zodSchema as zodSchema19 } from "ai";
|
|
6501
6545
|
import { z as z19 } from "zod";
|
|
6502
6546
|
function createBudgetStatusTool(tokenBudget) {
|
|
6503
6547
|
return tool19({
|
|
6504
6548
|
description: "Check the current token budget status \u2014 how many tokens have been used today, how many remain, and what percentage is consumed.",
|
|
6505
|
-
|
|
6549
|
+
inputSchema: zodSchema19(z19.object({})),
|
|
6506
6550
|
execute: async () => {
|
|
6507
6551
|
return tokenBudget.getStatusText();
|
|
6508
6552
|
}
|
|
@@ -6510,15 +6554,15 @@ function createBudgetStatusTool(tokenBudget) {
|
|
|
6510
6554
|
}
|
|
6511
6555
|
|
|
6512
6556
|
// src/capabilities/git/git-status.ts
|
|
6513
|
-
import { tool as tool20 } from "ai";
|
|
6557
|
+
import { tool as tool20, zodSchema as zodSchema20 } from "ai";
|
|
6514
6558
|
import { z as z20 } from "zod";
|
|
6515
6559
|
import { execSync as execSync2 } from "child_process";
|
|
6516
6560
|
function createGitStatusTool(getCwd) {
|
|
6517
6561
|
return tool20({
|
|
6518
6562
|
description: "Show the working tree status. Returns staged, unstaged, and untracked files.",
|
|
6519
|
-
|
|
6563
|
+
inputSchema: zodSchema20(z20.object({
|
|
6520
6564
|
path: z20.string().optional().describe("Path to check (defaults to current directory)")
|
|
6521
|
-
}),
|
|
6565
|
+
})),
|
|
6522
6566
|
execute: async ({ path: path3 }) => {
|
|
6523
6567
|
try {
|
|
6524
6568
|
const cmd = path3 ? `git -C "${path3}" status --porcelain` : "git status --porcelain";
|
|
@@ -6533,16 +6577,16 @@ function createGitStatusTool(getCwd) {
|
|
|
6533
6577
|
}
|
|
6534
6578
|
|
|
6535
6579
|
// src/capabilities/git/git-diff.ts
|
|
6536
|
-
import { tool as tool21 } from "ai";
|
|
6580
|
+
import { tool as tool21, zodSchema as zodSchema21 } from "ai";
|
|
6537
6581
|
import { z as z21 } from "zod";
|
|
6538
6582
|
import { execSync as execSync3 } from "child_process";
|
|
6539
6583
|
function createGitDiffTool(getCwd) {
|
|
6540
6584
|
return tool21({
|
|
6541
6585
|
description: "Show changes between commits, commit and working tree, etc. Shows what has been modified.",
|
|
6542
|
-
|
|
6586
|
+
inputSchema: zodSchema21(z21.object({
|
|
6543
6587
|
path: z21.string().optional().describe("File or directory to diff"),
|
|
6544
6588
|
staged: z21.boolean().optional().describe("Show staged changes (cached) instead of unstaged")
|
|
6545
|
-
}),
|
|
6589
|
+
})),
|
|
6546
6590
|
execute: async ({ path: path3, staged }) => {
|
|
6547
6591
|
try {
|
|
6548
6592
|
let cmd = "git diff";
|
|
@@ -6560,16 +6604,16 @@ function createGitDiffTool(getCwd) {
|
|
|
6560
6604
|
}
|
|
6561
6605
|
|
|
6562
6606
|
// src/capabilities/git/git-log.ts
|
|
6563
|
-
import { tool as tool22 } from "ai";
|
|
6607
|
+
import { tool as tool22, zodSchema as zodSchema22 } from "ai";
|
|
6564
6608
|
import { z as z22 } from "zod";
|
|
6565
6609
|
import { execSync as execSync4 } from "child_process";
|
|
6566
6610
|
function createGitLogTool(getCwd) {
|
|
6567
6611
|
return tool22({
|
|
6568
6612
|
description: "Show commit logs. Returns recent commit history with hash, author, date, and message.",
|
|
6569
|
-
|
|
6613
|
+
inputSchema: zodSchema22(z22.object({
|
|
6570
6614
|
count: z22.number().optional().describe("Number of commits to show (default 10)"),
|
|
6571
6615
|
path: z22.string().optional().describe("File or directory to show log for")
|
|
6572
|
-
}),
|
|
6616
|
+
})),
|
|
6573
6617
|
execute: async ({ count, path: path3 }) => {
|
|
6574
6618
|
try {
|
|
6575
6619
|
const n = count ?? 10;
|
|
@@ -6586,15 +6630,15 @@ function createGitLogTool(getCwd) {
|
|
|
6586
6630
|
}
|
|
6587
6631
|
|
|
6588
6632
|
// src/capabilities/git/git-add.ts
|
|
6589
|
-
import { tool as tool23 } from "ai";
|
|
6633
|
+
import { tool as tool23, zodSchema as zodSchema23 } from "ai";
|
|
6590
6634
|
import { z as z23 } from "zod";
|
|
6591
6635
|
import { execSync as execSync5 } from "child_process";
|
|
6592
6636
|
function createGitAddTool(getCwd) {
|
|
6593
6637
|
return tool23({
|
|
6594
6638
|
description: "Add file contents to the index (staging area). Prepares files for commit.",
|
|
6595
|
-
|
|
6639
|
+
inputSchema: zodSchema23(z23.object({
|
|
6596
6640
|
paths: z23.array(z23.string()).describe("File paths to stage")
|
|
6597
|
-
}),
|
|
6641
|
+
})),
|
|
6598
6642
|
execute: async ({ paths }) => {
|
|
6599
6643
|
try {
|
|
6600
6644
|
const fileArgs = paths.map((p) => `"${p}"`).join(" ");
|
|
@@ -6608,7 +6652,7 @@ function createGitAddTool(getCwd) {
|
|
|
6608
6652
|
}
|
|
6609
6653
|
|
|
6610
6654
|
// src/capabilities/git/git-commit.ts
|
|
6611
|
-
import { tool as tool24 } from "ai";
|
|
6655
|
+
import { tool as tool24, zodSchema as zodSchema24 } from "ai";
|
|
6612
6656
|
import { z as z24 } from "zod";
|
|
6613
6657
|
import { execSync as execSync6 } from "child_process";
|
|
6614
6658
|
import { writeFileSync as writeFileSync10, unlinkSync as unlinkSync3 } from "fs";
|
|
@@ -6617,9 +6661,9 @@ var CO_AUTHOR = "Mercury <mercury@cosmicstack.org>";
|
|
|
6617
6661
|
function createGitCommitTool(getCwd) {
|
|
6618
6662
|
return tool24({
|
|
6619
6663
|
description: "Record changes to the repository. Creates a new commit with staged changes. Automatically includes a Co-authored-by trailer for attribution.",
|
|
6620
|
-
|
|
6664
|
+
inputSchema: zodSchema24(z24.object({
|
|
6621
6665
|
message: z24.string().describe("Commit message")
|
|
6622
|
-
}),
|
|
6666
|
+
})),
|
|
6623
6667
|
execute: async ({ message }) => {
|
|
6624
6668
|
try {
|
|
6625
6669
|
const fullMessage = `${message}
|
|
@@ -6654,16 +6698,16 @@ Co-authored-by: ${CO_AUTHOR}`;
|
|
|
6654
6698
|
}
|
|
6655
6699
|
|
|
6656
6700
|
// src/capabilities/git/git-push.ts
|
|
6657
|
-
import { tool as tool25 } from "ai";
|
|
6701
|
+
import { tool as tool25, zodSchema as zodSchema25 } from "ai";
|
|
6658
6702
|
import { z as z25 } from "zod";
|
|
6659
6703
|
import { execSync as execSync7 } from "child_process";
|
|
6660
6704
|
function createGitPushTool(permissions, getCwd) {
|
|
6661
6705
|
return tool25({
|
|
6662
6706
|
description: "Push commits to a remote repository. This modifies a remote and requires approval.",
|
|
6663
|
-
|
|
6707
|
+
inputSchema: zodSchema25(z25.object({
|
|
6664
6708
|
remote: z25.string().optional().describe("Remote name (default: origin)"),
|
|
6665
6709
|
branch: z25.string().optional().describe("Branch name (default: current branch)")
|
|
6666
|
-
}),
|
|
6710
|
+
})),
|
|
6667
6711
|
execute: async ({ remote, branch }) => {
|
|
6668
6712
|
const cmd = `git push ${remote || "origin"} ${branch || ""}`.trim();
|
|
6669
6713
|
const check = await permissions.checkShellCommand(cmd);
|
|
@@ -6687,7 +6731,7 @@ Ask the user for permission. If they approve, try again. If they say "always", u
|
|
|
6687
6731
|
}
|
|
6688
6732
|
|
|
6689
6733
|
// src/capabilities/github/create-pr.ts
|
|
6690
|
-
import { tool as tool26 } from "ai";
|
|
6734
|
+
import { tool as tool26, zodSchema as zodSchema26 } from "ai";
|
|
6691
6735
|
import { z as z26 } from "zod";
|
|
6692
6736
|
|
|
6693
6737
|
// src/utils/github.ts
|
|
@@ -6745,7 +6789,7 @@ async function githubRequest(path3, options = {}) {
|
|
|
6745
6789
|
function createCreatePrTool() {
|
|
6746
6790
|
return tool26({
|
|
6747
6791
|
description: "Create a pull request on GitHub. Requires GITHUB_TOKEN to be configured.",
|
|
6748
|
-
|
|
6792
|
+
inputSchema: zodSchema26(z26.object({
|
|
6749
6793
|
owner: z26.string().describe("Repository owner (username or org)"),
|
|
6750
6794
|
repo: z26.string().describe("Repository name"),
|
|
6751
6795
|
title: z26.string().describe("PR title"),
|
|
@@ -6753,7 +6797,7 @@ function createCreatePrTool() {
|
|
|
6753
6797
|
head: z26.string().describe("The branch containing the changes"),
|
|
6754
6798
|
base: z26.string().describe("The branch to merge into").default("main"),
|
|
6755
6799
|
draft: z26.boolean().describe("Create as draft PR").default(false)
|
|
6756
|
-
}),
|
|
6800
|
+
})),
|
|
6757
6801
|
execute: async ({ owner, repo, title, body, head, base, draft }) => {
|
|
6758
6802
|
try {
|
|
6759
6803
|
const result = await githubRequest(`/repos/${owner}/${repo}/pulls`, {
|
|
@@ -6771,17 +6815,17 @@ ${draft ? "(draft)" : ""} ${result.state}`;
|
|
|
6771
6815
|
}
|
|
6772
6816
|
|
|
6773
6817
|
// src/capabilities/github/review-pr.ts
|
|
6774
|
-
import { tool as tool27 } from "ai";
|
|
6818
|
+
import { tool as tool27, zodSchema as zodSchema27 } from "ai";
|
|
6775
6819
|
import { z as z27 } from "zod";
|
|
6776
6820
|
function createReviewPrTool() {
|
|
6777
6821
|
return tool27({
|
|
6778
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.",
|
|
6779
|
-
|
|
6823
|
+
inputSchema: zodSchema27(z27.object({
|
|
6780
6824
|
owner: z27.string().describe("Repository owner (username or org)"),
|
|
6781
6825
|
repo: z27.string().describe("Repository name"),
|
|
6782
6826
|
number: z27.number().describe("PR number"),
|
|
6783
6827
|
comment: z27.string().describe("Review comment to post on the PR (optional)").optional()
|
|
6784
|
-
}),
|
|
6828
|
+
})),
|
|
6785
6829
|
execute: async ({ owner, repo, number, comment }) => {
|
|
6786
6830
|
try {
|
|
6787
6831
|
const pr = await githubRequest(`/repos/${owner}/${repo}/pulls/${number}`);
|
|
@@ -6846,18 +6890,18 @@ Failed to post review comment: ${err.message}`;
|
|
|
6846
6890
|
}
|
|
6847
6891
|
|
|
6848
6892
|
// src/capabilities/github/list-issues.ts
|
|
6849
|
-
import { tool as tool28 } from "ai";
|
|
6893
|
+
import { tool as tool28, zodSchema as zodSchema28 } from "ai";
|
|
6850
6894
|
import { z as z28 } from "zod";
|
|
6851
6895
|
function createListIssuesTool() {
|
|
6852
6896
|
return tool28({
|
|
6853
6897
|
description: "List GitHub issues for a repository. Requires GITHUB_TOKEN.",
|
|
6854
|
-
|
|
6898
|
+
inputSchema: zodSchema28(z28.object({
|
|
6855
6899
|
owner: z28.string().describe("Repository owner (username or org)"),
|
|
6856
6900
|
repo: z28.string().describe("Repository name"),
|
|
6857
6901
|
state: z28.enum(["open", "closed", "all"]).describe("Filter by issue state").default("open"),
|
|
6858
6902
|
labels: z28.string().describe("Comma-separated label names to filter by (optional)").optional(),
|
|
6859
6903
|
limit: z28.number().describe("Maximum number of issues to return").default(10)
|
|
6860
|
-
}),
|
|
6904
|
+
})),
|
|
6861
6905
|
execute: async ({ owner, repo, state, labels, limit }) => {
|
|
6862
6906
|
try {
|
|
6863
6907
|
const params = new URLSearchParams();
|
|
@@ -6884,18 +6928,18 @@ ${lines.join("\n")}`;
|
|
|
6884
6928
|
}
|
|
6885
6929
|
|
|
6886
6930
|
// src/capabilities/github/create-issue.ts
|
|
6887
|
-
import { tool as tool29 } from "ai";
|
|
6931
|
+
import { tool as tool29, zodSchema as zodSchema29 } from "ai";
|
|
6888
6932
|
import { z as z29 } from "zod";
|
|
6889
6933
|
function createCreateIssueTool() {
|
|
6890
6934
|
return tool29({
|
|
6891
6935
|
description: "Create a new GitHub issue in a repository. Requires GITHUB_TOKEN.",
|
|
6892
|
-
|
|
6936
|
+
inputSchema: zodSchema29(z29.object({
|
|
6893
6937
|
owner: z29.string().describe("Repository owner (username or org)"),
|
|
6894
6938
|
repo: z29.string().describe("Repository name"),
|
|
6895
6939
|
title: z29.string().describe("Issue title"),
|
|
6896
6940
|
body: z29.string().describe("Issue description (markdown supported)").default(""),
|
|
6897
6941
|
labels: z29.array(z29.string()).describe("Label names to apply").optional()
|
|
6898
|
-
}),
|
|
6942
|
+
})),
|
|
6899
6943
|
execute: async ({ owner, repo, title, body, labels }) => {
|
|
6900
6944
|
try {
|
|
6901
6945
|
const payload = { title, body };
|
|
@@ -6914,7 +6958,7 @@ function createCreateIssueTool() {
|
|
|
6914
6958
|
}
|
|
6915
6959
|
|
|
6916
6960
|
// src/capabilities/github/github-api.ts
|
|
6917
|
-
import { tool as tool30 } from "ai";
|
|
6961
|
+
import { tool as tool30, zodSchema as zodSchema30 } from "ai";
|
|
6918
6962
|
import { z as z30 } from "zod";
|
|
6919
6963
|
var CO_AUTHOR_NAME = "Mercury";
|
|
6920
6964
|
var CO_AUTHOR_EMAIL = "mercury@cosmicstack.org";
|
|
@@ -6950,11 +6994,11 @@ Common operations you can perform:
|
|
|
6950
6994
|
- Any other GitHub API v3 endpoint.
|
|
6951
6995
|
|
|
6952
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.`,
|
|
6953
|
-
|
|
6997
|
+
inputSchema: zodSchema30(z30.object({
|
|
6954
6998
|
path: z30.string().describe("Full API path (e.g., /repos/owner/repo/issues or /repos/owner/repo/contents/path/to/file)"),
|
|
6955
6999
|
method: z30.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).describe("HTTP method").default("GET"),
|
|
6956
7000
|
body: z30.string().describe("JSON body for write requests (as a JSON string)").optional()
|
|
6957
|
-
}),
|
|
7001
|
+
})),
|
|
6958
7002
|
execute: async ({ path: path3, method, body }) => {
|
|
6959
7003
|
try {
|
|
6960
7004
|
let parsedBody;
|
|
@@ -6983,7 +7027,7 @@ IMPORTANT: When the user wants to push code or files to GitHub and git push fail
|
|
|
6983
7027
|
}
|
|
6984
7028
|
|
|
6985
7029
|
// src/capabilities/web/fetch-url.ts
|
|
6986
|
-
import { tool as tool31 } from "ai";
|
|
7030
|
+
import { tool as tool31, zodSchema as zodSchema31 } from "ai";
|
|
6987
7031
|
import { z as z31 } from "zod";
|
|
6988
7032
|
var MAX_CONTENT_LENGTH = 15e3;
|
|
6989
7033
|
function stripHtml(html) {
|
|
@@ -7019,10 +7063,10 @@ function stripHtml(html) {
|
|
|
7019
7063
|
function createFetchUrlTool() {
|
|
7020
7064
|
return tool31({
|
|
7021
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.",
|
|
7022
|
-
|
|
7066
|
+
inputSchema: zodSchema31(z31.object({
|
|
7023
7067
|
url: z31.string().describe("The URL to fetch"),
|
|
7024
7068
|
format: z31.enum(["text", "markdown"]).optional().describe("Output format (default: markdown)")
|
|
7025
|
-
}),
|
|
7069
|
+
})),
|
|
7026
7070
|
execute: async ({ url, format }) => {
|
|
7027
7071
|
const outputFormat = format ?? "markdown";
|
|
7028
7072
|
try {
|