open-multi-agent-kit 0.92.0 → 0.93.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 +15 -0
- package/README.md +2 -2
- package/dist/core/agent-session.d.ts +29 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +81 -14
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +5 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +5 -7
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +12 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +28 -15
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/extensions/builtin/command-safety-gate.d.ts +8 -0
- package/dist/core/extensions/builtin/command-safety-gate.d.ts.map +1 -1
- package/dist/core/extensions/builtin/command-safety-gate.js +23 -0
- package/dist/core/extensions/builtin/command-safety-gate.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +4 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +2 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybindings.d.ts +5 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +5 -0
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-resolver.d.ts +41 -3
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +17 -9
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/provider-resilience.d.ts.map +1 -1
- package/dist/core/provider-resilience.js +3 -1
- package/dist/core/provider-resilience.js.map +1 -1
- package/dist/core/reasoning-router-v4-weights.d.ts.map +1 -1
- package/dist/core/reasoning-router-v4-weights.js +9 -3
- package/dist/core/reasoning-router-v4-weights.js.map +1 -1
- package/dist/core/reasoning-router-v4.d.ts.map +1 -1
- package/dist/core/reasoning-router-v4.js +94 -24
- package/dist/core/reasoning-router-v4.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +11 -5
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/session-file-compaction.d.ts.map +1 -1
- package/dist/core/session-file-compaction.js +39 -5
- package/dist/core/session-file-compaction.js.map +1 -1
- package/dist/core/session-termination.d.ts.map +1 -1
- package/dist/core/session-termination.js +1 -1
- package/dist/core/session-termination.js.map +1 -1
- package/dist/core/settings-manager.d.ts +3 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +8 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +2 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +38 -11
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/modes/interactive/components/control-panel-box.d.ts +27 -0
- package/dist/modes/interactive/components/control-panel-box.d.ts.map +1 -1
- package/dist/modes/interactive/components/control-panel-box.js +60 -8
- package/dist/modes/interactive/components/control-panel-box.js.map +1 -1
- package/dist/modes/interactive/components/control-panel-layout.d.ts.map +1 -1
- package/dist/modes/interactive/components/control-panel-layout.js +100 -45
- package/dist/modes/interactive/components/control-panel-layout.js.map +1 -1
- package/dist/modes/interactive/components/control-panel-runtime-status.d.ts +9 -0
- package/dist/modes/interactive/components/control-panel-runtime-status.d.ts.map +1 -1
- package/dist/modes/interactive/components/control-panel-runtime-status.js +10 -8
- package/dist/modes/interactive/components/control-panel-runtime-status.js.map +1 -1
- package/dist/modes/interactive/components/control-panel-sparkles.d.ts +5 -0
- package/dist/modes/interactive/components/control-panel-sparkles.d.ts.map +1 -1
- package/dist/modes/interactive/components/control-panel-sparkles.js +14 -9
- package/dist/modes/interactive/components/control-panel-sparkles.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +10 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +3 -3
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/status-sidebar.d.ts +49 -0
- package/dist/modes/interactive/components/status-sidebar.d.ts.map +1 -0
- package/dist/modes/interactive/components/status-sidebar.js +253 -0
- package/dist/modes/interactive/components/status-sidebar.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +9 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +94 -20
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/omk-neon-control.json +13 -13
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +1 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +19 -8
- package/dist/utils/clipboard.js.map +1 -1
- package/docs/compaction.md +7 -0
- package/docs/docs.json +4 -0
- package/docs/environment-variables.md +90 -0
- package/docs/index.md +1 -0
- package/docs/rpc.md +5 -2
- package/docs/settings.md +1 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/subagent/agents.test.ts +86 -0
- package/examples/extensions/subagent/agents.ts +18 -4
- package/examples/extensions/subagent/capabilities.ts +15 -1
- package/examples/extensions/subagent/domain-profiles.ts +272 -0
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +15 -15
- package/package.json +10 -7
|
@@ -286,6 +286,9 @@ export class AgentSession {
|
|
|
286
286
|
// Retry state
|
|
287
287
|
_retryAbortController = undefined;
|
|
288
288
|
_retryAttempt = 0;
|
|
289
|
+
// v10.3-Ω: models that already refused/failed this turn — failover must advance,
|
|
290
|
+
// not re-pick the same candidate (claude-opus-5 → grok → grok → grok loop fix).
|
|
291
|
+
_refusedModels = new Set();
|
|
289
292
|
// Bash execution state
|
|
290
293
|
_bashAbortController = undefined;
|
|
291
294
|
_pendingBashMessages = [];
|
|
@@ -927,6 +930,7 @@ export class AgentSession {
|
|
|
927
930
|
attempt: this._retryAttempt,
|
|
928
931
|
});
|
|
929
932
|
this._retryAttempt = 0;
|
|
933
|
+
this._refusedModels.clear();
|
|
930
934
|
}
|
|
931
935
|
}
|
|
932
936
|
}
|
|
@@ -1463,6 +1467,7 @@ export class AgentSession {
|
|
|
1463
1467
|
finalError: msg.errorMessage,
|
|
1464
1468
|
});
|
|
1465
1469
|
this._retryAttempt = 0;
|
|
1470
|
+
this._refusedModels.clear();
|
|
1466
1471
|
}
|
|
1467
1472
|
if (await this._checkCompaction(msg)) {
|
|
1468
1473
|
return true;
|
|
@@ -2743,7 +2748,7 @@ export class AgentSession {
|
|
|
2743
2748
|
}
|
|
2744
2749
|
else {
|
|
2745
2750
|
// Generate compaction result
|
|
2746
|
-
const result = await compact(preparation, compactionModel, apiKey, headers, customInstructions, this._compactionAbortController.signal, this.thinkingLevel, this.agent.streamFn);
|
|
2751
|
+
const result = await compact(preparation, compactionModel, apiKey, headers, customInstructions, this._compactionAbortController.signal, this.thinkingLevel, this.agent.streamFn, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason: "manual" }));
|
|
2747
2752
|
summary = result.summary;
|
|
2748
2753
|
firstKeptEntryId = result.firstKeptEntryId;
|
|
2749
2754
|
tokensBefore = result.tokensBefore;
|
|
@@ -3019,7 +3024,7 @@ export class AgentSession {
|
|
|
3019
3024
|
}
|
|
3020
3025
|
else {
|
|
3021
3026
|
// Generate compaction result
|
|
3022
|
-
const compactResult = await compact(preparation, compactionModel, apiKey, headers, undefined, this._autoCompactionAbortController.signal, this.thinkingLevel, this.agent.streamFn);
|
|
3027
|
+
const compactResult = await compact(preparation, compactionModel, apiKey, headers, undefined, this._autoCompactionAbortController.signal, this.thinkingLevel, this.agent.streamFn, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason }));
|
|
3023
3028
|
summary = compactResult.summary;
|
|
3024
3029
|
firstKeptEntryId = compactResult.firstKeptEntryId;
|
|
3025
3030
|
tokensBefore = compactResult.tokensBefore;
|
|
@@ -3050,7 +3055,21 @@ export class AgentSession {
|
|
|
3050
3055
|
fromExtension,
|
|
3051
3056
|
});
|
|
3052
3057
|
}
|
|
3053
|
-
|
|
3058
|
+
// Whether the agent loop will resume after this compaction. Shared by
|
|
3059
|
+
// the compaction_end event (so the TUI flushes its queued messages
|
|
3060
|
+
// correctly) and the return value below.
|
|
3061
|
+
const resumeMessages = this.agent.state.messages;
|
|
3062
|
+
let lastAssistantMsg;
|
|
3063
|
+
for (let i = resumeMessages.length - 1; i >= 0; i--) {
|
|
3064
|
+
const candidate = resumeMessages[i];
|
|
3065
|
+
if (candidate.role === "assistant") {
|
|
3066
|
+
lastAssistantMsg = candidate;
|
|
3067
|
+
break;
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
const endedCleanly = lastAssistantMsg?.stopReason === "stop";
|
|
3071
|
+
const willResume = this.agent.hasQueuedMessages() || !endedCleanly;
|
|
3072
|
+
const emitWillRetry = compactionEmitWillRetry(willRetry, willResume);
|
|
3054
3073
|
this._emit({ type: "compaction_end", reason, result, aborted: false, willRetry: emitWillRetry });
|
|
3055
3074
|
if (willRetry) {
|
|
3056
3075
|
const messages = this.agent.state.messages;
|
|
@@ -3060,9 +3079,16 @@ export class AgentSession {
|
|
|
3060
3079
|
}
|
|
3061
3080
|
return true;
|
|
3062
3081
|
}
|
|
3063
|
-
//
|
|
3064
|
-
//
|
|
3065
|
-
|
|
3082
|
+
// Resume the agent loop after a successful auto-compaction unless the
|
|
3083
|
+
// agent had already finished cleanly. Previously this returned
|
|
3084
|
+
// `hasQueuedMessages()`, which made the agent stall right after the
|
|
3085
|
+
// purple "Auto-compacting..." indicator whenever no steer/follow-up
|
|
3086
|
+
// messages were queued — even when the last turn was cut off mid-task
|
|
3087
|
+
// (stopReason toolUse/length/error/aborted). Continue in that case so
|
|
3088
|
+
// the task runs to completion on the compacted context. Hysteresis
|
|
3089
|
+
// (disarmed until context drops below rearmRatio) prevents an immediate
|
|
3090
|
+
// re-trigger; a clean "stop" with nothing queued still ends the loop.
|
|
3091
|
+
return willResume;
|
|
3066
3092
|
}
|
|
3067
3093
|
catch (error) {
|
|
3068
3094
|
const errorMessage = error instanceof Error ? error.message : "compaction failed";
|
|
@@ -3476,6 +3502,34 @@ export class AgentSession {
|
|
|
3476
3502
|
// Shared contract with provider-resilience.ts (Fable safety stop, K3 orphan tool_call_id, terminated).
|
|
3477
3503
|
return isTransientProviderErrorMessage(err);
|
|
3478
3504
|
}
|
|
3505
|
+
/**
|
|
3506
|
+
* Retry policy + callbacks shared by compaction and branch-summary summarization calls.
|
|
3507
|
+
* Uses the same `settings.retry` budget/backoff as agent-turn retries so a single transient
|
|
3508
|
+
* stream drop no longer fails the whole operation. `source` carries the context
|
|
3509
|
+
* the TUI needs to render the retry and recreate the underlying indicator.
|
|
3510
|
+
*/
|
|
3511
|
+
_summarizationRetryCallbacks(source) {
|
|
3512
|
+
return {
|
|
3513
|
+
onRetryScheduled: (attempt, maxAttempts, delayMs, errorMessage) => {
|
|
3514
|
+
this._emit({
|
|
3515
|
+
type: "summarization_retry_scheduled",
|
|
3516
|
+
attempt,
|
|
3517
|
+
maxAttempts,
|
|
3518
|
+
delayMs,
|
|
3519
|
+
errorMessage,
|
|
3520
|
+
});
|
|
3521
|
+
},
|
|
3522
|
+
onRetryAttemptStart: () => {
|
|
3523
|
+
this._emit({
|
|
3524
|
+
type: "summarization_retry_attempt_start",
|
|
3525
|
+
...source,
|
|
3526
|
+
});
|
|
3527
|
+
},
|
|
3528
|
+
onRetryFinished: () => {
|
|
3529
|
+
this._emit({ type: "summarization_retry_finished" });
|
|
3530
|
+
},
|
|
3531
|
+
};
|
|
3532
|
+
}
|
|
3479
3533
|
/**
|
|
3480
3534
|
* Prepare a retryable error for continuation with exponential backoff.
|
|
3481
3535
|
* @returns true if the caller should continue the agent, false otherwise
|
|
@@ -3504,8 +3558,9 @@ export class AgentSession {
|
|
|
3504
3558
|
await this.setModel(next);
|
|
3505
3559
|
}
|
|
3506
3560
|
/**
|
|
3507
|
-
*
|
|
3508
|
-
* Retrying the same model
|
|
3561
|
+
* Content/safety stops (stop_reason=refusal) are often false positives on coding turns
|
|
3562
|
+
* for Fable AND Claude Opus/Sonnet. Retrying the same model usually reprints the refusal —
|
|
3563
|
+
* switch via provider-resilience chain first. Failover targets still skip sticky models.
|
|
3509
3564
|
*/
|
|
3510
3565
|
async _maybeFailoverFromSafetyStop(message) {
|
|
3511
3566
|
const resilience = resolveProviderResilience(this.settingsManager.getProviderResilienceSettings());
|
|
@@ -3514,11 +3569,15 @@ export class AgentSession {
|
|
|
3514
3569
|
if (!isContentSafetyStopMessage(message.errorMessage))
|
|
3515
3570
|
return undefined;
|
|
3516
3571
|
const current = this.model;
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3572
|
+
// v10.0-Ω: do NOT gate on isStickySafetyModel(source).
|
|
3573
|
+
// claude-opus-5 emits the same stop_reason=refusal FP; same-model retry is useless.
|
|
3574
|
+
// v10.3-Ω: mark the model that just refused so we never re-pick it this turn.
|
|
3575
|
+
if (current)
|
|
3576
|
+
this._refusedModels.add(`${current.provider}/${current.id}`);
|
|
3521
3577
|
const pick = pickFailoverCandidate(resilience.failoverCandidates, current ? { provider: current.provider, id: current.id } : undefined, (c) => {
|
|
3578
|
+
// Skip any model that already refused/failed this turn → advance the chain.
|
|
3579
|
+
if (this._refusedModels.has(`${c.provider}/${c.id}`))
|
|
3580
|
+
return false;
|
|
3522
3581
|
const next = this._modelRegistry.find(c.provider, c.id);
|
|
3523
3582
|
return !!next && this._modelRegistry.hasConfiguredAuth(next);
|
|
3524
3583
|
});
|
|
@@ -3532,6 +3591,8 @@ export class AgentSession {
|
|
|
3532
3591
|
return `${next.provider}/${next.id}`;
|
|
3533
3592
|
}
|
|
3534
3593
|
catch {
|
|
3594
|
+
// setModel failed (auth/guard) — blacklist so next retry advances further.
|
|
3595
|
+
this._refusedModels.add(`${pick.provider}/${pick.id}`);
|
|
3535
3596
|
return undefined;
|
|
3536
3597
|
}
|
|
3537
3598
|
}
|
|
@@ -3546,7 +3607,7 @@ export class AgentSession {
|
|
|
3546
3607
|
this._retryAttempt--;
|
|
3547
3608
|
return false;
|
|
3548
3609
|
}
|
|
3549
|
-
// Content/safety stop
|
|
3610
|
+
// Content/safety stop (Fable/Opus/Sonnet): switch model BEFORE delay so retry is not same-model refusal.
|
|
3550
3611
|
const failoverTo = await this._maybeFailoverFromSafetyStop(message);
|
|
3551
3612
|
// Safety stops are usually immediate false positives — short delay after failover, full backoff otherwise.
|
|
3552
3613
|
const delayMs = failoverTo
|
|
@@ -3576,6 +3637,7 @@ export class AgentSession {
|
|
|
3576
3637
|
// Aborted during sleep - emit end event so UI can clean up
|
|
3577
3638
|
const attempt = this._retryAttempt;
|
|
3578
3639
|
this._retryAttempt = 0;
|
|
3640
|
+
this._refusedModels.clear();
|
|
3579
3641
|
this._emit({
|
|
3580
3642
|
type: "auto_retry_end",
|
|
3581
3643
|
success: false,
|
|
@@ -3662,7 +3724,10 @@ export class AgentSession {
|
|
|
3662
3724
|
shellPath,
|
|
3663
3725
|
sandboxPolicy: this._getBashSandboxPreflight(options?.sandboxPolicy),
|
|
3664
3726
|
}), {
|
|
3665
|
-
onChunk
|
|
3727
|
+
onChunk: (delta) => {
|
|
3728
|
+
onChunk?.(delta);
|
|
3729
|
+
this._emit({ type: "bash_execution_update", id: options?.id, delta });
|
|
3730
|
+
},
|
|
3666
3731
|
signal: this._bashAbortController.signal,
|
|
3667
3732
|
});
|
|
3668
3733
|
this.recordBashResult(command, result, options);
|
|
@@ -3838,6 +3903,8 @@ export class AgentSession {
|
|
|
3838
3903
|
replaceInstructions,
|
|
3839
3904
|
reserveTokens: branchSummarySettings.reserveTokens,
|
|
3840
3905
|
streamFn: this.agent.streamFn,
|
|
3906
|
+
retry: this.settingsManager.getRetrySettings(),
|
|
3907
|
+
callbacks: this._summarizationRetryCallbacks({ source: "branchSummary" }),
|
|
3841
3908
|
});
|
|
3842
3909
|
if (result.aborted) {
|
|
3843
3910
|
return { cancelled: true, aborted: true };
|