skyloom 1.14.8 → 1.15.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 (156) hide show
  1. package/.github/workflows/ci.yml +2 -2
  2. package/.github/workflows/publish.yml +51 -4
  3. package/CONVERSION_PLAN.md +191 -191
  4. package/config/default.yaml +46 -43
  5. package/config/models.yaml +928 -155
  6. package/config/providers.yaml +109 -6
  7. package/dist/agents/snow.d.ts +2 -0
  8. package/dist/agents/snow.d.ts.map +1 -1
  9. package/dist/agents/snow.js +36 -5
  10. package/dist/agents/snow.js.map +1 -1
  11. package/dist/cli/loom_chat.d.ts.map +1 -1
  12. package/dist/cli/loom_chat.js +207 -1
  13. package/dist/cli/loom_chat.js.map +1 -1
  14. package/dist/cli/main.js +190 -40
  15. package/dist/cli/main.js.map +1 -1
  16. package/dist/cli/tui.d.ts.map +1 -1
  17. package/dist/cli/tui.js +6 -31
  18. package/dist/cli/tui.js.map +1 -1
  19. package/dist/core/agent.d.ts +6 -4
  20. package/dist/core/agent.d.ts.map +1 -1
  21. package/dist/core/agent.js +61 -20
  22. package/dist/core/agent.js.map +1 -1
  23. package/dist/core/catalog.d.ts.map +1 -1
  24. package/dist/core/catalog.js +30 -9
  25. package/dist/core/catalog.js.map +1 -1
  26. package/dist/core/commands.d.ts +110 -0
  27. package/dist/core/commands.d.ts.map +1 -0
  28. package/dist/core/commands.js +633 -0
  29. package/dist/core/commands.js.map +1 -0
  30. package/dist/core/concurrency.d.ts +38 -0
  31. package/dist/core/concurrency.d.ts.map +1 -0
  32. package/dist/core/concurrency.js +65 -0
  33. package/dist/core/concurrency.js.map +1 -0
  34. package/dist/core/factory.js +16 -16
  35. package/dist/core/file_checkpoint.d.ts +9 -0
  36. package/dist/core/file_checkpoint.d.ts.map +1 -1
  37. package/dist/core/file_checkpoint.js +33 -1
  38. package/dist/core/file_checkpoint.js.map +1 -1
  39. package/dist/core/llm.d.ts.map +1 -1
  40. package/dist/core/llm.js +66 -13
  41. package/dist/core/llm.js.map +1 -1
  42. package/dist/core/memory.js +51 -51
  43. package/dist/core/schemas.d.ts +16 -0
  44. package/dist/core/schemas.d.ts.map +1 -1
  45. package/dist/core/schemas.js +32 -0
  46. package/dist/core/schemas.js.map +1 -1
  47. package/dist/core/security.d.ts.map +1 -1
  48. package/dist/core/security.js +27 -0
  49. package/dist/core/security.js.map +1 -1
  50. package/dist/core/skymd.js +14 -14
  51. package/dist/core/trace.d.ts +105 -0
  52. package/dist/core/trace.d.ts.map +1 -0
  53. package/dist/core/trace.js +213 -0
  54. package/dist/core/trace.js.map +1 -0
  55. package/dist/tools/builtin.d.ts +2 -6
  56. package/dist/tools/builtin.d.ts.map +1 -1
  57. package/dist/tools/builtin.js +18 -111
  58. package/dist/tools/builtin.js.map +1 -1
  59. package/dist/tools/extra.d.ts +13 -0
  60. package/dist/tools/extra.d.ts.map +1 -0
  61. package/dist/tools/extra.js +827 -0
  62. package/dist/tools/extra.js.map +1 -0
  63. package/dist/tools/guards.d.ts +12 -0
  64. package/dist/tools/guards.d.ts.map +1 -0
  65. package/dist/tools/guards.js +143 -0
  66. package/dist/tools/guards.js.map +1 -0
  67. package/dist/tools/model_tool.d.ts.map +1 -1
  68. package/dist/tools/model_tool.js +24 -4
  69. package/dist/tools/model_tool.js.map +1 -1
  70. package/dist/web/markdown.d.ts +32 -0
  71. package/dist/web/markdown.d.ts.map +1 -0
  72. package/dist/web/markdown.js +202 -0
  73. package/dist/web/markdown.js.map +1 -0
  74. package/dist/web/server.d.ts +4 -0
  75. package/dist/web/server.d.ts.map +1 -1
  76. package/dist/web/server.js +14 -582
  77. package/dist/web/server.js.map +1 -1
  78. package/dist/web/ui.d.ts +31 -0
  79. package/dist/web/ui.d.ts.map +1 -0
  80. package/dist/web/ui.js +1009 -0
  81. package/dist/web/ui.js.map +1 -0
  82. package/docs/AESTHETIC_DESIGN.md +152 -152
  83. package/docs/OPTIMIZATION_PLAN.md +178 -178
  84. package/package.json +1 -1
  85. package/src/agents/snow.ts +38 -5
  86. package/src/cli/commands_md.ts +112 -112
  87. package/src/cli/input_macros.ts +83 -83
  88. package/src/cli/loom.ts +1041 -1041
  89. package/src/cli/loom_chat.ts +772 -603
  90. package/src/cli/main.ts +853 -723
  91. package/src/cli/tui.ts +264 -289
  92. package/src/core/agent/guard.ts +133 -133
  93. package/src/core/agent/task.ts +100 -100
  94. package/src/core/agent.ts +1630 -1590
  95. package/src/core/agent_helpers.ts +500 -500
  96. package/src/core/bus.ts +221 -221
  97. package/src/core/cache.ts +153 -153
  98. package/src/core/catalog.ts +199 -178
  99. package/src/core/circuit_breaker.ts +119 -119
  100. package/src/core/commands.ts +704 -0
  101. package/src/core/concurrency.ts +73 -0
  102. package/src/core/config.ts +365 -365
  103. package/src/core/constants.ts +95 -95
  104. package/src/core/factory.ts +656 -656
  105. package/src/core/file_checkpoint.ts +163 -136
  106. package/src/core/hooks.ts +126 -126
  107. package/src/core/llm.ts +972 -915
  108. package/src/core/logger.ts +143 -143
  109. package/src/core/mcp.ts +1001 -1001
  110. package/src/core/memory.ts +1201 -1201
  111. package/src/core/middleware.ts +350 -350
  112. package/src/core/model_config.ts +159 -159
  113. package/src/core/pipelines.ts +424 -424
  114. package/src/core/schemas.ts +319 -282
  115. package/src/core/security.ts +27 -0
  116. package/src/core/semantic.ts +211 -211
  117. package/src/core/skill.ts +384 -384
  118. package/src/core/skymd.ts +143 -143
  119. package/src/core/theme.ts +65 -65
  120. package/src/core/tool.ts +457 -457
  121. package/src/core/trace.ts +236 -0
  122. package/src/core/verify.ts +71 -71
  123. package/src/plugins/loader.ts +91 -91
  124. package/src/skills/loader.ts +75 -75
  125. package/src/tools/builtin.ts +571 -642
  126. package/src/tools/computer.ts +279 -279
  127. package/src/tools/extra.ts +662 -0
  128. package/src/tools/guards.ts +82 -0
  129. package/src/tools/model_tool.ts +93 -74
  130. package/src/tools/todo.ts +76 -76
  131. package/src/web/markdown.ts +193 -0
  132. package/src/web/server.ts +117 -693
  133. package/src/web/ui.ts +949 -0
  134. package/tests/agent.test.ts +211 -159
  135. package/tests/agent_helpers.test.ts +48 -48
  136. package/tests/catalog.test.ts +86 -86
  137. package/tests/checkpoint_commands.test.ts +124 -124
  138. package/tests/claude_compat.test.ts +110 -110
  139. package/tests/commands.test.ts +103 -0
  140. package/tests/concurrency.test.ts +102 -0
  141. package/tests/config.test.ts +41 -41
  142. package/tests/extra_tools.test.ts +212 -0
  143. package/tests/fence_plugin.test.ts +52 -52
  144. package/tests/guard.test.ts +75 -75
  145. package/tests/loom.test.ts +337 -337
  146. package/tests/memory.test.ts +170 -170
  147. package/tests/model_config.test.ts +109 -109
  148. package/tests/skymd.test.ts +146 -146
  149. package/tests/ssrf.test.ts +38 -38
  150. package/tests/structured_retry.test.ts +87 -0
  151. package/tests/task.test.ts +60 -60
  152. package/tests/todo_toolstats.test.ts +94 -94
  153. package/tests/trace.test.ts +128 -0
  154. package/tests/tui.test.ts +67 -67
  155. package/tests/web.test.ts +169 -0
  156. package/tsconfig.json +38 -38
