@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 +67 -71
- package/dist/index.js +67 -71
- package/package.json +3 -3
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
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
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
|
-
`
|
|
3622
|
+
`Invocation state contains unknown Worker "${workerId}".`
|
|
3590
3623
|
);
|
|
3591
3624
|
}
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
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
|
|
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
|
|
3679
|
+
const topologyWorkerIds = lifecycle.topology.map((worker) => worker.id);
|
|
3681
3680
|
logger4.info("Worker initialization started", {
|
|
3682
|
-
workerCount:
|
|
3681
|
+
workerCount: topologyWorkerIds.length,
|
|
3683
3682
|
statusOverrideCount: Object.keys(state.workers).length
|
|
3684
3683
|
});
|
|
3685
3684
|
let workers;
|
|
3686
3685
|
try {
|
|
3687
|
-
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
|
|
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).
|
|
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
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
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
|
-
`
|
|
3522
|
+
`Invocation state contains unknown Worker "${workerId}".`
|
|
3490
3523
|
);
|
|
3491
3524
|
}
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
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
|
|
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
|
|
3579
|
+
const topologyWorkerIds = lifecycle.topology.map((worker) => worker.id);
|
|
3581
3580
|
logger4.info("Worker initialization started", {
|
|
3582
|
-
workerCount:
|
|
3581
|
+
workerCount: topologyWorkerIds.length,
|
|
3583
3582
|
statusOverrideCount: Object.keys(state.workers).length
|
|
3584
3583
|
});
|
|
3585
3584
|
let workers;
|
|
3586
3585
|
try {
|
|
3587
|
-
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
|
|
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).
|
|
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.
|
|
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.
|
|
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.
|
|
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",
|