@jixo/cli 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +36 -4
- package/dist/cli.js.map +1 -1
- package/dist/commands/doctor/doctor.js +1 -1
- package/dist/commands/doctor/doctor.js.map +1 -1
- package/dist/commands/tasks/ai-tools.d.ts +525 -255
- package/dist/commands/tasks/ai-tools.d.ts.map +1 -1
- package/dist/commands/tasks/ai-tools.js +39 -2
- package/dist/commands/tasks/ai-tools.js.map +1 -1
- package/dist/commands/tasks/run-ai-task.d.ts.map +1 -1
- package/dist/commands/tasks/run-ai-task.js +116 -68
- package/dist/commands/tasks/run-ai-task.js.map +1 -1
- package/dist/commands/tasks/run.d.ts +2 -0
- package/dist/commands/tasks/run.d.ts.map +1 -1
- package/dist/commands/tasks/run.js +66 -35
- package/dist/commands/tasks/run.js.map +1 -1
- package/dist/config.d.ts +14 -14
- package/dist/helper/ai-retry-error.d.ts +3 -0
- package/dist/helper/ai-retry-error.d.ts.map +1 -0
- package/dist/helper/ai-retry-error.js +75 -0
- package/dist/helper/ai-retry-error.js.map +1 -0
- package/dist/helper/parse-progress.d.ts +2 -0
- package/dist/helper/parse-progress.d.ts.map +1 -0
- package/dist/helper/parse-progress.js +28 -0
- package/dist/helper/parse-progress.js.map +1 -0
- package/dist/helper/resolve-ai-tasks.d.ts +3 -0
- package/dist/helper/resolve-ai-tasks.d.ts.map +1 -1
- package/dist/helper/resolve-ai-tasks.js +25 -4
- package/dist/helper/resolve-ai-tasks.js.map +1 -1
- package/dist/prompts.json +141 -12
- package/package.json +2 -2
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ai-tools.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/ai-tools.ts"],"names":[],"mappings":"AACA,OAAO,
|
1
|
+
{"version":3,"file":"ai-tools.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/ai-tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAwD,KAAK,OAAO,EAAC,MAAM,IAAI,CAAC;AAEvF,OAAO,CAAC,MAAM,KAAK,CAAC;AAGpB,eAAO,MAAM,KAAK;sBAGD,MAAM;8BAeM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAuCjB,MAAM;;;;;;;;;CA0CvB,CAAC"}
|
@@ -1,6 +1,8 @@
|
|
1
|
-
import { func_lazy, func_remember, map_get_or_put_async } from "@gaubee/util";
|
2
|
-
import { experimental_createMCPClient as createMCPClient } from "ai";
|
1
|
+
import { func_lazy, func_remember, map_get_or_put_async, obj_props } from "@gaubee/util";
|
2
|
+
import { experimental_createMCPClient as createMCPClient, tool } from "ai";
|
3
3
|
import { Experimental_StdioMCPTransport } from "ai/mcp-stdio";
|
4
|
+
import z from "zod";
|
5
|
+
import { getPromptConfigs } from "../../helper/prompts-loader.js";
|
4
6
|
export const tools = {
|
5
7
|
fileSystem: func_lazy(() => {
|
6
8
|
const map = new Map();
|
@@ -35,6 +37,16 @@ export const tools = {
|
|
35
37
|
});
|
36
38
|
};
|
37
39
|
}),
|
40
|
+
sequentialThinking: func_remember(async () => {
|
41
|
+
const mcpClient = await createMCPClient({
|
42
|
+
transport: new Experimental_StdioMCPTransport({
|
43
|
+
command: "pnpx",
|
44
|
+
args: ["@modelcontextprotocol/server-sequential-thinking"],
|
45
|
+
}),
|
46
|
+
});
|
47
|
+
const tools = await mcpClient.tools();
|
48
|
+
return tools;
|
49
|
+
}),
|
38
50
|
fetch: func_remember(async () => {
|
39
51
|
const mcpClient = await createMCPClient({
|
40
52
|
transport: new Experimental_StdioMCPTransport({
|
@@ -60,5 +72,30 @@ export const tools = {
|
|
60
72
|
});
|
61
73
|
};
|
62
74
|
}),
|
75
|
+
jixoSkill: func_remember(() => {
|
76
|
+
const configs = getPromptConfigs();
|
77
|
+
const skills = obj_props(configs).filter((key) => key.endsWith(".skill"));
|
78
|
+
const allSkillNavList = skills.reduce((tree, skill) => {
|
79
|
+
tree[skill] = configs[skill].content.split("\n")[0];
|
80
|
+
return tree;
|
81
|
+
}, Object.create(null));
|
82
|
+
return {
|
83
|
+
allSkillNavList,
|
84
|
+
tools: {
|
85
|
+
get_jixo_skill: tool({
|
86
|
+
description: "Get the JIXO skill prompt by name",
|
87
|
+
parameters: z.object({
|
88
|
+
name: z.string().describe("The name to get the skill for"),
|
89
|
+
}),
|
90
|
+
execute: async ({ name }) => {
|
91
|
+
if (name in allSkillNavList) {
|
92
|
+
return Reflect.get(configs, name);
|
93
|
+
}
|
94
|
+
return { type: "error", message: "Skill not found" };
|
95
|
+
},
|
96
|
+
}),
|
97
|
+
},
|
98
|
+
};
|
99
|
+
}),
|
63
100
|
};
|
64
101
|
//# sourceMappingURL=ai-tools.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ai-tools.js","sourceRoot":"","sources":["../../../src/commands/tasks/ai-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,aAAa,EAAE,oBAAoB,EAAC,MAAM,cAAc,CAAC;
|
1
|
+
{"version":3,"file":"ai-tools.js","sourceRoot":"","sources":["../../../src/commands/tasks/ai-tools.ts"],"names":[],"mappings":"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","sourcesContent":["import {func_lazy, func_remember, map_get_or_put_async, obj_props} from \"@gaubee/util\";\nimport {experimental_createMCPClient as createMCPClient, tool, type ToolSet} from \"ai\";\nimport {Experimental_StdioMCPTransport} from \"ai/mcp-stdio\";\nimport z from \"zod\";\nimport {getPromptConfigs} from \"../../helper/prompts-loader.js\";\n\nexport const tools = {\n fileSystem: func_lazy(() => {\n const map = new Map<string, ToolSet>();\n return (cwd: string) => {\n return map_get_or_put_async(map, cwd, async () => {\n const mcpClient = await createMCPClient({\n transport: new Experimental_StdioMCPTransport({\n command: \"pnpx\",\n args: [\"@modelcontextprotocol/server-filesystem\", cwd],\n }),\n });\n const tools = await mcpClient.tools();\n return tools;\n });\n };\n }),\n memory: func_lazy(() => {\n const map = new Map<string, ToolSet>();\n return (memory_filepath: string) => {\n return map_get_or_put_async(map, memory_filepath, async () => {\n const mcpClient = await createMCPClient({\n transport: new Experimental_StdioMCPTransport({\n command: \"pnpx\",\n args: [\"@modelcontextprotocol/server-memory\"],\n env: {\n MEMORY_FILE_PATH: memory_filepath,\n },\n }),\n });\n const tools = await mcpClient.tools();\n return tools;\n });\n };\n }),\n sequentialThinking: func_remember(async () => {\n const mcpClient = await createMCPClient({\n transport: new Experimental_StdioMCPTransport({\n command: \"pnpx\",\n args: [\"@modelcontextprotocol/server-sequential-thinking\"],\n }),\n });\n const tools = await mcpClient.tools();\n return tools;\n }),\n fetch: func_remember(async () => {\n const mcpClient = await createMCPClient({\n transport: new Experimental_StdioMCPTransport({\n command: \"uvx\",\n args: [\"mcp-server-fetch\"],\n }),\n });\n const tools = await mcpClient.tools();\n return tools;\n }),\n git: func_lazy(() => {\n const map = new Map<string, ToolSet>();\n\n return (repo: string) => {\n return map_get_or_put_async(map, repo, async () => {\n const mcpClient = await createMCPClient({\n transport: new Experimental_StdioMCPTransport({\n command: \"uvx\",\n args: [\"mcp-server-git\", \"--repository\", repo],\n }),\n });\n const tools = await mcpClient.tools();\n return tools;\n });\n };\n }),\n\n jixoSkill: func_remember(() => {\n const configs = getPromptConfigs();\n const skills = obj_props(configs).filter((key) => key.endsWith(\".skill\"));\n const allSkillNavList = skills.reduce(\n (tree, skill) => {\n tree[skill] = configs[skill].content.split(\"\\n\")[0];\n return tree;\n },\n Object.create(null) as Record<string, string>,\n );\n return {\n allSkillNavList,\n tools: {\n get_jixo_skill: tool({\n description: \"Get the JIXO skill prompt by name\",\n parameters: z.object({\n name: z.string().describe(\"The name to get the skill for\"),\n }),\n execute: async ({name}) => {\n if (name in allSkillNavList) {\n return Reflect.get(configs, name);\n }\n return {type: \"error\", message: \"Skill not found\"};\n },\n }),\n },\n };\n }),\n};\n"]}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"run-ai-task.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/run-ai-task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,SAAS,
|
1
|
+
{"version":3,"file":"run-ai-task.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/run-ai-task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,SAAS,EAAwD,MAAM,iBAAiB,CAAC;AAU7G,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,kCAAkC,CAAC;AAyD7D,eAAO,MAAM,SAAS,GAAU,SAAS,MAAM,EAAE,UAAU,SAAS,EAAE,EAAE,iBAAiB,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,kBAenH,CAAC"}
|
@@ -1,16 +1,37 @@
|
|
1
1
|
import { blue, cyan, FileEntry, gray, green, red, spinner, YAML, yellow } from "@gaubee/nodekit";
|
2
2
|
import { func_catch } from "@gaubee/util";
|
3
|
-
import { streamText } from "ai";
|
4
|
-
import
|
3
|
+
import { AISDKError, streamText } from "ai";
|
4
|
+
import createDebug from "debug";
|
5
5
|
import ms from "ms";
|
6
6
|
import os from "node:os";
|
7
|
-
import path from "node:path";
|
8
7
|
import { match, P } from "ts-pattern";
|
9
8
|
import { safeEnv } from "../../env.js";
|
10
|
-
import {
|
9
|
+
import { handleRetryError } from "../../helper/ai-retry-error.js";
|
10
|
+
import { getPromptConfigs } from "../../helper/prompts-loader.js";
|
11
11
|
import { tools } from "./ai-tools.js";
|
12
12
|
import { providers } from "./model-providers.js";
|
13
|
-
|
13
|
+
createDebug.formatters.y = (v) => {
|
14
|
+
return JSON.stringify(v, (_k, v) => {
|
15
|
+
if (typeof v === "string") {
|
16
|
+
let slice_len = 0;
|
17
|
+
if (v.length > 200) {
|
18
|
+
slice_len = 50;
|
19
|
+
}
|
20
|
+
if (v.length > 100) {
|
21
|
+
slice_len = 30;
|
22
|
+
}
|
23
|
+
if (slice_len > 0) {
|
24
|
+
return `<string:${v.length}>${v.slice(0, slice_len)}${gray("...")}${v.slice(-slice_len)}`;
|
25
|
+
}
|
26
|
+
return v;
|
27
|
+
}
|
28
|
+
if (AISDKError.isInstance(v)) {
|
29
|
+
return red(v.message);
|
30
|
+
}
|
31
|
+
return v;
|
32
|
+
});
|
33
|
+
};
|
34
|
+
const log = createDebug("jixo:run-ai-task");
|
14
35
|
const getModel = (model) => {
|
15
36
|
return match(model)
|
16
37
|
.with(P.string.startsWith("deepseek-"), (model) => providers.deepseek(model))
|
@@ -21,7 +42,7 @@ const getModel = (model) => {
|
|
21
42
|
.with(P.string.includes("/"), (model) => providers.deepinfra(model))
|
22
43
|
.otherwise(() => {
|
23
44
|
if (safeEnv.JIXO_DEEPSEEK_API_KEY) {
|
24
|
-
return providers.deepseek("deepseek-
|
45
|
+
return providers.deepseek("deepseek-reasoner");
|
25
46
|
}
|
26
47
|
if (safeEnv.JIXO_GOOGLE_API_KEY) {
|
27
48
|
return providers.google("gemini-2.5-pro-preview-05-06");
|
@@ -42,49 +63,7 @@ const getModel = (model) => {
|
|
42
63
|
});
|
43
64
|
};
|
44
65
|
export const runAiTask = async (ai_task, allFiles, changedFilesSet) => {
|
45
|
-
const
|
46
|
-
const availableTools = {
|
47
|
-
...(await tools.fileSystem(ai_task.cwd)),
|
48
|
-
...(await tools.memory(path.join(ai_task.cwd, `.jixo/${ai_task.name}.memory.json`))),
|
49
|
-
// ...(await tools.fetch()),
|
50
|
-
// ...(await tools.git(ai_task.cwd)),
|
51
|
-
};
|
52
|
-
const initialMessages = getModelMessage(ai_task.agents);
|
53
|
-
ai_task.startTime;
|
54
|
-
const userPrompt = getPromptConfigs()
|
55
|
-
.user.content //
|
56
|
-
.replace(/\{\{task.(\w+)\}\}/g, (_, key) => {
|
57
|
-
return Reflect.get(ai_task, key);
|
58
|
-
})
|
59
|
-
.replace(/\{\{env.(\w+)\}\}/g, (_, key) => {
|
60
|
-
const envKey = key.toUpperCase();
|
61
|
-
const envValue = Reflect.get(process.env, envKey) ??
|
62
|
-
match(envKey)
|
63
|
-
.with("USER", () => os.userInfo().username)
|
64
|
-
.otherwise(() => "");
|
65
|
-
return envValue;
|
66
|
-
})
|
67
|
-
.replaceAll("{{allFiles}}", YAML.stringify({
|
68
|
-
[ai_task.cwd]: {
|
69
|
-
count: allFiles.length,
|
70
|
-
file: allFiles.map((e) => e.relativePath),
|
71
|
-
},
|
72
|
-
}))
|
73
|
-
.replaceAll("{{changedFiles}}", YAML.stringify(Object.entries(changedFilesSet).reduce((tree, [dir, changedFiles]) => {
|
74
|
-
tree[dir] = {
|
75
|
-
count: changedFiles.length,
|
76
|
-
files: changedFiles.map((e) => e.relativePath),
|
77
|
-
};
|
78
|
-
return tree;
|
79
|
-
}, {})));
|
80
|
-
log("USER PROMPT:", userPrompt);
|
81
|
-
initialMessages.push({
|
82
|
-
role: "user",
|
83
|
-
content: userPrompt,
|
84
|
-
});
|
85
|
-
let currentMessages = [...initialMessages];
|
86
|
-
const maxTurns = 20; // Safeguard against infinite loops
|
87
|
-
const loading = spinner("Initializing AI task...");
|
66
|
+
const loading = spinner(`Initializing AI task: ${cyan(ai_task.name)}...`);
|
88
67
|
loading.prefixText = "⏳ ";
|
89
68
|
loading.start();
|
90
69
|
const endInfo = {
|
@@ -92,8 +71,75 @@ export const runAiTask = async (ai_task, allFiles, changedFilesSet) => {
|
|
92
71
|
text: "",
|
93
72
|
suffixText: `⏱️ ${gray(ms(new Date().getTime() - new Date(ai_task.startTime).getTime(), { long: true }))}`,
|
94
73
|
};
|
74
|
+
try {
|
75
|
+
await _runAiTask(ai_task, allFiles, changedFilesSet, loading, endInfo);
|
76
|
+
}
|
77
|
+
finally {
|
78
|
+
// Fallback spinner stop if loop exits unexpectedly
|
79
|
+
loading.stopAndPersist(endInfo);
|
80
|
+
}
|
81
|
+
};
|
82
|
+
const _runAiTask = async (ai_task, allFiles, changedFilesSet, loading, endInfo) => {
|
83
|
+
const model = getModel(ai_task.model);
|
84
|
+
const availableTools = {
|
85
|
+
...(await tools.fileSystem(ai_task.cwd)),
|
86
|
+
// ...(await tools.memory(path.join(ai_task.cwd, `.jixo/${ai_task.name}.memory.json`))),
|
87
|
+
...(await tools.sequentialThinking()),
|
88
|
+
...(await tools.jixoSkill().tools),
|
89
|
+
// ...(await tools.git(ai_task.cwd)),
|
90
|
+
};
|
91
|
+
const initialMessages = [];
|
92
|
+
const maxTurns = 40; // Safeguard against infinite loops
|
93
|
+
const promptConfigs = getPromptConfigs();
|
94
|
+
for (const role of ["system", "user"]) {
|
95
|
+
const promptConfig = promptConfigs[role];
|
96
|
+
const promptContent = promptConfig.content //
|
97
|
+
.replace(/\{\{task.(\w+)\}\}/g, (_, key) => {
|
98
|
+
return Reflect.get(ai_task, key);
|
99
|
+
})
|
100
|
+
.replace(/\{\{env.(\w+)\}\}/g, (_, key) => {
|
101
|
+
const envKey = key.toUpperCase();
|
102
|
+
const envValue = Reflect.get(process.env, envKey) ??
|
103
|
+
match(envKey)
|
104
|
+
.with("USER", () => os.userInfo().username)
|
105
|
+
.otherwise(() => "");
|
106
|
+
return envValue;
|
107
|
+
})
|
108
|
+
.replaceAll("{{allSkills}}", (_, key) => {
|
109
|
+
return YAML.stringify(tools.jixoSkill().allSkillNavList);
|
110
|
+
})
|
111
|
+
.replaceAll("{{allFiles}}", YAML.stringify({
|
112
|
+
[ai_task.cwd]: {
|
113
|
+
count: allFiles.length,
|
114
|
+
file: allFiles.map((e) => e.relativePath),
|
115
|
+
},
|
116
|
+
}))
|
117
|
+
.replaceAll("{{maxTurns}}", () => `${maxTurns}`)
|
118
|
+
.replaceAll("{{changedFiles}}", YAML.stringify(Object.entries(changedFilesSet).reduce((tree, [dir, changedFiles]) => {
|
119
|
+
tree[dir] = {
|
120
|
+
count: changedFiles.length,
|
121
|
+
files: changedFiles.map((e) => e.relativePath),
|
122
|
+
};
|
123
|
+
return tree;
|
124
|
+
}, {})));
|
125
|
+
log(`PROMPT ${role}:`, promptContent);
|
126
|
+
initialMessages.push({
|
127
|
+
role: role,
|
128
|
+
content: promptContent,
|
129
|
+
});
|
130
|
+
}
|
131
|
+
const currentMessages = [...initialMessages];
|
95
132
|
loop: for (let turn = 0; turn < maxTurns; turn++) {
|
96
|
-
|
133
|
+
if (turn === 0) {
|
134
|
+
loading.text = `Connecting To ${model.provider}...`;
|
135
|
+
}
|
136
|
+
else {
|
137
|
+
loading.text = `Processing turn ${turn + 1}...`;
|
138
|
+
currentMessages.push({
|
139
|
+
role: "user",
|
140
|
+
content: `Turns: ${turn}/${maxTurns}`,
|
141
|
+
});
|
142
|
+
}
|
97
143
|
const result = await streamText({
|
98
144
|
model: model,
|
99
145
|
messages: currentMessages,
|
@@ -110,6 +156,7 @@ export const runAiTask = async (ai_task, allFiles, changedFilesSet) => {
|
|
110
156
|
RETURN: "RETURN",
|
111
157
|
BREAK: "BREAK",
|
112
158
|
CONTINUE: "CONTINUE",
|
159
|
+
ERROR: "ERROR",
|
113
160
|
};
|
114
161
|
for await (const part of result.fullStream) {
|
115
162
|
if (firstStreamPart) {
|
@@ -132,8 +179,8 @@ export const runAiTask = async (ai_task, allFiles, changedFilesSet) => {
|
|
132
179
|
})
|
133
180
|
.with({ type: "tool-call" }, (callPart) => {
|
134
181
|
loading.prefixText = "🛠️ ";
|
135
|
-
loading.text = "Requesting tool:" + blue(callPart.toolName)
|
136
|
-
log("\nQAQ tool-call", callPart);
|
182
|
+
loading.text = "Requesting tool: " + blue(callPart.toolName);
|
183
|
+
log("\nQAQ tool-call: %y", callPart);
|
137
184
|
requestedToolCalls.push(callPart);
|
138
185
|
// Update assistant message to include tool calls
|
139
186
|
assistantMessageContent.push({
|
@@ -143,10 +190,10 @@ export const runAiTask = async (ai_task, allFiles, changedFilesSet) => {
|
|
143
190
|
args: callPart.args,
|
144
191
|
});
|
145
192
|
})
|
146
|
-
.with({ type: "error" }, (errorPart) => {
|
147
|
-
console.error("\nQAQ error", errorPart.error);
|
193
|
+
.with({ type: "error" }, async (errorPart) => {
|
148
194
|
loading.prefixText = endInfo.prefixText = "❌ ";
|
149
|
-
loading.text = endInfo.text = red(
|
195
|
+
loading.text = endInfo.text = red(`${errorPart.error}`);
|
196
|
+
await handleRetryError(errorPart.error, loading);
|
150
197
|
return LOOP_SIGNALS.BREAK; // Stop processing on error
|
151
198
|
})
|
152
199
|
.with({ type: "reasoning" }, (reasoningPart) => {
|
@@ -160,7 +207,7 @@ export const runAiTask = async (ai_task, allFiles, changedFilesSet) => {
|
|
160
207
|
.with({ type: "file" }, (p) => {
|
161
208
|
loading.prefixText = "📃 ";
|
162
209
|
loading.text = p.file.mediaType;
|
163
|
-
log("\nQAQ file", p.file);
|
210
|
+
log("\nQAQ file: %y", p.file);
|
164
211
|
})
|
165
212
|
.with({ type: "source" }, (p) => {
|
166
213
|
loading.prefixText = "🔗 ";
|
@@ -170,17 +217,17 @@ export const runAiTask = async (ai_task, allFiles, changedFilesSet) => {
|
|
170
217
|
else {
|
171
218
|
loading.text = p.url;
|
172
219
|
}
|
173
|
-
log("\nQAQ source", p);
|
220
|
+
log("\nQAQ source: %y", p);
|
174
221
|
})
|
175
|
-
.with({ type: "tool-result" }, (p) => log("\nQAQ tool-result", p))
|
176
|
-
.with({ type: "tool-call-streaming-start" }, (p) => log("\nQAQ tool-call-streaming-start", p))
|
177
|
-
.with({ type: "tool-call-delta" }, (p) => log("\nQAQ tool-call-delta", p))
|
178
|
-
.with({ type: "reasoning-part-finish" }, (p) => log("\nQAQ reasoning-part-finish", p))
|
179
|
-
.with({ type: "start-step" }, (p) => log("\nQAQ start-step", p))
|
180
|
-
.with({ type: "finish-step" }, (p) => log("\nQAQ finish-step", p))
|
181
|
-
.with({ type: "start" }, (p) => log("\nQAQ start", p))
|
222
|
+
.with({ type: "tool-result" }, (p) => log("\nQAQ tool-result: %y", p))
|
223
|
+
.with({ type: "tool-call-streaming-start" }, (p) => log("\nQAQ tool-call-streaming-start: %y", p))
|
224
|
+
.with({ type: "tool-call-delta" }, (p) => log("\nQAQ tool-call-delta: %y", p))
|
225
|
+
.with({ type: "reasoning-part-finish" }, (p) => log("\nQAQ reasoning-part-finish: %y", p))
|
226
|
+
.with({ type: "start-step" }, (p) => log("\nQAQ start-step: %y", p))
|
227
|
+
.with({ type: "finish-step" }, (p) => log("\nQAQ finish-step: %y", p))
|
228
|
+
.with({ type: "start" }, (p) => log("\nQAQ start: %y", p))
|
182
229
|
.with({ type: "finish" }, async (finishPart) => {
|
183
|
-
log("\nQAQ finish", finishPart);
|
230
|
+
log("\nQAQ finish: %y", finishPart);
|
184
231
|
// Add the assistant's message from this turn to the history
|
185
232
|
currentMessages.push(_currentAssistantMessage);
|
186
233
|
if (finishPart.finishReason === "stop" || finishPart.finishReason === "length") {
|
@@ -245,10 +292,13 @@ export const runAiTask = async (ai_task, allFiles, changedFilesSet) => {
|
|
245
292
|
// Other finish reasons, potentially an error or unexpected state
|
246
293
|
loading.prefixText = endInfo.prefixText = "🛑 ";
|
247
294
|
loading.text = endInfo.text = red(`${cyan(`[${ai_task.name}]`)} task finished with unhandled reason: ${finishPart.finishReason}`);
|
248
|
-
return LOOP_SIGNALS.
|
295
|
+
return LOOP_SIGNALS.ERROR;
|
249
296
|
}
|
250
297
|
})
|
251
298
|
.otherwise(() => { }); // Handle any other part types if necessary
|
299
|
+
if (LOOP_SIGNAL === LOOP_SIGNALS.ERROR) {
|
300
|
+
throw LOOP_SIGNAL;
|
301
|
+
}
|
252
302
|
if (LOOP_SIGNAL === LOOP_SIGNALS.RETURN) {
|
253
303
|
break loop;
|
254
304
|
}
|
@@ -263,7 +313,5 @@ export const runAiTask = async (ai_task, allFiles, changedFilesSet) => {
|
|
263
313
|
break;
|
264
314
|
}
|
265
315
|
}
|
266
|
-
// Fallback spinner stop if loop exits unexpectedly
|
267
|
-
loading.stopAndPersist(endInfo);
|
268
316
|
};
|
269
317
|
//# sourceMappingURL=run-ai-task.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"run-ai-task.js","sourceRoot":"","sources":["../../../src/commands/tasks/run-ai-task.ts"],"names":[],"mappings":"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","sourcesContent":["import {blue, cyan, FileEntry, gray, green, red, spinner, YAML, yellow} from \"@gaubee/nodekit\";\nimport {func_catch} from \"@gaubee/util\";\nimport {streamText, type AssistantModelMessage, type ModelMessage, type ToolCallPart} from \"ai\";\nimport debug from \"debug\";\nimport ms from \"ms\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport {match, P} from \"ts-pattern\";\nimport {safeEnv} from \"../../env.js\";\nimport {getModelMessage, getPromptConfigs} from \"../../helper/prompts-loader.js\";\nimport type {AiTask} from \"../../helper/resolve-ai-tasks.js\";\nimport {tools} from \"./ai-tools.js\";\nimport {providers} from \"./model-providers.js\";\n\nconst log = debug(\"jixo:run-ai-task\");\n\nconst getModel = (model?: string) => {\n return match(model)\n .with(P.string.startsWith(\"deepseek-\"), (model) => providers.deepseek(model))\n .with(P.string.startsWith(\"gemini-\"), (model) => providers.google(model))\n .with(P.string.startsWith(\"o3-\"), P.string.startsWith(\"o1-\"), P.string.startsWith(\"gpt-\"), (model) => providers.openai(model))\n .with(P.string.startsWith(\"claude-\"), (model) => providers.anthropic(model))\n .with(P.string.startsWith(\"grok-\"), (model) => providers.xai(model))\n .with(P.string.includes(\"/\"), (model) => providers.deepinfra(model))\n .otherwise(() => {\n if (safeEnv.JIXO_DEEPSEEK_API_KEY) {\n return providers.deepseek(\"deepseek-chat\");\n }\n if (safeEnv.JIXO_GOOGLE_API_KEY) {\n return providers.google(\"gemini-2.5-pro-preview-05-06\");\n }\n if (safeEnv.JIXO_OPENAI_API_KEY) {\n return providers.openai(\"o3-mini\");\n }\n if (safeEnv.JIXO_ANTHROPIC_API_KEY) {\n return providers.anthropic(\"claude-4-sonnet-20250514\");\n }\n if (safeEnv.JIXO_XAI_API_KEY) {\n return providers.xai(\"grok-3-beta\");\n }\n if (safeEnv.JIXO_DEEPINFRA_API_KEY) {\n return providers.deepinfra(\"meta-llama/Meta-Llama-3.1-405B-Instruct\");\n }\n return providers.deepseek(\"deepseek-reasoner\");\n });\n};\n\nexport const runAiTask = async (ai_task: AiTask, allFiles: FileEntry[], changedFilesSet: Record<string, FileEntry[]>) => {\n const model = getModel(ai_task.model);\n const availableTools = {\n ...(await tools.fileSystem(ai_task.cwd)),\n ...(await tools.memory(path.join(ai_task.cwd, `.jixo/${ai_task.name}.memory.json`))),\n // ...(await tools.fetch()),\n // ...(await tools.git(ai_task.cwd)),\n };\n\n const initialMessages: ModelMessage[] = getModelMessage(ai_task.agents);\n ai_task.startTime;\n const userPrompt = getPromptConfigs()\n .user.content //\n .replace(/\\{\\{task.(\\w+)\\}\\}/g, (_, key) => {\n return Reflect.get(ai_task, key);\n })\n .replace(/\\{\\{env.(\\w+)\\}\\}/g, (_, key) => {\n const envKey = key.toUpperCase();\n const envValue =\n Reflect.get(process.env, envKey) ??\n match(envKey)\n .with(\"USER\", () => os.userInfo().username)\n .otherwise(() => \"\");\n return envValue;\n })\n .replaceAll(\n \"{{allFiles}}\",\n YAML.stringify({\n [ai_task.cwd]: {\n count: allFiles.length,\n file: allFiles.map((e) => e.relativePath),\n },\n }),\n )\n .replaceAll(\n \"{{changedFiles}}\",\n YAML.stringify(\n Object.entries(changedFilesSet).reduce(\n (tree, [dir, changedFiles]) => {\n tree[dir] = {\n count: changedFiles.length,\n files: changedFiles.map((e) => e.relativePath),\n };\n return tree;\n },\n {} as Record<string, {count: number; files: string[]}>,\n ),\n ),\n );\n log(\"USER PROMPT:\", userPrompt);\n initialMessages.push({\n role: \"user\",\n content: userPrompt,\n });\n\n let currentMessages: ModelMessage[] = [...initialMessages];\n const maxTurns = 20; // Safeguard against infinite loops\n const loading = spinner(\"Initializing AI task...\");\n loading.prefixText = \"⏳ \";\n loading.start();\n const endInfo = {\n prefixText: \"\",\n text: \"\",\n suffixText: `⏱️ ${gray(ms(new Date().getTime() - new Date(ai_task.startTime).getTime(), {long: true}))}`,\n };\n\n loop: for (let turn = 0; turn < maxTurns; turn++) {\n loading.text = turn === 0 ? `Connecting To ${model.provider}...` : `Processing turn ${turn + 1}...`;\n\n const result = await streamText({\n model: model,\n messages: currentMessages,\n tools: availableTools,\n toolChoice: \"auto\", // Changed to auto for more flexibility\n });\n\n let fullReasoningText = \"\";\n let fullText = \"\";\n let firstStreamPart = true;\n const requestedToolCalls: ToolCallPart[] = []; // Using any for now, should be ToolCallPart from 'ai'\n\n const assistantMessageContent: AssistantModelMessage[\"content\"] & unknown[] = [];\n const _currentAssistantMessage: AssistantModelMessage = {role: \"assistant\", content: assistantMessageContent};\n\n const LOOP_SIGNALS = {\n RETURN: \"RETURN\",\n BREAK: \"BREAK\",\n CONTINUE: \"CONTINUE\",\n } as const;\n for await (const part of result.fullStream) {\n if (firstStreamPart) {\n firstStreamPart = false;\n loading.text = \"\"; // Clear initial connecting/processing message\n }\n const LOOP_SIGNAL = await match(part)\n .with({type: \"text\"}, (textPart) => {\n loading.prefixText = \"🤖 \";\n let assistantTextPart = assistantMessageContent.findLast((part) => part.type === \"text\");\n if (assistantTextPart == null) {\n assistantTextPart = {type: \"text\", text: \"\"};\n assistantMessageContent.push(assistantTextPart);\n }\n assistantTextPart.text += textPart.text;\n if (fullText === \"\") fullText = \"\\n\"; // For consistent display\n fullText += textPart.text;\n loading.text = fullText.split(\"\\n\").slice(-10).join(\"\\n\");\n })\n .with({type: \"tool-call\"}, (callPart) => {\n loading.prefixText = \"🛠️ \";\n loading.text = \"Requesting tool:\" + blue(callPart.toolName) + gray(\": \" + YAML.stringify(callPart.args).split(\"\\n\").slice(0, 3) + \"...\");\n log(\"\\nQAQ tool-call\", callPart);\n requestedToolCalls.push(callPart);\n // Update assistant message to include tool calls\n assistantMessageContent.push({\n type: \"tool-call\",\n toolCallId: callPart.toolCallId,\n toolName: callPart.toolName,\n args: callPart.args,\n });\n })\n .with({type: \"error\"}, (errorPart) => {\n console.error(\"\\nQAQ error\", errorPart.error);\n loading.prefixText = endInfo.prefixText = \"❌ \";\n loading.text = endInfo.text = red(`Error: ${errorPart.error?.toString()}`);\n return LOOP_SIGNALS.BREAK; // Stop processing on error\n })\n .with({type: \"reasoning\"}, (reasoningPart) => {\n loading.prefixText = \"🤔 \";\n if (fullReasoningText === \"\") loading.text = \"\";\n fullReasoningText += reasoningPart.text;\n loading.text = gray(fullReasoningText.split(\"\\n\").slice(-3).join(\"\\n\"));\n })\n // Add other console logs for debugging if needed, but keep them minimal for production\n .with({type: \"file\"}, (p) => {\n loading.prefixText = \"📃 \";\n loading.text = p.file.mediaType;\n\n log(\"\\nQAQ file\", p.file);\n })\n .with({type: \"source\"}, (p) => {\n loading.prefixText = \"🔗 \";\n if (p.title) {\n loading.text = `[${p.title}](${p.url})`;\n } else {\n loading.text = p.url;\n }\n\n log(\"\\nQAQ source\", p);\n })\n .with({type: \"tool-result\"}, (p) => log(\"\\nQAQ tool-result\", p))\n .with({type: \"tool-call-streaming-start\"}, (p) => log(\"\\nQAQ tool-call-streaming-start\", p))\n .with({type: \"tool-call-delta\"}, (p) => log(\"\\nQAQ tool-call-delta\", p))\n .with({type: \"reasoning-part-finish\"}, (p) => log(\"\\nQAQ reasoning-part-finish\", p))\n .with({type: \"start-step\"}, (p) => log(\"\\nQAQ start-step\", p))\n .with({type: \"finish-step\"}, (p) => log(\"\\nQAQ finish-step\", p))\n .with({type: \"start\"}, (p) => log(\"\\nQAQ start\", p))\n .with({type: \"finish\"}, async (finishPart) => {\n log(\"\\nQAQ finish\", finishPart);\n // Add the assistant's message from this turn to the history\n currentMessages.push(_currentAssistantMessage);\n\n if (finishPart.finishReason === \"stop\" || finishPart.finishReason === \"length\") {\n loading.prefixText = endInfo.prefixText = \"✅ \";\n loading.text = endInfo.text = green(`${cyan(`[${ai_task.name}]`)} Completed`);\n // Task finished without tool calls or after tool calls that didn't lead to more calls.\n return LOOP_SIGNALS.RETURN; // Exit the outer loop and function\n }\n\n if (finishPart.finishReason === \"tool-calls\") {\n if (requestedToolCalls.length === 0) {\n loading.prefixText = endInfo.prefixText = \"🚧 \";\n loading.text = endInfo.text = yellow(`${cyan(`[${ai_task.name}]`)} finished with 'tool-calls' but no tools were requested.`);\n return LOOP_SIGNALS.RETURN; // Exit, something is off\n }\n\n const toolResultMessages: ModelMessage[] = [];\n for (const toolCall of requestedToolCalls) {\n const toolToExecute = availableTools[toolCall.toolName];\n if (!toolToExecute || typeof toolToExecute.execute !== \"function\") {\n console.error(`Tool ${toolCall.toolName} not found or not executable.`);\n toolResultMessages.push({\n role: \"tool\",\n content: [\n {\n type: \"tool-result\",\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n result: JSON.stringify({error: `Tool ${toolCall.toolName} not found or not executable.`}),\n isError: true,\n },\n ],\n });\n continue;\n }\n loading.text = `Executing tool: ${toolCall.toolName}...`;\n const executionResult = await func_catch(() =>\n toolToExecute.execute!(toolCall.args, {\n toolCallId: toolCall.toolCallId,\n messages: currentMessages,\n }),\n )();\n toolResultMessages.push({\n role: \"tool\",\n content: [\n {\n type: \"tool-result\",\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n isError: !executionResult.success,\n result: JSON.stringify(executionResult.success ? executionResult.result : executionResult.error),\n },\n ],\n });\n if (executionResult.success) {\n loading.text = `Tool ${toolCall.toolName} executed.`;\n } else {\n loading.text = `Error executing tool ${toolCall.toolName}.`;\n }\n }\n currentMessages.push(...toolResultMessages);\n // Loop continues for the next turn\n } else {\n // Other finish reasons, potentially an error or unexpected state\n loading.prefixText = endInfo.prefixText = \"🛑 \";\n loading.text = endInfo.text = red(`${cyan(`[${ai_task.name}]`)} task finished with unhandled reason: ${finishPart.finishReason}`);\n return LOOP_SIGNALS.RETURN;\n }\n })\n .otherwise(() => {}); // Handle any other part types if necessary\n\n if (LOOP_SIGNAL === LOOP_SIGNALS.RETURN) {\n break loop;\n } else if (LOOP_SIGNAL === LOOP_SIGNALS.BREAK) {\n break;\n }\n }\n // If the stream finishes without a 'finish' part (e.g. error thrown inside), this loop might exit. Ensure spinner stops.\n if (turn === maxTurns - 1) {\n loading.prefixText = endInfo.prefixText = \"🚧 \";\n loading.text = endInfo.text = yellow(`${cyan(`[${ai_task.name}]`)} Max interaction turns reached.`);\n break;\n }\n }\n // Fallback spinner stop if loop exits unexpectedly\n loading.stopAndPersist(endInfo);\n};\n"]}
|
1
|
+
{"version":3,"file":"run-ai-task.js","sourceRoot":"","sources":["../../../src/commands/tasks/run-ai-task.ts"],"names":[],"mappings":"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","sourcesContent":["import {blue, cyan, FileEntry, gray, green, red, spinner, YAML, yellow, type Spinner} from \"@gaubee/nodekit\";\nimport {func_catch} from \"@gaubee/util\";\nimport {AISDKError, streamText, type AssistantModelMessage, type ModelMessage, type ToolCallPart, type ToolSet} from \"ai\";\nimport createDebug from \"debug\";\nimport ms from \"ms\";\nimport os from \"node:os\";\nimport {match, P} from \"ts-pattern\";\nimport {safeEnv} from \"../../env.js\";\nimport {handleRetryError} from \"../../helper/ai-retry-error.js\";\nimport {getPromptConfigs} from \"../../helper/prompts-loader.js\";\nimport type {AiTask} from \"../../helper/resolve-ai-tasks.js\";\nimport {tools} from \"./ai-tools.js\";\nimport {providers} from \"./model-providers.js\";\n\ncreateDebug.formatters.y = (v) => {\n return JSON.stringify(v, (_k, v) => {\n if (typeof v === \"string\") {\n let slice_len = 0;\n if (v.length > 200) {\n slice_len = 50;\n }\n if (v.length > 100) {\n slice_len = 30;\n }\n if (slice_len > 0) {\n return `<string:${v.length}>${v.slice(0, slice_len)}${gray(\"...\")}${v.slice(-slice_len)}`;\n }\n return v;\n }\n if (AISDKError.isInstance(v)) {\n return red(v.message);\n }\n return v;\n });\n};\nconst log = createDebug(\"jixo:run-ai-task\");\n\nconst getModel = (model?: string) => {\n return match(model)\n .with(P.string.startsWith(\"deepseek-\"), (model) => providers.deepseek(model))\n .with(P.string.startsWith(\"gemini-\"), (model) => providers.google(model))\n .with(P.string.startsWith(\"o3-\"), P.string.startsWith(\"o1-\"), P.string.startsWith(\"gpt-\"), (model) => providers.openai(model))\n .with(P.string.startsWith(\"claude-\"), (model) => providers.anthropic(model))\n .with(P.string.startsWith(\"grok-\"), (model) => providers.xai(model))\n .with(P.string.includes(\"/\"), (model) => providers.deepinfra(model))\n .otherwise(() => {\n if (safeEnv.JIXO_DEEPSEEK_API_KEY) {\n return providers.deepseek(\"deepseek-reasoner\");\n }\n if (safeEnv.JIXO_GOOGLE_API_KEY) {\n return providers.google(\"gemini-2.5-pro-preview-05-06\");\n }\n if (safeEnv.JIXO_OPENAI_API_KEY) {\n return providers.openai(\"o3-mini\");\n }\n if (safeEnv.JIXO_ANTHROPIC_API_KEY) {\n return providers.anthropic(\"claude-4-sonnet-20250514\");\n }\n if (safeEnv.JIXO_XAI_API_KEY) {\n return providers.xai(\"grok-3-beta\");\n }\n if (safeEnv.JIXO_DEEPINFRA_API_KEY) {\n return providers.deepinfra(\"meta-llama/Meta-Llama-3.1-405B-Instruct\");\n }\n return providers.deepseek(\"deepseek-reasoner\");\n });\n};\nexport const runAiTask = async (ai_task: AiTask, allFiles: FileEntry[], changedFilesSet: Record<string, FileEntry[]>) => {\n const loading = spinner(`Initializing AI task: ${cyan(ai_task.name)}...`);\n loading.prefixText = \"⏳ \";\n loading.start();\n const endInfo = {\n prefixText: \"\",\n text: \"\",\n suffixText: `⏱️ ${gray(ms(new Date().getTime() - new Date(ai_task.startTime).getTime(), {long: true}))}`,\n };\n try {\n await _runAiTask(ai_task, allFiles, changedFilesSet, loading, endInfo);\n } finally {\n // Fallback spinner stop if loop exits unexpectedly\n loading.stopAndPersist(endInfo);\n }\n};\n\nconst _runAiTask = async (\n ai_task: AiTask,\n allFiles: FileEntry[],\n changedFilesSet: Record<string, FileEntry[]>,\n loading: Spinner,\n endInfo: {\n prefixText: string;\n text: string;\n suffixText: string;\n },\n) => {\n const model = getModel(ai_task.model);\n const availableTools: ToolSet = {\n ...(await tools.fileSystem(ai_task.cwd)),\n // ...(await tools.memory(path.join(ai_task.cwd, `.jixo/${ai_task.name}.memory.json`))),\n ...(await tools.sequentialThinking()),\n ...(await tools.jixoSkill().tools),\n // ...(await tools.git(ai_task.cwd)),\n };\n\n const initialMessages: ModelMessage[] = [];\n const maxTurns = 40; // Safeguard against infinite loops\n\n const promptConfigs = getPromptConfigs();\n for (const role of [\"system\", \"user\"] as const) {\n const promptConfig = promptConfigs[role];\n\n const promptContent = promptConfig.content //\n .replace(/\\{\\{task.(\\w+)\\}\\}/g, (_, key) => {\n return Reflect.get(ai_task, key);\n })\n .replace(/\\{\\{env.(\\w+)\\}\\}/g, (_, key) => {\n const envKey = key.toUpperCase();\n const envValue =\n Reflect.get(process.env, envKey) ??\n match(envKey)\n .with(\"USER\", () => os.userInfo().username)\n .otherwise(() => \"\");\n return envValue;\n })\n .replaceAll(\"{{allSkills}}\", (_, key) => {\n return YAML.stringify(tools.jixoSkill().allSkillNavList);\n })\n .replaceAll(\n \"{{allFiles}}\",\n YAML.stringify({\n [ai_task.cwd]: {\n count: allFiles.length,\n file: allFiles.map((e) => e.relativePath),\n },\n }),\n )\n .replaceAll(\"{{maxTurns}}\", () => `${maxTurns}`)\n .replaceAll(\n \"{{changedFiles}}\",\n YAML.stringify(\n Object.entries(changedFilesSet).reduce(\n (tree, [dir, changedFiles]) => {\n tree[dir] = {\n count: changedFiles.length,\n files: changedFiles.map((e) => e.relativePath),\n };\n return tree;\n },\n {} as Record<string, {count: number; files: string[]}>,\n ),\n ),\n );\n log(`PROMPT ${role}:`, promptContent);\n initialMessages.push({\n role: role,\n content: promptContent,\n });\n }\n\n const currentMessages: ModelMessage[] = [...initialMessages];\n\n loop: for (let turn = 0; turn < maxTurns; turn++) {\n if (turn === 0) {\n loading.text = `Connecting To ${model.provider}...`;\n } else {\n loading.text = `Processing turn ${turn + 1}...`;\n currentMessages.push({\n role: \"user\",\n content: `Turns: ${turn}/${maxTurns}`,\n });\n }\n const result = await streamText({\n model: model,\n messages: currentMessages,\n tools: availableTools,\n toolChoice: \"auto\", // Changed to auto for more flexibility\n });\n\n let fullReasoningText = \"\";\n let fullText = \"\";\n let firstStreamPart = true;\n const requestedToolCalls: ToolCallPart[] = []; // Using any for now, should be ToolCallPart from 'ai'\n\n const assistantMessageContent: AssistantModelMessage[\"content\"] & unknown[] = [];\n const _currentAssistantMessage: AssistantModelMessage = {role: \"assistant\", content: assistantMessageContent};\n\n const LOOP_SIGNALS = {\n RETURN: \"RETURN\",\n BREAK: \"BREAK\",\n CONTINUE: \"CONTINUE\",\n ERROR: \"ERROR\",\n } as const;\n for await (const part of result.fullStream) {\n if (firstStreamPart) {\n firstStreamPart = false;\n loading.text = \"\"; // Clear initial connecting/processing message\n }\n const LOOP_SIGNAL = await match(part)\n .with({type: \"text\"}, (textPart) => {\n loading.prefixText = \"🤖 \";\n let assistantTextPart = assistantMessageContent.findLast((part) => part.type === \"text\");\n if (assistantTextPart == null) {\n assistantTextPart = {type: \"text\", text: \"\"};\n assistantMessageContent.push(assistantTextPart);\n }\n assistantTextPart.text += textPart.text;\n if (fullText === \"\") fullText = \"\\n\"; // For consistent display\n fullText += textPart.text;\n loading.text = fullText.split(\"\\n\").slice(-10).join(\"\\n\");\n })\n .with({type: \"tool-call\"}, (callPart) => {\n loading.prefixText = \"🛠️ \";\n loading.text = \"Requesting tool: \" + blue(callPart.toolName);\n log(\"\\nQAQ tool-call: %y\", callPart);\n requestedToolCalls.push(callPart);\n // Update assistant message to include tool calls\n assistantMessageContent.push({\n type: \"tool-call\",\n toolCallId: callPart.toolCallId,\n toolName: callPart.toolName,\n args: callPart.args,\n });\n })\n .with({type: \"error\"}, async (errorPart) => {\n loading.prefixText = endInfo.prefixText = \"❌ \";\n loading.text = endInfo.text = red(`${errorPart.error}`);\n await handleRetryError(errorPart.error, loading);\n return LOOP_SIGNALS.BREAK; // Stop processing on error\n })\n .with({type: \"reasoning\"}, (reasoningPart) => {\n loading.prefixText = \"🤔 \";\n if (fullReasoningText === \"\") loading.text = \"\";\n fullReasoningText += reasoningPart.text;\n loading.text = gray(fullReasoningText.split(\"\\n\").slice(-3).join(\"\\n\"));\n })\n // Add other console logs for debugging if needed, but keep them minimal for production\n .with({type: \"file\"}, (p) => {\n loading.prefixText = \"📃 \";\n loading.text = p.file.mediaType;\n\n log(\"\\nQAQ file: %y\", p.file);\n })\n .with({type: \"source\"}, (p) => {\n loading.prefixText = \"🔗 \";\n if (p.title) {\n loading.text = `[${p.title}](${p.url})`;\n } else {\n loading.text = p.url;\n }\n\n log(\"\\nQAQ source: %y\", p);\n })\n .with({type: \"tool-result\"}, (p) => log(\"\\nQAQ tool-result: %y\", p))\n .with({type: \"tool-call-streaming-start\"}, (p) => log(\"\\nQAQ tool-call-streaming-start: %y\", p))\n .with({type: \"tool-call-delta\"}, (p) => log(\"\\nQAQ tool-call-delta: %y\", p))\n .with({type: \"reasoning-part-finish\"}, (p) => log(\"\\nQAQ reasoning-part-finish: %y\", p))\n .with({type: \"start-step\"}, (p) => log(\"\\nQAQ start-step: %y\", p))\n .with({type: \"finish-step\"}, (p) => log(\"\\nQAQ finish-step: %y\", p))\n .with({type: \"start\"}, (p) => log(\"\\nQAQ start: %y\", p))\n .with({type: \"finish\"}, async (finishPart) => {\n log(\"\\nQAQ finish: %y\", finishPart);\n // Add the assistant's message from this turn to the history\n currentMessages.push(_currentAssistantMessage);\n\n if (finishPart.finishReason === \"stop\" || finishPart.finishReason === \"length\") {\n loading.prefixText = endInfo.prefixText = \"✅ \";\n loading.text = endInfo.text = green(`${cyan(`[${ai_task.name}]`)} Completed`);\n // Task finished without tool calls or after tool calls that didn't lead to more calls.\n return LOOP_SIGNALS.RETURN; // Exit the outer loop and function\n }\n\n if (finishPart.finishReason === \"tool-calls\") {\n if (requestedToolCalls.length === 0) {\n loading.prefixText = endInfo.prefixText = \"🚧 \";\n loading.text = endInfo.text = yellow(`${cyan(`[${ai_task.name}]`)} finished with 'tool-calls' but no tools were requested.`);\n return LOOP_SIGNALS.RETURN; // Exit, something is off\n }\n\n const toolResultMessages: ModelMessage[] = [];\n for (const toolCall of requestedToolCalls) {\n const toolToExecute = availableTools[toolCall.toolName];\n if (!toolToExecute || typeof toolToExecute.execute !== \"function\") {\n console.error(`Tool ${toolCall.toolName} not found or not executable.`);\n toolResultMessages.push({\n role: \"tool\",\n content: [\n {\n type: \"tool-result\",\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n result: JSON.stringify({error: `Tool ${toolCall.toolName} not found or not executable.`}),\n isError: true,\n },\n ],\n });\n continue;\n }\n loading.text = `Executing tool: ${toolCall.toolName}...`;\n const executionResult = await func_catch(() =>\n toolToExecute.execute!(toolCall.args, {\n toolCallId: toolCall.toolCallId,\n messages: currentMessages,\n }),\n )();\n toolResultMessages.push({\n role: \"tool\",\n content: [\n {\n type: \"tool-result\",\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n isError: !executionResult.success,\n result: JSON.stringify(executionResult.success ? executionResult.result : executionResult.error),\n },\n ],\n });\n if (executionResult.success) {\n loading.text = `Tool ${toolCall.toolName} executed.`;\n } else {\n loading.text = `Error executing tool ${toolCall.toolName}.`;\n }\n }\n currentMessages.push(...toolResultMessages);\n // Loop continues for the next turn\n } else {\n // Other finish reasons, potentially an error or unexpected state\n loading.prefixText = endInfo.prefixText = \"🛑 \";\n loading.text = endInfo.text = red(`${cyan(`[${ai_task.name}]`)} task finished with unhandled reason: ${finishPart.finishReason}`);\n return LOOP_SIGNALS.ERROR;\n }\n })\n .otherwise(() => {}); // Handle any other part types if necessary\n\n if (LOOP_SIGNAL === LOOP_SIGNALS.ERROR) {\n throw LOOP_SIGNAL;\n }\n if (LOOP_SIGNAL === LOOP_SIGNALS.RETURN) {\n break loop;\n } else if (LOOP_SIGNAL === LOOP_SIGNALS.BREAK) {\n break;\n }\n }\n // If the stream finishes without a 'finish' part (e.g. error thrown inside), this loop might exit. Ensure spinner stops.\n if (turn === maxTurns - 1) {\n loading.prefixText = endInfo.prefixText = \"🚧 \";\n loading.text = endInfo.text = yellow(`${cyan(`[${ai_task.name}]`)} Max interaction turns reached.`);\n break;\n }\n }\n};\n"]}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/run.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/run.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,GAAG,GACd,MAAM,MAAM,EACZ,SAAS;IACP,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,kBAmFF,CAAC"}
|
@@ -1,50 +1,81 @@
|
|
1
|
-
import { FileEntry, Ignore, normalizeFilePath, walkFiles } from "@gaubee/nodekit";
|
1
|
+
import { FileEntry, findChangedFilesSinceTime, Ignore, normalizeFilePath, walkFiles } from "@gaubee/nodekit";
|
2
2
|
import { iter_map_not_null } from "@gaubee/util";
|
3
3
|
import fs from "node:fs";
|
4
4
|
import path from "node:path";
|
5
5
|
import { loadConfig } from "../../config.js";
|
6
6
|
import { loadJixoEnv } from "../../env.js";
|
7
|
-
import { findChangedFilesSinceCommit } from "../../helper/find-changes.js";
|
8
7
|
import { resolveAiTasks } from "../../helper/resolve-ai-tasks.js";
|
9
8
|
import { runAiTask } from "./run-ai-task.js";
|
10
9
|
export const run = async (_cwd, options) => {
|
11
10
|
const cwd = normalizeFilePath(_cwd);
|
12
11
|
const config = await loadConfig(cwd);
|
13
|
-
|
14
|
-
const
|
15
|
-
|
16
|
-
|
17
|
-
const
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
const
|
28
|
-
|
29
|
-
|
12
|
+
let { force = false } = options;
|
13
|
+
const { loopTimes: MAX_LOOP_TIMES = Infinity } = options;
|
14
|
+
let currentTimes = 1;
|
15
|
+
let retryTimes = 0;
|
16
|
+
const MAX_RETRY_TIMES = 3;
|
17
|
+
while (currentTimes <= MAX_LOOP_TIMES) {
|
18
|
+
const ai_tasks = resolveAiTasks(cwd, config.tasks);
|
19
|
+
const nameMatcher = options.nameFilter.length ? new Ignore(options.nameFilter, cwd) : { isMatch: () => true };
|
20
|
+
const dirMatcher = options.dirFilter.length ? new Ignore(options.dirFilter, cwd) : { isMatch: () => true };
|
21
|
+
const cwdIgnoreFilepath = path.join(cwd, ".gitignore");
|
22
|
+
const ignore = [".git"];
|
23
|
+
if (fs.existsSync(cwdIgnoreFilepath)) {
|
24
|
+
ignore.push(...fs.readFileSync(cwdIgnoreFilepath, "utf-8").split("\n"));
|
25
|
+
}
|
26
|
+
const allFiles = [...walkFiles(cwd, { ignore })];
|
27
|
+
let allDone = true;
|
28
|
+
try {
|
29
|
+
for (const ai_task of ai_tasks) {
|
30
|
+
// 如果进度已经满了,那么跳过
|
31
|
+
if (ai_task.preProgress >= 1 && !force) {
|
32
|
+
continue;
|
33
|
+
}
|
34
|
+
const { dirs: task_dirs } = ai_task;
|
35
|
+
if (!task_dirs.some((dir) => dirMatcher.isMatch(dir))) {
|
36
|
+
continue;
|
37
|
+
}
|
38
|
+
if (!nameMatcher.isMatch(ai_task.name)) {
|
39
|
+
continue;
|
40
|
+
}
|
41
|
+
const isCwdTask = cwd === task_dirs[0] && task_dirs.length === 1;
|
42
|
+
const changedFiles = (await findChangedFilesSinceTime(ai_task.preUpdateTime, cwd)) ?? allFiles;
|
43
|
+
const task_changedFiles = isCwdTask
|
44
|
+
? { [cwd]: changedFiles }
|
45
|
+
: task_dirs.reduce((tree, task_dir) => {
|
46
|
+
tree[task_dir] = iter_map_not_null(changedFiles, (file) => {
|
47
|
+
if (file.path.startsWith(task_dirs + "/")) {
|
48
|
+
return new FileEntry(file.path, { cwd: task_dir, state: file.stats });
|
49
|
+
}
|
50
|
+
});
|
51
|
+
return tree;
|
52
|
+
}, {});
|
53
|
+
const task_allFiles = isCwdTask ? allFiles : task_dirs.map((task_dir) => [...walkFiles(task_dir, { ignore })]).flat();
|
54
|
+
loadJixoEnv(cwd);
|
55
|
+
/// 只要有一个任务执行了,那么allDone就要标记成false,进入下一次循环来判断
|
56
|
+
allDone = false;
|
57
|
+
await runAiTask(ai_task, task_allFiles, task_changedFiles);
|
58
|
+
}
|
59
|
+
}
|
60
|
+
catch {
|
61
|
+
// 遇到异常,那么重试
|
62
|
+
if (retryTimes < MAX_RETRY_TIMES) {
|
63
|
+
retryTimes += 1;
|
64
|
+
continue;
|
65
|
+
}
|
66
|
+
else {
|
67
|
+
break;
|
68
|
+
}
|
30
69
|
}
|
31
|
-
|
32
|
-
|
70
|
+
// force 只能生效一次,避免无限循环
|
71
|
+
force = false;
|
72
|
+
currentTimes += 1;
|
73
|
+
/// 成功一次后,retry计数就重制
|
74
|
+
retryTimes = 0;
|
75
|
+
/// 如果没有任务执行了,那么退出循环
|
76
|
+
if (allDone) {
|
77
|
+
break;
|
33
78
|
}
|
34
|
-
const isCwdTask = cwd === task_dirs[0] && task_dirs.length === 1;
|
35
|
-
const task_changedFiles = isCwdTask
|
36
|
-
? { [cwd]: changedFiles }
|
37
|
-
: task_dirs.reduce((tree, task_dir) => {
|
38
|
-
tree[task_dir] = iter_map_not_null(changedFiles, (file) => {
|
39
|
-
if (file.path.startsWith(task_dirs + "/")) {
|
40
|
-
return new FileEntry(file.path, { cwd: task_dir, state: file.stats });
|
41
|
-
}
|
42
|
-
});
|
43
|
-
return tree;
|
44
|
-
}, {});
|
45
|
-
const task_allFiles = isCwdTask ? allFiles : task_dirs.map((task_dir) => [...walkFiles(task_dir, { ignore })]).flat();
|
46
|
-
loadJixoEnv(cwd);
|
47
|
-
await runAiTask(ai_task, task_allFiles, task_changedFiles);
|
48
79
|
}
|
49
80
|
};
|
50
81
|
//# sourceMappingURL=run.js.map
|