@@ -1,4 +1,9 @@
1
1
  # Provider catalog — API key env vars, base URLs, docs
2
+ # All providers use OpenAI-compatible API format unless noted.
3
+
4
+ # ═══════════════════════════════════════════
5
+ # Major International Providers
6
+ # ═══════════════════════════════════════════
2
7
  openai:
3
8
  env_var: OPENAI_API_KEY
4
9
  base_url: https://api.openai.com/v1
@@ -9,31 +14,129 @@ anthropic:
9
14
  base_url: https://api.anthropic.com/v1
10
15
  docs_url: https://console.anthropic.com/settings/keys
11
16
 
17
+ google:
18
+ env_var: GEMINI_API_KEY
19
+ base_url: https://generativelanguage.googleapis.com/v1beta
20
+ docs_url: https://aistudio.google.com/app/apikey
21
+
12
22
  deepseek:
13
23
  env_var: DEEPSEEK_API_KEY
14
24
  base_url: https://api.deepseek.com/v1
15
25
  docs_url: https://platform.deepseek.com/api_keys
16
26
 
17
- groq:
18
- env_var: GROQ_API_KEY
19
- base_url: https://api.groq.com/openai/v1
27
+ xai:
28
+ env_var: XAI_API_KEY
29
+ base_url: https://api.x.ai/v1
30
+ docs_url: https://console.x.ai/
20
31
 
