@agentforge/patterns 0.16.91 → 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/README.md +10 -3
- package/dist/index.cjs +291 -118
- package/dist/index.d.cts +42 -20
- package/dist/index.d.ts +42 -20
- package/dist/index.js +289 -118
- 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,291 @@ 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
|
-
mergeWorkers(input, workerCapabilities),
|
|
3429
|
-
config
|
|
3430
|
-
);
|
|
3444
|
+
function normalizeWorkerRegistryRecord(workerId, capabilities, tools) {
|
|
3445
|
+
return Object.freeze({
|
|
3446
|
+
...normalizeWorkerDeclaredCapabilities(workerId, capabilities, tools),
|
|
3447
|
+
...normalizeWorkerStatus(capabilities)
|
|
3431
3448
|
});
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
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 } : {}
|
|
3438
3462
|
});
|
|
3439
|
-
return system;
|
|
3440
3463
|
}
|
|
3441
|
-
function
|
|
3442
|
-
if (
|
|
3443
|
-
|
|
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."
|
|
3469
|
+
);
|
|
3444
3470
|
}
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
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
|
+
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
|
+
];
|
|
3455
3508
|
});
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
system.stream = (async function(input, config) {
|
|
3460
|
-
return system._originalStream(
|
|
3461
|
-
mergeWorkers(input, system._workerRegistry || {}),
|
|
3462
|
-
config
|
|
3463
|
-
);
|
|
3509
|
+
workerCapabilities = Object.freeze({
|
|
3510
|
+
...workerCapabilities,
|
|
3511
|
+
...Object.fromEntries(replacements)
|
|
3464
3512
|
});
|
|
3513
|
+
};
|
|
3514
|
+
return Object.freeze({
|
|
3515
|
+
topology,
|
|
3516
|
+
captureSnapshot: (statusOverrides) => {
|
|
3517
|
+
const publishedCapabilities = workerCapabilities;
|
|
3518
|
+
for (const workerId of Object.keys(statusOverrides)) {
|
|
3519
|
+
if (!Object.hasOwn(publishedCapabilities, workerId)) {
|
|
3520
|
+
throw new WorkerLifecycleError(
|
|
3521
|
+
"unknown-worker",
|
|
3522
|
+
`Invocation state contains unknown Worker "${workerId}".`
|
|
3523
|
+
);
|
|
3524
|
+
}
|
|
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
|
|
3542
|
+
});
|
|
3543
|
+
}
|
|
3544
|
+
function associateWorkerLifecycle(system, lifecycle) {
|
|
3545
|
+
workerLifecycles.set(system, lifecycle);
|
|
3546
|
+
}
|
|
3547
|
+
function resolveWorkerLifecycle(system) {
|
|
3548
|
+
const lifecycle = workerLifecycles.get(system);
|
|
3549
|
+
if (!lifecycle) {
|
|
3550
|
+
throw new WorkerLifecycleError(
|
|
3551
|
+
"unsupported-system",
|
|
3552
|
+
"The compiled graph was not created by the Worker lifecycle."
|
|
3553
|
+
);
|
|
3465
3554
|
}
|
|
3555
|
+
return lifecycle;
|
|
3556
|
+
}
|
|
3557
|
+
function createWorkerRegistryData(workers) {
|
|
3558
|
+
validateIdentities(workers);
|
|
3559
|
+
return Object.freeze(
|
|
3560
|
+
Object.fromEntries(
|
|
3561
|
+
workers.map((worker) => [
|
|
3562
|
+
worker.id,
|
|
3563
|
+
asCompatibleWorkerCapabilities(
|
|
3564
|
+
normalizeWorkerRegistryRecord(
|
|
3565
|
+
worker.id,
|
|
3566
|
+
worker.capabilities,
|
|
3567
|
+
worker.capabilities.tools.map((name) => ({ name }))
|
|
3568
|
+
)
|
|
3569
|
+
)
|
|
3570
|
+
])
|
|
3571
|
+
)
|
|
3572
|
+
);
|
|
3573
|
+
}
|
|
3574
|
+
|
|
3575
|
+
// src/multi-agent/worker-initialization.ts
|
|
3576
|
+
var logger4 = createPatternLogger("agentforge:patterns:multi-agent:worker-initialization");
|
|
3577
|
+
function createWorkerInitializationNode(lifecycle) {
|
|
3578
|
+
return async (state) => {
|
|
3579
|
+
const topologyWorkerIds = lifecycle.topology.map((worker) => worker.id);
|
|
3580
|
+
logger4.info("Worker initialization started", {
|
|
3581
|
+
workerCount: topologyWorkerIds.length,
|
|
3582
|
+
statusOverrideCount: Object.keys(state.workers).length
|
|
3583
|
+
});
|
|
3584
|
+
let workers;
|
|
3585
|
+
try {
|
|
3586
|
+
workers = lifecycle.captureSnapshot(state.workers);
|
|
3587
|
+
} catch (error) {
|
|
3588
|
+
logger4.error("Worker initialization failed", {
|
|
3589
|
+
error: error instanceof Error ? error.message : String(error),
|
|
3590
|
+
invocationWorkerIds: Object.keys(state.workers),
|
|
3591
|
+
topologyWorkerIds
|
|
3592
|
+
});
|
|
3593
|
+
throw error;
|
|
3594
|
+
}
|
|
3595
|
+
logger4.info("Worker initialization complete", {
|
|
3596
|
+
workerCount: Object.keys(workers).length,
|
|
3597
|
+
workerIds: Object.keys(workers)
|
|
3598
|
+
});
|
|
3599
|
+
return { workers };
|
|
3600
|
+
};
|
|
3466
3601
|
}
|
|
3467
3602
|
|
|
3468
3603
|
// src/multi-agent/agent-graph.ts
|
|
3469
|
-
var
|
|
3604
|
+
var logger5 = createPatternLogger("agentforge:patterns:multi-agent:system");
|
|
3470
3605
|
function createSupervisorRouter() {
|
|
3471
3606
|
return (state) => {
|
|
3472
|
-
|
|
3607
|
+
logger5.debug("Supervisor router executing", {
|
|
3473
3608
|
status: state.status,
|
|
3474
3609
|
...state.currentAgent ? { currentAgent: state.currentAgent } : {},
|
|
3475
3610
|
iteration: state.iteration
|
|
3476
3611
|
});
|
|
3477
3612
|
if (state.status === "completed" || state.status === "failed") {
|
|
3478
|
-
|
|
3613
|
+
logger5.info("Supervisor router: ending workflow", { status: state.status });
|
|
3479
3614
|
return END4;
|
|
3480
3615
|
}
|
|
3481
3616
|
if (state.status === "aggregating") {
|
|
3482
|
-
|
|
3617
|
+
logger5.info("Supervisor router: routing to aggregator");
|
|
3483
3618
|
return "aggregator";
|
|
3484
3619
|
}
|
|
3485
3620
|
if (state.currentAgent && state.currentAgent !== "supervisor") {
|
|
3486
3621
|
if (state.currentAgent.includes(",")) {
|
|
3487
3622
|
const agents = state.currentAgent.split(",").map((agent) => agent.trim());
|
|
3488
|
-
|
|
3623
|
+
logger5.info("Supervisor router: parallel routing", {
|
|
3489
3624
|
agents,
|
|
3490
3625
|
count: agents.length
|
|
3491
3626
|
});
|
|
3492
3627
|
return agents;
|
|
3493
3628
|
}
|
|
3494
|
-
|
|
3629
|
+
logger5.info("Supervisor router: single agent routing", {
|
|
3495
3630
|
targetAgent: state.currentAgent
|
|
3496
3631
|
});
|
|
3497
3632
|
return state.currentAgent;
|
|
3498
3633
|
}
|
|
3499
|
-
|
|
3634
|
+
logger5.debug("Supervisor router: staying at supervisor");
|
|
3500
3635
|
return "supervisor";
|
|
3501
3636
|
};
|
|
3502
3637
|
}
|
|
3503
3638
|
function createWorkerRouter() {
|
|
3504
3639
|
return (state) => {
|
|
3505
|
-
|
|
3640
|
+
logger5.debug("Worker router executing", {
|
|
3506
3641
|
iteration: state.iteration,
|
|
3507
3642
|
completedTasks: state.completedTasks.length
|
|
3508
3643
|
});
|
|
3509
|
-
|
|
3644
|
+
logger5.debug("Worker router: returning to supervisor");
|
|
3510
3645
|
return "supervisor";
|
|
3511
3646
|
};
|
|
3512
3647
|
}
|
|
3513
3648
|
function createAggregatorRouter() {
|
|
3514
3649
|
return (state) => {
|
|
3515
|
-
|
|
3650
|
+
logger5.info("Aggregator router: ending workflow", {
|
|
3516
3651
|
completedTasks: state.completedTasks.length,
|
|
3517
3652
|
status: state.status
|
|
3518
3653
|
});
|
|
3519
3654
|
return END4;
|
|
3520
3655
|
};
|
|
3521
3656
|
}
|
|
3522
|
-
function createCompiledMultiAgentSystem(config) {
|
|
3523
|
-
const {
|
|
3524
|
-
supervisor,
|
|
3525
|
-
workers,
|
|
3526
|
-
aggregator,
|
|
3527
|
-
maxIterations = 10,
|
|
3528
|
-
verbose = false,
|
|
3529
|
-
checkpointer
|
|
3530
|
-
} = config;
|
|
3657
|
+
function createCompiledMultiAgentSystem(config, lifecycle = admitWorkerTopology(config.workers)) {
|
|
3658
|
+
const { supervisor, aggregator, maxIterations = 10, verbose = false, checkpointer } = config;
|
|
3531
3659
|
const workflow = new StateGraph4(MultiAgentState);
|
|
3532
3660
|
const workerIds = [];
|
|
3533
|
-
|
|
3534
|
-
workflow.addNode(
|
|
3535
|
-
|
|
3536
|
-
createSupervisorNode({ ...supervisor, maxIterations, verbose })
|
|
3537
|
-
);
|
|
3538
|
-
for (const workerConfig of workers) {
|
|
3661
|
+
workflow.addNode("initializeWorkers", createWorkerInitializationNode(lifecycle));
|
|
3662
|
+
workflow.addNode("supervisor", createSupervisorNode({ ...supervisor, maxIterations, verbose }));
|
|
3663
|
+
for (const workerConfig of lifecycle.topology) {
|
|
3539
3664
|
workflow.addNode(
|
|
3540
3665
|
workerConfig.id,
|
|
3541
3666
|
createWorkerNode({
|
|
@@ -3544,7 +3669,6 @@ function createCompiledMultiAgentSystem(config) {
|
|
|
3544
3669
|
})
|
|
3545
3670
|
);
|
|
3546
3671
|
workerIds.push(workerConfig.id);
|
|
3547
|
-
workerCapabilities[workerConfig.id] = workerConfig.capabilities;
|
|
3548
3672
|
}
|
|
3549
3673
|
workflow.addNode(
|
|
3550
3674
|
"aggregator",
|
|
@@ -3556,65 +3680,110 @@ function createCompiledMultiAgentSystem(config) {
|
|
|
3556
3680
|
const supervisorRouter = createSupervisorRouter();
|
|
3557
3681
|
const workerRouter = createWorkerRouter();
|
|
3558
3682
|
const aggregatorRouter = createAggregatorRouter();
|
|
3559
|
-
workflow.setEntryPoint("
|
|
3683
|
+
workflow.setEntryPoint("initializeWorkers");
|
|
3684
|
+
workflow.addEdge("initializeWorkers", "supervisor");
|
|
3560
3685
|
workflow.addConditionalEdges("supervisor", supervisorRouter, ["aggregator", END4, ...workerIds]);
|
|
3561
3686
|
for (const workerId of workerIds) {
|
|
3562
3687
|
workflow.addConditionalEdges(workerId, workerRouter, ["supervisor"]);
|
|
3563
3688
|
}
|
|
3564
3689
|
workflow.addConditionalEdges("aggregator", aggregatorRouter, [END4]);
|
|
3565
|
-
const
|
|
3690
|
+
const system = workflow.compile(
|
|
3566
3691
|
checkpointer ? { checkpointer } : void 0
|
|
3567
3692
|
);
|
|
3568
|
-
|
|
3693
|
+
associateWorkerLifecycle(system, lifecycle);
|
|
3694
|
+
return system;
|
|
3695
|
+
}
|
|
3696
|
+
|
|
3697
|
+
// src/multi-agent/agent-runtime.ts
|
|
3698
|
+
function registerWorkerCapabilities(system, workers) {
|
|
3699
|
+
resolveWorkerLifecycle(system).publishRoutingSkills(
|
|
3700
|
+
workers.map((worker) => ({
|
|
3701
|
+
id: worker.name,
|
|
3702
|
+
skills: worker.capabilities,
|
|
3703
|
+
...worker.tools === void 0 ? {} : { assertedTools: worker.tools }
|
|
3704
|
+
}))
|
|
3705
|
+
);
|
|
3706
|
+
}
|
|
3707
|
+
|
|
3708
|
+
// src/multi-agent/agent-workers.ts
|
|
3709
|
+
function toWorkerConfig(worker, fallbackModel) {
|
|
3710
|
+
return {
|
|
3711
|
+
id: worker.name,
|
|
3712
|
+
capabilities: {
|
|
3713
|
+
skills: worker.capabilities,
|
|
3714
|
+
tools: [],
|
|
3715
|
+
available: true,
|
|
3716
|
+
currentWorkload: 0
|
|
3717
|
+
},
|
|
3718
|
+
model: worker.model || fallbackModel,
|
|
3719
|
+
tools: worker.tools,
|
|
3720
|
+
systemPrompt: worker.systemPrompt
|
|
3721
|
+
};
|
|
3569
3722
|
}
|
|
3570
3723
|
|
|
3571
3724
|
// src/multi-agent/agent-builder.ts
|
|
3572
3725
|
var MultiAgentSystemBuilder = class {
|
|
3573
3726
|
config;
|
|
3574
|
-
|
|
3727
|
+
lifecycle;
|
|
3575
3728
|
compiled = false;
|
|
3576
3729
|
constructor(config) {
|
|
3577
3730
|
this.config = {
|
|
3578
3731
|
...config,
|
|
3579
|
-
workers:
|
|
3732
|
+
workers: []
|
|
3580
3733
|
};
|
|
3734
|
+
this.lifecycle = config.workers?.length ? admitWorkerTopology(config.workers) : void 0;
|
|
3581
3735
|
}
|
|
3582
3736
|
registerWorkers(workers) {
|
|
3583
3737
|
if (this.compiled) {
|
|
3584
3738
|
throw new Error("Cannot register workers after the system has been compiled");
|
|
3585
3739
|
}
|
|
3586
|
-
|
|
3587
|
-
|
|
3740
|
+
if (workers.length === 0) {
|
|
3741
|
+
return this;
|
|
3588
3742
|
}
|
|
3743
|
+
const existingWorkers = this.lifecycle?.topology ?? [];
|
|
3744
|
+
const pendingWorkers = workers.map(
|
|
3745
|
+
(worker) => toWorkerConfig(worker, this.config.supervisor.model)
|
|
3746
|
+
);
|
|
3747
|
+
const lifecycle = admitWorkerTopology([...existingWorkers, ...pendingWorkers]);
|
|
3748
|
+
this.lifecycle = lifecycle;
|
|
3589
3749
|
return this;
|
|
3590
3750
|
}
|
|
3591
3751
|
build() {
|
|
3592
3752
|
if (this.compiled) {
|
|
3593
3753
|
throw new Error("System has already been compiled");
|
|
3594
3754
|
}
|
|
3595
|
-
const
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3755
|
+
const lifecycle = this.lifecycle ?? admitWorkerTopology([]);
|
|
3756
|
+
const system = createCompiledMultiAgentSystem(
|
|
3757
|
+
{
|
|
3758
|
+
...this.config,
|
|
3759
|
+
workers: [...lifecycle.topology]
|
|
3760
|
+
},
|
|
3761
|
+
lifecycle
|
|
3762
|
+
);
|
|
3599
3763
|
this.compiled = true;
|
|
3600
|
-
return
|
|
3601
|
-
...this.config,
|
|
3602
|
-
workers: allWorkers
|
|
3603
|
-
});
|
|
3764
|
+
return system;
|
|
3604
3765
|
}
|
|
3605
3766
|
};
|
|
3606
3767
|
|
|
3607
3768
|
// src/multi-agent/agent.ts
|
|
3608
|
-
var
|
|
3769
|
+
var logger6 = createPatternLogger("agentforge:patterns:multi-agent:system");
|
|
3770
|
+
var systemsWarnedAboutLegacyRegistration = /* @__PURE__ */ new WeakSet();
|
|
3609
3771
|
function createMultiAgentSystem(config) {
|
|
3610
|
-
|
|
3772
|
+
const lifecycle = admitWorkerTopology(config.workers);
|
|
3773
|
+
return createCompiledMultiAgentSystem(config, lifecycle);
|
|
3611
3774
|
}
|
|
3612
3775
|
function registerWorkers(system, workers) {
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3776
|
+
if (!systemsWarnedAboutLegacyRegistration.has(system)) {
|
|
3777
|
+
systemsWarnedAboutLegacyRegistration.add(system);
|
|
3778
|
+
logger6.warn(
|
|
3779
|
+
"[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"
|
|
3780
|
+
);
|
|
3781
|
+
}
|
|
3616
3782
|
registerWorkerCapabilities(system, workers);
|
|
3617
3783
|
}
|
|
3784
|
+
function createWorkersRegistry(workers) {
|
|
3785
|
+
return createWorkerRegistryData(workers);
|
|
3786
|
+
}
|
|
3618
3787
|
export {
|
|
3619
3788
|
AgentMessageSchema,
|
|
3620
3789
|
AgentRoleSchema,
|
|
@@ -3667,6 +3836,7 @@ export {
|
|
|
3667
3836
|
ToolCallSchema,
|
|
3668
3837
|
ToolResultSchema,
|
|
3669
3838
|
WorkerCapabilitiesSchema,
|
|
3839
|
+
WorkerLifecycleError,
|
|
3670
3840
|
buildDeduplicationMetrics,
|
|
3671
3841
|
calculateDeduplicationSavings,
|
|
3672
3842
|
createAggregatorNode,
|
|
@@ -3686,6 +3856,7 @@ export {
|
|
|
3686
3856
|
createReviserNode,
|
|
3687
3857
|
createSupervisorNode,
|
|
3688
3858
|
createWorkerNode,
|
|
3859
|
+
createWorkersRegistry,
|
|
3689
3860
|
generateToolCallCacheKey,
|
|
3690
3861
|
getRoutingStrategy,
|
|
3691
3862
|
llmBasedRouting,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentforge/patterns",
|
|
3
|
-
"version": "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.
|
|
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.
|
|
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",
|