agent-contracts 0.8.0 → 0.9.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.
package/dist/index.d.ts CHANGED
@@ -196,6 +196,7 @@ declare const DslSchema: z.ZodObject<{
196
196
  wait_for_approval: "wait_for_approval";
197
197
  }>;
198
198
  }, z.core.$loose>>>;
199
+ validations: z.ZodDefault<z.ZodArray<z.ZodString>>;
199
200
  }, z.core.$loose>>>;
200
201
  artifacts: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
201
202
  type: z.ZodString;
@@ -250,6 +251,22 @@ declare const DslSchema: z.ZodObject<{
250
251
  entry_conditions: z.ZodDefault<z.ZodArray<z.ZodString>>;
251
252
  trigger: z.ZodOptional<z.ZodString>;
252
253
  steps: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
254
+ type: z.ZodLiteral<"delegate">;
255
+ description: z.ZodOptional<z.ZodString>;
256
+ task: z.ZodString;
257
+ from_agent: z.ZodString;
258
+ group: z.ZodOptional<z.ZodString>;
259
+ retry: z.ZodOptional<z.ZodObject<{
260
+ condition: z.ZodString;
261
+ fix_task: z.ZodString;
262
+ revalidate_task: z.ZodOptional<z.ZodString>;
263
+ }, z.core.$strip>>;
264
+ }, z.core.$loose>, z.ZodObject<{
265
+ type: z.ZodLiteral<"gate">;
266
+ description: z.ZodOptional<z.ZodString>;
267
+ gate_kind: z.ZodString;
268
+ group: z.ZodOptional<z.ZodString>;
269
+ }, z.core.$loose>, z.ZodObject<{
253
270
  type: z.ZodLiteral<"handoff">;
254
271
  description: z.ZodOptional<z.ZodString>;
255
272
  handoff_kind: z.ZodString;
@@ -427,6 +444,7 @@ declare const TaskSchema: z.ZodObject<{
427
444
  wait_for_approval: "wait_for_approval";
428
445
  }>;
429
446
  }, z.core.$loose>>>;
447
+ validations: z.ZodDefault<z.ZodArray<z.ZodString>>;
430
448
  }, z.core.$loose>;
431
449
  type Task = z.infer<typeof TaskSchema>;
432
450
 
@@ -490,6 +508,22 @@ declare const ExternalParticipantSchema: z.ZodObject<{
490
508
  }, z.core.$strip>;
491
509
  type ExternalParticipant = z.infer<typeof ExternalParticipantSchema>;
492
510
  declare const WorkflowStepSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
