@jixo/cli 0.10.1 → 0.11.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.
Files changed (34) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +2 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/prompts/list.js +2 -2
  5. package/dist/commands/prompts/list.js.map +1 -1
  6. package/dist/commands/tasks/ai-tools.d.ts +280 -8
  7. package/dist/commands/tasks/ai-tools.d.ts.map +1 -1
  8. package/dist/commands/tasks/ai-tools.js +49 -14
  9. package/dist/commands/tasks/ai-tools.js.map +1 -1
  10. package/dist/commands/tasks/run-ai-task.d.ts +1 -1
  11. package/dist/commands/tasks/run-ai-task.d.ts.map +1 -1
  12. package/dist/commands/tasks/run-ai-task.js +71 -24
  13. package/dist/commands/tasks/run-ai-task.js.map +1 -1
  14. package/dist/commands/tasks/run.d.ts.map +1 -1
  15. package/dist/commands/tasks/run.js +20 -11
  16. package/dist/commands/tasks/run.js.map +1 -1
  17. package/dist/helper/ai-retry-error.d.ts +1 -1
  18. package/dist/helper/ai-retry-error.d.ts.map +1 -1
  19. package/dist/helper/ai-retry-error.js +63 -30
  20. package/dist/helper/ai-retry-error.js.map +1 -1
  21. package/dist/helper/handle-ai-error.d.ts +5 -0
  22. package/dist/helper/handle-ai-error.d.ts.map +1 -0
  23. package/dist/helper/handle-ai-error.js +122 -0
  24. package/dist/helper/handle-ai-error.js.map +1 -0
  25. package/dist/helper/prompts-loader.d.ts +9 -3
  26. package/dist/helper/prompts-loader.d.ts.map +1 -1
  27. package/dist/helper/prompts-loader.js +16 -16
  28. package/dist/helper/prompts-loader.js.map +1 -1
  29. package/dist/helper/resolve-ai-tasks.d.ts +21 -8
  30. package/dist/helper/resolve-ai-tasks.d.ts.map +1 -1
  31. package/dist/helper/resolve-ai-tasks.js +58 -19
  32. package/dist/helper/resolve-ai-tasks.js.map +1 -1
  33. package/dist/prompts.json +14 -2
  34. package/package.json +4 -3
