blun-king-cli 9.1.102 → 9.1.103
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/LIESMICH.txt +1 -1
- package/bin/subagent-timeout-policy.cjs +16 -1
- package/blun.mjs +40 -1
- package/package.json +1 -1
package/LIESMICH.txt
CHANGED
|
@@ -103,7 +103,7 @@ Das Telemetrieereignis `tool_result_batch_offloaded` meldet ausschließlich die
|
|
|
103
103
|
|
|
104
104
|
Reguläre `Agent`-Teilaufgaben verwenden eine eigene `ContextMemory` und eine eigene `wire.jsonl` in einem getrennten Agentenverzeichnis. Der Hauptagent erhält nur die Ergebniszusammenfassung, sodass lange Teilaufgaben nicht den Hauptverlauf füllen. `TodoList` speichert Pläne weiterhin maschinenlesbar im Sitzungs-Wire; `blun handoff` übergibt sie zusammen mit prüfbaren Hashes zwischen CLI, Desktop und Web.
|
|
105
105
|
|
|
106
|
-
Verliert ein delegierter Einzelagent die Provider-Verbindung, erhält
|
|
106
|
+
Verliert ein delegierter Einzelagent oder ein Mitglied eines Agentenschwarms die Provider-Verbindung, erhält es eine leere Provider-Antwort, bricht sein Stream wegen Leerlaufs ab oder meldet der Server HTTP 408/500/502/503/504, setzt BLUN King denselben Agenten anhand seines dauerhaften Verlaufs fort. Bei Einzelagenten sowie bei Schwarm-Unterbrechungen außerhalb von HTTP 429 wartet die erste Fortsetzung zwei Sekunden und die zweite fünf Sekunden; danach bleibt der ursprüngliche Fehler sichtbar. HTTP 429 behält im Schwarm seine getrennte, längere Überlastungsregel. Authentifizierungs-, Zahlungs- oder Kontingent-, Richtlinien-, Kontext-, Werkzeug- und Codefehler sowie manuelle Abbrüche lösen keine automatische Fortsetzung aus. Jeder Fortsetzungsversuch verwendet die bestehende Agenten-ID, damit bereits abgeschlossene Arbeit nicht wiederholt wird.
|
|
107
107
|
|
|
108
108
|
Rein lesende Sitzungsdiagnose
|
|
109
109
|
--------------------------------
|
|
@@ -74,6 +74,18 @@ function isRetryableSubagentFailure(error) {
|
|
|
74
74
|
return RETRYABLE_MESSAGE_RE.test(message);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
function transientSubagentRetryDelayMs(retryCount) {
|
|
78
|
+
if (!Number.isInteger(retryCount) || retryCount < 1) {
|
|
79
|
+
throw new Error("retryCount must be a positive integer.");
|
|
80
|
+
}
|
|
81
|
+
return DEFAULT_TRANSIENT_RETRY_DELAYS_MS[retryCount - 1]
|
|
82
|
+
?? DEFAULT_TRANSIENT_RETRY_DELAYS_MS.at(-1);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function shouldStopTransientSubagentContinuation(retryCount) {
|
|
86
|
+
return retryCount >= MAX_TRANSIENT_SUBAGENT_CONTINUATIONS;
|
|
87
|
+
}
|
|
88
|
+
|
|
77
89
|
function waitForRetryDelay(delayMs, signal) {
|
|
78
90
|
if (delayMs <= 0) return Promise.resolve();
|
|
79
91
|
if (signal.aborted) return Promise.reject(abortError(signal.reason));
|
|
@@ -134,7 +146,8 @@ async function runAgentWithTimeoutContinuation({
|
|
|
134
146
|
throw result.error;
|
|
135
147
|
}
|
|
136
148
|
const attempt = transientContinuations + 1;
|
|
137
|
-
const delayMs = retryDelaysMs[transientContinuations]
|
|
149
|
+
const delayMs = retryDelaysMs[transientContinuations]
|
|
150
|
+
?? transientSubagentRetryDelayMs(attempt);
|
|
138
151
|
transientContinuations = attempt;
|
|
139
152
|
await waitForRetryDelay(delayMs, signal);
|
|
140
153
|
currentHandle = await retrySameAgent(currentHandle.agentId, {
|
|
@@ -164,4 +177,6 @@ module.exports = {
|
|
|
164
177
|
isRetryableSubagentFailure,
|
|
165
178
|
resolveSubagentTimeoutMs,
|
|
166
179
|
runAgentWithTimeoutContinuation,
|
|
180
|
+
shouldStopTransientSubagentContinuation,
|
|
181
|
+
transientSubagentRetryDelayMs,
|
|
167
182
|
};
|
package/blun.mjs
CHANGED
|
@@ -251353,18 +251353,20 @@ function resolveSwarmMaxConcurrency(env = process.env) {
|
|
|
251353
251353
|
if (!Number.isInteger(value) || value <= 0) throw new Error(`${AGENT_SWARM_MAX_CONCURRENCY_ENV} must be a positive integer, got ${JSON.stringify(raw)}.`);
|
|
251354
251354
|
return value;
|
|
251355
251355
|
}
|
|
251356
|
-
var import_retry, INITIAL_LAUNCH_LIMIT, INITIAL_LAUNCH_INTERVAL_MS, RATE_LIMIT_RETRY_BASE_MS, RATE_LIMIT_RETRY_FACTOR, RATE_LIMIT_CAPACITY_SHRINK_INTERVAL_MS, RATE_LIMIT_CAPACITY_RECOVERY_INTERVAL_MS, RATE_LIMIT_SUSPENDED_REASON, AGENT_SWARM_MAX_CONCURRENCY_ENV, MAX_AUTOMATIC_RATE_LIMIT_RESUMES, rateLimitRetryDelayMs, shouldCompactBeforeRateLimitResume, shouldStopAutomaticRateLimitResume, SubagentBatch;
|
|
251356
|
+
var import_retry, INITIAL_LAUNCH_LIMIT, INITIAL_LAUNCH_INTERVAL_MS, RATE_LIMIT_RETRY_BASE_MS, RATE_LIMIT_RETRY_FACTOR, RATE_LIMIT_CAPACITY_SHRINK_INTERVAL_MS, RATE_LIMIT_CAPACITY_RECOVERY_INTERVAL_MS, RATE_LIMIT_SUSPENDED_REASON, TRANSIENT_PROVIDER_SUSPENDED_REASON, AGENT_SWARM_MAX_CONCURRENCY_ENV, MAX_AUTOMATIC_RATE_LIMIT_RESUMES, MAX_TRANSIENT_SUBAGENT_CONTINUATIONS, isRetryableSubagentFailure, rateLimitRetryDelayMs, shouldCompactBeforeRateLimitResume, shouldStopAutomaticRateLimitResume, shouldStopTransientSubagentContinuation, transientSubagentRetryDelayMs, SubagentBatch;
|
|
251357
251357
|
var init_subagent_batch = __esmMin((() => {
|
|
251358
251358
|
init_src$4();
|
|
251359
251359
|
import_retry = /* @__PURE__ */ __toESM(require_retry$1(), 1);
|
|
251360
251360
|
init_abort();
|
|
251361
251361
|
({ MAX_AUTOMATIC_RATE_LIMIT_RESUMES, RATE_LIMIT_RETRY_BASE_MS, rateLimitRetryDelayMs, shouldCompactBeforeRateLimitResume, shouldStopAutomaticRateLimitResume } = createRequire(import.meta.url)("./bin/rate-limit-recovery-policy.cjs"));
|
|
251362
|
+
({ MAX_TRANSIENT_SUBAGENT_CONTINUATIONS, isRetryableSubagentFailure, shouldStopTransientSubagentContinuation, transientSubagentRetryDelayMs } = createRequire(import.meta.url)("./bin/subagent-timeout-policy.cjs"));
|
|
251362
251363
|
INITIAL_LAUNCH_LIMIT = 5;
|
|
251363
251364
|
INITIAL_LAUNCH_INTERVAL_MS = 700;
|
|
251364
251365
|
RATE_LIMIT_RETRY_FACTOR = 2;
|
|
251365
251366
|
RATE_LIMIT_CAPACITY_SHRINK_INTERVAL_MS = 2e3;
|
|
251366
251367
|
RATE_LIMIT_CAPACITY_RECOVERY_INTERVAL_MS = 180 * 1e3;
|
|
251367
251368
|
RATE_LIMIT_SUSPENDED_REASON = "Provider rate limit; subagent requeued for retry.";
|
|
251369
|
+
TRANSIENT_PROVIDER_SUSPENDED_REASON = "Transient provider interruption; subagent requeued for continuation.";
|
|
251368
251370
|
AGENT_SWARM_MAX_CONCURRENCY_ENV = "BLUN_AGENT_SWARM_MAX_CONCURRENCY";
|
|
251369
251371
|
SubagentBatch = class {
|
|
251370
251372
|
launcher;
|
|
@@ -251379,6 +251381,7 @@ var init_subagent_batch = __esmMin((() => {
|
|
|
251379
251381
|
normalLaunchCount = 0;
|
|
251380
251382
|
normalLaunchTimer;
|
|
251381
251383
|
rateLimitLaunchTimer;
|
|
251384
|
+
transientRetryTimers = /* @__PURE__ */ new Set();
|
|
251382
251385
|
resolve;
|
|
251383
251386
|
reject;
|
|
251384
251387
|
finished = false;
|
|
@@ -251398,6 +251401,7 @@ var init_subagent_batch = __esmMin((() => {
|
|
|
251398
251401
|
index,
|
|
251399
251402
|
task,
|
|
251400
251403
|
retryCount: 0,
|
|
251404
|
+
transientRetryCount: 0,
|
|
251401
251405
|
retryReadyAt: 0,
|
|
251402
251406
|
started: false
|
|
251403
251407
|
}));
|
|
@@ -251540,6 +251544,11 @@ var init_subagent_batch = __esmMin((() => {
|
|
|
251540
251544
|
agentId: handle.agentId,
|
|
251541
251545
|
error: this.attemptErrorMessage(attempt, error, "failed")
|
|
251542
251546
|
};
|
|
251547
|
+
if (isRetryableSubagentFailure(error)) return {
|
|
251548
|
+
type: "transient_provider",
|
|
251549
|
+
agentId: handle.agentId,
|
|
251550
|
+
error: this.attemptErrorMessage(attempt, error, "failed")
|
|
251551
|
+
};
|
|
251543
251552
|
return this.failedAttemptOutcome(attempt, error);
|
|
251544
251553
|
}
|
|
251545
251554
|
}
|
|
@@ -251571,6 +251580,14 @@ var init_subagent_batch = __esmMin((() => {
|
|
|
251571
251580
|
this.requeueTimedOut(attempt, outcome.agentId);
|
|
251572
251581
|
}
|
|
251573
251582
|
else if ("status" in outcome) this.results[attempt.state.index] = outcome;
|
|
251583
|
+
else if (outcome.type === "transient_provider" && shouldStopTransientSubagentContinuation(attempt.state.transientRetryCount)) this.results[attempt.state.index] = {
|
|
251584
|
+
task: attempt.state.task,
|
|
251585
|
+
agentId: outcome.agentId,
|
|
251586
|
+
status: "failed",
|
|
251587
|
+
state: "started",
|
|
251588
|
+
error: `${outcome.error} Automatic continuation stopped after ${String(MAX_TRANSIENT_SUBAGENT_CONTINUATIONS)} attempts; agent ${outcome.agentId} remains resumable.`
|
|
251589
|
+
};
|
|
251590
|
+
else if (outcome.type === "transient_provider") this.requeueTransientProvider(attempt, outcome.agentId);
|
|
251574
251591
|
else if (shouldStopAutomaticRateLimitResume(attempt.state.retryCount)) this.results[attempt.state.index] = {
|
|
251575
251592
|
task: attempt.state.task,
|
|
251576
251593
|
agentId: outcome.agentId,
|
|
@@ -251604,6 +251621,26 @@ var init_subagent_batch = __esmMin((() => {
|
|
|
251604
251621
|
attempt.cleanup();
|
|
251605
251622
|
return true;
|
|
251606
251623
|
}
|
|
251624
|
+
requeueTransientProvider(attempt, agentId) {
|
|
251625
|
+
const state = attempt.state;
|
|
251626
|
+
state.agentId = agentId;
|
|
251627
|
+
state.retryAgentId = agentId;
|
|
251628
|
+
state.transientRetryCount += 1;
|
|
251629
|
+
this.launcher.suspended?.({
|
|
251630
|
+
task: state.task,
|
|
251631
|
+
agentId,
|
|
251632
|
+
reason: TRANSIENT_PROVIDER_SUSPENDED_REASON
|
|
251633
|
+
});
|
|
251634
|
+
const retryDelay = transientSubagentRetryDelayMs(state.transientRetryCount);
|
|
251635
|
+
const timer = setTimeout(() => {
|
|
251636
|
+
this.transientRetryTimers.delete(timer);
|
|
251637
|
+
if (this.finished || this.controller.signal.aborted) return;
|
|
251638
|
+
state.retryReadyAt = 0;
|
|
251639
|
+
this.pending.unshift(state);
|
|
251640
|
+
this.schedule();
|
|
251641
|
+
}, retryDelay);
|
|
251642
|
+
this.transientRetryTimers.add(timer);
|
|
251643
|
+
}
|
|
251607
251644
|
requeueRateLimited(attempt, agentId) {
|
|
251608
251645
|
const state = attempt.state;
|
|
251609
251646
|
state.agentId = agentId;
|
|
@@ -251714,6 +251751,8 @@ var init_subagent_batch = __esmMin((() => {
|
|
|
251714
251751
|
this.batchSignal?.removeEventListener("abort", this.batchAbortListener);
|
|
251715
251752
|
this.clearNormalTimer();
|
|
251716
251753
|
this.clearRateLimitTimer();
|
|
251754
|
+
for (const timer of this.transientRetryTimers) clearTimeout(timer);
|
|
251755
|
+
this.transientRetryTimers.clear();
|
|
251717
251756
|
for (const attempt of this.active.values()) attempt.cleanup();
|
|
251718
251757
|
this.active.clear();
|
|
251719
251758
|
}
|