@jixo/cli 0.10.1 → 0.12.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 (54) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +6 -5
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/init.d.ts.map +1 -1
  5. package/dist/commands/init.js +18 -12
  6. package/dist/commands/init.js.map +1 -1
  7. package/dist/commands/prompts/list.js +2 -2
  8. package/dist/commands/prompts/list.js.map +1 -1
  9. package/dist/commands/tasks/AiTaskTui.d.ts +22 -0
  10. package/dist/commands/tasks/AiTaskTui.d.ts.map +1 -0
  11. package/dist/commands/tasks/AiTaskTui.js +52 -0
  12. package/dist/commands/tasks/AiTaskTui.js.map +1 -0
  13. package/dist/commands/tasks/ai-tasl-tui.d.ts +22 -0
  14. package/dist/commands/tasks/ai-tasl-tui.d.ts.map +1 -0
  15. package/dist/commands/tasks/ai-tasl-tui.js +53 -0
  16. package/dist/commands/tasks/ai-tasl-tui.js.map +1 -0
  17. package/dist/commands/tasks/ai-tools.d.ts +281 -8
  18. package/dist/commands/tasks/ai-tools.d.ts.map +1 -1
  19. package/dist/commands/tasks/ai-tools.js +55 -16
  20. package/dist/commands/tasks/ai-tools.js.map +1 -1
  21. package/dist/commands/tasks/model-providers.d.ts +5 -1
  22. package/dist/commands/tasks/model-providers.d.ts.map +1 -1
  23. package/dist/commands/tasks/model-providers.js +31 -0
  24. package/dist/commands/tasks/model-providers.js.map +1 -1
  25. package/dist/commands/tasks/run-ai-task.d.ts +1 -1
  26. package/dist/commands/tasks/run-ai-task.d.ts.map +1 -1
  27. package/dist/commands/tasks/run-ai-task.js +141 -115
  28. package/dist/commands/tasks/run-ai-task.js.map +1 -1
  29. package/dist/commands/tasks/run.d.ts.map +1 -1
  30. package/dist/commands/tasks/run.js +24 -14
  31. package/dist/commands/tasks/run.js.map +1 -1
  32. package/dist/config.d.ts +14 -14
  33. package/dist/helper/ai-retry-error.d.ts +1 -1
  34. package/dist/helper/ai-retry-error.d.ts.map +1 -1
  35. package/dist/helper/ai-retry-error.js +63 -30
  36. package/dist/helper/ai-retry-error.js.map +1 -1
  37. package/dist/helper/handle-ai-error.d.ts +5 -0
  38. package/dist/helper/handle-ai-error.d.ts.map +1 -0
  39. package/dist/helper/handle-ai-error.js +122 -0
  40. package/dist/helper/handle-ai-error.js.map +1 -0
  41. package/dist/helper/logger.d.ts +3 -0
  42. package/dist/helper/logger.d.ts.map +1 -0
  43. package/dist/helper/logger.js +26 -0
  44. package/dist/helper/logger.js.map +1 -0
  45. package/dist/helper/prompts-loader.d.ts +9 -3
  46. package/dist/helper/prompts-loader.d.ts.map +1 -1
  47. package/dist/helper/prompts-loader.js +16 -16
  48. package/dist/helper/prompts-loader.js.map +1 -1
  49. package/dist/helper/resolve-ai-tasks.d.ts +24 -10
  50. package/dist/helper/resolve-ai-tasks.d.ts.map +1 -1
  51. package/dist/helper/resolve-ai-tasks.js +68 -26
  52. package/dist/helper/resolve-ai-tasks.js.map +1 -1
  53. package/dist/prompts.json +2 -2
  54. package/package.json +8 -3
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/commands/tasks/run.ts"],"names":[],"mappings":"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","sourcesContent":["import {FileEntry, findChangedFilesSinceTime, Ignore, normalizeFilePath, walkFiles} from \"@gaubee/nodekit\";\nimport {iter_map_not_null} from \"@gaubee/util\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport {loadConfig} from \"../../config.js\";\nimport {loadJixoEnv} from \"../../env.js\";\nimport {resolveAiTasks} from \"../../helper/resolve-ai-tasks.js\";\nimport {runAiTask} from \"./run-ai-task.js\";\n\nexport const run = async (\n _cwd: string,\n options: {\n nameFilter: string[];\n dirFilter: string[];\n force?: boolean;\n loopTimes?: number;\n },\n) => {\n const cwd = normalizeFilePath(_cwd);\n const config = await loadConfig(cwd);\n\n let {force = false} = options;\n const {loopTimes: MAX_LOOP_TIMES = Infinity} = options;\n let currentTimes = 1;\n let retryTimes = 0;\n const MAX_RETRY_TIMES = 3;\n\n while (currentTimes <= MAX_LOOP_TIMES) {\n const ai_tasks = resolveAiTasks(cwd, config.tasks);\n const nameMatcher = options.nameFilter.length ? new Ignore(options.nameFilter, cwd) : {isMatch: () => true};\n const dirMatcher = options.dirFilter.length ? new Ignore(options.dirFilter, cwd) : {isMatch: () => true};\n const cwdIgnoreFilepath = path.join(cwd, \".gitignore\");\n const ignore = [\".git\"];\n if (fs.existsSync(cwdIgnoreFilepath)) {\n ignore.push(...fs.readFileSync(cwdIgnoreFilepath, \"utf-8\").split(\"\\n\"));\n }\n\n const allFiles = [...walkFiles(cwd, {ignore})];\n let allDone = true;\n\n try {\n for (const ai_task of ai_tasks) {\n // 如果进度已经满了,那么跳过\n if (ai_task.preProgress >= 1 && !force) {\n continue;\n }\n const {dirs: task_dirs} = ai_task;\n if (!task_dirs.some((dir) => dirMatcher.isMatch(dir))) {\n continue;\n }\n if (!nameMatcher.isMatch(ai_task.name)) {\n continue;\n }\n const isCwdTask = cwd === task_dirs[0] && task_dirs.length === 1;\n\n const changedFiles = (await findChangedFilesSinceTime(ai_task.preUpdateTime, cwd)) ?? allFiles;\n\n const task_changedFiles = isCwdTask\n ? {[cwd]: changedFiles}\n : task_dirs.reduce(\n (tree, task_dir) => {\n tree[task_dir] = iter_map_not_null(changedFiles, (file) => {\n if (file.path.startsWith(task_dirs + \"/\")) {\n return new FileEntry(file.path, {cwd: task_dir, state: file.stats});\n }\n });\n return tree;\n },\n {} as Record<string, FileEntry[]>,\n );\n\n const task_allFiles = isCwdTask ? allFiles : task_dirs.map((task_dir) => [...walkFiles(task_dir, {ignore})]).flat();\n\n loadJixoEnv(cwd);\n\n /// 只要有一个任务执行了,那么allDone就要标记成false,进入下一次循环来判断\n allDone = false;\n await runAiTask(ai_task, task_allFiles, task_changedFiles);\n }\n } catch {\n // 遇到异常,那么重试\n if (retryTimes < MAX_RETRY_TIMES) {\n retryTimes += 1;\n continue;\n } else {\n break;\n }\n }\n // force 只能生效一次,避免无限循环\n force = false;\n currentTimes += 1;\n /// 成功一次后,retry计数就重制\n retryTimes = 0;\n\n /// 如果没有任务执行了,那么退出循环\n if (allDone) {\n break;\n }\n }\n};\n"]}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/commands/tasks/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,yBAAyB,EAAE,MAAM,EAAE,iBAAiB,EAAE,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAC3G,OAAO,EAAC,iBAAiB,EAAC,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAC,UAAU,EAAC,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAC,WAAW,EAAC,MAAM,cAAc,CAAC;AACzC,OAAO,EAAC,cAAc,EAAC,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAC,SAAS,EAAC,MAAM,kBAAkB,CAAC;AAE3C,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EACtB,IAAY,EACZ,OAKC,EACD,EAAE;IACF,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;IAErC,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,EAAC,CAAC;IAC5G,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,EAAC,CAAC;IACzG,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB,IAAI,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IAErC,IAAI,EAAC,KAAK,GAAG,KAAK,EAAC,GAAG,OAAO,CAAC;IAC9B,MAAM,EAAC,SAAS,EAAE,cAAc,GAAG,QAAQ,EAAC,GAAG,OAAO,CAAC;IACvD,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,MAAM,eAAe,GAAG,CAAC,CAAC;IAC1B,OAAO,YAAY,IAAI,cAAc,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,EAAE,YAAY,GAAG,CAAC,CAAC,CAAC;QAErE,MAAM,QAAQ,GAAG,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,EAAC,MAAM,EAAC,CAAC,CAAC,CAAC;QAC/C,IAAI,OAAO,GAAG,IAAI,CAAC;QAEnB,IAAI,CAAC;YACH,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,kCAAkC;gBAClC,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,EAAE,CAAC;wBACjC,SAAS;oBACX,CAAC;gBACH,CAAC;gBACD,IAAI,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;oBACpC,SAAS;gBACX,CAAC;gBAED,MAAM,EAAC,IAAI,EAAE,SAAS,EAAC,GAAG,OAAO,CAAC;gBAClC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;oBACtD,SAAS;gBACX,CAAC;gBACD,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC1C,SAAS;gBACX,CAAC;gBACD,MAAM,SAAS,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC;gBAEjE,MAAM,YAAY,GAAG,CAAC,MAAM,yBAAyB,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,IAAI,QAAQ,CAAC;gBAEnG,MAAM,iBAAiB,GAAG,SAAS;oBACjC,CAAC,CAAC,EAAC,CAAC,GAAG,CAAC,EAAE,YAAY,EAAC;oBACvB,CAAC,CAAC,SAAS,CAAC,MAAM,CACd,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE;wBACjB,IAAI,CAAC,QAAQ,CAAC,GAAG,iBAAiB,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE;4BACxD,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,GAAG,GAAG,CAAC,EAAE,CAAC;gCAC1C,OAAO,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,EAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAC,CAAC,CAAC;4BACtE,CAAC;wBACH,CAAC,CAAC,CAAC;wBACH,OAAO,IAAI,CAAC;oBACd,CAAC,EACD,EAAiC,CAClC,CAAC;gBAEN,MAAM,aAAa,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,QAAQ,EAAE,EAAC,MAAM,EAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAEpH,WAAW,CAAC,GAAG,CAAC,CAAC;gBAEjB,6CAA6C;gBAC7C,OAAO,GAAG,KAAK,CAAC;gBAChB,MAAM,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,CAAC,CAAC;gBAEzE,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;oBAC7B,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACjB,YAAY;YACZ,IAAI,UAAU,GAAG,eAAe,EAAE,CAAC;gBACjC,UAAU,IAAI,CAAC,CAAC;gBAChB,SAAS;YACX,CAAC;iBAAM,CAAC;gBACN,MAAM;YACR,CAAC;QACH,CAAC;QACD,sBAAsB;QACtB,KAAK,GAAG,KAAK,CAAC;QACd,YAAY,IAAI,CAAC,CAAC;QAClB,oBAAoB;QACpB,UAAU,GAAG,CAAC,CAAC;QAEf,oBAAoB;QACpB,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM;QACR,CAAC;IACH,CAAC;AACH,CAAC,CAAC","sourcesContent":["import {FileEntry, findChangedFilesSinceTime, Ignore, normalizeFilePath, walkFiles} from \"@gaubee/nodekit\";\nimport {iter_map_not_null} from \"@gaubee/util\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport {loadConfig} from \"../../config.js\";\nimport {loadJixoEnv} from \"../../env.js\";\nimport {resolveAiTasks} from \"../../helper/resolve-ai-tasks.js\";\nimport {runAiTask} from \"./run-ai-task.js\";\n\nexport const run = async (\n _cwd: string,\n options: {\n nameFilter: string[];\n dirFilter: string[];\n force?: boolean;\n loopTimes?: number;\n },\n) => {\n const cwd = normalizeFilePath(_cwd);\n const config = await loadConfig(cwd);\n\n const nameMatcher = options.nameFilter.length ? new Ignore(options.nameFilter, cwd) : {isMatch: () => true};\n const dirMatcher = options.dirFilter.length ? new Ignore(options.dirFilter, cwd) : {isMatch: () => true};\n const cwdIgnoreFilepath = path.join(cwd, \".gitignore\");\n const ignore = [\".git\"];\n if (fs.existsSync(cwdIgnoreFilepath)) {\n ignore.push(...fs.readFileSync(cwdIgnoreFilepath, \"utf-8\").split(\"\\n\"));\n }\n const exitedJobs = new Set<string>();\n\n let {force = false} = options;\n const {loopTimes: MAX_LOOP_TIMES = Infinity} = options;\n let currentTimes = 1;\n let retryTimes = 0;\n const MAX_RETRY_TIMES = 3;\n while (currentTimes <= MAX_LOOP_TIMES) {\n const ai_tasks = resolveAiTasks(cwd, config.tasks, currentTimes - 1);\n\n const allFiles = [...walkFiles(cwd, {ignore})];\n let allDone = true;\n\n try {\n for (const ai_task of ai_tasks) {\n // 如果进度已经满了,并且没有任何依赖文件的变更,那么跳过这个任务\n if (!force) {\n if (ai_task.log.preProgress >= 1) {\n continue;\n }\n }\n if (exitedJobs.has(ai_task.jobName)) {\n continue;\n }\n\n const {dirs: task_dirs} = ai_task;\n if (!task_dirs.some((dir) => dirMatcher.isMatch(dir))) {\n continue;\n }\n if (!nameMatcher.isMatch(ai_task.jobName)) {\n continue;\n }\n const isCwdTask = cwd === task_dirs[0] && task_dirs.length === 1;\n\n const changedFiles = (await findChangedFilesSinceTime(ai_task.log.preUpdateTime, cwd)) ?? allFiles;\n\n const task_changedFiles = isCwdTask\n ? {[cwd]: changedFiles}\n : task_dirs.reduce(\n (tree, task_dir) => {\n tree[task_dir] = iter_map_not_null(changedFiles, (file) => {\n if (file.path.startsWith(task_dirs + \"/\")) {\n return new FileEntry(file.path, {cwd: task_dir, state: file.stats});\n }\n });\n return tree;\n },\n {} as Record<string, FileEntry[]>,\n );\n\n const task_allFiles = isCwdTask ? allFiles : task_dirs.map((task_dir) => [...walkFiles(task_dir, {ignore})]).flat();\n\n loadJixoEnv(cwd);\n\n /// 只要有一个任务执行了,那么allDone就要标记成false,进入下一次循环来判断\n allDone = false;\n await runAiTask(ai_task, currentTimes, task_allFiles, task_changedFiles);\n\n if (ai_task.exitCode != null) {\n exitedJobs.add(ai_task.jobName);\n }\n }\n } catch (e) {\n console.error(e);\n // 遇到异常,那么重试\n if (retryTimes < MAX_RETRY_TIMES) {\n retryTimes += 1;\n continue;\n } else {\n break;\n }\n }\n // force 只能生效一次,避免无限循环\n force = false;\n currentTimes += 1;\n /// 成功一次后,retry计数就重制\n retryTimes = 0;\n\n /// 如果没有任务执行了,那么退出循环\n if (allDone) {\n break;\n }\n }\n};\n"]}
package/dist/config.d.ts CHANGED
@@ -4,12 +4,12 @@ declare const zJixoTask: z.ZodUnion<[z.ZodString, z.ZodObject<{
4
4
  name: z.ZodOptional<z.ZodString>;
5
5
  filename: z.ZodString;
6
6
  }, "strip", z.ZodTypeAny, {
7
- filename: string;
8
7
  type: "file";
8
+ filename: string;
9
9
  name?: string | undefined;
10
10
  }, {
11
- filename: string;
12
11
  type: "file";
12
+ filename: string;
13
13
  name?: string | undefined;
14
14
  }>, z.ZodObject<{
15
15
  type: z.ZodLiteral<"dir">;
@@ -39,12 +39,12 @@ declare const zJixoConfig: z.ZodObject<{
39
39
  name: z.ZodOptional<z.ZodString>;
40
40
  filename: z.ZodString;
41
41
  }, "strip", z.ZodTypeAny, {
42
- filename: string;
43
42
  type: "file";
43
+ filename: string;
44
44
  name?: string | undefined;
45
45
  }, {
46
- filename: string;
47
46
  type: "file";
47
+ filename: string;
48
48
  name?: string | undefined;
49
49
  }>, z.ZodObject<{
50
50
  type: z.ZodLiteral<"dir">;
@@ -72,12 +72,12 @@ declare const zJixoConfig: z.ZodObject<{
72
72
  name: z.ZodOptional<z.ZodString>;
73
73
  filename: z.ZodString;
74
74
  }, "strip", z.ZodTypeAny, {
75
- filename: string;
76
75
  type: "file";
76
+ filename: string;
77
77
  name?: string | undefined;
78
78
  }, {
79
- filename: string;
80
79
  type: "file";
80
+ filename: string;
81
81
  name?: string | undefined;
82
82
  }>, z.ZodObject<{
83
83
  type: z.ZodLiteral<"dir">;
@@ -103,8 +103,8 @@ declare const zJixoConfig: z.ZodObject<{
103
103
  }>]>]>;
104
104
  }, "strip", z.ZodTypeAny, {
105
105
  tasks: string | {
106
- filename: string;
107
106
  type: "file";
107
+ filename: string;
108
108
  name?: string | undefined;
109
109
  } | {
110
110
  type: "dir";
@@ -114,8 +114,8 @@ declare const zJixoConfig: z.ZodObject<{
114
114
  content: string;
115
115
  name?: string | undefined;
116
116
  } | (string | {
117
- filename: string;
118
117
  type: "file";
118
+ filename: string;
119
119
  name?: string | undefined;
120
120
  } | {
121
121
  type: "dir";
@@ -127,8 +127,8 @@ declare const zJixoConfig: z.ZodObject<{
127
127
  })[];
128
128
  }, {
129
129
  tasks: string | {
130
- filename: string;
131
130
  type: "file";
131
+ filename: string;
132
132
  name?: string | undefined;
133
133
  } | {
134
134
  type: "dir";
@@ -138,8 +138,8 @@ declare const zJixoConfig: z.ZodObject<{
138
138
  content: string;
139
139
  name?: string | undefined;
140
140
  } | (string | {
141
- filename: string;
142
141
  type: "file";
142
+ filename: string;
143
143
  name?: string | undefined;
144
144
  } | {
145
145
  type: "dir";
@@ -154,8 +154,8 @@ export type JixoTask = z.output<typeof zJixoTask>;
154
154
  export type JixoConfig = z.output<typeof zJixoConfig>;
155
155
  export declare const defineConfig: (config: Partial<JixoConfig>) => {
156
156
  tasks: string | {
157
- filename: string;
158
157
  type: "file";
158
+ filename: string;
159
159
  name?: string | undefined;
160
160
  } | {
161
161
  type: "dir";
@@ -165,8 +165,8 @@ export declare const defineConfig: (config: Partial<JixoConfig>) => {
165
165
  content: string;
166
166
  name?: string | undefined;
167
167
  } | (string | {
168
- filename: string;
169
168
  type: "file";
169
+ filename: string;
170
170
  name?: string | undefined;
171
171
  } | {
172
172
  type: "dir";
@@ -179,8 +179,8 @@ export declare const defineConfig: (config: Partial<JixoConfig>) => {
179
179
  };
180
180
  export declare const loadConfig: (dir: string) => Promise<{
181
181
  tasks: string | {
182
- filename: string;
183
182
  type: "file";
183
+ filename: string;
184
184
  name?: string | undefined;
185
185
  } | {
186
186
  type: "dir";
@@ -190,8 +190,8 @@ export declare const loadConfig: (dir: string) => Promise<{
190
190
  content: string;
191
191
  name?: string | undefined;
192
192
  } | (string | {
193
- filename: string;
194
193
  type: "file";
194
+ filename: string;
195
195
  name?: string | undefined;
196
196
  } | {
197
197
  type: "dir";
@@ -1,3 +1,3 @@
1
1
  import { type Spinner } from "@gaubee/nodekit";
2
- export declare const handleRetryError: (error: unknown, loading: Spinner) => Promise<void>;
2
+ export declare const handleRetryError: (error: unknown, loading: Pick<Spinner, "prefixText" | "text">) => Promise<void>;
3
3
  //# sourceMappingURL=ai-retry-error.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai-retry-error.d.ts","sourceRoot":"","sources":["../../src/helper/ai-retry-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAK3D,eAAO,MAAM,gBAAgB,GAAU,OAAO,OAAO,EAAE,SAAS,OAAO,kBA6CtE,CAAC"}
1
+ {"version":3,"file":"ai-retry-error.d.ts","sourceRoot":"","sources":["../../src/helper/ai-retry-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAMhE,eAAO,MAAM,gBAAgB,GAAU,OAAO,OAAO,EAAE,SAAS,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAAC,kBA0CnG,CAAC"}
@@ -1,7 +1,8 @@
1
- import { gray, yellow } from "@gaubee/nodekit";
2
- import { delay, str_trim_indent } from "@gaubee/util";
1
+ import { gray, red, yellow } from "@gaubee/nodekit";
2
+ import { delay } from "@gaubee/util";
3
3
  import { APICallError, RetryError } from "ai";
4
4
  import ms from "ms";
5
+ import { match } from "ts-pattern";
5
6
  import z from "zod";
6
7
  export const handleRetryError = async (error, loading) => {
7
8
  if (!RetryError.isInstance(error)) {
@@ -11,42 +12,52 @@ export const handleRetryError = async (error, loading) => {
11
12
  if (!APICallError.isInstance(inner_error)) {
12
13
  continue;
13
14
  }
14
- if (!inner_error.isRetryable) {
15
- continue;
16
- }
17
15
  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
- ${yellow(inner_error.message)}
30
- ${" " + gray("─".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;
16
+ if (!inner_error.isRetryable) {
17
+ const safeData = geminiErrorSchema.safeParse(inner_error.data);
18
+ if (!safeData.success) {
19
+ throw safeData.error;
20
+ }
21
+ const retryDetail = safeData.data.error.details.find((d) => "retryDelay" in d);
22
+ if (retryDetail) {
23
+ const retryDelay = ms(retryDetail.retryDelay);
24
+ if (typeof retryDelay === "number") {
25
+ await waitRetryDelay(loading, retryDelay, yellow(inner_error.message));
26
+ }
27
+ }
28
+ }
29
+ else {
30
+ const safeData = commonErrorSchema.safeParse(inner_error.data);
31
+ if (!safeData.success) {
32
+ throw safeData.error;
41
33
  }
34
+ console.log("QAQ response.error", safeData);
35
+ await match(safeData.data.error)
36
+ /// 余额不足
37
+ .with({ message: "Insufficient Balance" }, async () => {
38
+ /// 30s重试
39
+ await waitRetryDelay(loading, 1000 * 30, red("Insufficient Balance") + "\n" + red(inner_error.url));
40
+ })
41
+ .otherwise(() => {
42
+ throw inner_error;
43
+ });
42
44
  }
43
45
  }
44
46
  catch {
45
- console.error("\nQAQ unknown error", error);
47
+ console.error("\nQAQ unknown error", inner_error);
46
48
  }
47
49
  }
48
50
  };
49
- const errorSchema = z.object({
51
+ // const handleError
52
+ const commonErrorSchema = z.object({
53
+ error: z.object({
54
+ message: z.string(),
55
+ type: z.string(),
56
+ param: z.any(),
57
+ code: z.string(),
58
+ }),
59
+ });
60
+ const geminiErrorSchema = z.object({
50
61
  error: z.object({
51
62
  code: z.number(),
52
63
  message: z.string(),
@@ -72,4 +83,26 @@ const errorSchema = z.object({
72
83
  ])),
73
84
  }),
74
85
  });
86
+ const waitRetryDelay = async (loading, retryDelay, message) => {
87
+ const { prefixText, text } = loading;
88
+ let remainingDelay = retryDelay;
89
+ const tickInterval = 1000;
90
+ const tick = () => {
91
+ loading.prefixText = "⏲️ ";
92
+ loading.text = [
93
+ //
94
+ message,
95
+ " " + gray("─".repeat(Math.max(4, process.stdout.columns - 2))),
96
+ `Retrying in ${ms(remainingDelay)}...`,
97
+ ].join("\n");
98
+ remainingDelay -= tickInterval;
99
+ };
100
+ tick();
101
+ const ti = setInterval(tick, tickInterval);
102
+ await delay(retryDelay);
103
+ clearInterval(ti);
104
+ // 回滚
105
+ loading.prefixText = prefixText;
106
+ loading.text = text;
107
+ };
75
108
  //# sourceMappingURL=ai-retry-error.js.map
@@ -1 +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 {gray, yellow, type 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\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 ${yellow(inner_error.message)}\r\n ${\" \" + gray(\"─\".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
+ {"version":3,"file":"ai-retry-error.js","sourceRoot":"","sources":["../../src/helper/ai-retry-error.ts"],"names":[],"mappings":"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","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\nexport const handleRetryError = async (error: unknown, loading: Pick<Spinner, \"prefixText\" | \"text\">) => {\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 try {\r\n if (!inner_error.isRetryable) {\r\n const safeData = geminiErrorSchema.safeParse(inner_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, yellow(inner_error.message));\r\n }\r\n }\r\n } else {\r\n const safeData = commonErrorSchema.safeParse(inner_error.data);\r\n if (!safeData.success) {\r\n throw safeData.error;\r\n }\r\n console.log(\"QAQ response.error\", safeData);\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, red(\"Insufficient Balance\") + \"\\n\" + red(inner_error.url));\r\n })\r\n .otherwise(() => {\r\n throw inner_error;\r\n });\r\n }\r\n } catch {\r\n console.error(\"\\nQAQ unknown error\", inner_error);\r\n }\r\n }\r\n};\r\n\r\n// const handleError\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: Pick<Spinner, \"prefixText\" | \"text\">, 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"]}
@@ -0,0 +1,5 @@
1
+ import { type Spinner } from "@gaubee/nodekit";
2
+ type Loading = Pick<Spinner, "prefixText" | "text">;
3
+ export declare const handleError: (error: unknown, loading: Loading) => Promise<true | undefined>;
4
+ export {};
5
+ //# sourceMappingURL=handle-ai-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handle-ai-error.d.ts","sourceRoot":"","sources":["../../src/helper/handle-ai-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAMhE,KAAK,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAAC,CAAC;AAEpD,eAAO,MAAM,WAAW,GAAU,OAAO,OAAO,EAAE,SAAS,OAAO,8BAOjE,CAAC"}
@@ -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(JSON.parse(error.responseBody));
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":"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","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(JSON.parse(error.responseBody!));\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"]}
@@ -0,0 +1,3 @@
1
+ import createDebug from "debug";
2
+ export { createDebug };
3
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/helper/logger.ts"],"names":[],"mappings":"AAEA,OAAO,WAAW,MAAM,OAAO,CAAC;AAuBhC,OAAO,EAAC,WAAW,EAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { gray, red } from "@gaubee/nodekit";
2
+ import { AISDKError } from "ai";
3
+ import createDebug from "debug";
4
+ createDebug.formatters.y = (v) => {
5
+ return JSON.stringify(v, (_k, v) => {
6
+ if (typeof v === "string") {
7
+ let slice_len = 0;
8
+ if (v.length > 200) {
9
+ slice_len = 50;
10
+ }
11
+ if (v.length > 100) {
12
+ slice_len = 30;
13
+ }
14
+ if (slice_len > 0) {
15
+ return `<string:${v.length}>${v.slice(0, slice_len)}${gray("...")}${v.slice(-slice_len)}`;
16
+ }
17
+ return v;
18
+ }
19
+ if (AISDKError.isInstance(v)) {
20
+ return red(v.message);
21
+ }
22
+ return v;
23
+ });
24
+ };
25
+ export { createDebug };
26
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/helper/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,GAAG,EAAC,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAC,UAAU,EAAC,MAAM,IAAI,CAAC;AAC9B,OAAO,WAAW,MAAM,OAAO,CAAC;AAEhC,WAAW,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE;IAC/B,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;QACjC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC1B,IAAI,SAAS,GAAG,CAAC,CAAC;YAClB,IAAI,CAAC,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;gBACnB,SAAS,GAAG,EAAE,CAAC;YACjB,CAAC;YACD,IAAI,CAAC,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;gBACnB,SAAS,GAAG,EAAE,CAAC;YACjB,CAAC;YACD,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBAClB,OAAO,WAAW,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5F,CAAC;YACD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7B,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AACF,OAAO,EAAC,WAAW,EAAC,CAAC","sourcesContent":["import {gray, red} from \"@gaubee/nodekit\";\nimport {AISDKError} from \"ai\";\nimport createDebug from \"debug\";\n\ncreateDebug.formatters.y = (v) => {\n return JSON.stringify(v, (_k, v) => {\n if (typeof v === \"string\") {\n let slice_len = 0;\n if (v.length > 200) {\n slice_len = 50;\n }\n if (v.length > 100) {\n slice_len = 30;\n }\n if (slice_len > 0) {\n return `<string:${v.length}>${v.slice(0, slice_len)}${gray(\"...\")}${v.slice(-slice_len)}`;\n }\n return v;\n }\n if (AISDKError.isInstance(v)) {\n return red(v.message);\n }\n return v;\n });\n};\nexport {createDebug};\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"]}