@@ -0,0 +1,122 @@
1
+ import { gray, red, yellow } from "@gaubee/nodekit";
2
+ import { delay } from "@gaubee/util";
3
+ import { APICallError, RetryError } from "ai";
4
+ import ms from "ms";
5
+ import { match } from "ts-pattern";
6
+ import z from "zod";
7
+ export const handleError = async (error, loading) => {
8
+ for (const handle of [handleAPICallError, handleRetryError]) {
9
+ const matched = await handle(error, loading);
10
+ if (matched) {
11
+ return true;
12
+ }
13
+ }
14
+ };
15
+ const handleRetryError = async (error, loading) => {
16
+ if (!RetryError.isInstance(error)) {
17
+ return;
18
+ }
19
+ for (const inner_error of error.errors) {
20
+ const matched = await handleAPICallError(inner_error, loading);
21
+ if (matched) {
22
+ return true;
23
+ }
24
+ }
25
+ };
26
+ const handleAPICallError = async (error, loading) => {
27
+ if (!APICallError.isInstance(error)) {
28
+ return;
29
+ }
30
+ try {
31
+ if (error.isRetryable) {
32
+ const safeData = geminiErrorSchema.safeParse(error.data);
33
+ if (!safeData.success) {
34
+ throw safeData.error;
35
+ }
36
+ const retryDetail = safeData.data.error.details.find((d) => "retryDelay" in d);
37
+ if (retryDetail) {
38
+ const retryDelay = ms(retryDetail.retryDelay);
39
+ if (typeof retryDelay === "number") {
40
+ await waitRetryDelay(loading, retryDelay, (loading.text = yellow(error.message)));
41
+ return true;
42
+ }
43
+ }
44
+ }
45
+ else {
46
+ const safeData = commonErrorSchema.safeParse(error.data);
47
+ if (!safeData.success) {
48
+ throw safeData.error;
49
+ }
50
+ await match(safeData.data.error)
51
+ /// 余额不足
52
+ .with({ message: "Insufficient Balance" }, async () => {
53
+ /// 30s重试
54
+ await waitRetryDelay(loading, 1000 * 30, (loading.text = red("Insufficient Balance") + "\n" + red(error.url)));
55
+ })
56
+ .otherwise(() => {
57
+ throw error;
58
+ });
59
+ return true;
60
+ }
61
+ }
62
+ catch {
63
+ console.error("\nQAQ unknown error", error);
64
+ }
65
+ };
66
+ const commonErrorSchema = z.object({
67
+ error: z.object({
68
+ message: z.string(),
69
+ type: z.string(),
70
+ param: z.any(),
71
+ code: z.string(),
72
+ }),
73
+ });
74
+ const geminiErrorSchema = z.object({
75
+ error: z.object({
76
+ code: z.number(),
77
+ message: z.string(),
78
+ status: z.string(),
79
+ details: z.array(z.union([
80
+ z.object({
81
+ "@type": z.string(),
82
+ violations: z.array(z.object({
83
+ quotaMetric: z.string(),
84
+ quotaId: z.string(),
85
+ quotaDimensions: z.object({
86
+ location: z.string(),
87
+ model: z.string(),
88
+ }),
89
+ quotaValue: z.string(),
90
+ })),
91
+ }),
92
+ z.object({
93
+ "@type": z.string(),
94
+ links: z.array(z.object({ description: z.string(), url: z.string() })),
95
+ }),
96
+ z.object({ "@type": z.string(), retryDelay: z.string() }),
97
+ ])),
98
+ }),
99
+ });
100
+ const waitRetryDelay = async (loading, retryDelay, message) => {
101
+ const { prefixText, text } = loading;
102
+ let remainingDelay = retryDelay;
103
+ const tickInterval = 1000;
104
+ const tick = () => {
105
+ loading.prefixText = "⏲️ ";
106
+ loading.text = [
107
+ //
108
+ message,
109
+ " " + gray("─".repeat(Math.max(4, process.stdout.columns - 2))),
110
+ `Retrying in ${ms(remainingDelay)}...`,
111
+ ].join("\n");
112
+ remainingDelay -= tickInterval;
113
+ };
114
+ tick();
115
+ const ti = setInterval(tick, tickInterval);
116
+ await delay(retryDelay);
117
+ clearInterval(ti);
118
+ // 回滚
119
+ loading.prefixText = prefixText;
120
+ loading.text = text;
121
+ };
122
+ //# sourceMappingURL=handle-ai-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handle-ai-error.js","sourceRoot":"","sources":["../../src/helper/handle-ai-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAe,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AACnC,OAAO,EAAC,YAAY,EAAE,UAAU,EAAC,MAAM,IAAI,CAAC;AAC5C,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAC,KAAK,EAAC,MAAM,YAAY,CAAC;AACjC,OAAO,CAAC,MAAM,KAAK,CAAC;AAGpB,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,KAAc,EAAE,OAAgB,EAAE,EAAE;IACpE,KAAK,MAAM,MAAM,IAAI,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,EAAE,CAAC;QAC5D,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC7C,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,KAAK,EAAE,KAAc,EAAE,OAAgB,EAAE,EAAE;IAClE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO;IACT,CAAC;IACD,KAAK,MAAM,WAAW,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC/D,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,KAAK,EAAE,KAAc,EAAE,OAAgB,EAAE,EAAE;IACpE,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO;IACT,CAAC;IACD,IAAI,CAAC;QACH,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzD,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,MAAM,QAAQ,CAAC,KAAK,CAAC;YACvB,CAAC;YACD,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC;YAC/E,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,UAAU,GAAG,EAAE,CAAC,WAAW,CAAC,UAA4B,CAAC,CAAC;gBAEhE,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;oBACnC,MAAM,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;oBAClF,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,QAAQ,GAAG,iBAAiB,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzD,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,MAAM,QAAQ,CAAC,KAAK,CAAC;YACvB,CAAC;YACD,MAAM,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;gBAC9B,QAAQ;iBACP,IAAI,CAAC,EAAC,OAAO,EAAE,sBAAsB,EAAC,EAAE,KAAK,IAAI,EAAE;gBAClD,SAAS;gBACT,MAAM,cAAc,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,sBAAsB,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACjH,CAAC,CAAC;iBACD,SAAS,CAAC,GAAG,EAAE;gBACd,MAAM,KAAK,CAAC;YACd,CAAC,CAAC,CAAC;YACL,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;QACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,KAAK,EAAE,CAAC,CAAC,GAAG,EAAE;QACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;KACjB,CAAC;CACH,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;QACnB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,OAAO,EAAE,CAAC,CAAC,KAAK,CACd,CAAC,CAAC,KAAK,CAAC;YACN,CAAC,CAAC,MAAM,CAAC;gBACP,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;gBACnB,UAAU,EAAE,CAAC,CAAC,KAAK,CACjB,CAAC,CAAC,MAAM,CAAC;oBACP,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;oBACvB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;oBACnB,eAAe,EAAE,CAAC,CAAC,MAAM,CAAC;wBACxB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;wBACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;qBAClB,CAAC;oBACF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;iBACvB,CAAC,CACH;aACF,CAAC;YACF,CAAC,CAAC,MAAM,CAAC;gBACP,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;gBACnB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAC,CAAC,CAAC;aACrE,CAAC;YACF,CAAC,CAAC,MAAM,CAAC,EAAC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,EAAC,CAAC;SACxD,CAAC,CACH;KACF,CAAC;CACH,CAAC,CAAC;AAEH,MAAM,cAAc,GAAG,KAAK,EAAE,OAAgB,EAAE,UAAkB,EAAE,OAAe,EAAE,EAAE;IACrF,MAAM,EAAC,UAAU,EAAE,IAAI,EAAC,GAAG,OAAO,CAAC;IACnC,IAAI,cAAc,GAAG,UAAU,CAAC;IAChC,MAAM,YAAY,GAAG,IAAI,CAAC;IAC1B,MAAM,IAAI,GAAG,GAAG,EAAE;QAChB,OAAO,CAAC,UAAU,GAAG,KAAK,CAAC;QAC3B,OAAO,CAAC,IAAI,GAAG;YACb,EAAE;YACF,OAAO;YACP,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;YAC/D,eAAe,EAAE,CAAC,cAAc,CAAC,KAAK;SACvC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,cAAc,IAAI,YAAY,CAAC;IACjC,CAAC,CAAC;IACF,IAAI,EAAE,CAAC;IAEP,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAC3C,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,CAAC;IAElB,KAAK;IACL,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC;IAChC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;AACtB,CAAC,CAAC","sourcesContent":["import {gray, red, yellow, type Spinner} from \"@gaubee/nodekit\";\r\nimport {delay} from \"@gaubee/util\";\r\nimport {APICallError, RetryError} from \"ai\";\r\nimport ms from \"ms\";\r\nimport {match} from \"ts-pattern\";\r\nimport z from \"zod\";\r\ntype Loading = Pick<Spinner, \"prefixText\" | \"text\">;\r\n\r\nexport const handleError = async (error: unknown, loading: Loading) => {\r\n for (const handle of [handleAPICallError, handleRetryError]) {\r\n const matched = await handle(error, loading);\r\n if (matched) {\r\n return true;\r\n }\r\n }\r\n};\r\n\r\nconst handleRetryError = async (error: unknown, loading: Loading) => {\r\n if (!RetryError.isInstance(error)) {\r\n return;\r\n }\r\n for (const inner_error of error.errors) {\r\n const matched = await handleAPICallError(inner_error, loading);\r\n if (matched) {\r\n return true;\r\n }\r\n }\r\n};\r\n\r\nconst handleAPICallError = async (error: unknown, loading: Loading) => {\r\n if (!APICallError.isInstance(error)) {\r\n return;\r\n }\r\n try {\r\n if (error.isRetryable) {\r\n const safeData = geminiErrorSchema.safeParse(error.data);\r\n if (!safeData.success) {\r\n throw safeData.error;\r\n }\r\n const retryDetail = safeData.data.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 await waitRetryDelay(loading, retryDelay, (loading.text = yellow(error.message)));\r\n return true;\r\n }\r\n }\r\n } else {\r\n const safeData = commonErrorSchema.safeParse(error.data);\r\n if (!safeData.success) {\r\n throw safeData.error;\r\n }\r\n await match(safeData.data.error)\r\n /// 余额不足\r\n .with({message: \"Insufficient Balance\"}, async () => {\r\n /// 30s重试\r\n await waitRetryDelay(loading, 1000 * 30, (loading.text = red(\"Insufficient Balance\") + \"\\n\" + red(error.url)));\r\n })\r\n .otherwise(() => {\r\n throw error;\r\n });\r\n return true;\r\n }\r\n } catch {\r\n console.error(\"\\nQAQ unknown error\", error);\r\n }\r\n};\r\n\r\nconst commonErrorSchema = z.object({\r\n error: z.object({\r\n message: z.string(),\r\n type: z.string(),\r\n param: z.any(),\r\n code: z.string(),\r\n }),\r\n});\r\n\r\nconst geminiErrorSchema = 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\r\nconst waitRetryDelay = async (loading: Loading, retryDelay: number, message: string) => {\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 = [\r\n //\r\n message,\r\n \" \" + gray(\"─\".repeat(Math.max(4, process.stdout.columns - 2))),\r\n `Retrying in ${ms(remainingDelay)}...`,\r\n ].join(\"\\n\");\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"]}
@@ -1,5 +1,11 @@
1
- import type { ModelMessage } from "ai";
2
1
  import defaultPrompts from "../prompts.json";
