@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.
@@ -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) => normalizeWorkflowArtifact(item, index, action ? "action" : "global"));
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 projections" };
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: cleanString(payload.source || "agentflow-cli", 120) || "agentflow-cli",
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}`;