@fieldwangai/agentflow 0.1.135 → 0.1.136
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/bin/lib/ui-server.mjs +300 -37
- package/bin/lib/workflow-report.mjs +70 -9
- package/builtin/web-ui/dist/assets/{index-CmpbCHAj.js → index-HdswcJWY.js} +278 -133
- package/builtin/web-ui/dist/assets/index-KIGufzQf.css +1 -0
- package/builtin/web-ui/dist/index.html +2 -2
- package/package.json +1 -1
- package/skills/agentflow-cli/SKILL.md +1 -1
- package/skills/agentflow-cli/scripts/agentflow-cli.mjs +24 -4
- package/skills/agentflow-cli/scripts/workflow-report-client.mjs +68 -0
- package/skills/agentflow-workflow-report/SKILL.md +31 -8
- package/skills/agentflow-workflow-report/references/protocol.md +457 -236
- package/builtin/web-ui/dist/assets/index-BFQVTav-.css +0 -1
|
@@ -144,6 +144,32 @@ function normalizeWorkflowProjectionState(value = {}) {
|
|
|
144
144
|
return raw;
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
+
export function normalizeWorkflowExtensions(value = {}) {
|
|
148
|
+
const raw = plainObject(value);
|
|
149
|
+
const out = {};
|
|
150
|
+
for (const [namespace, extension] of Object.entries(raw)) {
|
|
151
|
+
const key = cleanString(namespace, 120).toLowerCase();
|
|
152
|
+
if (!key || !/^[a-z][a-z0-9._-]{0,119}$/.test(key)) continue;
|
|
153
|
+
if (!extension || typeof extension !== "object" || Array.isArray(extension)) continue;
|
|
154
|
+
out[key] = mergeWorkflowGlobalState({}, extension);
|
|
155
|
+
}
|
|
156
|
+
return out;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function materializeWorkflowExtensions(snapshot = {}, runtimeEvents = []) {
|
|
160
|
+
let extensions = normalizeWorkflowExtensions(
|
|
161
|
+
snapshot.extensions || snapshot.workflowExtensions || snapshot.workflow_extensions || {},
|
|
162
|
+
);
|
|
163
|
+
const events = [...(Array.isArray(runtimeEvents) ? runtimeEvents : [])]
|
|
164
|
+
.sort((left, right) => eventTime(left) - eventTime(right));
|
|
165
|
+
for (const event of events) {
|
|
166
|
+
const patch = event?.extensionsPatch || event?.extensions_patch;
|
|
167
|
+
if (!patch || typeof patch !== "object" || Array.isArray(patch)) continue;
|
|
168
|
+
extensions = mergeWorkflowGlobalState(extensions, normalizeWorkflowExtensions(patch));
|
|
169
|
+
}
|
|
170
|
+
return extensions;
|
|
171
|
+
}
|
|
172
|
+
|
|
147
173
|
export function materializeWorkflowProjections(snapshot = {}, runtimeEvents = []) {
|
|
148
174
|
const base =
|
|
149
175
|
snapshot.projections ||
|
|
@@ -241,6 +267,24 @@ export function normalizeWorkflowReport(payload = {}) {
|
|
|
241
267
|
const workflow = normalizeWorkflowReference(payload);
|
|
242
268
|
if (workflow.error) return workflow;
|
|
243
269
|
const rawWorkflow = plainObject(payload.workflow);
|
|
270
|
+
const source = cleanString(payload.source || "agentflow-cli", 120).toLowerCase() || "agentflow-cli";
|
|
271
|
+
if (!/^[a-z][a-z0-9._-]{0,119}$/.test(source)) {
|
|
272
|
+
return { error: "Invalid workflow report source" };
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const rawObservation = plainObject(payload.observation);
|
|
276
|
+
const hasObservation = Object.keys(rawObservation).length > 0;
|
|
277
|
+
const observationState = plainObject(rawObservation.state || rawObservation.facts || rawObservation.value);
|
|
278
|
+
if (hasObservation && !Object.keys(observationState).length) {
|
|
279
|
+
return { error: "observation requires state" };
|
|
280
|
+
}
|
|
281
|
+
const observation = hasObservation ? {
|
|
282
|
+
schema: cleanString(rawObservation.schema || rawObservation.model || "workflow-observation/v1", 160),
|
|
283
|
+
state: mergeWorkflowGlobalState({}, observationState),
|
|
284
|
+
observedAt: cleanString(rawObservation.observedAt || rawObservation.observed_at, 80),
|
|
285
|
+
clientId: cleanString(rawObservation.clientId || rawObservation.client_id, 160),
|
|
286
|
+
scope: cleanString(rawObservation.scope || "client", 80).toLowerCase() || "client",
|
|
287
|
+
} : null;
|
|
244
288
|
|
|
245
289
|
const rawAction = plainObject(payload.action);
|
|
246
290
|
const hasAction = Object.keys(rawAction).length > 0;
|
|
@@ -269,7 +313,10 @@ export function normalizeWorkflowReport(payload = {}) {
|
|
|
269
313
|
const rawArtifacts = Array.isArray(payload.artifacts) ? payload.artifacts : [];
|
|
270
314
|
const artifacts = rawArtifacts
|
|
271
315
|
.filter((item) => item && typeof item === "object" && !Array.isArray(item))
|
|
272
|
-
.map((item, index) =>
|
|
316
|
+
.map((item, index) => ({
|
|
317
|
+
...normalizeWorkflowArtifact(item, index, action ? "action" : "global"),
|
|
318
|
+
producer: source,
|
|
319
|
+
}));
|
|
273
320
|
|
|
274
321
|
const rawProjections = plainObject(payload.projections || payload.workflowProjections || payload.workflow_projections);
|
|
275
322
|
const hasProjections = Object.keys(rawProjections).length > 0 || hasOwn(payload, "projections");
|
|
@@ -287,6 +334,13 @@ export function normalizeWorkflowReport(payload = {}) {
|
|
|
287
334
|
}
|
|
288
335
|
const projections = hasProjections ? normalizeWorkflowProjectionState(rawProjections) : null;
|
|
289
336
|
|
|
337
|
+
const rawExtensions = plainObject(payload.extensions);
|
|
338
|
+
const hasExtensions = Object.keys(rawExtensions).length > 0;
|
|
339
|
+
const extensions = hasExtensions ? normalizeWorkflowExtensions(rawExtensions) : null;
|
|
340
|
+
if (hasExtensions && !Object.keys(extensions).length) {
|
|
341
|
+
return { error: "extensions requires at least one valid namespace object" };
|
|
342
|
+
}
|
|
343
|
+
|
|
290
344
|
const rawGlobalState = plainObject(payload.globalState || payload.global_state);
|
|
291
345
|
const hasGlobalState = Object.keys(rawGlobalState).length > 0;
|
|
292
346
|
const globalStatePatch = plainObject(rawGlobalState.patch);
|
|
@@ -296,8 +350,8 @@ export function normalizeWorkflowReport(payload = {}) {
|
|
|
296
350
|
if (hasGlobalState && !Object.keys(globalStatePatch).length && !globalStateRemove.length) {
|
|
297
351
|
return { error: "globalState requires patch or remove" };
|
|
298
352
|
}
|
|
299
|
-
if (!action && !artifacts.length && !hasGlobalState && !hasProjections) {
|
|
300
|
-
return { error: "Workflow report requires action, artifacts, globalState, or
|
|
353
|
+
if (!action && !artifacts.length && !hasGlobalState && !hasProjections && !hasExtensions && !hasObservation) {
|
|
354
|
+
return { error: "Workflow report requires observation, action, artifacts, globalState, projections, or extensions" };
|
|
301
355
|
}
|
|
302
356
|
|
|
303
357
|
const idempotencyKey = cleanString(
|
|
@@ -310,7 +364,7 @@ export function normalizeWorkflowReport(payload = {}) {
|
|
|
310
364
|
const event = {
|
|
311
365
|
schemaVersion,
|
|
312
366
|
type: "workflow-report",
|
|
313
|
-
source
|
|
367
|
+
source,
|
|
314
368
|
workflow,
|
|
315
369
|
workflowKey: workflow.key,
|
|
316
370
|
aggregateByStage: Boolean(action),
|
|
@@ -339,6 +393,7 @@ export function normalizeWorkflowReport(payload = {}) {
|
|
|
339
393
|
}),
|
|
340
394
|
artifacts,
|
|
341
395
|
...(hasProjections ? { projections } : {}),
|
|
396
|
+
...(hasExtensions ? { extensionsPatch: extensions } : {}),
|
|
342
397
|
...(hasGlobalState ? {
|
|
343
398
|
globalStatePatch,
|
|
344
399
|
globalStateRemove,
|
|
@@ -351,6 +406,9 @@ export function normalizeWorkflowReport(payload = {}) {
|
|
|
351
406
|
action,
|
|
352
407
|
artifacts,
|
|
353
408
|
projections,
|
|
409
|
+
extensions,
|
|
410
|
+
observation,
|
|
411
|
+
hasRuntimeUpdate: Boolean(action || artifacts.length || hasGlobalState || hasProjections || hasExtensions),
|
|
354
412
|
globalState: hasGlobalState ? {
|
|
355
413
|
mode: "merge",
|
|
356
414
|
patch: globalStatePatch,
|
|
@@ -491,20 +549,22 @@ export function mergeWorkflowArtifactLists(left = [], right = [], defaultScope =
|
|
|
491
549
|
};
|
|
492
550
|
const artifactAliases = (artifact) => {
|
|
493
551
|
const aliases = [];
|
|
552
|
+
const producer = cleanString(artifact?.producer || artifact?.reportSource || artifact?.report_source, 120).toLowerCase();
|
|
553
|
+
const ownedAlias = (alias) => producer ? `producer:${producer}:${alias}` : alias;
|
|
494
554
|
const explicitKey = cleanString(
|
|
495
555
|
artifact?.key || artifact?.artifactKey || artifact?.artifact_key,
|
|
496
556
|
500,
|
|
497
557
|
);
|
|
498
|
-
if (explicitKey) aliases.push(`key:${explicitKey}`);
|
|
558
|
+
if (explicitKey) aliases.push(ownedAlias(`key:${explicitKey}`));
|
|
499
559
|
const url = normalizedUrl(
|
|
500
560
|
artifact?.canonicalUrl
|
|
501
561
|
|| artifact?.canonical_url
|
|
502
562
|
|| artifact?.href
|
|
503
563
|
|| artifact?.url,
|
|
504
564
|
);
|
|
505
|
-
if (url) aliases.push(`url:${url}`);
|
|
565
|
+
if (url) aliases.push(ownedAlias(`url:${url}`));
|
|
506
566
|
const artifactPath = cleanString(artifact?.path, 4000);
|
|
507
|
-
if (artifactPath) aliases.push(`path:${artifactPath}`);
|
|
567
|
+
if (artifactPath) aliases.push(ownedAlias(`path:${artifactPath}`));
|
|
508
568
|
return aliases;
|
|
509
569
|
};
|
|
510
570
|
const add = (artifact) => {
|
|
@@ -531,7 +591,7 @@ export function mergeWorkflowArtifactLists(left = [], right = [], defaultScope =
|
|
|
531
591
|
return out;
|
|
532
592
|
}
|
|
533
593
|
|
|
534
|
-
export function workflowRuntimeRevision(globalState = {}, artifacts = [], runtimeEvents = [], projections = {}) {
|
|
594
|
+
export function workflowRuntimeRevision(globalState = {}, artifacts = [], runtimeEvents = [], projections = {}, extensions = {}) {
|
|
535
595
|
const events = (Array.isArray(runtimeEvents) ? runtimeEvents : []).map((event) => ({
|
|
536
596
|
id: event?.id || "",
|
|
537
597
|
action: event?.action || event?.actionId || "",
|
|
@@ -541,10 +601,11 @@ export function workflowRuntimeRevision(globalState = {}, artifacts = [], runtim
|
|
|
541
601
|
globalStatePatch: event?.globalStatePatch || {},
|
|
542
602
|
globalStateRemove: event?.globalStateRemove || [],
|
|
543
603
|
projections: event?.projections || {},
|
|
604
|
+
extensionsPatch: event?.extensionsPatch || {},
|
|
544
605
|
}));
|
|
545
606
|
const hash = crypto
|
|
546
607
|
.createHash("sha256")
|
|
547
|
-
.update(JSON.stringify(stableValue({ globalState, artifacts, projections, events })))
|
|
608
|
+
.update(JSON.stringify(stableValue({ globalState, artifacts, projections, extensions, events })))
|
|
548
609
|
.digest("hex")
|
|
549
610
|
.slice(0, 24);
|
|
550
611
|
return `runtime:${hash}`;
|