3
- export declare const getPromptConfigs: import("@gaubee/util").FuncRemember<() => typeof defaultPrompts, void | ((this: unknown) => any)>;
4
- export declare const getModelMessage: (agents: string[]) => ModelMessage[];
2
+ export declare const getAllPromptConfigs: import("@gaubee/util").FuncRemember<() => typeof defaultPrompts, void | ((this: unknown) => any)>;
3
+ export type PromptConfigs = typeof defaultPrompts;
4
+ export type PromptItemConfig = PromptConfigs[keyof PromptConfigs];
5
+ /**
6
+ * 所有的技能信息
7
+ * key: skill-name
8
+ * value: skill-description
9
+ */
10
+ export declare const getAllSkillMap: import("@gaubee/util").FuncRemember<() => Record<string, string>, void | ((this: unknown) => any)>;
5
11
  //# sourceMappingURL=prompts-loader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts-loader.d.ts","sourceRoot":"","sources":["../../src/helper/prompts-loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,IAAI,CAAC;AAErC,OAAO,cAAc,MAAM,iBAAiB,CAAqB;AAGjE,eAAO,MAAM,gBAAgB,4CAAqB,OAAO,cAAc,kCAMrE,CAAC;AAIH,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,EAAE,mBAc/C,CAAC"}
1
+ {"version":3,"file":"prompts-loader.d.ts","sourceRoot":"","sources":["../../src/helper/prompts-loader.ts"],"names":[],"mappings":"AAIA,OAAO,cAAc,MAAM,iBAAiB,CAAqB;AAGjE,eAAO,MAAM,mBAAmB,4CAAqB,OAAO,cAAc,kCAMxE,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,cAAc,CAAC;AAClD,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAAC,MAAM,aAAa,CAAC,CAAC;AAElE;;;;GAIG;AACH,eAAO,MAAM,cAAc,oGAWzB,CAAC"}
@@ -1,28 +1,28 @@
1
1
  import { createResolverByRootFile } from "@gaubee/node";
2
2
  import { readJson } from "@gaubee/nodekit";
3
- import { func_remember } from "@gaubee/util";
3
+ import { func_remember, obj_props } from "@gaubee/util";
4
4
  import fs from "node:fs";
5
5
  import defaultPrompts from "../prompts.json" with { type: "json" };
6
6
  const rootResolver = createResolverByRootFile(import.meta.url);
