@jixo/cli 0.7.0 → 0.9.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.
@@ -1 +1 @@
1
- {"version":3,"file":"ai-tools.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/ai-tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAkD,KAAK,OAAO,EAAC,MAAM,IAAI,CAAC;AAGjF,eAAO,MAAM,KAAK;sBAGD,MAAM;8BAeM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA6BjB,MAAM;CAavB,CAAC"}
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;AAC5E,OAAO,EAAC,4BAA4B,IAAI,eAAe,EAAe,MAAM,IAAI,CAAC;AACjF,OAAO,EAAC,8BAA8B,EAAC,MAAM,cAAc,CAAC;AAE5D,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,UAAU,EAAE,SAAS,CAAC,GAAG,EAAE;QACzB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAmB,CAAC;QACvC,OAAO,CAAC,GAAW,EAAE,EAAE;YACrB,OAAO,oBAAoB,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE;gBAC/C,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC;oBACtC,SAAS,EAAE,IAAI,8BAA8B,CAAC;wBAC5C,OAAO,EAAE,MAAM;wBACf,IAAI,EAAE,CAAC,yCAAyC,EAAE,GAAG,CAAC;qBACvD,CAAC;iBACH,CAAC,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;gBACtC,OAAO,KAAK,CAAC;YACf,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC,CAAC;IACF,MAAM,EAAE,SAAS,CAAC,GAAG,EAAE;QACrB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAmB,CAAC;QACvC,OAAO,CAAC,eAAuB,EAAE,EAAE;YACjC,OAAO,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,KAAK,IAAI,EAAE;gBAC3D,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC;oBACtC,SAAS,EAAE,IAAI,8BAA8B,CAAC;wBAC5C,OAAO,EAAE,MAAM;wBACf,IAAI,EAAE,CAAC,qCAAqC,CAAC;wBAC7C,GAAG,EAAE;4BACH,gBAAgB,EAAE,eAAe;yBAClC;qBACF,CAAC;iBACH,CAAC,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;gBACtC,OAAO,KAAK,CAAC;YACf,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC,CAAC;IACF,KAAK,EAAE,aAAa,CAAC,KAAK,IAAI,EAAE;QAC9B,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC;YACtC,SAAS,EAAE,IAAI,8BAA8B,CAAC;gBAC5C,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,CAAC,kBAAkB,CAAC;aAC3B,CAAC;SACH,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IACF,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE;QAClB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAmB,CAAC;QAEvC,OAAO,CAAC,IAAY,EAAE,EAAE;YACtB,OAAO,oBAAoB,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE;gBAChD,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC;oBACtC,SAAS,EAAE,IAAI,8BAA8B,CAAC;wBAC5C,OAAO,EAAE,KAAK;wBACd,IAAI,EAAE,CAAC,gBAAgB,EAAE,cAAc,EAAE,IAAI,CAAC;qBAC/C,CAAC;iBACH,CAAC,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;gBACtC,OAAO,KAAK,CAAC;YACf,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC,CAAC;CACH,CAAC","sourcesContent":["import {func_lazy, func_remember, map_get_or_put_async} from \"@gaubee/util\";\nimport {experimental_createMCPClient as createMCPClient, type ToolSet} from \"ai\";\nimport {Experimental_StdioMCPTransport} from \"ai/mcp-stdio\";\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 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"]}
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,EAA6B,MAAM,iBAAiB,CAAC;AASlF,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,kCAAkC,CAAC;AAoC7D,eAAO,MAAM,SAAS,GAAU,SAAS,MAAM,EAAE,UAAU,SAAS,EAAE,EAAE,iBAAiB,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,kBA+NnH,CAAC"}
1
+ {"version":3,"file":"run-ai-task.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/run-ai-task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,SAAS,EAA0C,MAAM,iBAAiB,CAAC;AAU/F,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,kCAAkC,CAAC;AAqC7D,eAAO,MAAM,SAAS,GAAU,SAAS,MAAM,EAAE,UAAU,SAAS,EAAE,EAAE,iBAAiB,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,kBAmQnH,CAAC"}
@@ -1,12 +1,13 @@
1
- import { blue, cyan, FileEntry, gray, green, spinner, YAML } from "@gaubee/nodekit";
1
+ import { blue, cyan, FileEntry, gray, green, red, spinner, YAML, yellow } from "@gaubee/nodekit";
2
2
  import { func_catch } from "@gaubee/util";
