@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
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { d as TaskConfig, a as Crew, e as CrewConfig } from '../Crew-BnvVjN7A.js';
|
|
2
|
+
|
|
3
|
+
interface ResearchCrewOptions {
|
|
4
|
+
name?: string;
|
|
5
|
+
model?: string;
|
|
6
|
+
provider?: string;
|
|
7
|
+
includeWriter?: boolean;
|
|
8
|
+
depth?: 'shallow' | 'standard' | 'deep';
|
|
9
|
+
tools?: string[];
|
|
10
|
+
}
|
|
11
|
+
declare function createResearchCrewConfig(options?: ResearchCrewOptions): CrewConfig;
|
|
12
|
+
declare function createResearchCrew(options?: ResearchCrewOptions): Crew;
|
|
13
|
+
declare const ResearchTasks: {
|
|
14
|
+
research(topic: string, depth?: "shallow" | "standard" | "deep"): TaskConfig;
|
|
15
|
+
analyze(data: string, focusAreas?: string[]): TaskConfig;
|
|
16
|
+
writeReport(topic: string, format?: "summary" | "detailed" | "executive"): TaskConfig;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
interface WritingCrewOptions {
|
|
20
|
+
name?: string;
|
|
21
|
+
model?: string;
|
|
22
|
+
provider?: string;
|
|
23
|
+
contentType?: 'blog' | 'technical' | 'marketing' | 'creative' | 'general';
|
|
24
|
+
audience?: string;
|
|
25
|
+
tools?: string[];
|
|
26
|
+
}
|
|
27
|
+
declare function createWritingCrewConfig(options?: WritingCrewOptions): CrewConfig;
|
|
28
|
+
declare function createWritingCrew(options?: WritingCrewOptions): Crew;
|
|
29
|
+
declare const WritingTasks: {
|
|
30
|
+
draft(topic: string, wordCount?: number, style?: string): TaskConfig;
|
|
31
|
+
edit(content: string, focusAreas?: string[]): TaskConfig;
|
|
32
|
+
proofread(content: string): TaskConfig;
|
|
33
|
+
blogPost(topic: string, keywords?: string[]): TaskConfig;
|
|
34
|
+
technicalDoc(subject: string, audience?: "beginner" | "intermediate" | "advanced"): TaskConfig;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
interface CodeReviewCrewOptions {
|
|
38
|
+
name?: string;
|
|
39
|
+
model?: string;
|
|
40
|
+
provider?: string;
|
|
41
|
+
languages?: string[];
|
|
42
|
+
includeSecurity?: boolean;
|
|
43
|
+
includePerformance?: boolean;
|
|
44
|
+
strictness?: 'relaxed' | 'standard' | 'strict';
|
|
45
|
+
tools?: string[];
|
|
46
|
+
}
|
|
47
|
+
declare function createCodeReviewCrewConfig(options?: CodeReviewCrewOptions): CrewConfig;
|
|
48
|
+
declare function createCodeReviewCrew(options?: CodeReviewCrewOptions): Crew;
|
|
49
|
+
declare const CodeReviewTasks: {
|
|
50
|
+
review(code: string, language?: string, context?: string): TaskConfig;
|
|
51
|
+
securityReview(code: string, language?: string): TaskConfig;
|
|
52
|
+
performanceReview(code: string, language?: string): TaskConfig;
|
|
53
|
+
pullRequestReview(diff: string, prDescription?: string): TaskConfig;
|
|
54
|
+
architectureReview(description: string, codebase?: string): TaskConfig;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
interface CustomerSupportCrewOptions {
|
|
58
|
+
name?: string;
|
|
59
|
+
model?: string;
|
|
60
|
+
provider?: string;
|
|
61
|
+
productName?: string;
|
|
62
|
+
companyName?: string;
|
|
63
|
+
supportStyle?: 'formal' | 'friendly' | 'technical';
|
|
64
|
+
includeSpecialist?: boolean;
|
|
65
|
+
includeEscalation?: boolean;
|
|
66
|
+
tools?: string[];
|
|
67
|
+
}
|
|
68
|
+
declare function createCustomerSupportCrewConfig(options?: CustomerSupportCrewOptions): CrewConfig;
|
|
69
|
+
declare function createCustomerSupportCrew(options?: CustomerSupportCrewOptions): Crew;
|
|
70
|
+
declare const CustomerSupportTasks: {
|
|
71
|
+
handleTicket(customerMessage: string, priority?: "low" | "normal" | "high" | "urgent", customerTier?: string): TaskConfig;
|
|
72
|
+
resolveTechnicalIssue(issueDescription: string, errorLogs?: string, environment?: string): TaskConfig;
|
|
73
|
+
handleEscalation(caseHistory: string, customerSentiment?: "frustrated" | "angry" | "neutral", businessImpact?: string): TaskConfig;
|
|
74
|
+
respondToFeedback(feedback: string, sentiment: "positive" | "neutral" | "negative"): TaskConfig;
|
|
75
|
+
createKnowledgeBaseArticle(topic: string, resolution: string): TaskConfig;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export { type CodeReviewCrewOptions, CodeReviewTasks, type CustomerSupportCrewOptions, CustomerSupportTasks, type ResearchCrewOptions, ResearchTasks, type WritingCrewOptions, WritingTasks, createCodeReviewCrew, createCodeReviewCrewConfig, createCustomerSupportCrew, createCustomerSupportCrewConfig, createResearchCrew, createResearchCrewConfig, createWritingCrew, createWritingCrewConfig };
|
package/dist/templates/index.js
CHANGED
|
@@ -255,8 +255,37 @@ Background: ${this.backstory}`);
|
|
|
255
255
|
}
|
|
256
256
|
};
|
|
257
257
|
|
|
258
|
+
// ../../node_modules/.pnpm/nanoid@5.1.6/node_modules/nanoid/index.js
|
|
259
|
+
var import_node_crypto = require("crypto");
|
|
260
|
+
|
|
261
|
+
// ../../node_modules/.pnpm/nanoid@5.1.6/node_modules/nanoid/url-alphabet/index.js
|
|
262
|
+
var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
263
|
+
|
|
264
|
+
// ../../node_modules/.pnpm/nanoid@5.1.6/node_modules/nanoid/index.js
|
|
265
|
+
var POOL_SIZE_MULTIPLIER = 128;
|
|
266
|
+
var pool;
|
|
267
|
+
var poolOffset;
|
|
268
|
+
function fillPool(bytes) {
|
|
269
|
+
if (!pool || pool.length < bytes) {
|
|
270
|
+
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
|
|
271
|
+
import_node_crypto.webcrypto.getRandomValues(pool);
|
|
272
|
+
poolOffset = 0;
|
|
273
|
+
} else if (poolOffset + bytes > pool.length) {
|
|
274
|
+
import_node_crypto.webcrypto.getRandomValues(pool);
|
|
275
|
+
poolOffset = 0;
|
|
276
|
+
}
|
|
277
|
+
poolOffset += bytes;
|
|
278
|
+
}
|
|
279
|
+
function nanoid(size = 21) {
|
|
280
|
+
fillPool(size |= 0);
|
|
281
|
+
let id = "";
|
|
282
|
+
for (let i = poolOffset - size; i < poolOffset; i++) {
|
|
283
|
+
id += urlAlphabet[pool[i] & 63];
|
|
284
|
+
}
|
|
285
|
+
return id;
|
|
286
|
+
}
|
|
287
|
+
|
|
258
288
|
// src/core/Task.ts
|
|
259
|
-
var import_nanoid = require("nanoid");
|
|
260
289
|
var Task = class _Task {
|
|
261
290
|
id;
|
|
262
291
|
description;
|
|
@@ -276,7 +305,7 @@ var Task = class _Task {
|
|
|
276
305
|
_result;
|
|
277
306
|
_metadata;
|
|
278
307
|
constructor(config) {
|
|
279
|
-
this.id = config.id ??
|
|
308
|
+
this.id = config.id ?? nanoid();
|
|
280
309
|
this.description = config.description;
|
|
281
310
|
this.expectedOutput = config.expectedOutput;
|
|
282
311
|
this.priority = config.priority ?? "medium";
|
|
@@ -882,7 +911,6 @@ var TaskQueue = class {
|
|
|
882
911
|
|
|
883
912
|
// src/core/ExecutionContext.ts
|
|
884
913
|
var import_eventemitter3 = __toESM(require("eventemitter3"));
|
|
885
|
-
var import_nanoid2 = require("nanoid");
|
|
886
914
|
var ExecutionContext = class {
|
|
887
915
|
crewId;
|
|
888
916
|
crewName;
|
|
@@ -899,7 +927,7 @@ var ExecutionContext = class {
|
|
|
899
927
|
startTime;
|
|
900
928
|
endTime;
|
|
901
929
|
constructor(config) {
|
|
902
|
-
this.crewId = config.crewId ??
|
|
930
|
+
this.crewId = config.crewId ?? nanoid();
|
|
903
931
|
this.crewName = config.crewName;
|
|
904
932
|
this.state = /* @__PURE__ */ new Map();
|
|
905
933
|
this.completedTasks = /* @__PURE__ */ new Map();
|
|
@@ -1145,7 +1173,7 @@ var ExecutionContext = class {
|
|
|
1145
1173
|
*/
|
|
1146
1174
|
createCheckpoint() {
|
|
1147
1175
|
return {
|
|
1148
|
-
id:
|
|
1176
|
+
id: nanoid(),
|
|
1149
1177
|
timestamp: /* @__PURE__ */ new Date(),
|
|
1150
1178
|
crewId: this.crewId,
|
|
1151
1179
|
crewName: this.crewName,
|
|
@@ -1231,12 +1259,6 @@ var ExecutionContext = class {
|
|
|
1231
1259
|
}
|
|
1232
1260
|
};
|
|
1233
1261
|
|
|
1234
|
-
// src/core/Crew.ts
|
|
1235
|
-
var import_nanoid4 = require("nanoid");
|
|
1236
|
-
|
|
1237
|
-
// src/agents/CrewAgent.ts
|
|
1238
|
-
var import_nanoid3 = require("nanoid");
|
|
1239
|
-
|
|
1240
1262
|
// src/agents/AgentCapabilities.ts
|
|
1241
1263
|
var PROFICIENCY_WEIGHTS = {
|
|
1242
1264
|
novice: 0.25,
|
|
@@ -1428,7 +1450,80 @@ var AgentCapabilities = class {
|
|
|
1428
1450
|
}
|
|
1429
1451
|
};
|
|
1430
1452
|
|
|
1453
|
+
// src/agents/CoreExecutor.ts
|
|
1454
|
+
async function loadProvider(providerName) {
|
|
1455
|
+
const ctorName = resolveProviderCtorName(providerName);
|
|
1456
|
+
let core;
|
|
1457
|
+
try {
|
|
1458
|
+
core = await import("@lov3kaizen/agentsea-core");
|
|
1459
|
+
} catch {
|
|
1460
|
+
throw new Error(
|
|
1461
|
+
'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.'
|
|
1462
|
+
);
|
|
1463
|
+
}
|
|
1464
|
+
const Ctor = core[ctorName];
|
|
1465
|
+
return new Ctor();
|
|
1466
|
+
}
|
|
1467
|
+
function resolveProviderCtorName(providerName) {
|
|
1468
|
+
switch ((providerName ?? "").toLowerCase()) {
|
|
1469
|
+
case "anthropic":
|
|
1470
|
+
case "claude":
|
|
1471
|
+
return "AnthropicProvider";
|
|
1472
|
+
case "openai":
|
|
1473
|
+
case "gpt":
|
|
1474
|
+
return "OpenAIProvider";
|
|
1475
|
+
case "gemini":
|
|
1476
|
+
case "google":
|
|
1477
|
+
return "GeminiProvider";
|
|
1478
|
+
case "ollama":
|
|
1479
|
+
return "OllamaProvider";
|
|
1480
|
+
default:
|
|
1481
|
+
throw new Error(
|
|
1482
|
+
`CrewAgent: unsupported provider "${providerName}". Supported providers are: anthropic, openai, gemini, ollama. Pass a custom \`execute\` function to createCrewAgent for any other provider.`
|
|
1483
|
+
);
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
function createCoreExecutor(config, options = {}) {
|
|
1487
|
+
let providerPromise;
|
|
1488
|
+
const getProvider = () => {
|
|
1489
|
+
if (!providerPromise) {
|
|
1490
|
+
providerPromise = options.provider ? Promise.resolve(options.provider) : loadProvider(config.provider);
|
|
1491
|
+
}
|
|
1492
|
+
return providerPromise;
|
|
1493
|
+
};
|
|
1494
|
+
return async (input, systemPrompt) => {
|
|
1495
|
+
const provider = await getProvider();
|
|
1496
|
+
const start = Date.now();
|
|
1497
|
+
const response = await provider.generateResponse(
|
|
1498
|
+
[{ role: "user", content: input }],
|
|
1499
|
+
{
|
|
1500
|
+
model: config.model,
|
|
1501
|
+
systemPrompt,
|
|
1502
|
+
temperature: config.temperature,
|
|
1503
|
+
maxTokens: config.maxTokens
|
|
1504
|
+
}
|
|
1505
|
+
);
|
|
1506
|
+
return {
|
|
1507
|
+
output: response.content,
|
|
1508
|
+
tokensUsed: response.usage.inputTokens + response.usage.outputTokens,
|
|
1509
|
+
latencyMs: Date.now() - start,
|
|
1510
|
+
iterations: 1
|
|
1511
|
+
};
|
|
1512
|
+
};
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1431
1515
|
// src/agents/CrewAgent.ts
|
|
1516
|
+
function modelCostWeight(model) {
|
|
1517
|
+
const m = (model ?? "").toLowerCase();
|
|
1518
|
+
if (m.includes("opus") || m.includes("gpt-5") || m.includes("o3")) return 5;
|
|
1519
|
+
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")) {
|
|
1520
|
+
return 3;
|
|
1521
|
+
}
|
|
1522
|
+
if (m.includes("haiku") || m.includes("mini") || m.includes("flash") || m.includes("llama") || m.includes("mistral")) {
|
|
1523
|
+
return 1;
|
|
1524
|
+
}
|
|
1525
|
+
return 3;
|
|
1526
|
+
}
|
|
1432
1527
|
var CrewAgent = class _CrewAgent {
|
|
1433
1528
|
id;
|
|
1434
1529
|
name;
|
|
@@ -1448,7 +1543,7 @@ var CrewAgent = class _CrewAgent {
|
|
|
1448
1543
|
totalTokensUsed = 0;
|
|
1449
1544
|
constructor(options) {
|
|
1450
1545
|
const { config, execute } = options;
|
|
1451
|
-
this.id =
|
|
1546
|
+
this.id = nanoid();
|
|
1452
1547
|
this.name = config.name;
|
|
1453
1548
|
this.role = new Role(config.role);
|
|
1454
1549
|
this.capabilities = config.role.capabilities;
|
|
@@ -1467,10 +1562,11 @@ var CrewAgent = class _CrewAgent {
|
|
|
1467
1562
|
*/
|
|
1468
1563
|
async execute(input) {
|
|
1469
1564
|
if (!this.executeFunc) {
|
|
1565
|
+
const tokensUsed = 100 + Math.min(input.length, 400);
|
|
1470
1566
|
const mockResult = {
|
|
1471
1567
|
output: `[Mock response from ${this.name}]: ${input.slice(0, 100)}...`,
|
|
1472
|
-
tokensUsed
|
|
1473
|
-
latencyMs:
|
|
1568
|
+
tokensUsed,
|
|
1569
|
+
latencyMs: 0,
|
|
1474
1570
|
iterations: 1
|
|
1475
1571
|
};
|
|
1476
1572
|
this.totalTokensUsed += mockResult.tokensUsed;
|
|
@@ -1573,16 +1669,27 @@ ${JSON.stringify(task.context, null, 2)}`);
|
|
|
1573
1669
|
) ?? true
|
|
1574
1670
|
).map((c) => c.name);
|
|
1575
1671
|
const estimatedTime = this.estimateTaskTime(task);
|
|
1672
|
+
const estimatedCost = this.estimateTaskCost(estimatedTime);
|
|
1576
1673
|
const reasoning = this.generateBidReasoning(task, confidence, matchedCaps);
|
|
1577
1674
|
return Promise.resolve({
|
|
1578
1675
|
agentName: this.name,
|
|
1579
1676
|
taskId: task.id ?? "unknown",
|
|
1580
1677
|
confidence,
|
|
1581
1678
|
estimatedTime,
|
|
1679
|
+
estimatedCost,
|
|
1582
1680
|
reasoning,
|
|
1583
1681
|
capabilities: matchedCaps
|
|
1584
1682
|
});
|
|
1585
1683
|
}
|
|
1684
|
+
/**
|
|
1685
|
+
* Estimate a relative cost for handling a task. Combines the agent's model
|
|
1686
|
+
* price tier with the estimated effort so the auction `cheapest` criterion
|
|
1687
|
+
* can distinguish a cheap-but-slower model from an expensive-but-faster one.
|
|
1688
|
+
* The unit is arbitrary and only meaningful relative to other bids.
|
|
1689
|
+
*/
|
|
1690
|
+
estimateTaskCost(estimatedTime) {
|
|
1691
|
+
return modelCostWeight(this.model) * Math.max(estimatedTime, 1);
|
|
1692
|
+
}
|
|
1586
1693
|
/**
|
|
1587
1694
|
* Check if agent has all required capabilities
|
|
1588
1695
|
*/
|
|
@@ -1633,7 +1740,7 @@ ${JSON.stringify(task.context, null, 2)}`);
|
|
|
1633
1740
|
*/
|
|
1634
1741
|
createHelpRequest(taskId, request) {
|
|
1635
1742
|
return {
|
|
1636
|
-
requestId:
|
|
1743
|
+
requestId: nanoid(),
|
|
1637
1744
|
fromAgent: this.name,
|
|
1638
1745
|
taskId,
|
|
1639
1746
|
request
|
|
@@ -1768,7 +1875,13 @@ Please provide helpful guidance based on your expertise.
|
|
|
1768
1875
|
}
|
|
1769
1876
|
};
|
|
1770
1877
|
function createCrewAgent(options) {
|
|
1771
|
-
|
|
1878
|
+
if (options.execute || options.mock) {
|
|
1879
|
+
return new CrewAgent(options);
|
|
1880
|
+
}
|
|
1881
|
+
return new CrewAgent({
|
|
1882
|
+
...options,
|
|
1883
|
+
execute: createCoreExecutor(options.config, { provider: options.provider })
|
|
1884
|
+
});
|
|
1772
1885
|
}
|
|
1773
1886
|
|
|
1774
1887
|
// src/agents/AgentRegistry.ts
|
|
@@ -2468,9 +2581,9 @@ var AuctionStrategy = class extends BaseDelegationStrategy {
|
|
|
2468
2581
|
}, bids[0]);
|
|
2469
2582
|
case "cheapest":
|
|
2470
2583
|
return bids.reduce((best, bid) => {
|
|
2471
|
-
const
|
|
2472
|
-
const
|
|
2473
|
-
return
|
|
2584
|
+
const bestCost = best.estimatedCost ?? best.estimatedTime ?? Infinity;
|
|
2585
|
+
const bidCost = bid.estimatedCost ?? bid.estimatedTime ?? Infinity;
|
|
2586
|
+
return bidCost < bestCost ? bid : best;
|
|
2474
2587
|
}, bids[0]);
|
|
2475
2588
|
case "confidence":
|
|
2476
2589
|
default:
|
|
@@ -2953,9 +3066,8 @@ var ConsensusStrategy = class extends BaseDelegationStrategy {
|
|
|
2953
3066
|
*/
|
|
2954
3067
|
async collectVotes(task, voters, candidates) {
|
|
2955
3068
|
const votes = [];
|
|
2956
|
-
const candidateNames = candidates.map((c) => c.name);
|
|
2957
3069
|
for (const voter of voters) {
|
|
2958
|
-
const vote = await this.getVote(voter, task,
|
|
3070
|
+
const vote = await this.getVote(voter, task, candidates);
|
|
2959
3071
|
if (vote) {
|
|
2960
3072
|
votes.push(vote);
|
|
2961
3073
|
}
|
|
@@ -2963,33 +3075,35 @@ var ConsensusStrategy = class extends BaseDelegationStrategy {
|
|
|
2963
3075
|
return votes;
|
|
2964
3076
|
}
|
|
2965
3077
|
/**
|
|
2966
|
-
* Get a vote from an agent
|
|
3078
|
+
* Get a vote from an agent.
|
|
3079
|
+
*
|
|
3080
|
+
* Each voter ranks the candidates by how well their capabilities fit the
|
|
3081
|
+
* task (the same `calculateTaskScore` signal the BestMatch/Auction strategies
|
|
3082
|
+
* use), plus a small self-preference bias so an agent leans toward itself when
|
|
3083
|
+
* candidates are otherwise comparable. This is fully deterministic — given the
|
|
3084
|
+
* same agents and task it always produces the same votes — and explainable,
|
|
3085
|
+
* which is what consensus needs. (A future enhancement could replace this with
|
|
3086
|
+
* an actual LLM deliberation per voter; the tally/agreement logic is unchanged.)
|
|
2967
3087
|
*/
|
|
2968
3088
|
getVote(voter, task, candidates) {
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
scores.push({
|
|
2976
|
-
name: candidateName,
|
|
2977
|
-
score: Math.random() * randomFactor
|
|
2978
|
-
});
|
|
3089
|
+
if (candidates.length === 0) return Promise.resolve(null);
|
|
3090
|
+
const SELF_PREFERENCE_BONUS = 0.15;
|
|
3091
|
+
const scores = candidates.map((candidate) => {
|
|
3092
|
+
let score = candidate.calculateTaskScore(task);
|
|
3093
|
+
if (candidate.name === voter.name) {
|
|
3094
|
+
score += SELF_PREFERENCE_BONUS;
|
|
2979
3095
|
}
|
|
2980
|
-
|
|
2981
|
-
|
|
3096
|
+
return { name: candidate.name, score };
|
|
3097
|
+
});
|
|
3098
|
+
scores.sort((a, b) => b.score - a.score || a.name.localeCompare(b.name));
|
|
2982
3099
|
const selected = scores[0];
|
|
2983
3100
|
if (!selected) return Promise.resolve(null);
|
|
2984
|
-
|
|
2985
|
-
if (this.weightedVoting) {
|
|
2986
|
-
weight = voter.calculateTaskScore(task) || 0.5;
|
|
2987
|
-
}
|
|
3101
|
+
const weight = this.weightedVoting ? voter.calculateTaskScore(task) || 0.5 : 1;
|
|
2988
3102
|
return Promise.resolve({
|
|
2989
3103
|
voter: voter.name,
|
|
2990
3104
|
candidate: selected.name,
|
|
2991
3105
|
weight,
|
|
2992
|
-
reasoning: `
|
|
3106
|
+
reasoning: `Ranked "${selected.name}" highest by capability fit for the task (score: ${selected.score.toFixed(2)})`
|
|
2993
3107
|
});
|
|
2994
3108
|
}
|
|
2995
3109
|
/**
|
|
@@ -3853,13 +3967,24 @@ var ConflictResolver = class {
|
|
|
3853
3967
|
resolved: /* @__PURE__ */ new Date()
|
|
3854
3968
|
};
|
|
3855
3969
|
}
|
|
3970
|
+
/**
|
|
3971
|
+
* Normalize response content for equality comparison: trim, collapse runs of
|
|
3972
|
+
* whitespace, and lowercase. This groups textually-equivalent answers (ignoring
|
|
3973
|
+
* incidental formatting) over their FULL content rather than a fragile first-N
|
|
3974
|
+
* characters prefix. Note: this is exact-match-after-normalization, not semantic
|
|
3975
|
+
* similarity — agents that express the same idea with different wording will not
|
|
3976
|
+
* group. Semantic grouping would require embeddings (future enhancement).
|
|
3977
|
+
*/
|
|
3978
|
+
normalizeContent(content) {
|
|
3979
|
+
return content.trim().replace(/\s+/g, " ").toLowerCase();
|
|
3980
|
+
}
|
|
3856
3981
|
/**
|
|
3857
3982
|
* Resolve by voting
|
|
3858
3983
|
*/
|
|
3859
3984
|
resolveByVoting(conflict, _context) {
|
|
3860
3985
|
const votes = /* @__PURE__ */ new Map();
|
|
3861
3986
|
for (const response of conflict.responses) {
|
|
3862
|
-
const key = response.content
|
|
3987
|
+
const key = this.normalizeContent(response.content);
|
|
3863
3988
|
const current = votes.get(key) ?? 0;
|
|
3864
3989
|
votes.set(key, current + response.confidence);
|
|
3865
3990
|
}
|
|
@@ -3872,7 +3997,7 @@ var ConflictResolver = class {
|
|
|
3872
3997
|
}
|
|
3873
3998
|
}
|
|
3874
3999
|
const winner = conflict.responses.find(
|
|
3875
|
-
(r) => r.content
|
|
4000
|
+
(r) => this.normalizeContent(r.content) === winningKey
|
|
3876
4001
|
);
|
|
3877
4002
|
return Promise.resolve({
|
|
3878
4003
|
conflictId: conflict.id,
|
|
@@ -3888,7 +4013,31 @@ var ConflictResolver = class {
|
|
|
3888
4013
|
* Resolve by authority
|
|
3889
4014
|
*/
|
|
3890
4015
|
resolveByAuthority(conflict, _context) {
|
|
3891
|
-
|
|
4016
|
+
const ranked = conflict.responses.map((r) => ({
|
|
4017
|
+
response: r,
|
|
4018
|
+
authority: typeof r.metadata?.authority === "number" ? r.metadata.authority : void 0
|
|
4019
|
+
})).filter(
|
|
4020
|
+
(x) => x.authority !== void 0
|
|
4021
|
+
);
|
|
4022
|
+
if (ranked.length === 0) {
|
|
4023
|
+
return Promise.resolve({
|
|
4024
|
+
...this.resolveByConfidence(conflict),
|
|
4025
|
+
strategy: "authority",
|
|
4026
|
+
explanation: "No authority metadata provided; fell back to highest confidence"
|
|
4027
|
+
});
|
|
4028
|
+
}
|
|
4029
|
+
const winnerEntry = ranked.reduce(
|
|
4030
|
+
(best, cur) => cur.authority > best.authority ? cur : best
|
|
4031
|
+
);
|
|
4032
|
+
return Promise.resolve({
|
|
4033
|
+
conflictId: conflict.id,
|
|
4034
|
+
strategy: "authority",
|
|
4035
|
+
winner: winnerEntry.response,
|
|
4036
|
+
explanation: `Selected response from highest-authority agent "${winnerEntry.response.agentName}" (authority: ${winnerEntry.authority})`,
|
|
4037
|
+
successful: true,
|
|
4038
|
+
escalated: false,
|
|
4039
|
+
resolved: /* @__PURE__ */ new Date()
|
|
4040
|
+
});
|
|
3892
4041
|
}
|
|
3893
4042
|
/**
|
|
3894
4043
|
* Resolve by consensus
|
|
@@ -3896,7 +4045,7 @@ var ConflictResolver = class {
|
|
|
3896
4045
|
resolveByConsensus(conflict, _context) {
|
|
3897
4046
|
const contentGroups = /* @__PURE__ */ new Map();
|
|
3898
4047
|
for (const response of conflict.responses) {
|
|
3899
|
-
const key = response.content
|
|
4048
|
+
const key = this.normalizeContent(response.content);
|
|
3900
4049
|
const group = contentGroups.get(key) ?? [];
|
|
3901
4050
|
group.push(response);
|
|
3902
4051
|
contentGroups.set(key, group);
|
|
@@ -4036,7 +4185,7 @@ var Crew = class {
|
|
|
4036
4185
|
timeline = [];
|
|
4037
4186
|
results = /* @__PURE__ */ new Map();
|
|
4038
4187
|
constructor(config) {
|
|
4039
|
-
this.id =
|
|
4188
|
+
this.id = nanoid();
|
|
4040
4189
|
this.name = config.name;
|
|
4041
4190
|
this.description = config.description;
|
|
4042
4191
|
this.config = config;
|
|
@@ -4056,7 +4205,12 @@ var Crew = class {
|
|
|
4056
4205
|
*/
|
|
4057
4206
|
initializeAgents() {
|
|
4058
4207
|
for (const agentConfig of this.config.agents) {
|
|
4059
|
-
const agent = createCrewAgent({
|
|
4208
|
+
const agent = createCrewAgent({
|
|
4209
|
+
config: agentConfig,
|
|
4210
|
+
execute: this.config.execute,
|
|
4211
|
+
mock: this.config.mock,
|
|
4212
|
+
provider: this.config.provider
|
|
4213
|
+
});
|
|
4060
4214
|
this.addAgent(agent);
|
|
4061
4215
|
}
|
|
4062
4216
|
}
|
|
@@ -4180,27 +4334,40 @@ var Crew = class {
|
|
|
4180
4334
|
await this.sleep(100);
|
|
4181
4335
|
continue;
|
|
4182
4336
|
}
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4337
|
+
const concurrency = Math.max(
|
|
4338
|
+
1,
|
|
4339
|
+
options.maxConcurrentTasks ?? this.config.maxConcurrentTasks ?? 1
|
|
4340
|
+
);
|
|
4341
|
+
if (concurrency === 1) {
|
|
4342
|
+
for (const task of readyTasks) {
|
|
4343
|
+
if (this.state !== "running") break;
|
|
4344
|
+
const delegationResult = await this.delegateTask(task, options);
|
|
4345
|
+
yield this.createEvent({
|
|
4346
|
+
type: "task:assigned",
|
|
4347
|
+
taskId: task.id,
|
|
4348
|
+
agentName: delegationResult.selectedAgent,
|
|
4349
|
+
reason: delegationResult.reason,
|
|
4350
|
+
strategy: this.config.delegationStrategy
|
|
4351
|
+
});
|
|
4352
|
+
const taskResult = await this.executeTask(task, delegationResult);
|
|
4353
|
+
yield this.createEvent({
|
|
4354
|
+
type: "task:completed",
|
|
4355
|
+
taskId: task.id,
|
|
4356
|
+
result: taskResult,
|
|
4357
|
+
agentName: delegationResult.selectedAgent,
|
|
4358
|
+
durationMs: taskResult.latencyMs ?? 0
|
|
4359
|
+
});
|
|
4360
|
+
while (eventQueue.length > 0) {
|
|
4361
|
+
yield eventQueue.shift();
|
|
4362
|
+
}
|
|
4203
4363
|
}
|
|
4364
|
+
} else {
|
|
4365
|
+
yield* this.processReadyTasksConcurrently(
|
|
4366
|
+
readyTasks,
|
|
4367
|
+
options,
|
|
4368
|
+
eventQueue,
|
|
4369
|
+
concurrency
|
|
4370
|
+
);
|
|
4204
4371
|
}
|
|
4205
4372
|
while (this.state === "paused") {
|
|
4206
4373
|
await this.sleep(100);
|
|
@@ -4243,6 +4410,78 @@ var Crew = class {
|
|
|
4243
4410
|
});
|
|
4244
4411
|
this.addTimelineEntry("crew_completed", this.name);
|
|
4245
4412
|
}
|
|
4413
|
+
/**
|
|
4414
|
+
* Execute a batch of ready tasks concurrently with a bounded worker pool.
|
|
4415
|
+
*
|
|
4416
|
+
* Each task still emits its `task:assigned` and `task:completed` events in
|
|
4417
|
+
* order relative to itself, but events across tasks are interleaved as the
|
|
4418
|
+
* workers settle. At most `concurrency` tasks run at once. If any task throws
|
|
4419
|
+
* (after exhausting retries), no further tasks are started, in-flight tasks
|
|
4420
|
+
* are allowed to settle, and the first error is rethrown so the caller's
|
|
4421
|
+
* error handling (crew:error) behaves identically to the sequential path.
|
|
4422
|
+
*/
|
|
4423
|
+
async *processReadyTasksConcurrently(readyTasks, options, eventQueue, concurrency) {
|
|
4424
|
+
let nextIndex = 0;
|
|
4425
|
+
let firstError;
|
|
4426
|
+
const buffer = [];
|
|
4427
|
+
const inFlight = /* @__PURE__ */ new Set();
|
|
4428
|
+
const launch = (task) => {
|
|
4429
|
+
const worker = (async () => {
|
|
4430
|
+
const delegationResult = await this.delegateTask(task, options);
|
|
4431
|
+
buffer.push(
|
|
4432
|
+
this.createEvent({
|
|
4433
|
+
type: "task:assigned",
|
|
4434
|
+
taskId: task.id,
|
|
4435
|
+
agentName: delegationResult.selectedAgent,
|
|
4436
|
+
reason: delegationResult.reason,
|
|
4437
|
+
strategy: this.config.delegationStrategy
|
|
4438
|
+
})
|
|
4439
|
+
);
|
|
4440
|
+
const taskResult = await this.executeTask(task, delegationResult);
|
|
4441
|
+
buffer.push(
|
|
4442
|
+
this.createEvent({
|
|
4443
|
+
type: "task:completed",
|
|
4444
|
+
taskId: task.id,
|
|
4445
|
+
result: taskResult,
|
|
4446
|
+
agentName: delegationResult.selectedAgent,
|
|
4447
|
+
durationMs: taskResult.latencyMs ?? 0
|
|
4448
|
+
})
|
|
4449
|
+
);
|
|
4450
|
+
})().catch((error) => {
|
|
4451
|
+
if (firstError === void 0) {
|
|
4452
|
+
firstError = error;
|
|
4453
|
+
}
|
|
4454
|
+
}).finally(() => {
|
|
4455
|
+
inFlight.delete(worker);
|
|
4456
|
+
});
|
|
4457
|
+
inFlight.add(worker);
|
|
4458
|
+
};
|
|
4459
|
+
const fill = () => {
|
|
4460
|
+
while (inFlight.size < concurrency && nextIndex < readyTasks.length && this.state === "running" && firstError === void 0) {
|
|
4461
|
+
launch(readyTasks[nextIndex++]);
|
|
4462
|
+
}
|
|
4463
|
+
};
|
|
4464
|
+
fill();
|
|
4465
|
+
while (inFlight.size > 0) {
|
|
4466
|
+
await Promise.race(inFlight);
|
|
4467
|
+
while (buffer.length > 0) {
|
|
4468
|
+
yield buffer.shift();
|
|
4469
|
+
}
|
|
4470
|
+
while (eventQueue.length > 0) {
|
|
4471
|
+
yield eventQueue.shift();
|
|
4472
|
+
}
|
|
4473
|
+
fill();
|
|
4474
|
+
}
|
|
4475
|
+
while (buffer.length > 0) {
|
|
4476
|
+
yield buffer.shift();
|
|
4477
|
+
}
|
|
4478
|
+
while (eventQueue.length > 0) {
|
|
4479
|
+
yield eventQueue.shift();
|
|
4480
|
+
}
|
|
4481
|
+
if (firstError !== void 0) {
|
|
4482
|
+
throw firstError;
|
|
4483
|
+
}
|
|
4484
|
+
}
|
|
4246
4485
|
/**
|
|
4247
4486
|
* Delegate a task to an agent
|
|
4248
4487
|
*/
|
|
@@ -4462,7 +4701,7 @@ ${r.output}`).join("\n\n---\n\n");
|
|
|
4462
4701
|
*/
|
|
4463
4702
|
createCheckpoint() {
|
|
4464
4703
|
return {
|
|
4465
|
-
id:
|
|
4704
|
+
id: nanoid(),
|
|
4466
4705
|
crewId: this.id,
|
|
4467
4706
|
crewName: this.name,
|
|
4468
4707
|
timestamp: /* @__PURE__ */ new Date(),
|
package/dist/templates/index.mjs
CHANGED
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
createResearchCrewConfig,
|
|
12
12
|
createWritingCrew,
|
|
13
13
|
createWritingCrewConfig
|
|
14
|
-
} from "../chunk-
|
|
15
|
-
import "../chunk-
|
|
14
|
+
} from "../chunk-3NMVWRVW.mjs";
|
|
15
|
+
import "../chunk-J5KQSOGT.mjs";
|
|
16
16
|
export {
|
|
17
17
|
CodeReviewTasks,
|
|
18
18
|
CustomerSupportTasks,
|