7
- export const getPromptConfigs = func_remember(() => {
7
+ export const getAllPromptConfigs = func_remember(() => {
8
8
  const download_prompts_json_filepath = rootResolver("prompts.json");
9
9
  if (fs.existsSync(download_prompts_json_filepath)) {
10
10
  return readJson(download_prompts_json_filepath);
11
11
  }
12
12
  return defaultPrompts;
13
13
  });
14
- export const getModelMessage = (agents) => {
15
- const promptConfigs = getPromptConfigs();
16
- const modelMessage = [];
17
- const names = agents.slice();
18
- for (const name of names) {
19
- const promptConfig = name in promptConfigs ? Reflect.get(promptConfigs, name) : null;
20
- if (!promptConfig) {
21
- continue;
22
- }
23
- modelMessage.unshift({ role: "system", content: promptConfig.content });
24
- names.push(...promptConfig.data.parent);
25
- }
26
- return modelMessage;
27
- };
14
+ /**
15
+ * 所有的技能信息
16
+ * key: skill-name
17
+ * value: skill-description
18
+ */
19
+ export const getAllSkillMap = func_remember(() => {
20
+ const configs = getAllPromptConfigs();
21
+ const skills = obj_props(configs).filter((key) => key.endsWith(".skill"));
22
+ const allSkillMap = skills.reduce((tree, skill) => {
23
+ tree[skill] = configs[skill].content.split("\n")[0];
24
+ return tree;
25
+ }, Object.create(null));
26
+ return allSkillMap;
27
+ });
28
28
  //# sourceMappingURL=prompts-loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts-loader.js","sourceRoot":"","sources":["../../src/helper/prompts-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,wBAAwB,EAAC,MAAM,cAAc,CAAC;AACtD,OAAO,EAAC,QAAQ,EAAC,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAC,aAAa,EAAC,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,cAAc,MAAM,iBAAiB,CAAC,OAAM,IAAI,EAAE,MAAM,EAAC,CAAC;AACjE,MAAM,YAAY,GAAG,wBAAwB,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/D,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAC,GAA0B,EAAE;IACxE,MAAM,8BAA8B,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;IACpE,IAAI,EAAE,CAAC,UAAU,CAAC,8BAA8B,CAAC,EAAE,CAAC;QAClD,OAAO,QAAQ,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAgB,EAAE,EAAE;IAClD,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;IACzC,MAAM,YAAY,GAAmB,EAAE,CAAC;IACxC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,YAAY,GAAG,IAAI,IAAI,aAAa,CAAC,CAAC,CAAE,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAsB,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3G,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,SAAS;QACX,CAAC;QACD,YAAY,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,CAAC,OAAO,EAAC,CAAC,CAAC;QACtE,KAAK,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC","sourcesContent":["import {createResolverByRootFile} from \"@gaubee/node\";\nimport {readJson} from \"@gaubee/nodekit\";\nimport {func_remember} from \"@gaubee/util\";\nimport type {ModelMessage} from \"ai\";\nimport fs from \"node:fs\";\nimport defaultPrompts from \"../prompts.json\" with {type: \"json\"};\nconst rootResolver = createResolverByRootFile(import.meta.url);\n\nexport const getPromptConfigs = func_remember((): typeof defaultPrompts => {\n const download_prompts_json_filepath = rootResolver(\"prompts.json\");\n if (fs.existsSync(download_prompts_json_filepath)) {\n return readJson(download_prompts_json_filepath);\n }\n return defaultPrompts;\n});\ntype PromptConfigs = typeof defaultPrompts;\ntype PromptItemConfig = PromptConfigs[keyof PromptConfigs];\n\nexport const getModelMessage = (agents: string[]) => {\n const promptConfigs = getPromptConfigs();\n const modelMessage: ModelMessage[] = [];\n const names = agents.slice();\n for (const name of names) {\n const promptConfig = name in promptConfigs ? (Reflect.get(promptConfigs, name) as PromptItemConfig) : null;\n if (!promptConfig) {\n continue;\n }\n modelMessage.unshift({role: \"system\", content: promptConfig.content});\n names.push(...promptConfig.data.parent);\n }\n\n return modelMessage;\n};\n"]}
1
+ {"version":3,"file":"prompts-loader.js","sourceRoot":"","sources":["../../src/helper/prompts-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,wBAAwB,EAAC,MAAM,cAAc,CAAC;AACtD,OAAO,EAAC,QAAQ,EAAC,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAC,aAAa,EAAE,SAAS,EAAC,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,cAAc,MAAM,iBAAiB,CAAC,OAAM,IAAI,EAAE,MAAM,EAAC,CAAC;AACjE,MAAM,YAAY,GAAG,wBAAwB,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/D,MAAM,CAAC,MAAM,mBAAmB,GAAG,aAAa,CAAC,GAA0B,EAAE;IAC3E,MAAM,8BAA8B,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;IACpE,IAAI,EAAE,CAAC,UAAU,CAAC,8BAA8B,CAAC,EAAE,CAAC;QAClD,OAAO,QAAQ,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC,CAAC,CAAC;AAIH;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC,GAAG,EAAE;IAC/C,MAAM,OAAO,GAAG,mBAAmB,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1E,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAC/B,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QACd,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC,EACD,MAAM,CAAC,MAAM,CAAC,IAAI,CAA2B,CAC9C,CAAC;IACF,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC,CAAC","sourcesContent":["import {createResolverByRootFile} from \"@gaubee/node\";\nimport {readJson} from \"@gaubee/nodekit\";\nimport {func_remember, obj_props} from \"@gaubee/util\";\nimport fs from \"node:fs\";\nimport defaultPrompts from \"../prompts.json\" with {type: \"json\"};\nconst rootResolver = createResolverByRootFile(import.meta.url);\n\nexport const getAllPromptConfigs = func_remember((): typeof defaultPrompts => {\n const download_prompts_json_filepath = rootResolver(\"prompts.json\");\n if (fs.existsSync(download_prompts_json_filepath)) {\n return readJson(download_prompts_json_filepath);\n }\n return defaultPrompts;\n});\nexport type PromptConfigs = typeof defaultPrompts;\nexport type PromptItemConfig = PromptConfigs[keyof PromptConfigs];\n\n/**\n * 所有的技能信息\n * key: skill-name\n * value: skill-description\n */\nexport const getAllSkillMap = func_remember(() => {\n const configs = getAllPromptConfigs();\n const skills = obj_props(configs).filter((key) => key.endsWith(\".skill\"));\n const allSkillMap = 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 allSkillMap;\n});\n"]}
@@ -10,19 +10,32 @@ export declare const resolveAiTasks: (cwd: string, config_tasks: JixoConfig["tas
10
10
  [key: string]: any;
11
11
  };
12
12
  content: string;
13
- } & {
13
+ } & Readonly<{
14
14
  name: string;
15
+ filepath: string;
16
+ exited: boolean;
17
+ exitReason: string;
18
+ exit: (reason: string) => void;
15
19
  cwd: string;
16
20
  dirs: string[];
17
21
  agents: string[];
18
22
  model: string;
19
- useMemory: string;
20
- useLog: string;
21
- log: string;
22
23
  startTime: string;
23
- createTime: string;
24
- preUpdateTime: string;
25
- preProgress: number;
26
- })[];
24
+ maxTurns: number;
25
+ executor: string;
26
+ allExecutors: string[];
27
+ log: Readonly<{
28
+ name: string;
29
+ filepath: string;
30
+ content: string;
31
+ data: {
32
+ [key: string]: any;
33
+ };
34
+ createTime: string;
35
+ preUpdateTime: string;
36
+ preProgress: number;
37
+ }>;
38
+ reloadLog: () => void;
39
+ }>)[];
27
40
  export type AiTask = ReturnType<typeof resolveAiTasks>[number];