3
3
  import { streamText } from "ai";
4
4
  import debug from "debug";
5
+ import ms from "ms";
5
6
  import os from "node:os";
6
- import path from "node:path";
7
7
  import { match, P } from "ts-pattern";
8
8
  import { safeEnv } from "../../env.js";
9
- import { getModelMessage, getPromptConfigs } from "../../helper/prompts-loader.js";
9
+ import { handleRetryError } from "../../helper/ai-retry-error.js";
10
+ import { getPromptConfigs } from "../../helper/prompts-loader.js";
10
11
  import { tools } from "./ai-tools.js";
11
12
  import { providers } from "./model-providers.js";
12
13
  const log = debug("jixo:run-ai-task");
@@ -20,7 +21,7 @@ const getModel = (model) => {
20
21
  .with(P.string.includes("/"), (model) => providers.deepinfra(model))
21
22
  .otherwise(() => {
22
23
  if (safeEnv.JIXO_DEEPSEEK_API_KEY) {
23
- return providers.deepseek("deepseek-chat");
24
+ return providers.deepseek("deepseek-reasoner");
24
25
  }
25
26
  if (safeEnv.JIXO_GOOGLE_API_KEY) {
26
27
  return providers.google("gemini-2.5-pro-preview-05-06");
@@ -44,58 +45,74 @@ export const runAiTask = async (ai_task, allFiles, changedFilesSet) => {
44
45
  const model = getModel(ai_task.model);
45
46
  const availableTools = {
46
47
  ...(await tools.fileSystem(ai_task.cwd)),
47
- ...(await tools.memory(path.join(ai_task.cwd, `.jixo/${ai_task.name}.memory.json`))),
48
- // ...(await tools.fetch()),
48
+ // ...(await tools.memory(path.join(ai_task.cwd, `.jixo/${ai_task.name}.memory.json`))),
49
+ ...(await tools.sequentialThinking()),
50
+ ...(await tools.jixoSkill().tools),
49
51
  // ...(await tools.git(ai_task.cwd)),
50
52
  };
51
- const initialMessages = getModelMessage(ai_task.agents);
52
- ai_task.startTime;
53
- const userPrompt = getPromptConfigs()
54
- .user.content //
55
- .replace(/\{\{task.(\w+)\}\}/g, (_, key) => {
56
- return Reflect.get(ai_task, key);
57
- })
58
- .replace(/\{\{env.(\w+)\}\}/g, (_, key) => {
59
- const envKey = key.toUpperCase();
60
- const envValue = Reflect.get(process.env, envKey) ??
61
- match(envKey)
62
- .with("USER", () => os.userInfo().username)
63
- .otherwise(() => "");
64
- return envValue;
65
- })
66
- .replaceAll("{{allFiles}}", YAML.stringify({
67
- [ai_task.cwd]: {
68
- count: allFiles.length,
69
- file: allFiles.map((e) => e.relativePath),
70
- },
71
- }))
72
- .replaceAll("{{changedFiles}}", YAML.stringify(Object.entries(changedFilesSet).reduce((tree, [dir, changedFiles]) => {
73
- tree[dir] = {
74
- count: changedFiles.length,
75
- files: changedFiles.map((e) => e.relativePath),
76
- };
77
- return tree;
78
- }, {})));
79
- log("USER PROMPT:", userPrompt);
80
- initialMessages.push({
81
- role: "user",
82
- content: userPrompt,
83
- });
84
- let currentMessages = [...initialMessages];
85
- const maxTurns = 10; // Safeguard against infinite loops
53
+ const initialMessages = [];
54
+ const maxTurns = 40; // Safeguard against infinite loops
55
+ const promptConfigs = getPromptConfigs();
56
+ for (const role of ["system", "user"]) {
57
+ const promptConfig = promptConfigs[role];
58
+ const promptContent = promptConfig.content //
59
+ .replace(/\{\{task.(\w+)\}\}/g, (_, key) => {
60
+ return Reflect.get(ai_task, key);
61
+ })
62
+ .replace(/\{\{env.(\w+)\}\}/g, (_, key) => {
63
+ const envKey = key.toUpperCase();
64
+ const envValue = Reflect.get(process.env, envKey) ??
65
+ match(envKey)
66
+ .with("USER", () => os.userInfo().username)
67
+ .otherwise(() => "");
68
+ return envValue;
69
+ })
70
+ .replaceAll("{{allSkills}}", (_, key) => {
71
+ return YAML.stringify(tools.jixoSkill().allSkillNavList);
72
+ })
73
+ .replaceAll("{{allFiles}}", YAML.stringify({
74
+ [ai_task.cwd]: {
75
+ count: allFiles.length,
76
+ file: allFiles.map((e) => e.relativePath),
77
+ },
78
+ }))
79
+ .replaceAll("{{maxTurns}}", () => `${maxTurns}`)
80
+ .replaceAll("{{changedFiles}}", YAML.stringify(Object.entries(changedFilesSet).reduce((tree, [dir, changedFiles]) => {
81
+ tree[dir] = {
82
+ count: changedFiles.length,
83
+ files: changedFiles.map((e) => e.relativePath),
84
+ };
85
+ return tree;
86
+ }, {})));
87
+ log(`PROMPT ${role}:`, promptContent);
88
+ initialMessages.push({
89
+ role: role,
90
+ content: promptContent,
91
+ });
92
+ }
93
+ const currentMessages = [...initialMessages];
86
94
  const loading = spinner("Initializing AI task...");
87
95
  loading.prefixText = "⏳ ";
88
96
  loading.start();
97
+ const endInfo = {
98
+ prefixText: "",
99
+ text: "",
100
+ suffixText: `⏱️ ${gray(ms(new Date().getTime() - new Date(ai_task.startTime).getTime(), { long: true }))}`,
101
+ };
89
102
  loop: for (let turn = 0; turn < maxTurns; turn++) {
90
103
  loading.text = turn === 0 ? `Connecting To ${model.provider}...` : `Processing turn ${turn + 1}...`;
104
+ currentMessages.push({
105
+ role: "user",
106
+ content: `Turns: ${turn}/${maxTurns}`,
107
+ });
91
108
  const result = await streamText({
92
109
  model: model,
93
110
  messages: currentMessages,
94
111
  tools: availableTools,
95
112
  toolChoice: "auto", // Changed to auto for more flexibility
96
113
  });
97
- let reasoning = "";
98
- let fulltext = "";
114
+ let fullReasoningText = "";
115
+ let fullText = "";
99
116
  let firstStreamPart = true;
100
117
  const requestedToolCalls = []; // Using any for now, should be ToolCallPart from 'ai'
101
118
  const assistantMessageContent = [];
@@ -119,14 +136,14 @@ export const runAiTask = async (ai_task, allFiles, changedFilesSet) => {
119
136
  assistantMessageContent.push(assistantTextPart);
120
137
  }
121
138
  assistantTextPart.text += textPart.text;
122
- if (fulltext === "")
123
- fulltext = "\n"; // For consistent display
124
- fulltext += textPart.text;
125
- loading.text = fulltext;
139
+ if (fullText === "")
140
+ fullText = "\n"; // For consistent display
141
+ fullText += textPart.text;
142
+ loading.text = fullText.split("\n").slice(-10).join("\n");
126
143
  })
127
144
  .with({ type: "tool-call" }, (callPart) => {
128
145
  loading.prefixText = "🛠️ ";
129
- loading.text = "Requesting tool:" + blue(callPart.toolName) + gray(": " + YAML.stringify(callPart.args));
146
+ loading.text = "Requesting tool:" + blue(callPart.toolName) + gray(": " + YAML.stringify(callPart.args).split("\n").slice(0, 3) + "...");
130
147
  log("\nQAQ tool-call", callPart);
131
148
  requestedToolCalls.push(callPart);
132
149
  // Update assistant message to include tool calls
@@ -137,22 +154,35 @@ export const runAiTask = async (ai_task, allFiles, changedFilesSet) => {
137
154
  args: callPart.args,
138
155
  });
139
156
  })
140
- .with({ type: "error" }, (errorPart) => {
141
- loading.prefixText = "❌ ";
142
- console.error("\nQAQ error", errorPart.error);
143
- loading.fail(`Error: ${errorPart.error?.toString()}`);
157
+ .with({ type: "error" }, async (errorPart) => {
158
+ await handleRetryError(errorPart.error, loading);
159
+ loading.prefixText = endInfo.prefixText = " ";
160
+ loading.text = endInfo.text = red(`Error: ${errorPart.error?.toString()}`);
144
161
  return LOOP_SIGNALS.BREAK; // Stop processing on error
145
162
  })
146
163
  .with({ type: "reasoning" }, (reasoningPart) => {
147
164
  loading.prefixText = "🤔 ";
148
- if (reasoning === "")
165
+ if (fullReasoningText === "")
149
166
  loading.text = "";
150
- reasoning += reasoningPart.text;
151
- loading.text = gray(reasoning.split("\n").slice(-3).join("\n"));
167
+ fullReasoningText += reasoningPart.text;
168
+ loading.text = gray(fullReasoningText.split("\n").slice(-3).join("\n"));
152
169
  })
153
170
  // Add other console logs for debugging if needed, but keep them minimal for production
154
- .with({ type: "file" }, (p) => log("\nQAQ file", p.file))
155
- .with({ type: "source" }, (p) => log("\nQAQ source", p))
171
+ .with({ type: "file" }, (p) => {
172
+ loading.prefixText = "📃 ";
173
+ loading.text = p.file.mediaType;
174
+ log("\nQAQ file", p.file);
175
+ })
176
+ .with({ type: "source" }, (p) => {
177
+ loading.prefixText = "🔗 ";
178
+ if (p.title) {
179
+ loading.text = `[${p.title}](${p.url})`;
180
+ }
181
+ else {
182
+ loading.text = p.url;
183
+ }
184
+ log("\nQAQ source", p);
185
+ })
156
186
  .with({ type: "tool-result" }, (p) => log("\nQAQ tool-result", p))
157
187
  .with({ type: "tool-call-streaming-start" }, (p) => log("\nQAQ tool-call-streaming-start", p))
158
188
  .with({ type: "tool-call-delta" }, (p) => log("\nQAQ tool-call-delta", p))
@@ -165,14 +195,15 @@ export const runAiTask = async (ai_task, allFiles, changedFilesSet) => {
165
195
  // Add the assistant's message from this turn to the history
166
196
  currentMessages.push(_currentAssistantMessage);
167
197
  if (finishPart.finishReason === "stop" || finishPart.finishReason === "length") {
168
- loading.prefixText = "✅ ";
169
- loading.text = green(`${cyan(`[${ai_task.name}]`)} Completed`);
198
+ loading.prefixText = endInfo.prefixText = "✅ ";
199
+ loading.text = endInfo.text = green(`${cyan(`[${ai_task.name}]`)} Completed`);
170
200
  // Task finished without tool calls or after tool calls that didn't lead to more calls.
171
201
  return LOOP_SIGNALS.RETURN; // Exit the outer loop and function
172
202
  }
173
203
  if (finishPart.finishReason === "tool-calls") {
174
204
  if (requestedToolCalls.length === 0) {
175
- loading.warn("Finished with 'tool-calls' but no tools were requested.");
205
+ loading.prefixText = endInfo.prefixText = "🚧 ";
206
+ loading.text = endInfo.text = yellow(`${cyan(`[${ai_task.name}]`)} finished with 'tool-calls' but no tools were requested.`);
176
207
  return LOOP_SIGNALS.RETURN; // Exit, something is off
177
208
  }
178
209
  const toolResultMessages = [];
@@ -223,7 +254,8 @@ export const runAiTask = async (ai_task, allFiles, changedFilesSet) => {
223
254
  }
224
255
  else {
225
256
  // Other finish reasons, potentially an error or unexpected state
226
- loading.warn(`Task finished with unhandled reason: ${finishPart.finishReason}`);
257
+ loading.prefixText = endInfo.prefixText = "🛑 ";
258
+ loading.text = endInfo.text = red(`${cyan(`[${ai_task.name}]`)} task finished with unhandled reason: ${finishPart.finishReason}`);
227
259
  return LOOP_SIGNALS.RETURN;
228
260
  }
229
261
  })
@@ -237,11 +269,12 @@ export const runAiTask = async (ai_task, allFiles, changedFilesSet) => {
237
269
  }
238
270
  // If the stream finishes without a 'finish' part (e.g. error thrown inside), this loop might exit. Ensure spinner stops.
239
271
  if (turn === maxTurns - 1) {
240
- loading.warn("Max interaction turns reached.");
241
- return;
272
+ loading.prefixText = endInfo.prefixText = "🚧 ";
273
+ loading.text = endInfo.text = yellow(`${cyan(`[${ai_task.name}]`)} Max interaction turns reached.`);
274
+ break;
242
275
  }
243
276
  }
244
277
  // Fallback spinner stop if loop exits unexpectedly
245
- loading.stop();
278
+ loading.stopAndPersist(endInfo);
246
279
  };
247
280
  //# 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, spinner, YAML} from \"@gaubee/nodekit\";\nimport {func_catch} from \"@gaubee/util\";\nimport {streamText, type AssistantModelMessage, type ModelMessage, type ToolCallPart} from \"ai\";\nimport debug from \"debug\";\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\";\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 = 10; // Safeguard against infinite loops\n const loading = spinner(\"Initializing AI task...\");\n loading.prefixText = \"⏳ \";\n loading.start();\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 reasoning = \"\";\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;\n })\n .with({type: \"tool-call\"}, (callPart) => {\n loading.prefixText = \"🛠️ \";\n loading.text = \"Requesting tool:\" + blue(callPart.toolName) + gray(\": \" + YAML.stringify(callPart.args));\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 loading.prefixText = \"❌ \";\n console.error(\"\\nQAQ error\", errorPart.error);\n loading.fail(`Error: ${errorPart.error?.toString()}`);\n return LOOP_SIGNALS.BREAK; // Stop processing on error\n })\n .with({type: \"reasoning\"}, (reasoningPart) => {\n loading.prefixText = \"🤔 \";\n if (reasoning === \"\") loading.text = \"\";\n reasoning += reasoningPart.text;\n loading.text = gray(reasoning.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) => log(\"\\nQAQ file\", p.file))\n .with({type: \"source\"}, (p) => log(\"\\nQAQ source\", p))\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 = \"✅ \";\n loading.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.warn(\"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.warn(`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.warn(\"Max interaction turns reached.\");\n return;\n }\n }\n // Fallback spinner stop if loop exits unexpectedly\n loading.stop();\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} from \"@gaubee/nodekit\";\nimport {func_catch} from \"@gaubee/util\";\nimport {streamText, type AssistantModelMessage, type ModelMessage, type ToolCallPart, type ToolSet} from \"ai\";\nimport debug 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\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-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};\n\nexport const runAiTask = async (ai_task: AiTask, allFiles: FileEntry[], changedFilesSet: Record<string, FileEntry[]>) => {\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 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 currentMessages.push({\n role: \"user\",\n content: `Turns: ${turn}/${maxTurns}`,\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\"}, async (errorPart) => {\n await handleRetryError(errorPart.error, loading);\n\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"]}
@@ -0,0 +1,5 @@
1
+ import { spinner } from "@gaubee/nodekit";
2
+ type Spinner = ReturnType<typeof spinner>;
3
+ export declare const handleRetryError: (error: unknown, loading: Spinner) => Promise<void>;
4
+ export {};
5
+ //# sourceMappingURL=ai-retry-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-retry-error.d.ts","sourceRoot":"","sources":["../../src/helper/ai-retry-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAKxC,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAO,MAAM,gBAAgB,GAAU,OAAO,OAAO,EAAE,SAAS,OAAO,kBA6CtE,CAAC"}
@@ -0,0 +1,75 @@
1
+ import { spinner } from "@gaubee/nodekit";
2
+ import { delay, str_trim_indent } from "@gaubee/util";
3
+ import { APICallError, RetryError } from "ai";
4
+ import ms from "ms";
5
+ import z from "zod";
6
+ export const handleRetryError = async (error, loading) => {
7
+ if (!RetryError.isInstance(error)) {
8
+ return;
9
+ }
10
+ for (const inner_error of error.errors) {
11
+ if (!APICallError.isInstance(inner_error)) {
12
+ continue;
13
+ }
14
+ if (!inner_error.isRetryable) {
15
+ continue;
16
+ }
17
+ try {
18
+ const response = errorSchema.parse(JSON.parse(inner_error.responseBody ?? "{}"));
19
+ const retryDetail = response.error.details.find((d) => "retryDelay" in d);
20
+ if (retryDetail) {
21
+ const retryDelay = ms(retryDetail.retryDelay);
22
+ if (typeof retryDelay === "number") {
23
+ const { prefixText, text } = loading;
24
+ let remainingDelay = retryDelay;
25
+ const tickInterval = 1000;
26
+ const tick = () => {
27
+ loading.prefixText = "⏲️ ";
28
+ loading.text = str_trim_indent(`
29
+ ${inner_error.message}
30
+ ${" " + "─".repeat(Math.max(4, process.stdout.columns - 2))}
31
+ Retrying in ${ms(remainingDelay)}...`);
32
+ remainingDelay -= tickInterval;
33
+ };
34
+ tick();
35
+ const ti = setInterval(tick, tickInterval);
36
+ await delay(retryDelay);
37
+ clearInterval(ti);
38
+ // 回滚
39
+ loading.prefixText = prefixText;
40
+ loading.text = text;
41
+ }
42
+ }
43
+ }
44
+ catch {
45
+ console.error("\nQAQ unknown error", error);
46
+ }
47
+ }
48
+ };
49
+ const errorSchema = z.object({
50
+ error: z.object({
51
+ code: z.number(),
52
+ message: z.string(),
53
+ status: z.string(),
54
+ details: z.array(z.union([
55
+ z.object({
56
+ "@type": z.string(),
57
+ violations: z.array(z.object({
58
+ quotaMetric: z.string(),
59
+ quotaId: z.string(),
60
+ quotaDimensions: z.object({
61
+ location: z.string(),
62
+ model: z.string(),
63
+ }),
64
+ quotaValue: z.string(),
65
+ })),
66
+ }),
67
+ z.object({
68
+ "@type": z.string(),
69
+ links: z.array(z.object({ description: z.string(), url: z.string() })),
70
+ }),
71
+ z.object({ "@type": z.string(), retryDelay: z.string() }),
72
+ ])),
73
+ }),
74
+ });
75
+ //# sourceMappingURL=ai-retry-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-retry-error.js","sourceRoot":"","sources":["../../src/helper/ai-retry-error.ts"],"names":[],"mappings":"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","sourcesContent":["import {spinner} from \"@gaubee/nodekit\";\r\nimport {delay, str_trim_indent} from \"@gaubee/util\";\r\nimport {APICallError, RetryError} from \"ai\";\r\nimport ms from \"ms\";\r\nimport z from \"zod\";\r\ntype Spinner = ReturnType<typeof spinner>;\r\nexport const handleRetryError = async (error: unknown, loading: Spinner) => {\r\n if (!RetryError.isInstance(error)) {\r\n return;\r\n }\r\n for (const inner_error of error.errors) {\r\n if (!APICallError.isInstance(inner_error)) {\r\n continue;\r\n }\r\n if (!inner_error.isRetryable) {\r\n continue;\r\n }\r\n\r\n try {\r\n const response = errorSchema.parse(JSON.parse(inner_error.responseBody ?? \"{}\"));\r\n const retryDetail = response.error.details.find((d) => \"retryDelay\" in d);\r\n if (retryDetail) {\r\n const retryDelay = ms(retryDetail.retryDelay as ms.StringValue);\r\n\r\n if (typeof retryDelay === \"number\") {\r\n const {prefixText, text} = loading;\r\n let remainingDelay = retryDelay;\r\n const tickInterval = 1000;\r\n const tick = () => {\r\n loading.prefixText = \"⏲️ \";\r\n loading.text = str_trim_indent(`\r\n ${inner_error.message}\r\n ${\" \" + \"─\".repeat(Math.max(4, process.stdout.columns - 2))}\r\n Retrying in ${ms(remainingDelay)}...`);\r\n remainingDelay -= tickInterval;\r\n };\r\n tick();\r\n\r\n const ti = setInterval(tick, tickInterval);\r\n await delay(retryDelay);\r\n clearInterval(ti);\r\n\r\n // 回滚\r\n loading.prefixText = prefixText;\r\n loading.text = text;\r\n }\r\n }\r\n } catch {\r\n console.error(\"\\nQAQ unknown error\", error);\r\n }\r\n }\r\n};\r\n\r\nconst errorSchema = z.object({\r\n error: z.object({\r\n code: z.number(),\r\n message: z.string(),\r\n status: z.string(),\r\n details: z.array(\r\n z.union([\r\n z.object({\r\n \"@type\": z.string(),\r\n violations: z.array(\r\n z.object({\r\n quotaMetric: z.string(),\r\n quotaId: z.string(),\r\n quotaDimensions: z.object({\r\n location: z.string(),\r\n model: z.string(),\r\n }),\r\n quotaValue: z.string(),\r\n }),\r\n ),\r\n }),\r\n z.object({\r\n \"@type\": z.string(),\r\n links: z.array(z.object({description: z.string(), url: z.string()})),\r\n }),\r\n z.object({\"@type\": z.string(), retryDelay: z.string()}),\r\n ]),\r\n ),\r\n }),\r\n});\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-ai-tasks.d.ts","sourceRoot":"","sources":["../../src/helper/resolve-ai-tasks.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,KAAK,UAAU,EAAC,MAAM,cAAc,CAAC;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,EAAE,cAAc,UAAU,CAAC,OAAO,CAAC;UAGnE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAC;aACjB,MAAM;;UAGT,MAAM;SACP,MAAM;UACL,MAAM,EAAE;YACN,MAAM,EAAE;WACT,MAAM;eACF,MAAM;YACT,MAAM;SACT,MAAM;eACA,MAAM;IAwGpB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC"}
1
+ {"version":3,"file":"resolve-ai-tasks.d.ts","sourceRoot":"","sources":["../../src/helper/resolve-ai-tasks.ts"],"names":[],"mappings":"AAMA,OAAO,EAAC,KAAK,UAAU,EAAC,MAAM,cAAc,CAAC;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,EAAE,cAAc,UAAU,CAAC,OAAO,CAAC;UAGnE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAC;aACjB,MAAM;;UAGT,MAAM;SACP,MAAM;UACL,MAAM,EAAE;YACN,MAAM,EAAE;WACT,MAAM;eACF,MAAM;YACT,MAAM;SACT,MAAM;eACA,MAAM;IA0HpB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { matter, normalizeFilePath, readMarkdown, walkFiles, writeMarkdown } from "@gaubee/nodekit";
2
+ import { str_trim_indent } from "@gaubee/util";
2
3
  import fs from "node:fs";
3
4
  import path from "node:path";
4
5
  import { match, P } from "ts-pattern";
@@ -28,11 +29,25 @@ export const resolveAiTasks = (cwd, config_tasks) => {
28
29
  const useMemory = ai_task.data.useMemory || task_name;
29
30
  const useLog = ai_task.data.useLog || task_name;
30
31
  const log_filepath = path.join(cwd, `.jixo/${useLog}.log.md`);
31
- if (!fs.existsSync(log_filepath)) {
32
- writeMarkdown(log_filepath, ``, {
32
+ let log_fileContent = fs.readFileSync(log_filepath, "utf-8");
33
+ if (!fs.existsSync(log_filepath) || log_fileContent.trim() === "") {
34
+ writeMarkdown(log_filepath, str_trim_indent(`
35
+ ## 工作计划
36
+
37
+ <!--待定-->
38
+
39
+ ---
40
+
41
+ ## 工作日志
42
+
43
+ <!--暂无-->
44
+ `), {
45
+ title: "_待定_",
33
46
  createTime: new Date().toISOString(),
34
47
  updateTime: new Date().toISOString(),
48
+ progress: "0%",
35
49
  });
50
+ log_fileContent = fs.readFileSync(log_filepath, "utf-8");
36
51
  }
37
52
  tasks.push({
38
53
  ...ai_task,
@@ -49,7 +64,7 @@ export const resolveAiTasks = (cwd, config_tasks) => {
49
64
  .otherwise(() => ""),
50
65
  useMemory,
51
66
  useLog,
52
- log: fs.readFileSync(log_filepath, "utf-8"),
67
+ log: log_fileContent,
53
68
  startTime: new Date().toISOString(),
54
69
  });
55
70
  };