taskmeld 0.1.1

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 (204) hide show
  1. package/LICENSE +18 -0
  2. package/README.md +172 -0
  3. package/README.zh-CN.md +172 -0
  4. package/dist/src/app/app-context-env.js +51 -0
  5. package/dist/src/app/create-app-context.js +127 -0
  6. package/dist/src/app/data-dir.js +29 -0
  7. package/dist/src/app/pipeline-config.js +105 -0
  8. package/dist/src/app/pipeline-plugin-config.js +2 -0
  9. package/dist/src/app/pipeline-registry.js +502 -0
  10. package/dist/src/app/pipeline-runtime.js +202 -0
  11. package/dist/src/app/runtime-store.js +151 -0
  12. package/dist/src/app/user-config.js +37 -0
  13. package/dist/src/artifacts/artifact-cleanup.js +192 -0
  14. package/dist/src/artifacts/artifact-index.js +262 -0
  15. package/dist/src/artifacts/artifact-rebuilder.js +120 -0
  16. package/dist/src/artifacts/storage-service.js +371 -0
  17. package/dist/src/cli/bootstrap.js +226 -0
  18. package/dist/src/cli/commands/agent.js +126 -0
  19. package/dist/src/cli/commands/artifact.js +175 -0
  20. package/dist/src/cli/commands/init.js +150 -0
  21. package/dist/src/cli/commands/pipeline/errors.js +37 -0
  22. package/dist/src/cli/commands/pipeline/result.js +179 -0
  23. package/dist/src/cli/commands/pipeline/selector.js +51 -0
  24. package/dist/src/cli/commands/pipeline/types.js +2 -0
  25. package/dist/src/cli/commands/pipeline/watch.js +67 -0
  26. package/dist/src/cli/commands/pipeline.js +339 -0
  27. package/dist/src/cli/commands/scheduler.js +81 -0
  28. package/dist/src/cli/commands/server.js +70 -0
  29. package/dist/src/cli/commands/system.js +21 -0
  30. package/dist/src/cli/errors.js +71 -0
  31. package/dist/src/cli/help.js +184 -0
  32. package/dist/src/cli/index.js +65 -0
  33. package/dist/src/cli/output.js +19 -0
  34. package/dist/src/cli/renderers/engine/json.js +67 -0
  35. package/dist/src/cli/renderers/engine/markdown.js +95 -0
  36. package/dist/src/cli/renderers/engine/types.js +2 -0
  37. package/dist/src/cli/renderers/engine/utils.js +32 -0
  38. package/dist/src/cli/renderers/index.js +27 -0
  39. package/dist/src/cli/renderers/specs/agent.js +78 -0
  40. package/dist/src/cli/renderers/specs/artifact.js +32 -0
  41. package/dist/src/cli/renderers/specs/index.js +36 -0
  42. package/dist/src/cli/renderers/specs/init.js +25 -0
  43. package/dist/src/cli/renderers/specs/pipeline.js +561 -0
  44. package/dist/src/cli/renderers/specs/scheduler.js +46 -0
  45. package/dist/src/cli/renderers/specs/server.js +38 -0
  46. package/dist/src/cli/renderers/specs/system.js +36 -0
  47. package/dist/src/cli/router.js +199 -0
  48. package/dist/src/cli/server-runtime-client.js +780 -0
  49. package/dist/src/cli/types.js +2 -0
  50. package/dist/src/gateway/frame-sanitizer.js +78 -0
  51. package/dist/src/gateway/gateway-client.js +462 -0
  52. package/dist/src/gateway/index.js +18 -0
  53. package/dist/src/gateway/types.js +2 -0
  54. package/dist/src/index.js +123 -0
  55. package/dist/src/logs/run-log-reader.js +141 -0
  56. package/dist/src/logs/run-log-service.js +42 -0
  57. package/dist/src/logs/run-log-types.js +2 -0
  58. package/dist/src/pipeline/agent-activity.js +191 -0
  59. package/dist/src/pipeline/artifact-storage.js +208 -0
  60. package/dist/src/pipeline/diagnostics/dependency-diagnostic.js +105 -0
  61. package/dist/src/pipeline/diagnostics/index.js +6 -0
  62. package/dist/src/pipeline/dispatch/pipeline-inbound-queue.js +215 -0
  63. package/dist/src/pipeline/dispatch/pipeline-link-dispatcher.js +66 -0
  64. package/dist/src/pipeline/dispatch/pipeline-link-store.js +94 -0
  65. package/dist/src/pipeline/dispatch/pipeline-queue-drainer.js +71 -0
  66. package/dist/src/pipeline/execution/dependency-check.js +52 -0
  67. package/dist/src/pipeline/execution/execution-result.js +2 -0
  68. package/dist/src/pipeline/execution/group-item-executor.js +128 -0
  69. package/dist/src/pipeline/execution/index.js +5 -0
  70. package/dist/src/pipeline/execution/node-item-executor.js +58 -0
  71. package/dist/src/pipeline/execution/node-runner.js +159 -0
  72. package/dist/src/pipeline/execution/readiness-state.js +10 -0
  73. package/dist/src/pipeline/execution/reject-handler.js +94 -0
  74. package/dist/src/pipeline/execution/rejected-artifact-archiver.js +45 -0
  75. package/dist/src/pipeline/execution/route-item-manager.js +253 -0
  76. package/dist/src/pipeline/execution/run-abort-controller.js +66 -0
  77. package/dist/src/pipeline/execution/run-state-helpers.js +257 -0
  78. package/dist/src/pipeline/execution/service.js +165 -0
  79. package/dist/src/pipeline/execution/session-registry.js +96 -0
  80. package/dist/src/pipeline/execution/structured-node-runner.js +411 -0
  81. package/dist/src/pipeline/execution-status.js +96 -0
  82. package/dist/src/pipeline/execution-timeout.js +21 -0
  83. package/dist/src/pipeline/identity/index.js +32 -0
  84. package/dist/src/pipeline/identity/types.js +2 -0
  85. package/dist/src/pipeline/item-batch-controller.js +227 -0
  86. package/dist/src/pipeline/output/pipeline-output-resolver.js +91 -0
  87. package/dist/src/pipeline/output/pipeline-output-store.js +60 -0
  88. package/dist/src/pipeline/runtime-model.js +173 -0
  89. package/dist/src/pipeline/scheduler/dependency-state.js +144 -0
  90. package/dist/src/pipeline/scheduler-service.js +314 -0
  91. package/dist/src/pipeline/state/group-item-state.js +50 -0
  92. package/dist/src/pipeline/state/group-run-state.js +41 -0
  93. package/dist/src/pipeline/state/index.js +20 -0
  94. package/dist/src/pipeline/state/node-item-state.js +67 -0
  95. package/dist/src/pipeline/state/node-run-state.js +51 -0
  96. package/dist/src/pipeline/state/types.js +2 -0
  97. package/dist/src/pipeline/state-machine.js +101 -0
  98. package/dist/src/pipeline/structured-output/contract.js +133 -0
  99. package/dist/src/pipeline/structured-output/index.js +22 -0
  100. package/dist/src/pipeline/structured-output/parser.js +214 -0
  101. package/dist/src/pipeline/structured-output/prompt.js +290 -0
  102. package/dist/src/pipeline/structured-output/waiter.js +139 -0
  103. package/dist/src/pipeline/template.js +135 -0
  104. package/dist/src/pipeline/timeline-log-store.js +57 -0
  105. package/dist/src/pipeline/tool-activity.js +94 -0
  106. package/dist/src/pipeline/types/pipeline-link.js +7 -0
  107. package/dist/src/pipeline/types/pipeline-output.js +11 -0
  108. package/dist/src/pipeline/types/workflow.js +2 -0
  109. package/dist/src/pipeline/workflow/branch-rules.js +74 -0
  110. package/dist/src/pipeline/workflow/defaults.js +48 -0
  111. package/dist/src/pipeline/workflow/io.js +89 -0
  112. package/dist/src/pipeline/workflow/normalize.js +347 -0
  113. package/dist/src/pipeline/workflow/routes.js +16 -0
  114. package/dist/src/pipeline/workflow/template-mapper.js +113 -0
  115. package/dist/src/pipeline/workflow/validate.js +312 -0
  116. package/dist/src/pipeline/workflow-graph.js +165 -0
  117. package/dist/src/server/api-handler.js +163 -0
  118. package/dist/src/server/http-utils.js +34 -0
  119. package/dist/src/server/middleware.js +61 -0
  120. package/dist/src/server/router.js +105 -0
  121. package/dist/src/server/routes/agents.js +189 -0
  122. package/dist/src/server/routes/artifacts.js +163 -0
  123. package/dist/src/server/routes/gateway.js +18 -0
  124. package/dist/src/server/routes/health.js +16 -0
  125. package/dist/src/server/routes/logs.js +73 -0
  126. package/dist/src/server/routes/pipeline-batch.js +163 -0
  127. package/dist/src/server/routes/pipeline-diagnostics.js +33 -0
  128. package/dist/src/server/routes/pipeline-identity.js +24 -0
  129. package/dist/src/server/routes/pipeline-links.js +117 -0
  130. package/dist/src/server/routes/pipeline-outputs.js +27 -0
  131. package/dist/src/server/routes/pipeline-queue.js +62 -0
  132. package/dist/src/server/routes/pipeline-runtime.js +162 -0
  133. package/dist/src/server/routes/pipeline-scheduler.js +69 -0
  134. package/dist/src/server/routes/pipeline-workflow.js +180 -0
  135. package/dist/src/server/routes/pipelines.js +96 -0
  136. package/dist/src/server/routes/sessions.js +244 -0
  137. package/dist/src/server/routes/timeline.js +14 -0
  138. package/dist/src/server/serve-static.js +42 -0
  139. package/dist/src/server/types.js +2 -0
  140. package/dist/src/services/agent-service.js +79 -0
  141. package/dist/src/services/artifact-service.js +74 -0
  142. package/dist/src/services/gateway-read-helpers.js +10 -0
  143. package/dist/src/services/index.js +23 -0
  144. package/dist/src/services/pipeline-service.js +529 -0
  145. package/dist/src/services/pipeline-status.js +93 -0
  146. package/dist/src/services/read-services.js +60 -0
  147. package/dist/src/services/scheduler-service.js +37 -0
  148. package/dist/src/services/session-service.js +227 -0
  149. package/dist/src/services/system-service.js +26 -0
  150. package/dist/src/transport/ws-broker.js +48 -0
  151. package/dist/src/utils/array.js +17 -0
  152. package/dist/src/utils/guards.js +5 -0
  153. package/dist/src/utils/session.js +60 -0
  154. package/dist/src/version.js +5 -0
  155. package/package.json +61 -0
  156. package/web/dist/assets/index-CWnfhkn-.js +65 -0
  157. package/web/dist/assets/index-gZ0xOfSO.css +1 -0
  158. package/web/dist/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
  159. package/web/dist/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
  160. package/web/dist/assets/jetbrains-mono-cyrillic-500-normal-DJqRU3vO.woff +0 -0
  161. package/web/dist/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2 +0 -0
  162. package/web/dist/assets/jetbrains-mono-cyrillic-700-normal-BWTpRfYl.woff2 +0 -0
  163. package/web/dist/assets/jetbrains-mono-cyrillic-700-normal-CEoEElIJ.woff +0 -0
  164. package/web/dist/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
  165. package/web/dist/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
  166. package/web/dist/assets/jetbrains-mono-greek-500-normal-D7SFKleX.woff +0 -0
  167. package/web/dist/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2 +0 -0
  168. package/web/dist/assets/jetbrains-mono-greek-700-normal-C6CZE3T8.woff2 +0 -0
  169. package/web/dist/assets/jetbrains-mono-greek-700-normal-DEigVDxa.woff +0 -0
  170. package/web/dist/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  171. package/web/dist/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  172. package/web/dist/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  173. package/web/dist/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
  174. package/web/dist/assets/jetbrains-mono-latin-700-normal-BYuf6tUa.woff2 +0 -0
  175. package/web/dist/assets/jetbrains-mono-latin-700-normal-D3wTyLJW.woff +0 -0
  176. package/web/dist/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
  177. package/web/dist/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
  178. package/web/dist/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2 +0 -0
  179. package/web/dist/assets/jetbrains-mono-latin-ext-500-normal-ckzbgY84.woff +0 -0
  180. package/web/dist/assets/jetbrains-mono-latin-ext-700-normal-CZipNAKV.woff2 +0 -0
  181. package/web/dist/assets/jetbrains-mono-latin-ext-700-normal-CxPITLHs.woff +0 -0
  182. package/web/dist/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
  183. package/web/dist/assets/jetbrains-mono-vietnamese-500-normal-DNRqzVM1.woff +0 -0
  184. package/web/dist/assets/jetbrains-mono-vietnamese-700-normal-BDLVIk2r.woff +0 -0
  185. package/web/dist/assets/space-grotesk-latin-400-normal-BnQMeOim.woff +0 -0
  186. package/web/dist/assets/space-grotesk-latin-400-normal-CJ-V5oYT.woff2 +0 -0
  187. package/web/dist/assets/space-grotesk-latin-500-normal-CNSSEhBt.woff +0 -0
  188. package/web/dist/assets/space-grotesk-latin-500-normal-lFbtlQH6.woff2 +0 -0
  189. package/web/dist/assets/space-grotesk-latin-700-normal-CwsQ-cCU.woff +0 -0
  190. package/web/dist/assets/space-grotesk-latin-700-normal-RjhwGPKo.woff2 +0 -0
  191. package/web/dist/assets/space-grotesk-latin-ext-400-normal-CfP_5XZW.woff2 +0 -0
  192. package/web/dist/assets/space-grotesk-latin-ext-400-normal-DRPE3kg4.woff +0 -0
  193. package/web/dist/assets/space-grotesk-latin-ext-500-normal-3dgZTiw9.woff +0 -0
  194. package/web/dist/assets/space-grotesk-latin-ext-500-normal-DUe3BAxM.woff2 +0 -0
  195. package/web/dist/assets/space-grotesk-latin-ext-700-normal-BQnZhY3m.woff2 +0 -0
  196. package/web/dist/assets/space-grotesk-latin-ext-700-normal-HVCqSBdx.woff +0 -0
  197. package/web/dist/assets/space-grotesk-vietnamese-400-normal-B7xT_GF5.woff2 +0 -0
  198. package/web/dist/assets/space-grotesk-vietnamese-400-normal-BIWiOVfw.woff +0 -0
  199. package/web/dist/assets/space-grotesk-vietnamese-500-normal-BTqKIpxg.woff +0 -0
  200. package/web/dist/assets/space-grotesk-vietnamese-500-normal-BmEvtly_.woff2 +0 -0
  201. package/web/dist/assets/space-grotesk-vietnamese-700-normal-DMty7AZE.woff2 +0 -0
  202. package/web/dist/assets/space-grotesk-vietnamese-700-normal-Duxec5Rn.woff +0 -0
  203. package/web/dist/favicon.svg +10 -0
  204. package/web/dist/index.html +14 -0
