@lov3kaizen/agentsea-crews 1.0.1 → 1.1.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 +56 -0
- package/dist/Crew-BnvVjN7A.d.mts +1060 -0
- package/dist/Crew-BnvVjN7A.d.ts +1060 -0
- package/dist/DebugMode-CbYgA7Yw.d.mts +190 -0
- package/dist/DebugMode-o5e9gmQ7.d.ts +190 -0
- package/dist/{chunk-TFB7N65B.mjs → chunk-3NMVWRVW.mjs} +1 -1
- package/dist/{chunk-QMK3HWFX.mjs → chunk-J5KQSOGT.mjs} +306 -61
- package/dist/index.d.mts +975 -0
- package/dist/index.d.ts +975 -0
- package/dist/index.js +335 -96
- package/dist/index.mjs +26 -25
- package/dist/nestjs/index.d.mts +98 -0
- package/dist/nestjs/index.d.ts +98 -0
- package/dist/nestjs/index.js +305 -66
- package/dist/nestjs/index.mjs +1 -1
- package/dist/templates/index.d.mts +78 -0
- package/dist/templates/index.d.ts +78 -0
- package/dist/templates/index.js +305 -66
- package/dist/templates/index.mjs +2 -2
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -77,6 +77,7 @@ __export(index_exports, {
|
|
|
77
77
|
createConflictResolver: () => createConflictResolver,
|
|
78
78
|
createConsensusStrategy: () => createConsensusStrategy,
|
|
79
79
|
createConversationHistory: () => createConversationHistory,
|
|
80
|
+
createCoreExecutor: () => createCoreExecutor,
|
|
80
81
|
createCrew: () => createCrew,
|
|
81
82
|
createCrewAgent: () => createCrewAgent,
|
|
82
83
|
createCustomerSupportCrew: () => createCustomerSupportCrew,
|
|
@@ -333,8 +334,37 @@ function createRole(config) {
|
|
|
333
334
|
return new Role(config);
|
|
334
335
|
}
|
|
335
336
|
|
|
337
|
+
// ../../node_modules/.pnpm/nanoid@5.1.6/node_modules/nanoid/index.js
|
|
338
|
+
var import_node_crypto = require("crypto");
|
|
339
|
+
|
|
340
|
+
// ../../node_modules/.pnpm/nanoid@5.1.6/node_modules/nanoid/url-alphabet/index.js
|
|
341
|
+
var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
342
|
+
|
|
343
|
+
// ../../node_modules/.pnpm/nanoid@5.1.6/node_modules/nanoid/index.js
|
|
344
|
+
var POOL_SIZE_MULTIPLIER = 128;
|
|
345
|
+
var pool;
|
|
346
|
+
var poolOffset;
|
|
347
|
+
function fillPool(bytes) {
|
|
348
|
+
if (!pool || pool.length < bytes) {
|
|
349
|
+
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
|
|
350
|
+
import_node_crypto.webcrypto.getRandomValues(pool);
|
|
351
|
+
poolOffset = 0;
|
|
352
|
+
} else if (poolOffset + bytes > pool.length) {
|
|
353
|
+
import_node_crypto.webcrypto.getRandomValues(pool);
|
|
354
|
+
poolOffset = 0;
|
|
355
|
+
}
|
|
356
|
+
poolOffset += bytes;
|
|
357
|
+
}
|
|
358
|
+
function nanoid(size = 21) {
|
|
359
|
+
fillPool(size |= 0);
|
|
360
|
+
let id = "";
|
|
361
|
+
for (let i = poolOffset - size; i < poolOffset; i++) {
|
|
362
|
+
id += urlAlphabet[pool[i] & 63];
|
|
363
|
+
}
|
|
364
|
+
return id;
|
|
365
|
+
}
|
|
366
|
+
|
|
336
367
|
// src/core/Task.ts
|
|
337
|
-
var import_nanoid = require("nanoid");
|
|
338
368
|
var Task = class _Task {
|
|
339
369
|
id;
|
|
340
370
|
description;
|
|
@@ -354,7 +384,7 @@ var Task = class _Task {
|
|
|
354
384
|
_result;
|
|
355
385
|
_metadata;
|
|
356
386
|
constructor(config) {
|
|
357
|
-
this.id = config.id ??
|
|
387
|
+
this.id = config.id ?? nanoid();
|
|
358
388
|
this.description = config.description;
|
|
359
389
|
this.expectedOutput = config.expectedOutput;
|
|
360
390
|
this.priority = config.priority ?? "medium";
|
|
@@ -966,7 +996,6 @@ function createTaskQueue(config) {
|
|
|
966
996
|
|
|
967
997
|
// src/core/ExecutionContext.ts
|
|
968
998
|
var import_eventemitter3 = __toESM(require("eventemitter3"));
|
|
969
|
-
var import_nanoid2 = require("nanoid");
|
|
970
999
|
var ExecutionContext = class {
|
|
971
1000
|
crewId;
|
|
972
1001
|
crewName;
|
|
@@ -983,7 +1012,7 @@ var ExecutionContext = class {
|
|
|
983
1012
|
startTime;
|
|
984
1013
|
endTime;
|
|
985
1014
|
constructor(config) {
|
|
986
|
-
this.crewId = config.crewId ??
|
|
1015
|
+
this.crewId = config.crewId ?? nanoid();
|
|
987
1016
|
this.crewName = config.crewName;
|
|
988
1017
|
this.state = /* @__PURE__ */ new Map();
|
|
989
1018
|
this.completedTasks = /* @__PURE__ */ new Map();
|
|
@@ -1229,7 +1258,7 @@ var ExecutionContext = class {
|
|
|
1229
1258
|
*/
|
|
1230
1259
|
createCheckpoint() {
|
|
1231
1260
|
return {
|
|
1232
|
-
id:
|
|
1261
|
+
id: nanoid(),
|
|
1233
1262
|
timestamp: /* @__PURE__ */ new Date(),
|
|
1234
1263
|
crewId: this.crewId,
|
|
1235
1264
|
crewName: this.crewName,
|
|
@@ -1318,12 +1347,6 @@ function createExecutionContext(config) {
|
|
|
1318
1347
|
return new ExecutionContext(config);
|
|
1319
1348
|
}
|
|
1320
1349
|
|
|
1321
|
-
// src/core/Crew.ts
|
|
1322
|
-
var import_nanoid4 = require("nanoid");
|
|
1323
|
-
|
|
1324
|
-
// src/agents/CrewAgent.ts
|
|
1325
|
-
var import_nanoid3 = require("nanoid");
|
|
1326
|
-
|
|
1327
1350
|
// src/agents/AgentCapabilities.ts
|
|
1328
1351
|
var PROFICIENCY_WEIGHTS2 = {
|
|
1329
1352
|
novice: 0.25,
|
|
@@ -1515,7 +1538,80 @@ var AgentCapabilities = class {
|
|
|
1515
1538
|
}
|
|
1516
1539
|
};
|
|
1517
1540
|
|
|
1541
|
+
// src/agents/CoreExecutor.ts
|
|
1542
|
+
async function loadProvider(providerName) {
|
|
1543
|
+
const ctorName = resolveProviderCtorName(providerName);
|
|
1544
|
+
let core;
|
|
1545
|
+
try {
|
|
1546
|
+
core = await import("@lov3kaizen/agentsea-core");
|
|
1547
|
+
} catch {
|
|
1548
|
+
throw new Error(
|
|
1549
|
+
'CrewAgent requires "@lov3kaizen/agentsea-core" to execute against a real LLM. Install it, or pass a custom `execute` function (or `mock: true`) to createCrewAgent / createCrew.'
|
|
1550
|
+
);
|
|
1551
|
+
}
|
|
1552
|
+
const Ctor = core[ctorName];
|
|
1553
|
+
return new Ctor();
|
|
1554
|
+
}
|
|
1555
|
+
function resolveProviderCtorName(providerName) {
|
|
1556
|
+
switch ((providerName ?? "").toLowerCase()) {
|
|
1557
|
+
case "anthropic":
|
|
1558
|
+
case "claude":
|
|
1559
|
+
return "AnthropicProvider";
|
|
1560
|
+
case "openai":
|
|
1561
|
+
case "gpt":
|
|
1562
|
+
return "OpenAIProvider";
|
|
1563
|
+
case "gemini":
|
|
1564
|
+
case "google":
|
|
1565
|
+
return "GeminiProvider";
|
|
1566
|
+
case "ollama":
|
|
1567
|
+
return "OllamaProvider";
|
|
1568
|
+
default:
|
|
1569
|
+
throw new Error(
|
|
1570
|
+
`CrewAgent: unsupported provider "${providerName}". Supported providers are: anthropic, openai, gemini, ollama. Pass a custom \`execute\` function to createCrewAgent for any other provider.`
|
|
1571
|
+
);
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
function createCoreExecutor(config, options = {}) {
|
|
1575
|
+
let providerPromise;
|
|
1576
|
+
const getProvider = () => {
|
|
1577
|
+
if (!providerPromise) {
|
|
1578
|
+
providerPromise = options.provider ? Promise.resolve(options.provider) : loadProvider(config.provider);
|
|
1579
|
+
}
|
|
1580
|
+
return providerPromise;
|
|
1581
|
+
};
|
|
1582
|
+
return async (input, systemPrompt) => {
|
|
1583
|
+
const provider = await getProvider();
|
|
1584
|
+
const start = Date.now();
|
|
1585
|
+
const response = await provider.generateResponse(
|
|
1586
|
+
[{ role: "user", content: input }],
|
|
1587
|
+
{
|
|
1588
|
+
model: config.model,
|
|
1589
|
+
systemPrompt,
|
|
1590
|
+
temperature: config.temperature,
|
|
1591
|
+
maxTokens: config.maxTokens
|
|
1592
|
+
}
|
|
1593
|
+
);
|
|
1594
|
+
return {
|
|
1595
|
+
output: response.content,
|
|
1596
|
+
tokensUsed: response.usage.inputTokens + response.usage.outputTokens,
|
|
1597
|
+
latencyMs: Date.now() - start,
|
|
1598
|
+
iterations: 1
|
|
1599
|
+
};
|
|
1600
|
+
};
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1518
1603
|
// src/agents/CrewAgent.ts
|
|
1604
|
+
function modelCostWeight(model) {
|
|
1605
|
+
const m = (model ?? "").toLowerCase();
|
|
1606
|
+
if (m.includes("opus") || m.includes("gpt-5") || m.includes("o3")) return 5;
|
|
1607
|
+
if (m.includes("sonnet") || m.includes("gpt-4.1") || m.includes("gpt-4") && !m.includes("mini") || m.includes("gemini-1.5-pro") || m.includes("gemini-2.5-pro")) {
|
|
1608
|
+
return 3;
|
|
1609
|
+
}
|
|
1610
|
+
if (m.includes("haiku") || m.includes("mini") || m.includes("flash") || m.includes("llama") || m.includes("mistral")) {
|
|
1611
|
+
return 1;
|
|
1612
|
+
}
|
|
1613
|
+
return 3;
|
|
1614
|
+
}
|
|
1519
1615
|
var CrewAgent = class _CrewAgent {
|
|
1520
1616
|
id;
|
|
1521
1617
|
name;
|
|
@@ -1535,7 +1631,7 @@ var CrewAgent = class _CrewAgent {
|
|
|
1535
1631
|
totalTokensUsed = 0;
|
|
1536
1632
|
constructor(options) {
|
|
1537
1633
|
const { config, execute } = options;
|
|
1538
|
-
this.id =
|
|
1634
|
+
this.id = nanoid();
|
|
1539
1635
|
this.name = config.name;
|
|
1540
1636
|
this.role = new Role(config.role);
|
|
1541
1637
|
this.capabilities = config.role.capabilities;
|
|
@@ -1554,10 +1650,11 @@ var CrewAgent = class _CrewAgent {
|
|
|
1554
1650
|
*/
|
|
1555
1651
|
async execute(input) {
|
|
1556
1652
|
if (!this.executeFunc) {
|
|
1653
|
+
const tokensUsed = 100 + Math.min(input.length, 400);
|
|
1557
1654
|
const mockResult = {
|
|
1558
1655
|
output: `[Mock response from ${this.name}]: ${input.slice(0, 100)}...`,
|
|
1559
|
-
tokensUsed
|
|
1560
|
-
latencyMs:
|
|
1656
|
+
tokensUsed,
|
|
1657
|
+
latencyMs: 0,
|
|
1561
1658
|
iterations: 1
|
|
1562
1659
|
};
|
|
1563
1660
|
this.totalTokensUsed += mockResult.tokensUsed;
|
|
@@ -1660,16 +1757,27 @@ ${JSON.stringify(task.context, null, 2)}`);
|
|
|
1660
1757
|
) ?? true
|
|
1661
1758
|
).map((c) => c.name);
|
|
1662
1759
|
const estimatedTime = this.estimateTaskTime(task);
|
|
1760
|
+
const estimatedCost = this.estimateTaskCost(estimatedTime);
|
|
1663
1761
|
const reasoning = this.generateBidReasoning(task, confidence, matchedCaps);
|
|
1664
1762
|
return Promise.resolve({
|
|
1665
1763
|
agentName: this.name,
|
|
1666
1764
|
taskId: task.id ?? "unknown",
|
|
1667
1765
|
confidence,
|
|
1668
1766
|
estimatedTime,
|
|
1767
|
+
estimatedCost,
|
|
1669
1768
|
reasoning,
|
|
1670
1769
|
capabilities: matchedCaps
|
|
1671
1770
|
});
|
|
1672
1771
|
}
|
|
1772
|
+
/**
|
|
1773
|
+
* Estimate a relative cost for handling a task. Combines the agent's model
|
|
1774
|
+
* price tier with the estimated effort so the auction `cheapest` criterion
|
|
1775
|
+
* can distinguish a cheap-but-slower model from an expensive-but-faster one.
|
|
1776
|
+
* The unit is arbitrary and only meaningful relative to other bids.
|
|
1777
|
+
*/
|
|
1778
|
+
estimateTaskCost(estimatedTime) {
|
|
1779
|
+
return modelCostWeight(this.model) * Math.max(estimatedTime, 1);
|
|
1780
|
+
}
|
|
1673
1781
|
/**
|
|
1674
1782
|
* Check if agent has all required capabilities
|
|
1675
1783
|
*/
|
|
@@ -1720,7 +1828,7 @@ ${JSON.stringify(task.context, null, 2)}`);
|
|
|
1720
1828
|
*/
|
|
1721
1829
|
createHelpRequest(taskId, request) {
|
|
1722
1830
|
return {
|
|
1723
|
-
requestId:
|
|
1831
|
+
requestId: nanoid(),
|
|
1724
1832
|
fromAgent: this.name,
|
|
1725
1833
|
taskId,
|
|
1726
1834
|
request
|
|
@@ -1855,7 +1963,13 @@ Please provide helpful guidance based on your expertise.
|
|
|
1855
1963
|
}
|
|
1856
1964
|
};
|
|
1857
1965
|
function createCrewAgent(options) {
|
|
1858
|
-
|
|
1966
|
+
if (options.execute || options.mock) {
|
|
1967
|
+
return new CrewAgent(options);
|
|
1968
|
+
}
|
|
1969
|
+
return new CrewAgent({
|
|
1970
|
+
...options,
|
|
1971
|
+
execute: createCoreExecutor(options.config, { provider: options.provider })
|
|
1972
|
+
});
|
|
1859
1973
|
}
|
|
1860
1974
|
|
|
1861
1975
|
// src/agents/AgentRegistry.ts
|
|
@@ -2564,9 +2678,9 @@ var AuctionStrategy = class extends BaseDelegationStrategy {
|
|
|
2564
2678
|
}, bids[0]);
|
|
2565
2679
|
case "cheapest":
|
|
2566
2680
|
return bids.reduce((best, bid) => {
|
|
2567
|
-
const
|
|
2568
|
-
const
|
|
2569
|
-
return
|
|
2681
|
+
const bestCost = best.estimatedCost ?? best.estimatedTime ?? Infinity;
|
|
2682
|
+
const bidCost = bid.estimatedCost ?? bid.estimatedTime ?? Infinity;
|
|
2683
|
+
return bidCost < bestCost ? bid : best;
|
|
2570
2684
|
}, bids[0]);
|
|
2571
2685
|
case "confidence":
|
|
2572
2686
|
default:
|
|
@@ -3055,9 +3169,8 @@ var ConsensusStrategy = class extends BaseDelegationStrategy {
|
|
|
3055
3169
|
*/
|
|
3056
3170
|
async collectVotes(task, voters, candidates) {
|
|
3057
3171
|
const votes = [];
|
|
3058
|
-
const candidateNames = candidates.map((c) => c.name);
|
|
3059
3172
|
for (const voter of voters) {
|
|
3060
|
-
const vote = await this.getVote(voter, task,
|
|
3173
|
+
const vote = await this.getVote(voter, task, candidates);
|
|
3061
3174
|
if (vote) {
|
|
3062
3175
|
votes.push(vote);
|
|
3063
3176
|
}
|
|
@@ -3065,33 +3178,35 @@ var ConsensusStrategy = class extends BaseDelegationStrategy {
|
|
|
3065
3178
|
return votes;
|
|
3066
3179
|
}
|
|
3067
3180
|
/**
|
|
3068
|
-
* Get a vote from an agent
|
|
3181
|
+
* Get a vote from an agent.
|
|
3182
|
+
*
|
|
3183
|
+
* Each voter ranks the candidates by how well their capabilities fit the
|
|
3184
|
+
* task (the same `calculateTaskScore` signal the BestMatch/Auction strategies
|
|
3185
|
+
* use), plus a small self-preference bias so an agent leans toward itself when
|
|
3186
|
+
* candidates are otherwise comparable. This is fully deterministic — given the
|
|
3187
|
+
* same agents and task it always produces the same votes — and explainable,
|
|
3188
|
+
* which is what consensus needs. (A future enhancement could replace this with
|
|
3189
|
+
* an actual LLM deliberation per voter; the tally/agreement logic is unchanged.)
|
|
3069
3190
|
*/
|
|
3070
3191
|
getVote(voter, task, candidates) {
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
}
|
|
3082
|
-
}
|
|
3083
|
-
scores.sort((a, b) => b.score - a.score);
|
|
3192
|
+
if (candidates.length === 0) return Promise.resolve(null);
|
|
3193
|
+
const SELF_PREFERENCE_BONUS = 0.15;
|
|
3194
|
+
const scores = candidates.map((candidate) => {
|
|
3195
|
+
let score = candidate.calculateTaskScore(task);
|
|
3196
|
+
if (candidate.name === voter.name) {
|
|
3197
|
+
score += SELF_PREFERENCE_BONUS;
|
|
3198
|
+
}
|
|
3199
|
+
return { name: candidate.name, score };
|
|
3200
|
+
});
|
|
3201
|
+
scores.sort((a, b) => b.score - a.score || a.name.localeCompare(b.name));
|
|
3084
3202
|
const selected = scores[0];
|
|
3085
3203
|
if (!selected) return Promise.resolve(null);
|
|
3086
|
-
|
|
3087
|
-
if (this.weightedVoting) {
|
|
3088
|
-
weight = voter.calculateTaskScore(task) || 0.5;
|
|
3089
|
-
}
|
|
3204
|
+
const weight = this.weightedVoting ? voter.calculateTaskScore(task) || 0.5 : 1;
|
|
3090
3205
|
return Promise.resolve({
|
|
3091
3206
|
voter: voter.name,
|
|
3092
3207
|
candidate: selected.name,
|
|
3093
3208
|
weight,
|
|
3094
|
-
reasoning: `
|
|
3209
|
+
reasoning: `Ranked "${selected.name}" highest by capability fit for the task (score: ${selected.score.toFixed(2)})`
|
|
3095
3210
|
});
|
|
3096
3211
|
}
|
|
3097
3212
|
/**
|
|
@@ -3964,13 +4079,24 @@ var ConflictResolver = class {
|
|
|
3964
4079
|
resolved: /* @__PURE__ */ new Date()
|
|
3965
4080
|
};
|
|
3966
4081
|
}
|
|
4082
|
+
/**
|
|
4083
|
+
* Normalize response content for equality comparison: trim, collapse runs of
|
|
4084
|
+
* whitespace, and lowercase. This groups textually-equivalent answers (ignoring
|
|
4085
|
+
* incidental formatting) over their FULL content rather than a fragile first-N
|
|
4086
|
+
* characters prefix. Note: this is exact-match-after-normalization, not semantic
|
|
4087
|
+
* similarity — agents that express the same idea with different wording will not
|
|
4088
|
+
* group. Semantic grouping would require embeddings (future enhancement).
|
|
4089
|
+
*/
|
|
4090
|
+
normalizeContent(content) {
|
|
4091
|
+
return content.trim().replace(/\s+/g, " ").toLowerCase();
|
|
4092
|
+
}
|
|
3967
4093
|
/**
|
|
3968
4094
|
* Resolve by voting
|
|
3969
4095
|
*/
|
|
3970
4096
|
resolveByVoting(conflict, _context) {
|
|
3971
4097
|
const votes = /* @__PURE__ */ new Map();
|
|
3972
4098
|
for (const response of conflict.responses) {
|
|
3973
|
-
const key = response.content
|
|
4099
|
+
const key = this.normalizeContent(response.content);
|
|
3974
4100
|
const current = votes.get(key) ?? 0;
|
|
3975
4101
|
votes.set(key, current + response.confidence);
|
|
3976
4102
|
}
|
|
@@ -3983,7 +4109,7 @@ var ConflictResolver = class {
|
|
|
3983
4109
|
}
|
|
3984
4110
|
}
|
|
3985
4111
|
const winner = conflict.responses.find(
|
|
3986
|
-
(r) => r.content
|
|
4112
|
+
(r) => this.normalizeContent(r.content) === winningKey
|
|
3987
4113
|
);
|
|
3988
4114
|
return Promise.resolve({
|
|
3989
4115
|
conflictId: conflict.id,
|
|
@@ -3999,7 +4125,31 @@ var ConflictResolver = class {
|
|
|
3999
4125
|
* Resolve by authority
|
|
4000
4126
|
*/
|
|
4001
4127
|
resolveByAuthority(conflict, _context) {
|
|
4002
|
-
|
|
4128
|
+
const ranked = conflict.responses.map((r) => ({
|
|
4129
|
+
response: r,
|
|
4130
|
+
authority: typeof r.metadata?.authority === "number" ? r.metadata.authority : void 0
|
|
4131
|
+
})).filter(
|
|
4132
|
+
(x) => x.authority !== void 0
|
|
4133
|
+
);
|
|
4134
|
+
if (ranked.length === 0) {
|
|
4135
|
+
return Promise.resolve({
|
|
4136
|
+
...this.resolveByConfidence(conflict),
|
|
4137
|
+
strategy: "authority",
|
|
4138
|
+
explanation: "No authority metadata provided; fell back to highest confidence"
|
|
4139
|
+
});
|
|
4140
|
+
}
|
|
4141
|
+
const winnerEntry = ranked.reduce(
|
|
4142
|
+
(best, cur) => cur.authority > best.authority ? cur : best
|
|
4143
|
+
);
|
|
4144
|
+
return Promise.resolve({
|
|
4145
|
+
conflictId: conflict.id,
|
|
4146
|
+
strategy: "authority",
|
|
4147
|
+
winner: winnerEntry.response,
|
|
4148
|
+
explanation: `Selected response from highest-authority agent "${winnerEntry.response.agentName}" (authority: ${winnerEntry.authority})`,
|
|
4149
|
+
successful: true,
|
|
4150
|
+
escalated: false,
|
|
4151
|
+
resolved: /* @__PURE__ */ new Date()
|
|
4152
|
+
});
|
|
4003
4153
|
}
|
|
4004
4154
|
/**
|
|
4005
4155
|
* Resolve by consensus
|
|
@@ -4007,7 +4157,7 @@ var ConflictResolver = class {
|
|
|
4007
4157
|
resolveByConsensus(conflict, _context) {
|
|
4008
4158
|
const contentGroups = /* @__PURE__ */ new Map();
|
|
4009
4159
|
for (const response of conflict.responses) {
|
|
4010
|
-
const key = response.content
|
|
4160
|
+
const key = this.normalizeContent(response.content);
|
|
4011
4161
|
const group = contentGroups.get(key) ?? [];
|
|
4012
4162
|
group.push(response);
|
|
4013
4163
|
contentGroups.set(key, group);
|
|
@@ -4150,7 +4300,7 @@ var Crew = class {
|
|
|
4150
4300
|
timeline = [];
|
|
4151
4301
|
results = /* @__PURE__ */ new Map();
|
|
4152
4302
|
constructor(config) {
|
|
4153
|
-
this.id =
|
|
4303
|
+
this.id = nanoid();
|
|
4154
4304
|
this.name = config.name;
|
|
4155
4305
|
this.description = config.description;
|
|
4156
4306
|
this.config = config;
|
|
@@ -4170,7 +4320,12 @@ var Crew = class {
|
|
|
4170
4320
|
*/
|
|
4171
4321
|
initializeAgents() {
|
|
4172
4322
|
for (const agentConfig of this.config.agents) {
|
|
4173
|
-
const agent = createCrewAgent({
|
|
4323
|
+
const agent = createCrewAgent({
|
|
4324
|
+
config: agentConfig,
|
|
4325
|
+
execute: this.config.execute,
|
|
4326
|
+
mock: this.config.mock,
|
|
4327
|
+
provider: this.config.provider
|
|
4328
|
+
});
|
|
4174
4329
|
this.addAgent(agent);
|
|
4175
4330
|
}
|
|
4176
4331
|
}
|
|
@@ -4294,27 +4449,40 @@ var Crew = class {
|
|
|
4294
4449
|
await this.sleep(100);
|
|
4295
4450
|
continue;
|
|
4296
4451
|
}
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4452
|
+
const concurrency = Math.max(
|
|
4453
|
+
1,
|
|
4454
|
+
options.maxConcurrentTasks ?? this.config.maxConcurrentTasks ?? 1
|
|
4455
|
+
);
|
|
4456
|
+
if (concurrency === 1) {
|
|
4457
|
+
for (const task of readyTasks) {
|
|
4458
|
+
if (this.state !== "running") break;
|
|
4459
|
+
const delegationResult = await this.delegateTask(task, options);
|
|
4460
|
+
yield this.createEvent({
|
|
4461
|
+
type: "task:assigned",
|
|
4462
|
+
taskId: task.id,
|
|
4463
|
+
agentName: delegationResult.selectedAgent,
|
|
4464
|
+
reason: delegationResult.reason,
|
|
4465
|
+
strategy: this.config.delegationStrategy
|
|
4466
|
+
});
|
|
4467
|
+
const taskResult = await this.executeTask(task, delegationResult);
|
|
4468
|
+
yield this.createEvent({
|
|
4469
|
+
type: "task:completed",
|
|
4470
|
+
taskId: task.id,
|
|
4471
|
+
result: taskResult,
|
|
4472
|
+
agentName: delegationResult.selectedAgent,
|
|
4473
|
+
durationMs: taskResult.latencyMs ?? 0
|
|
4474
|
+
});
|
|
4475
|
+
while (eventQueue.length > 0) {
|
|
4476
|
+
yield eventQueue.shift();
|
|
4477
|
+
}
|
|
4317
4478
|
}
|
|
4479
|
+
} else {
|
|
4480
|
+
yield* this.processReadyTasksConcurrently(
|
|
4481
|
+
readyTasks,
|
|
4482
|
+
options,
|
|
4483
|
+
eventQueue,
|
|
4484
|
+
concurrency
|
|
4485
|
+
);
|
|
4318
4486
|
}
|
|
4319
4487
|
while (this.state === "paused") {
|
|
4320
4488
|
await this.sleep(100);
|
|
@@ -4357,6 +4525,78 @@ var Crew = class {
|
|
|
4357
4525
|
});
|
|
4358
4526
|
this.addTimelineEntry("crew_completed", this.name);
|
|
4359
4527
|
}
|
|
4528
|
+
/**
|
|
4529
|
+
* Execute a batch of ready tasks concurrently with a bounded worker pool.
|
|
4530
|
+
*
|
|
4531
|
+
* Each task still emits its `task:assigned` and `task:completed` events in
|
|
4532
|
+
* order relative to itself, but events across tasks are interleaved as the
|
|
4533
|
+
* workers settle. At most `concurrency` tasks run at once. If any task throws
|
|
4534
|
+
* (after exhausting retries), no further tasks are started, in-flight tasks
|
|
4535
|
+
* are allowed to settle, and the first error is rethrown so the caller's
|
|
4536
|
+
* error handling (crew:error) behaves identically to the sequential path.
|
|
4537
|
+
*/
|
|
4538
|
+
async *processReadyTasksConcurrently(readyTasks, options, eventQueue, concurrency) {
|
|
4539
|
+
let nextIndex = 0;
|
|
4540
|
+
let firstError;
|
|
4541
|
+
const buffer = [];
|
|
4542
|
+
const inFlight = /* @__PURE__ */ new Set();
|
|
4543
|
+
const launch = (task) => {
|
|
4544
|
+
const worker = (async () => {
|
|
4545
|
+
const delegationResult = await this.delegateTask(task, options);
|
|
4546
|
+
buffer.push(
|
|
4547
|
+
this.createEvent({
|
|
4548
|
+
type: "task:assigned",
|
|
4549
|
+
taskId: task.id,
|
|
4550
|
+
agentName: delegationResult.selectedAgent,
|
|
4551
|
+
reason: delegationResult.reason,
|
|
4552
|
+
strategy: this.config.delegationStrategy
|
|
4553
|
+
})
|
|
4554
|
+
);
|
|
4555
|
+
const taskResult = await this.executeTask(task, delegationResult);
|
|
4556
|
+
buffer.push(
|
|
4557
|
+
this.createEvent({
|
|
4558
|
+
type: "task:completed",
|
|
4559
|
+
taskId: task.id,
|
|
4560
|
+
result: taskResult,
|
|
4561
|
+
agentName: delegationResult.selectedAgent,
|
|
4562
|
+
durationMs: taskResult.latencyMs ?? 0
|
|
4563
|
+
})
|
|
4564
|
+
);
|
|
4565
|
+
})().catch((error) => {
|
|
4566
|
+
if (firstError === void 0) {
|
|
4567
|
+
firstError = error;
|
|
4568
|
+
}
|
|
4569
|
+
}).finally(() => {
|
|
4570
|
+
inFlight.delete(worker);
|
|
4571
|
+
});
|
|
4572
|
+
inFlight.add(worker);
|
|
4573
|
+
};
|
|
4574
|
+
const fill = () => {
|
|
4575
|
+
while (inFlight.size < concurrency && nextIndex < readyTasks.length && this.state === "running" && firstError === void 0) {
|
|
4576
|
+
launch(readyTasks[nextIndex++]);
|
|
4577
|
+
}
|
|
4578
|
+
};
|
|
4579
|
+
fill();
|
|
4580
|
+
while (inFlight.size > 0) {
|
|
4581
|
+
await Promise.race(inFlight);
|
|
4582
|
+
while (buffer.length > 0) {
|
|
4583
|
+
yield buffer.shift();
|
|
4584
|
+
}
|
|
4585
|
+
while (eventQueue.length > 0) {
|
|
4586
|
+
yield eventQueue.shift();
|
|
4587
|
+
}
|
|
4588
|
+
fill();
|
|
4589
|
+
}
|
|
4590
|
+
while (buffer.length > 0) {
|
|
4591
|
+
yield buffer.shift();
|
|
4592
|
+
}
|
|
4593
|
+
while (eventQueue.length > 0) {
|
|
4594
|
+
yield eventQueue.shift();
|
|
4595
|
+
}
|
|
4596
|
+
if (firstError !== void 0) {
|
|
4597
|
+
throw firstError;
|
|
4598
|
+
}
|
|
4599
|
+
}
|
|
4360
4600
|
/**
|
|
4361
4601
|
* Delegate a task to an agent
|
|
4362
4602
|
*/
|
|
@@ -4576,7 +4816,7 @@ ${r.output}`).join("\n\n---\n\n");
|
|
|
4576
4816
|
*/
|
|
4577
4817
|
createCheckpoint() {
|
|
4578
4818
|
return {
|
|
4579
|
-
id:
|
|
4819
|
+
id: nanoid(),
|
|
4580
4820
|
crewId: this.id,
|
|
4581
4821
|
crewName: this.name,
|
|
4582
4822
|
timestamp: /* @__PURE__ */ new Date(),
|
|
@@ -4672,7 +4912,6 @@ function createCrew(config) {
|
|
|
4672
4912
|
}
|
|
4673
4913
|
|
|
4674
4914
|
// src/workflows/WorkflowBuilder.ts
|
|
4675
|
-
var import_nanoid5 = require("nanoid");
|
|
4676
4915
|
var BranchBuilder = class {
|
|
4677
4916
|
parent;
|
|
4678
4917
|
condition;
|
|
@@ -4686,7 +4925,7 @@ var BranchBuilder = class {
|
|
|
4686
4925
|
* Add steps for true branch
|
|
4687
4926
|
*/
|
|
4688
4927
|
then(builder) {
|
|
4689
|
-
const subBuilder = new WorkflowBuilder(`then-${
|
|
4928
|
+
const subBuilder = new WorkflowBuilder(`then-${nanoid(6)}`);
|
|
4690
4929
|
builder(subBuilder);
|
|
4691
4930
|
this.thenSteps = subBuilder.getSteps();
|
|
4692
4931
|
return this;
|
|
@@ -4695,7 +4934,7 @@ var BranchBuilder = class {
|
|
|
4695
4934
|
* Add steps for false branch
|
|
4696
4935
|
*/
|
|
4697
4936
|
otherwise(builder) {
|
|
4698
|
-
const subBuilder = new WorkflowBuilder(`else-${
|
|
4937
|
+
const subBuilder = new WorkflowBuilder(`else-${nanoid(6)}`);
|
|
4699
4938
|
builder(subBuilder);
|
|
4700
4939
|
this.elseSteps = subBuilder.getSteps();
|
|
4701
4940
|
return this;
|
|
@@ -4705,7 +4944,7 @@ var BranchBuilder = class {
|
|
|
4705
4944
|
*/
|
|
4706
4945
|
endBranch() {
|
|
4707
4946
|
const conditionalConfig = {
|
|
4708
|
-
name: `conditional-${
|
|
4947
|
+
name: `conditional-${nanoid(6)}`,
|
|
4709
4948
|
condition: this.condition,
|
|
4710
4949
|
thenSteps: this.thenSteps.map((s) => s.config),
|
|
4711
4950
|
elseSteps: this.elseSteps.length > 0 ? this.elseSteps.map((s) => s.config) : void 0
|
|
@@ -4731,7 +4970,7 @@ var LoopBuilder = class {
|
|
|
4731
4970
|
* Set loop body
|
|
4732
4971
|
*/
|
|
4733
4972
|
do(builder) {
|
|
4734
|
-
const subBuilder = new WorkflowBuilder(`loop-body-${
|
|
4973
|
+
const subBuilder = new WorkflowBuilder(`loop-body-${nanoid(6)}`);
|
|
4735
4974
|
builder(subBuilder);
|
|
4736
4975
|
this.bodySteps = subBuilder.getSteps();
|
|
4737
4976
|
return this;
|
|
@@ -4748,7 +4987,7 @@ var LoopBuilder = class {
|
|
|
4748
4987
|
*/
|
|
4749
4988
|
endLoop() {
|
|
4750
4989
|
const loopConfig = {
|
|
4751
|
-
name: `loop-${
|
|
4990
|
+
name: `loop-${nanoid(6)}`,
|
|
4752
4991
|
condition: this.condition,
|
|
4753
4992
|
maxIterations: this.maxIter,
|
|
4754
4993
|
bodySteps: this.bodySteps.map((s) => s.config)
|
|
@@ -4796,7 +5035,7 @@ var WorkflowBuilder = class {
|
|
|
4796
5035
|
*/
|
|
4797
5036
|
parallel(...steps) {
|
|
4798
5037
|
const parallelConfig = {
|
|
4799
|
-
name: `parallel-${
|
|
5038
|
+
name: `parallel-${nanoid(6)}`,
|
|
4800
5039
|
steps: steps.map((s) => ({
|
|
4801
5040
|
name: s.name,
|
|
4802
5041
|
type: "task"
|
|
@@ -4947,7 +5186,7 @@ var WorkflowBuilder = class {
|
|
|
4947
5186
|
*/
|
|
4948
5187
|
build() {
|
|
4949
5188
|
return {
|
|
4950
|
-
id:
|
|
5189
|
+
id: nanoid(),
|
|
4951
5190
|
name: this.name,
|
|
4952
5191
|
description: this.description,
|
|
4953
5192
|
steps: this.steps.map((s) => s.config),
|
|
@@ -4996,7 +5235,6 @@ function workflow(name) {
|
|
|
4996
5235
|
}
|
|
4997
5236
|
|
|
4998
5237
|
// src/workflows/DAGExecutor.ts
|
|
4999
|
-
var import_nanoid6 = require("nanoid");
|
|
5000
5238
|
var DAGExecutor = class {
|
|
5001
5239
|
dag;
|
|
5002
5240
|
_handlers;
|
|
@@ -5427,24 +5665,27 @@ var DAGExecutor = class {
|
|
|
5427
5665
|
}
|
|
5428
5666
|
};
|
|
5429
5667
|
function createDAGFromSteps(steps, _handlers) {
|
|
5430
|
-
const
|
|
5431
|
-
const
|
|
5668
|
+
const nodeIds = steps.map(() => nanoid());
|
|
5669
|
+
const nameToId = /* @__PURE__ */ new Map();
|
|
5432
5670
|
for (let i = 0; i < steps.length; i++) {
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5671
|
+
nameToId.set(steps[i].name, nodeIds[i]);
|
|
5672
|
+
}
|
|
5673
|
+
const nodes = steps.map((step, i) => {
|
|
5674
|
+
let dependencies;
|
|
5675
|
+
if (step.dependsOn && step.dependsOn.length > 0) {
|
|
5676
|
+
dependencies = step.dependsOn.map((name) => nameToId.get(name)).filter((id) => id !== void 0);
|
|
5677
|
+
} else {
|
|
5678
|
+
dependencies = i > 0 ? [nodeIds[i - 1]] : [];
|
|
5679
|
+
}
|
|
5680
|
+
return {
|
|
5681
|
+
id: nodeIds[i],
|
|
5437
5682
|
name: step.name,
|
|
5438
5683
|
stepConfig: step,
|
|
5439
|
-
dependencies
|
|
5440
|
-
// Sequential by default
|
|
5684
|
+
dependencies
|
|
5441
5685
|
};
|
|
5442
|
-
|
|
5443
|
-
previousNodeIds.length = 0;
|
|
5444
|
-
previousNodeIds.push(nodeId);
|
|
5445
|
-
}
|
|
5686
|
+
});
|
|
5446
5687
|
return {
|
|
5447
|
-
id:
|
|
5688
|
+
id: nanoid(),
|
|
5448
5689
|
nodes,
|
|
5449
5690
|
edges: []
|
|
5450
5691
|
};
|
|
@@ -5658,7 +5899,6 @@ function createParallelExecutor(options) {
|
|
|
5658
5899
|
}
|
|
5659
5900
|
|
|
5660
5901
|
// src/workflows/Checkpointing.ts
|
|
5661
|
-
var import_nanoid7 = require("nanoid");
|
|
5662
5902
|
var InMemoryCheckpointStorage = class {
|
|
5663
5903
|
checkpoints = /* @__PURE__ */ new Map();
|
|
5664
5904
|
save(checkpoint) {
|
|
@@ -5712,7 +5952,7 @@ var CheckpointManager = class {
|
|
|
5712
5952
|
*/
|
|
5713
5953
|
async save(workflowId, state) {
|
|
5714
5954
|
const checkpoint = {
|
|
5715
|
-
id:
|
|
5955
|
+
id: nanoid(),
|
|
5716
5956
|
workflowId,
|
|
5717
5957
|
timestamp: /* @__PURE__ */ new Date(),
|
|
5718
5958
|
stepIndex: state.currentStepIndex,
|
|
@@ -6237,7 +6477,6 @@ function createSharedMemory(config) {
|
|
|
6237
6477
|
}
|
|
6238
6478
|
|
|
6239
6479
|
// src/memory/ConversationHistory.ts
|
|
6240
|
-
var import_nanoid8 = require("nanoid");
|
|
6241
6480
|
var ConversationHistory = class {
|
|
6242
6481
|
agentMessages = /* @__PURE__ */ new Map();
|
|
6243
6482
|
threads = /* @__PURE__ */ new Map();
|
|
@@ -6259,7 +6498,7 @@ var ConversationHistory = class {
|
|
|
6259
6498
|
addMessage(agentName, message) {
|
|
6260
6499
|
const fullMessage = {
|
|
6261
6500
|
...message,
|
|
6262
|
-
id:
|
|
6501
|
+
id: nanoid(),
|
|
6263
6502
|
agentName,
|
|
6264
6503
|
timestamp: /* @__PURE__ */ new Date(),
|
|
6265
6504
|
threadId: this.currentThreadId
|
|
@@ -6406,7 +6645,7 @@ var ConversationHistory = class {
|
|
|
6406
6645
|
*/
|
|
6407
6646
|
createThread(title, participants = []) {
|
|
6408
6647
|
const thread = {
|
|
6409
|
-
id:
|
|
6648
|
+
id: nanoid(),
|
|
6410
6649
|
title,
|
|
6411
6650
|
participants,
|
|
6412
6651
|
messages: [],
|
|
@@ -6601,7 +6840,6 @@ function createConversationHistory(config) {
|
|
|
6601
6840
|
}
|
|
6602
6841
|
|
|
6603
6842
|
// src/memory/KnowledgeBase.ts
|
|
6604
|
-
var import_nanoid9 = require("nanoid");
|
|
6605
6843
|
var KnowledgeBase = class {
|
|
6606
6844
|
items = /* @__PURE__ */ new Map();
|
|
6607
6845
|
tagIndex = /* @__PURE__ */ new Map();
|
|
@@ -6640,7 +6878,7 @@ var KnowledgeBase = class {
|
|
|
6640
6878
|
}
|
|
6641
6879
|
const fullItem = {
|
|
6642
6880
|
...item,
|
|
6643
|
-
id:
|
|
6881
|
+
id: nanoid(),
|
|
6644
6882
|
created: /* @__PURE__ */ new Date(),
|
|
6645
6883
|
updated: /* @__PURE__ */ new Date(),
|
|
6646
6884
|
accessCount: 0
|
|
@@ -8734,6 +8972,7 @@ Resolution: ${resolution}`,
|
|
|
8734
8972
|
createConflictResolver,
|
|
8735
8973
|
createConsensusStrategy,
|
|
8736
8974
|
createConversationHistory,
|
|
8975
|
+
createCoreExecutor,
|
|
8737
8976
|
createCrew,
|
|
8738
8977
|
createCrewAgent,
|
|
8739
8978
|
createCustomerSupportCrew,
|