21
32
  mistral:
22
33
  env_var: MISTRAL_API_KEY
23
34
  base_url: https://api.mistral.ai/v1
35
+ docs_url: https://console.mistral.ai/api-keys/
36
+
37
+ groq:
38
+ env_var: GROQ_API_KEY
39
+ base_url: https://api.groq.com/openai/v1
40
+ docs_url: https://console.groq.com/keys
24
41
 
25
42
  cohere:
26
43
  env_var: COHERE_API_KEY
27
44
  base_url: https://api.cohere.ai/v1
45
+ docs_url: https://dashboard.cohere.com/api-keys
46
+
47
+ perplexity:
48
+ env_var: PERPLEXITY_API_KEY
49
+ base_url: https://api.perplexity.ai
50
+ docs_url: https://www.perplexity.ai/settings/api
51
+
52
+ fireworks:
53
+ env_var: FIREWORKS_API_KEY
54
+ base_url: https://api.fireworks.ai/inference/v1
55
+ docs_url: https://fireworks.ai/api-keys
56
+
57
+ together:
58
+ env_var: TOGETHER_API_KEY
59
+ base_url: https://api.together.xyz/v1
60
+ docs_url: https://api.together.xyz/settings/api-keys
28
61
 
29
62
  openrouter:
30
63
  env_var: OPENROUTER_API_KEY
31
64
  base_url: https://openrouter.ai/api/v1
65
+ docs_url: https://openrouter.ai/keys
32
66
 
33
- gemini:
34
- env_var: GEMINI_API_KEY
35
- base_url: https://generativelanguage.googleapis.com/v1beta
67
+ reka:
68
+ env_var: REKA_API_KEY
69
+ base_url: https://api.reka.ai/v1
70
+ docs_url: https://platform.reka.ai/api-keys
71
+
72
+ nvidia:
73
+ env_var: NVIDIA_API_KEY
74
+ base_url: https://integrate.api.nvidia.com/v1
75
+ docs_url: https://build.nvidia.com/explore/discover
76
+
77
+ sambanova:
78
+ env_var: SAMBANOVA_API_KEY
79
+ base_url: https://api.sambanova.ai/v1
80
+ docs_url: https://cloud.sambanova.ai/apis
81
+
82
+ # ═══════════════════════════════════════════
83
+ # Chinese Providers
84
+ # ═══════════════════════════════════════════
85
+ qwen:
86
+ env_var: QWEN_API_KEY
87
+ base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
88
+ docs_url: https://dashscope.console.aliyun.com/apiKey
89
+
90
+ zhipu:
91
+ env_var: ZHIPU_API_KEY
92
+ base_url: https://open.bigmodel.cn/api/paas/v4
93
+ docs_url: https://open.bigmodel.cn/usercenter/apikeys
94
+
95
+ lingyiwanwu:
96
+ env_var: LINGYIWANWU_API_KEY
97
+ base_url: https://api.lingyiwanwu.com/v1
98
+ docs_url: https://platform.lingyiwanwu.com/apikeys
99
+
100
+ minimax:
101
+ env_var: MINIMAX_API_KEY
102
+ base_url: https://api.minimax.chat/v1
103
+ docs_url: https://platform.minimaxi.com/user-center/basic-information/interface-key
36
104
 