@@ -0,0 +1,244 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerSessionsRoutes = void 0;
4
+ const http_utils_js_1 = require("../http-utils.js");
5
+ const asRecord = (value) => value && typeof value === "object" && !Array.isArray(value)
6
+ ? value
7
+ : null;
8
+ const pickString = (record, keys) => {
9
+ for (const key of keys) {
10
+ const raw = record[key];
11
+ if (typeof raw === "string" && raw.trim())
12
+ return raw.trim();
13
+ }
14
+ return null;
15
+ };
16
+ const readModelInfo = (value) => {
17
+ const direct = asRecord(value);
18
+ if (!direct)
19
+ return { model: null, modelProvider: null, api: null };
20
+ const nestedSession = asRecord(direct.session);
21
+ const nestedMeta = asRecord(direct.meta);
22
+ const model = pickString(direct, ["model", "modelName"]) ??
23
+ (nestedSession
24
+ ? pickString(nestedSession, ["model", "modelName"])
25
+ : null) ??
26
+ (nestedMeta
27
+ ? pickString(nestedMeta, ["model", "modelName"])
28
+ : null);
29
+ const modelProvider = pickString(direct, ["modelProvider", "provider", "model_provider"]) ??
30
+ (nestedSession
31
+ ? pickString(nestedSession, [
32
+ "modelProvider",
33
+ "provider",
34
+ "model_provider",
35
+ ])
36
+ : null) ??
37
+ (nestedMeta
38
+ ? pickString(nestedMeta, ["modelProvider", "provider", "model_provider"])
39
+ : null);
40
+ const api = pickString(direct, ["api", "apiType"]) ??
41
+ (nestedSession
42
+ ? pickString(nestedSession, ["api", "apiType"])
43
+ : null) ??
44
+ (nestedMeta ? pickString(nestedMeta, ["api", "apiType"]) : null);
45
+ return { model, modelProvider, api };
46
+ };
47
+ const mergeModelInfo = (preferred, fallback) => ({
48
+ model: preferred.model ?? fallback.model,
49
+ modelProvider: preferred.modelProvider ?? fallback.modelProvider,
50
+ api: preferred.api ?? fallback.api,
51
+ });
52
+ const registerSessionsRoutes = (router) => {
53
+ router.register("GET", "/api/sessions", async (ctx) => {
54
+ const services = ctx.services;
55
+ try {
56
+ const { payload, items } = await services.refreshSessionsFromGateway();
57
+ ctx.sendJson(200, { items, raw: payload });
58
+ }
59
+ catch (error) {
60
+ ctx.sendJson(503, { error: String(error) });
61
+ }
62
+ });
63
+ router.register("GET", "/api/sessions/:sessionId/history", async (ctx) => {
64
+ const services = ctx.services;
65
+ try {
66
+ const sessionId = ctx.params.sessionId;
67
+ if (!sessionId) {
68
+ ctx.sendJson(400, { error: "invalid_session_id" });
69
+ return;
70
+ }
71
+ const limitRaw = Number(ctx.url.searchParams.get("limit") ?? 200);
72
+ const limit = Number.isFinite(limitRaw) && limitRaw > 0
73
+ ? Math.min(500, Math.floor(limitRaw))
74
+ : 200;
75
+ const payload = await services.client.sendReq("chat.history", {
76
+ sessionKey: sessionId,
77
+ limit,
78
+ });
79
+ const raw = (payload ?? {});
80
+ const rawItems = Array.isArray(raw.items)
81
+ ? raw.items
82
+ : Array.isArray(raw.messages)
83
+ ? raw.messages
84
+ : Array.isArray(raw.history)
85
+ ? raw.history
86
+ : Array.isArray(payload)
87
+ ? payload
88
+ : [];
89
+ const latestAssistant = [...rawItems]
90
+ .reverse()
91
+ .find((item) => String((asRecord(item) ?? {}).role ?? "").toLowerCase() === "assistant");
92
+ const latestModelInfo = readModelInfo(latestAssistant);
93
+ let sessionModelInfo = {
94
+ model: null,
95
+ modelProvider: null,
96
+ api: null,
97
+ };
98
+ try {
99
+ const { items } = await services.refreshSessionsFromGateway();
100
+ const matched = items.find((session) => session.id === sessionId);
101
+ sessionModelInfo = readModelInfo(matched?.raw);
102
+ }
103
+ catch {
104
+ // 即使 sessions.list 暂时不可用,仍保持 history 端点可用
105
+ }
106
+ const mergedInfo = mergeModelInfo(latestModelInfo, sessionModelInfo);
107
+ const items = rawItems.map((item) => {
108
+ const rec = asRecord(item);
109
+ if (!rec)
110
+ return item;
111
+ const role = String(rec.role ?? "").toLowerCase();
112
+ if (role !== "assistant")
113
+ return item;
114
+ const itemModelInfo = mergeModelInfo(readModelInfo(rec), mergedInfo);
115
+ return {
116
+ ...rec,
117
+ model: rec.model ?? itemModelInfo.model,
118
+ modelProvider: rec.modelProvider ??
119
+ rec.provider ??
120
+ itemModelInfo.modelProvider,
121
+ provider: rec.provider ??
122
+ rec.modelProvider ??
123
+ itemModelInfo.modelProvider,
124
+ api: rec.api ?? itemModelInfo.api,
125
+ };
126
+ });
127
+ ctx.sendJson(200, {
128
+ items,
129
+ raw: payload,
130
+ limit,
131
+ model: mergedInfo.model,
132
+ modelProvider: mergedInfo.modelProvider,
133
+ api: mergedInfo.api,
134
+ });
135
+ }
136
+ catch (error) {
137
+ ctx.sendJson(503, { error: String(error) });
138
+ }
139
+ });
140
+ router.register("POST", "/api/sessions", async (ctx) => {
141
+ const services = ctx.services;
142
+ try {
143
+ const body = await ctx.readBody();
144
+ const payload = await services.client.sendReq("sessions.create", body, { sideEffect: true });
145
+ ctx.sendJson(200, { item: payload ?? null });
146
+ }
147
+ catch (error) {
148
+ ctx.sendJson(500, { error: String(error) });
149
+ }
150
+ });
151
+ router.register("POST", "/api/sessions/:sessionId/send", async (ctx) => {
152
+ const services = ctx.services;
153
+ try {
154
+ const sessionId = ctx.params.sessionId;
155
+ if (!sessionId) {
156
+ ctx.sendJson(400, { error: "invalid_session_id" });
157
+ return;
158
+ }
159
+ const body = await ctx.readBody();
160
+ const text = (0, http_utils_js_1.firstText)(body);
161
+ const mode = String(body.mode ?? "auto");
162
+ if (!text) {
163
+ ctx.sendJson(400, { error: "message_required" });
164
+ return;
165
+ }
166
+ const attempts = [];
167
+ const chatAttempts = [
168
+ {
169
+ method: "chat.send",
170
+ params: { sessionKey: sessionId, message: text },
171
+ },
172
+ ];
173
+ const sessionsAttempts = [
174
+ {
175
+ method: "sessions.send",
176
+ params: { key: sessionId, message: text },
177
+ },
178
+ ];
179
+ if (mode === "chat") {
180
+ attempts.push(...chatAttempts);
181
+ }
182
+ else if (mode === "sessions") {
183
+ attempts.push(...sessionsAttempts);
184
+ }
185
+ else {
186
+ attempts.push(...chatAttempts, ...sessionsAttempts);
187
+ }
188
+ let payload = null;
189
+ let lastError = null;
190
+ const attemptErrors = [];
191
+ let usedMethod = null;
192
+ let usedParams = null;
193
+ for (const attempt of attempts) {
194
+ try {
195
+ payload = await services.client.sendReq(attempt.method, attempt.params, { sideEffect: true });
196
+ usedMethod = attempt.method;
197
+ usedParams = attempt.params;
198
+ services.pushTimeline(`会话消息发送成功: ${sessionId} (${attempt.method})`);
199
+ break;
200
+ }
201
+ catch (error) {
202
+ lastError = error;
203
+ attemptErrors.push(`${attempt.method}: ${String(error)}`);
204
+ }
205
+ }
206
+ if (payload === null) {
207
+ ctx.sendJson(500, {
208
+ error: String(lastError ?? "sessions_send_failed"),
209
+ attempts: attemptErrors,
210
+ mode,
211
+ });
212
+ return;
213
+ }
214
+ let sessionModelInfo = {
215
+ model: null,
216
+ modelProvider: null,
217
+ api: null,
218
+ };
219
+ try {
220
+ const { items } = await services.refreshSessionsFromGateway();
221
+ const matched = items.find((session) => session.id === sessionId);
222
+ sessionModelInfo = readModelInfo(matched?.raw);
223
+ }
224
+ catch {
225
+ // 即使 sessions.list 刷新失败,仍保持 send 路径可用
226
+ }
227
+ const usedModelInfo = mergeModelInfo(readModelInfo(payload), sessionModelInfo);
228
+ ctx.sendJson(200, {
229
+ item: payload ?? null,
230
+ mode,
231
+ usedMethod,
232
+ usedParams,
233
+ model: usedModelInfo.model,
234
+ modelProvider: usedModelInfo.modelProvider,
235
+ api: usedModelInfo.api,
236
+ });
237
+ }
238
+ catch (error) {
239
+ services.pushTimeline(`会话消息发送失败: ${String(error)}`, "error");
240
+ ctx.sendJson(500, { error: String(error) });
241
+ }
242
+ });
243
+ };
244
+ exports.registerSessionsRoutes = registerSessionsRoutes;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerTimelineRoutes = void 0;
4
+ /**
5
+ * 注册 GET /api/timeline 路由。
6
+ * 返回合并后的全流水线时间线记录。
7
+ */
8
+ const registerTimelineRoutes = (router) => {
9
+ router.register("GET", "/api/timeline", (ctx) => {
10
+ const services = ctx.services;
11
+ ctx.sendJson(200, { items: services.getTimeline() });
12
+ });
13
+ };
14
+ exports.registerTimelineRoutes = registerTimelineRoutes;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.serveStatic = void 0;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ const MIME = {
7
+ ".html": "text/html; charset=utf-8",
8
+ ".css": "text/css; charset=utf-8",
9
+ ".js": "application/javascript; charset=utf-8",
10
+ ".json": "application/json; charset=utf-8",
11
+ ".svg": "image/svg+xml",
12
+ ".png": "image/png",
13
+ ".ico": "image/x-icon",
14
+ ".woff": "font/woff",
15
+ ".woff2": "font/woff2",
16
+ };
17
+ const resolveWebDist = () => {
18
+ // dist/src/server/serve-static.js → ../../../web/dist
19
+ return (0, node_path_1.join)(__dirname, "..", "..", "..", "web", "dist");
20
+ };
21
+ const webDistRoot = resolveWebDist();
22
+ const serveStatic = (req, res) => {
23
+ if (!(0, node_fs_1.existsSync)(webDistRoot))
24
+ return false;
25
+ const url = new URL(req.url ?? "/", "http://localhost");
26
+ let filePath = (0, node_path_1.join)(webDistRoot, url.pathname === "/" ? "index.html" : url.pathname);
27
+ // If the path doesn't map to a real file, serve index.html (SPA fallback)
28
+ if (!(0, node_fs_1.existsSync)(filePath) || !filePath.startsWith(webDistRoot)) {
29
+ filePath = (0, node_path_1.join)(webDistRoot, "index.html");
30
+ }
31
+ if (!(0, node_fs_1.existsSync)(filePath))
32
+ return false;
33
+ const ext = (0, node_path_1.extname)(filePath);
34
+ const contentType = MIME[ext] ?? "application/octet-stream";
35
+ res.writeHead(200, {
36
+ "Content-Type": contentType,
37
+ "Cache-Control": ext === ".html" ? "no-cache" : "public, max-age=3600",
38
+ });
39
+ (0, node_fs_1.createReadStream)(filePath).pipe(res);
40
+ return true;
41
+ };
42
+ exports.serveStatic = serveStatic;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAgentService = void 0;
4
+ const gateway_read_helpers_1 = require("./gateway-read-helpers");
5
+ const asRecord = (value) => value && typeof value === "object" ? value : null;
6
+ const readSessionActivityMs = (raw) => {
7
+ const candidates = [raw.updatedAt, raw.endedAt, raw.startedAt, raw.timestamp, raw.ts];
8
+ let best = null;
9
+ for (const candidate of candidates) {
10
+ const asNumber = typeof candidate === "number" && Number.isFinite(candidate) ? candidate : null;
11
+ const asDate = typeof candidate === "string" && candidate.trim() ? Date.parse(candidate) : Number.NaN;
12
+ const ms = asNumber ?? (Number.isFinite(asDate) ? asDate : null);
13
+ if (ms === null)
14
+ continue;
15
+ if (best === null || ms > best)
16
+ best = ms;
17
+ }
18
+ return best;
19
+ };
20
+ const inferAgentIdsFromSession = (session) => {
21
+ const out = new Set();
22
+ const id = session.id.trim();
23
+ if (id) {
24
+ const match = id.match(/^agent:([^:]+):/i);
25
+ if (match?.[1])
26
+ out.add(match[1]);
27
+ }
28
+ const raw = session.raw;
29
+ const directKeys = [raw.agentId, raw.agent_id, raw.executorAgentId, raw.ownerAgentId];
30
+ for (const value of directKeys) {
31
+ if (typeof value === "string" && value.trim())
32
+ out.add(value.trim());
33
+ }
34
+ return [...out];
35
+ };
36
+ const createAgentService = (app) => {
37
+ const listAgents = async () => {
38
+ await (0, gateway_read_helpers_1.ensureGatewayReadyForReadonly)(app);
39
+ const payload = await app.gateway.client.sendReq("agents.list");
40
+ const rawItems = app.gateway.pickArray(payload);
41
+ // 会话活动时间优先尝试刷新;刷新失败时回退缓存,保证只读查询可用性。
42
+ let sessionItems = app.gateway.getSessionCache();
43
+ try {
44
+ const refreshed = await app.gateway.refreshSessionsFromGateway();
45
+ sessionItems = refreshed.items;
46
+ }
47
+ catch {
48
+ // 只读查询容错:会话刷新失败不应阻断 agents.list 输出。
49
+ }
50
+ const lastActiveByAgentId = new Map();
51
+ for (const session of sessionItems) {
52
+ const activityMs = readSessionActivityMs(session.raw);
53
+ if (activityMs === null)
54
+ continue;
55
+ const agentIds = inferAgentIdsFromSession(session);
56
+ for (const agentId of agentIds) {
57
+ const prev = lastActiveByAgentId.get(agentId);
58
+ if (prev === undefined || activityMs > prev) {
59
+ lastActiveByAgentId.set(agentId, activityMs);
60
+ }
61
+ }
62
+ }
63
+ return rawItems.map((item) => {
64
+ const obj = asRecord(item);
65
+ const agentId = obj ? String(obj.id ?? obj.name ?? obj.key ?? "").trim() || null : null;
66
+ const activeMs = agentId ? (lastActiveByAgentId.get(agentId) ?? null) : null;
67
+ return {
68
+ id: agentId,
69
+ raw: item,
70
+ lastActiveAtMs: activeMs,
71
+ lastActiveAt: activeMs ? new Date(activeMs).toISOString() : null,
72
+ };
73
+ });
74
+ };
75
+ return {
76
+ listAgents,
77
+ };
78
+ };
79
+ exports.createAgentService = createAgentService;
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createArtifactService = void 0;
4
+ const storage_service_1 = require("../artifacts/storage-service");
5
+ const artifact_index_1 = require("../artifacts/artifact-index");
6
+ const artifact_cleanup_1 = require("../artifacts/artifact-cleanup");
7
+ const createArtifactService = (app) => {
8
+ const listArtifacts = async (query) => (0, storage_service_1.listStoredArtifacts)(app.listPipelines(), {
9
+ pipelineIds: query?.pipelineIds,
10
+ nodeIds: query?.nodeIds,
11
+ dateFrom: query?.dateFrom,
12
+ dateTo: query?.dateTo,
13
+ limit: query?.limit,
14
+ cursor: query?.cursor,
15
+ statuses: query?.statuses,
16
+ kinds: query?.kinds,
17
+ batchRunId: query?.batchRunId,
18
+ runId: query?.runId,
19
+ });
20
+ const getArtifactContent = async (query) => {
21
+ const definition = app.getPipelineDefinition(query.pipelineId);
22
+ if (!definition)
23
+ return null;
24
+ const content = await (0, storage_service_1.readStoredArtifactContent)(definition, query.relativePath);
25
+ if (!content)
26
+ return null;
27
+ return {
28
+ pipelineId: query.pipelineId,
29
+ relativePath: query.relativePath,
30
+ content,
31
+ };
32
+ };
33
+ const exportArtifactContents = async (query) => (0, storage_service_1.exportStoredArtifactContents)(app.listPipelines(), {
34
+ pipelineIds: query?.pipelineIds,
35
+ nodeIds: query?.nodeIds,
36
+ dateFrom: query?.dateFrom,
37
+ dateTo: query?.dateTo,
38
+ limit: query?.limit,
39
+ });
40
+ const rebuildIndexFn = async (pipelineId) => {
41
+ const definitions = pipelineId
42
+ ? [app.getPipelineDefinition(pipelineId)].filter(Boolean)
43
+ : app.listPipelines();
44
+ let indexed = 0;
45
+ let skipped = 0;
46
+ const warnings = [];
47
+ for (const definition of definitions) {
48
+ const result = await (0, artifact_index_1.rebuildArtifactIndex)(definition, (d) => (0, storage_service_1.scanStoredArtifacts)([d]));
49
+ indexed += result.indexed;
50
+ skipped += result.skipped;
51
+ warnings.push(...result.warnings);
52
+ }
53
+ return { indexed, skipped, warnings };
54
+ };
55
+ return {
56
+ listArtifacts,
57
+ getArtifactContent,
58
+ exportArtifactContents,
59
+ rebuildIndex: rebuildIndexFn,
60
+ planCleanup: (pipelineId, options) => {
61
+ const definition = app.getPipelineDefinition(pipelineId);
62
+ if (!definition)
63
+ throw new Error(`pipeline_not_found:${pipelineId}`);
64
+ return (0, artifact_cleanup_1.planCleanup)(definition, options);
65
+ },
66
+ executeCleanup: (pipelineId, plan) => {
67
+ const definition = app.getPipelineDefinition(pipelineId);
68
+ if (!definition)
69
+ throw new Error(`pipeline_not_found:${pipelineId}`);
70
+ return (0, artifact_cleanup_1.executeCleanup)(definition, plan);
71
+ },
72
+ };
73
+ };
74
+ exports.createArtifactService = createArtifactService;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ensureGatewayReadyForReadonly = void 0;
4
+ const ensureGatewayReadyForReadonly = async (app) => {
5
+ if (app.gateway.client.getStatus().status === "ready")
6
+ return;
7
+ // 只读命令一旦命中网关方法,也必须先建好链路,否则 sendReq 会直接失败。
8
+ await app.gateway.client.connect();
9
+ };
10
+ exports.ensureGatewayReadyForReadonly = ensureGatewayReadyForReadonly;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./system-service"), exports);
18
+ __exportStar(require("./pipeline-service"), exports);
19
+ __exportStar(require("./agent-service"), exports);
20
+ __exportStar(require("./session-service"), exports);
21
+ __exportStar(require("./artifact-service"), exports);
22
+ __exportStar(require("./scheduler-service"), exports);
23
+ __exportStar(require("./read-services"), exports);