@agentforge/patterns 0.17.0 → 0.17.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/dist/index.cjs CHANGED
@@ -3573,49 +3573,72 @@ function admitWorkerTopology(workers) {
3573
3573
  let workerCapabilities = Object.freeze(
3574
3574
  Object.fromEntries(topology.map((worker) => [worker.id, worker.capabilities]))
3575
3575
  );
3576
+ const publishRoutingSkills = (updates) => {
3577
+ if (updates.length === 0) {
3578
+ return;
3579
+ }
3580
+ validateIdentities(updates);
3581
+ const replacements = updates.map((update) => {
3582
+ const current = workerCapabilities[update.id];
3583
+ if (!Object.hasOwn(workerCapabilities, update.id) || !current) {
3584
+ throw new WorkerLifecycleError(
3585
+ "unknown-worker",
3586
+ `Cannot update unknown Worker "${update.id}" after compilation.`
3587
+ );
3588
+ }
3589
+ if (update.assertedTools !== void 0) {
3590
+ const assertedTools = [...normalizeWorkerToolNames(update.id, update.assertedTools)].sort();
3591
+ const executableTools = [...current.tools].sort();
3592
+ if (assertedTools.length !== executableTools.length || assertedTools.some((toolName, index) => toolName !== executableTools[index])) {
3593
+ throw new WorkerLifecycleError(
3594
+ "invalid-tool",
3595
+ `Worker "${update.id}" tools do not match its compiled executable tools.`
3596
+ );
3597
+ }
3598
+ }
3599
+ return [
3600
+ update.id,
3601
+ asCompatibleWorkerCapabilities(
3602
+ Object.freeze({
3603
+ ...current,
3604
+ skills: Object.freeze([...update.skills])
3605
+ })
3606
+ )
3607
+ ];
3608
+ });
3609
+ workerCapabilities = Object.freeze({
3610
+ ...workerCapabilities,
3611
+ ...Object.fromEntries(replacements)
3612
+ });
3613
+ };
3576
3614
  return Object.freeze({
3577
3615
  topology,
3578
- captureWorkerSnapshot: () => workerCapabilities,
3579
- updateRoutingSkills: (updates) => {
3580
- if (updates.length === 0) {
3581
- return;
3582
- }
3583
- validateIdentities(updates);
3584
- const replacements = updates.map((update) => {
3585
- const current = workerCapabilities[update.id];
3586
- if (!Object.hasOwn(workerCapabilities, update.id) || !current) {
3616
+ captureSnapshot: (statusOverrides) => {
3617
+ const publishedCapabilities = workerCapabilities;
3618
+ for (const workerId of Object.keys(statusOverrides)) {
3619
+ if (!Object.hasOwn(publishedCapabilities, workerId)) {
3587
3620
  throw new WorkerLifecycleError(
3588
3621
  "unknown-worker",
3589
- `Cannot update unknown Worker "${update.id}" after compilation.`
3622
+ `Invocation state contains unknown Worker "${workerId}".`
3590
3623
  );
3591
3624
  }
3592
- if (update.assertedTools !== void 0) {
3593
- const assertedTools = [
3594
- ...normalizeWorkerToolNames(update.id, update.assertedTools)
3595
- ].sort();
3596
- const executableTools = [...current.tools].sort();
3597
- if (assertedTools.length !== executableTools.length || assertedTools.some((toolName, index) => toolName !== executableTools[index])) {
3598
- throw new WorkerLifecycleError(
3599
- "invalid-tool",
3600
- `Worker "${update.id}" tools do not match its compiled executable tools.`
3601
- );
3602
- }
3603
- }
3604
- return [
3605
- update.id,
3606
- asCompatibleWorkerCapabilities(
3607
- Object.freeze({
3608
- ...current,
3609
- skills: Object.freeze([...update.skills])
3610
- })
3611
- )
3612
- ];
3613
- });
3614
- workerCapabilities = Object.freeze({
3615
- ...workerCapabilities,
3616
- ...Object.fromEntries(replacements)
3617
- });
3618
- }
3625
+ }
3626
+ return Object.fromEntries(
3627
+ Object.entries(publishedCapabilities).map(([workerId, capabilities]) => {
3628
+ const status = Object.hasOwn(statusOverrides, workerId) ? statusOverrides[workerId] : capabilities;
3629
+ return [
3630
+ workerId,
3631
+ {
3632
+ skills: [...capabilities.skills],
3633
+ tools: [...capabilities.tools],
3634
+ available: status.available,
3635
+ currentWorkload: status.currentWorkload
3636
+ }
3637
+ ];
3638
+ })
3639
+ );
3640
+ },
3641
+ publishRoutingSkills
3619
3642
  });
3620
3643
  }
3621
3644
  function associateWorkerLifecycle(system, lifecycle) {
@@ -3651,45 +3674,21 @@ function createWorkerRegistryData(workers) {
3651
3674
 
3652
3675
  // src/multi-agent/worker-initialization.ts
3653
3676
  var logger4 = createPatternLogger("agentforge:patterns:multi-agent:worker-initialization");
3654
- function initializeWorkerState(topologyCapabilities, invocationWorkers) {
3655
- for (const workerId of Object.keys(invocationWorkers)) {
3656
- if (!Object.hasOwn(topologyCapabilities, workerId)) {
3657
- throw new WorkerLifecycleError(
3658
- "unknown-worker",
3659
- `Invocation state contains unknown Worker "${workerId}".`
3660
- );
3661
- }
3662
- }
3663
- return Object.fromEntries(
3664
- Object.entries(topologyCapabilities).map(([workerId, capabilities]) => {
3665
- const status = Object.hasOwn(invocationWorkers, workerId) ? invocationWorkers[workerId] : capabilities;
3666
- return [
3667
- workerId,
3668
- {
3669
- skills: [...capabilities.skills],
3670
- tools: [...capabilities.tools],
3671
- available: status.available,
3672
- currentWorkload: status.currentWorkload
3673
- }
3674
- ];
3675
- })
3676
- );
3677
- }
3678
- function createWorkerInitializationNode(captureWorkerSnapshot) {
3677
+ function createWorkerInitializationNode(lifecycle) {
3679
3678
  return async (state) => {
3680
- const topologyCapabilities = captureWorkerSnapshot();
3679
+ const topologyWorkerIds = lifecycle.topology.map((worker) => worker.id);
3681
3680
  logger4.info("Worker initialization started", {
3682
- workerCount: Object.keys(topologyCapabilities).length,
3681
+ workerCount: topologyWorkerIds.length,
3683
3682
  statusOverrideCount: Object.keys(state.workers).length
3684
3683
  });
3685
3684
  let workers;
3686
3685
  try {
3687
- workers = initializeWorkerState(topologyCapabilities, state.workers);
3686
+ workers = lifecycle.captureSnapshot(state.workers);
3688
3687
  } catch (error) {
3689
3688
  logger4.error("Worker initialization failed", {
3690
3689
  error: error instanceof Error ? error.message : String(error),
3691
3690
  invocationWorkerIds: Object.keys(state.workers),
3692
- topologyWorkerIds: Object.keys(topologyCapabilities)
3691
+ topologyWorkerIds
3693
3692
  });
3694
3693
  throw error;
3695
3694
  }
@@ -3759,10 +3758,7 @@ function createCompiledMultiAgentSystem(config, lifecycle = admitWorkerTopology(
3759
3758
  const { supervisor, aggregator, maxIterations = 10, verbose = false, checkpointer } = config;
3760
3759
  const workflow = new import_langgraph4.StateGraph(MultiAgentState);
3761
3760
  const workerIds = [];
3762
- workflow.addNode(
3763
- "initializeWorkers",
3764
- createWorkerInitializationNode(lifecycle.captureWorkerSnapshot)
3765
- );
3761
+ workflow.addNode("initializeWorkers", createWorkerInitializationNode(lifecycle));
3766
3762
  workflow.addNode("supervisor", createSupervisorNode({ ...supervisor, maxIterations, verbose }));
3767
3763
  for (const workerConfig of lifecycle.topology) {
3768
3764
  workflow.addNode(
@@ -3800,7 +3796,7 @@ function createCompiledMultiAgentSystem(config, lifecycle = admitWorkerTopology(
3800
3796
 
3801
3797
  // src/multi-agent/agent-runtime.ts
3802
3798
  function registerWorkerCapabilities(system, workers) {
3803
- resolveWorkerLifecycle(system).updateRoutingSkills(
3799
+ resolveWorkerLifecycle(system).publishRoutingSkills(
3804
3800
  workers.map((worker) => ({
3805
3801
  id: worker.name,
3806
3802
  skills: worker.capabilities,
package/dist/index.js CHANGED
@@ -3473,49 +3473,72 @@ function admitWorkerTopology(workers) {
3473
3473
  let workerCapabilities = Object.freeze(
3474
3474
  Object.fromEntries(topology.map((worker) => [worker.id, worker.capabilities]))
3475
3475
  );
3476
+ const publishRoutingSkills = (updates) => {
3477
+ if (updates.length === 0) {
3478
+ return;
3479
+ }
3480
+ validateIdentities(updates);
3481
+ const replacements = updates.map((update) => {
3482
+ const current = workerCapabilities[update.id];
3483
+ if (!Object.hasOwn(workerCapabilities, update.id) || !current) {
3484
+ throw new WorkerLifecycleError(
3485
+ "unknown-worker",
3486
+ `Cannot update unknown Worker "${update.id}" after compilation.`
3487
+ );
3488
+ }
3489
+ if (update.assertedTools !== void 0) {
3490
+ const assertedTools = [...normalizeWorkerToolNames(update.id, update.assertedTools)].sort();
3491
+ const executableTools = [...current.tools].sort();
3492
+ if (assertedTools.length !== executableTools.length || assertedTools.some((toolName, index) => toolName !== executableTools[index])) {
3493
+ throw new WorkerLifecycleError(
3494
+ "invalid-tool",
3495
+ `Worker "${update.id}" tools do not match its compiled executable tools.`
3496
+ );
3497
+ }
3498
+ }
3499
+ return [
3500
+ update.id,
3501
+ asCompatibleWorkerCapabilities(
3502
+ Object.freeze({
3503
+ ...current,
3504
+ skills: Object.freeze([...update.skills])
3505
+ })
3506
+ )
3507
+ ];
3508
+ });
3509
+ workerCapabilities = Object.freeze({
3510
+ ...workerCapabilities,
3511
+ ...Object.fromEntries(replacements)
3512
+ });
3513
+ };
3476
3514
  return Object.freeze({
3477
3515
  topology,
3478
- captureWorkerSnapshot: () => workerCapabilities,
3479
- updateRoutingSkills: (updates) => {
3480
- if (updates.length === 0) {
3481
- return;
3482
- }
3483
- validateIdentities(updates);
3484
- const replacements = updates.map((update) => {
3485
- const current = workerCapabilities[update.id];
3486
- if (!Object.hasOwn(workerCapabilities, update.id) || !current) {
3516
+ captureSnapshot: (statusOverrides) => {
3517
+ const publishedCapabilities = workerCapabilities;
3518
+ for (const workerId of Object.keys(statusOverrides)) {
3519
+ if (!Object.hasOwn(publishedCapabilities, workerId)) {
3487
3520
  throw new WorkerLifecycleError(
3488
3521
  "unknown-worker",
3489
- `Cannot update unknown Worker "${update.id}" after compilation.`
3522
+ `Invocation state contains unknown Worker "${workerId}".`
3490
3523
  );
3491
3524
  }
3492
- if (update.assertedTools !== void 0) {
3493
- const assertedTools = [
3494
- ...normalizeWorkerToolNames(update.id, update.assertedTools)
3495
- ].sort();
3496
- const executableTools = [...current.tools].sort();
3497
- if (assertedTools.length !== executableTools.length || assertedTools.some((toolName, index) => toolName !== executableTools[index])) {
3498
- throw new WorkerLifecycleError(
3499
- "invalid-tool",
3500
- `Worker "${update.id}" tools do not match its compiled executable tools.`
3501
- );
3502
- }
3503
- }
3504
- return [
3505
- update.id,
3506
- asCompatibleWorkerCapabilities(
3507
- Object.freeze({
3508
- ...current,
3509
- skills: Object.freeze([...update.skills])
3510
- })
3511
- )
3512
- ];
3513
- });
3514
- workerCapabilities = Object.freeze({
3515
- ...workerCapabilities,
3516
- ...Object.fromEntries(replacements)
3517
- });
3518
- }
3525
+ }
3526
+ return Object.fromEntries(
3527
+ Object.entries(publishedCapabilities).map(([workerId, capabilities]) => {
3528
+ const status = Object.hasOwn(statusOverrides, workerId) ? statusOverrides[workerId] : capabilities;
3529
+ return [
3530
+ workerId,
3531
+ {
3532
+ skills: [...capabilities.skills],
3533
+ tools: [...capabilities.tools],
3534
+ available: status.available,
3535
+ currentWorkload: status.currentWorkload
3536
+ }
3537
+ ];
3538
+ })
3539
+ );
3540
+ },
3541
+ publishRoutingSkills
3519
3542
  });
3520
3543
  }
3521
3544
  function associateWorkerLifecycle(system, lifecycle) {
@@ -3551,45 +3574,21 @@ function createWorkerRegistryData(workers) {
3551
3574
 
3552
3575
  // src/multi-agent/worker-initialization.ts
3553
3576
  var logger4 = createPatternLogger("agentforge:patterns:multi-agent:worker-initialization");
3554
- function initializeWorkerState(topologyCapabilities, invocationWorkers) {
3555
- for (const workerId of Object.keys(invocationWorkers)) {
3556
- if (!Object.hasOwn(topologyCapabilities, workerId)) {
3557
- throw new WorkerLifecycleError(
3558
- "unknown-worker",
3559
- `Invocation state contains unknown Worker "${workerId}".`
3560
- );
3561
- }
3562
- }
3563
- return Object.fromEntries(
3564
- Object.entries(topologyCapabilities).map(([workerId, capabilities]) => {
3565
- const status = Object.hasOwn(invocationWorkers, workerId) ? invocationWorkers[workerId] : capabilities;
3566
- return [
3567
- workerId,
3568
- {
3569
- skills: [...capabilities.skills],
3570
- tools: [...capabilities.tools],
3571
- available: status.available,
3572
- currentWorkload: status.currentWorkload
3573
- }
3574
- ];
3575
- })
3576
- );
3577
- }
3578
- function createWorkerInitializationNode(captureWorkerSnapshot) {
3577
+ function createWorkerInitializationNode(lifecycle) {
3579
3578
  return async (state) => {
3580
- const topologyCapabilities = captureWorkerSnapshot();
3579
+ const topologyWorkerIds = lifecycle.topology.map((worker) => worker.id);
3581
3580
  logger4.info("Worker initialization started", {
3582
- workerCount: Object.keys(topologyCapabilities).length,
3581
+ workerCount: topologyWorkerIds.length,
3583
3582
  statusOverrideCount: Object.keys(state.workers).length
3584
3583
  });
3585
3584
  let workers;
3586
3585
  try {
3587
- workers = initializeWorkerState(topologyCapabilities, state.workers);
3586
+ workers = lifecycle.captureSnapshot(state.workers);
3588
3587
  } catch (error) {
3589
3588
  logger4.error("Worker initialization failed", {
3590
3589
  error: error instanceof Error ? error.message : String(error),
3591
3590
  invocationWorkerIds: Object.keys(state.workers),
3592
- topologyWorkerIds: Object.keys(topologyCapabilities)
3591
+ topologyWorkerIds
3593
3592
  });
3594
3593
  throw error;
3595
3594
  }
@@ -3659,10 +3658,7 @@ function createCompiledMultiAgentSystem(config, lifecycle = admitWorkerTopology(
3659
3658
  const { supervisor, aggregator, maxIterations = 10, verbose = false, checkpointer } = config;
3660
3659
  const workflow = new StateGraph4(MultiAgentState);
3661
3660
  const workerIds = [];
3662
- workflow.addNode(
3663
- "initializeWorkers",
3664
- createWorkerInitializationNode(lifecycle.captureWorkerSnapshot)
3665
- );
3661
+ workflow.addNode("initializeWorkers", createWorkerInitializationNode(lifecycle));
3666
3662
  workflow.addNode("supervisor", createSupervisorNode({ ...supervisor, maxIterations, verbose }));
3667
3663
  for (const workerConfig of lifecycle.topology) {
3668
3664
  workflow.addNode(
@@ -3700,7 +3696,7 @@ function createCompiledMultiAgentSystem(config, lifecycle = admitWorkerTopology(
3700
3696
 
3701
3697
  // src/multi-agent/agent-runtime.ts
3702
3698
  function registerWorkerCapabilities(system, workers) {
3703
- resolveWorkerLifecycle(system).updateRoutingSkills(
3699
+ resolveWorkerLifecycle(system).publishRoutingSkills(
3704
3700
  workers.map((worker) => ({
3705
3701
  id: worker.name,
3706
3702
  skills: worker.capabilities,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentforge/patterns",
3
- "version": "0.17.0",
3
+ "version": "0.17.1",
4
4
  "description": "Production-ready agent workflow patterns for TypeScript including ReAct and Planner-Executor, built on LangGraph.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -41,13 +41,13 @@
41
41
  "url": "https://github.com/TVScoundrel/agentforge/issues"
42
42
  },
43
43
  "dependencies": {
44
- "@agentforge/core": "0.17.0",
44
+ "@agentforge/core": "0.17.1",
45
45
  "@langchain/core": "^1.1.17",
46
46
  "@langchain/langgraph": "^1.1.2",
47
47
  "zod": "^3.23.8"
48
48
  },
49
49
  "devDependencies": {
50
- "@agentforge/testing": "0.17.0",
50
+ "@agentforge/testing": "0.17.1",
51
51
  "@eslint/js": "^9.17.0",
52
52
  "@types/node": "^22.10.2",
53
53
  "eslint": "^9.17.0",