@agentforge/patterns 0.16.91 → 0.17.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/README.md +10 -3
- package/dist/index.cjs +292 -115
- package/dist/index.d.cts +42 -20
- package/dist/index.d.ts +42 -20
- package/dist/index.js +290 -115
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -333,9 +333,9 @@ function stringifyActionArguments(arguments_) {
|
|
|
333
333
|
function getLatestThought(thoughts) {
|
|
334
334
|
return thoughts[thoughts.length - 1]?.content ?? "";
|
|
335
335
|
}
|
|
336
|
-
function debugIfVerbose(
|
|
336
|
+
function debugIfVerbose(logger7, verbose, message, data) {
|
|
337
337
|
if (verbose) {
|
|
338
|
-
|
|
338
|
+
logger7.debug(message, data);
|
|
339
339
|
}
|
|
340
340
|
}
|
|
341
341
|
|
|
@@ -2167,10 +2167,7 @@ var MultiAgentStateConfig = {
|
|
|
2167
2167
|
*/
|
|
2168
2168
|
workers: {
|
|
2169
2169
|
schema: z13.record(z13.string(), WorkerCapabilitiesSchema),
|
|
2170
|
-
reducer: (
|
|
2171
|
-
...left,
|
|
2172
|
-
...right
|
|
2173
|
-
}),
|
|
2170
|
+
reducer: (_left, right) => right,
|
|
2174
2171
|
default: () => ({}),
|
|
2175
2172
|
description: "Available worker agents and their capabilities"
|
|
2176
2173
|
},
|
|
@@ -3379,163 +3376,295 @@ function createWorkerNode(config) {
|
|
|
3379
3376
|
// src/multi-agent/agent-graph.ts
|
|
3380
3377
|
import { END as END4, StateGraph as StateGraph4 } from "@langchain/langgraph";
|
|
3381
3378
|
|
|
3382
|
-
// src/multi-agent/
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3379
|
+
// src/multi-agent/worker-lifecycle.ts
|
|
3380
|
+
var WorkerLifecycleError = class extends Error {
|
|
3381
|
+
reason;
|
|
3382
|
+
constructor(reason, message) {
|
|
3383
|
+
super(message);
|
|
3384
|
+
this.name = "WorkerLifecycleError";
|
|
3385
|
+
this.reason = reason;
|
|
3386
3386
|
}
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3387
|
+
};
|
|
3388
|
+
var workerLifecycles = /* @__PURE__ */ new WeakMap();
|
|
3389
|
+
function normalizeToolName(tool, workerId, index) {
|
|
3390
|
+
const candidate = tool && typeof tool === "object" ? tool : void 0;
|
|
3391
|
+
const rawName = candidate?.metadata?.name ?? candidate?.name;
|
|
3392
|
+
const name = typeof rawName === "string" ? rawName.trim() : "";
|
|
3393
|
+
if (!name) {
|
|
3394
|
+
throw new WorkerLifecycleError(
|
|
3395
|
+
"invalid-tool",
|
|
3396
|
+
`Worker "${workerId}" has a nameless tool at index ${index}.`
|
|
3397
|
+
);
|
|
3390
3398
|
}
|
|
3391
|
-
|
|
3392
|
-
|
|
3399
|
+
return name;
|
|
3400
|
+
}
|
|
3401
|
+
function normalizeWorkerToolNames(workerId, tools) {
|
|
3402
|
+
const toolNames = (tools ?? []).map((tool, index) => normalizeToolName(tool, workerId, index));
|
|
3403
|
+
const uniqueToolNames = new Set(toolNames);
|
|
3404
|
+
if (uniqueToolNames.size !== toolNames.length) {
|
|
3405
|
+
throw new WorkerLifecycleError(
|
|
3406
|
+
"invalid-tool",
|
|
3407
|
+
`Worker "${workerId}" has duplicate normalized tool names.`
|
|
3408
|
+
);
|
|
3393
3409
|
}
|
|
3394
|
-
return
|
|
3410
|
+
return Object.freeze(toolNames);
|
|
3395
3411
|
}
|
|
3396
|
-
function
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3412
|
+
function validateIdentities(workers) {
|
|
3413
|
+
for (const worker of workers) {
|
|
3414
|
+
if (!worker.id || worker.id.trim() !== worker.id || worker.id.includes(",")) {
|
|
3415
|
+
throw new WorkerLifecycleError(
|
|
3416
|
+
"invalid-identity",
|
|
3417
|
+
`Worker identity "${worker.id}" must be non-empty, trimmed, and comma-free.`
|
|
3418
|
+
);
|
|
3419
|
+
}
|
|
3420
|
+
}
|
|
3421
|
+
const identities = /* @__PURE__ */ new Set();
|
|
3422
|
+
for (const worker of workers) {
|
|
3423
|
+
if (identities.has(worker.id)) {
|
|
3424
|
+
throw new WorkerLifecycleError(
|
|
3425
|
+
"duplicate-identity",
|
|
3426
|
+
`Worker identity "${worker.id}" appears more than once in the Worker batch.`
|
|
3427
|
+
);
|
|
3428
|
+
}
|
|
3429
|
+
identities.add(worker.id);
|
|
3430
|
+
}
|
|
3403
3431
|
}
|
|
3404
|
-
function
|
|
3432
|
+
function normalizeWorkerDeclaredCapabilities(workerId, capabilities, tools) {
|
|
3405
3433
|
return {
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
model: worker.model || fallbackModel,
|
|
3409
|
-
tools: worker.tools,
|
|
3410
|
-
systemPrompt: worker.systemPrompt
|
|
3434
|
+
skills: Object.freeze([...capabilities.skills]),
|
|
3435
|
+
tools: normalizeWorkerToolNames(workerId, tools)
|
|
3411
3436
|
};
|
|
3412
3437
|
}
|
|
3413
|
-
|
|
3414
|
-
// src/multi-agent/agent-runtime.ts
|
|
3415
|
-
function mergeWorkers(input, workerCapabilities) {
|
|
3438
|
+
function normalizeWorkerStatus(capabilities) {
|
|
3416
3439
|
return {
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
...workerCapabilities,
|
|
3420
|
-
...input.workers || {}
|
|
3421
|
-
}
|
|
3440
|
+
available: capabilities.available,
|
|
3441
|
+
currentWorkload: capabilities.currentWorkload
|
|
3422
3442
|
};
|
|
3423
3443
|
}
|
|
3424
|
-
function
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3444
|
+
function normalizeWorkerRegistryRecord(workerId, capabilities, tools) {
|
|
3445
|
+
return Object.freeze({
|
|
3446
|
+
...normalizeWorkerDeclaredCapabilities(workerId, capabilities, tools),
|
|
3447
|
+
...normalizeWorkerStatus(capabilities)
|
|
3448
|
+
});
|
|
3449
|
+
}
|
|
3450
|
+
function asCompatibleWorkerCapabilities(record) {
|
|
3451
|
+
return record;
|
|
3452
|
+
}
|
|
3453
|
+
function admitWorker(worker) {
|
|
3454
|
+
const capabilities = asCompatibleWorkerCapabilities(
|
|
3455
|
+
normalizeWorkerRegistryRecord(worker.id, worker.capabilities, worker.tools)
|
|
3456
|
+
);
|
|
3457
|
+
const tools = worker.tools ? Object.freeze([...worker.tools]) : void 0;
|
|
3458
|
+
return Object.freeze({
|
|
3459
|
+
...worker,
|
|
3460
|
+
capabilities,
|
|
3461
|
+
...tools ? { tools } : {}
|
|
3431
3462
|
});
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3463
|
+
}
|
|
3464
|
+
function admitWorkerTopology(workers) {
|
|
3465
|
+
if (workers.length === 0) {
|
|
3466
|
+
throw new WorkerLifecycleError(
|
|
3467
|
+
"empty-topology",
|
|
3468
|
+
"A Multi-Agent System requires at least one Worker."
|
|
3437
3469
|
);
|
|
3470
|
+
}
|
|
3471
|
+
validateIdentities(workers);
|
|
3472
|
+
const topology = Object.freeze(workers.map(admitWorker));
|
|
3473
|
+
let workerCapabilities = Object.freeze(
|
|
3474
|
+
Object.fromEntries(topology.map((worker) => [worker.id, worker.capabilities]))
|
|
3475
|
+
);
|
|
3476
|
+
return Object.freeze({
|
|
3477
|
+
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) {
|
|
3487
|
+
throw new WorkerLifecycleError(
|
|
3488
|
+
"unknown-worker",
|
|
3489
|
+
`Cannot update unknown Worker "${update.id}" after compilation.`
|
|
3490
|
+
);
|
|
3491
|
+
}
|
|
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
|
+
}
|
|
3438
3519
|
});
|
|
3439
|
-
return system;
|
|
3440
3520
|
}
|
|
3441
|
-
function
|
|
3442
|
-
|
|
3443
|
-
|
|
3521
|
+
function associateWorkerLifecycle(system, lifecycle) {
|
|
3522
|
+
workerLifecycles.set(system, lifecycle);
|
|
3523
|
+
}
|
|
3524
|
+
function resolveWorkerLifecycle(system) {
|
|
3525
|
+
const lifecycle = workerLifecycles.get(system);
|
|
3526
|
+
if (!lifecycle) {
|
|
3527
|
+
throw new WorkerLifecycleError(
|
|
3528
|
+
"unsupported-system",
|
|
3529
|
+
"The compiled graph was not created by the Worker lifecycle."
|
|
3530
|
+
);
|
|
3444
3531
|
}
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3532
|
+
return lifecycle;
|
|
3533
|
+
}
|
|
3534
|
+
function createWorkerRegistryData(workers) {
|
|
3535
|
+
validateIdentities(workers);
|
|
3536
|
+
return Object.freeze(
|
|
3537
|
+
Object.fromEntries(
|
|
3538
|
+
workers.map((worker) => [
|
|
3539
|
+
worker.id,
|
|
3540
|
+
asCompatibleWorkerCapabilities(
|
|
3541
|
+
normalizeWorkerRegistryRecord(
|
|
3542
|
+
worker.id,
|
|
3543
|
+
worker.capabilities,
|
|
3544
|
+
worker.capabilities.tools.map((name) => ({ name }))
|
|
3545
|
+
)
|
|
3546
|
+
)
|
|
3547
|
+
])
|
|
3548
|
+
)
|
|
3549
|
+
);
|
|
3550
|
+
}
|
|
3551
|
+
|
|
3552
|
+
// src/multi-agent/worker-initialization.ts
|
|
3553
|
+
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}".`
|
|
3454
3560
|
);
|
|
3455
|
-
}
|
|
3561
|
+
}
|
|
3456
3562
|
}
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
return
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
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) {
|
|
3579
|
+
return async (state) => {
|
|
3580
|
+
const topologyCapabilities = captureWorkerSnapshot();
|
|
3581
|
+
logger4.info("Worker initialization started", {
|
|
3582
|
+
workerCount: Object.keys(topologyCapabilities).length,
|
|
3583
|
+
statusOverrideCount: Object.keys(state.workers).length
|
|
3464
3584
|
});
|
|
3465
|
-
|
|
3585
|
+
let workers;
|
|
3586
|
+
try {
|
|
3587
|
+
workers = initializeWorkerState(topologyCapabilities, state.workers);
|
|
3588
|
+
} catch (error) {
|
|
3589
|
+
logger4.error("Worker initialization failed", {
|
|
3590
|
+
error: error instanceof Error ? error.message : String(error),
|
|
3591
|
+
invocationWorkerIds: Object.keys(state.workers),
|
|
3592
|
+
topologyWorkerIds: Object.keys(topologyCapabilities)
|
|
3593
|
+
});
|
|
3594
|
+
throw error;
|
|
3595
|
+
}
|
|
3596
|
+
logger4.info("Worker initialization complete", {
|
|
3597
|
+
workerCount: Object.keys(workers).length,
|
|
3598
|
+
workerIds: Object.keys(workers)
|
|
3599
|
+
});
|
|
3600
|
+
return { workers };
|
|
3601
|
+
};
|
|
3466
3602
|
}
|
|
3467
3603
|
|
|
3468
3604
|
// src/multi-agent/agent-graph.ts
|
|
3469
|
-
var
|
|
3605
|
+
var logger5 = createPatternLogger("agentforge:patterns:multi-agent:system");
|
|
3470
3606
|
function createSupervisorRouter() {
|
|
3471
3607
|
return (state) => {
|
|
3472
|
-
|
|
3608
|
+
logger5.debug("Supervisor router executing", {
|
|
3473
3609
|
status: state.status,
|
|
3474
3610
|
...state.currentAgent ? { currentAgent: state.currentAgent } : {},
|
|
3475
3611
|
iteration: state.iteration
|
|
3476
3612
|
});
|
|
3477
3613
|
if (state.status === "completed" || state.status === "failed") {
|
|
3478
|
-
|
|
3614
|
+
logger5.info("Supervisor router: ending workflow", { status: state.status });
|
|
3479
3615
|
return END4;
|
|
3480
3616
|
}
|
|
3481
3617
|
if (state.status === "aggregating") {
|
|
3482
|
-
|
|
3618
|
+
logger5.info("Supervisor router: routing to aggregator");
|
|
3483
3619
|
return "aggregator";
|
|
3484
3620
|
}
|
|
3485
3621
|
if (state.currentAgent && state.currentAgent !== "supervisor") {
|
|
3486
3622
|
if (state.currentAgent.includes(",")) {
|
|
3487
3623
|
const agents = state.currentAgent.split(",").map((agent) => agent.trim());
|
|
3488
|
-
|
|
3624
|
+
logger5.info("Supervisor router: parallel routing", {
|
|
3489
3625
|
agents,
|
|
3490
3626
|
count: agents.length
|
|
3491
3627
|
});
|
|
3492
3628
|
return agents;
|
|
3493
3629
|
}
|
|
3494
|
-
|
|
3630
|
+
logger5.info("Supervisor router: single agent routing", {
|
|
3495
3631
|
targetAgent: state.currentAgent
|
|
3496
3632
|
});
|
|
3497
3633
|
return state.currentAgent;
|
|
3498
3634
|
}
|
|
3499
|
-
|
|
3635
|
+
logger5.debug("Supervisor router: staying at supervisor");
|
|
3500
3636
|
return "supervisor";
|
|
3501
3637
|
};
|
|
3502
3638
|
}
|
|
3503
3639
|
function createWorkerRouter() {
|
|
3504
3640
|
return (state) => {
|
|
3505
|
-
|
|
3641
|
+
logger5.debug("Worker router executing", {
|
|
3506
3642
|
iteration: state.iteration,
|
|
3507
3643
|
completedTasks: state.completedTasks.length
|
|
3508
3644
|
});
|
|
3509
|
-
|
|
3645
|
+
logger5.debug("Worker router: returning to supervisor");
|
|
3510
3646
|
return "supervisor";
|
|
3511
3647
|
};
|
|
3512
3648
|
}
|
|
3513
3649
|
function createAggregatorRouter() {
|
|
3514
3650
|
return (state) => {
|
|
3515
|
-
|
|
3651
|
+
logger5.info("Aggregator router: ending workflow", {
|
|
3516
3652
|
completedTasks: state.completedTasks.length,
|
|
3517
3653
|
status: state.status
|
|
3518
3654
|
});
|
|
3519
3655
|
return END4;
|
|
3520
3656
|
};
|
|
3521
3657
|
}
|
|
3522
|
-
function createCompiledMultiAgentSystem(config) {
|
|
3523
|
-
const {
|
|
3524
|
-
supervisor,
|
|
3525
|
-
workers,
|
|
3526
|
-
aggregator,
|
|
3527
|
-
maxIterations = 10,
|
|
3528
|
-
verbose = false,
|
|
3529
|
-
checkpointer
|
|
3530
|
-
} = config;
|
|
3658
|
+
function createCompiledMultiAgentSystem(config, lifecycle = admitWorkerTopology(config.workers)) {
|
|
3659
|
+
const { supervisor, aggregator, maxIterations = 10, verbose = false, checkpointer } = config;
|
|
3531
3660
|
const workflow = new StateGraph4(MultiAgentState);
|
|
3532
3661
|
const workerIds = [];
|
|
3533
|
-
const workerCapabilities = {};
|
|
3534
3662
|
workflow.addNode(
|
|
3535
|
-
"
|
|
3536
|
-
|
|
3663
|
+
"initializeWorkers",
|
|
3664
|
+
createWorkerInitializationNode(lifecycle.captureWorkerSnapshot)
|
|
3537
3665
|
);
|
|
3538
|
-
|
|
3666
|
+
workflow.addNode("supervisor", createSupervisorNode({ ...supervisor, maxIterations, verbose }));
|
|
3667
|
+
for (const workerConfig of lifecycle.topology) {
|
|
3539
3668
|
workflow.addNode(
|
|
3540
3669
|
workerConfig.id,
|
|
3541
3670
|
createWorkerNode({
|
|
@@ -3544,7 +3673,6 @@ function createCompiledMultiAgentSystem(config) {
|
|
|
3544
3673
|
})
|
|
3545
3674
|
);
|
|
3546
3675
|
workerIds.push(workerConfig.id);
|
|
3547
|
-
workerCapabilities[workerConfig.id] = workerConfig.capabilities;
|
|
3548
3676
|
}
|
|
3549
3677
|
workflow.addNode(
|
|
3550
3678
|
"aggregator",
|
|
@@ -3556,65 +3684,110 @@ function createCompiledMultiAgentSystem(config) {
|
|
|
3556
3684
|
const supervisorRouter = createSupervisorRouter();
|
|
3557
3685
|
const workerRouter = createWorkerRouter();
|
|
3558
3686
|
const aggregatorRouter = createAggregatorRouter();
|
|
3559
|
-
workflow.setEntryPoint("
|
|
3687
|
+
workflow.setEntryPoint("initializeWorkers");
|
|
3688
|
+
workflow.addEdge("initializeWorkers", "supervisor");
|
|
3560
3689
|
workflow.addConditionalEdges("supervisor", supervisorRouter, ["aggregator", END4, ...workerIds]);
|
|
3561
3690
|
for (const workerId of workerIds) {
|
|
3562
3691
|
workflow.addConditionalEdges(workerId, workerRouter, ["supervisor"]);
|
|
3563
3692
|
}
|
|
3564
3693
|
workflow.addConditionalEdges("aggregator", aggregatorRouter, [END4]);
|
|
3565
|
-
const
|
|
3694
|
+
const system = workflow.compile(
|
|
3566
3695
|
checkpointer ? { checkpointer } : void 0
|
|
3567
3696
|
);
|
|
3568
|
-
|
|
3697
|
+
associateWorkerLifecycle(system, lifecycle);
|
|
3698
|
+
return system;
|
|
3699
|
+
}
|
|
3700
|
+
|
|
3701
|
+
// src/multi-agent/agent-runtime.ts
|
|
3702
|
+
function registerWorkerCapabilities(system, workers) {
|
|
3703
|
+
resolveWorkerLifecycle(system).updateRoutingSkills(
|
|
3704
|
+
workers.map((worker) => ({
|
|
3705
|
+
id: worker.name,
|
|
3706
|
+
skills: worker.capabilities,
|
|
3707
|
+
...worker.tools === void 0 ? {} : { assertedTools: worker.tools }
|
|
3708
|
+
}))
|
|
3709
|
+
);
|
|
3710
|
+
}
|
|
3711
|
+
|
|
3712
|
+
// src/multi-agent/agent-workers.ts
|
|
3713
|
+
function toWorkerConfig(worker, fallbackModel) {
|
|
3714
|
+
return {
|
|
3715
|
+
id: worker.name,
|
|
3716
|
+
capabilities: {
|
|
3717
|
+
skills: worker.capabilities,
|
|
3718
|
+
tools: [],
|
|
3719
|
+
available: true,
|
|
3720
|
+
currentWorkload: 0
|
|
3721
|
+
},
|
|
3722
|
+
model: worker.model || fallbackModel,
|
|
3723
|
+
tools: worker.tools,
|
|
3724
|
+
systemPrompt: worker.systemPrompt
|
|
3725
|
+
};
|
|
3569
3726
|
}
|
|
3570
3727
|
|
|
3571
3728
|
// src/multi-agent/agent-builder.ts
|
|
3572
3729
|
var MultiAgentSystemBuilder = class {
|
|
3573
3730
|
config;
|
|
3574
|
-
|
|
3731
|
+
lifecycle;
|
|
3575
3732
|
compiled = false;
|
|
3576
3733
|
constructor(config) {
|
|
3577
3734
|
this.config = {
|
|
3578
3735
|
...config,
|
|
3579
|
-
workers:
|
|
3736
|
+
workers: []
|
|
3580
3737
|
};
|
|
3738
|
+
this.lifecycle = config.workers?.length ? admitWorkerTopology(config.workers) : void 0;
|
|
3581
3739
|
}
|
|
3582
3740
|
registerWorkers(workers) {
|
|
3583
3741
|
if (this.compiled) {
|
|
3584
3742
|
throw new Error("Cannot register workers after the system has been compiled");
|
|
3585
3743
|
}
|
|
3586
|
-
|
|
3587
|
-
|
|
3744
|
+
if (workers.length === 0) {
|
|
3745
|
+
return this;
|
|
3588
3746
|
}
|
|
3747
|
+
const existingWorkers = this.lifecycle?.topology ?? [];
|
|
3748
|
+
const pendingWorkers = workers.map(
|
|
3749
|
+
(worker) => toWorkerConfig(worker, this.config.supervisor.model)
|
|
3750
|
+
);
|
|
3751
|
+
const lifecycle = admitWorkerTopology([...existingWorkers, ...pendingWorkers]);
|
|
3752
|
+
this.lifecycle = lifecycle;
|
|
3589
3753
|
return this;
|
|
3590
3754
|
}
|
|
3591
3755
|
build() {
|
|
3592
3756
|
if (this.compiled) {
|
|
3593
3757
|
throw new Error("System has already been compiled");
|
|
3594
3758
|
}
|
|
3595
|
-
const
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3759
|
+
const lifecycle = this.lifecycle ?? admitWorkerTopology([]);
|
|
3760
|
+
const system = createCompiledMultiAgentSystem(
|
|
3761
|
+
{
|
|
3762
|
+
...this.config,
|
|
3763
|
+
workers: [...lifecycle.topology]
|
|
3764
|
+
},
|
|
3765
|
+
lifecycle
|
|
3766
|
+
);
|
|
3599
3767
|
this.compiled = true;
|
|
3600
|
-
return
|
|
3601
|
-
...this.config,
|
|
3602
|
-
workers: allWorkers
|
|
3603
|
-
});
|
|
3768
|
+
return system;
|
|
3604
3769
|
}
|
|
3605
3770
|
};
|
|
3606
3771
|
|
|
3607
3772
|
// src/multi-agent/agent.ts
|
|
3608
|
-
var
|
|
3773
|
+
var logger6 = createPatternLogger("agentforge:patterns:multi-agent:system");
|
|
3774
|
+
var systemsWarnedAboutLegacyRegistration = /* @__PURE__ */ new WeakSet();
|
|
3609
3775
|
function createMultiAgentSystem(config) {
|
|
3610
|
-
|
|
3776
|
+
const lifecycle = admitWorkerTopology(config.workers);
|
|
3777
|
+
return createCompiledMultiAgentSystem(config, lifecycle);
|
|
3611
3778
|
}
|
|
3612
3779
|
function registerWorkers(system, workers) {
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3780
|
+
if (!systemsWarnedAboutLegacyRegistration.has(system)) {
|
|
3781
|
+
systemsWarnedAboutLegacyRegistration.add(system);
|
|
3782
|
+
logger6.warn(
|
|
3783
|
+
"[AgentForge] registerWorkers() on a compiled system only updates routing skills for known Workers.\nIt does NOT add Worker nodes or change compiled tools. Use MultiAgentSystemBuilder before compilation.\nSee: https://github.com/TVScoundrel/agentforge/blob/main/packages/patterns/docs/multi-agent-pattern.md"
|
|
3784
|
+
);
|
|
3785
|
+
}
|
|
3616
3786
|
registerWorkerCapabilities(system, workers);
|
|
3617
3787
|
}
|
|
3788
|
+
function createWorkersRegistry(workers) {
|
|
3789
|
+
return createWorkerRegistryData(workers);
|
|
3790
|
+
}
|
|
3618
3791
|
export {
|
|
3619
3792
|
AgentMessageSchema,
|
|
3620
3793
|
AgentRoleSchema,
|
|
@@ -3667,6 +3840,7 @@ export {
|
|
|
3667
3840
|
ToolCallSchema,
|
|
3668
3841
|
ToolResultSchema,
|
|
3669
3842
|
WorkerCapabilitiesSchema,
|
|
3843
|
+
WorkerLifecycleError,
|
|
3670
3844
|
buildDeduplicationMetrics,
|
|
3671
3845
|
calculateDeduplicationSavings,
|
|
3672
3846
|
createAggregatorNode,
|
|
@@ -3686,6 +3860,7 @@ export {
|
|
|
3686
3860
|
createReviserNode,
|
|
3687
3861
|
createSupervisorNode,
|
|
3688
3862
|
createWorkerNode,
|
|
3863
|
+
createWorkersRegistry,
|
|
3689
3864
|
generateToolCallCacheKey,
|
|
3690
3865
|
getRoutingStrategy,
|
|
3691
3866
|
llmBasedRouting,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentforge/patterns",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
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.
|
|
44
|
+
"@agentforge/core": "0.17.0",
|
|
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.
|
|
50
|
+
"@agentforge/testing": "0.17.0",
|
|
51
51
|
"@eslint/js": "^9.17.0",
|
|
52
52
|
"@types/node": "^22.10.2",
|
|
53
53
|
"eslint": "^9.17.0",
|