@aiden-ade/sandbox-agent 0.1.38 → 0.1.39
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/dist/index.cjs +221 -35
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -15717,10 +15717,107 @@ function getCodexPermissionArgs(config) {
|
|
|
15717
15717
|
const sandbox = shouldUseReadOnlyRuntimePermissions(config) ? "read-only" : "danger-full-access";
|
|
15718
15718
|
return ["--ask-for-approval", "never", "--sandbox", sandbox];
|
|
15719
15719
|
}
|
|
15720
|
+
var ERROR_SPECS = {
|
|
15721
|
+
model_mismatch: {
|
|
15722
|
+
message: "The selected model isn't available, or you don't have access to it. Pick a different model, then send your message again.",
|
|
15723
|
+
recoveryClass: "user_fixable"
|
|
15724
|
+
},
|
|
15725
|
+
auth_invalid: {
|
|
15726
|
+
message: "API key invalid or expired. Check your provider settings, then retry.",
|
|
15727
|
+
recoveryClass: "user_fixable"
|
|
15728
|
+
},
|
|
15729
|
+
not_logged_in: {
|
|
15730
|
+
message: "Not logged in to this provider. Sign in from provider settings, then retry.",
|
|
15731
|
+
recoveryClass: "user_fixable"
|
|
15732
|
+
},
|
|
15733
|
+
not_authenticated: {
|
|
15734
|
+
message: "The agent CLI isn't signed in on this runtime. Authenticate it there, then retry.",
|
|
15735
|
+
recoveryClass: "needs_env"
|
|
15736
|
+
},
|
|
15737
|
+
auth_expired: {
|
|
15738
|
+
message: "The provider connection expired. Reconnect it in Cloud settings, then restart or recreate the machine.",
|
|
15739
|
+
recoveryClass: "user_fixable"
|
|
15740
|
+
},
|
|
15741
|
+
subscription_required: {
|
|
15742
|
+
message: "This model requires a paid subscription. Switch to a supported model or upgrade your plan.",
|
|
15743
|
+
recoveryClass: "user_fixable"
|
|
15744
|
+
},
|
|
15745
|
+
quota_exceeded: {
|
|
15746
|
+
message: "API quota exceeded. Wait for it to reset or check your billing, then retry.",
|
|
15747
|
+
recoveryClass: "user_fixable"
|
|
15748
|
+
},
|
|
15749
|
+
usage_limit: {
|
|
15750
|
+
message: "Provider usage limit reached. Switch model or wait for the limit to reset, then retry.",
|
|
15751
|
+
recoveryClass: "user_fixable"
|
|
15752
|
+
},
|
|
15753
|
+
context_length: {
|
|
15754
|
+
message: "Context window exceeded \u2014 the conversation is too long. Start a new session or send a shorter message.",
|
|
15755
|
+
recoveryClass: "user_fixable"
|
|
15756
|
+
},
|
|
15757
|
+
rate_limited: {
|
|
15758
|
+
message: "Rate limited by the provider. Retrying automatically shortly.",
|
|
15759
|
+
recoveryClass: "auto_recovering"
|
|
15760
|
+
},
|
|
15761
|
+
overloaded: {
|
|
15762
|
+
message: "The provider is overloaded. Retrying automatically.",
|
|
15763
|
+
recoveryClass: "auto_recovering"
|
|
15764
|
+
},
|
|
15765
|
+
network: {
|
|
15766
|
+
message: "Network connection failed. Check your internet connection \u2014 retrying automatically.",
|
|
15767
|
+
recoveryClass: "auto_recovering"
|
|
15768
|
+
},
|
|
15769
|
+
provider_timeout: {
|
|
15770
|
+
message: "The provider timed out while continuing the turn. Send your message again; if it repeats, check network/API latency or reduce slow tool calls.",
|
|
15771
|
+
recoveryClass: "retry"
|
|
15772
|
+
},
|
|
15773
|
+
resume_failed: {
|
|
15774
|
+
message: "The previous session could not be resumed \u2014 its stored session was missing or expired. The next message starts a fresh session without earlier context.",
|
|
15775
|
+
recoveryClass: "retry"
|
|
15776
|
+
},
|
|
15777
|
+
permission_denied: {
|
|
15778
|
+
message: "Permission denied. Check file or command permissions on the runtime.",
|
|
15779
|
+
recoveryClass: "needs_env"
|
|
15780
|
+
},
|
|
15781
|
+
out_of_memory: {
|
|
15782
|
+
message: "Out of memory on the runtime. Close other work or use a larger machine, then retry.",
|
|
15783
|
+
recoveryClass: "needs_env"
|
|
15784
|
+
},
|
|
15785
|
+
provider_error: {
|
|
15786
|
+
message: "The provider returned an error. Send your message again to retry.",
|
|
15787
|
+
recoveryClass: "retry"
|
|
15788
|
+
},
|
|
15789
|
+
unknown_cli_error: {
|
|
15790
|
+
message: "The agent stopped unexpectedly. Send your message again to retry.",
|
|
15791
|
+
recoveryClass: "retry"
|
|
15792
|
+
}
|
|
15793
|
+
};
|
|
15794
|
+
function specForErrorKind(errorKind) {
|
|
15795
|
+
const spec = ERROR_SPECS[errorKind];
|
|
15796
|
+
return { message: spec.message, errorKind, recoveryClass: spec.recoveryClass };
|
|
15797
|
+
}
|
|
15720
15798
|
function isLikelyProviderAuthError(stderr) {
|
|
15721
15799
|
const lower = stderr.toLowerCase();
|
|
15722
15800
|
return lower.includes("api key") || lower.includes("api_key") || lower.includes("invalid api key") || lower.includes("api key invalid") || lower.includes("unauthorized") || lower.includes("authentication failed") || lower.includes("authentication error") || lower.includes("provider settings") || lower.includes("invalid token") || lower.includes("token expired");
|
|
15723
15801
|
}
|
|
15802
|
+
function mapProviderApiError(errorCode, apiStatus) {
|
|
15803
|
+
const code = errorCode?.trim().toLowerCase();
|
|
15804
|
+
if (code) {
|
|
15805
|
+
if (code.includes("model_not_found") || code.includes("model_not_available")) {
|
|
15806
|
+
return "model_mismatch";
|
|
15807
|
+
}
|
|
15808
|
+
if (code.includes("authentication") || code.includes("permission_error")) return "auth_invalid";
|
|
15809
|
+
if (code.includes("rate_limit")) return "rate_limited";
|
|
15810
|
+
if (code.includes("overloaded")) return "overloaded";
|
|
15811
|
+
if (code.includes("insufficient_quota") || code.includes("billing")) return "quota_exceeded";
|
|
15812
|
+
}
|
|
15813
|
+
if (typeof apiStatus === "number") {
|
|
15814
|
+
if (apiStatus === 404) return "model_mismatch";
|
|
15815
|
+
if (apiStatus === 401 || apiStatus === 403) return "auth_invalid";
|
|
15816
|
+
if (apiStatus === 429) return "rate_limited";
|
|
15817
|
+
if (apiStatus >= 500) return "overloaded";
|
|
15818
|
+
}
|
|
15819
|
+
return null;
|
|
15820
|
+
}
|
|
15724
15821
|
function normalizeCodexCliErrorMessage(message) {
|
|
15725
15822
|
const lower = message.toLowerCase();
|
|
15726
15823
|
if (lower.includes("reconnecting") && lower.includes("request timed out")) {
|
|
@@ -15731,40 +15828,73 @@ function normalizeCodexCliErrorMessage(message) {
|
|
|
15731
15828
|
}
|
|
15732
15829
|
return message;
|
|
15733
15830
|
}
|
|
15734
|
-
function
|
|
15831
|
+
function classifyCliErrorDetailed(stderr, _exitCode, opts) {
|
|
15735
15832
|
const normalizedCodexError = normalizeCodexCliErrorMessage(stderr);
|
|
15736
|
-
if (normalizedCodexError !== stderr)
|
|
15737
|
-
|
|
15738
|
-
|
|
15739
|
-
|
|
15740
|
-
|
|
15741
|
-
|
|
15742
|
-
|
|
15743
|
-
|
|
15744
|
-
|
|
15745
|
-
|
|
15746
|
-
if (
|
|
15747
|
-
return "
|
|
15748
|
-
if (
|
|
15749
|
-
|
|
15750
|
-
|
|
15751
|
-
|
|
15752
|
-
if (
|
|
15753
|
-
|
|
15754
|
-
|
|
15755
|
-
|
|
15756
|
-
|
|
15757
|
-
|
|
15758
|
-
|
|
15759
|
-
|
|
15760
|
-
|
|
15761
|
-
return "
|
|
15762
|
-
if (
|
|
15763
|
-
|
|
15764
|
-
|
|
15765
|
-
|
|
15833
|
+
if (normalizedCodexError !== stderr) {
|
|
15834
|
+
const kind = /timed out/i.test(normalizedCodexError) ? "provider_timeout" : "auth_expired";
|
|
15835
|
+
return {
|
|
15836
|
+
message: normalizedCodexError,
|
|
15837
|
+
errorKind: kind,
|
|
15838
|
+
recoveryClass: ERROR_SPECS[kind].recoveryClass
|
|
15839
|
+
};
|
|
15840
|
+
}
|
|
15841
|
+
const haystack = [stderr, ...opts?.extraSignals ?? []].join("\n").toLowerCase();
|
|
15842
|
+
const has = (...needles) => needles.some((n) => haystack.includes(n));
|
|
15843
|
+
if (has("authentication required", "not authenticated"))
|
|
15844
|
+
return specForErrorKind("not_authenticated");
|
|
15845
|
+
if (has("out of usage", "increase your limit")) return specForErrorKind("usage_limit");
|
|
15846
|
+
if (has("no chat found", "chat not found", "session not found", "could not resume"))
|
|
15847
|
+
return specForErrorKind("resume_failed");
|
|
15848
|
+
if (has("rate_limit", "rate limit", "429")) return specForErrorKind("rate_limited");
|
|
15849
|
+
if (isLikelyProviderAuthError(haystack)) return specForErrorKind("auth_invalid");
|
|
15850
|
+
if (has(
|
|
15851
|
+
"not logged in",
|
|
15852
|
+
"login required",
|
|
15853
|
+
"please sign in",
|
|
15854
|
+
"please log in",
|
|
15855
|
+
"sign in to",
|
|
15856
|
+
"log in to"
|
|
15857
|
+
))
|
|
15858
|
+
return specForErrorKind("not_logged_in");
|
|
15859
|
+
if (has(
|
|
15860
|
+
"model not supported",
|
|
15861
|
+
"unsupported model",
|
|
15862
|
+
"model not found",
|
|
15863
|
+
"model not available",
|
|
15864
|
+
"model is not available",
|
|
15865
|
+
"invalid model",
|
|
15866
|
+
"unknown model",
|
|
15867
|
+
"no such model",
|
|
15868
|
+
"llm not set",
|
|
15869
|
+
// Claude Code phrasings (safety net; the structured decoder catches these first).
|
|
15870
|
+
"issue with the selected model",
|
|
15871
|
+
"may not exist or you may not have access"
|
|
15872
|
+
))
|
|
15873
|
+
return specForErrorKind("model_mismatch");
|
|
15874
|
+
if (has(
|
|
15875
|
+
"subscription",
|
|
15876
|
+
"paid plan",
|
|
15877
|
+
"plan required",
|
|
15878
|
+
"upgrade your plan",
|
|
15879
|
+
"only supports free",
|
|
15880
|
+
"not available on your",
|
|
15881
|
+
"requires a paid"
|
|
15882
|
+
))
|
|
15883
|
+
return specForErrorKind("subscription_required");
|
|
15884
|
+
if (has("quota exceeded", "quota limit", "daily limit", "monthly limit", "usage limit"))
|
|
15885
|
+
return specForErrorKind("quota_exceeded");
|
|
15886
|
+
if (has("overloaded", "503", "service unavailable")) return specForErrorKind("overloaded");
|
|
15887
|
+
if (has("context_length", "too long", "max tokens", "context window"))
|
|
15888
|
+
return specForErrorKind("context_length");
|
|
15889
|
+
if (has("econnrefused", "network", "enotfound", "timeout", "etimedout"))
|
|
15890
|
+
return specForErrorKind("network");
|
|
15891
|
+
if (has("permission denied", "eacces")) return specForErrorKind("permission_denied");
|
|
15892
|
+
if (has("out of memory", "enomem")) return specForErrorKind("out_of_memory");
|
|
15766
15893
|
const raw = stderr.trim().slice(0, 200);
|
|
15767
|
-
|
|
15894
|
+
if (raw) {
|
|
15895
|
+
return { message: raw, errorKind: "unknown_cli_error", recoveryClass: "unknown" };
|
|
15896
|
+
}
|
|
15897
|
+
return specForErrorKind("unknown_cli_error");
|
|
15768
15898
|
}
|
|
15769
15899
|
function isTransientError(errorMessage) {
|
|
15770
15900
|
const lower = errorMessage.toLowerCase();
|
|
@@ -16204,13 +16334,34 @@ function createGenericCliBackend(options) {
|
|
|
16204
16334
|
};
|
|
16205
16335
|
}
|
|
16206
16336
|
const summary = state.summary.trim() || state.error?.trim() || (failed ? "Task failed" : "Task completed");
|
|
16337
|
+
let classifiedError;
|
|
16338
|
+
let classifiedErrorKind;
|
|
16339
|
+
let classifiedRecoveryClass;
|
|
16340
|
+
if (failed) {
|
|
16341
|
+
if (state.errorKind && state.error?.trim()) {
|
|
16342
|
+
classifiedError = state.error.trim();
|
|
16343
|
+
classifiedErrorKind = state.errorKind;
|
|
16344
|
+
classifiedRecoveryClass = state.recoveryClass;
|
|
16345
|
+
} else {
|
|
16346
|
+
const detailed = classifyCliErrorDetailed(
|
|
16347
|
+
state.error?.trim() || stderrText || "",
|
|
16348
|
+
exitCode,
|
|
16349
|
+
{ extraSignals: state.summary ? [state.summary] : void 0 }
|
|
16350
|
+
);
|
|
16351
|
+
classifiedError = detailed.message;
|
|
16352
|
+
classifiedErrorKind = detailed.errorKind;
|
|
16353
|
+
classifiedRecoveryClass = detailed.recoveryClass;
|
|
16354
|
+
}
|
|
16355
|
+
}
|
|
16207
16356
|
return {
|
|
16208
16357
|
success: !failed,
|
|
16209
16358
|
summary,
|
|
16210
16359
|
filesModified: [],
|
|
16211
16360
|
planFilesCreated: [],
|
|
16212
16361
|
iterations: Math.max(state.iterations, 1),
|
|
16213
|
-
error:
|
|
16362
|
+
error: classifiedError,
|
|
16363
|
+
...classifiedErrorKind ? { errorKind: classifiedErrorKind } : {},
|
|
16364
|
+
...classifiedRecoveryClass ? { recoveryClass: classifiedRecoveryClass } : {},
|
|
16214
16365
|
providerSessionId: state.runtimeSessionId,
|
|
16215
16366
|
runtimeSessionId: state.runtimeSessionId,
|
|
16216
16367
|
backendKind: options.kind,
|
|
@@ -16884,6 +17035,9 @@ function handleClaudeStructuredEvent(parsed, context, state) {
|
|
|
16884
17035
|
if (typeof parsed.session_id === "string") {
|
|
16885
17036
|
state.runtimeSessionId = parsed.session_id;
|
|
16886
17037
|
}
|
|
17038
|
+
if (typeof parsed.error === "string" && parsed.error.trim()) {
|
|
17039
|
+
state.providerErrorCode = parsed.error.trim();
|
|
17040
|
+
}
|
|
16887
17041
|
const parentToolUseId = typeof parsed.parent_tool_use_id === "string" ? parsed.parent_tool_use_id : null;
|
|
16888
17042
|
switch (type) {
|
|
16889
17043
|
case "system": {
|
|
@@ -17096,6 +17250,27 @@ function handleClaudeStructuredEvent(parsed, context, state) {
|
|
|
17096
17250
|
})
|
|
17097
17251
|
);
|
|
17098
17252
|
}
|
|
17253
|
+
const isApiError = parsed.is_error === true || parsed.terminal_reason === "api_error" || typeof parsed.api_error_status === "number";
|
|
17254
|
+
if (isApiError && !state.error) {
|
|
17255
|
+
const apiStatus = typeof parsed.api_error_status === "number" ? parsed.api_error_status : void 0;
|
|
17256
|
+
state.apiErrorStatus = apiStatus;
|
|
17257
|
+
const mappedKind = mapProviderApiError(state.providerErrorCode, apiStatus);
|
|
17258
|
+
const spec = mappedKind ? specForErrorKind(mappedKind) : specForErrorKind("provider_error");
|
|
17259
|
+
state.error = mappedKind || typeof parsed.result !== "string" || !parsed.result.trim() ? spec.message : parsed.result.trim();
|
|
17260
|
+
state.errorKind = spec.errorKind;
|
|
17261
|
+
state.recoveryClass = spec.recoveryClass;
|
|
17262
|
+
console.error(
|
|
17263
|
+
"[claude_cli] result flagged API error:",
|
|
17264
|
+
JSON.stringify({
|
|
17265
|
+
is_error: parsed.is_error,
|
|
17266
|
+
terminal_reason: parsed.terminal_reason,
|
|
17267
|
+
api_error_status: parsed.api_error_status,
|
|
17268
|
+
providerErrorCode: state.providerErrorCode,
|
|
17269
|
+
mappedKind,
|
|
17270
|
+
result: typeof parsed.result === "string" ? parsed.result.slice(0, 200) : void 0
|
|
17271
|
+
})
|
|
17272
|
+
);
|
|
17273
|
+
}
|
|
17099
17274
|
debugAskLog(
|
|
17100
17275
|
`[claude_cli] result event \u2014 pendingAskUserToolIds size=${presenter.pendingAskUserToolIds?.size ?? "undefined"}, hasOwnProp=${Object.hasOwn(presenter, "pendingAskUserToolIds")}`
|
|
17101
17276
|
);
|
|
@@ -21829,6 +22004,10 @@ var ANTIGRAVITY_MODEL_DISCOVERY_TIMEOUT_MS = 12e3;
|
|
|
21829
22004
|
var OPENCODE_ZEN_MODEL_IDS = OPENCODE_ZEN_MODELS.map((model) => model.id);
|
|
21830
22005
|
var CLAUDE_MODEL_ID_PATTERN = /claude-(?:sonnet|opus|haiku|fable)-[a-z0-9][a-z0-9-]*/g;
|
|
21831
22006
|
var CLAUDE_MODEL_ALIASES = ["sonnet", "opus", "haiku", "fable"];
|
|
22007
|
+
var CLAUDE_MODEL_QUALIFIER_SEGMENTS = /* @__PURE__ */ new Set(["fast", "thinking", "latest", "preview"]);
|
|
22008
|
+
var PROTECTED_CATALOG_MODEL_IDS = new Set(
|
|
22009
|
+
AVAILABLE_MODELS.map((model) => model.id).filter((id) => id.length > 0)
|
|
22010
|
+
);
|
|
21832
22011
|
var CATALOG_MODEL_IDS_BY_PROVIDER = Object.fromEntries(
|
|
21833
22012
|
Object.entries(PROVIDER_MODELS).map(([provider, models]) => [
|
|
21834
22013
|
provider,
|
|
@@ -21919,15 +22098,22 @@ function extractModelIdsFromLabeledList(value2) {
|
|
|
21919
22098
|
}
|
|
21920
22099
|
function isValidClaudeModelId(id) {
|
|
21921
22100
|
if (CLAUDE_MODEL_ALIASES.includes(id)) return true;
|
|
21922
|
-
|
|
22101
|
+
const match = id.match(/^claude-(sonnet|opus|haiku|fable)-([a-z0-9][a-z0-9-]*)$/);
|
|
22102
|
+
if (!match) return false;
|
|
21923
22103
|
if (id.includes(".")) return false;
|
|
21924
22104
|
if (/-\d{8}$/.test(id)) return false;
|
|
21925
22105
|
if (/-v\d+$/.test(id)) return false;
|
|
22106
|
+
for (const segment of match[2].split("-")) {
|
|
22107
|
+
if (/^\d+$/.test(segment)) continue;
|
|
22108
|
+
if (CLAUDE_MODEL_QUALIFIER_SEGMENTS.has(segment)) continue;
|
|
22109
|
+
return false;
|
|
22110
|
+
}
|
|
21926
22111
|
return true;
|
|
21927
22112
|
}
|
|
21928
22113
|
function filterClaudePrefixModelIds(ids) {
|
|
21929
22114
|
const set = new Set(ids);
|
|
21930
22115
|
return ids.filter((id) => {
|
|
22116
|
+
if (PROTECTED_CATALOG_MODEL_IDS.has(id)) return true;
|
|
21931
22117
|
for (const other of set) {
|
|
21932
22118
|
if (other !== id && other.startsWith(`${id}-`)) return false;
|
|
21933
22119
|
}
|
|
@@ -22250,7 +22436,7 @@ var RunStartGate = class {
|
|
|
22250
22436
|
};
|
|
22251
22437
|
|
|
22252
22438
|
// src/version.ts
|
|
22253
|
-
var AGENT_VERSION = "0.1.
|
|
22439
|
+
var AGENT_VERSION = "0.1.39";
|
|
22254
22440
|
|
|
22255
22441
|
// src/workspace-relocation.ts
|
|
22256
22442
|
var import_node_child_process3 = require("child_process");
|