28
41
  //# sourceMappingURL=resolve-ai-tasks.d.ts.map
@@ -1 +1 @@
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;AAG7C;;;;;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;gBACL,MAAM;mBACH,MAAM;iBACR,MAAM;IA+HtB,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;AAG7C;;;;;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;;UAIP,MAAM;cACF,MAAM;YACR,OAAO;gBACH,MAAM;UACZ,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI;SAEzB,MAAM;UACL,MAAM,EAAE;YACN,MAAM,EAAE;WACT,MAAM;eACF,MAAM;cACP,MAAM;cACN,MAAM;kBACF,MAAM,EAAE;SAEjB,QAAQ,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE;YAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;SAAC,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;eACS,MAAM,IAAI;KAyK1B,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -27,12 +27,26 @@ export const resolveAiTasks = (cwd, config_tasks) => {
27
27
  task_dir.push(cwd);
28
28
  }
29
29
  const task_name = inner_task_name || options.defaultName;
30
- const useMemory = ai_task.data.useMemory || task_name;
31
30
  const useLog = ai_task.data.useLog || task_name;
32
- const log_filepath = path.join(cwd, `.jixo/${useLog}.log.md`);
33
- let log_fileContent = fs.existsSync(log_filepath) ? fs.readFileSync(log_filepath, "utf-8").trim() : "";
34
- if (log_fileContent === "") {
35
- writeMarkdown(log_filepath, str_trim_indent(`
31
+ const log = {
32
+ name: useLog,
33
+ filepath: path.join(cwd, `.jixo/${useLog}.log.md`),
34
+ content: "",
35
+ data: {},
36
+ get createTime() {
37
+ return log.data.createTime ?? startTime;
38
+ },
39
+ get preUpdateTime() {
40
+ return log.data.updateTime ?? startTime;
41
+ },
42
+ get preProgress() {
43
+ return parseProgress(log.data.progress);
44
+ },
45
+ };
46
+ const reloadLog = () => {
47
+ log.content = fs.existsSync(log.filepath) ? fs.readFileSync(log.filepath, "utf-8").trim() : "";
48
+ if (log.content === "") {
49
+ writeMarkdown(log.filepath, str_trim_indent(`
36
50
  ## 工作计划
37
51
 
38
52
  <!--待定-->
@@ -43,18 +57,33 @@ export const resolveAiTasks = (cwd, config_tasks) => {
43
57
 
44
58
  <!--暂无-->
45
59
  `), {
46
- title: "_待定_",
47
- createTime: new Date().toISOString(),
48
- updateTime: new Date().toISOString(),
49
- progress: "0%",
50
- });
51
- log_fileContent = fs.readFileSync(log_filepath, "utf-8");
52
- }
53
- const log_fileData = matter(log_fileContent).data;
60
+ title: "_待定_",
61
+ createTime: new Date().toISOString(),
62
+ updateTime: new Date().toISOString(),
63
+ progress: "0%",
64
+ });
65
+ log.content = fs.readFileSync(log.filepath, "utf-8");
66
+ }
67
+ log.data = matter(log.content).data;
68
+ };
69
+ reloadLog();
54
70
  const startTime = new Date().toISOString();
71
+ const executor = `${task_name}-${crypto.randomUUID()}`;
72
+ const task_process = {
73
+ exited: false,
74
+ reason: "",
75
+ exit(reason) {
76
+ if (task_process.exited) {
77
+ return;
78
+ }
79
+ task_process.exited = true;
80
+ task_process.reason = reason;
81
+ },
82
+ };
55
83
  tasks.push({
56
84
  ...ai_task,
57
85
  name: task_name,
86
+ filepath: options.filepath ?? path.join(cwd, `.jixo/${task_name}.task.md`),
58
87
  cwd: cwd,
59
88
  dirs: task_dir,
60
89
  agents: match(z.union([z.string(), z.string().array()]).safeParse(ai_task.data.agents))
@@ -62,16 +91,24 @@ export const resolveAiTasks = (cwd, config_tasks) => {
62
91
  return Array.isArray(agents) ? agents : agents.split(/\s+/);
63
92
  })
64
93
  .otherwise(() => []),
94
+ maxTurns: 40,
95
+ executor: executor,
96
+ allExecutors: [executor],
65
97
  model: match(z.string().safeParse(ai_task.data.model))
66
98
  .with({ success: true, data: P.select() }, (model) => model)
67
99
  .otherwise(() => ""),
68
- useMemory,
69
- useLog,
70
- createTime: log_fileData.createTime ?? startTime,
71
- preUpdateTime: log_fileData.updateTime ?? startTime,
72
- preProgress: parseProgress(log_fileData.progress),
73
- log: log_fileContent,
74
100
  startTime: startTime,
101
+ reloadLog: reloadLog,
102
+ log: log,
103
+ get exited() {
104
+ return task_process.exited;
105
+ },
106
+ get exitReason() {
107
+ return task_process.reason;
108
+ },
109
+ exit(reason) {
110
+ task_process.exit(reason);
111
+ },
75
112
  });
76
113
  };
77
114
  for (const config_task of config_tasks_arr) {
@@ -86,6 +123,7 @@ export const resolveAiTasks = (cwd, config_tasks) => {
86
123
  },
87
124
  })) {
88
125
  addTask(readMarkdown(entry.path), {
126
+ filepath: entry.path,
89
127
  defaultName: entry.name.slice(0, -".task.md".length),
90
128
  });
91
129
  }
@@ -96,6 +134,7 @@ export const resolveAiTasks = (cwd, config_tasks) => {
96
134
  name: P.string.select("name").optional(),
97
135
  }, (m) => {
98
136
  addTask(readMarkdown(m.filename), {
137
+ filepath: m.filename,
99
138
  defaultName: m.name ?? m.filename.slice(0, -".task.md".length),
100
139
  });
101
140
  })
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-ai-tasks.js","sourceRoot":"","sources":["../../src/helper/resolve-ai-tasks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAClG,OAAO,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAC,KAAK,EAAE,CAAC,EAAC,MAAM,YAAY,CAAC;AACpC,OAAO,CAAC,MAAM,KAAK,CAAC;AACpB,OAAO,EAAiB,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAElD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,YAAiC,EAAE,EAAE;IAC/E,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IAmBrF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,CACd,OAAiB,EACjB,OAEC,EACD,EAAE;QACF,MAAM,EAAC,IAAI,EAAE,eAAe,EAAC,GAAG,OAAO,CAAC,IAAI,CAAC;QAE7C,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;aAC/G,IAAI,CAAC,EAAC,OAAO,EAAE,IAAI,EAAC,EAAE,CAAC,EAAE,EAAE,EAAE;YAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;YAC7D,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACzE,CAAC,CAAC;aACD,SAAS,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACvB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QAED,MAAM,SAAS,GAAG,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC;QACzD,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC;QACtD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC;QAEhD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,MAAM,SAAS,CAAC,CAAC;QAC9D,IAAI,eAAe,GAAG,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvG,IAAI,eAAe,KAAK,EAAE,EAAE,CAAC;YAC3B,aAAa,CACX,YAAY,EACZ,eAAe,CAAC;;;;;;;;;;SAUf,CAAC,EACF;gBACE,KAAK,EAAE,MAAM;gBACb,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,QAAQ,EAAE,IAAI;aACf,CACF,CAAC;YACF,eAAe,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC3D,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC;QAClD,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAE3C,KAAK,CAAC,IAAI,CAAC;YACT,GAAG,OAAO;YACV,IAAI,EAAE,SAAS;YACf,GAAG,EAAE,GAAG;YACR,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;iBACpF,IAAI,CAAC,EAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAC,EAAE,CAAC,MAAM,EAAE,EAAE;gBAClD,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC9D,CAAC,CAAC;iBACD,SAAS,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;YACtB,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;iBACnD,IAAI,CAAC,EAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC;iBACzD,SAAS,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;YACtB,SAAS;YACT,MAAM;YACN,UAAU,EAAE,YAAY,CAAC,UAAU,IAAI,SAAS;YAChD,aAAa,EAAE,YAAY,CAAC,UAAU,IAAI,SAAS;YACnD,WAAW,EAAE,aAAa,CAAC,YAAY,CAAC,QAAQ,CAAC;YACjD,GAAG,EAAE,eAAe;YACpB,SAAS,EAAE,SAAS;SACrB,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,KAAK,MAAM,WAAW,IAAI,gBAAgB,EAAE,CAAC;QAC3C,KAAK,CAAC,WAAW,CAAC;aACf,IAAI,CACH;YACE,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE;SAC3B,EACD,CAAC,OAAO,EAAE,EAAE;YACV,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE;gBACxD,SAAS,CAAC,KAAK;oBACb,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;gBACzC,CAAC;aACF,CAAC,EAAE,CAAC;gBACH,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;oBAChC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;iBACrD,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CACF;aACA,IAAI,CACH;YACE,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;YACrC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;SACzC,EACD,CAAC,CAAC,EAAE,EAAE;YACJ,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE;gBAChC,WAAW,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;aAC/D,CAAC,CAAC;QACL,CAAC,CACF;aACA,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE;YACrC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;gBACzB,WAAW,EAAE,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;aACnC,CAAC,CAAC;QACL,CAAC,CAAC;aACD,IAAI,CACH;YACE,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;YACnC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;SACzC,EACD,CAAC,CAAC,EAAE,EAAE;YACJ,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE;gBACzB,WAAW,EAAE,CAAC,CAAC,IAAI,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;aAC7C,CAAC,CAAC;QACL,CAAC,CACF;aACA,UAAU,EAAE,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC","sourcesContent":["import {matter, normalizeFilePath, readMarkdown, walkFiles, writeMarkdown} from \"@gaubee/nodekit\";\nimport {str_trim_indent} from \"@gaubee/util\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport {match, P} from \"ts-pattern\";\nimport z from \"zod\";\nimport {type JixoConfig} from \"../config.js\";\nimport {parseProgress} from \"./parse-progress.js\";\n\n/**\n * 将 config.tasks 字段转化成具体的 ai-tasks 信息\n * @param cwd\n * @param config_tasks\n * @returns\n */\nexport const resolveAiTasks = (cwd: string, config_tasks: JixoConfig[\"tasks\"]) => {\n const config_tasks_arr = Array.isArray(config_tasks) ? config_tasks : [config_tasks];\n type TaskBase = {\n data: {[key: string]: any};\n content: string;\n };\n type AiTask = TaskBase & {\n name: string;\n cwd: string;\n dirs: string[];\n agents: string[];\n model: string;\n useMemory: string;\n useLog: string;\n log: string;\n startTime: string;\n createTime: string;\n preUpdateTime: string;\n preProgress: number;\n };\n const tasks: AiTask[] = [];\n const addTask = (\n ai_task: TaskBase,\n options: {\n defaultName: string;\n },\n ) => {\n const {name: inner_task_name} = ai_task.data;\n\n const task_dir = match(z.union([z.string(), z.string().array()]).safeParse(ai_task.data.dirs ?? ai_task.data.dir))\n .with({success: true}, (it) => {\n const dirList = Array.isArray(it.data) ? it.data : [it.data];\n return dirList.map((dir) => normalizeFilePath(path.resolve(cwd, dir)));\n })\n .otherwise(() => []);\n if (task_dir.length === 0) {\n task_dir.push(cwd);\n }\n\n const task_name = inner_task_name || options.defaultName;\n const useMemory = ai_task.data.useMemory || task_name;\n const useLog = ai_task.data.useLog || task_name;\n\n const log_filepath = path.join(cwd, `.jixo/${useLog}.log.md`);\n let log_fileContent = fs.existsSync(log_filepath) ? fs.readFileSync(log_filepath, \"utf-8\").trim() : \"\";\n if (log_fileContent === \"\") {\n writeMarkdown(\n log_filepath,\n str_trim_indent(`\n ## 工作计划\n \n <!--待定-->\n\n ---\n\n ## 工作日志\n\n <!--暂无-->\n `),\n {\n title: \"_待定_\",\n createTime: new Date().toISOString(),\n updateTime: new Date().toISOString(),\n progress: \"0%\",\n },\n );\n log_fileContent = fs.readFileSync(log_filepath, \"utf-8\");\n }\n const log_fileData = matter(log_fileContent).data;\n const startTime = new Date().toISOString();\n\n tasks.push({\n ...ai_task,\n name: task_name,\n cwd: cwd,\n dirs: task_dir,\n agents: match(z.union([z.string(), z.string().array()]).safeParse(ai_task.data.agents))\n .with({success: true, data: P.select()}, (agents) => {\n return Array.isArray(agents) ? agents : agents.split(/\\s+/);\n })\n .otherwise(() => []),\n model: match(z.string().safeParse(ai_task.data.model))\n .with({success: true, data: P.select()}, (model) => model)\n .otherwise(() => \"\"),\n useMemory,\n useLog,\n createTime: log_fileData.createTime ?? startTime,\n preUpdateTime: log_fileData.updateTime ?? startTime,\n preProgress: parseProgress(log_fileData.progress),\n log: log_fileContent,\n startTime: startTime,\n });\n };\n\n for (const config_task of config_tasks_arr) {\n match(config_task)\n .with(\n {\n type: \"dir\",\n dirname: P.string.select(),\n },\n (dirname) => {\n for (const entry of walkFiles(path.resolve(cwd, dirname), {\n matchFile(entry) {\n return entry.name.endsWith(\".task.md\");\n },\n })) {\n addTask(readMarkdown(entry.path), {\n defaultName: entry.name.slice(0, -\".task.md\".length),\n });\n }\n },\n )\n .with(\n {\n type: \"file\",\n filename: P.string.select(\"filename\"),\n name: P.string.select(\"name\").optional(),\n },\n (m) => {\n addTask(readMarkdown(m.filename), {\n defaultName: m.name ?? m.filename.slice(0, -\".task.md\".length),\n });\n },\n )\n .with(P.string.select(), (mdContent) => {\n addTask(matter(mdContent), {\n defaultName: `${tasks.length + 1}`,\n });\n })\n .with(\n {\n type: \"prompt\",\n content: P.string.select(\"content\"),\n name: P.string.select(\"name\").optional(),\n },\n (m) => {\n addTask(matter(m.content), {\n defaultName: m.name ?? `${tasks.length + 1}`,\n });\n },\n )\n .exhaustive();\n }\n return tasks;\n};\n\nexport type AiTask = ReturnType<typeof resolveAiTasks>[number];\n"]}
1
+ {"version":3,"file":"resolve-ai-tasks.js","sourceRoot":"","sources":["../../src/helper/resolve-ai-tasks.ts"],"names":[],"mappings":"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","sourcesContent":["import {matter, normalizeFilePath, readMarkdown, walkFiles, writeMarkdown} from \"@gaubee/nodekit\";\nimport {str_trim_indent} from \"@gaubee/util\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport {match, P} from \"ts-pattern\";\nimport z from \"zod\";\nimport {type JixoConfig} from \"../config.js\";\nimport {parseProgress} from \"./parse-progress.js\";\n\n/**\n * 将 config.tasks 字段转化成具体的 ai-tasks 信息\n * @param cwd\n * @param config_tasks\n * @returns\n */\nexport const resolveAiTasks = (cwd: string, config_tasks: JixoConfig[\"tasks\"]) => {\n const config_tasks_arr = Array.isArray(config_tasks) ? config_tasks : [config_tasks];\n type TaskBase = {\n data: {[key: string]: any};\n content: string;\n };\n type AiTask = TaskBase &\n Readonly<{\n name: string;\n filepath: string;\n exited: boolean;\n exitReason: string;\n exit: (reason: string) => void;\n\n cwd: string;\n dirs: string[];\n agents: string[];\n model: string;\n startTime: string;\n maxTurns: number;\n executor: string;\n allExecutors: string[];\n\n log: Readonly<{\n name: string;\n filepath: string;\n content: string;\n data: {[key: string]: any};\n createTime: string;\n preUpdateTime: string;\n preProgress: number;\n }>;\n reloadLog: () => void;\n }>;\n const tasks: AiTask[] = [];\n const addTask = (\n ai_task: TaskBase,\n options: {\n filepath?: string;\n defaultName: string;\n },\n ) => {\n const {name: inner_task_name} = ai_task.data;\n\n const task_dir = match(z.union([z.string(), z.string().array()]).safeParse(ai_task.data.dirs ?? ai_task.data.dir))\n .with({success: true}, (it) => {\n const dirList = Array.isArray(it.data) ? it.data : [it.data];\n return dirList.map((dir) => normalizeFilePath(path.resolve(cwd, dir)));\n })\n .otherwise(() => []);\n if (task_dir.length === 0) {\n task_dir.push(cwd);\n }\n\n const task_name = inner_task_name || options.defaultName;\n const useLog = ai_task.data.useLog || task_name;\n\n const log = {\n name: useLog,\n filepath: path.join(cwd, `.jixo/${useLog}.log.md`),\n content: \"\",\n data: {} as {[key: string]: any},\n get createTime(): string {\n return log.data.createTime ?? startTime;\n },\n get preUpdateTime(): string {\n return log.data.updateTime ?? startTime;\n },\n get preProgress(): number {\n return parseProgress(log.data.progress);\n },\n } satisfies AiTask[\"log\"];\n const reloadLog = () => {\n log.content = fs.existsSync(log.filepath) ? fs.readFileSync(log.filepath, \"utf-8\").trim() : \"\";\n if (log.content === \"\") {\n writeMarkdown(\n log.filepath,\n str_trim_indent(`\n ## 工作计划\n \n <!--待定-->\n\n ---\n\n ## 工作日志\n\n <!--暂无-->\n `),\n {\n title: \"_待定_\",\n createTime: new Date().toISOString(),\n updateTime: new Date().toISOString(),\n progress: \"0%\",\n },\n );\n log.content = fs.readFileSync(log.filepath, \"utf-8\");\n }\n log.data = matter(log.content).data;\n };\n reloadLog();\n const startTime = new Date().toISOString();\n const executor = `${task_name}-${crypto.randomUUID()}`;\n\n const task_process = {\n exited: false,\n reason: \"\",\n exit(reason: string) {\n if (task_process.exited) {\n return;\n }\n task_process.exited = true;\n task_process.reason = reason;\n },\n };\n\n tasks.push({\n ...ai_task,\n name: task_name,\n filepath: options.filepath ?? path.join(cwd, `.jixo/${task_name}.task.md`),\n cwd: cwd,\n dirs: task_dir,\n agents: match(z.union([z.string(), z.string().array()]).safeParse(ai_task.data.agents))\n .with({success: true, data: P.select()}, (agents) => {\n return Array.isArray(agents) ? agents : agents.split(/\\s+/);\n })\n .otherwise(() => []),\n maxTurns: 40,\n executor: executor,\n allExecutors: [executor],\n model: match(z.string().safeParse(ai_task.data.model))\n .with({success: true, data: P.select()}, (model) => model)\n .otherwise(() => \"\"),\n startTime: startTime,\n reloadLog: reloadLog,\n log: log,\n\n get exited() {\n return task_process.exited;\n },\n get exitReason() {\n return task_process.reason;\n },\n exit(reason) {\n task_process.exit(reason);\n },\n });\n };\n\n for (const config_task of config_tasks_arr) {\n match(config_task)\n .with(\n {\n type: \"dir\",\n dirname: P.string.select(),\n },\n (dirname) => {\n for (const entry of walkFiles(path.resolve(cwd, dirname), {\n matchFile(entry) {\n return entry.name.endsWith(\".task.md\");\n },\n })) {\n addTask(readMarkdown(entry.path), {\n filepath: entry.path,\n defaultName: entry.name.slice(0, -\".task.md\".length),\n });\n }\n },\n )\n .with(\n {\n type: \"file\",\n filename: P.string.select(\"filename\"),\n name: P.string.select(\"name\").optional(),\n },\n (m) => {\n addTask(readMarkdown(m.filename), {\n filepath: m.filename,\n defaultName: m.name ?? m.filename.slice(0, -\".task.md\".length),\n });\n },\n )\n .with(P.string.select(), (mdContent) => {\n addTask(matter(mdContent), {\n defaultName: `${tasks.length + 1}`,\n });\n })\n .with(\n {\n type: \"prompt\",\n content: P.string.select(\"content\"),\n name: P.string.select(\"name\").optional(),\n },\n (m) => {\n addTask(matter(m.content), {\n defaultName: m.name ?? `${tasks.length + 1}`,\n });\n },\n )\n .exhaustive();\n }\n return tasks;\n};\n\nexport type AiTask = ReturnType<typeof resolveAiTasks>[number];\n"]}