105
+ moonshot:
106
+ env_var: MOONSHOT_API_KEY
107
+ base_url: https://api.moonshot.cn/v1
108
+ docs_url: https://platform.moonshot.cn/console/api-keys
109
+
110
+ baidu:
111
+ env_var: BAIDU_API_KEY
112
+ base_url: https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop
113
+ docs_url: https://console.bce.baidu.com/qianfan/ais/console/onlineService
114
+
115
+ baichuan:
116
+ env_var: BAICHUAN_API_KEY
117
+ base_url: https://api.baichuan-ai.com/v1
118
+ docs_url: https://platform.baichuan-ai.com/console/apikey
119
+
120
+ stepfun:
121
+ env_var: STEPFUN_API_KEY
122
+ base_url: https://api.stepfun.com/v1
123
+ docs_url: https://platform.stepfun.com/interface-key
124
+
125
+ # ═══════════════════════════════════════════
126
+ # Local / Self-hosted
127
+ # ═══════════════════════════════════════════
37
128
  ollama:
38
129
  base_url: http://localhost:11434/v1
39
130
  env_var: OLLAMA_HOST
131
+
132
+ lmstudio:
133
+ base_url: http://localhost:1234/v1
134
+ env_var: LMSTUDIO_HOST
135
+
136
+ vllm:
137
+ base_url: http://localhost:8000/v1
138
+ env_var: VLLM_HOST
139
+
140
+ litellm:
141
+ base_url: http://localhost:4000/v1
142
+ env_var: LITELLM_HOST
@@ -11,6 +11,8 @@ export declare class SnowAgent extends BaseAgent {
11
11
  systemPrompt: string;
12
12
  systemPromptEn: string;
13
13
  orchestrate(goal: string): Promise<Task[]>;
14
+ /** Strict plan parse: throws on unparseable/invalid JSON or an empty plan. */
15
+ private parsePlanStrict;
14
16
  private parseTaskPlan;
15
17
  replanForMissing(goal: string, priorResults: any[], missing: string, existingIds?: Set<string>): Promise<Task[]>;
16
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"snow.d.ts","sourceRoot":"","sources":["../../src/agents/snow.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAIhD,qBAAa,SAAU,SAAQ,SAAS;IACtC,IAAI,SAAU;IACd,WAAW,SAAO;IAClB,KAAK,SAAO;IACZ,SAAS,SAAU;IACnB,UAAU,WAAyE;IAEnF,YAAY,SAWJ;IAER,cAAc,SAQuG;IAE/G,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAQhD,OAAO,CAAC,aAAa;IAiBf,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;CASvH"}
1
+ {"version":3,"file":"snow.d.ts","sourceRoot":"","sources":["../../src/agents/snow.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAKhD,qBAAa,SAAU,SAAQ,SAAS;IACtC,IAAI,SAAU;IACd,WAAW,SAAO;IAClB,KAAK,SAAO;IACZ,SAAS,SAAU;IACnB,UAAU,WAAyE;IAEnF,YAAY,SAWJ;IAER,cAAc,SAQuG;IAE/G,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAyBhD,8EAA8E;IAC9E,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,aAAa;IAiBf,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;CASvH"}
@@ -5,6 +5,7 @@ exports.SnowAgent = void 0;
5
5
  * 雪 (Snow) — 架构规划型 Agent.
6
6
  */
7
7
  const agent_1 = require("../core/agent");
8
+ const schemas_1 = require("../core/schemas");
8
9
  const VALID_AGENTS = new Set(['fog', 'rain', 'frost', 'snow', 'dew']);
9
10
  class SnowAgent extends agent_1.BaseAgent {
10
11
  constructor() {
@@ -37,11 +38,41 @@ Do 90% yourself. When orchestrating, assign to fog/rain/frost/dew. Never assign
37
38
  Like snow—silent but all-covering. Framework first, then detail. Note dependencies and risks. Prioritize and deliver.`;
38
39
  }
39
40
  async orchestrate(goal) {
40
- const prompt = `请将以下目标分解为子任务,并分配给合适的 Agent。\n\n目标: ${goal}\n\n请严格按 JSON 格式输出:\n{"goal": "目标", "steps": [{"id": "1", "description": "任务", "agent": "fog|rain|frost|dew"}]}\n\n可用: fog(调研) rain(代码) frost(审查) dew(运维)。不要分配 fair。直接输出 JSON。`;
41
- this.memory.addMessage('user', prompt);
42
- const response = await this.llmLoop();
43
- this.memory.addMessage('assistant', response.content);
44
- return this.parseTaskPlan(response.content, goal);
41
+ const base = `请将以下目标分解为子任务,并分配给合适的 Agent。\n\n目标: ${goal}\n\n请严格按 JSON 格式输出:\n{"goal": "目标", "steps": [{"id": "1", "description": "任务", "agent": "fog|rain|frost|dew"}]}\n\n可用: fog(调研) rain(代码) frost(审查) dew(运维)。不要分配 fair。直接输出 JSON。`;
42
+ try {
43
+ // Structured-output retry: if the plan JSON is malformed, feed the parse
44
+ // error back and re-ask before falling back — a bad response no longer
45
+ // silently collapses a multi-step plan into a single task.
46
+ return await (0, schemas_1.parseWithRetry)(async (priorError) => {
47
+ const prompt = priorError
48
+ ? `${base}\n\n[你上一次的输出无法解析:${priorError}。只输出严格合法的 JSON,不要任何额外文字、解释或 markdown 代码围栏。]`
49
+ : base;
50
+ this.memory.addMessage('user', prompt);
51
+ const response = await this.llmLoop();
52
+ this.memory.addMessage('assistant', response.content);
53
+ return response.content;
54
+ }, (raw) => this.parsePlanStrict(raw, goal), { retries: 2 });
55
+ }
56
+ catch {
57
+ // Every attempt failed → safe single-task fallback (prior behavior).
58
+ return [new agent_1.Task({ id: '1', description: goal, assignedTo: 'rain', metadata: { goal } })];
59
+ }
60
+ }
61
+ /** Strict plan parse: throws on unparseable/invalid JSON or an empty plan. */
62
+ parsePlanStrict(content, goal) {
63
+ const data = (0, schemas_1.parseSchema)(content); // throws SchemaValidationError on bad JSON
64
+ if (data && typeof data.goal !== 'string')
65
+ data.goal = goal; // we already know the goal
66
+ const plan = (0, schemas_1.validateTaskPlan)(data); // throws on a malformed plan shape
67
+ const tasks = [];
68
+ for (const step of plan.steps) {
69
+ const a = VALID_AGENTS.has(String(step.agent)) ? String(step.agent) : 'rain';
70
+ const deps = Array.isArray(step.depends_on) ? step.depends_on : [];
71
+ tasks.push(new agent_1.Task({ id: String(step.id), description: step.description, assignedTo: a, dependsOn: deps, metadata: { goal } }));
72
+ }
73
+ if (!tasks.length)
74
+ throw new schemas_1.SchemaValidationError('plan has no steps');
75
+ return tasks;
45
76
  }
46
77
  parseTaskPlan(content, goal) {
47
78
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"snow.js","sourceRoot":"","sources":["../../src/agents/snow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"snow.js","sourceRoot":"","sources":["../../src/agents/snow.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"loom_chat.d.ts","sourceRoot":"","sources":["../../src/cli/loom_chat.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA0PH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACpF,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAkV3F"}
1
+ {"version":3,"file":"loom_chat.d.ts","sourceRoot":"","sources":["../../src/cli/loom_chat.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA4PH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACpF,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAyf3F"}
@@ -23,6 +23,8 @@ const input_macros_1 = require("./input_macros");
23
23
  const commands_md_1 = require("./commands_md");
24
24
  const file_checkpoint_1 = require("../core/file_checkpoint");
25
25
  const loom_1 = require("./loom");
26
+ const catalog_1 = require("../core/catalog");
27
+ const skill_1 = require("../core/skill");
26
28
  const OK_HEX = "#3a7a6e"; // 石绿 — success
27
29
  const ERR_HEX = "#b3342d"; // 朱砂 — failure
28
30
  const AGENT_NAMES = ["fog", "rain", "frost", "snow", "dew", "fair"];
@@ -398,6 +400,26 @@ async function loomChat(ctx, startAgent, deps) {
398
400
  ui.blank();
399
401
  continue;
400
402
  }
403
+ if (cmdL === "/trace") {
404
+ const trace = agent.getLastTrace?.();
405
+ if (!trace || !trace.spans?.length) {
406
+ dim("本会话还没有可追踪的运行(先对话一次)");
407
+ continue;
408
+ }
409
+ const { renderTrace } = require("../core/trace");
410
+ const t = (0, theme_1.agentTheme)(agent.name);
411
+ ui.blank();
412
+ say(" " + chalk_1.default.bold.hex(t.hex)(`${t.symbol} 运行追踪`) + chalk_1.default.dim(` · ${trace.label}`));
413
+ const rendered = renderTrace(trace, {
414
+ dim: (s) => chalk_1.default.dim(s),
415
+ ok: (s) => chalk_1.default.hex(OK_HEX)(s),
416
+ err: (s) => chalk_1.default.hex(ERR_HEX)(s),
417
+ });
418
+ for (const ln of rendered.split("\n"))
419
+ ui.line(" " + ln);
420
+ ui.blank();
421
+ continue;
422
+ }
401
423
  if (cmdL === "/verify") {
402
424
  const vc = (0, verify_1.resolveVerifyConfig)(ctx.config);
403
425
  if (!vc.commands.length) {
@@ -527,6 +549,36 @@ async function loomChat(ctx, startAgent, deps) {
527
549
  dim(`⚠ ${r.provider} 还没有 API key — /apikey set ${r.provider} <key> 或 /model key <key>`);
528
550
  continue;
529
551
  }
552
+ if (cmdL === "/models" || cmdL.startsWith("/models ")) {
553
+ const { listProviders, modelsFor, providerLabel } = require("../core/catalog");
554
+ const args = inp.split(/\s+/).slice(1);
555
+ const filter = args[0]?.toLowerCase() || "";
556
+ ui.blank();
557
+ say(" " + chalk_1.default.bold.hex("#3a7a6e")("✦ 模型目录 · Model Catalog"));
558
+ dim(" ─────────────────────────────────────────────");
559
+ const providers = listProviders();
560
+ let totalModels = 0;
561
+ for (const p of providers) {
562
+ const models = modelsFor(p);
563
+ if (!models.length)
564
+ continue;
565
+ if (filter && !p.toLowerCase().includes(filter) && !providerLabel(p).toLowerCase().includes(filter))
566
+ continue;
567
+ const label = providerLabel(p);
568
+ say(" " + chalk_1.default.bold.hex("#3a7a6e")(` ${label}`));
569
+ for (const m of models) {
570
+ totalModels++;
571
+ const costStr = m.costIn === 0 && m.costOut === 0 ? chalk_1.default.green("免费") : chalk_1.default.dim(`$${m.costIn.toFixed(2)}/$${m.costOut.toFixed(2)}`);
572
+ const ctxStr = m.context >= 1000000 ? chalk_1.default.cyan(`${(m.context / 1000000).toFixed(0)}M`) : m.context >= 1000 ? chalk_1.default.cyan(`${(m.context / 1000).toFixed(0)}K`) : chalk_1.default.cyan(`${m.context}`);
573
+ say(` ${chalk_1.default.dim("·")} ${chalk_1.default.white(m.id.padEnd(38))} ${ctxStr} ${chalk_1.default.dim(" ")} ${costStr} ${chalk_1.default.gray(m.desc)}`);
574
+ }
575
+ }
576
+ dim(` ────────────────────────────────────────────`);
577
+ dim(` 共 ${providers.length} 个 Provider · ${totalModels} 个模型`);
578
+ dim(" 用法: /models [provider] 筛选 · /model <id> 切换");
579
+ ui.blank();
580
+ continue;
581
+ }
530
582
  if (cmdL === "/sessions") {
531
583
  lastSessions = await agent.memory.listSessions();
532
584
  const active = agent.memory.getActiveSession();
@@ -623,7 +675,161 @@ async function loomChat(ctx, startAgent, deps) {
623
675
  dim(f);
624
676
  continue;
625
677
  }
626
- // ── 自定义斜杠命令 ──
678
+ if (cmdL === "/undo" || cmdL.startsWith("/undo ")) {
679
+ const cp = (0, file_checkpoint_1.getFileCheckpoints)();
680
+ const arg = inp.slice(5).trim();
681
+ const n = /^\d+$/.test(arg) ? parseInt(arg, 10) : 1;
682
+ const r = cp.rewind(n);
683
+ if (r.turns === 0) {
684
+ const turns = cp.list();
685
+ if (!turns.length) {
686
+ dim("没有可撤销的文件改动");
687
+ continue;
688
+ }
689
+ say(" " + chalk_1.default.bold("检查点") + chalk_1.default.dim(` · ${turns.length} 轮可撤销`));
690
+ for (const t of turns.slice(0, 8))
691
+ dim(`${t.label} · ${t.files.length} 个文件`);
692
+ continue;
693
+ }
694
+ say(" " + chalk_1.default.hex(OK_HEX)(`↺ 已撤销 ${r.turns} 轮`) + chalk_1.default.dim(` · 恢复 ${r.restored.length} 个文件`));
695
+ for (const f of r.restored.slice(0, 10))
696
+ dim(f);
697
+ continue;
698
+ }
699
+ if (cmdL === "/redo") {
700
+ const cp = (0, file_checkpoint_1.getFileCheckpoints)();
701
+ const r = cp.redo();
702
+ if (r.turns === 0) {
703
+ dim("没有可重做的操作");
704
+ continue;
705
+ }
706
+ say(" " + chalk_1.default.hex(OK_HEX)(`↻ 已重做 ${r.turns} 轮`) + chalk_1.default.dim(` · 恢复 ${r.restored.length} 个文件`));
707
+ for (const f of r.restored.slice(0, 10))
708
+ dim(f);
709
+ continue;
710
+ }
711
+ if (cmdL === "/export" || cmdL.startsWith("/export ")) {
712
+ const filename = inp.slice(8).trim() || `skyloom-export-${Date.now()}.md`;
713
+ const msgs = agent.memory.shortTerm.filter((m) => m.role !== "system");
714
+ let md = `# Skyloom Session Export\n\n**Agent**: ${agent.name}\n**Date**: ${new Date().toISOString()}\n**Messages**: ${msgs.length}\n\n---\n\n`;
715
+ for (const m of msgs) {
716
+ const role = m.role === "user" ? "👤 User" : `🤖 ${agent.name}`;
717
+ md += `## ${role}\n\n${m.content}\n\n`;
718
+ }
719
+ require("fs").writeFileSync(filename, md, "utf-8");
720
+ say(" " + chalk_1.default.hex(OK_HEX)(`✓ 已导出到 ${filename}`) + chalk_1.default.dim(` · ${msgs.length} 条消息`));
721
+ continue;
722
+ }
723
+ if (cmdL === "/thinking") {
724
+ const cfg = ctx.config;
725
+ cfg.show_thinking = !cfg.show_thinking;
726
+ dim(`推理过程显示 → ${cfg.show_thinking ? "开启" : "关闭"}`);
727
+ continue;
728
+ }
729
+ if (cmdL === "/details") {
730
+ const cfg = ctx.config;
731
+ cfg.show_tool_details = !cfg.show_tool_details;
732
+ dim(`工具执行详情 → ${cfg.show_tool_details ? "开启" : "关闭"}`);
733
+ continue;
734
+ }
735
+ if (cmdL === "/skills") {
736
+ const skills = skill_1.globalSkillRegistry.getSkills();
737
+ ui.blank();
738
+ say(" " + chalk_1.default.bold.hex("#3a7a6e")("✦ 技能目录 · Skills"));
739
+ dim(" ─────────────────────────────────────────────");
740
+ for (const s of skills.slice(0, 20)) {
741
+ say(` ${chalk_1.default.dim("·")} ${chalk_1.default.white(s.name.padEnd(24))} ${chalk_1.default.gray(s.description.slice(0, 50))}`);
742
+ }
743
+ dim(` 共 ${skills.length} 个技能 · 使用时自动激活`);
744
+ ui.blank();
745
+ continue;
746
+ }
747
+ if (cmdL === "/review" || cmdL.startsWith("/review ")) {
748
+ const target = inp.slice(9).trim() || "uncommitted";
749
+ ui.blank();
750
+ say(" " + chalk_1.default.bold(" 代码审查 · Code Review"));
751
+ dim(` 目标: ${target}`);
752
+ ui.blank();
753
+ const reviewPrompt = `Please review the code changes for ${target}. Focus on:
754
+ 1. Code quality and best practices
755
+ 2. Potential bugs or issues
756
+ 3. Security concerns
757
+ 4. Performance implications
758
+ 5. Suggestions for improvement
759
+
760
+ Provide specific, actionable feedback.`;
761
+ await loomStream(ui, agent, reviewPrompt);
762
+ continue;
763
+ }
764
+ if (cmdL === "/connect" || cmdL.startsWith("/connect ")) {
765
+ const provider = inp.slice(9).trim();
766
+ if (!provider) {
767
+ ui.blank();
768
+ say(" " + chalk_1.default.bold("✦ 配置 Provider"));
769
+ dim(" 用法: /connect <provider>");
770
+ dim(" 示例: /connect openai");
771
+ ui.blank();
772
+ continue;
773
+ }
774
+ const meta = catalog_1.PROVIDER_META[provider.toLowerCase()];
775
+ if (!meta) {
776
+ dim(`'${provider}' 不是已知 Provider`);
777
+ continue;
778
+ }
779
+ ui.blank();
780
+ say(" " + chalk_1.default.bold.hex("#3a7a6e")(meta.name));
781
+ dim(` 环境变量: ${meta.envVar || "(无)"}`);
782
+ dim(` 设置: /apikey set ${provider} <key>`);
783
+ ui.blank();
784
+ continue;
785
+ }
786
+ if (cmdL === "/warp" || cmdL.startsWith("/warp ")) {
787
+ const newPath = inp.slice(6).trim();
788
+ if (!newPath) {
789
+ dim("用法: /warp <path> — 切换工作区");
790
+ continue;
791
+ }
792
+ const resolved = require("path").resolve(newPath);
793
+ if (!require("fs").existsSync(resolved)) {
794
+ dim(`路径不存在: ${resolved}`);
795
+ continue;
796
+ }
797
+ ctx.workspacePath = resolved;
798
+ agent.reloadProjectMemory();
799
+ say(" " + chalk_1.default.hex(OK_HEX)(`✓ 工作区 → ${resolved}`));
800
+ continue;
801
+ }
802
+ if (cmdL === "/move" || cmdL.startsWith("/move ")) {
803
+ const newPath = inp.slice(6).trim();
804
+ if (!newPath) {
805
+ dim("用法: /move <path> — 移动会话到项目");
806
+ continue;
807
+ }
808
+ const resolved = require("path").resolve(newPath);
809
+ if (!require("fs").existsSync(resolved)) {
810
+ dim(`路径不存在: ${resolved}`);
811
+ continue;
812
+ }
813
+ ctx.workspacePath = resolved;
814
+ agent.reloadProjectMemory();
815
+ say(" " + chalk_1.default.hex(OK_HEX)(`✓ 工作区 → ${resolved}`));
816
+ continue;
817
+ }
818
+ if (cmdL === "/summarize") {
819
+ ui.busy = true;
820
+ ui.busyLabel = "压缩上下文";
821
+ try {
822
+ const r = await agent.compact();
823
+ say(" " + chalk_1.default.hex(OK_HEX)("✓ ") + chalk_1.default.dim(String(r)));
824
+ }
825
+ catch (e) {
826
+ say(" " + chalk_1.default.hex(ERR_HEX)("✗ ") + chalk_1.default.dim(String(e?.message || e)));
827
+ }
828
+ ui.busy = false;
829
+ ui.busyLabel = "";
830
+ continue;
831
+ }
832
+ // ── 自定义斜杠命令 ─
627
833
  if (inp.startsWith("/")) {
628
834
  const hit = (0, commands_md_1.resolveCustomCommand)(inp, customCommands);
629
835
  if (hit) {