open-multi-agent-kit 0.95.2 → 0.96.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 +20 -0
- package/README.md +15 -0
- package/dist/approvals/approval-receipt-store.d.ts.map +1 -1
- package/dist/approvals/approval-receipt-store.js +25 -0
- package/dist/approvals/approval-receipt-store.js.map +1 -1
- package/dist/core/agent-session.d.ts +2 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +41 -17
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/provider-resilience.d.ts +7 -0
- package/dist/core/provider-resilience.d.ts.map +1 -1
- package/dist/core/provider-resilience.js +11 -0
- package/dist/core/provider-resilience.js.map +1 -1
- package/dist/core/subagent-orchestration.d.ts.map +1 -1
- package/dist/core/subagent-orchestration.js +4 -2
- package/dist/core/subagent-orchestration.js.map +1 -1
- package/dist/core/tools/diagnostics.d.ts.map +1 -1
- package/dist/core/tools/diagnostics.js +8 -2
- package/dist/core/tools/diagnostics.js.map +1 -1
- package/dist/guardrails/evidence-protocol.d.ts +10 -0
- package/dist/guardrails/evidence-protocol.d.ts.map +1 -0
- package/dist/guardrails/evidence-protocol.js +34 -0
- package/dist/guardrails/evidence-protocol.js.map +1 -0
- package/dist/guardrails/evidence-system.d.ts +3 -1
- package/dist/guardrails/evidence-system.d.ts.map +1 -1
- package/dist/guardrails/evidence-system.js +22 -14
- package/dist/guardrails/evidence-system.js.map +1 -1
- package/dist/guardrails/replay-ledger-lock-owner.d.ts.map +1 -1
- package/dist/guardrails/replay-ledger-lock-owner.js +3 -1
- package/dist/guardrails/replay-ledger-lock-owner.js.map +1 -1
- package/dist/guardrails/replay-payload-hash.d.ts +6 -0
- package/dist/guardrails/replay-payload-hash.d.ts.map +1 -0
- package/dist/guardrails/replay-payload-hash.js +24 -0
- package/dist/guardrails/replay-payload-hash.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/types/evidence.d.ts +11 -3
- package/dist/types/evidence.d.ts.map +1 -1
- package/dist/types/evidence.js.map +1 -1
- package/docs/book-to-skill.md +79 -0
- package/docs/compaction.md +10 -0
- package/docs/docs.json +8 -0
- package/docs/index.md +3 -0
- package/docs/models.md +12 -0
- package/docs/provider-resilience.md +37 -56
- package/docs/providers.md +4 -0
- package/docs/run-protocol.md +72 -0
- package/docs/sdk.md +15 -2
- package/docs/sessions.md +6 -0
- package/docs/settings.md +2 -0
- package/docs/skills.md +9 -1
- package/docs/usage.md +1 -1
- 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/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +37 -15
- package/package.json +8 -5
- package/dist/core/context-budget-compressors.d.ts +0 -50
- package/dist/core/context-budget-compressors.d.ts.map +0 -1
- package/dist/core/context-budget-compressors.js +0 -166
- package/dist/core/context-budget-compressors.js.map +0 -1
- package/dist/core/extensions/loader.js.bak-sharedjiti-20260812-111246 +0 -553
|
@@ -50,6 +50,8 @@ import { buildRuntimeProvenance } from "./runtime-provenance.js";
|
|
|
50
50
|
import { TurnMetricsSink } from "./turn-metrics.js";
|
|
51
51
|
/** Values that disable a session-level feature through its environment variable. */
|
|
52
52
|
const DISABLED_ENV_VALUES = new Set(["0", "false", "off", "disable", "disabled"]);
|
|
53
|
+
const MAX_OVERFLOW_RECOVERY_ATTEMPTS = 2;
|
|
54
|
+
const OVERFLOW_RECOVERY_EMERGENCY_TOKENS = 4_096;
|
|
53
55
|
function isDisabledEnvValue(value) {
|
|
54
56
|
return value !== undefined && DISABLED_ENV_VALUES.has(value.trim().toLowerCase());
|
|
55
57
|
}
|
|
@@ -70,7 +72,7 @@ function firstTextContent(result) {
|
|
|
70
72
|
import { redactCredentialShapedContent } from "./compaction/transaction.js";
|
|
71
73
|
import { findExactModelReferenceMatch } from "./model-resolver.js";
|
|
72
74
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
73
|
-
import { isContentSafetyStopMessage, isStickySafetyModel, isTransientProviderErrorMessage, pickFailoverCandidate, resolveProviderResilience, stickySafetyBlockMessage, } from "./provider-resilience.js";
|
|
75
|
+
import { isContentSafetyStopMessage, isQuotaExhaustionMessage, isStickySafetyModel, isTransientProviderErrorMessage, pickFailoverCandidate, resolveProviderResilience, stickySafetyBlockMessage, } from "./provider-resilience.js";
|
|
74
76
|
import { getBiasStepsForCell, parseRouterBiasSnapshot } from "./reasoning-router-bias.js";
|
|
75
77
|
import { classifyTaskV4, deriveRouterFeedbackFeaturesV4, resolveThinkingLevelV4WithUncertainty, TASK_CLASS_THINKING_LEVELS_V4, } from "./reasoning-router-v4.js";
|
|
76
78
|
import { redactSensitiveText, redactSensitiveTextForced } from "./redaction.js";
|
|
@@ -302,7 +304,7 @@ export class AgentSession {
|
|
|
302
304
|
// Compaction state
|
|
303
305
|
_compactionAbortController = undefined;
|
|
304
306
|
_autoCompactionAbortController = undefined;
|
|
305
|
-
|
|
307
|
+
_overflowRecoveryAttempts = 0;
|
|
306
308
|
_thresholdCompactionEmergency = false;
|
|
307
309
|
_compactionHysteresisState = createCompactionHysteresisState();
|
|
308
310
|
// Branch summarization state
|
|
@@ -585,12 +587,15 @@ export class AgentSession {
|
|
|
585
587
|
if (/stop_reason\s*=\s*(refusal|sensitive)|content\/safety stop|safety stop|provider\.refusal|kind=provider_refusal/i.test(text)) {
|
|
586
588
|
return { area: "provider", code: "refusal" };
|
|
587
589
|
}
|
|
590
|
+
// Quota/billing exhaustion is checked BEFORE the generic 401/403 auth
|
|
591
|
+
// patterns: "403 ... usage limit for this billing cycle" is transient per
|
|
592
|
+
// cycle and must fail over, not terminate the turn as an auth error.
|
|
593
|
+
if (isQuotaExhaustionMessage(text) || /rate.?limit|too many requests|429/i.test(text)) {
|
|
594
|
+
return { area: "provider", code: "rate_limit" };
|
|
595
|
+
}
|
|
588
596
|
if (/auth|unauthori[sz]ed|forbidden|invalid.?api.?key|no api key|401|403|\/login/i.test(text)) {
|
|
589
597
|
return { area: "provider", code: "auth" };
|
|
590
598
|
}
|
|
591
|
-
if (/rate.?limit|too many requests|429|quota|available balance|billing/i.test(text)) {
|
|
592
|
-
return { area: "provider", code: "rate_limit" };
|
|
593
|
-
}
|
|
594
599
|
// Kimi/K3 + OpenAI-compat: orphan tool results after dropped error assistants.
|
|
595
600
|
// Sanitize-and-retry (transform-messages drops orphans), not a hard tool fatal.
|
|
596
601
|
if (/tool_call_id\s+is\s+not\s+found|tool_call_id\s+not\s+found|unknown\s+tool_call_id/i.test(text)) {
|
|
@@ -609,6 +614,9 @@ export class AgentSession {
|
|
|
609
614
|
if (!this.model || /no model|model selected|model is required/i.test(message)) {
|
|
610
615
|
return { area: "configuration", code: "invalid" };
|
|
611
616
|
}
|
|
617
|
+
if (isQuotaExhaustionMessage(message)) {
|
|
618
|
+
return { area: "provider", code: "rate_limit" };
|
|
619
|
+
}
|
|
612
620
|
if (/auth|api key|unauthori[sz]ed|forbidden|401|403|\/login/i.test(message)) {
|
|
613
621
|
return { area: "provider", code: "auth" };
|
|
614
622
|
}
|
|
@@ -966,7 +974,7 @@ export class AgentSession {
|
|
|
966
974
|
// When a user message starts, check if it's from either queue and remove it BEFORE emitting
|
|
967
975
|
// This ensures the UI sees the updated queue state
|
|
968
976
|
if (event.type === "message_start" && event.message.role === "user") {
|
|
969
|
-
this.
|
|
977
|
+
this._overflowRecoveryAttempts = 0;
|
|
970
978
|
const messageText = this._getUserMessageText(event.message);
|
|
971
979
|
if (messageText) {
|
|
972
980
|
// Check steering queue first
|
|
@@ -1017,7 +1025,7 @@ export class AgentSession {
|
|
|
1017
1025
|
this._lastAssistantMessage = finalizedEvent.message;
|
|
1018
1026
|
const assistantMsg = finalizedEvent.message;
|
|
1019
1027
|
if (assistantMsg.stopReason !== "error") {
|
|
1020
|
-
this.
|
|
1028
|
+
this._overflowRecoveryAttempts = 0;
|
|
1021
1029
|
}
|
|
1022
1030
|
// Reset retry counter immediately on successful assistant response
|
|
1023
1031
|
// This prevents accumulation across multiple LLM calls within a turn
|
|
@@ -2977,18 +2985,18 @@ export class AgentSession {
|
|
|
2977
2985
|
}
|
|
2978
2986
|
// Case 1: Overflow - LLM returned context overflow error
|
|
2979
2987
|
if ((sameModel || visionRouteOverflow) && isContextOverflow(assistantMessage, contextWindow)) {
|
|
2980
|
-
if (this.
|
|
2988
|
+
if (this._overflowRecoveryAttempts >= MAX_OVERFLOW_RECOVERY_ATTEMPTS) {
|
|
2981
2989
|
this._emit({
|
|
2982
2990
|
type: "compaction_end",
|
|
2983
2991
|
reason: "overflow",
|
|
2984
2992
|
result: undefined,
|
|
2985
2993
|
aborted: false,
|
|
2986
2994
|
willRetry: false,
|
|
2987
|
-
errorMessage: "Context overflow recovery failed after
|
|
2995
|
+
errorMessage: "Context overflow recovery failed after two staged compact-and-retry attempts. Reduce the latest input or switch to a model with a larger effective context window.",
|
|
2988
2996
|
});
|
|
2989
2997
|
return false;
|
|
2990
2998
|
}
|
|
2991
|
-
this.
|
|
2999
|
+
this._overflowRecoveryAttempts++;
|
|
2992
3000
|
// Remove the error message from agent state (it IS saved to session for history,
|
|
2993
3001
|
// but we don't want it in context for the retry)
|
|
2994
3002
|
const messages = this.agent.state.messages;
|
|
@@ -3026,11 +3034,24 @@ export class AgentSession {
|
|
|
3026
3034
|
}
|
|
3027
3035
|
return false;
|
|
3028
3036
|
}
|
|
3037
|
+
_overflowCompactionSettings(settings, attempt) {
|
|
3038
|
+
if (attempt < MAX_OVERFLOW_RECOVERY_ATTEMPTS)
|
|
3039
|
+
return settings;
|
|
3040
|
+
return {
|
|
3041
|
+
...settings,
|
|
3042
|
+
reserveTokens: Math.min(settings.reserveTokens, OVERFLOW_RECOVERY_EMERGENCY_TOKENS),
|
|
3043
|
+
reservedOutputTokens: Math.min(settings.reservedOutputTokens ?? settings.reserveTokens, OVERFLOW_RECOVERY_EMERGENCY_TOKENS),
|
|
3044
|
+
keepRecentTokens: Math.min(settings.keepRecentTokens, OVERFLOW_RECOVERY_EMERGENCY_TOKENS),
|
|
3045
|
+
};
|
|
3046
|
+
}
|
|
3029
3047
|
/**
|
|
3030
3048
|
* Internal: Run auto-compaction with events.
|
|
3031
3049
|
*/
|
|
3032
3050
|
async _runAutoCompaction(reason, willRetry, emergency = reason === "overflow" || this._thresholdCompactionEmergency) {
|
|
3033
|
-
const
|
|
3051
|
+
const configuredSettings = this.settingsManager.getCompactionSettings();
|
|
3052
|
+
const settings = reason === "overflow"
|
|
3053
|
+
? this._overflowCompactionSettings(configuredSettings, this._overflowRecoveryAttempts)
|
|
3054
|
+
: configuredSettings;
|
|
3034
3055
|
this._emit({ type: "compaction_start", reason });
|
|
3035
3056
|
this._autoCompactionAbortController = new AbortController();
|
|
3036
3057
|
try {
|
|
@@ -3666,9 +3687,6 @@ export class AgentSession {
|
|
|
3666
3687
|
// =========================================================================
|
|
3667
3688
|
// Auto-Retry
|
|
3668
3689
|
// =========================================================================
|
|
3669
|
-
_isNonRetryableProviderLimitError(errorMessage) {
|
|
3670
|
-
return /GoUsageLimitError|FreeUsageLimitError|Monthly usage limit reached|available balance|insufficient_quota|out of budget|quota exceeded|billing/i.test(errorMessage);
|
|
3671
|
-
}
|
|
3672
3690
|
/**
|
|
3673
3691
|
* Check if an error is retryable (overloaded, rate limit, server errors).
|
|
3674
3692
|
* Context overflow errors are NOT retryable (handled by compaction instead).
|
|
@@ -3681,8 +3699,11 @@ export class AgentSession {
|
|
|
3681
3699
|
if (isContextOverflow(message, contextWindow))
|
|
3682
3700
|
return false;
|
|
3683
3701
|
const err = message.errorMessage;
|
|
3684
|
-
|
|
3685
|
-
|
|
3702
|
+
// Billing/quota exhaustion: useless to retry the same model until the
|
|
3703
|
+
// cycle resets, but the turn may still be saved by failing over to the
|
|
3704
|
+
// next candidate, so let _prepareRetry run its failover path.
|
|
3705
|
+
if (isQuotaExhaustionMessage(err))
|
|
3706
|
+
return true;
|
|
3686
3707
|
// Shared contract with provider-resilience.ts (Fable safety stop, K3 orphan tool_call_id, terminated).
|
|
3687
3708
|
return isTransientProviderErrorMessage(err);
|
|
3688
3709
|
}
|
|
@@ -3752,8 +3773,11 @@ export class AgentSession {
|
|
|
3752
3773
|
const resilience = resolveProviderResilience(this.settingsManager.getProviderResilienceSettings());
|
|
3753
3774
|
if (!resilience.autoFailoverOnSafetyStop)
|
|
3754
3775
|
return undefined;
|
|
3755
|
-
|
|
3776
|
+
// Fire on safety-stop FPs AND on billing/quota exhaustion: both mean the
|
|
3777
|
+
// current model cannot finish this turn and same-model retry is useless.
|
|
3778
|
+
if (!isContentSafetyStopMessage(message.errorMessage) && !isQuotaExhaustionMessage(message.errorMessage)) {
|
|
3756
3779
|
return undefined;
|
|
3780
|
+
}
|
|
3757
3781
|
const current = this.model;
|
|
3758
3782
|
// v10.0-Ω: do NOT gate on isStickySafetyModel(source).
|
|
3759
3783
|
// claude-opus-5 emits the same stop_reason=refusal FP; same-model retry is useless.
|