yaml-flow 8.5.3 → 8.6.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.
- package/browser/asset-integrity.json +3 -3
- package/examples/board/demo-shell-with-server.html +2 -2
- package/examples/board/doc.html +2 -2
- package/examples/board/server/board-server.js +266 -5
- package/examples/board/server/board-worker/task-executor.js +166 -51
- package/examples/board/server/chat-flow/copilot-chat/assistant.js +25 -12
- package/examples/board/server/chat-flow/copilot-chat/probe.js +7 -0
- package/examples/board/server/chat-flow/copilot-chat/shared.js +97 -0
- package/examples/board/server/chat-flow/flow-steps.json +109 -51
- package/examples/board/server-config.json +1 -0
- package/examples/board/test/server-http-test.js +870 -67
- package/examples/board-local/demo-shell-localstorage.html +3 -3
- package/lib/{artifacts-store-lib-D-k-E8Vy.d.ts → artifacts-store-lib-C1rtrkxm.d.ts} +1 -1
- package/lib/{artifacts-store-lib-CVgtQrNZ.d.cts → artifacts-store-lib-CLOtsiav.d.cts} +1 -1
- package/lib/artifacts-store-public.cjs +1 -1
- package/lib/artifacts-store-public.d.cts +3 -3
- package/lib/artifacts-store-public.d.ts +3 -3
- package/lib/artifacts-store-public.js +1 -1
- package/lib/batch/index.cjs +1 -1
- package/lib/batch/index.js +1 -1
- package/lib/board-live-cards-mcp.cjs +1 -1
- package/lib/board-live-cards-mcp.d.cts +35 -15
- package/lib/board-live-cards-mcp.d.ts +35 -15
- package/lib/board-live-cards-mcp.js +1 -1
- package/lib/board-live-cards-node.cjs +8 -16
- package/lib/board-live-cards-node.d.cts +32 -12
- package/lib/board-live-cards-node.d.ts +32 -12
- package/lib/board-live-cards-node.js +8 -16
- package/lib/{board-live-cards-public-BGS22cMb.d.ts → board-live-cards-public-CBVjm327.d.ts} +59 -24
- package/lib/{board-live-cards-public-B13InXhC.d.cts → board-live-cards-public-CPJy-aGW.d.cts} +59 -24
- package/lib/board-live-cards-public.cjs +1 -2
- package/lib/board-live-cards-public.d.cts +2 -2
- package/lib/board-live-cards-public.d.ts +2 -2
- package/lib/board-live-cards-public.js +1 -2
- package/lib/board-live-cards-server-runtime.cjs +1 -7
- package/lib/board-live-cards-server-runtime.d.cts +5 -5
- package/lib/board-live-cards-server-runtime.d.ts +5 -5
- package/lib/board-live-cards-server-runtime.js +1 -7
- package/lib/board-livegraph-runtime/index.cjs +1 -2
- package/lib/board-livegraph-runtime/index.js +1 -2
- package/lib/board-worker-adapter.cjs +21 -7
- package/lib/board-worker-adapter.d.cts +17 -2
- package/lib/board-worker-adapter.d.ts +17 -2
- package/lib/board-worker-adapter.js +21 -7
- package/lib/card-compute/index.cjs +1 -9
- package/lib/card-compute/index.js +1 -9
- package/lib/card-store-public.cjs +1 -1
- package/lib/card-store-public.d.cts +2 -2
- package/lib/card-store-public.d.ts +2 -2
- package/lib/card-store-public.js +1 -1
- package/lib/card-validation.cjs +1 -9
- package/lib/card-validation.js +1 -9
- package/lib/{chat-storage-lib-CJn7a6OH.d.ts → chat-storage-lib-Bce-xx6l.d.ts} +1 -1
- package/lib/{chat-storage-lib-0imhRX3l.d.cts → chat-storage-lib-CKylihjm.d.cts} +1 -1
- package/lib/chat-store-public.cjs +1 -1
- package/lib/chat-store-public.d.cts +3 -3
- package/lib/chat-store-public.d.ts +3 -3
- package/lib/chat-store-public.js +1 -1
- package/lib/chunk-2MZUYY65.cjs +2 -0
- package/lib/chunk-5DB54ZX2.cjs +2 -0
- package/lib/chunk-5EA2ESS4.cjs +16 -0
- package/lib/chunk-6APH25VI.js +2 -0
- package/lib/chunk-76ON3V7R.js +2 -0
- package/lib/chunk-7BKNHFNH.js +2 -0
- package/lib/chunk-CWREBRXS.js +3 -0
- package/lib/chunk-DAXACY63.js +2 -0
- package/lib/chunk-FW4363Y4.js +2 -0
- package/lib/chunk-FZ2SBU5M.js +3 -0
- package/lib/chunk-G4XXRHL2.cjs +3 -0
- package/lib/chunk-GNFE24S7.cjs +2 -0
- package/lib/chunk-GYQXDNNI.cjs +2 -0
- package/lib/chunk-H5KD3JPY.cjs +2 -0
- package/lib/chunk-HLJH7LGW.js +16 -0
- package/lib/chunk-I4WH5U5D.cjs +2 -0
- package/lib/chunk-IXZG74EW.cjs +2 -0
- package/lib/chunk-JAL25FGA.cjs +2 -0
- package/lib/chunk-JM5EKT57.js +2 -0
- package/lib/chunk-JMDHDY6M.js +2 -0
- package/lib/chunk-KBELAKIY.js +2 -0
- package/lib/chunk-KHJABJ45.cjs +3 -0
- package/lib/chunk-KLRUISRY.cjs +2 -0
- package/lib/chunk-KNFFDVLD.cjs +2 -0
- package/lib/chunk-LBMEVV4U.js +2 -0
- package/lib/chunk-LDAP75GN.js +2 -0
- package/lib/chunk-LODXIALE.cjs +2 -0
- package/lib/chunk-LVNQCE5X.cjs +3 -0
- package/lib/chunk-M7EQRS6W.js +3 -0
- package/lib/chunk-MNEOJWPS.js +10 -0
- package/lib/chunk-NJJ7WEDT.cjs +2 -0
- package/lib/chunk-NMZ6XNLB.cjs +3 -0
- package/lib/chunk-OPNGCSXJ.js +2 -0
- package/lib/chunk-P64UKI3L.cjs +8 -0
- package/lib/chunk-P7ZCDICS.cjs +2 -0
- package/lib/chunk-Q6H7NINN.cjs +5 -0
- package/lib/chunk-Q6VSL327.js +8 -0
- package/lib/chunk-QWBNDVUA.js +5 -0
- package/lib/chunk-S6DRP2HX.cjs +2 -0
- package/lib/chunk-UJ7ZTV4J.cjs +10 -0
- package/lib/chunk-UVE65IPR.cjs +3 -0
- package/lib/chunk-VCCTAUIG.js +2 -0
- package/lib/chunk-VGT3TRQG.js +3 -0
- package/lib/chunk-VLBB3D6B.js +3 -0
- package/lib/chunk-WDPOGXTY.js +2 -0
- package/lib/chunk-X3LC4LII.js +2 -0
- package/lib/chunk-YGKDQLYP.js +2 -0
- package/lib/chunk-YMEIPKLW.cjs +2 -0
- package/lib/config/index.cjs +1 -1
- package/lib/config/index.js +1 -1
- package/lib/continuous-event-graph/index.cjs +1 -2
- package/lib/continuous-event-graph/index.js +1 -2
- package/lib/event-graph/index.cjs +1 -22
- package/lib/event-graph/index.js +1 -22
- package/lib/execution-refs.cjs +1 -2
- package/lib/execution-refs.d.cts +3 -2
- package/lib/execution-refs.d.ts +3 -2
- package/lib/execution-refs.js +1 -2
- package/lib/index.cjs +2 -24
- package/lib/index.d.cts +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -24
- package/lib/server-runtime/index.cjs +1 -7
- package/lib/server-runtime/index.d.cts +6 -6
- package/lib/server-runtime/index.d.ts +6 -6
- package/lib/server-runtime/index.js +1 -7
- package/lib/step-machine/index.cjs +1 -11
- package/lib/step-machine/index.js +1 -11
- package/lib/step-machine-public/index.cjs +1 -4
- package/lib/step-machine-public/index.d.cts +1 -1
- package/lib/step-machine-public/index.d.ts +1 -1
- package/lib/step-machine-public/index.js +1 -4
- package/lib/{storage-interface-B2WD9D5n.d.cts → storage-interface-Ct-C4tlz.d.cts} +28 -1
- package/lib/{storage-interface-B2WD9D5n.d.ts → storage-interface-Ct-C4tlz.d.ts} +28 -1
- package/lib/stores/index.cjs +1 -2
- package/lib/stores/index.d.cts +1 -1
- package/lib/stores/index.d.ts +1 -1
- package/lib/stores/index.js +1 -2
- package/lib/stores/kv.cjs +1 -2
- package/lib/stores/kv.d.cts +1 -1
- package/lib/stores/kv.d.ts +1 -1
- package/lib/stores/kv.js +1 -2
- package/lib/stores/memory.cjs +1 -1
- package/lib/stores/memory.js +1 -1
- package/lib/{types-30R357js.d.ts → types-BuK2UMxk.d.ts} +4 -4
- package/lib/{types-CIgsh56O.d.cts → types-DRl0Hy_p.d.cts} +4 -4
- package/package.json +2 -16
- package/cli/board-live-cards-lib-COi4bSpk.d.ts +0 -322
- package/cli/browser-api/board-live-cards-browser-adapter.d.ts +0 -36
- package/cli/browser-api/board-live-cards-browser-adapter.js +0 -4
- package/cli/browser-api/card-store-browser-api.d.ts +0 -25
- package/cli/browser-api/card-store-browser-api.js +0 -2
- package/cli/browser-api/jsonata-sync.cjs +0 -7623
- package/cli/bundled/artifacts-store-cli.mjs +0 -12
- package/cli/bundled/batch-runner-cli.mjs +0 -3
- package/cli/bundled/board-live-cards-cli.mjs +0 -29
- package/cli/bundled/card-store-cli.mjs +0 -154
- package/cli/bundled/chat-store-cli.mjs +0 -16
- package/cli/bundled/jsonata-sync.cjs +0 -7623
- package/cli/bundled/step-machine-cli.mjs +0 -150
- package/cli/execution-interface-BCIhu1gO.d.ts +0 -442
- package/cli/types-H3EMBPY2.d.ts +0 -398
- package/examples/board/server/README-mcp-api.md +0 -690
- package/examples/board/test/server-http-mcp-test.js +0 -1280
- package/lib/board-livegraph-runtime/jsonata-sync.cjs +0 -7623
- package/lib/card-compute/jsonata-sync.cjs +0 -7623
- package/lib/continuous-event-graph/jsonata-sync.cjs +0 -7623
- package/lib/server-runtime/jsonata-sync.cjs +0 -7623
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-05-
|
|
2
|
+
"generatedAt": "2026-05-31T10:04:54.839Z",
|
|
3
3
|
"algorithm": "sha256",
|
|
4
4
|
"files": {
|
|
5
5
|
"browser/board-livecards-localstorage.js": {
|
|
6
|
-
"sha256": "sha256-
|
|
7
|
-
"bytes":
|
|
6
|
+
"sha256": "sha256-ZsTMRbMZNr915issy2horB25TVTwUCI35oGGZ8vWF7k=",
|
|
7
|
+
"bytes": 153257
|
|
8
8
|
},
|
|
9
9
|
"browser/live-cards.schema.json": {
|
|
10
10
|
"sha256": "sha256-F5nfqDzZ5L3p0lLTMxGt4YtMa2sVzdNPh8sbQ8OiXHE=",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
20
20
|
<script src="https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js"></script>
|
|
21
21
|
<script src="https://cdn.jsdelivr.net/npm/leader-line/leader-line.min.js"></script>
|
|
22
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.
|
|
23
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.
|
|
22
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.6.1/browser/live-cards.js"></script>
|
|
23
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.6.1/browser/board-livecards-client.js"></script>
|
|
24
24
|
</head>
|
|
25
25
|
<body class="bg-light">
|
|
26
26
|
<div class="container-fluid py-3">
|
package/examples/board/doc.html
CHANGED
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
38
38
|
<script src="https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js"></script>
|
|
39
39
|
<script src="https://cdn.jsdelivr.net/npm/leader-line/leader-line.min.js"></script>
|
|
40
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.
|
|
41
|
-
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.
|
|
40
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.6.1/browser/live-cards.js"></script>
|
|
41
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@8.6.1/browser/board-livecards-client.js"></script>
|
|
42
42
|
</head>
|
|
43
43
|
<body class="bg-light">
|
|
44
44
|
<div class="container-fluid py-3">
|
|
@@ -6,7 +6,7 @@ import path from 'node:path';
|
|
|
6
6
|
import net from 'node:net';
|
|
7
7
|
import os from 'node:os';
|
|
8
8
|
import { spawn } from 'node:child_process';
|
|
9
|
-
import { fileURLToPath } from 'node:url';
|
|
9
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
12
|
createMultiBoardServerRuntime,
|
|
@@ -23,8 +23,11 @@ import {
|
|
|
23
23
|
evaluateArgsMassaging,
|
|
24
24
|
invokeExecutionRef,
|
|
25
25
|
parseRef,
|
|
26
|
+
registerInProcessExecutionHandler,
|
|
27
|
+
startBoardWorkerQueueRunner,
|
|
26
28
|
serializeRef,
|
|
27
29
|
} from 'yaml-flow/board-live-cards-node';
|
|
30
|
+
import { registerInProcessBoardWorkerCallback } from 'yaml-flow/board-worker-adapter';
|
|
28
31
|
import {
|
|
29
32
|
createStepMachineChatFlowRunner,
|
|
30
33
|
} from 'yaml-flow/step-machine-public';
|
|
@@ -141,6 +144,17 @@ const configuredChatFlowTimeoutMs = normalizeTimeoutMs(serverConfig.chatFlowTime
|
|
|
141
144
|
const configuredInvokeRefTimeoutMs = normalizeTimeoutMs(serverConfig.chatInvokeRefTimeoutMs, 300000);
|
|
142
145
|
const configuredCopilotTimeoutMs = normalizeTimeoutMs(serverConfig.chatCopilotTimeoutMs, 300000);
|
|
143
146
|
|
|
147
|
+
function normalizeBoardWorkerTransport(value) {
|
|
148
|
+
const normalized = String(value || '').trim().toLowerCase();
|
|
149
|
+
if (normalized === 'http') return 'http';
|
|
150
|
+
if (normalized === 'queue') return 'queue';
|
|
151
|
+
return 'in-process-loop';
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const configuredBoardWorkerTransport = normalizeBoardWorkerTransport(
|
|
155
|
+
process.env.DEMO_TASK_EXECUTOR_TRANSPORT || serverConfig.taskExecutorTransport || 'in-process-loop',
|
|
156
|
+
);
|
|
157
|
+
|
|
144
158
|
// Resolve top-level config defaults (used as fallbacks for per-board config)
|
|
145
159
|
const configuredTaskExecutorPath = resolveFromConfig(serverConfig.taskExecutorPath);
|
|
146
160
|
const configuredChatHandlerPath = resolveFromConfig(serverConfig.chatHandlerPath);
|
|
@@ -167,6 +181,7 @@ const PORT = Number(process.env.DEMO_SERVER_PORT || serverConfig.port || 7799);
|
|
|
167
181
|
const cardsPatternArgIndex = cliArgs.indexOf('--cards-pattern');
|
|
168
182
|
const cliCardsPattern = cardsPatternArgIndex !== -1 ? cliArgs[cardsPatternArgIndex + 1] : null;
|
|
169
183
|
const selectedCardsPattern = (process.env.DEMO_CARDS_PATTERN || cliCardsPattern || '').trim() || null;
|
|
184
|
+
const enableTestReq = /^(1|true|yes|on)$/i.test((process.env.BOARD_SERVER_ENABLE_TEST_REQ || '').trim());
|
|
170
185
|
|
|
171
186
|
const CORS_HEADERS = {
|
|
172
187
|
'Access-Control-Allow-Origin': '*',
|
|
@@ -229,6 +244,107 @@ function makeExecutionRef(scriptPath, extra) {
|
|
|
229
244
|
};
|
|
230
245
|
}
|
|
231
246
|
|
|
247
|
+
function makeLocalTaskExecutorRef(scriptPath, extra) {
|
|
248
|
+
if (!scriptPath) return undefined;
|
|
249
|
+
const resolved = path.isAbsolute(scriptPath) ? scriptPath : path.resolve(process.cwd(), scriptPath);
|
|
250
|
+
return {
|
|
251
|
+
meta: 'task-executor',
|
|
252
|
+
howToRun: 'local-node',
|
|
253
|
+
whatToRun: serializeRef({ kind: 'fs-path', value: resolved }),
|
|
254
|
+
...(extra !== undefined ? { extra } : {}),
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function isHostedTaskExecutorRef(ref) {
|
|
259
|
+
return ref?.howToRun === 'queue-storage'
|
|
260
|
+
|| ref?.howToRun === 'in-process-loop'
|
|
261
|
+
|| ref?.howToRun === 'http:post'
|
|
262
|
+
|| ref?.howToRun === 'http:get';
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function makeHostedBoardWorkerRef(boardId, taskExecPath, transport, executionExtra) {
|
|
266
|
+
if (!taskExecPath) return undefined;
|
|
267
|
+
if (transport === 'in-process-loop') {
|
|
268
|
+
return {
|
|
269
|
+
meta: 'task-executor',
|
|
270
|
+
howToRun: 'in-process-loop',
|
|
271
|
+
whatToRun: serializeRef({ kind: 'in-process-loop', value: `board:${boardId}:board-worker` }),
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
if (transport === 'http') {
|
|
275
|
+
return {
|
|
276
|
+
meta: 'task-executor',
|
|
277
|
+
howToRun: 'http:post',
|
|
278
|
+
whatToRun: serializeRef({
|
|
279
|
+
kind: 'http-url',
|
|
280
|
+
value: `${String(executionExtra.serverUrl || '').replace(/\/+$/, '')}/api/board-worker`,
|
|
281
|
+
}),
|
|
282
|
+
extra: { boardId },
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
if (transport === 'queue') {
|
|
286
|
+
return {
|
|
287
|
+
meta: 'task-executor',
|
|
288
|
+
howToRun: 'queue-storage',
|
|
289
|
+
whatToRun: serializeRef({ kind: 'queue-storage', value: `board:${boardId}:board-worker` }),
|
|
290
|
+
extra: { boardId },
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
throw new Error(`Unsupported board-worker transport for demo host: ${transport}`);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function makeBoardWorkerCallbackSelfRef(serverUrl, boardApiBasePath, transport, boardId) {
|
|
297
|
+
if (transport === 'in-process-loop' || transport === 'queue') {
|
|
298
|
+
return {
|
|
299
|
+
meta: 'board-live-cards',
|
|
300
|
+
howToRun: 'in-process-loop',
|
|
301
|
+
whatToRun: serializeRef({ kind: 'in-process-loop', value: `board:${boardId}:board-worker-callback` }),
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
const normalizedServerUrl = typeof serverUrl === 'string' ? serverUrl.trim().replace(/\/+$/, '') : '';
|
|
305
|
+
const normalizedApiBasePath = typeof boardApiBasePath === 'string' ? boardApiBasePath.trim().replace(/\/+$/, '') : '';
|
|
306
|
+
if (!normalizedServerUrl || !normalizedApiBasePath) return undefined;
|
|
307
|
+
return {
|
|
308
|
+
meta: 'board-live-cards',
|
|
309
|
+
howToRun: 'http:post',
|
|
310
|
+
whatToRun: serializeRef({
|
|
311
|
+
kind: 'http-url',
|
|
312
|
+
value: `${normalizedServerUrl}${normalizedApiBasePath}/callback/board-worker`,
|
|
313
|
+
}),
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
async function readJsonRequest(req) {
|
|
318
|
+
const parts = [];
|
|
319
|
+
for await (const chunk of req) parts.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
320
|
+
const raw = Buffer.concat(parts).toString('utf-8').trim();
|
|
321
|
+
return raw ? JSON.parse(raw) : {};
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const boardWorkerModuleCache = new Map();
|
|
325
|
+
|
|
326
|
+
async function loadBoardWorkerModule(taskExecPath) {
|
|
327
|
+
const resolved = path.isAbsolute(taskExecPath) ? taskExecPath : path.resolve(BOARD_ROOT, taskExecPath);
|
|
328
|
+
if (!boardWorkerModuleCache.has(resolved)) {
|
|
329
|
+
boardWorkerModuleCache.set(resolved, import(pathToFileURL(resolved).href));
|
|
330
|
+
}
|
|
331
|
+
return boardWorkerModuleCache.get(resolved);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function createHostedBoardWorkerDispatcher(boardId, taskExecPath) {
|
|
335
|
+
if (!taskExecPath) return null;
|
|
336
|
+
return async (request) => {
|
|
337
|
+
const mod = await loadBoardWorkerModule(taskExecPath);
|
|
338
|
+
if (typeof mod.executeBoardWorkerRequest === 'function') {
|
|
339
|
+
return await mod.executeBoardWorkerRequest(request);
|
|
340
|
+
}
|
|
341
|
+
if (typeof mod.executeTaskExecutorRequest === 'function') {
|
|
342
|
+
return await mod.executeTaskExecutorRequest(request);
|
|
343
|
+
}
|
|
344
|
+
throw new Error(`Hosted board worker for board ${boardId} must export executeBoardWorkerRequest(request)`);
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
|
|
232
348
|
function createNamedPipeNotificationTransport() {
|
|
233
349
|
return {
|
|
234
350
|
async subscribe(ref, onEvent) {
|
|
@@ -283,6 +399,9 @@ const apiBasePath = '/api/boards';
|
|
|
283
399
|
const invocationAdapter = createNodeSpawnInvocationAdapter();
|
|
284
400
|
const notificationTransport = createNamedPipeNotificationTransport();
|
|
285
401
|
const logger = { info: console.log, warn: console.warn, error: console.error };
|
|
402
|
+
const hostedBoardWorkerDispatchers = new Map();
|
|
403
|
+
const hostedBoardWorkerQueueStops = new Map();
|
|
404
|
+
const hostedBoardChatStorages = new Map();
|
|
286
405
|
|
|
287
406
|
// Map config keys to board entries for the factory
|
|
288
407
|
const boardConfigEntries = serverConfig.boards ? Object.entries(serverConfig.boards) : [];
|
|
@@ -301,8 +420,24 @@ function buildBoardContextConfig(label, boardDir, taskExecPath, chatHandlerFlow,
|
|
|
301
420
|
|
|
302
421
|
const notifyChannel = `yaml-flow-server-${label}-${boardId}-${process.pid}`;
|
|
303
422
|
const baseRef = parseRef(serializeRef({ kind: 'fs-path', value: boardDir }));
|
|
304
|
-
const
|
|
305
|
-
const
|
|
423
|
+
const boardWorkerTransport = normalizeBoardWorkerTransport(executionExtra.taskExecutorTransport);
|
|
424
|
+
const callbackSelfRef = makeBoardWorkerCallbackSelfRef(executionExtra.serverUrl, executionExtra.apiBasePath, boardWorkerTransport, boardId);
|
|
425
|
+
const boardAdapter = createFsBoardPlatformAdapter(baseRef, {
|
|
426
|
+
notifyChannel,
|
|
427
|
+
...(callbackSelfRef ? { selfRef: callbackSelfRef } : {}),
|
|
428
|
+
});
|
|
429
|
+
const nonCoreAdapter = createFsBoardNonCorePlatformAdapter(baseRef, {
|
|
430
|
+
notifyChannel,
|
|
431
|
+
...(callbackSelfRef ? { selfRef: callbackSelfRef } : {}),
|
|
432
|
+
});
|
|
433
|
+
const localSyncTaskExecutorRef = makeLocalTaskExecutorRef(taskExecPath, executionExtra);
|
|
434
|
+
if (localSyncTaskExecutorRef) {
|
|
435
|
+
const invokeExecutor = nonCoreAdapter.invokeExecutor.bind(nonCoreAdapter);
|
|
436
|
+
nonCoreAdapter.invokeExecutor = (ref, subcommand, execOpts) => {
|
|
437
|
+
const syncRef = isHostedTaskExecutorRef(ref) ? localSyncTaskExecutorRef : ref;
|
|
438
|
+
return invokeExecutor(syncRef, subcommand, execOpts);
|
|
439
|
+
};
|
|
440
|
+
}
|
|
306
441
|
boardAdapter.requestProcessAccumulated = () => {};
|
|
307
442
|
nonCoreAdapter.requestProcessAccumulated = () => {};
|
|
308
443
|
|
|
@@ -325,7 +460,7 @@ function buildBoardContextConfig(label, boardDir, taskExecPath, chatHandlerFlow,
|
|
|
325
460
|
scratchStoreRef,
|
|
326
461
|
archiveStoreRef,
|
|
327
462
|
notifyRef: { kind: 'named-pipe', value: namedPipePath(notifyChannel) },
|
|
328
|
-
taskExecutorRef:
|
|
463
|
+
taskExecutorRef: makeHostedBoardWorkerRef(boardId, taskExecPath, boardWorkerTransport, executionExtra),
|
|
329
464
|
chatHandlerFlow,
|
|
330
465
|
inferenceAdapterRef: makeExecutionRef(infAdapterPath),
|
|
331
466
|
};
|
|
@@ -401,6 +536,7 @@ const runtime = createMultiBoardServerRuntime({
|
|
|
401
536
|
);
|
|
402
537
|
const infAdapterPath = resolveFromConfig(regular.inferenceAdapterPath) || (entry?.inferenceAdapterPath || configuredInferenceAdapterPath);
|
|
403
538
|
const stepMachinePath = resolveFromConfig(regular.stepMachineCliPath || cfg?.stepMachineCliPath) || (entry?.stepMachineCliPath || configuredStepMachineCliPath);
|
|
539
|
+
const boardWorkerTransport = normalizeBoardWorkerTransport(regular.taskExecutorTransport || entry?.taskExecutorTransport || configuredBoardWorkerTransport);
|
|
404
540
|
const chatInvokeRefTimeoutMs = configuredInvokeRefTimeoutMs;
|
|
405
541
|
const chatCopilotTimeoutMs = configuredCopilotTimeoutMs;
|
|
406
542
|
|
|
@@ -436,6 +572,7 @@ const runtime = createMultiBoardServerRuntime({
|
|
|
436
572
|
chatFlowRoot,
|
|
437
573
|
apiBasePath: `${apiBasePath}/${boardId}`,
|
|
438
574
|
serverUrl: `http://127.0.0.1:${PORT}`,
|
|
575
|
+
taskExecutorTransport: boardWorkerTransport,
|
|
439
576
|
chatCopilotTimeoutMs,
|
|
440
577
|
...(stepMachinePath ? { stepMachineCliPath: stepMachinePath } : {}),
|
|
441
578
|
};
|
|
@@ -446,6 +583,7 @@ const runtime = createMultiBoardServerRuntime({
|
|
|
446
583
|
demoPrepSetup({ cardsDir, boardDir });
|
|
447
584
|
|
|
448
585
|
const chatStorage = createFsBoardChatStorage(boardDir);
|
|
586
|
+
hostedBoardChatStorages.set(boardId, chatStorage);
|
|
449
587
|
|
|
450
588
|
const singleBoardRuntime = createSingleBoardServerRuntime({
|
|
451
589
|
apiBasePath: `${apiBasePath}/${boardId}`,
|
|
@@ -470,6 +608,44 @@ const runtime = createMultiBoardServerRuntime({
|
|
|
470
608
|
},
|
|
471
609
|
});
|
|
472
610
|
|
|
611
|
+
const hostedBoardWorkerDispatch = createHostedBoardWorkerDispatcher(boardId, taskExecPath);
|
|
612
|
+
if (hostedBoardWorkerDispatch) {
|
|
613
|
+
hostedBoardWorkerDispatchers.set(boardId, hostedBoardWorkerDispatch);
|
|
614
|
+
}
|
|
615
|
+
const previousQueueStop = hostedBoardWorkerQueueStops.get(boardId);
|
|
616
|
+
if (previousQueueStop) {
|
|
617
|
+
previousQueueStop();
|
|
618
|
+
hostedBoardWorkerQueueStops.delete(boardId);
|
|
619
|
+
}
|
|
620
|
+
if (boardWorkerTransport === 'in-process-loop' && hostedBoardWorkerDispatch) {
|
|
621
|
+
registerInProcessExecutionHandler(`board:${boardId}:board-worker`, async (_ref, args) => {
|
|
622
|
+
void hostedBoardWorkerDispatch(args).catch((err) => {
|
|
623
|
+
logger.error(`[board-server] in-process board-worker failed for ${boardId}: ${String(err && err.message || err)}`);
|
|
624
|
+
});
|
|
625
|
+
return { result: 'success', data: { dispatched: true } };
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
if ((boardWorkerTransport === 'in-process-loop' || boardWorkerTransport === 'queue') && hostedBoardWorkerDispatch) {
|
|
629
|
+
registerInProcessBoardWorkerCallback(`board:${boardId}:board-worker-callback`, (payload) => {
|
|
630
|
+
if (payload.outcome === 'success') {
|
|
631
|
+
return singleBoardRuntime.reportSourceFetched(payload.token, String(payload.ref || ''));
|
|
632
|
+
}
|
|
633
|
+
return singleBoardRuntime.reportSourceFetchFailure(payload.token, String(payload.reason || 'unknown'));
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
if (boardWorkerTransport === 'queue' && hostedBoardWorkerDispatch) {
|
|
637
|
+
const stopQueueRunner = startBoardWorkerQueueRunner({
|
|
638
|
+
workerStore: baseCfg.boardAdapter.boardWorkerStore(),
|
|
639
|
+
executeBoardWorkerRequest: hostedBoardWorkerDispatch,
|
|
640
|
+
onError: (error, lease) => {
|
|
641
|
+
logger.error(
|
|
642
|
+
`[board-server] queued board-worker failed for ${boardId} (attempt ${lease.attempt}): ${String(error && error.message || error)}`,
|
|
643
|
+
);
|
|
644
|
+
},
|
|
645
|
+
});
|
|
646
|
+
hostedBoardWorkerQueueStops.set(boardId, stopQueueRunner);
|
|
647
|
+
}
|
|
648
|
+
|
|
473
649
|
// Seed card store from source cardsDir if empty
|
|
474
650
|
const existing = singleBoardRuntime.cardStore.get({});
|
|
475
651
|
const isEmpty = existing.status !== 'success' || !existing.data?.cards?.length;
|
|
@@ -509,7 +685,7 @@ function jsonReply(res, status, payload) {
|
|
|
509
685
|
res.end(body);
|
|
510
686
|
}
|
|
511
687
|
|
|
512
|
-
const server = http.createServer((req, res) => {
|
|
688
|
+
const server = http.createServer(async (req, res) => {
|
|
513
689
|
const method = req.method || 'GET';
|
|
514
690
|
const url = new URL(req.url || '/', 'http://localhost');
|
|
515
691
|
const pathname = url.pathname;
|
|
@@ -520,6 +696,87 @@ const server = http.createServer((req, res) => {
|
|
|
520
696
|
return;
|
|
521
697
|
}
|
|
522
698
|
|
|
699
|
+
const testSystemChatMatch = pathname.match(/^\/test-req\/boards\/([^/]+)\/chat\/system-message$/);
|
|
700
|
+
if (method === 'POST' && testSystemChatMatch) {
|
|
701
|
+
if (!enableTestReq) {
|
|
702
|
+
jsonReply(res, 404, { error: 'Not found' });
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
try {
|
|
707
|
+
const boardId = decodeURIComponent(testSystemChatMatch[1]);
|
|
708
|
+
runtime.requireBoardService(boardId);
|
|
709
|
+
const chatStorage = hostedBoardChatStorages.get(boardId);
|
|
710
|
+
if (!chatStorage) {
|
|
711
|
+
jsonReply(res, 409, { error: `No hosted chat storage configured for board: ${boardId}` });
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
const body = await readJsonRequest(req);
|
|
716
|
+
const cardId = typeof body?.cardId === 'string' ? body.cardId.trim() : '';
|
|
717
|
+
const text = typeof body?.text === 'string' ? body.text : '';
|
|
718
|
+
const turn = typeof body?.turn === 'string' ? body.turn : '';
|
|
719
|
+
const files = Array.isArray(body?.files) ? body.files : [];
|
|
720
|
+
|
|
721
|
+
if (!cardId) {
|
|
722
|
+
jsonReply(res, 400, { error: 'cardId is required' });
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
if (typeof body?.text !== 'string') {
|
|
726
|
+
jsonReply(res, 400, { error: 'text is required' });
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
const id = chatStorage.append(cardId, 'system', text, files, turn);
|
|
731
|
+
jsonReply(res, 200, {
|
|
732
|
+
status: 'success',
|
|
733
|
+
data: {
|
|
734
|
+
id,
|
|
735
|
+
boardId,
|
|
736
|
+
cardId,
|
|
737
|
+
role: 'system',
|
|
738
|
+
text,
|
|
739
|
+
turn,
|
|
740
|
+
files,
|
|
741
|
+
},
|
|
742
|
+
});
|
|
743
|
+
return;
|
|
744
|
+
} catch (err) {
|
|
745
|
+
jsonReply(res, 404, { error: String(err && err.message || err) });
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
if (method === 'POST' && pathname === '/api/board-worker') {
|
|
751
|
+
try {
|
|
752
|
+
const body = await readJsonRequest(req);
|
|
753
|
+
const boardId = typeof body?.extra?.boardId === 'string' ? body.extra.boardId.trim() : '';
|
|
754
|
+
if (!boardId) {
|
|
755
|
+
jsonReply(res, 400, { error: 'boardId is required in request.extra.boardId' });
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
runtime.requireBoardService(boardId);
|
|
759
|
+
const dispatcher = hostedBoardWorkerDispatchers.get(boardId);
|
|
760
|
+
if (!dispatcher) {
|
|
761
|
+
jsonReply(res, 409, { error: `No hosted board-worker configured for board: ${boardId}` });
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
if (body?.source_def) {
|
|
765
|
+
void dispatcher(body).catch((err) => {
|
|
766
|
+
logger.error(`[board-server] hosted board-worker failed for ${boardId}: ${String(err && err.message || err)}`);
|
|
767
|
+
});
|
|
768
|
+
jsonReply(res, 202, { status: 'success', dispatched: true });
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
const workerResult = await dispatcher(body);
|
|
772
|
+
jsonReply(res, 200, workerResult ?? { status: 'success', data: {} });
|
|
773
|
+
return;
|
|
774
|
+
} catch (err) {
|
|
775
|
+
jsonReply(res, 404, { error: String(err && err.message || err) });
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
|
|
523
780
|
// All other /api/boards routes are handled by the platform-free runtime
|
|
524
781
|
runtime.handleApi(req, res, url).then((handled) => {
|
|
525
782
|
if (!handled) {
|
|
@@ -546,4 +803,8 @@ server.listen(PORT, '127.0.0.1', () => {
|
|
|
546
803
|
console.log(` GET ${apiBasePath}/:boardId/cards/:id/chats`);
|
|
547
804
|
console.log(` POST ${apiBasePath}/:boardId/cards/:id/chats/subscribe-sse`);
|
|
548
805
|
console.log(` POST ${apiBasePath}/:boardId/cards/:id/chats/unsubscribe-sse`);
|
|
806
|
+
console.log(' POST /api/board-worker');
|
|
807
|
+
if (enableTestReq) {
|
|
808
|
+
console.log(' POST /test-req/boards/:boardId/chat/system-message');
|
|
809
|
+
}
|
|
549
810
|
});
|