skyloom 1.4.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 (225) hide show
  1. package/.github/workflows/ci.yml +36 -0
  2. package/CONVERSION_PLAN.md +191 -0
  3. package/README.md +67 -0
  4. package/dist/agents/dew.d.ts +15 -0
  5. package/dist/agents/dew.d.ts.map +1 -0
  6. package/dist/agents/dew.js +74 -0
  7. package/dist/agents/dew.js.map +1 -0
  8. package/dist/agents/fair.d.ts +15 -0
  9. package/dist/agents/fair.d.ts.map +1 -0
  10. package/dist/agents/fair.js +106 -0
  11. package/dist/agents/fair.js.map +1 -0
  12. package/dist/agents/fog.d.ts +15 -0
  13. package/dist/agents/fog.d.ts.map +1 -0
  14. package/dist/agents/fog.js +52 -0
  15. package/dist/agents/fog.js.map +1 -0
  16. package/dist/agents/frost.d.ts +15 -0
  17. package/dist/agents/frost.d.ts.map +1 -0
  18. package/dist/agents/frost.js +54 -0
  19. package/dist/agents/frost.js.map +1 -0
  20. package/dist/agents/rain.d.ts +15 -0
  21. package/dist/agents/rain.d.ts.map +1 -0
  22. package/dist/agents/rain.js +54 -0
  23. package/dist/agents/rain.js.map +1 -0
  24. package/dist/agents/snow.d.ts +27 -0
  25. package/dist/agents/snow.d.ts.map +1 -0
  26. package/dist/agents/snow.js +226 -0
  27. package/dist/agents/snow.js.map +1 -0
  28. package/dist/cli/main.d.ts +7 -0
  29. package/dist/cli/main.d.ts.map +1 -0
  30. package/dist/cli/main.js +402 -0
  31. package/dist/cli/main.js.map +1 -0
  32. package/dist/cli/mode.d.ts +17 -0
  33. package/dist/cli/mode.d.ts.map +1 -0
  34. package/dist/cli/mode.js +56 -0
  35. package/dist/cli/mode.js.map +1 -0
  36. package/dist/core/agent.d.ts +174 -0
  37. package/dist/core/agent.d.ts.map +1 -0
  38. package/dist/core/agent.js +1332 -0
  39. package/dist/core/agent.js.map +1 -0
  40. package/dist/core/agent_helpers.d.ts +51 -0
  41. package/dist/core/agent_helpers.d.ts.map +1 -0
  42. package/dist/core/agent_helpers.js +477 -0
  43. package/dist/core/agent_helpers.js.map +1 -0
  44. package/dist/core/bus.d.ts +99 -0
  45. package/dist/core/bus.d.ts.map +1 -0
  46. package/dist/core/bus.js +191 -0
  47. package/dist/core/bus.js.map +1 -0
  48. package/dist/core/cache.d.ts +63 -0
  49. package/dist/core/cache.d.ts.map +1 -0
  50. package/dist/core/cache.js +121 -0
  51. package/dist/core/cache.js.map +1 -0
  52. package/dist/core/checkpoint.d.ts +19 -0
  53. package/dist/core/checkpoint.d.ts.map +1 -0
  54. package/dist/core/checkpoint.js +120 -0
  55. package/dist/core/checkpoint.js.map +1 -0
  56. package/dist/core/circuit_breaker.d.ts +46 -0
  57. package/dist/core/circuit_breaker.d.ts.map +1 -0
  58. package/dist/core/circuit_breaker.js +99 -0
  59. package/dist/core/circuit_breaker.js.map +1 -0
  60. package/dist/core/config.d.ts +97 -0
  61. package/dist/core/config.d.ts.map +1 -0
  62. package/dist/core/config.js +281 -0
  63. package/dist/core/config.js.map +1 -0
  64. package/dist/core/constants.d.ts +78 -0
  65. package/dist/core/constants.d.ts.map +1 -0
  66. package/dist/core/constants.js +84 -0
  67. package/dist/core/constants.js.map +1 -0
  68. package/dist/core/factory.d.ts +63 -0
  69. package/dist/core/factory.d.ts.map +1 -0
  70. package/dist/core/factory.js +537 -0
  71. package/dist/core/factory.js.map +1 -0
  72. package/dist/core/icons.d.ts +28 -0
  73. package/dist/core/icons.d.ts.map +1 -0
  74. package/dist/core/icons.js +86 -0
  75. package/dist/core/icons.js.map +1 -0
  76. package/dist/core/index.d.ts +29 -0
  77. package/dist/core/index.d.ts.map +1 -0
  78. package/dist/core/index.js +54 -0
  79. package/dist/core/index.js.map +1 -0
  80. package/dist/core/llm.d.ts +121 -0
  81. package/dist/core/llm.d.ts.map +1 -0
  82. package/dist/core/llm.js +532 -0
  83. package/dist/core/llm.js.map +1 -0
  84. package/dist/core/logger.d.ts +57 -0
  85. package/dist/core/logger.d.ts.map +1 -0
  86. package/dist/core/logger.js +122 -0
  87. package/dist/core/logger.js.map +1 -0
  88. package/dist/core/mcp.d.ts +190 -0
  89. package/dist/core/mcp.d.ts.map +1 -0
  90. package/dist/core/mcp.js +822 -0
  91. package/dist/core/mcp.js.map +1 -0
  92. package/dist/core/mcp_server.d.ts +26 -0
  93. package/dist/core/mcp_server.d.ts.map +1 -0
  94. package/dist/core/mcp_server.js +211 -0
  95. package/dist/core/mcp_server.js.map +1 -0
  96. package/dist/core/memory.d.ts +190 -0
  97. package/dist/core/memory.d.ts.map +1 -0
  98. package/dist/core/memory.js +988 -0
  99. package/dist/core/memory.js.map +1 -0
  100. package/dist/core/middleware.d.ts +114 -0
  101. package/dist/core/middleware.d.ts.map +1 -0
  102. package/dist/core/middleware.js +248 -0
  103. package/dist/core/middleware.js.map +1 -0
  104. package/dist/core/pipelines.d.ts +87 -0
  105. package/dist/core/pipelines.d.ts.map +1 -0
  106. package/dist/core/pipelines.js +301 -0
  107. package/dist/core/pipelines.js.map +1 -0
  108. package/dist/core/profile.d.ts +23 -0
  109. package/dist/core/profile.d.ts.map +1 -0
  110. package/dist/core/profile.js +289 -0
  111. package/dist/core/profile.js.map +1 -0
  112. package/dist/core/router.d.ts +24 -0
  113. package/dist/core/router.d.ts.map +1 -0
  114. package/dist/core/router.js +111 -0
  115. package/dist/core/router.js.map +1 -0
  116. package/dist/core/schemas.d.ts +82 -0
  117. package/dist/core/schemas.d.ts.map +1 -0
  118. package/dist/core/schemas.js +200 -0
  119. package/dist/core/schemas.js.map +1 -0
  120. package/dist/core/semantic.d.ts +92 -0
  121. package/dist/core/semantic.d.ts.map +1 -0
  122. package/dist/core/semantic.js +175 -0
  123. package/dist/core/semantic.js.map +1 -0
  124. package/dist/core/skill.d.ts +68 -0
  125. package/dist/core/skill.d.ts.map +1 -0
  126. package/dist/core/skill.js +350 -0
  127. package/dist/core/skill.js.map +1 -0
  128. package/dist/core/tool.d.ts +99 -0
  129. package/dist/core/tool.d.ts.map +1 -0
  130. package/dist/core/tool.js +341 -0
  131. package/dist/core/tool.js.map +1 -0
  132. package/dist/core/tool_router.d.ts +29 -0
  133. package/dist/core/tool_router.d.ts.map +1 -0
  134. package/dist/core/tool_router.js +172 -0
  135. package/dist/core/tool_router.js.map +1 -0
  136. package/dist/core/workspace.d.ts +48 -0
  137. package/dist/core/workspace.d.ts.map +1 -0
  138. package/dist/core/workspace.js +179 -0
  139. package/dist/core/workspace.js.map +1 -0
  140. package/dist/plugins/loader.d.ts +17 -0
  141. package/dist/plugins/loader.d.ts.map +1 -0
  142. package/dist/plugins/loader.js +96 -0
  143. package/dist/plugins/loader.js.map +1 -0
  144. package/dist/skills/loader.d.ts +9 -0
  145. package/dist/skills/loader.d.ts.map +1 -0
  146. package/dist/skills/loader.js +78 -0
  147. package/dist/skills/loader.js.map +1 -0
  148. package/dist/tools/builtin.d.ts +10 -0
  149. package/dist/tools/builtin.d.ts.map +1 -0
  150. package/dist/tools/builtin.js +414 -0
  151. package/dist/tools/builtin.js.map +1 -0
  152. package/dist/tools/computer.d.ts +12 -0
  153. package/dist/tools/computer.d.ts.map +1 -0
  154. package/dist/tools/computer.js +326 -0
  155. package/dist/tools/computer.js.map +1 -0
  156. package/dist/tools/delegate.d.ts +10 -0
  157. package/dist/tools/delegate.d.ts.map +1 -0
  158. package/dist/tools/delegate.js +45 -0
  159. package/dist/tools/delegate.js.map +1 -0
  160. package/dist/web/server.d.ts +5 -0
  161. package/dist/web/server.d.ts.map +1 -0
  162. package/dist/web/server.js +647 -0
  163. package/dist/web/server.js.map +1 -0
  164. package/dist/web/tts.d.ts +33 -0
  165. package/dist/web/tts.d.ts.map +1 -0
  166. package/dist/web/tts.js +69 -0
  167. package/dist/web/tts.js.map +1 -0
  168. package/package.json +60 -0
  169. package/scripts/install.js +48 -0
  170. package/scripts/link.js +10 -0
  171. package/setup.bat +79 -0
  172. package/skill-test-ty2fOA/test.md +10 -0
  173. package/src/agents/dew.ts +70 -0
  174. package/src/agents/fair.ts +102 -0
  175. package/src/agents/fog.ts +48 -0
  176. package/src/agents/frost.ts +50 -0
  177. package/src/agents/rain.ts +50 -0
  178. package/src/agents/snow.ts +239 -0
  179. package/src/cli/main.ts +405 -0
  180. package/src/cli/mode.ts +58 -0
  181. package/src/core/agent.ts +1506 -0
  182. package/src/core/agent_helpers.ts +461 -0
  183. package/src/core/bus.ts +221 -0
  184. package/src/core/cache.ts +153 -0
  185. package/src/core/checkpoint.ts +94 -0
  186. package/src/core/circuit_breaker.ts +119 -0
  187. package/src/core/config.ts +341 -0
  188. package/src/core/constants.ts +95 -0
  189. package/src/core/factory.ts +627 -0
  190. package/src/core/icons.ts +53 -0
  191. package/src/core/index.ts +31 -0
  192. package/src/core/llm.ts +724 -0
  193. package/src/core/logger.ts +144 -0
  194. package/src/core/mcp.ts +953 -0
  195. package/src/core/mcp_server.ts +176 -0
  196. package/src/core/memory.ts +1169 -0
  197. package/src/core/middleware.ts +350 -0
  198. package/src/core/pipelines.ts +424 -0
  199. package/src/core/profile.ts +255 -0
  200. package/src/core/router.ts +124 -0
  201. package/src/core/schemas.ts +282 -0
  202. package/src/core/semantic.ts +211 -0
  203. package/src/core/skill.ts +342 -0
  204. package/src/core/tool.ts +427 -0
  205. package/src/core/tool_router.ts +193 -0
  206. package/src/core/workspace.ts +150 -0
  207. package/src/plugins/loader.ts +66 -0
  208. package/src/skills/loader.ts +46 -0
  209. package/src/sql.js.d.ts +29 -0
  210. package/src/tools/builtin.ts +382 -0
  211. package/src/tools/computer.ts +269 -0
  212. package/src/tools/delegate.ts +49 -0
  213. package/src/web/server.ts +634 -0
  214. package/src/web/tts.ts +93 -0
  215. package/tests/bus.test.ts +121 -0
  216. package/tests/icons.test.ts +45 -0
  217. package/tests/router.test.ts +86 -0
  218. package/tests/schemas.test.ts +51 -0
  219. package/tests/semantic.test.ts +83 -0
  220. package/tests/setup.ts +10 -0
  221. package/tests/skill.test.ts +172 -0
  222. package/tests/tool.test.ts +108 -0
  223. package/tests/tool_router.test.ts +71 -0
  224. package/tsconfig.json +37 -0
  225. package/vitest.config.ts +17 -0
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ /**
3
+ * Shared constants across the Skyloom framework.
4
+ * Central home for values that cross module boundaries — keeps
5
+ * circular imports in check and avoids duplication.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.ROUTING_MODES = exports.MAX_CONTEXT_TOKENS = exports.LOG_LEVELS = exports.RESPONSE_TYPES = exports.MEMORY_LAYERS = exports.MAX_TOOL_RETRIES = exports.DEFAULT_TOOL_TIMEOUT = exports.AGENT_DESCRIPTIONS = exports.VALID_AGENTS = exports.TASK_DONE_SENTINEL = void 0;
9
+ /**
10
+ * Sentinel returned by the task_done tool. When the LLM calls
11
+ * task_done, the chat-stream loop detects this value in the tool
12
+ * result and terminates the turn cleanly (no truncation warning).
13
+ */
14
+ exports.TASK_DONE_SENTINEL = "__TASK_DONE__";
15
+ /**
16
+ * Valid agent names in the system
17
+ */
18
+ exports.VALID_AGENTS = Object.freeze({
19
+ fog: "fog",
20
+ rain: "rain",
21
+ frost: "frost",
22
+ snow: "snow",
23
+ dew: "dew",
24
+ fair: "fair",
25
+ });
26
+ /**
27
+ * Agent roles and descriptions
28
+ */
29
+ exports.AGENT_DESCRIPTIONS = {
30
+ fog: "Research & Analysis — explore, investigate, analyze",
31
+ rain: "Code Generation — create, implement, generate",
32
+ frost: "Review & Optimization — critique, optimize, verify",
33
+ snow: "Planning & Orchestration — plan, decompose, coordinate",
34
+ dew: "DevOps & Execution — operate, deploy, execute",
35
+ fair: "Emotional Companion — comfort, encourage, advise",
36
+ };
37
+ /**
38
+ * Default tool timeout in milliseconds
39
+ */
40
+ exports.DEFAULT_TOOL_TIMEOUT = 30000; // 30 seconds
41
+ /**
42
+ * Maximum retries for tool execution
43
+ */
44
+ exports.MAX_TOOL_RETRIES = 3;
45
+ /**
46
+ * Memory layer configuration
47
+ */
48
+ exports.MEMORY_LAYERS = Object.freeze({
49
+ SHORT_TERM: "short_term",
50
+ WORKING: "working",
51
+ LONG_TERM: "long_term",
52
+ });
53
+ /**
54
+ * Response types
55
+ */
56
+ exports.RESPONSE_TYPES = Object.freeze({
57
+ TEXT: "text",
58
+ TOOL_CALL: "tool_call",
59
+ TOOL_RESULT: "tool_result",
60
+ ERROR: "error",
61
+ });
62
+ /**
63
+ * Log levels
64
+ */
65
+ exports.LOG_LEVELS = Object.freeze({
66
+ DEBUG: 0,
67
+ INFO: 1,
68
+ WARN: 2,
69
+ ERROR: 3,
70
+ });
71
+ /**
72
+ * Maximum context window (tokens)
73
+ */
74
+ exports.MAX_CONTEXT_TOKENS = 100000;
75
+ /**
76
+ * Routing modes for CLI
77
+ */
78
+ exports.ROUTING_MODES = Object.freeze({
79
+ DIRECT: "direct",
80
+ SINGLE: "single",
81
+ ORCHESTRATE: "orchestrate",
82
+ AUTO: "auto",
83
+ });
84
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/core/constants.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH;;;;GAIG;AACU,QAAA,kBAAkB,GAAG,eAAe,CAAC;AAElD;;GAEG;AACU,QAAA,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC;IACxC,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,MAAM;CACJ,CAAC,CAAC;AAOZ;;GAEG;AACU,QAAA,kBAAkB,GAA8B;IAC3D,GAAG,EAAE,qDAAqD;IAC1D,IAAI,EAAE,+CAA+C;IACrD,KAAK,EAAE,oDAAoD;IAC3D,IAAI,EAAE,wDAAwD;IAC9D,GAAG,EAAE,+CAA+C;IACpD,IAAI,EAAE,kDAAkD;CACzD,CAAC;AAEF;;GAEG;AACU,QAAA,oBAAoB,GAAG,KAAK,CAAC,CAAC,aAAa;AAExD;;GAEG;AACU,QAAA,gBAAgB,GAAG,CAAC,CAAC;AAElC;;GAEG;AACU,QAAA,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC;IACzC,UAAU,EAAE,YAAY;IACxB,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,WAAW;CACd,CAAC,CAAC;AAEZ;;GAEG;AACU,QAAA,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1C,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,WAAW;IACtB,WAAW,EAAE,aAAa;IAC1B,KAAK,EAAE,OAAO;CACN,CAAC,CAAC;AAEZ;;GAEG;AACU,QAAA,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IACtC,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACA,CAAC,CAAC;AAEZ;;GAEG;AACU,QAAA,kBAAkB,GAAG,MAAM,CAAC;AAEzC;;GAEG;AACU,QAAA,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC;IACzC,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,aAAa;IAC1B,IAAI,EAAE,MAAM;CACJ,CAAC,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * System factory — unified Agent creation and task orchestration.
3
+ *
4
+ * Avoids duplication between CLI and web entry points.
5
+ */
6
+ import { BaseAgent } from './agent';
7
+ import { MessageBus } from './bus';
8
+ import { loadConfig } from './config';
9
+ import { LLMClient } from './llm';
10
+ import { ToolRegistry } from './tool';
11
+ export declare class SystemContext {
12
+ config: ReturnType<typeof loadConfig>;
13
+ bus: MessageBus;
14
+ llm: LLMClient;
15
+ agentMap: Map<string, BaseAgent>;
16
+ toolRegistry: ToolRegistry;
17
+ workspacePath: string;
18
+ mcp: any;
19
+ mcpStatus: string[];
20
+ constructor(opts: {
21
+ config: ReturnType<typeof loadConfig>;
22
+ bus: MessageBus;
23
+ llm: LLMClient;
24
+ agentMap: Map<string, BaseAgent>;
25
+ toolRegistry: ToolRegistry;
26
+ workspacePath?: string;
27
+ mcp?: any;
28
+ mcpStatus?: string[];
29
+ });
30
+ initAll(): Promise<void>;
31
+ closeAll(): Promise<void>;
32
+ }
33
+ /**
34
+ * Bootstrap the full system: config, bus, LLM, tools, skills, plugins, agents.
35
+ */
36
+ export declare function createSystemContext(): SystemContext;
37
+ export declare class TaskExecutionResult {
38
+ id: string;
39
+ agent: string;
40
+ description: string;
41
+ success: boolean;
42
+ content: string;
43
+ constructor(opts: {
44
+ id: string;
45
+ agent: string;
46
+ description: string;
47
+ success: boolean;
48
+ content: string;
49
+ });
50
+ }
51
+ export declare function orchestrateTask(goal: string, agentMap: Map<string, BaseAgent>, snow?: BaseAgent | null, options?: {
52
+ onTaskStart?: ((task: any) => Promise<void>) | null;
53
+ onTaskDone?: ((task: any, result: TaskExecutionResult) => Promise<void>) | null;
54
+ onPlanned?: ((tasks: any[]) => Promise<boolean | null>) | null;
55
+ onToolStatus?: ((status: string) => void) | null;
56
+ resultTruncate?: number | null;
57
+ summaryPromptTemplate?: string;
58
+ maxTaskRetries?: number;
59
+ maxReplanRounds?: number;
60
+ maxTotalTasks?: number;
61
+ resume?: boolean;
62
+ }): Promise<[any[], TaskExecutionResult[], string]>;
63
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/core/factory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,537 @@
1
+ "use strict";
2
+ /**
3
+ * System factory — unified Agent creation and task orchestration.
4
+ *
5
+ * Avoids duplication between CLI and web entry points.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.TaskExecutionResult = exports.SystemContext = void 0;
9
+ exports.createSystemContext = createSystemContext;
10
+ exports.orchestrateTask = orchestrateTask;
11
+ const agent_1 = require("./agent");
12
+ const bus_1 = require("./bus");
13
+ const config_1 = require("./config");
14
+ const llm_1 = require("./llm");
15
+ const logger_1 = require("./logger");
16
+ const skill_1 = require("./skill");
17
+ const tool_1 = require("./tool");
18
+ const log = (0, logger_1.getLogger)('factory');
19
+ class SystemContext {
20
+ constructor(opts) {
21
+ this.workspacePath = '';
22
+ this.mcp = null;
23
+ this.mcpStatus = [];
24
+ this.config = opts.config;
25
+ this.bus = opts.bus;
26
+ this.llm = opts.llm;
27
+ this.agentMap = opts.agentMap;
28
+ this.toolRegistry = opts.toolRegistry;
29
+ this.workspacePath = opts.workspacePath || '';
30
+ this.mcp = opts.mcp || null;
31
+ this.mcpStatus = opts.mcpStatus || [];
32
+ }
33
+ async initAll() {
34
+ if (this.mcp) {
35
+ try {
36
+ this.mcpStatus = await this.mcp.connectAll();
37
+ if (this.mcpStatus.length > 0) {
38
+ log.info('mcp_connected', { servers: this.mcpStatus.join(', ') });
39
+ }
40
+ }
41
+ catch (e) {
42
+ log.warn('mcp_connect_all_failed', { error: String(e) });
43
+ }
44
+ }
45
+ for (const agent of this.agentMap.values()) {
46
+ await agent.init();
47
+ }
48
+ }
49
+ async closeAll() {
50
+ for (const agent of this.agentMap.values()) {
51
+ await agent.close();
52
+ }
53
+ if (this.mcp) {
54
+ try {
55
+ await this.mcp.closeAll();
56
+ }
57
+ catch (e) {
58
+ log.warn('mcp_close_failed', { error: String(e) });
59
+ }
60
+ }
61
+ }
62
+ }
63
+ exports.SystemContext = SystemContext;
64
+ /**
65
+ * Bootstrap the full system: config, bus, LLM, tools, skills, plugins, agents.
66
+ */
67
+ function createSystemContext() {
68
+ const config = (0, config_1.loadConfig)();
69
+ let workspacePath = '';
70
+ try {
71
+ const { resolveWorkspacePath, initWorkspace } = require('./workspace');
72
+ const wsRoot = resolveWorkspacePath(config.workspace?.path || 'auto');
73
+ initWorkspace(wsRoot);
74
+ workspacePath = wsRoot;
75
+ log.info('workspace', { path: workspacePath });
76
+ }
77
+ catch { /* ignore */ }
78
+ const bus = new bus_1.MessageBus();
79
+ // Shared registries
80
+ const baseToolRegistry = new tool_1.ToolRegistry();
81
+ const baseSkillRegistry = new skill_1.SkillRegistry();
82
+ // Register builtin tools
83
+ try {
84
+ const { registerBuiltinTools } = require('../tools/builtin');
85
+ registerBuiltinTools(baseToolRegistry);
86
+ }
87
+ catch (e) {
88
+ log.warn('builtin_tools_not_available', { error: String(e) });
89
+ }
90
+ // Register all skills
91
+ try {
92
+ const { registerAllSkills } = require('../skills/loader');
93
+ registerAllSkills(baseSkillRegistry);
94
+ }
95
+ catch (e) {
96
+ log.warn('skills_not_available', { error: String(e) });
97
+ }
98
+ // Load plugins
99
+ try {
100
+ const { PluginLoader } = require('../plugins/loader');
101
+ const pluginLoader = new PluginLoader(baseToolRegistry);
102
+ const pluginConfig = config.plugins;
103
+ const pluginDirs = pluginConfig?.enabled ? (pluginConfig.directories || []) : [];
104
+ pluginLoader.loadFromDirectories(pluginDirs);
105
+ }
106
+ catch (e) {
107
+ log.warn('plugins_not_available', { error: String(e) });
108
+ }
109
+ // Configure MCP manager
110
+ let mcpManager = null;
111
+ try {
112
+ const { MCPManager, loadPersistedServers } = require('./mcp');
113
+ mcpManager = new MCPManager(baseToolRegistry);
114
+ const persisted = loadPersistedServers();
115
+ const mcpServers = config.mcp?.servers || [];
116
+ const allServers = [...mcpServers, ...persisted];
117
+ if (allServers.length > 0) {
118
+ mcpManager.configure(allServers);
119
+ }
120
+ }
121
+ catch (e) {
122
+ log.warn('mcp_not_available', { error: String(e) });
123
+ }
124
+ // Shared LLM client
125
+ const llm = new llm_1.LLMClient(config, baseToolRegistry);
126
+ // Per-agent registries
127
+ const agents = new Map();
128
+ // Try to dynamically load agent classes
129
+ const agentNames = ['fog', 'rain', 'frost', 'snow', 'dew', 'fair'];
130
+ for (const name of agentNames) {
131
+ const agentRegistry = new tool_1.ToolRegistry();
132
+ agentRegistry.merge(baseToolRegistry);
133
+ const agentSkills = new skill_1.SkillRegistry();
134
+ agentSkills.merge(baseSkillRegistry);
135
+ try {
136
+ // Try dynamic import
137
+ const clsName = name.charAt(0).toUpperCase() + name.slice(1) + 'Agent';
138
+ // Use require for now since dynamic imports are async
139
+ let AgentClass = null;
140
+ try {
141
+ const mod = require(`../agents/${name}`);
142
+ AgentClass = mod[clsName];
143
+ }
144
+ catch {
145
+ log.warn('agent_class_missing', { agent: name });
146
+ continue;
147
+ }
148
+ if (!AgentClass) {
149
+ log.warn('agent_class_not_found', { agent: name, class: clsName });
150
+ continue;
151
+ }
152
+ const agent = new AgentClass(config, llm, bus, agentRegistry, agentSkills);
153
+ // Register delegate_to tool
154
+ try {
155
+ const { createDelegateTool } = require('../tools/delegate');
156
+ agentRegistry.register(createDelegateTool(agents, agent));
157
+ }
158
+ catch (e) {
159
+ log.warn('delegate_tool_not_available', { agent: name, error: String(e) });
160
+ }
161
+ agents.set(name, agent);
162
+ }
163
+ catch (e) {
164
+ log.warn('agent_creation_failed', { agent: name, error: String(e) });
165
+ }
166
+ }
167
+ // Bind agents to MCP
168
+ if (mcpManager) {
169
+ try {
170
+ mcpManager.bindAgents(agents);
171
+ }
172
+ catch (e) {
173
+ log.warn('mcp_bind_failed', { error: String(e) });
174
+ }
175
+ }
176
+ return new SystemContext({
177
+ config,
178
+ bus,
179
+ llm,
180
+ agentMap: agents,
181
+ toolRegistry: baseToolRegistry,
182
+ workspacePath,
183
+ mcp: mcpManager,
184
+ });
185
+ }
186
+ // ── Task orchestration ──
187
+ class TaskExecutionResult {
188
+ constructor(opts) {
189
+ this.id = opts.id;
190
+ this.agent = opts.agent;
191
+ this.description = opts.description;
192
+ this.success = opts.success;
193
+ this.content = opts.content;
194
+ }
195
+ }
196
+ exports.TaskExecutionResult = TaskExecutionResult;
197
+ // Placeholder phrases that mean the LLM gave up
198
+ const PLACEHOLDER_PATTERNS = [
199
+ 'done', 'ok', 'completed', 'task completed', 'task done', 'task finished',
200
+ 'finished', '已完成', '完成了', '好的', '好了', 'ok!',
201
+ ];
202
+ const STATUS_REPORT_KEYWORDS = [
203
+ '已完成', '完成了', '已成功', '已经完成', '工作已', '任务已',
204
+ 'task complete', 'task is complete', 'i have completed', "i've completed",
205
+ 'successfully completed', 'finished the', 'i finished',
206
+ '已经写好', '已经写完', '已经做好', '写完了', '做完了',
207
+ ];
208
+ const DELIVERABLE_MARKERS = [
209
+ '```', 'http://', 'https://', '|', '## ', '###', '- [ ]', '1.', '/', '\\',
210
+ ];
211
+ function isThinContent(content) {
212
+ if (!content)
213
+ return true;
214
+ const stripped = content.trim();
215
+ if (!stripped)
216
+ return true;
217
+ const lowered = stripped.toLowerCase();
218
+ if (lowered.startsWith('[truncated]') || lowered.startsWith('[error:'))
219
+ return true;
220
+ const bare = lowered.replace(/[.!?。!?\s]+$/, '').trim();
221
+ if (PLACEHOLDER_PATTERNS.includes(bare))
222
+ return true;
223
+ return (stripped.length <= 200 &&
224
+ STATUS_REPORT_KEYWORDS.some(k => lowered.includes(k)) &&
225
+ !DELIVERABLE_MARKERS.some(m => stripped.includes(m)));
226
+ }
227
+ const RESULT_FAILURE_MARKERS = [
228
+ '[truncated]', '[stuck]', '[Error', 'Error:',
229
+ '未能完成', '无法完成', '[cycle detected]', '[CircuitBreakerOpen]',
230
+ ];
231
+ function looksObviouslyComplete(results) {
232
+ if (!results.length)
233
+ return false;
234
+ return results.every(r => {
235
+ if (!r.success)
236
+ return false;
237
+ const body = (r.content || '').trim();
238
+ if (body.length < 400)
239
+ return false;
240
+ return !RESULT_FAILURE_MARKERS.some(m => body.includes(m));
241
+ });
242
+ }
243
+ async function executeWithRetry(agent, aTask, maxAttempts, onStatus) {
244
+ let lastResult = null;
245
+ const originalDescription = aTask.description;
246
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
247
+ try {
248
+ const result = await agent.executeTask(aTask, onStatus);
249
+ const content = (result.content || '').trim();
250
+ const truncated = result.truncated === true;
251
+ const ok = result.success && !isThinContent(content);
252
+ if (ok && !truncated)
253
+ return result;
254
+ lastResult = result;
255
+ if (attempt < maxAttempts) {
256
+ const reason = truncated
257
+ ? 'previous attempt was truncated'
258
+ : 'previous attempt was empty or a placeholder ack';
259
+ aTask.description = `${originalDescription}\n\n[retry ${attempt + 1}/${maxAttempts}] ${reason}. You MUST produce the actual deliverable.`;
260
+ }
261
+ }
262
+ catch (e) {
263
+ lastResult = { success: false, content: `Attempt ${attempt} threw: ${e}` };
264
+ }
265
+ if (attempt < maxAttempts) {
266
+ await new Promise(r => setTimeout(r, Math.min(500 * Math.pow(2, attempt - 1), 2000)));
267
+ }
268
+ }
269
+ aTask.description = originalDescription;
270
+ return lastResult || { success: false, content: `All ${maxAttempts} attempts failed` };
271
+ }
272
+ async function executePending(pending, agentMap, results, resultsById, fullContentsById, completed, options) {
273
+ while (pending.length > 0) {
274
+ const ready = pending.filter(t => t.allDeps.every((dep) => completed.has(dep)));
275
+ if (ready.length === 0) {
276
+ for (const t of pending) {
277
+ const missing = t.allDeps.filter((d) => !completed.has(d));
278
+ t.transitionTo(agent_1.TaskState.FAILED);
279
+ const r = new TaskExecutionResult({
280
+ id: t.id, agent: t.assignedTo || '',
281
+ description: t.description, success: false,
282
+ content: `[dependency missing] task ${t.id} requires ${missing.join(', ')} which never completed`,
283
+ });
284
+ results.push(r);
285
+ resultsById.set(r.id, r);
286
+ completed.add(r.id);
287
+ if (options.onTaskDone)
288
+ await options.onTaskDone(t, r);
289
+ }
290
+ pending.length = 0;
291
+ return;
292
+ }
293
+ for (const t of ready)
294
+ t.transitionTo(agent_1.TaskState.RUNNING);
295
+ const batchResults = await Promise.all(ready.map(async (t) => {
296
+ const agent = agentMap.get(t.assignedTo);
297
+ if (!agent) {
298
+ return new TaskExecutionResult({
299
+ id: t.id, agent: t.assignedTo || '',
300
+ description: t.description, success: false,
301
+ content: `Agent '${t.assignedTo}' not found`,
302
+ });
303
+ }
304
+ if (options.onTaskStart)
305
+ await options.onTaskStart(t);
306
+ let description = t.description;
307
+ const upstreamSections = [];
308
+ const thinUpstreamIds = [];
309
+ for (const depId of t.allDeps) {
310
+ if (resultsById.has(depId)) {
311
+ const parent = resultsById.get(depId);
312
+ const fullContent = fullContentsById.get(depId) || parent.content || '';
313
+ if (isThinContent(fullContent)) {
314
+ thinUpstreamIds.push(parent.id);
315
+ upstreamSections.push(`## 上游产出缺失 (task ${parent.id} · ${parent.agent})\n` +
316
+ `⚠ 上游任务声称完成但未产出实际内容。\n` +
317
+ `原始回复:\n${fullContent}`);
318
+ }
319
+ else {
320
+ upstreamSections.push(`## 上游产出 (task ${parent.id} · ${parent.agent})\n${fullContent}`);
321
+ }
322
+ }
323
+ }
324
+ if (upstreamSections.length > 0) {
325
+ description = `${t.description}\n\n${upstreamSections.join('\n\n')}`;
326
+ }
327
+ if (thinUpstreamIds.length > 0) {
328
+ log.warn('thin_upstream', { task: t.id, thin_upstream: thinUpstreamIds });
329
+ }
330
+ const aTask = new agent_1.Task({
331
+ id: t.id,
332
+ description,
333
+ assignedTo: t.assignedTo,
334
+ parentId: t.parentId,
335
+ metadata: t.metadata,
336
+ });
337
+ const result = await executeWithRetry(agent, aTask, options.maxTaskRetries, options.onToolStatus);
338
+ if (result.success)
339
+ t.transitionTo(agent_1.TaskState.COMPLETED);
340
+ else
341
+ t.transitionTo(agent_1.TaskState.FAILED);
342
+ const full = result.content || '';
343
+ fullContentsById.set(t.id, full);
344
+ const tr = options.resultTruncate != null && full.length > options.resultTruncate
345
+ ? full.slice(0, options.resultTruncate) : full;
346
+ const r = new TaskExecutionResult({
347
+ id: t.id, agent: t.assignedTo || '',
348
+ description: t.description, success: result.success,
349
+ content: tr,
350
+ });
351
+ if (options.onTaskDone)
352
+ await options.onTaskDone(t, r);
353
+ return r;
354
+ }));
355
+ for (const r of batchResults) {
356
+ results.push(r);
357
+ resultsById.set(r.id, r);
358
+ completed.add(r.id);
359
+ }
360
+ for (const t of ready) {
361
+ const idx = pending.indexOf(t);
362
+ if (idx >= 0)
363
+ pending.splice(idx, 1);
364
+ }
365
+ }
366
+ }
367
+ async function judgeGoalAchievement(snow, goal, results) {
368
+ const bullets = results.map(r => {
369
+ const status = r.success ? '成功' : '失败';
370
+ const excerpt = (r.content || '').slice(0, 800);
371
+ return `- [task ${r.id} · agent=${r.agent} · status=${status}] len=${(r.content || '').length}chars\n ${excerpt}`;
372
+ }).join('\n');
373
+ const prompt = `你是一名极严格的项目验收员。验证 sub-task 真的产出了可验证的交付物。
374
+
375
+ ## 验收规则(严格执行)
376
+
377
+ 1. **「调研/搜集/查询」类**:必须列出具体对象名称和数据/特性/链接。
378
+ 2. **「撰写/生成/写作」类**:必须包含实际的文本/代码/markdown。
379
+ 3. **「审查/审计/对比」类**:必须列出具体问题点。
380
+ 4. **核心交付物缺失绝不容忍**。
381
+
382
+ ## 用户原目标
383
+ ${goal}
384
+
385
+ ## 子任务执行结果
386
+ ${bullets}
387
+
388
+ 严格按下列 JSON 格式输出(除 JSON 之外不要任何其他字符):
389
+ {"achieved": true/false, "missing": "若未达成,逐项列出缺什么"}`;
390
+ try {
391
+ const raw = await snow.chatOneshot(prompt);
392
+ let text = raw.trim();
393
+ if (text.startsWith('```')) {
394
+ text = text.replace(/```/g, '').replace(/^json/i, '').trim();
395
+ }
396
+ const start = text.indexOf('{');
397
+ const end = text.lastIndexOf('}');
398
+ if (start < 0 || end <= start)
399
+ return [true, ''];
400
+ const parsed = JSON.parse(text.slice(start, end + 1));
401
+ return [!!parsed.achieved, (parsed.missing || '').trim()];
402
+ }
403
+ catch {
404
+ return [true, ''];
405
+ }
406
+ }
407
+ async function orchestrateTask(goal, agentMap, snow = null, options) {
408
+ const snowAgent = snow || agentMap.get('snow') || null;
409
+ if (!snowAgent) {
410
+ return [[], [], 'Snow agent not available'];
411
+ }
412
+ const maxTaskRetries = options?.maxTaskRetries ?? 3;
413
+ const maxReplanRounds = options?.maxReplanRounds ?? 1;
414
+ const maxTotalTasks = options?.maxTotalTasks ?? 6;
415
+ const resultTruncate = options?.resultTruncate ?? 500;
416
+ // Try pipeline match first
417
+ let tasks;
418
+ try {
419
+ const { matchPipeline, buildTasksFromPipeline } = require('./pipelines');
420
+ const matched = matchPipeline(goal);
421
+ if (matched) {
422
+ tasks = buildTasksFromPipeline(matched, goal);
423
+ }
424
+ else {
425
+ tasks = await snowAgent.orchestrate(goal);
426
+ }
427
+ }
428
+ catch {
429
+ tasks = await snowAgent.orchestrate(goal);
430
+ }
431
+ if (!tasks || tasks.length === 0) {
432
+ return [[], [], 'No tasks were planned'];
433
+ }
434
+ // Notify caller of the plan
435
+ if (options?.onPlanned) {
436
+ const proceed = await options.onPlanned(tasks);
437
+ if (proceed === false) {
438
+ return [tasks, [], '[CANCELLED] plan rejected before execution'];
439
+ }
440
+ }
441
+ const completed = new Set();
442
+ const results = [];
443
+ const resultsById = new Map();
444
+ const fullContentsById = new Map();
445
+ let pending = tasks.filter((t) => t.assignedTo && t.assignedTo !== 'snow');
446
+ let replanRound = 0;
447
+ // Cycle detection
448
+ function hasCycle(t, path) {
449
+ if (path.has(t.id))
450
+ return true;
451
+ path.add(t.id);
452
+ for (const depId of t.allDeps || []) {
453
+ const dep = tasks.find((x) => x.id === depId);
454
+ if (dep && hasCycle(dep, new Set(path)))
455
+ return true;
456
+ }
457
+ return false;
458
+ }
459
+ pending = pending.filter((t) => {
460
+ if (hasCycle(t, new Set())) {
461
+ results.push(new TaskExecutionResult({
462
+ id: t.id, agent: t.assignedTo || '',
463
+ description: t.description, success: false,
464
+ content: `[cycle detected] task ${t.id} has circular dependency`,
465
+ }));
466
+ completed.add(t.id);
467
+ return false;
468
+ }
469
+ return true;
470
+ });
471
+ while (true) {
472
+ await executePending(pending, agentMap, results, resultsById, fullContentsById, completed, {
473
+ onTaskStart: options?.onTaskStart || null,
474
+ onTaskDone: options?.onTaskDone || null,
475
+ onToolStatus: options?.onToolStatus || null,
476
+ resultTruncate,
477
+ maxTaskRetries,
478
+ });
479
+ pending = [];
480
+ if (!results.length || replanRound >= maxReplanRounds)
481
+ break;
482
+ if (results.length === 1 && results[0].success)
483
+ break;
484
+ if (looksObviouslyComplete(results))
485
+ break;
486
+ const [achieved, missing] = await judgeGoalAchievement(snowAgent, goal, results);
487
+ if (achieved)
488
+ break;
489
+ replanRound++;
490
+ try {
491
+ const extraTasks = await snowAgent.replanForMissing(goal, results, missing, new Set(tasks.map((t) => t.id)));
492
+ if (!extraTasks || extraTasks.length === 0)
493
+ break;
494
+ if (tasks.length + extraTasks.length > maxTotalTasks)
495
+ break;
496
+ tasks.push(...extraTasks);
497
+ if (options?.onPlanned) {
498
+ const proceed = await options.onPlanned(tasks);
499
+ if (proceed === false)
500
+ break;
501
+ }
502
+ pending = extraTasks.filter((t) => t.assignedTo && t.assignedTo !== 'snow');
503
+ }
504
+ catch {
505
+ break;
506
+ }
507
+ }
508
+ // Generate summary
509
+ let summary;
510
+ if (!results.length) {
511
+ summary = '没有需要执行的任务。';
512
+ }
513
+ else if (results.length === 1) {
514
+ summary = results[0].content;
515
+ }
516
+ else {
517
+ const tpl = options?.summaryPromptTemplate || '请汇总以下所有子任务的执行结果:\n\n';
518
+ let summaryPrompt = tpl;
519
+ for (const r of results) {
520
+ const status = r.success ? '成功' : '失败';
521
+ summaryPrompt += `### 任务 ${r.id} (${r.agent}) - ${status}\n${(r.content || '').slice(0, 300)}\n\n`;
522
+ }
523
+ summary = await snowAgent.chatOneshot(summaryPrompt);
524
+ }
525
+ // Check if we hit the replan budget without full completion
526
+ if (replanRound >= maxReplanRounds && results.length > 1) {
527
+ try {
528
+ const [achieved, missing] = await judgeGoalAchievement(snowAgent, goal, results);
529
+ if (!achieved && missing) {
530
+ summary = `[INCOMPLETE] 经过 ${maxReplanRounds + 1} 轮规划仍未完全达成目标。\n剩余缺口:${missing}\n\n${summary}`;
531
+ }
532
+ }
533
+ catch { /* ignore */ }
534
+ }
535
+ return [tasks, results, summary];
536
+ }
537
+ //# sourceMappingURL=factory.js.map