@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/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 ?? (0, import_nanoid.nanoid)();
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 ?? (0, import_nanoid2.nanoid)();
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: (0, import_nanoid2.nanoid)(),
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 = (0, import_nanoid3.nanoid)();
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: Math.floor(Math.random() * 500) + 100,
1560
- latencyMs: Math.floor(Math.random() * 2e3) + 500,
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: (0, import_nanoid3.nanoid)(),
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
- return new CrewAgent(options);
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 bestTime = best.estimatedTime ?? Infinity;
2568
- const bidTime = bid.estimatedTime ?? Infinity;
2569
- return bidTime < bestTime ? bid : best;
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, candidateNames);
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
- const scores = [];
3072
- for (const candidateName of candidates) {
3073
- if (candidateName === voter.name) {
3074
- scores.push({ name: candidateName, score: 0.7 });
3075
- } else {
3076
- const randomFactor = 0.8 + Math.random() * 0.4;
3077
- scores.push({
3078
- name: candidateName,
3079
- score: Math.random() * randomFactor
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
- let weight = 1;
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: `Selected based on perceived suitability (score: ${selected.score.toFixed(2)})`
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.substring(0, 100);
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.substring(0, 100) === winningKey
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
- return Promise.resolve(this.resolveByConfidence(conflict));
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.substring(0, 100);
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 = (0, import_nanoid4.nanoid)();
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({ config: agentConfig });
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
- for (const task of readyTasks) {
4298
- if (this.state !== "running") break;
4299
- const delegationResult = await this.delegateTask(task, options);
4300
- yield this.createEvent({
4301
- type: "task:assigned",
4302
- taskId: task.id,
4303
- agentName: delegationResult.selectedAgent,
4304
- reason: delegationResult.reason,
4305
- strategy: this.config.delegationStrategy
4306
- });
4307
- const taskResult = await this.executeTask(task, delegationResult);
4308
- yield this.createEvent({
4309
- type: "task:completed",
4310
- taskId: task.id,
4311
- result: taskResult,
4312
- agentName: delegationResult.selectedAgent,
4313
- durationMs: taskResult.latencyMs ?? 0
4314
- });
4315
- while (eventQueue.length > 0) {
4316
- yield eventQueue.shift();
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: (0, import_nanoid4.nanoid)(),
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-${(0, import_nanoid5.nanoid)(6)}`);
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-${(0, import_nanoid5.nanoid)(6)}`);
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-${(0, import_nanoid5.nanoid)(6)}`,
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-${(0, import_nanoid5.nanoid)(6)}`);
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-${(0, import_nanoid5.nanoid)(6)}`,
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-${(0, import_nanoid5.nanoid)(6)}`,
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: (0, import_nanoid5.nanoid)(),
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 nodes = [];
5431
- const previousNodeIds = [];
5668
+ const nodeIds = steps.map(() => nanoid());
5669
+ const nameToId = /* @__PURE__ */ new Map();
5432
5670
  for (let i = 0; i < steps.length; i++) {
5433
- const step = steps[i];
5434
- const nodeId = (0, import_nanoid6.nanoid)();
5435
- const node = {
5436
- id: nodeId,
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: [...previousNodeIds]
5440
- // Sequential by default
5684
+ dependencies
5441
5685
  };
5442
- nodes.push(node);
5443
- previousNodeIds.length = 0;
5444
- previousNodeIds.push(nodeId);
5445
- }
5686
+ });
5446
5687
  return {
5447
- id: (0, import_nanoid6.nanoid)(),
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: (0, import_nanoid7.nanoid)(),
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: (0, import_nanoid8.nanoid)(),
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: (0, import_nanoid8.nanoid)(),
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: (0, import_nanoid9.nanoid)(),
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,