511
+ type: z.ZodLiteral<"delegate">;
512
+ description: z.ZodOptional<z.ZodString>;
513
+ task: z.ZodString;
514
+ from_agent: z.ZodString;
515
+ group: z.ZodOptional<z.ZodString>;
516
+ retry: z.ZodOptional<z.ZodObject<{
517
+ condition: z.ZodString;
518
+ fix_task: z.ZodString;
519
+ revalidate_task: z.ZodOptional<z.ZodString>;
520
+ }, z.core.$strip>>;
521
+ }, z.core.$loose>, z.ZodObject<{
522
+ type: z.ZodLiteral<"gate">;
523
+ description: z.ZodOptional<z.ZodString>;
524
+ gate_kind: z.ZodString;
525
+ group: z.ZodOptional<z.ZodString>;
526
+ }, z.core.$loose>, z.ZodObject<{
493
527
  type: z.ZodLiteral<"handoff">;
494
528
  description: z.ZodOptional<z.ZodString>;
495
529
  handoff_kind: z.ZodString;
@@ -519,6 +553,22 @@ declare const WorkflowSchema: z.ZodObject<{
519
553
  entry_conditions: z.ZodDefault<z.ZodArray<z.ZodString>>;
520
554
  trigger: z.ZodOptional<z.ZodString>;
521
555
  steps: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
556
+ type: z.ZodLiteral<"delegate">;
557
+ description: z.ZodOptional<z.ZodString>;
558
+ task: z.ZodString;
559
+ from_agent: z.ZodString;
560
+ group: z.ZodOptional<z.ZodString>;
561
+ retry: z.ZodOptional<z.ZodObject<{
562
+ condition: z.ZodString;
563
+ fix_task: z.ZodString;
564
+ revalidate_task: z.ZodOptional<z.ZodString>;
565
+ }, z.core.$strip>>;
566
+ }, z.core.$loose>, z.ZodObject<{
567
+ type: z.ZodLiteral<"gate">;
568
+ description: z.ZodOptional<z.ZodString>;
569
+ gate_kind: z.ZodString;
570
+ group: z.ZodOptional<z.ZodString>;
571
+ }, z.core.$loose>, z.ZodObject<{
522
572
  type: z.ZodLiteral<"handoff">;
523
573
  description: z.ZodOptional<z.ZodString>;
524
574
  handoff_kind: z.ZodString;
package/dist/index.js CHANGED
@@ -58419,7 +58419,8 @@ var TaskSchema = z6.object({
58419
58419
  completion_criteria: z6.array(z6.string()).optional(),
58420
58420
  rules: z6.array(RuleSchema).optional(),
58421
58421
  anti_patterns: z6.array(z6.string()).optional(),
58422
- escalation_criteria: z6.array(EscalationCriterionSchema).optional()
58422
+ escalation_criteria: z6.array(EscalationCriterionSchema).optional(),
58423
+ validations: z6.array(z6.string()).default([])
58423
58424
  }).passthrough();
58424
58425
 
58425
58426
  // src/schema/tool.ts
@@ -58465,6 +58466,20 @@ var ExternalParticipantSchema = z9.object({
58465
58466
  label: z9.string(),
58466
58467
  description: z9.string().optional()
58467
58468
  });
58469
+ var WorkflowDelegateStepSchema = z9.object({
58470
+ type: z9.literal("delegate"),
58471
+ description: z9.string().optional(),
58472
+ task: z9.string(),
58473
+ from_agent: z9.string(),
58474
+ group: z9.string().optional(),
58475
+ retry: RetrySchema.optional()
58476
+ }).passthrough();
58477
+ var WorkflowGateStepSchema = z9.object({
58478
+ type: z9.literal("gate"),
58479
+ description: z9.string().optional(),
58480
+ gate_kind: z9.string(),
58481
+ group: z9.string().optional()
58482
+ }).passthrough();
58468
58483
  var WorkflowHandoffStepSchema = z9.object({
58469
58484
  type: z9.literal("handoff"),
58470
58485
  description: z9.string().optional(),
@@ -58488,6 +58503,8 @@ var WorkflowDecisionStepSchema = z9.object({
58488
58503
  group: z9.string().optional()
58489
58504
  }).passthrough();
58490
58505
  var WorkflowStepSchema = z9.discriminatedUnion("type", [
58506
+ WorkflowDelegateStepSchema,
58507
+ WorkflowGateStepSchema,
58491
58508
  WorkflowHandoffStepSchema,
58492
58509
  WorkflowValidationStepSchema,
58493
58510
  WorkflowDecisionStepSchema
@@ -59264,12 +59281,20 @@ function checkReferences(dsl) {
59264
59281
  for (const ref of task.input_artifacts) {
59265
59282
  checkExists(ref, artifactIds, "artifacts", `tasks.${id}.input_artifacts`);
59266
59283
  }
59284
+ for (const ref of task.validations) {
59285
+ checkExists(ref, validationIds, "validations", `tasks.${id}.validations`);
59286
+ }
59267
59287
  }
59268
59288
  for (const [wfId, wf] of Object.entries(dsl.workflow)) {
59269
59289
  checkExists(wfId, workflowIds, "system.default_workflow_order", `workflow.${wfId}`);
59270
59290
  for (let j2 = 0; j2 < wf.steps.length; j2++) {
59271
59291
  const step = wf.steps[j2];
59272
- if (step.type === "handoff") {
59292
+ if (step.type === "delegate") {
59293
+ checkExists(step.task, taskIds, "tasks", `workflow.${wfId}.steps[${j2}].task`);
59294
+ checkExists(step.from_agent, agentIds, "agents", `workflow.${wfId}.steps[${j2}].from_agent`);
59295
+ } else if (step.type === "gate") {
59296
+ checkExists(step.gate_kind, handoffKinds, "handoff_types", `workflow.${wfId}.steps[${j2}].gate_kind`);
59297
+ } else if (step.type === "handoff") {
59273
59298
  if (step.task) {
59274
59299
  checkExists(step.task, taskIds, "tasks", `workflow.${wfId}.steps[${j2}].task`);
59275
59300
  }
@@ -59394,21 +59419,26 @@ var validationCoverageRule = {
59394
59419
  });
59395
59420
  }
59396
59421
  }
59397
- const validationsReferencedInWorkflow = /* @__PURE__ */ new Set();
59422
+ const referencedValidations = /* @__PURE__ */ new Set();
59398
59423
  for (const wf of Object.values(dsl.workflow)) {
59399
59424
  for (const step of wf.steps) {
59400
59425
  if (step.type === "validation") {
59401
- validationsReferencedInWorkflow.add(step.validation);
59426
+ referencedValidations.add(step.validation);
59402
59427
  }
59403
59428
  }
59404
59429
  }
59430
+ for (const task of Object.values(dsl.tasks)) {
59431
+ for (const valId of task.validations) {
59432
+ referencedValidations.add(valId);
59433
+ }
59434
+ }
59405
59435
  for (const [valId, val] of Object.entries(dsl.validations)) {
59406
- if (val.blocking && !validationsReferencedInWorkflow.has(valId)) {
59436
+ if (val.blocking && !referencedValidations.has(valId)) {
59407
59437
  diagnostics.push({
59408
59438
  ruleId: "validation-coverage",
59409
59439
  severity: "warning",
59410
59440
  path: `validations.${valId}`,
59411
- message: `Blocking validation "${valId}" is not referenced in any workflow step`
59441
+ message: `Blocking validation "${valId}" is not referenced in any workflow step or task`
59412
59442
  });
59413
59443
  }
59414
59444
  }
@@ -59884,6 +59914,28 @@ var workflow_handoff_kind_exists_default = (0, import_spectral_core6.createRules
59884
59914
  for (let i3 = 0; i3 < steps.length; i3++) {
59885
59915
  const step = steps[i3];
59886
59916
  const stepPath = [...context.path, "steps", i3];
59917
+ if (step.type === "delegate") {
59918
+ if (step.task && !taskKeys.has(step.task)) {
59919
+ results.push({
59920
+ message: `task "${step.task}" does not exist in tasks`,
59921
+ path: [...stepPath, "task"]
59922
+ });
59923
+ }
59924
+ if (step.from_agent && !agentKeys.has(step.from_agent)) {
59925
+ results.push({
59926
+ message: `from_agent "${step.from_agent}" does not exist in agents`,
59927
+ path: [...stepPath, "from_agent"]
59928
+ });
59929
+ }
59930
+ }
59931
+ if (step.type === "gate") {
59932
+ if (step.gate_kind && !handoffKeys.has(step.gate_kind)) {
59933
+ results.push({
59934
+ message: `gate_kind "${step.gate_kind}" does not exist in handoff_types`,
59935
+ path: [...stepPath, "gate_kind"]
59936
+ });
59937
+ }
59938
+ }
59887
59939
  if (step.type === "handoff") {
59888
59940
  if (step.handoff_kind && !handoffKeys.has(step.handoff_kind)) {
59889
59941
  results.push({
@@ -60097,6 +60149,17 @@ var ruleset = {
60097
60149
  functionOptions: { referenceTo: "artifacts" }
60098
60150
  }
60099
60151
  },
60152
+ "task-validations-ref": {
60153
+ description: "Task validations must reference existing validations",
60154
+ message: "{{error}}",
60155
+ severity: "error",
60156
+ given: "$.tasks.*",
60157
+ then: {
60158
+ field: "validations",
60159
+ function: ref_exists_default,
60160
+ functionOptions: { referenceTo: "validations" }
60161
+ }
60162
+ },
60100
60163
  "validation-target-artifact-ref": {
60101
60164
  description: "Validation target_artifact must reference an existing artifact",
60102
60165
  message: "{{error}}",
@@ -60140,7 +60203,7 @@ var ruleset = {
60140
60203
  },
60141
60204
  // ========== 15.2.5 Handoff integrity ==========
60142
60205
  "workflow-step-refs": {
60143
- description: "Workflow step references (handoff_kind, task, from_agent, validation) must exist",
60206
+ description: "Workflow step references (task, from_agent, gate_kind, handoff_kind, validation) must exist",
60144
60207
  message: "{{error}}",
60145
60208
  severity: "error",
60146
60209
  given: "$.workflow.*",
@@ -60407,7 +60470,23 @@ function buildHandoffTypeContext(dsl, handoffTypeId) {
60407
60470
  function buildWorkflowContext(dsl, workflowId) {
60408
60471
  const wfDef = dsl.workflow[workflowId];
60409
60472
  const workflow = { ...wfDef, id: workflowId };
60410
- const relatedTasks = Object.entries(dsl.tasks).filter(([, t3]) => t3.workflow === workflowId).map(([id, t3]) => ({ ...t3, id }));
60473
+ const stepReferencedTaskIds = /* @__PURE__ */ new Set();
60474
+ for (const step of wfDef.steps) {
60475
+ if (step.type === "delegate") {
60476
+ stepReferencedTaskIds.add(step.task);
60477
+ if (step.retry) {
60478
+ stepReferencedTaskIds.add(step.retry.fix_task);
60479
+ if (step.retry.revalidate_task) stepReferencedTaskIds.add(step.retry.revalidate_task);
60480
+ }
60481
+ } else if (step.type === "handoff" && step.task) {
60482
+ stepReferencedTaskIds.add(step.task);
60483
+ if (step.retry) {
60484
+ stepReferencedTaskIds.add(step.retry.fix_task);
60485
+ if (step.retry.revalidate_task) stepReferencedTaskIds.add(step.retry.revalidate_task);
60486
+ }
60487
+ }
60488
+ }
60489
+ const relatedTasks = Object.entries(dsl.tasks).filter(([id, t3]) => t3.workflow === workflowId || stepReferencedTaskIds.has(id)).map(([id, t3]) => ({ ...t3, id }));
60411
60490
  const agentIds = /* @__PURE__ */ new Set();
60412
60491
  for (const task of relatedTasks) {
60413
60492
  agentIds.add(task.target_agent);
@@ -60416,7 +60495,9 @@ function buildWorkflowContext(dsl, workflowId) {
60416
60495
  }
60417
60496
  }
60418
60497
  for (const step of wfDef.steps) {
60419
- if (step.type === "handoff" && step.from_agent) {
60498
+ if (step.type === "delegate") {
60499
+ agentIds.add(step.from_agent);
60500
+ } else if (step.type === "handoff" && step.from_agent) {
60420
60501
  agentIds.add(step.from_agent);
60421
60502
  }
60422
60503
  if (step.type === "validation") {
@@ -60473,6 +60554,11 @@ function buildWorkflowContext(dsl, workflowId) {
60473
60554
  validationIds.add(step.validation);
60474
60555
  }
60475
60556
  }
60557
+ for (const task of relatedTasks) {
60558
+ for (const valId of task.validations ?? []) {
60559
+ validationIds.add(valId);
60560
+ }
60561
+ }
60476
60562
  const relatedValidations = {};
60477
60563
  for (const id of validationIds) {
60478
60564
  if (dsl.validations[id]) relatedValidations[id] = dsl.validations[id];
@@ -60643,33 +60729,34 @@ function collectReferencedIds(workflow, dsl, relatedTasks) {
60643
60729
  const artifacts = /* @__PURE__ */ new Set();
60644
60730
  const taskMap = /* @__PURE__ */ new Map();
60645
60731
  for (const t3 of relatedTasks) taskMap.set(t3.id, t3);
60732
+ function collectTaskIds(task) {
60733
+ addAgent(task.target_agent);
60734
+ for (const es of task.execution_steps ?? []) {
60735
+ collectExecutionStepIds(es, tools, artifacts);
60736
+ }
60737
+ }
60738
+ function collectRetryIds(retry) {
60739
+ const fixTask = taskMap.get(retry.fix_task);
60740
+ if (fixTask) collectTaskIds(fixTask);
60741
+ if (retry.revalidate_task) {
60742
+ const revalTask = taskMap.get(retry.revalidate_task);
60743
+ if (revalTask) addAgent(revalTask.target_agent);
60744
+ }
60745
+ }
60646
60746
  for (const step of workflow.steps) {
60647
- if (step.type === "handoff") {
60747
+ if (step.type === "delegate") {
60748
+ addAgent(step.from_agent);
60749
+ const task = taskMap.get(step.task);
60750
+ if (task) collectTaskIds(task);
60751
+ if (step.retry) collectRetryIds(step.retry);
60752
+ } else if (step.type === "gate") {
60753
+ } else if (step.type === "handoff") {
60648
60754
  if (step.from_agent) addAgent(step.from_agent);
60649
60755
  if (step.task) {
60650
60756
  const task = taskMap.get(step.task);
60651
- if (task) {
60652
- addAgent(task.target_agent);
60653
- for (const es of task.execution_steps ?? []) {
60654
- collectExecutionStepIds(es, tools, artifacts);
60655
- }
60656
- }
60657
- }
60658
- if (step.retry) {
60659
- const fixTask = taskMap.get(step.retry.fix_task);
60660
- if (fixTask) {
60661
- addAgent(fixTask.target_agent);
60662
- for (const es of fixTask.execution_steps ?? []) {
60663
- collectExecutionStepIds(es, tools, artifacts);
60664
- }
60665
- }
60666
- if (step.retry.revalidate_task) {
60667
- const revalTask = taskMap.get(step.retry.revalidate_task);
60668
- if (revalTask) {
60669
- addAgent(revalTask.target_agent);
60670
- }
60671
- }
60757
+ if (task) collectTaskIds(task);
60672
60758
  }
60759
+ if (step.retry) collectRetryIds(step.retry);
60673
60760
  } else if (step.type === "validation") {
60674
60761
  const val = dsl.validations[step.validation];
60675
60762
  if (val) {
@@ -60857,16 +60944,33 @@ function emitDecisionStep(step, participants, lastFromAgent, lines, indent) {
60857
60944
  }
60858
60945
  lines.push(`${indent}end`);
60859
60946
  }
60860
- function emitRetryBlock(step, participants, dsl, relatedTasks, lines, indent) {
60861
- const retry = step.retry;
60862
- if (!retry) return;
60947
+ function emitDelegateStep(step, participants, dsl, relatedTasks, lines, indent) {
60948
+ const taskMap = /* @__PURE__ */ new Map();
60949
+ for (const t3 of relatedTasks) taskMap.set(t3.id, t3);
60950
+ const task = taskMap.get(step.task);
60951
+ if (!task) return;
60952
+ const fromAlias = participantAlias(participants, step.from_agent);
60953
+ const targetAlias = participantAlias(participants, task.target_agent);
60954
+ lines.push(`${indent}${fromAlias}->>${targetAlias}: delegate ${step.task}`);
60955
+ for (const es of task.execution_steps ?? []) {
60956
+ emitExecutionStep(es, targetAlias, participants, lines, indent);
60957
+ }
60958
+ lines.push(`${indent}${targetAlias}-->>${fromAlias}: ${task.result_handoff}`);
60959
+ }
60960
+ function emitGateStep(step, participants, lastFromAgent, lines, indent) {
60961
+ if (lastFromAgent) {
60962
+ const agentAl = participantAlias(participants, lastFromAgent);
60963
+ lines.push(`${indent}${agentAl}->>${agentAl}: ${step.gate_kind}`);
60964
+ }
60965
+ }
60966
+ function emitRetryBlock(fromAgent, retry, participants, relatedTasks, lines, indent) {
60863
60967
  const taskMap = /* @__PURE__ */ new Map();
60864
60968
  for (const t3 of relatedTasks) taskMap.set(t3.id, t3);
60865
60969
  lines.push(`${indent}opt ${retry.condition}`);
60866
60970
  const innerIndent = indent + " ";
60867
60971
  const fixTask = taskMap.get(retry.fix_task);
60868
60972
  if (fixTask) {
60869
- const fromAlias = step.from_agent ? participantAlias(participants, step.from_agent) : null;
60973
+ const fromAlias = fromAgent ? participantAlias(participants, fromAgent) : null;
60870
60974
  const targetAlias = participantAlias(participants, fixTask.target_agent);
60871
60975
  if (fromAlias) {
60872
60976
  lines.push(`${innerIndent}${fromAlias}->>${targetAlias}: fix ${retry.fix_task}`);
@@ -60881,7 +60985,7 @@ function emitRetryBlock(step, participants, dsl, relatedTasks, lines, indent) {
60881
60985
  if (retry.revalidate_task) {
60882
60986
  const revalTask = taskMap.get(retry.revalidate_task);
60883
60987
  if (revalTask) {
60884
- const fromAlias = step.from_agent ? participantAlias(participants, step.from_agent) : null;
60988
+ const fromAlias = fromAgent ? participantAlias(participants, fromAgent) : null;
60885
60989
  const revalAlias = participantAlias(participants, revalTask.target_agent);
60886
60990
  if (fromAlias) {
60887
60991
  lines.push(`${innerIndent}${fromAlias}->>${revalAlias}: revalidate ${retry.revalidate_task}`);
@@ -60968,11 +61072,19 @@ function generateSequenceDiagram(workflow, relatedTasks, dsl) {
60968
61072
  return lines.join("\n");
60969
61073
  }
60970
61074
  function emitStep(step, participants, dsl, relatedTasks, lines, indent, lastFromAgent, setLastFromAgent) {
60971
- if (step.type === "handoff") {
61075
+ if (step.type === "delegate") {
61076
+ setLastFromAgent(step.from_agent);
61077
+ emitDelegateStep(step, participants, dsl, relatedTasks, lines, indent);
61078
+ if (step.retry) {
61079
+ emitRetryBlock(step.from_agent, step.retry, participants, relatedTasks, lines, indent);
61080
+ }
61081
+ } else if (step.type === "gate") {
61082
+ emitGateStep(step, participants, lastFromAgent, lines, indent);
61083
+ } else if (step.type === "handoff") {
60972
61084
  if (step.from_agent) setLastFromAgent(step.from_agent);
60973
61085
  emitHandoffStep(step, participants, dsl, relatedTasks, lines, indent);
60974
61086
  if (step.retry) {
60975
- emitRetryBlock(step, participants, dsl, relatedTasks, lines, indent);
61087
+ emitRetryBlock(step.from_agent, step.retry, participants, relatedTasks, lines, indent);
60976
61088
  }
60977
61089
  } else if (step.type === "validation") {
60978
61090
  emitValidationStep(step, participants, dsl, lastFromAgent, lines, indent);
@@ -60993,28 +61105,34 @@ function collectPhaseOps(dsl, wfId) {
60993
61105
  map.get(id).add(op);
60994
61106
  }
60995
61107
  const taskMap = new Map(ctx.relatedTasks.map((t3) => [t3.id, t3]));
61108
+ function collectTaskOps(task) {
61109
+ addOp(agentOps, task.target_agent, "execute");
61110
+ for (const es of task.execution_steps ?? []) {
61111
+ if (es.reads_artifact) addOp(artifactOps, es.reads_artifact, "R");
61112
+ if (es.produces_artifact) addOp(artifactOps, es.produces_artifact, "W");
61113
+ if (es.uses_tool) {
61114
+ const tool = dsl.tools[es.uses_tool];
61115
+ if (tool) {
61116
+ const cats = tool.commands.map((c2) => c2.category).filter((v2, i3, a3) => a3.indexOf(v2) === i3);
61117
+ for (const cat of cats) addOp(toolOps, es.uses_tool, cat);
61118
+ if (cats.length === 0) addOp(toolOps, es.uses_tool, "\u2713");
61119
+ } else {
61120
+ addOp(toolOps, es.uses_tool, "\u2713");
61121
+ }
61122
+ }
61123
+ }
61124
+ }
60996
61125
  for (const step of wf.steps) {
60997
- if (step.type === "handoff") {
61126
+ if (step.type === "delegate") {
61127
+ addOp(agentOps, step.from_agent, "delegate");
61128
+ const task = taskMap.get(step.task);
61129
+ if (task) collectTaskOps(task);
61130
+ } else if (step.type === "gate") {
61131
+ } else if (step.type === "handoff") {
60998
61132
  if (step.from_agent) addOp(agentOps, step.from_agent, "delegate");
60999
61133
  if (step.task) {
61000
61134
  const task = taskMap.get(step.task);
61001
- if (task) {
61002
- addOp(agentOps, task.target_agent, "execute");
61003
- for (const es of task.execution_steps ?? []) {
61004
- if (es.reads_artifact) addOp(artifactOps, es.reads_artifact, "R");
61005
- if (es.produces_artifact) addOp(artifactOps, es.produces_artifact, "W");
61006
- if (es.uses_tool) {
61007
- const tool = dsl.tools[es.uses_tool];
61008
- if (tool) {
61009
- const cats = tool.commands.map((c2) => c2.category).filter((v2, i3, a3) => a3.indexOf(v2) === i3);
61010
- for (const cat of cats) addOp(toolOps, es.uses_tool, cat);
61011
- if (cats.length === 0) addOp(toolOps, es.uses_tool, "\u2713");
61012
- } else {
61013
- addOp(toolOps, es.uses_tool, "\u2713");
61014
- }
61015
- }
61016
- }
61017
- }
61135
+ if (task) collectTaskOps(task);
61018
61136
  }
61019
61137
  } else if (step.type === "validation") {
61020
61138
  const val = dsl.validations[step.validation];