@dogpile/sdk 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +86 -655
- package/dist/browser/index.js +337 -22
- package/dist/browser/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/runtime/broadcast.d.ts +1 -0
- package/dist/runtime/broadcast.d.ts.map +1 -1
- package/dist/runtime/broadcast.js +27 -6
- package/dist/runtime/broadcast.js.map +1 -1
- package/dist/runtime/coordinator.d.ts +1 -0
- package/dist/runtime/coordinator.d.ts.map +1 -1
- package/dist/runtime/coordinator.js +45 -8
- package/dist/runtime/coordinator.js.map +1 -1
- package/dist/runtime/engine.d.ts.map +1 -1
- package/dist/runtime/engine.js +5 -0
- package/dist/runtime/engine.js.map +1 -1
- package/dist/runtime/sequential.d.ts +1 -0
- package/dist/runtime/sequential.d.ts.map +1 -1
- package/dist/runtime/sequential.js +24 -6
- package/dist/runtime/sequential.js.map +1 -1
- package/dist/runtime/shared.d.ts +1 -0
- package/dist/runtime/shared.d.ts.map +1 -1
- package/dist/runtime/shared.js +24 -6
- package/dist/runtime/shared.js.map +1 -1
- package/dist/runtime/termination.d.ts +6 -1
- package/dist/runtime/termination.d.ts.map +1 -1
- package/dist/runtime/termination.js +75 -0
- package/dist/runtime/termination.js.map +1 -1
- package/dist/runtime/validation.d.ts.map +1 -1
- package/dist/runtime/validation.js +22 -0
- package/dist/runtime/validation.js.map +1 -1
- package/dist/runtime/wrap-up.d.ts +26 -0
- package/dist/runtime/wrap-up.d.ts.map +1 -0
- package/dist/runtime/wrap-up.js +178 -0
- package/dist/runtime/wrap-up.js.map +1 -0
- package/dist/types.d.ts +68 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/index.ts +3 -1
- package/src/runtime/broadcast.ts +49 -19
- package/src/runtime/coordinator.ts +83 -27
- package/src/runtime/engine.ts +6 -0
- package/src/runtime/sequential.ts +45 -19
- package/src/runtime/shared.ts +45 -19
- package/src/runtime/termination.ts +100 -0
- package/src/runtime/validation.ts +25 -0
- package/src/runtime/wrap-up.ts +257 -0
- package/src/types.ts +70 -0
package/dist/browser/index.js
CHANGED
|
@@ -638,6 +638,10 @@ function firstOf(...conditions) {
|
|
|
638
638
|
* own normalized inputs so one stop class cannot accidentally satisfy another.
|
|
639
639
|
*/
|
|
640
640
|
function evaluateTermination(condition, context) {
|
|
641
|
+
if (isTerminationFloorBlocked(condition, context)) return {
|
|
642
|
+
type: "continue",
|
|
643
|
+
condition
|
|
644
|
+
};
|
|
641
645
|
switch (condition.kind) {
|
|
642
646
|
case "budget": return evaluateBudget(condition, context);
|
|
643
647
|
case "firstOf": return evaluateFirstOf(condition, context).decision;
|
|
@@ -695,6 +699,17 @@ function evaluateTerminationStop(condition, context) {
|
|
|
695
699
|
return stopRecord(condition, decision);
|
|
696
700
|
}
|
|
697
701
|
/**
|
|
702
|
+
* Warn when a protocol-level termination floor cannot be satisfied because a
|
|
703
|
+
* lower iteration cap will stop the run first.
|
|
704
|
+
*/
|
|
705
|
+
function warnOnProtocolTerminationMisconfiguration(protocol, terminate, warn = console.warn) {
|
|
706
|
+
const minTurns = protocolMinTurns(protocol);
|
|
707
|
+
if (minTurns === void 0 || !terminate) return;
|
|
708
|
+
const limitingIterationBudget = smallestIterationBudget(terminate);
|
|
709
|
+
if (limitingIterationBudget === void 0 || limitingIterationBudget >= minTurns) return;
|
|
710
|
+
warn(`[dogpile] protocol.minTurns (${minTurns}) exceeds terminate budget maxIterations (${limitingIterationBudget}); maxIterations will win.`);
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
698
713
|
* Combine independently evaluated termination decisions with SDK precedence.
|
|
699
714
|
*
|
|
700
715
|
* Budget caps win over judge decisions, and judge decisions win over
|
|
@@ -843,6 +858,48 @@ function stopPrecedence(reason) {
|
|
|
843
858
|
if (reason.startsWith("judge:")) return 1;
|
|
844
859
|
return 2;
|
|
845
860
|
}
|
|
861
|
+
function isTerminationFloorBlocked(condition, context) {
|
|
862
|
+
if (condition.kind !== "convergence" && condition.kind !== "judge") return false;
|
|
863
|
+
const floor = protocolTerminationFloor(context.protocolConfig);
|
|
864
|
+
if (floor === void 0 || floor <= 0) return false;
|
|
865
|
+
return protocolProgress(context) < floor;
|
|
866
|
+
}
|
|
867
|
+
function protocolTerminationFloor(protocol) {
|
|
868
|
+
if (!protocol) return;
|
|
869
|
+
switch (protocol.kind) {
|
|
870
|
+
case "broadcast": return protocol.minRounds;
|
|
871
|
+
case "coordinator":
|
|
872
|
+
case "sequential":
|
|
873
|
+
case "shared": return protocol.minTurns;
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
function protocolProgress(context) {
|
|
877
|
+
return context.protocolIteration ?? context.iteration ?? context.transcript.length;
|
|
878
|
+
}
|
|
879
|
+
function protocolMinTurns(protocol) {
|
|
880
|
+
switch (protocol.kind) {
|
|
881
|
+
case "broadcast": return;
|
|
882
|
+
case "coordinator":
|
|
883
|
+
case "sequential":
|
|
884
|
+
case "shared": return protocol.minTurns;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
function smallestIterationBudget(condition) {
|
|
888
|
+
switch (condition.kind) {
|
|
889
|
+
case "budget": return condition.maxIterations;
|
|
890
|
+
case "convergence":
|
|
891
|
+
case "judge": return;
|
|
892
|
+
case "firstOf": {
|
|
893
|
+
let smallest;
|
|
894
|
+
for (const child of condition.conditions) {
|
|
895
|
+
const budget = smallestIterationBudget(child);
|
|
896
|
+
if (budget === void 0) continue;
|
|
897
|
+
smallest = smallest === void 0 ? budget : Math.min(smallest, budget);
|
|
898
|
+
}
|
|
899
|
+
return smallest;
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
}
|
|
846
903
|
function judgeStopDetail(decision, minScore) {
|
|
847
904
|
return {
|
|
848
905
|
decision: decision.type,
|
|
@@ -921,6 +978,7 @@ function validateDogpileOptions(options) {
|
|
|
921
978
|
validateOptionalTemperature(options.temperature, "temperature");
|
|
922
979
|
validateOptionalBudgetCaps(options.budget, "budget");
|
|
923
980
|
validateOptionalTerminationCondition(options.terminate, "terminate");
|
|
981
|
+
validateOptionalWrapUpHint(options.wrapUpHint, "wrapUpHint");
|
|
924
982
|
validateOptionalFunction(options.evaluate, "evaluate");
|
|
925
983
|
validateOptionalSeed(options.seed, "seed");
|
|
926
984
|
validateOptionalAbortSignal(options.signal, "signal");
|
|
@@ -941,6 +999,7 @@ function validateEngineOptions(options) {
|
|
|
941
999
|
validateOptionalTemperature(options.temperature, "temperature");
|
|
942
1000
|
validateOptionalBudgetCaps(options.budget, "budget");
|
|
943
1001
|
validateOptionalTerminationCondition(options.terminate, "terminate");
|
|
1002
|
+
validateOptionalWrapUpHint(options.wrapUpHint, "wrapUpHint");
|
|
944
1003
|
validateOptionalFunction(options.evaluate, "evaluate");
|
|
945
1004
|
validateOptionalSeed(options.seed, "seed");
|
|
946
1005
|
validateOptionalAbortSignal(options.signal, "signal");
|
|
@@ -973,10 +1032,12 @@ function validateProtocolConfig(value, path) {
|
|
|
973
1032
|
case "sequential":
|
|
974
1033
|
case "shared":
|
|
975
1034
|
validateOptionalPositiveInteger(record.maxTurns, `${path}.maxTurns`);
|
|
1035
|
+
validateOptionalNonNegativeInteger(record.minTurns, `${path}.minTurns`);
|
|
976
1036
|
if (kind === "shared") validateOptionalString(record.organizationalMemory, `${path}.organizationalMemory`);
|
|
977
1037
|
return;
|
|
978
1038
|
case "broadcast":
|
|
979
1039
|
validateOptionalPositiveInteger(record.maxRounds, `${path}.maxRounds`);
|
|
1040
|
+
validateOptionalNonNegativeInteger(record.minRounds, `${path}.minRounds`);
|
|
980
1041
|
return;
|
|
981
1042
|
}
|
|
982
1043
|
}
|
|
@@ -1144,6 +1205,20 @@ function validateJudgeRubric(value, path) {
|
|
|
1144
1205
|
function validateOptionalTemperature(value, path) {
|
|
1145
1206
|
validateOptionalNumberInRange(value, path, 0, 2);
|
|
1146
1207
|
}
|
|
1208
|
+
function validateOptionalWrapUpHint(value, path) {
|
|
1209
|
+
if (value === void 0) return;
|
|
1210
|
+
const record = requireRecord(value, path);
|
|
1211
|
+
validateOptionalNonNegativeInteger(record.atIteration, `${path}.atIteration`);
|
|
1212
|
+
validateOptionalNumberInRange(record.atFraction, `${path}.atFraction`, 0, 1);
|
|
1213
|
+
validateOptionalFunction(record.inject, `${path}.inject`);
|
|
1214
|
+
if (record.atIteration === void 0 && record.atFraction === void 0) invalidConfiguration({
|
|
1215
|
+
path,
|
|
1216
|
+
rule: "object",
|
|
1217
|
+
message: "wrapUpHint must configure atIteration or atFraction.",
|
|
1218
|
+
expected: "WrapUpHintConfig with atIteration or atFraction",
|
|
1219
|
+
actual: value
|
|
1220
|
+
});
|
|
1221
|
+
}
|
|
1147
1222
|
function validateOptionalSeed(value, path) {
|
|
1148
1223
|
if (value === void 0) return;
|
|
1149
1224
|
if (typeof value === "string") return;
|
|
@@ -2067,6 +2142,151 @@ function isRuntimeToolAdapterErrorCode(value) {
|
|
|
2067
2142
|
return value === "invalid-input" || value === "permission-denied" || value === "timeout" || value === "aborted" || value === "unavailable" || value === "backend-error" || value === "unknown";
|
|
2068
2143
|
}
|
|
2069
2144
|
//#endregion
|
|
2145
|
+
//#region src/runtime/wrap-up.ts
|
|
2146
|
+
function createWrapUpHintController(options) {
|
|
2147
|
+
const hint = options.wrapUpHint;
|
|
2148
|
+
const effectiveBudget = effectiveWrapUpBudget(options.budget, options.terminate);
|
|
2149
|
+
let emitted = false;
|
|
2150
|
+
return {
|
|
2151
|
+
context(context) {
|
|
2152
|
+
return wrapUpEvaluationContext({
|
|
2153
|
+
...context,
|
|
2154
|
+
tier: options.tier,
|
|
2155
|
+
...effectiveBudget !== void 0 ? { budget: effectiveBudget } : {}
|
|
2156
|
+
});
|
|
2157
|
+
},
|
|
2158
|
+
inject(messages, context) {
|
|
2159
|
+
if (!hint || emitted) return messages;
|
|
2160
|
+
const evaluationContext = wrapUpEvaluationContext({
|
|
2161
|
+
...context,
|
|
2162
|
+
tier: options.tier,
|
|
2163
|
+
...effectiveBudget !== void 0 ? { budget: effectiveBudget } : {}
|
|
2164
|
+
});
|
|
2165
|
+
if (!shouldInjectWrapUpHint(hint, evaluationContext)) return messages;
|
|
2166
|
+
const content = (hint.inject ?? defaultWrapUpHint)(evaluationContext);
|
|
2167
|
+
emitted = true;
|
|
2168
|
+
return [
|
|
2169
|
+
messages[0] ?? {
|
|
2170
|
+
role: "system",
|
|
2171
|
+
content: ""
|
|
2172
|
+
},
|
|
2173
|
+
{
|
|
2174
|
+
role: "system",
|
|
2175
|
+
content
|
|
2176
|
+
},
|
|
2177
|
+
...messages.slice(1)
|
|
2178
|
+
];
|
|
2179
|
+
}
|
|
2180
|
+
};
|
|
2181
|
+
}
|
|
2182
|
+
function wrapUpEvaluationContext(options) {
|
|
2183
|
+
const iteration = options.iteration ?? options.transcript.length;
|
|
2184
|
+
const elapsedMs = options.elapsedMs;
|
|
2185
|
+
return {
|
|
2186
|
+
runId: options.runId,
|
|
2187
|
+
protocol: options.protocol,
|
|
2188
|
+
tier: options.tier,
|
|
2189
|
+
cost: options.cost,
|
|
2190
|
+
events: options.events,
|
|
2191
|
+
transcript: options.transcript,
|
|
2192
|
+
...options.protocolConfig !== void 0 ? { protocolConfig: options.protocolConfig } : {},
|
|
2193
|
+
...iteration !== void 0 ? { iteration } : {},
|
|
2194
|
+
...options.protocolIteration !== void 0 ? { protocolIteration: options.protocolIteration } : {},
|
|
2195
|
+
...elapsedMs !== void 0 ? { elapsedMs } : {},
|
|
2196
|
+
...options.budget !== void 0 ? { budget: options.budget } : {},
|
|
2197
|
+
...options.budget !== void 0 ? { remainingBudget: remainingBudget(options.budget, {
|
|
2198
|
+
cost: options.cost,
|
|
2199
|
+
iteration,
|
|
2200
|
+
elapsedMs
|
|
2201
|
+
}) } : {},
|
|
2202
|
+
...options.metadata !== void 0 ? { metadata: options.metadata } : {}
|
|
2203
|
+
};
|
|
2204
|
+
}
|
|
2205
|
+
function shouldInjectWrapUpHint(hint, context) {
|
|
2206
|
+
const iteration = context.iteration ?? context.transcript.length;
|
|
2207
|
+
if (hint.atIteration !== void 0 && iteration >= hint.atIteration) return true;
|
|
2208
|
+
if (hint.atFraction === void 0 || context.budget === void 0) return false;
|
|
2209
|
+
const fraction = hint.atFraction;
|
|
2210
|
+
return capFractionReached(iteration, context.budget.maxIterations, fraction) || capFractionReached(context.elapsedMs, context.budget.timeoutMs, fraction);
|
|
2211
|
+
}
|
|
2212
|
+
function capFractionReached(current, limit, fraction) {
|
|
2213
|
+
if (current === void 0 || limit === void 0 || limit <= 0) return false;
|
|
2214
|
+
return current / limit >= fraction;
|
|
2215
|
+
}
|
|
2216
|
+
function remainingBudget(budget, current) {
|
|
2217
|
+
return {
|
|
2218
|
+
...budget.maxIterations !== void 0 && current.iteration !== void 0 ? { iterations: Math.max(0, budget.maxIterations - current.iteration) } : {},
|
|
2219
|
+
...budget.timeoutMs !== void 0 && current.elapsedMs !== void 0 ? { timeoutMs: Math.max(0, budget.timeoutMs - current.elapsedMs) } : {},
|
|
2220
|
+
...budget.maxUsd !== void 0 ? { usd: Math.max(0, budget.maxUsd - current.cost.usd) } : {},
|
|
2221
|
+
...budget.maxTokens !== void 0 ? { tokens: Math.max(0, budget.maxTokens - current.cost.totalTokens) } : {}
|
|
2222
|
+
};
|
|
2223
|
+
}
|
|
2224
|
+
function defaultWrapUpHint(context) {
|
|
2225
|
+
const parts = [];
|
|
2226
|
+
const remaining = context.remainingBudget;
|
|
2227
|
+
if (remaining?.iterations !== void 0) {
|
|
2228
|
+
const label = remaining.iterations === 1 ? "turn" : "turns";
|
|
2229
|
+
parts.push(`${remaining.iterations} ${label} remaining`);
|
|
2230
|
+
}
|
|
2231
|
+
if (remaining?.timeoutMs !== void 0) parts.push(`${formatRemainingTime(remaining.timeoutMs)} remaining`);
|
|
2232
|
+
return `[wrap-up] ${parts.length === 0 ? "You are approaching a configured hard limit." : `You are approaching a hard limit with ${parts.join(" and ")}.`} If you have enough context, package your work now and return a final-ready answer.`;
|
|
2233
|
+
}
|
|
2234
|
+
function formatRemainingTime(timeoutMs) {
|
|
2235
|
+
if (timeoutMs >= 1e3) return `${(timeoutMs / 1e3).toFixed(1)}s`;
|
|
2236
|
+
return `${timeoutMs}ms`;
|
|
2237
|
+
}
|
|
2238
|
+
function effectiveWrapUpBudget(budget, terminate) {
|
|
2239
|
+
const terminationBudget = budgetCapsFromTermination(terminate);
|
|
2240
|
+
if (!budget && !terminationBudget) return;
|
|
2241
|
+
const maxUsd = minCap(budget?.maxUsd, terminationBudget?.maxUsd);
|
|
2242
|
+
const maxTokens = minCap(budget?.maxTokens, terminationBudget?.maxTokens);
|
|
2243
|
+
const maxIterations = minCap(budget?.maxIterations, terminationBudget?.maxIterations);
|
|
2244
|
+
const timeoutMs = minCap(budget?.timeoutMs, terminationBudget?.timeoutMs);
|
|
2245
|
+
return {
|
|
2246
|
+
...maxUsd !== void 0 ? { maxUsd } : {},
|
|
2247
|
+
...maxTokens !== void 0 ? { maxTokens } : {},
|
|
2248
|
+
...maxIterations !== void 0 ? { maxIterations } : {},
|
|
2249
|
+
...timeoutMs !== void 0 ? { timeoutMs } : {}
|
|
2250
|
+
};
|
|
2251
|
+
}
|
|
2252
|
+
function budgetCapsFromTermination(condition) {
|
|
2253
|
+
if (!condition) return;
|
|
2254
|
+
switch (condition.kind) {
|
|
2255
|
+
case "budget": return {
|
|
2256
|
+
...condition.maxUsd !== void 0 ? { maxUsd: condition.maxUsd } : {},
|
|
2257
|
+
...condition.maxTokens !== void 0 ? { maxTokens: condition.maxTokens } : {},
|
|
2258
|
+
...condition.maxIterations !== void 0 ? { maxIterations: condition.maxIterations } : {},
|
|
2259
|
+
...condition.timeoutMs !== void 0 ? { timeoutMs: condition.timeoutMs } : {}
|
|
2260
|
+
};
|
|
2261
|
+
case "firstOf": {
|
|
2262
|
+
let merged;
|
|
2263
|
+
for (const child of condition.conditions) merged = mergeBudgetCaps(merged, budgetCapsFromTermination(child));
|
|
2264
|
+
return merged;
|
|
2265
|
+
}
|
|
2266
|
+
case "convergence":
|
|
2267
|
+
case "judge": return;
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
function mergeBudgetCaps(left, right) {
|
|
2271
|
+
if (!left) return right;
|
|
2272
|
+
if (!right) return left;
|
|
2273
|
+
const maxUsd = minCap(left.maxUsd, right.maxUsd);
|
|
2274
|
+
const maxTokens = minCap(left.maxTokens, right.maxTokens);
|
|
2275
|
+
const maxIterations = minCap(left.maxIterations, right.maxIterations);
|
|
2276
|
+
const timeoutMs = minCap(left.timeoutMs, right.timeoutMs);
|
|
2277
|
+
return {
|
|
2278
|
+
...maxUsd !== void 0 ? { maxUsd } : {},
|
|
2279
|
+
...maxTokens !== void 0 ? { maxTokens } : {},
|
|
2280
|
+
...maxIterations !== void 0 ? { maxIterations } : {},
|
|
2281
|
+
...timeoutMs !== void 0 ? { timeoutMs } : {}
|
|
2282
|
+
};
|
|
2283
|
+
}
|
|
2284
|
+
function minCap(left, right) {
|
|
2285
|
+
if (left === void 0) return right;
|
|
2286
|
+
if (right === void 0) return left;
|
|
2287
|
+
return Math.min(left, right);
|
|
2288
|
+
}
|
|
2289
|
+
//#endregion
|
|
2070
2290
|
//#region src/runtime/broadcast.ts
|
|
2071
2291
|
async function runBroadcast(options) {
|
|
2072
2292
|
const runId = createRunId$3();
|
|
@@ -2081,6 +2301,14 @@ async function runBroadcast(options) {
|
|
|
2081
2301
|
const startedAtMs = nowMs$3();
|
|
2082
2302
|
let stopped = false;
|
|
2083
2303
|
let termination;
|
|
2304
|
+
const wrapUpHint = createWrapUpHintController({
|
|
2305
|
+
protocol: options.protocol,
|
|
2306
|
+
tier: options.tier,
|
|
2307
|
+
...options.budget ? { budget: options.budget } : {},
|
|
2308
|
+
...options.terminate ? { terminate: options.terminate } : {},
|
|
2309
|
+
...options.wrapUpHint ? { wrapUpHint: options.wrapUpHint } : {}
|
|
2310
|
+
});
|
|
2311
|
+
warnOnProtocolTerminationMisconfiguration(options.protocol, options.terminate);
|
|
2084
2312
|
const emit = (event) => {
|
|
2085
2313
|
events.push(event);
|
|
2086
2314
|
options.emit?.(event);
|
|
@@ -2134,13 +2362,21 @@ async function runBroadcast(options) {
|
|
|
2134
2362
|
round,
|
|
2135
2363
|
...toolAvailability
|
|
2136
2364
|
},
|
|
2137
|
-
messages: [{
|
|
2365
|
+
messages: wrapUpHint.inject([{
|
|
2138
2366
|
role: "system",
|
|
2139
2367
|
content: buildSystemPrompt$3(agent)
|
|
2140
2368
|
}, {
|
|
2141
2369
|
role: "user",
|
|
2142
2370
|
content: input
|
|
2143
|
-
}]
|
|
2371
|
+
}], {
|
|
2372
|
+
runId,
|
|
2373
|
+
protocol: "broadcast",
|
|
2374
|
+
cost: totalCost,
|
|
2375
|
+
events,
|
|
2376
|
+
transcript,
|
|
2377
|
+
iteration: transcript.length,
|
|
2378
|
+
elapsedMs: elapsedMs$3(startedAtMs)
|
|
2379
|
+
})
|
|
2144
2380
|
};
|
|
2145
2381
|
const response = await generateModelTurn({
|
|
2146
2382
|
model: options.model,
|
|
@@ -2305,16 +2541,17 @@ async function runBroadcast(options) {
|
|
|
2305
2541
|
function stopIfNeeded() {
|
|
2306
2542
|
throwIfAborted(options.signal, options.model.id);
|
|
2307
2543
|
if (stopped || !options.terminate) return stopped;
|
|
2308
|
-
const stopRecord = evaluateTerminationStop(options.terminate, {
|
|
2544
|
+
const stopRecord = evaluateTerminationStop(options.terminate, wrapUpHint.context({
|
|
2309
2545
|
runId,
|
|
2310
2546
|
protocol: "broadcast",
|
|
2311
|
-
|
|
2547
|
+
protocolConfig: options.protocol,
|
|
2548
|
+
protocolIteration: broadcastRoundsCompleted(events),
|
|
2312
2549
|
cost: totalCost,
|
|
2313
2550
|
events,
|
|
2314
2551
|
transcript,
|
|
2315
2552
|
iteration: transcript.length,
|
|
2316
2553
|
elapsedMs: elapsedMs$3(startedAtMs)
|
|
2317
|
-
});
|
|
2554
|
+
}));
|
|
2318
2555
|
if (!stopRecord) return false;
|
|
2319
2556
|
stopped = true;
|
|
2320
2557
|
termination = stopRecord;
|
|
@@ -2336,6 +2573,9 @@ async function runBroadcast(options) {
|
|
|
2336
2573
|
recordProtocolDecision(event, { transcriptEntryCount: transcript.length });
|
|
2337
2574
|
}
|
|
2338
2575
|
}
|
|
2576
|
+
function broadcastRoundsCompleted(events) {
|
|
2577
|
+
return events.filter((event) => event.type === "broadcast").length;
|
|
2578
|
+
}
|
|
2339
2579
|
function buildSystemPrompt$3(agent) {
|
|
2340
2580
|
const instruction = agent.instructions ? `\nInstructions: ${agent.instructions}` : "";
|
|
2341
2581
|
return `You are ${agent.id}, acting as ${agent.role} in a Broadcast multi-agent protocol.${instruction}`;
|
|
@@ -2383,6 +2623,14 @@ async function runCoordinator(options) {
|
|
|
2383
2623
|
const startedAtMs = nowMs$2();
|
|
2384
2624
|
let stopped = false;
|
|
2385
2625
|
let termination;
|
|
2626
|
+
const wrapUpHint = createWrapUpHintController({
|
|
2627
|
+
protocol: options.protocol,
|
|
2628
|
+
tier: options.tier,
|
|
2629
|
+
...options.budget ? { budget: options.budget } : {},
|
|
2630
|
+
...options.terminate ? { terminate: options.terminate } : {},
|
|
2631
|
+
...options.wrapUpHint ? { wrapUpHint: options.wrapUpHint } : {}
|
|
2632
|
+
});
|
|
2633
|
+
warnOnProtocolTerminationMisconfiguration(options.protocol, options.terminate);
|
|
2386
2634
|
const emit = (event) => {
|
|
2387
2635
|
events.push(event);
|
|
2388
2636
|
options.emit?.(event);
|
|
@@ -2432,6 +2680,9 @@ async function runCoordinator(options) {
|
|
|
2432
2680
|
providerCalls,
|
|
2433
2681
|
toolExecutor,
|
|
2434
2682
|
toolAvailability,
|
|
2683
|
+
events,
|
|
2684
|
+
startedAtMs,
|
|
2685
|
+
wrapUpHint,
|
|
2435
2686
|
emit,
|
|
2436
2687
|
recordProtocolDecision
|
|
2437
2688
|
});
|
|
@@ -2453,6 +2704,11 @@ async function runCoordinator(options) {
|
|
|
2453
2704
|
providerCallSlots,
|
|
2454
2705
|
toolExecutor,
|
|
2455
2706
|
toolAvailability,
|
|
2707
|
+
totalCost,
|
|
2708
|
+
events,
|
|
2709
|
+
transcript: planTranscript,
|
|
2710
|
+
startedAtMs,
|
|
2711
|
+
wrapUpHint,
|
|
2456
2712
|
emit
|
|
2457
2713
|
})));
|
|
2458
2714
|
providerCalls.push(...providerCallSlots.filter((call) => call !== void 0));
|
|
@@ -2499,6 +2755,9 @@ async function runCoordinator(options) {
|
|
|
2499
2755
|
providerCalls,
|
|
2500
2756
|
toolExecutor,
|
|
2501
2757
|
toolAvailability,
|
|
2758
|
+
events,
|
|
2759
|
+
startedAtMs,
|
|
2760
|
+
wrapUpHint,
|
|
2502
2761
|
emit,
|
|
2503
2762
|
recordProtocolDecision
|
|
2504
2763
|
});
|
|
@@ -2579,16 +2838,17 @@ async function runCoordinator(options) {
|
|
|
2579
2838
|
function stopIfNeeded() {
|
|
2580
2839
|
throwIfAborted(options.signal, options.model.id);
|
|
2581
2840
|
if (stopped || !options.terminate) return stopped;
|
|
2582
|
-
const stopRecord = evaluateTerminationStop(options.terminate, {
|
|
2841
|
+
const stopRecord = evaluateTerminationStop(options.terminate, wrapUpHint.context({
|
|
2583
2842
|
runId,
|
|
2584
2843
|
protocol: "coordinator",
|
|
2585
|
-
|
|
2844
|
+
protocolConfig: options.protocol,
|
|
2845
|
+
protocolIteration: transcript.length,
|
|
2586
2846
|
cost: totalCost,
|
|
2587
2847
|
events,
|
|
2588
2848
|
transcript,
|
|
2589
2849
|
iteration: transcript.length,
|
|
2590
2850
|
elapsedMs: elapsedMs$2(startedAtMs)
|
|
2591
|
-
});
|
|
2851
|
+
}));
|
|
2592
2852
|
if (!stopRecord) return false;
|
|
2593
2853
|
stopped = true;
|
|
2594
2854
|
termination = stopRecord;
|
|
@@ -2625,13 +2885,21 @@ async function runCoordinatorTurn(turn) {
|
|
|
2625
2885
|
phase: turn.phase,
|
|
2626
2886
|
...turn.toolAvailability
|
|
2627
2887
|
},
|
|
2628
|
-
messages: [{
|
|
2888
|
+
messages: turn.wrapUpHint.inject([{
|
|
2629
2889
|
role: "system",
|
|
2630
2890
|
content: buildSystemPrompt$2(turn.agent, turn.coordinator)
|
|
2631
2891
|
}, {
|
|
2632
2892
|
role: "user",
|
|
2633
2893
|
content: turn.input
|
|
2634
|
-
}]
|
|
2894
|
+
}], {
|
|
2895
|
+
runId: turn.runId,
|
|
2896
|
+
protocol: "coordinator",
|
|
2897
|
+
cost: turn.totalCost,
|
|
2898
|
+
events: turn.events,
|
|
2899
|
+
transcript: turn.transcript,
|
|
2900
|
+
iteration: turn.transcript.length,
|
|
2901
|
+
elapsedMs: elapsedMs$2(turn.startedAtMs)
|
|
2902
|
+
})
|
|
2635
2903
|
};
|
|
2636
2904
|
const response = await generateModelTurn({
|
|
2637
2905
|
model: turn.options.model,
|
|
@@ -2698,13 +2966,21 @@ async function runCoordinatorWorkerTurn(turn) {
|
|
|
2698
2966
|
phase: "worker",
|
|
2699
2967
|
...turn.toolAvailability
|
|
2700
2968
|
},
|
|
2701
|
-
messages: [{
|
|
2969
|
+
messages: turn.wrapUpHint.inject([{
|
|
2702
2970
|
role: "system",
|
|
2703
2971
|
content: buildSystemPrompt$2(turn.agent, turn.coordinator)
|
|
2704
2972
|
}, {
|
|
2705
2973
|
role: "user",
|
|
2706
2974
|
content: turn.input
|
|
2707
|
-
}]
|
|
2975
|
+
}], {
|
|
2976
|
+
runId: turn.runId,
|
|
2977
|
+
protocol: "coordinator",
|
|
2978
|
+
cost: turn.totalCost,
|
|
2979
|
+
events: turn.events,
|
|
2980
|
+
transcript: turn.transcript,
|
|
2981
|
+
iteration: turn.turn - 1,
|
|
2982
|
+
elapsedMs: elapsedMs$2(turn.startedAtMs)
|
|
2983
|
+
})
|
|
2708
2984
|
};
|
|
2709
2985
|
const response = await generateModelTurn({
|
|
2710
2986
|
model: turn.options.model,
|
|
@@ -2787,6 +3063,14 @@ async function runSequential(options) {
|
|
|
2787
3063
|
const startedAtMs = nowMs$1();
|
|
2788
3064
|
let stopped = false;
|
|
2789
3065
|
let termination;
|
|
3066
|
+
const wrapUpHint = createWrapUpHintController({
|
|
3067
|
+
protocol: options.protocol,
|
|
3068
|
+
tier: options.tier,
|
|
3069
|
+
...options.budget ? { budget: options.budget } : {},
|
|
3070
|
+
...options.terminate ? { terminate: options.terminate } : {},
|
|
3071
|
+
...options.wrapUpHint ? { wrapUpHint: options.wrapUpHint } : {}
|
|
3072
|
+
});
|
|
3073
|
+
warnOnProtocolTerminationMisconfiguration(options.protocol, options.terminate);
|
|
2790
3074
|
const emit = (event) => {
|
|
2791
3075
|
events.push(event);
|
|
2792
3076
|
options.emit?.(event);
|
|
@@ -2838,13 +3122,21 @@ async function runSequential(options) {
|
|
|
2838
3122
|
turn,
|
|
2839
3123
|
...toolAvailability
|
|
2840
3124
|
},
|
|
2841
|
-
messages: [{
|
|
3125
|
+
messages: wrapUpHint.inject([{
|
|
2842
3126
|
role: "system",
|
|
2843
3127
|
content: buildSystemPrompt$1(agent)
|
|
2844
3128
|
}, {
|
|
2845
3129
|
role: "user",
|
|
2846
3130
|
content: input
|
|
2847
|
-
}]
|
|
3131
|
+
}], {
|
|
3132
|
+
runId,
|
|
3133
|
+
protocol: "sequential",
|
|
3134
|
+
cost: totalCost,
|
|
3135
|
+
events,
|
|
3136
|
+
transcript,
|
|
3137
|
+
iteration: transcript.length,
|
|
3138
|
+
elapsedMs: elapsedMs$1(startedAtMs)
|
|
3139
|
+
})
|
|
2848
3140
|
};
|
|
2849
3141
|
const response = await generateModelTurn({
|
|
2850
3142
|
model: options.model,
|
|
@@ -2969,16 +3261,17 @@ async function runSequential(options) {
|
|
|
2969
3261
|
function stopIfNeeded() {
|
|
2970
3262
|
throwIfAborted(options.signal, options.model.id);
|
|
2971
3263
|
if (stopped || !options.terminate) return stopped;
|
|
2972
|
-
const stopRecord = evaluateTerminationStop(options.terminate, {
|
|
3264
|
+
const stopRecord = evaluateTerminationStop(options.terminate, wrapUpHint.context({
|
|
2973
3265
|
runId,
|
|
2974
3266
|
protocol: "sequential",
|
|
2975
|
-
|
|
3267
|
+
protocolConfig: options.protocol,
|
|
3268
|
+
protocolIteration: transcript.length,
|
|
2976
3269
|
cost: totalCost,
|
|
2977
3270
|
events,
|
|
2978
3271
|
transcript,
|
|
2979
3272
|
iteration: transcript.length,
|
|
2980
3273
|
elapsedMs: elapsedMs$1(startedAtMs)
|
|
2981
|
-
});
|
|
3274
|
+
}));
|
|
2982
3275
|
if (!stopRecord) return false;
|
|
2983
3276
|
stopped = true;
|
|
2984
3277
|
termination = stopRecord;
|
|
@@ -3040,6 +3333,14 @@ async function runShared(options) {
|
|
|
3040
3333
|
const startedAtMs = nowMs();
|
|
3041
3334
|
let stopped = false;
|
|
3042
3335
|
let termination;
|
|
3336
|
+
const wrapUpHint = createWrapUpHintController({
|
|
3337
|
+
protocol: options.protocol,
|
|
3338
|
+
tier: options.tier,
|
|
3339
|
+
...options.budget ? { budget: options.budget } : {},
|
|
3340
|
+
...options.terminate ? { terminate: options.terminate } : {},
|
|
3341
|
+
...options.wrapUpHint ? { wrapUpHint: options.wrapUpHint } : {}
|
|
3342
|
+
});
|
|
3343
|
+
warnOnProtocolTerminationMisconfiguration(options.protocol, options.terminate);
|
|
3043
3344
|
const emit = (event) => {
|
|
3044
3345
|
events.push(event);
|
|
3045
3346
|
options.emit?.(event);
|
|
@@ -3092,13 +3393,21 @@ async function runShared(options) {
|
|
|
3092
3393
|
turn,
|
|
3093
3394
|
...toolAvailability
|
|
3094
3395
|
},
|
|
3095
|
-
messages: [{
|
|
3396
|
+
messages: wrapUpHint.inject([{
|
|
3096
3397
|
role: "system",
|
|
3097
3398
|
content: buildSystemPrompt(agent)
|
|
3098
3399
|
}, {
|
|
3099
3400
|
role: "user",
|
|
3100
3401
|
content: input
|
|
3101
|
-
}]
|
|
3402
|
+
}], {
|
|
3403
|
+
runId,
|
|
3404
|
+
protocol: "shared",
|
|
3405
|
+
cost: totalCost,
|
|
3406
|
+
events,
|
|
3407
|
+
transcript,
|
|
3408
|
+
iteration: transcript.length,
|
|
3409
|
+
elapsedMs: elapsedMs(startedAtMs)
|
|
3410
|
+
})
|
|
3102
3411
|
};
|
|
3103
3412
|
const response = await generateModelTurn({
|
|
3104
3413
|
model: options.model,
|
|
@@ -3235,16 +3544,17 @@ async function runShared(options) {
|
|
|
3235
3544
|
function stopIfNeeded() {
|
|
3236
3545
|
throwIfAborted(options.signal, options.model.id);
|
|
3237
3546
|
if (stopped || !options.terminate) return stopped;
|
|
3238
|
-
const stopRecord = evaluateTerminationStop(options.terminate, {
|
|
3547
|
+
const stopRecord = evaluateTerminationStop(options.terminate, wrapUpHint.context({
|
|
3239
3548
|
runId,
|
|
3240
3549
|
protocol: "shared",
|
|
3241
|
-
|
|
3550
|
+
protocolConfig: options.protocol,
|
|
3551
|
+
protocolIteration: transcript.length,
|
|
3242
3552
|
cost: totalCost,
|
|
3243
3553
|
events,
|
|
3244
3554
|
transcript,
|
|
3245
3555
|
iteration: transcript.length,
|
|
3246
3556
|
elapsedMs: elapsedMs(startedAtMs)
|
|
3247
|
-
});
|
|
3557
|
+
}));
|
|
3248
3558
|
if (!stopRecord) return false;
|
|
3249
3559
|
stopped = true;
|
|
3250
3560
|
termination = stopRecord;
|
|
@@ -3333,6 +3643,7 @@ function createEngine(options) {
|
|
|
3333
3643
|
...options.seed !== void 0 ? { seed: options.seed } : {},
|
|
3334
3644
|
...options.signal !== void 0 ? { signal: options.signal } : {},
|
|
3335
3645
|
...terminate ? { terminate } : {},
|
|
3646
|
+
...options.wrapUpHint ? { wrapUpHint: options.wrapUpHint } : {},
|
|
3336
3647
|
...options.evaluate ? { evaluate: options.evaluate } : {}
|
|
3337
3648
|
});
|
|
3338
3649
|
},
|
|
@@ -3715,6 +4026,7 @@ function runProtocol(options) {
|
|
|
3715
4026
|
...options.seed !== void 0 ? { seed: options.seed } : {},
|
|
3716
4027
|
...options.signal !== void 0 ? { signal: options.signal } : {},
|
|
3717
4028
|
...options.terminate ? { terminate: options.terminate } : {},
|
|
4029
|
+
...options.wrapUpHint ? { wrapUpHint: options.wrapUpHint } : {},
|
|
3718
4030
|
...options.emit ? { emit: options.emit } : {}
|
|
3719
4031
|
});
|
|
3720
4032
|
case "broadcast": return runBroadcast({
|
|
@@ -3729,6 +4041,7 @@ function runProtocol(options) {
|
|
|
3729
4041
|
...options.seed !== void 0 ? { seed: options.seed } : {},
|
|
3730
4042
|
...options.signal !== void 0 ? { signal: options.signal } : {},
|
|
3731
4043
|
...options.terminate ? { terminate: options.terminate } : {},
|
|
4044
|
+
...options.wrapUpHint ? { wrapUpHint: options.wrapUpHint } : {},
|
|
3732
4045
|
...options.emit ? { emit: options.emit } : {}
|
|
3733
4046
|
});
|
|
3734
4047
|
case "coordinator": return runCoordinator({
|
|
@@ -3743,6 +4056,7 @@ function runProtocol(options) {
|
|
|
3743
4056
|
...options.seed !== void 0 ? { seed: options.seed } : {},
|
|
3744
4057
|
...options.signal !== void 0 ? { signal: options.signal } : {},
|
|
3745
4058
|
...options.terminate ? { terminate: options.terminate } : {},
|
|
4059
|
+
...options.wrapUpHint ? { wrapUpHint: options.wrapUpHint } : {},
|
|
3746
4060
|
...options.emit ? { emit: options.emit } : {}
|
|
3747
4061
|
});
|
|
3748
4062
|
case "shared": return runShared({
|
|
@@ -3757,6 +4071,7 @@ function runProtocol(options) {
|
|
|
3757
4071
|
...options.seed !== void 0 ? { seed: options.seed } : {},
|
|
3758
4072
|
...options.signal !== void 0 ? { signal: options.signal } : {},
|
|
3759
4073
|
...options.terminate ? { terminate: options.terminate } : {},
|
|
4074
|
+
...options.wrapUpHint ? { wrapUpHint: options.wrapUpHint } : {},
|
|
3760
4075
|
...options.emit ? { emit: options.emit } : {}
|
|
3761
4076
|
});
|
|
3762
4077
|
}
|