@atlasharness/atlascode 0.1.15 → 0.1.17
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/cli.js +507 -318
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -129,6 +129,29 @@ function cliOk(msg) {
|
|
|
129
129
|
return;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
// src/cli/crashBackstop.ts
|
|
133
|
+
function registerGlobalCrashBackstop() {
|
|
134
|
+
if (registered) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
registered = true;
|
|
138
|
+
process.on("uncaughtException", (error) => {
|
|
139
|
+
writeCrashDiag("uncaughtException", error);
|
|
140
|
+
});
|
|
141
|
+
process.on("unhandledRejection", (reason) => {
|
|
142
|
+
writeCrashDiag("unhandledRejection", reason);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function writeCrashDiag(kind, value) {
|
|
146
|
+
const formatted = value instanceof Error ? `${value.name}: ${value.message}
|
|
147
|
+
${value.stack ?? ""}`.trim() : String(value);
|
|
148
|
+
try {
|
|
149
|
+
process.stderr.write(`[atlas][${kind}] ${formatted}
|
|
150
|
+
`);
|
|
151
|
+
} catch {}
|
|
152
|
+
}
|
|
153
|
+
var registered = false;
|
|
154
|
+
|
|
132
155
|
// src/shared/feature.ts
|
|
133
156
|
function feature(name) {
|
|
134
157
|
const key = "FEATURE_" + name;
|
|
@@ -668,266 +691,6 @@ var init_shared = __esm(() => {
|
|
|
668
691
|
init_types();
|
|
669
692
|
});
|
|
670
693
|
|
|
671
|
-
// src/engine/pipeline/errorClassification.ts
|
|
672
|
-
function classifyToolError(error) {
|
|
673
|
-
if (error instanceof Error) {
|
|
674
|
-
const errnoCode = error.code;
|
|
675
|
-
if (typeof errnoCode === "string") {
|
|
676
|
-
return `Error:${errnoCode}`;
|
|
677
|
-
}
|
|
678
|
-
if (error.name && error.name !== "Error" && error.name.length > 3) {
|
|
679
|
-
return error.name.slice(0, 60);
|
|
680
|
-
}
|
|
681
|
-
return "Error";
|
|
682
|
-
}
|
|
683
|
-
return "UnknownError";
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
// src/engine/pipeline/schemaValidation.ts
|
|
687
|
-
function typeName(v) {
|
|
688
|
-
if (v === null)
|
|
689
|
-
return "null";
|
|
690
|
-
if (Array.isArray(v))
|
|
691
|
-
return "array";
|
|
692
|
-
return typeof v;
|
|
693
|
-
}
|
|
694
|
-
function checkBasicType(value, type) {
|
|
695
|
-
switch (type) {
|
|
696
|
-
case "string":
|
|
697
|
-
return typeof value === "string" ? null : `expected string, got ${typeName(value)}`;
|
|
698
|
-
case "number":
|
|
699
|
-
if (typeof value === "number") {
|
|
700
|
-
return Number.isFinite(value) ? null : "expected number, got non-finite number";
|
|
701
|
-
}
|
|
702
|
-
return `expected number, got ${typeName(value)}`;
|
|
703
|
-
case "integer":
|
|
704
|
-
if (typeof value === "number") {
|
|
705
|
-
return Number.isInteger(value) ? null : "expected integer, got non-integer number";
|
|
706
|
-
}
|
|
707
|
-
return `expected integer, got ${typeName(value)}`;
|
|
708
|
-
case "boolean":
|
|
709
|
-
return typeof value === "boolean" ? null : `expected boolean, got ${typeName(value)}`;
|
|
710
|
-
case "array":
|
|
711
|
-
return Array.isArray(value) ? null : `expected array, got ${typeName(value)}`;
|
|
712
|
-
case "object":
|
|
713
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? null : `expected object, got ${typeName(value)}`;
|
|
714
|
-
case "null":
|
|
715
|
-
return value === null ? null : `expected null, got ${typeName(value)}`;
|
|
716
|
-
default:
|
|
717
|
-
return null;
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
function validateInputBySchema(input, schema) {
|
|
721
|
-
if (!schema) {
|
|
722
|
-
return { valid: true };
|
|
723
|
-
}
|
|
724
|
-
if (input === null || typeof input !== "object" || Array.isArray(input)) {
|
|
725
|
-
return { valid: false, message: "expected object input" };
|
|
726
|
-
}
|
|
727
|
-
const record = input;
|
|
728
|
-
const errors = [];
|
|
729
|
-
const required = schema.required;
|
|
730
|
-
if (Array.isArray(required)) {
|
|
731
|
-
for (const rawKey of required) {
|
|
732
|
-
const key = String(rawKey);
|
|
733
|
-
if (!(key in record) || record[key] === undefined) {
|
|
734
|
-
errors.push(`missing required field "${key}"`);
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
const properties = schema.properties;
|
|
739
|
-
if (properties) {
|
|
740
|
-
for (const [key, value] of Object.entries(record)) {
|
|
741
|
-
if (value === undefined)
|
|
742
|
-
continue;
|
|
743
|
-
const propSchema = properties[key];
|
|
744
|
-
if (!propSchema || typeof propSchema !== "object")
|
|
745
|
-
continue;
|
|
746
|
-
const type = propSchema.type;
|
|
747
|
-
if (typeof type !== "string")
|
|
748
|
-
continue;
|
|
749
|
-
const err = checkBasicType(value, type);
|
|
750
|
-
if (err)
|
|
751
|
-
errors.push(`field "${key}": ${err}`);
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
return errors.length > 0 ? { valid: false, message: errors.join("; ") } : { valid: true };
|
|
755
|
-
}
|
|
756
|
-
function buildSchemaNotSentHint(tool, discoveredToolNames) {
|
|
757
|
-
if (!tool.shouldDefer)
|
|
758
|
-
return null;
|
|
759
|
-
if (discoveredToolNames.has(tool.name))
|
|
760
|
-
return null;
|
|
761
|
-
return `
|
|
762
|
-
|
|
763
|
-
This tool's schema was not sent to the API — it was not in the discovered-tool set derived from message history. ` + `Without the schema in your prompt, typed parameters (arrays, numbers, booleans) get emitted as strings and the client-side parser rejects them. ` + `Re-issue the call with correctly-typed parameters (arrays/numbers/booleans, not their string forms).`;
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
// src/engine/pipeline/toolExecution.ts
|
|
767
|
-
function mergeHookPermission(hookBehavior, gate) {
|
|
768
|
-
if (hookBehavior === "deny") {
|
|
769
|
-
return { allowed: false, reason: "blocked by hook" };
|
|
770
|
-
}
|
|
771
|
-
if (!gate.allowed)
|
|
772
|
-
return gate;
|
|
773
|
-
if (hookBehavior === "ask") {
|
|
774
|
-
return { allowed: false, ask: true, reason: "hook requested confirmation" };
|
|
775
|
-
}
|
|
776
|
-
return gate;
|
|
777
|
-
}
|
|
778
|
-
function findTool(tools, name) {
|
|
779
|
-
return tools.find((t) => t.name === name || (t.aliases?.includes(name) ?? false));
|
|
780
|
-
}
|
|
781
|
-
async function executeToolUse(tu, assistantMsg, deps) {
|
|
782
|
-
const tool = findTool(deps.tools, tu.name);
|
|
783
|
-
if (!tool) {
|
|
784
|
-
return {
|
|
785
|
-
block: {
|
|
786
|
-
type: "tool_result",
|
|
787
|
-
tool_use_id: tu.id,
|
|
788
|
-
content: `unknown tool: ${tu.name}`,
|
|
789
|
-
is_error: true
|
|
790
|
-
},
|
|
791
|
-
isError: true
|
|
792
|
-
};
|
|
793
|
-
}
|
|
794
|
-
const toolCallContext = deps.toolContext !== undefined ? { ...deps.toolContext, signal: deps.signal, checkPermission: deps.checkPermission } : { signal: deps.signal, checkPermission: deps.checkPermission };
|
|
795
|
-
const schemaResult = validateInputBySchema(tu.input, tool.inputSchema);
|
|
796
|
-
if (schemaResult.valid === false) {
|
|
797
|
-
const discovered = deps.discoveredToolNames ?? new Set(deps.tools.map((t) => t.name));
|
|
798
|
-
const schemaHint = buildSchemaNotSentHint(tool, discovered);
|
|
799
|
-
const errorContent = schemaHint ? `${schemaResult.message}${schemaHint}` : schemaResult.message;
|
|
800
|
-
return {
|
|
801
|
-
block: {
|
|
802
|
-
type: "tool_result",
|
|
803
|
-
tool_use_id: tu.id,
|
|
804
|
-
content: `<tool_use_error>InputValidationError: ${errorContent}</tool_use_error>`,
|
|
805
|
-
is_error: true
|
|
806
|
-
},
|
|
807
|
-
isError: true
|
|
808
|
-
};
|
|
809
|
-
}
|
|
810
|
-
const validation = await tool.validateInput?.(tu.input, toolCallContext);
|
|
811
|
-
if (validation && validation.result === false) {
|
|
812
|
-
return {
|
|
813
|
-
block: {
|
|
814
|
-
type: "tool_result",
|
|
815
|
-
tool_use_id: tu.id,
|
|
816
|
-
content: `<tool_use_error>InputValidationError: ${validation.message}</tool_use_error>`,
|
|
817
|
-
is_error: true
|
|
818
|
-
},
|
|
819
|
-
isError: true
|
|
820
|
-
};
|
|
821
|
-
}
|
|
822
|
-
const preOutcome = await deps.hooks?.preToolUse?.(tool, tu.input, tu.id);
|
|
823
|
-
if (preOutcome?.blockingError) {
|
|
824
|
-
return {
|
|
825
|
-
block: {
|
|
826
|
-
type: "tool_result",
|
|
827
|
-
tool_use_id: tu.id,
|
|
828
|
-
content: `<tool_use_error>hook blocked: ${preOutcome.blockingError}</tool_use_error>`,
|
|
829
|
-
is_error: true
|
|
830
|
-
},
|
|
831
|
-
isError: true
|
|
832
|
-
};
|
|
833
|
-
}
|
|
834
|
-
if (preOutcome?.preventContinuation) {
|
|
835
|
-
return {
|
|
836
|
-
block: {
|
|
837
|
-
type: "tool_result",
|
|
838
|
-
tool_use_id: tu.id,
|
|
839
|
-
content: `<tool_use_error>Execution stopped by PreToolUse hook${preOutcome.stopReason ? `: ${preOutcome.stopReason}` : ""}</tool_use_error>`,
|
|
840
|
-
is_error: true
|
|
841
|
-
},
|
|
842
|
-
isError: true
|
|
843
|
-
};
|
|
844
|
-
}
|
|
845
|
-
const effectiveInput = preOutcome?.updatedInput ?? tu.input;
|
|
846
|
-
const gateVerdict = deps.checkPermission ? await deps.checkPermission(tool, effectiveInput, {
|
|
847
|
-
toolUseId: tu.id,
|
|
848
|
-
assistantMessage: assistantMsg
|
|
849
|
-
}) : { allowed: true };
|
|
850
|
-
const verdict = mergeHookPermission(preOutcome?.hookBehavior, gateVerdict);
|
|
851
|
-
if (!verdict.allowed) {
|
|
852
|
-
const content = verdict.ask ? `<tool_use_error>permission confirmation required (prompt 面残留守): ${verdict.reason ?? tu.name}</tool_use_error>` : `<tool_use_error>permission denied: ${verdict.reason ?? tu.name}</tool_use_error>`;
|
|
853
|
-
return {
|
|
854
|
-
block: {
|
|
855
|
-
type: "tool_result",
|
|
856
|
-
tool_use_id: tu.id,
|
|
857
|
-
content,
|
|
858
|
-
is_error: true
|
|
859
|
-
},
|
|
860
|
-
isError: true
|
|
861
|
-
};
|
|
862
|
-
}
|
|
863
|
-
const callInput = verdict.updatedInput ?? effectiveInput;
|
|
864
|
-
let block;
|
|
865
|
-
let isError = false;
|
|
866
|
-
let toolUseResult;
|
|
867
|
-
try {
|
|
868
|
-
const res = await tool.call(callInput, toolCallContext, undefined, assistantMsg);
|
|
869
|
-
block = tool.mapToolResultToToolResultBlockParam(res.data, tu.id);
|
|
870
|
-
toolUseResult = res.data;
|
|
871
|
-
} catch (error) {
|
|
872
|
-
const errorText = `tool error [${classifyToolError(error)}]: ${String(error?.message ?? error)}`;
|
|
873
|
-
block = {
|
|
874
|
-
type: "tool_result",
|
|
875
|
-
tool_use_id: tu.id,
|
|
876
|
-
content: `<tool_use_error>${errorText}</tool_use_error>`,
|
|
877
|
-
is_error: true
|
|
878
|
-
};
|
|
879
|
-
isError = true;
|
|
880
|
-
toolUseResult = errorText;
|
|
881
|
-
}
|
|
882
|
-
const postOutcome = await deps.hooks?.postToolUse?.(tool, callInput, block, tu.id);
|
|
883
|
-
return { block, isError, toolUseResult };
|
|
884
|
-
}
|
|
885
|
-
var init_toolExecution = () => {};
|
|
886
|
-
|
|
887
|
-
// src/engine/pipeline/toolOrchestration.ts
|
|
888
|
-
function partitionToolCalls(toolUses, tools) {
|
|
889
|
-
return toolUses.reduce((acc, tu) => {
|
|
890
|
-
const tool = findTool(tools, tu.name);
|
|
891
|
-
let safe = false;
|
|
892
|
-
try {
|
|
893
|
-
safe = tool ? tool.isConcurrencySafe(tu.input) : false;
|
|
894
|
-
} catch {
|
|
895
|
-
safe = false;
|
|
896
|
-
}
|
|
897
|
-
if (safe && acc[acc.length - 1]?.isConcurrencySafe) {
|
|
898
|
-
acc[acc.length - 1].blocks.push(tu);
|
|
899
|
-
} else {
|
|
900
|
-
acc.push({ isConcurrencySafe: safe, blocks: [tu] });
|
|
901
|
-
}
|
|
902
|
-
return acc;
|
|
903
|
-
}, []);
|
|
904
|
-
}
|
|
905
|
-
async function runToolBatch(toolUses, assistantMsg, deps) {
|
|
906
|
-
const outcomes = [];
|
|
907
|
-
for (const batch of partitionToolCalls(toolUses, deps.tools)) {
|
|
908
|
-
for (const tu of batch.blocks) {
|
|
909
|
-
const r = await executeToolUse(tu, assistantMsg, deps);
|
|
910
|
-
outcomes.push({
|
|
911
|
-
toolUseId: tu.id,
|
|
912
|
-
name: tu.name,
|
|
913
|
-
block: r.block,
|
|
914
|
-
isError: r.isError,
|
|
915
|
-
toolUseResult: r.toolUseResult
|
|
916
|
-
});
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
return outcomes;
|
|
920
|
-
}
|
|
921
|
-
var init_toolOrchestration = __esm(() => {
|
|
922
|
-
init_toolExecution();
|
|
923
|
-
});
|
|
924
|
-
|
|
925
|
-
// src/engine/pipeline/index.ts
|
|
926
|
-
var init_pipeline = __esm(() => {
|
|
927
|
-
init_toolExecution();
|
|
928
|
-
init_toolOrchestration();
|
|
929
|
-
});
|
|
930
|
-
|
|
931
694
|
// node_modules/openai/internal/tslib.mjs
|
|
932
695
|
function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
933
696
|
if (kind === "m")
|
|
@@ -20052,6 +19815,17 @@ var init_openai = __esm(() => {
|
|
|
20052
19815
|
init_bedrock2();
|
|
20053
19816
|
});
|
|
20054
19817
|
|
|
19818
|
+
// src/modelprovider/constants.ts
|
|
19819
|
+
var API_IMAGE_MAX_BASE64_SIZE, IMAGE_TARGET_RAW_SIZE, PDF_TARGET_RAW_SIZE, API_PDF_MAX_PAGES = 100, LLM_TIMEOUT_DEFAULT_MS = 600000, LLM_TIMEOUT_CAP_MS = 1800000, SUMMARIZE_CONNECTOR_TEXT_BETA_HEADER, AFK_MODE_BETA_HEADER;
|
|
19820
|
+
var init_constants2 = __esm(() => {
|
|
19821
|
+
init_shared();
|
|
19822
|
+
API_IMAGE_MAX_BASE64_SIZE = 5 * 1024 * 1024;
|
|
19823
|
+
IMAGE_TARGET_RAW_SIZE = API_IMAGE_MAX_BASE64_SIZE * 3 / 4;
|
|
19824
|
+
PDF_TARGET_RAW_SIZE = 20 * 1024 * 1024;
|
|
19825
|
+
SUMMARIZE_CONNECTOR_TEXT_BETA_HEADER = feature("CONNECTOR_TEXT") ? "summarize-connector-text-2026-03-13" : "";
|
|
19826
|
+
AFK_MODE_BETA_HEADER = feature("TRANSCRIPT_CLASSIFIER") ? "afk-mode-2026-01-31" : "";
|
|
19827
|
+
});
|
|
19828
|
+
|
|
20055
19829
|
// src/modelprovider/clients.ts
|
|
20056
19830
|
function clientCacheKey(provider, baseURL, apiKey) {
|
|
20057
19831
|
return provider + "|" + (baseURL || "") + "|" + (apiKey || "");
|
|
@@ -20066,7 +19840,7 @@ function getClientForEntry(entry) {
|
|
|
20066
19840
|
baseURL: entry.baseURL,
|
|
20067
19841
|
apiKey: entry.apiKey,
|
|
20068
19842
|
maxRetries: 0,
|
|
20069
|
-
timeout:
|
|
19843
|
+
timeout: LLM_TIMEOUT_DEFAULT_MS
|
|
20070
19844
|
});
|
|
20071
19845
|
clientCache.set(key, client);
|
|
20072
19846
|
return client;
|
|
@@ -20074,6 +19848,7 @@ function getClientForEntry(entry) {
|
|
|
20074
19848
|
var clientCache;
|
|
20075
19849
|
var init_clients = __esm(() => {
|
|
20076
19850
|
init_openai();
|
|
19851
|
+
init_constants2();
|
|
20077
19852
|
clientCache = new Map;
|
|
20078
19853
|
});
|
|
20079
19854
|
|
|
@@ -27007,6 +26782,27 @@ var init_params = __esm(() => {
|
|
|
27007
26782
|
init_effort();
|
|
27008
26783
|
});
|
|
27009
26784
|
|
|
26785
|
+
// src/modelprovider/types.ts
|
|
26786
|
+
var APIError2, APIConnectionError2, APIConnectionTimeoutError2;
|
|
26787
|
+
var init_types2 = __esm(() => {
|
|
26788
|
+
APIError2 = class APIError2 extends Error {
|
|
26789
|
+
status;
|
|
26790
|
+
error;
|
|
26791
|
+
constructor(message, status, error) {
|
|
26792
|
+
super(message);
|
|
26793
|
+
this.name = "APIError";
|
|
26794
|
+
if (status !== undefined)
|
|
26795
|
+
this.status = status;
|
|
26796
|
+
if (error !== undefined)
|
|
26797
|
+
this.error = error;
|
|
26798
|
+
}
|
|
26799
|
+
};
|
|
26800
|
+
APIConnectionError2 = class APIConnectionError2 extends APIError2 {
|
|
26801
|
+
};
|
|
26802
|
+
APIConnectionTimeoutError2 = class APIConnectionTimeoutError2 extends APIConnectionError2 {
|
|
26803
|
+
};
|
|
26804
|
+
});
|
|
26805
|
+
|
|
27010
26806
|
// src/modelprovider/modelprovider.ts
|
|
27011
26807
|
import { randomUUID } from "crypto";
|
|
27012
26808
|
function mapOpenAIUsage(u) {
|
|
@@ -27025,6 +26821,29 @@ function isRetryableError(err) {
|
|
|
27025
26821
|
const msg = String(err?.message || err?.code || "");
|
|
27026
26822
|
return /timeout|ECONN|EPIPE|fetch failed|socket|aborted/i.test(msg);
|
|
27027
26823
|
}
|
|
26824
|
+
function isClientRequestTimeout(err) {
|
|
26825
|
+
if (!err || typeof err !== "object")
|
|
26826
|
+
return false;
|
|
26827
|
+
const e = err;
|
|
26828
|
+
if (err instanceof APIConnectionTimeoutError2)
|
|
26829
|
+
return true;
|
|
26830
|
+
if (e.name === "APIConnectionTimeoutError" || e.name === "APITimeoutError")
|
|
26831
|
+
return true;
|
|
26832
|
+
return false;
|
|
26833
|
+
}
|
|
26834
|
+
function shouldRetryModelError(err, signal) {
|
|
26835
|
+
if (signal?.aborted)
|
|
26836
|
+
return false;
|
|
26837
|
+
if (isClientRequestTimeout(err))
|
|
26838
|
+
return false;
|
|
26839
|
+
return isRetryableError(err);
|
|
26840
|
+
}
|
|
26841
|
+
function llmTimeoutRemediationHint(error, currentTimeoutMs) {
|
|
26842
|
+
if (!isClientRequestTimeout(error))
|
|
26843
|
+
return null;
|
|
26844
|
+
const head = typeof currentTimeoutMs === "number" && currentTimeoutMs > 0 ? `当前超时 ${Math.round(currentTimeoutMs / 1000)}s` : "慢模型长生成可能超过缺省超时";
|
|
26845
|
+
return `LLM 请求超时(${head})。可调大:env ATLAS_LLM_TIMEOUT=<毫秒> 或 settings.json llmTimeoutMs 键(上限 ${Math.round(LLM_TIMEOUT_CAP_MS / 60000)}min)。`;
|
|
26846
|
+
}
|
|
27028
26847
|
function startLlmWaitHeartbeat(modelId, attempt, totalRetries) {
|
|
27029
26848
|
const startedAt = Date.now();
|
|
27030
26849
|
const id = setInterval(() => {
|
|
@@ -27038,9 +26857,14 @@ function startLlmWaitHeartbeat(modelId, attempt, totalRetries) {
|
|
|
27038
26857
|
class OpenAIProvider {
|
|
27039
26858
|
maxRetriesPerModel;
|
|
27040
26859
|
timeoutMs;
|
|
27041
|
-
|
|
26860
|
+
timeoutResolver;
|
|
26861
|
+
constructor(maxRetriesPerModel = 3, timeoutMs = LLM_TIMEOUT_DEFAULT_MS, timeoutResolver) {
|
|
27042
26862
|
this.maxRetriesPerModel = maxRetriesPerModel;
|
|
27043
26863
|
this.timeoutMs = timeoutMs;
|
|
26864
|
+
this.timeoutResolver = timeoutResolver;
|
|
26865
|
+
}
|
|
26866
|
+
getTimeoutMs() {
|
|
26867
|
+
return this.timeoutResolver ? this.timeoutResolver() : this.timeoutMs;
|
|
27044
26868
|
}
|
|
27045
26869
|
async chat(args) {
|
|
27046
26870
|
const refs = getRoleModels(args.role, args.sessionModel, args.fallbackModel);
|
|
@@ -27080,7 +26904,7 @@ class OpenAIProvider {
|
|
|
27080
26904
|
const stopWait = startLlmWaitHeartbeat(entry.modelId, attempt, this.maxRetriesPerModel);
|
|
27081
26905
|
let res;
|
|
27082
26906
|
try {
|
|
27083
|
-
res = await client.chat.completions.create(params, { signal: args.signal, timeout: this.
|
|
26907
|
+
res = await client.chat.completions.create(params, { signal: args.signal, timeout: this.getTimeoutMs() });
|
|
27084
26908
|
} finally {
|
|
27085
26909
|
stopWait();
|
|
27086
26910
|
}
|
|
@@ -27128,7 +26952,7 @@ class OpenAIProvider {
|
|
|
27128
26952
|
};
|
|
27129
26953
|
} catch (err) {
|
|
27130
26954
|
lastErr = err;
|
|
27131
|
-
if (!
|
|
26955
|
+
if (!shouldRetryModelError(err, args.signal))
|
|
27132
26956
|
break;
|
|
27133
26957
|
}
|
|
27134
26958
|
}
|
|
@@ -27178,7 +27002,7 @@ class OpenAIProvider {
|
|
|
27178
27002
|
break;
|
|
27179
27003
|
} catch (err) {
|
|
27180
27004
|
lastErr = err;
|
|
27181
|
-
if (!
|
|
27005
|
+
if (!shouldRetryModelError(err, args.signal))
|
|
27182
27006
|
break;
|
|
27183
27007
|
}
|
|
27184
27008
|
}
|
|
@@ -27188,7 +27012,7 @@ class OpenAIProvider {
|
|
|
27188
27012
|
if (lastErr) {
|
|
27189
27013
|
const message = lastErr instanceof Error ? lastErr.message || lastErr.name : String(lastErr);
|
|
27190
27014
|
const code = lastErr?.name === "TimeoutError" ? "TIMEOUT" : "API_ERROR";
|
|
27191
|
-
yield { type: "error", code, message, retryable:
|
|
27015
|
+
yield { type: "error", code, message, retryable: shouldRetryModelError(lastErr, args.signal) };
|
|
27192
27016
|
return;
|
|
27193
27017
|
}
|
|
27194
27018
|
throw new Error(`No models configured for role '${args.role}'.`);
|
|
@@ -27197,7 +27021,7 @@ class OpenAIProvider {
|
|
|
27197
27021
|
const stopWait = startLlmWaitHeartbeat(entry.modelId, attempt, totalRetries);
|
|
27198
27022
|
let stream;
|
|
27199
27023
|
try {
|
|
27200
|
-
stream = await client.chat.completions.create({ ...params, stream: true, stream_options: { include_usage: true } }, { signal, timeout: this.
|
|
27024
|
+
stream = await client.chat.completions.create({ ...params, stream: true, stream_options: { include_usage: true } }, { signal, timeout: this.getTimeoutMs() });
|
|
27201
27025
|
} finally {
|
|
27202
27026
|
stopWait();
|
|
27203
27027
|
}
|
|
@@ -27385,7 +27209,7 @@ class OpenAIProvider {
|
|
|
27385
27209
|
const wav = Buffer.concat([header, pcm]);
|
|
27386
27210
|
const file = new File([wav], "audio.wav", { type: "audio/wav" });
|
|
27387
27211
|
const client = getClientForEntry(entry);
|
|
27388
|
-
const resp = await client.audio.transcriptions.create({ file, model, ...language ? { language } : {} }, { timeout: this.
|
|
27212
|
+
const resp = await client.audio.transcriptions.create({ file, model, ...language ? { language } : {} }, { timeout: this.getTimeoutMs() });
|
|
27389
27213
|
return resp?.text ?? "";
|
|
27390
27214
|
}
|
|
27391
27215
|
async synthesizeSpeech(text, model, voice) {
|
|
@@ -27399,7 +27223,7 @@ class OpenAIProvider {
|
|
|
27399
27223
|
voice: voice || "alloy",
|
|
27400
27224
|
input: text,
|
|
27401
27225
|
response_format: "mp3"
|
|
27402
|
-
}, { timeout: this.
|
|
27226
|
+
}, { timeout: this.getTimeoutMs() });
|
|
27403
27227
|
const buf = await resp.arrayBuffer();
|
|
27404
27228
|
return Buffer.from(buf);
|
|
27405
27229
|
}
|
|
@@ -27434,15 +27258,15 @@ class OpenAIProvider {
|
|
|
27434
27258
|
var init_modelprovider = __esm(() => {
|
|
27435
27259
|
init_openai();
|
|
27436
27260
|
init_clients();
|
|
27261
|
+
init_constants2();
|
|
27437
27262
|
init_roles7();
|
|
27438
27263
|
init_shared();
|
|
27439
27264
|
init_shared();
|
|
27440
27265
|
init_params();
|
|
27266
|
+
init_types2();
|
|
27267
|
+
init_constants2();
|
|
27441
27268
|
});
|
|
27442
27269
|
|
|
27443
|
-
// src/modelprovider/types.ts
|
|
27444
|
-
var init_types2 = () => {};
|
|
27445
|
-
|
|
27446
27270
|
// src/modelprovider/errorUtils.ts
|
|
27447
27271
|
function extractConnectionErrorDetails(error) {
|
|
27448
27272
|
if (!error || typeof error !== "object") {
|
|
@@ -27581,17 +27405,6 @@ var init_errorUtils = __esm(() => {
|
|
|
27581
27405
|
]);
|
|
27582
27406
|
});
|
|
27583
27407
|
|
|
27584
|
-
// src/modelprovider/constants.ts
|
|
27585
|
-
var API_IMAGE_MAX_BASE64_SIZE, IMAGE_TARGET_RAW_SIZE, PDF_TARGET_RAW_SIZE, API_PDF_MAX_PAGES = 100, SUMMARIZE_CONNECTOR_TEXT_BETA_HEADER, AFK_MODE_BETA_HEADER;
|
|
27586
|
-
var init_constants2 = __esm(() => {
|
|
27587
|
-
init_shared();
|
|
27588
|
-
API_IMAGE_MAX_BASE64_SIZE = 5 * 1024 * 1024;
|
|
27589
|
-
IMAGE_TARGET_RAW_SIZE = API_IMAGE_MAX_BASE64_SIZE * 3 / 4;
|
|
27590
|
-
PDF_TARGET_RAW_SIZE = 20 * 1024 * 1024;
|
|
27591
|
-
SUMMARIZE_CONNECTOR_TEXT_BETA_HEADER = feature("CONNECTOR_TEXT") ? "summarize-connector-text-2026-03-13" : "";
|
|
27592
|
-
AFK_MODE_BETA_HEADER = feature("TRANSCRIPT_CLASSIFIER") ? "afk-mode-2026-01-31" : "";
|
|
27593
|
-
});
|
|
27594
|
-
|
|
27595
27408
|
// src/modelprovider/errorMessaging.ts
|
|
27596
27409
|
function registerErrorMessagingPorts(p) {
|
|
27597
27410
|
ports = p;
|
|
@@ -27731,10 +27544,22 @@ var init_queryWithRoleFallback = __esm(() => {
|
|
|
27731
27544
|
|
|
27732
27545
|
// src/modelprovider/index.ts
|
|
27733
27546
|
function getModelProvider() {
|
|
27734
|
-
return _provider ??= new OpenAIProvider(3, resolveLlmTimeoutMs());
|
|
27547
|
+
return _provider ??= new OpenAIProvider(3, LLM_TIMEOUT_DEFAULT_MS, () => resolveLlmTimeoutMs(process.env.ATLAS_LLM_TIMEOUT, llmTimeoutSettingsSource?.()));
|
|
27548
|
+
}
|
|
27549
|
+
function setLlmTimeoutSettingsSource(next) {
|
|
27550
|
+
llmTimeoutSettingsSource = next;
|
|
27551
|
+
}
|
|
27552
|
+
function getCurrentLlmTimeoutMs() {
|
|
27553
|
+
return resolveLlmTimeoutMs(process.env.ATLAS_LLM_TIMEOUT, llmTimeoutSettingsSource?.());
|
|
27735
27554
|
}
|
|
27736
|
-
function resolveLlmTimeoutMs() {
|
|
27737
|
-
|
|
27555
|
+
function resolveLlmTimeoutMs(envRaw = process.env.ATLAS_LLM_TIMEOUT, settingsMs) {
|
|
27556
|
+
const fromSettings = () => typeof settingsMs === "number" && Number.isInteger(settingsMs) && settingsMs >= 1 ? Math.min(settingsMs, LLM_TIMEOUT_CAP_MS) : LLM_TIMEOUT_DEFAULT_MS;
|
|
27557
|
+
if (envRaw === undefined || envRaw === "")
|
|
27558
|
+
return fromSettings();
|
|
27559
|
+
const env = parseBoundedIntEnv("ATLAS_LLM_TIMEOUT", envRaw, LLM_TIMEOUT_DEFAULT_MS, LLM_TIMEOUT_CAP_MS, 1);
|
|
27560
|
+
if (env.status !== "invalid")
|
|
27561
|
+
return env.effective;
|
|
27562
|
+
return fromSettings();
|
|
27738
27563
|
}
|
|
27739
27564
|
function lazyProxy(resolve) {
|
|
27740
27565
|
return new Proxy({}, {
|
|
@@ -27745,13 +27570,16 @@ function lazyProxy(resolve) {
|
|
|
27745
27570
|
}
|
|
27746
27571
|
});
|
|
27747
27572
|
}
|
|
27748
|
-
var _provider, modelProvider;
|
|
27573
|
+
var _provider, llmTimeoutSettingsSource = null, modelProvider;
|
|
27749
27574
|
var init_modelprovider2 = __esm(() => {
|
|
27750
27575
|
init_modelprovider();
|
|
27576
|
+
init_constants2();
|
|
27751
27577
|
init_shared();
|
|
27578
|
+
init_constants2();
|
|
27752
27579
|
init_modelprovider();
|
|
27753
27580
|
init_types2();
|
|
27754
27581
|
init_modelErrors();
|
|
27582
|
+
init_modelprovider();
|
|
27755
27583
|
init_params();
|
|
27756
27584
|
init_roles7();
|
|
27757
27585
|
init_errorUtils();
|
|
@@ -27766,6 +27594,345 @@ var init_modelprovider2 = __esm(() => {
|
|
|
27766
27594
|
modelProvider = lazyProxy(getModelProvider);
|
|
27767
27595
|
});
|
|
27768
27596
|
|
|
27597
|
+
// src/engine/query/turnRecovery.ts
|
|
27598
|
+
function parseNonNegativeInt(value, fallback) {
|
|
27599
|
+
if (value === undefined || value === "")
|
|
27600
|
+
return fallback;
|
|
27601
|
+
const n = Number.parseInt(value, 10);
|
|
27602
|
+
return Number.isFinite(n) && n >= 0 ? n : fallback;
|
|
27603
|
+
}
|
|
27604
|
+
function resolveTurnRecoveryConfig(env = process.env) {
|
|
27605
|
+
return {
|
|
27606
|
+
enabled: env.ATLAS_TURN_RECOVER_ENABLED !== "0",
|
|
27607
|
+
maxRetries: parseNonNegativeInt(env.ATLAS_TURN_RECOVER_MAX, DEFAULT_MAX_RETRIES),
|
|
27608
|
+
backoffBaseMs: parseNonNegativeInt(env.ATLAS_TURN_RECOVER_BACKOFF_MS, DEFAULT_BACKOFF_BASE_MS),
|
|
27609
|
+
backoffCapMs: parseNonNegativeInt(env.ATLAS_TURN_RECOVER_BACKOFF_CAP_MS, DEFAULT_BACKOFF_CAP_MS)
|
|
27610
|
+
};
|
|
27611
|
+
}
|
|
27612
|
+
function turnRecoveryBackoffMs(attempt, baseMs, capMs) {
|
|
27613
|
+
const base = Math.max(0, baseMs);
|
|
27614
|
+
const cap = Math.max(base, capMs);
|
|
27615
|
+
if (attempt <= 0)
|
|
27616
|
+
return Math.min(base, cap);
|
|
27617
|
+
return Math.min(base * 2 ** attempt, cap);
|
|
27618
|
+
}
|
|
27619
|
+
function sleepSignalAware(ms, signal) {
|
|
27620
|
+
if (ms <= 0)
|
|
27621
|
+
return Promise.resolve();
|
|
27622
|
+
return new Promise((resolve) => {
|
|
27623
|
+
if (signal?.aborted) {
|
|
27624
|
+
resolve();
|
|
27625
|
+
return;
|
|
27626
|
+
}
|
|
27627
|
+
let settled = false;
|
|
27628
|
+
const timer = setTimeout(() => {
|
|
27629
|
+
settled = true;
|
|
27630
|
+
if (signal)
|
|
27631
|
+
signal.removeEventListener("abort", onAbort);
|
|
27632
|
+
resolve();
|
|
27633
|
+
}, ms);
|
|
27634
|
+
function onAbort() {
|
|
27635
|
+
if (settled)
|
|
27636
|
+
return;
|
|
27637
|
+
settled = true;
|
|
27638
|
+
clearTimeout(timer);
|
|
27639
|
+
resolve();
|
|
27640
|
+
}
|
|
27641
|
+
if (signal)
|
|
27642
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
27643
|
+
});
|
|
27644
|
+
}
|
|
27645
|
+
async function withTurnRecovery(attempt, options = {}) {
|
|
27646
|
+
const cfg = options.config ?? resolveTurnRecoveryConfig();
|
|
27647
|
+
if (!cfg.enabled) {
|
|
27648
|
+
return attempt();
|
|
27649
|
+
}
|
|
27650
|
+
let lastErr;
|
|
27651
|
+
for (let i = 0;i <= cfg.maxRetries; i++) {
|
|
27652
|
+
if (i > 0 && options.signal?.aborted) {
|
|
27653
|
+
throw options.signal.reason ?? new Error("aborted");
|
|
27654
|
+
}
|
|
27655
|
+
try {
|
|
27656
|
+
return await attempt();
|
|
27657
|
+
} catch (err) {
|
|
27658
|
+
lastErr = err;
|
|
27659
|
+
if (i < cfg.maxRetries && shouldRetryModelError(err, options.signal)) {
|
|
27660
|
+
const backoff = turnRecoveryBackoffMs(i, cfg.backoffBaseMs, cfg.backoffCapMs);
|
|
27661
|
+
if (backoff > 0) {
|
|
27662
|
+
await sleepSignalAware(backoff, options.signal);
|
|
27663
|
+
}
|
|
27664
|
+
continue;
|
|
27665
|
+
}
|
|
27666
|
+
throw err;
|
|
27667
|
+
}
|
|
27668
|
+
}
|
|
27669
|
+
throw lastErr;
|
|
27670
|
+
}
|
|
27671
|
+
var DEFAULT_MAX_RETRIES = 13, DEFAULT_BACKOFF_BASE_MS = 100, DEFAULT_BACKOFF_CAP_MS = 1000;
|
|
27672
|
+
var init_turnRecovery = __esm(() => {
|
|
27673
|
+
init_modelprovider2();
|
|
27674
|
+
});
|
|
27675
|
+
|
|
27676
|
+
// src/engine/pipeline/errorClassification.ts
|
|
27677
|
+
function classifyToolError(error) {
|
|
27678
|
+
if (error instanceof Error) {
|
|
27679
|
+
const errnoCode = error.code;
|
|
27680
|
+
if (typeof errnoCode === "string") {
|
|
27681
|
+
return `Error:${errnoCode}`;
|
|
27682
|
+
}
|
|
27683
|
+
if (error.name && error.name !== "Error" && error.name.length > 3) {
|
|
27684
|
+
return error.name.slice(0, 60);
|
|
27685
|
+
}
|
|
27686
|
+
return "Error";
|
|
27687
|
+
}
|
|
27688
|
+
return "UnknownError";
|
|
27689
|
+
}
|
|
27690
|
+
|
|
27691
|
+
// src/engine/pipeline/schemaValidation.ts
|
|
27692
|
+
function typeName(v) {
|
|
27693
|
+
if (v === null)
|
|
27694
|
+
return "null";
|
|
27695
|
+
if (Array.isArray(v))
|
|
27696
|
+
return "array";
|
|
27697
|
+
return typeof v;
|
|
27698
|
+
}
|
|
27699
|
+
function checkBasicType(value, type) {
|
|
27700
|
+
switch (type) {
|
|
27701
|
+
case "string":
|
|
27702
|
+
return typeof value === "string" ? null : `expected string, got ${typeName(value)}`;
|
|
27703
|
+
case "number":
|
|
27704
|
+
if (typeof value === "number") {
|
|
27705
|
+
return Number.isFinite(value) ? null : "expected number, got non-finite number";
|
|
27706
|
+
}
|
|
27707
|
+
return `expected number, got ${typeName(value)}`;
|
|
27708
|
+
case "integer":
|
|
27709
|
+
if (typeof value === "number") {
|
|
27710
|
+
return Number.isInteger(value) ? null : "expected integer, got non-integer number";
|
|
27711
|
+
}
|
|
27712
|
+
return `expected integer, got ${typeName(value)}`;
|
|
27713
|
+
case "boolean":
|
|
27714
|
+
return typeof value === "boolean" ? null : `expected boolean, got ${typeName(value)}`;
|
|
27715
|
+
case "array":
|
|
27716
|
+
return Array.isArray(value) ? null : `expected array, got ${typeName(value)}`;
|
|
27717
|
+
case "object":
|
|
27718
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? null : `expected object, got ${typeName(value)}`;
|
|
27719
|
+
case "null":
|
|
27720
|
+
return value === null ? null : `expected null, got ${typeName(value)}`;
|
|
27721
|
+
default:
|
|
27722
|
+
return null;
|
|
27723
|
+
}
|
|
27724
|
+
}
|
|
27725
|
+
function validateInputBySchema(input, schema) {
|
|
27726
|
+
if (!schema) {
|
|
27727
|
+
return { valid: true };
|
|
27728
|
+
}
|
|
27729
|
+
if (input === null || typeof input !== "object" || Array.isArray(input)) {
|
|
27730
|
+
return { valid: false, message: "expected object input" };
|
|
27731
|
+
}
|
|
27732
|
+
const record = input;
|
|
27733
|
+
const errors = [];
|
|
27734
|
+
const required = schema.required;
|
|
27735
|
+
if (Array.isArray(required)) {
|
|
27736
|
+
for (const rawKey of required) {
|
|
27737
|
+
const key = String(rawKey);
|
|
27738
|
+
if (!(key in record) || record[key] === undefined) {
|
|
27739
|
+
errors.push(`missing required field "${key}"`);
|
|
27740
|
+
}
|
|
27741
|
+
}
|
|
27742
|
+
}
|
|
27743
|
+
const properties = schema.properties;
|
|
27744
|
+
if (properties) {
|
|
27745
|
+
for (const [key, value] of Object.entries(record)) {
|
|
27746
|
+
if (value === undefined)
|
|
27747
|
+
continue;
|
|
27748
|
+
const propSchema = properties[key];
|
|
27749
|
+
if (!propSchema || typeof propSchema !== "object")
|
|
27750
|
+
continue;
|
|
27751
|
+
const type = propSchema.type;
|
|
27752
|
+
if (typeof type !== "string")
|
|
27753
|
+
continue;
|
|
27754
|
+
const err = checkBasicType(value, type);
|
|
27755
|
+
if (err)
|
|
27756
|
+
errors.push(`field "${key}": ${err}`);
|
|
27757
|
+
}
|
|
27758
|
+
}
|
|
27759
|
+
return errors.length > 0 ? { valid: false, message: errors.join("; ") } : { valid: true };
|
|
27760
|
+
}
|
|
27761
|
+
function buildSchemaNotSentHint(tool, discoveredToolNames) {
|
|
27762
|
+
if (!tool.shouldDefer)
|
|
27763
|
+
return null;
|
|
27764
|
+
if (discoveredToolNames.has(tool.name))
|
|
27765
|
+
return null;
|
|
27766
|
+
return `
|
|
27767
|
+
|
|
27768
|
+
This tool's schema was not sent to the API — it was not in the discovered-tool set derived from message history. ` + `Without the schema in your prompt, typed parameters (arrays, numbers, booleans) get emitted as strings and the client-side parser rejects them. ` + `Re-issue the call with correctly-typed parameters (arrays/numbers/booleans, not their string forms).`;
|
|
27769
|
+
}
|
|
27770
|
+
|
|
27771
|
+
// src/engine/pipeline/toolExecution.ts
|
|
27772
|
+
function mergeHookPermission(hookBehavior, gate) {
|
|
27773
|
+
if (hookBehavior === "deny") {
|
|
27774
|
+
return { allowed: false, reason: "blocked by hook" };
|
|
27775
|
+
}
|
|
27776
|
+
if (!gate.allowed)
|
|
27777
|
+
return gate;
|
|
27778
|
+
if (hookBehavior === "ask") {
|
|
27779
|
+
return { allowed: false, ask: true, reason: "hook requested confirmation" };
|
|
27780
|
+
}
|
|
27781
|
+
return gate;
|
|
27782
|
+
}
|
|
27783
|
+
function findTool(tools, name) {
|
|
27784
|
+
return tools.find((t) => t.name === name || (t.aliases?.includes(name) ?? false));
|
|
27785
|
+
}
|
|
27786
|
+
async function executeToolUse(tu, assistantMsg, deps) {
|
|
27787
|
+
const tool = findTool(deps.tools, tu.name);
|
|
27788
|
+
if (!tool) {
|
|
27789
|
+
return {
|
|
27790
|
+
block: {
|
|
27791
|
+
type: "tool_result",
|
|
27792
|
+
tool_use_id: tu.id,
|
|
27793
|
+
content: `unknown tool: ${tu.name}`,
|
|
27794
|
+
is_error: true
|
|
27795
|
+
},
|
|
27796
|
+
isError: true
|
|
27797
|
+
};
|
|
27798
|
+
}
|
|
27799
|
+
const toolCallContext = deps.toolContext !== undefined ? { ...deps.toolContext, signal: deps.signal, checkPermission: deps.checkPermission } : { signal: deps.signal, checkPermission: deps.checkPermission };
|
|
27800
|
+
const schemaResult = validateInputBySchema(tu.input, tool.inputSchema);
|
|
27801
|
+
if (schemaResult.valid === false) {
|
|
27802
|
+
const discovered = deps.discoveredToolNames ?? new Set(deps.tools.map((t) => t.name));
|
|
27803
|
+
const schemaHint = buildSchemaNotSentHint(tool, discovered);
|
|
27804
|
+
const errorContent = schemaHint ? `${schemaResult.message}${schemaHint}` : schemaResult.message;
|
|
27805
|
+
return {
|
|
27806
|
+
block: {
|
|
27807
|
+
type: "tool_result",
|
|
27808
|
+
tool_use_id: tu.id,
|
|
27809
|
+
content: `<tool_use_error>InputValidationError: ${errorContent}</tool_use_error>`,
|
|
27810
|
+
is_error: true
|
|
27811
|
+
},
|
|
27812
|
+
isError: true
|
|
27813
|
+
};
|
|
27814
|
+
}
|
|
27815
|
+
const validation = await tool.validateInput?.(tu.input, toolCallContext);
|
|
27816
|
+
if (validation && validation.result === false) {
|
|
27817
|
+
return {
|
|
27818
|
+
block: {
|
|
27819
|
+
type: "tool_result",
|
|
27820
|
+
tool_use_id: tu.id,
|
|
27821
|
+
content: `<tool_use_error>InputValidationError: ${validation.message}</tool_use_error>`,
|
|
27822
|
+
is_error: true
|
|
27823
|
+
},
|
|
27824
|
+
isError: true
|
|
27825
|
+
};
|
|
27826
|
+
}
|
|
27827
|
+
const preOutcome = await deps.hooks?.preToolUse?.(tool, tu.input, tu.id);
|
|
27828
|
+
if (preOutcome?.blockingError) {
|
|
27829
|
+
return {
|
|
27830
|
+
block: {
|
|
27831
|
+
type: "tool_result",
|
|
27832
|
+
tool_use_id: tu.id,
|
|
27833
|
+
content: `<tool_use_error>hook blocked: ${preOutcome.blockingError}</tool_use_error>`,
|
|
27834
|
+
is_error: true
|
|
27835
|
+
},
|
|
27836
|
+
isError: true
|
|
27837
|
+
};
|
|
27838
|
+
}
|
|
27839
|
+
if (preOutcome?.preventContinuation) {
|
|
27840
|
+
return {
|
|
27841
|
+
block: {
|
|
27842
|
+
type: "tool_result",
|
|
27843
|
+
tool_use_id: tu.id,
|
|
27844
|
+
content: `<tool_use_error>Execution stopped by PreToolUse hook${preOutcome.stopReason ? `: ${preOutcome.stopReason}` : ""}</tool_use_error>`,
|
|
27845
|
+
is_error: true
|
|
27846
|
+
},
|
|
27847
|
+
isError: true
|
|
27848
|
+
};
|
|
27849
|
+
}
|
|
27850
|
+
const effectiveInput = preOutcome?.updatedInput ?? tu.input;
|
|
27851
|
+
const gateVerdict = deps.checkPermission ? await deps.checkPermission(tool, effectiveInput, {
|
|
27852
|
+
toolUseId: tu.id,
|
|
27853
|
+
assistantMessage: assistantMsg
|
|
27854
|
+
}) : { allowed: true };
|
|
27855
|
+
const verdict = mergeHookPermission(preOutcome?.hookBehavior, gateVerdict);
|
|
27856
|
+
if (!verdict.allowed) {
|
|
27857
|
+
const content = verdict.ask ? `<tool_use_error>permission confirmation required (prompt 面残留守): ${verdict.reason ?? tu.name}</tool_use_error>` : `<tool_use_error>permission denied: ${verdict.reason ?? tu.name}</tool_use_error>`;
|
|
27858
|
+
return {
|
|
27859
|
+
block: {
|
|
27860
|
+
type: "tool_result",
|
|
27861
|
+
tool_use_id: tu.id,
|
|
27862
|
+
content,
|
|
27863
|
+
is_error: true
|
|
27864
|
+
},
|
|
27865
|
+
isError: true
|
|
27866
|
+
};
|
|
27867
|
+
}
|
|
27868
|
+
const callInput = verdict.updatedInput ?? effectiveInput;
|
|
27869
|
+
let block;
|
|
27870
|
+
let isError = false;
|
|
27871
|
+
let toolUseResult;
|
|
27872
|
+
try {
|
|
27873
|
+
const res = await tool.call(callInput, toolCallContext, undefined, assistantMsg);
|
|
27874
|
+
block = tool.mapToolResultToToolResultBlockParam(res.data, tu.id);
|
|
27875
|
+
toolUseResult = res.data;
|
|
27876
|
+
} catch (error) {
|
|
27877
|
+
const errorText = `tool error [${classifyToolError(error)}]: ${String(error?.message ?? error)}`;
|
|
27878
|
+
block = {
|
|
27879
|
+
type: "tool_result",
|
|
27880
|
+
tool_use_id: tu.id,
|
|
27881
|
+
content: `<tool_use_error>${errorText}</tool_use_error>`,
|
|
27882
|
+
is_error: true
|
|
27883
|
+
};
|
|
27884
|
+
isError = true;
|
|
27885
|
+
toolUseResult = errorText;
|
|
27886
|
+
}
|
|
27887
|
+
const postOutcome = await deps.hooks?.postToolUse?.(tool, callInput, block, tu.id);
|
|
27888
|
+
return { block, isError, toolUseResult };
|
|
27889
|
+
}
|
|
27890
|
+
var init_toolExecution = () => {};
|
|
27891
|
+
|
|
27892
|
+
// src/engine/pipeline/toolOrchestration.ts
|
|
27893
|
+
function partitionToolCalls(toolUses, tools) {
|
|
27894
|
+
return toolUses.reduce((acc, tu) => {
|
|
27895
|
+
const tool = findTool(tools, tu.name);
|
|
27896
|
+
let safe = false;
|
|
27897
|
+
try {
|
|
27898
|
+
safe = tool ? tool.isConcurrencySafe(tu.input) : false;
|
|
27899
|
+
} catch {
|
|
27900
|
+
safe = false;
|
|
27901
|
+
}
|
|
27902
|
+
if (safe && acc[acc.length - 1]?.isConcurrencySafe) {
|
|
27903
|
+
acc[acc.length - 1].blocks.push(tu);
|
|
27904
|
+
} else {
|
|
27905
|
+
acc.push({ isConcurrencySafe: safe, blocks: [tu] });
|
|
27906
|
+
}
|
|
27907
|
+
return acc;
|
|
27908
|
+
}, []);
|
|
27909
|
+
}
|
|
27910
|
+
async function runToolBatch(toolUses, assistantMsg, deps) {
|
|
27911
|
+
const outcomes = [];
|
|
27912
|
+
for (const batch of partitionToolCalls(toolUses, deps.tools)) {
|
|
27913
|
+
for (const tu of batch.blocks) {
|
|
27914
|
+
const r = await executeToolUse(tu, assistantMsg, deps);
|
|
27915
|
+
outcomes.push({
|
|
27916
|
+
toolUseId: tu.id,
|
|
27917
|
+
name: tu.name,
|
|
27918
|
+
block: r.block,
|
|
27919
|
+
isError: r.isError,
|
|
27920
|
+
toolUseResult: r.toolUseResult
|
|
27921
|
+
});
|
|
27922
|
+
}
|
|
27923
|
+
}
|
|
27924
|
+
return outcomes;
|
|
27925
|
+
}
|
|
27926
|
+
var init_toolOrchestration = __esm(() => {
|
|
27927
|
+
init_toolExecution();
|
|
27928
|
+
});
|
|
27929
|
+
|
|
27930
|
+
// src/engine/pipeline/index.ts
|
|
27931
|
+
var init_pipeline = __esm(() => {
|
|
27932
|
+
init_toolExecution();
|
|
27933
|
+
init_toolOrchestration();
|
|
27934
|
+
});
|
|
27935
|
+
|
|
27769
27936
|
// node_modules/zod/index.js
|
|
27770
27937
|
var init_zod = __esm(() => {
|
|
27771
27938
|
init_external();
|
|
@@ -76317,7 +76484,7 @@ Important:
|
|
|
76317
76484
|
// src/engine/tools/skill/skillTool.ts
|
|
76318
76485
|
import { randomUUID as randomUUID14 } from "crypto";
|
|
76319
76486
|
async function getAllCommands() {
|
|
76320
|
-
return getCommands(
|
|
76487
|
+
return getCommands(process.cwd());
|
|
76321
76488
|
}
|
|
76322
76489
|
function getToolUseIDFromParentMessage(parentMessage, toolName) {
|
|
76323
76490
|
if (!parentMessage)
|
|
@@ -76388,7 +76555,6 @@ function skillHasOnlySafeProperties(command) {
|
|
|
76388
76555
|
}
|
|
76389
76556
|
var SKILL_TOOL_INPUT_SCHEMA, SAFE_SKILL_PROPERTIES, SkillTool;
|
|
76390
76557
|
var init_skillTool = __esm(() => {
|
|
76391
|
-
init_bootstrap();
|
|
76392
76558
|
init_shared();
|
|
76393
76559
|
init_permissions3();
|
|
76394
76560
|
init_modelprovider2();
|
|
@@ -76455,7 +76621,7 @@ var init_skillTool = __esm(() => {
|
|
|
76455
76621
|
return skill ?? "";
|
|
76456
76622
|
},
|
|
76457
76623
|
async description() {
|
|
76458
|
-
return getSkillPrompt(
|
|
76624
|
+
return getSkillPrompt(process.cwd());
|
|
76459
76625
|
},
|
|
76460
76626
|
async checkPermissions(input, context) {
|
|
76461
76627
|
const { skill, args } = input;
|
|
@@ -80550,7 +80716,9 @@ async function queryOneRound(deps, tools, messages) {
|
|
|
80550
80716
|
fallbackModel: deps.fallbackModel,
|
|
80551
80717
|
options: deps.effortValue !== undefined ? { effortValue: deps.effortValue } : undefined
|
|
80552
80718
|
};
|
|
80553
|
-
let resp = await deps.modelProvider.chat(chatArgs)
|
|
80719
|
+
let resp = await withTurnRecovery(() => deps.modelProvider.chat(chatArgs), {
|
|
80720
|
+
signal: deps.signal
|
|
80721
|
+
});
|
|
80554
80722
|
let assistantContent = resp.message.content ?? [];
|
|
80555
80723
|
const isEmptyContent = (content) => {
|
|
80556
80724
|
if (!Array.isArray(content))
|
|
@@ -80565,7 +80733,9 @@ async function queryOneRound(deps, tools, messages) {
|
|
|
80565
80733
|
});
|
|
80566
80734
|
};
|
|
80567
80735
|
if (isEmptyContent(assistantContent) && !deps.signal?.aborted) {
|
|
80568
|
-
const retried = await deps.modelProvider.chat(chatArgs)
|
|
80736
|
+
const retried = await withTurnRecovery(() => deps.modelProvider.chat(chatArgs), {
|
|
80737
|
+
signal: deps.signal
|
|
80738
|
+
});
|
|
80569
80739
|
const retriedContent = retried.message.content ?? [];
|
|
80570
80740
|
if (!isEmptyContent(retriedContent)) {
|
|
80571
80741
|
resp = retried;
|
|
@@ -80697,6 +80867,7 @@ async function queryAgentLoop(deps, args) {
|
|
|
80697
80867
|
var DEFAULT_AGENT_LOOP_MAX_TURNS = 20;
|
|
80698
80868
|
var init_loop = __esm(() => {
|
|
80699
80869
|
init_shared();
|
|
80870
|
+
init_turnRecovery();
|
|
80700
80871
|
init_pipeline();
|
|
80701
80872
|
init_context();
|
|
80702
80873
|
});
|
|
@@ -80717,6 +80888,7 @@ var init_QueryEngine = __esm(() => {
|
|
|
80717
80888
|
// src/engine/query/index.ts
|
|
80718
80889
|
var init_query2 = __esm(() => {
|
|
80719
80890
|
init_loop();
|
|
80891
|
+
init_turnRecovery();
|
|
80720
80892
|
init_QueryEngine();
|
|
80721
80893
|
});
|
|
80722
80894
|
|
|
@@ -121613,6 +121785,7 @@ var isMcpServerCommandEntry = () => ({}), isMcpServerNameEntry = () => ({}), isM
|
|
|
121613
121785
|
object({ kind: literal("window"), tokens: number2().int().min(1000) }),
|
|
121614
121786
|
object({ kind: literal("pct"), pct: number2().min(1).max(100) })
|
|
121615
121787
|
]).optional(),
|
|
121788
|
+
llmTimeoutMs: number2().int().positive().optional(),
|
|
121616
121789
|
prefersReducedMotion: boolean2().optional(),
|
|
121617
121790
|
syntaxHighlightingDisabled: boolean2().optional(),
|
|
121618
121791
|
spinnerTipsEnabled: boolean2().optional(),
|
|
@@ -148277,28 +148450,28 @@ function getEventPriority(eventType) {
|
|
|
148277
148450
|
case "focus":
|
|
148278
148451
|
case "blur":
|
|
148279
148452
|
case "paste":
|
|
148280
|
-
return
|
|
148453
|
+
return import_constants53.DiscreteEventPriority;
|
|
148281
148454
|
case "resize":
|
|
148282
148455
|
case "scroll":
|
|
148283
148456
|
case "mousemove":
|
|
148284
|
-
return
|
|
148457
|
+
return import_constants53.ContinuousEventPriority;
|
|
148285
148458
|
default:
|
|
148286
|
-
return
|
|
148459
|
+
return import_constants53.DefaultEventPriority;
|
|
148287
148460
|
}
|
|
148288
148461
|
}
|
|
148289
148462
|
|
|
148290
148463
|
class Dispatcher {
|
|
148291
148464
|
currentEvent = null;
|
|
148292
|
-
currentUpdatePriority =
|
|
148465
|
+
currentUpdatePriority = import_constants53.DefaultEventPriority;
|
|
148293
148466
|
discreteUpdates = null;
|
|
148294
148467
|
resolveEventPriority() {
|
|
148295
|
-
if (this.currentUpdatePriority !==
|
|
148468
|
+
if (this.currentUpdatePriority !== import_constants53.NoEventPriority) {
|
|
148296
148469
|
return this.currentUpdatePriority;
|
|
148297
148470
|
}
|
|
148298
148471
|
if (this.currentEvent) {
|
|
148299
148472
|
return getEventPriority(this.currentEvent.type);
|
|
148300
148473
|
}
|
|
148301
|
-
return
|
|
148474
|
+
return import_constants53.DefaultEventPriority;
|
|
148302
148475
|
}
|
|
148303
148476
|
dispatch(target, event) {
|
|
148304
148477
|
const previousEvent = this.currentEvent;
|
|
@@ -148323,18 +148496,18 @@ class Dispatcher {
|
|
|
148323
148496
|
dispatchContinuous(target, event) {
|
|
148324
148497
|
const previousPriority = this.currentUpdatePriority;
|
|
148325
148498
|
try {
|
|
148326
|
-
this.currentUpdatePriority =
|
|
148499
|
+
this.currentUpdatePriority = import_constants53.ContinuousEventPriority;
|
|
148327
148500
|
return this.dispatch(target, event);
|
|
148328
148501
|
} finally {
|
|
148329
148502
|
this.currentUpdatePriority = previousPriority;
|
|
148330
148503
|
}
|
|
148331
148504
|
}
|
|
148332
148505
|
}
|
|
148333
|
-
var
|
|
148506
|
+
var import_constants53;
|
|
148334
148507
|
var init_dispatcher = __esm(() => {
|
|
148335
148508
|
init_log5();
|
|
148336
148509
|
init_event_handlers();
|
|
148337
|
-
|
|
148510
|
+
import_constants53 = __toESM(require_constants2(), 1);
|
|
148338
148511
|
});
|
|
148339
148512
|
|
|
148340
148513
|
// src/tui/ink/events/terminal-event.ts
|
|
@@ -157141,7 +157314,7 @@ function applyPositionedHighlight(screen, stylePool, positions, rowOffset, curre
|
|
|
157141
157314
|
}
|
|
157142
157315
|
return true;
|
|
157143
157316
|
}
|
|
157144
|
-
var
|
|
157317
|
+
var import_constants55, timing;
|
|
157145
157318
|
var init_render_to_screen = __esm(() => {
|
|
157146
157319
|
init_debug();
|
|
157147
157320
|
init_dom();
|
|
@@ -157150,7 +157323,7 @@ var init_render_to_screen = __esm(() => {
|
|
|
157150
157323
|
init_reconciler();
|
|
157151
157324
|
init_render_node_to_output();
|
|
157152
157325
|
init_screen();
|
|
157153
|
-
|
|
157326
|
+
import_constants55 = __toESM(require_constants2(), 1);
|
|
157154
157327
|
timing = { reconcile: 0, yoga: 0, paint: 0, scan: 0, calls: 0 };
|
|
157155
157328
|
});
|
|
157156
157329
|
|
|
@@ -157456,7 +157629,7 @@ class Ink {
|
|
|
157456
157629
|
};
|
|
157457
157630
|
}
|
|
157458
157631
|
};
|
|
157459
|
-
this.container = reconciler_default.createContainer(this.rootNode,
|
|
157632
|
+
this.container = reconciler_default.createContainer(this.rootNode, import_constants56.ConcurrentRoot, null, false, null, "id", noop_default, noop_default, noop_default, noop_default);
|
|
157460
157633
|
if (false) {}
|
|
157461
157634
|
}
|
|
157462
157635
|
handleResume = () => {
|
|
@@ -158269,7 +158442,7 @@ function drainStdin(stdin = process.stdin) {
|
|
|
158269
158442
|
}
|
|
158270
158443
|
}
|
|
158271
158444
|
}
|
|
158272
|
-
var
|
|
158445
|
+
var import_constants56, jsx_dev_runtime8, ALT_SCREEN_ANCHOR_CURSOR, CURSOR_HOME_PATCH, ERASE_THEN_HOME_PATCH, CONSOLE_STDOUT_METHODS, CONSOLE_STDERR_METHODS;
|
|
158273
158446
|
var init_ink = __esm(() => {
|
|
158274
158447
|
init_noop();
|
|
158275
158448
|
init_throttle2();
|
|
@@ -158302,7 +158475,7 @@ var init_ink = __esm(() => {
|
|
|
158302
158475
|
init_dec();
|
|
158303
158476
|
init_osc();
|
|
158304
158477
|
init_useTerminalNotification();
|
|
158305
|
-
|
|
158478
|
+
import_constants56 = __toESM(require_constants2(), 1);
|
|
158306
158479
|
jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
|
|
158307
158480
|
ALT_SCREEN_ANCHOR_CURSOR = Object.freeze({
|
|
158308
158481
|
x: 0,
|
|
@@ -203040,7 +203213,7 @@ var init_drainRunLoop = __esm(() => {
|
|
|
203040
203213
|
|
|
203041
203214
|
// src/tui/utils/computerUse/escHotkey.ts
|
|
203042
203215
|
function registerEscHotkey(onEscape) {
|
|
203043
|
-
if (
|
|
203216
|
+
if (registered2)
|
|
203044
203217
|
return true;
|
|
203045
203218
|
const cu = requireComputerUseSwift();
|
|
203046
203219
|
if (!cu.hotkey.registerEscape(onEscape)) {
|
|
@@ -203048,16 +203221,16 @@ function registerEscHotkey(onEscape) {
|
|
|
203048
203221
|
return false;
|
|
203049
203222
|
}
|
|
203050
203223
|
retainPump();
|
|
203051
|
-
|
|
203224
|
+
registered2 = true;
|
|
203052
203225
|
logForDebugging3("[cu-esc] registered");
|
|
203053
203226
|
return true;
|
|
203054
203227
|
}
|
|
203055
203228
|
function notifyExpectedEscape() {
|
|
203056
|
-
if (!
|
|
203229
|
+
if (!registered2)
|
|
203057
203230
|
return;
|
|
203058
203231
|
requireComputerUseSwift().hotkey.notifyExpectedEscape();
|
|
203059
203232
|
}
|
|
203060
|
-
var
|
|
203233
|
+
var registered2 = false;
|
|
203061
203234
|
var init_escHotkey = __esm(() => {
|
|
203062
203235
|
init_debug();
|
|
203063
203236
|
init_drainRunLoop();
|
|
@@ -271660,7 +271833,7 @@ async function* runAgent2({
|
|
|
271660
271833
|
}
|
|
271661
271834
|
const skillsToPreload = agentDefinition.skills ?? [];
|
|
271662
271835
|
if (skillsToPreload.length > 0) {
|
|
271663
|
-
const allSkills = await getSkillToolCommands2(
|
|
271836
|
+
const allSkills = await getSkillToolCommands2(process.cwd());
|
|
271664
271837
|
const validSkills = [];
|
|
271665
271838
|
for (const skillName of skillsToPreload) {
|
|
271666
271839
|
const resolvedName = resolveSkillName(skillName, allSkills, agentDefinition);
|
|
@@ -272269,9 +272442,9 @@ function getDefaultMaxRetries() {
|
|
|
272269
272442
|
if (process.env.ATLAS_MAX_RETRIES) {
|
|
272270
272443
|
return parseInt(process.env.ATLAS_MAX_RETRIES || "", 10);
|
|
272271
272444
|
}
|
|
272272
|
-
return
|
|
272445
|
+
return DEFAULT_MAX_RETRIES2;
|
|
272273
272446
|
}
|
|
272274
|
-
var
|
|
272447
|
+
var DEFAULT_MAX_RETRIES2 = 10, BASE_DELAY_MS = 500, FOREGROUND_529_RETRY_SOURCES, PERSISTENT_MAX_BACKOFF_MS, PERSISTENT_RESET_CAP_MS;
|
|
272275
272448
|
var init_withRetry = __esm(() => {
|
|
272276
272449
|
init_shared();
|
|
272277
272450
|
init_atlas();
|
|
@@ -274526,8 +274699,8 @@ var init_UI10 = __esm(() => {
|
|
|
274526
274699
|
async function getAllCommands2(context) {
|
|
274527
274700
|
const mcpSkills = context.getAppState().mcp.commands.filter((cmd) => cmd.type === "prompt" && cmd.loadedFrom === "mcp");
|
|
274528
274701
|
if (mcpSkills.length === 0)
|
|
274529
|
-
return getCommands2(
|
|
274530
|
-
const localCommands = await getCommands2(
|
|
274702
|
+
return getCommands2(process.cwd());
|
|
274703
|
+
const localCommands = await getCommands2(process.cwd());
|
|
274531
274704
|
return uniqBy_default([...localCommands, ...mcpSkills], "name");
|
|
274532
274705
|
}
|
|
274533
274706
|
async function executeForkedSkill2(command, commandName, args, context, canUseTool, parentMessage, onProgress) {
|
|
@@ -274623,7 +274796,6 @@ function isOfficialMarketplaceSkill(command) {
|
|
|
274623
274796
|
var inputSchema14, outputSchema12, SkillTool2, SAFE_SKILL_PROPERTIES2;
|
|
274624
274797
|
var init_SkillTool = __esm(() => {
|
|
274625
274798
|
init_uniqBy();
|
|
274626
|
-
init_bootstrap();
|
|
274627
274799
|
init_commands5();
|
|
274628
274800
|
init_Tool();
|
|
274629
274801
|
init_debug();
|
|
@@ -274673,7 +274845,7 @@ var init_SkillTool = __esm(() => {
|
|
|
274673
274845
|
return outputSchema12();
|
|
274674
274846
|
},
|
|
274675
274847
|
description: async ({ skill }) => `Execute skill: ${skill}`,
|
|
274676
|
-
prompt: async () => getPrompt20(
|
|
274848
|
+
prompt: async () => getPrompt20(process.cwd()),
|
|
274677
274849
|
toAutoClassifierInput: ({ skill }) => skill ?? "",
|
|
274678
274850
|
async validateInput({ skill }, context) {
|
|
274679
274851
|
const trimmed = skill.trim();
|
|
@@ -430263,6 +430435,7 @@ function wireContextHostPorts() {
|
|
|
430263
430435
|
});
|
|
430264
430436
|
setAutoCompactSettingsSource(() => getGlobalConfig().autoCompactEnabled);
|
|
430265
430437
|
setAutoCompactWindowSettingsSource(() => getInitialSettings2().autoCompactWindow);
|
|
430438
|
+
setLlmTimeoutSettingsSource(() => getInitialSettings2().llmTimeoutMs);
|
|
430266
430439
|
setTimeBasedMCConfigSource(() => getFeatureValue_CACHED_MAY_BE_STALE("atlas_slate_heron", TIME_BASED_MC_CONFIG_DEFAULTS));
|
|
430267
430440
|
clearPostCompactResetsForTesting();
|
|
430268
430441
|
if (feature("CONTEXT_COLLAPSE")) {
|
|
@@ -430291,6 +430464,7 @@ function wireContextHostPorts() {
|
|
|
430291
430464
|
}
|
|
430292
430465
|
var init_contextHostWiring = __esm(() => {
|
|
430293
430466
|
init_shared();
|
|
430467
|
+
init_modelprovider2();
|
|
430294
430468
|
init_engine();
|
|
430295
430469
|
init_config6();
|
|
430296
430470
|
init_settings3();
|
|
@@ -475922,7 +476096,8 @@ Error: sandbox required but unavailable: ${reason}
|
|
|
475922
476096
|
await onQueryImpl(latestMessages, newMessages, abortController, shouldQuery, additionalAllowedTools, mainLoopModelParam, effort);
|
|
475923
476097
|
} catch (error) {
|
|
475924
476098
|
logError3(error);
|
|
475925
|
-
|
|
476099
|
+
const llmTimeoutHint = llmTimeoutRemediationHint(error, getCurrentLlmTimeoutMs());
|
|
476100
|
+
setMessages((prev) => [...prev, createSystemMessage(`本轮执行出错:${errorMessage2(error)}。${llmTimeoutHint ? `${llmTimeoutHint} ` : ""}请重试。`, "error")]);
|
|
475926
476101
|
} finally {
|
|
475927
476102
|
if (queryGuard.end(thisGeneration)) {
|
|
475928
476103
|
setLastQueryCompletionTime(Date.now());
|
|
@@ -477601,6 +477776,7 @@ Note: ctrl + z now suspends AtlasHarness, ctrl + _ undoes input.
|
|
|
477601
477776
|
var import_compiler_runtime323, React137, import_react280, jsx_dev_runtime427, UltraplanChoiceDialog = () => null, UltraplanLaunchDialog = () => null, launchUltraplan2 = null, useVoiceIntegration2, VoiceKeybindingHandler2, useAntOrgWarningNotification = () => {}, getCoordinatorUserContext3, SUGGEST_BG_PR_NOOP = (_p, _n) => false, useScheduledTasks2, EMPTY_MCP_CLIENTS2, RECENT_SCROLL_REPIN_WINDOW_MS = 3000, TITLE_ANIMATION_FRAMES, TITLE_STATIC_PREFIX = "✳", TITLE_ANIMATION_INTERVAL_MS = 960;
|
|
477602
477777
|
var init_REPL = __esm(() => {
|
|
477603
477778
|
init_shared();
|
|
477779
|
+
init_modelprovider2();
|
|
477604
477780
|
init_bootstrap();
|
|
477605
477781
|
init_bootstrapState();
|
|
477606
477782
|
init_tokenBudget();
|
|
@@ -490824,6 +491000,14 @@ function createCoreDependencies() {
|
|
|
490824
491000
|
return;
|
|
490825
491001
|
}
|
|
490826
491002
|
});
|
|
491003
|
+
setLlmTimeoutSettingsSource(() => {
|
|
491004
|
+
try {
|
|
491005
|
+
const v = getInitialSettings().llmTimeoutMs;
|
|
491006
|
+
return typeof v === "number" ? v : undefined;
|
|
491007
|
+
} catch {
|
|
491008
|
+
return;
|
|
491009
|
+
}
|
|
491010
|
+
});
|
|
490827
491011
|
return {
|
|
490828
491012
|
sandboxManager,
|
|
490829
491013
|
modelProvider: getModelProvider(),
|
|
@@ -493912,6 +494096,11 @@ async function binMain() {
|
|
|
493912
494096
|
await main2();
|
|
493913
494097
|
return;
|
|
493914
494098
|
}
|
|
494099
|
+
registerGlobalCrashBackstop();
|
|
494100
|
+
if (process.env.ATLAS_TEST_CRASH_BACKSTOP === "1") {
|
|
494101
|
+
process.emit("uncaughtException", new Error("atlas crash-backstop live probe"));
|
|
494102
|
+
process.exit(0);
|
|
494103
|
+
}
|
|
493915
494104
|
getCoreDependencies();
|
|
493916
494105
|
await main();
|
|
493917
494106
|
}
|
package/package.json
CHANGED