@atlasharness/atlascode 0.1.63 → 0.1.65
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 +221 -39
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -26901,7 +26901,39 @@ function llmTimeoutRemediationHint(error, currentTimeoutMs) {
|
|
|
26901
26901
|
const head = typeof currentTimeoutMs === "number" && currentTimeoutMs > 0 ? `当前超时 ${Math.round(currentTimeoutMs / 1000)}s` : "慢模型长生成可能超过缺省超时";
|
|
26902
26902
|
return `LLM 请求超时(${head})。可调大:env ATLAS_LLM_TIMEOUT=<毫秒> 或 settings.json llmTimeoutMs 键(上限 ${Math.round(LLM_TIMEOUT_CAP_MS / 60000)}min)。`;
|
|
26903
26903
|
}
|
|
26904
|
-
function
|
|
26904
|
+
function describeEndpointFailure(baseURL) {
|
|
26905
|
+
if (!baseURL)
|
|
26906
|
+
return "LLM 端点";
|
|
26907
|
+
let host;
|
|
26908
|
+
let port;
|
|
26909
|
+
try {
|
|
26910
|
+
const u = new URL(baseURL);
|
|
26911
|
+
host = u.hostname;
|
|
26912
|
+
port = u.port;
|
|
26913
|
+
} catch {
|
|
26914
|
+
return "LLM 端点";
|
|
26915
|
+
}
|
|
26916
|
+
if (host === "localhost" || host === "0.0.0.0" || host === "[::1]" || host.startsWith("127.")) {
|
|
26917
|
+
return port ? `本地端口 ${port}` : "本地网关";
|
|
26918
|
+
}
|
|
26919
|
+
const knownProviders = [
|
|
26920
|
+
[/api\.deepseek\.com$/i, "DeepSeek"],
|
|
26921
|
+
[/api\.openai\.com$/i, "OpenAI"],
|
|
26922
|
+
[/^(dashscope|api)\.aliyuncs\.com$/i, "阿里百炼"],
|
|
26923
|
+
[/api\.moonshot\.cn$/i, "Kimi"],
|
|
26924
|
+
[/api\.minimax\.chat$/i, "MiniMax"],
|
|
26925
|
+
[/api\.baichuan-ai\.com$/i, "百川"],
|
|
26926
|
+
[/api\.01\.ai$/i, "零一万物"],
|
|
26927
|
+
[/api\.siliconflow\.cn$/i, "硅基流动"],
|
|
26928
|
+
[/api\.lkeap\.com$/i, "腾讯混元"]
|
|
26929
|
+
];
|
|
26930
|
+
for (const [re, name] of knownProviders) {
|
|
26931
|
+
if (re.test(host))
|
|
26932
|
+
return `${name} 服务`;
|
|
26933
|
+
}
|
|
26934
|
+
return host;
|
|
26935
|
+
}
|
|
26936
|
+
function gatewayUnreachableRemediationHint(error, endpointLabel) {
|
|
26905
26937
|
if (!error || typeof error !== "object")
|
|
26906
26938
|
return null;
|
|
26907
26939
|
const e = error;
|
|
@@ -26918,7 +26950,7 @@ function gatewayUnreachableRemediationHint(error) {
|
|
|
26918
26950
|
const isNetworkErrno = /ECONNREFUSED|ECONNRESET|ENOTFOUND|ENETUNREACH|EHOSTUNREACH|EAI_AGAIN|fetch failed|socket hang up/i.test(haystack);
|
|
26919
26951
|
if (!isSdkConnection && !isNetworkErrno)
|
|
26920
26952
|
return null;
|
|
26921
|
-
return "
|
|
26953
|
+
return `${endpointLabel ?? "LLM 端点"} 不可达:已切人工确认 —— /doctor 排查`;
|
|
26922
26954
|
}
|
|
26923
26955
|
function modelRetryBackoffMs(attempt, baseMs = MODEL_RETRY_BACKOFF_BASE_MS, capMs = MODEL_RETRY_BACKOFF_CAP_MS) {
|
|
26924
26956
|
const base = Math.max(0, baseMs);
|
|
@@ -27824,6 +27856,18 @@ function setLlmTimeoutSettingsSource(next) {
|
|
|
27824
27856
|
function getCurrentLlmTimeoutMs() {
|
|
27825
27857
|
return resolveLlmTimeoutMs(process.env.ATLAS_LLM_TIMEOUT, llmTimeoutSettingsSource?.());
|
|
27826
27858
|
}
|
|
27859
|
+
function getCurrentEndpointLabel(modelRef) {
|
|
27860
|
+
let baseURL;
|
|
27861
|
+
if (modelRef) {
|
|
27862
|
+
const resolved = resolveModel(modelRef);
|
|
27863
|
+
if (resolved?.baseURL)
|
|
27864
|
+
baseURL = resolved.baseURL;
|
|
27865
|
+
}
|
|
27866
|
+
if (!baseURL) {
|
|
27867
|
+
baseURL = getRoleConfig("small").baseURL;
|
|
27868
|
+
}
|
|
27869
|
+
return describeEndpointFailure(baseURL);
|
|
27870
|
+
}
|
|
27827
27871
|
function resolveLlmTimeoutMs(envRaw = process.env.ATLAS_LLM_TIMEOUT, settingsMs) {
|
|
27828
27872
|
const fromSettings = () => typeof settingsMs === "number" && Number.isInteger(settingsMs) && settingsMs >= 1 ? Math.min(settingsMs, LLM_TIMEOUT_CAP_MS) : LLM_TIMEOUT_DEFAULT_MS;
|
|
27829
27873
|
if (envRaw === undefined || envRaw === "")
|
|
@@ -27847,6 +27891,7 @@ var init_modelprovider2 = __esm(() => {
|
|
|
27847
27891
|
init_modelprovider();
|
|
27848
27892
|
init_constants2();
|
|
27849
27893
|
init_shared();
|
|
27894
|
+
init_roles7();
|
|
27850
27895
|
init_constants2();
|
|
27851
27896
|
init_modelprovider();
|
|
27852
27897
|
init_types2();
|
|
@@ -37047,9 +37092,9 @@ function formatAgentLine(agent) {
|
|
|
37047
37092
|
function getPrompt(agents) {
|
|
37048
37093
|
const list = agents.length > 0 ? agents.map(formatAgentLine).join(`
|
|
37049
37094
|
`) : "- general-purpose: General-purpose agent for researching and executing multi-step tasks.";
|
|
37050
|
-
return "Launch a subagent to run a self-contained task in an isolated context. " + "Provide a short description (3-5 words) and a fully self-contained prompt " + "(the subagent cannot see this conversation). " + "Be cost-aware about delegating: prefer to do the work inline in this " + "conversation for a small task with a known, bounded target (a single-file " + "edit, a quick lookup, a change you can finish without broad exploration) — " + "spawning a subagent has overhead. Delegate when the task is genuinely " + "parallelizable or would otherwise flood this context with material you do " + "not need to keep (a broad multi-file search, an isolated multi-step " + "implementation, or independent work that can run alongside your own). Keep " + "each delegated brief narrow and evidence-focused: name the exact goal, the " + "files or area, and the expected deliverable rather than a broad " + '"figure this out." Because the subagent cannot see this conversation, its ' + "prompt must be fully self-contained — state every constraint, file, and " + "reporting requirement it needs. " + `Available agent types and the tools they have access to:
|
|
37095
|
+
return "Launch a subagent to run a self-contained task in an isolated context. " + "Provide a short description (3-5 words) and a fully self-contained prompt " + "(the subagent cannot see this conversation). " + "Be cost-aware about delegating: prefer to do the work inline in this " + "conversation for a small task with a known, bounded target (a single-file " + "edit, a quick lookup, a change you can finish without broad exploration) — " + "spawning a subagent has overhead. Delegate when the task is genuinely " + "parallelizable or would otherwise flood this context with material you do " + "not need to keep (a broad multi-file search, an isolated multi-step " + "implementation, or independent work that can run alongside your own). Keep " + "each delegated brief narrow and evidence-focused: name the exact goal, the " + "files or area, and the expected deliverable rather than a broad " + '"figure this out." Because the subagent cannot see this conversation, its ' + "prompt must be fully self-contained — state every constraint, file, and " + "reporting requirement it needs. " + "Set run_in_background to true to launch a subagent that runs while you " + "continue working in this conversation; you will receive a task-notification " + "when it completes. Use this only for genuinely parallel work, not to defer " + "a result you need before you can proceed. " + `Available agent types and the tools they have access to:
|
|
37051
37096
|
${list}
|
|
37052
|
-
` + `The ${AGENT_TOOL_NAME} tool runs the subagent and returns its final result ` + "when it completes; act on that result once it is returned.";
|
|
37097
|
+
` + `The ${AGENT_TOOL_NAME} tool runs the subagent and returns its final result ` + "when it completes; act on that result once it is returned. " + "Do not predict or assume what the subagent will find — wait for its " + "returned result and act on what it actually reports.";
|
|
37053
37098
|
}
|
|
37054
37099
|
var init_prompt = () => {};
|
|
37055
37100
|
|
|
@@ -37091,9 +37136,72 @@ async function runAgent(args) {
|
|
|
37091
37136
|
turns: loopResult.turns
|
|
37092
37137
|
};
|
|
37093
37138
|
}
|
|
37139
|
+
function wrapPermissionGateForBackground(gate, onNeedsInput) {
|
|
37140
|
+
if (!gate)
|
|
37141
|
+
return;
|
|
37142
|
+
return async (tool, input, callContext) => {
|
|
37143
|
+
const verdict = await gate(tool, input, callContext);
|
|
37144
|
+
if (verdict.ask) {
|
|
37145
|
+
onNeedsInput({
|
|
37146
|
+
toolName: tool.name,
|
|
37147
|
+
reason: verdict.reason
|
|
37148
|
+
});
|
|
37149
|
+
}
|
|
37150
|
+
return verdict;
|
|
37151
|
+
};
|
|
37152
|
+
}
|
|
37153
|
+
async function runAsyncAgentLifecycle(args) {
|
|
37154
|
+
const { description, toolUseId, signal, agentId } = args;
|
|
37155
|
+
const wrappedCheckPermission = wrapPermissionGateForBackground(args.checkPermission, (req) => {
|
|
37156
|
+
enqueueAgentNotification({
|
|
37157
|
+
taskId: agentId,
|
|
37158
|
+
description,
|
|
37159
|
+
status: "needs_input",
|
|
37160
|
+
inputRequest: `Permission required for ${req.toolName}${req.reason ? `: ${req.reason}` : ""}`,
|
|
37161
|
+
...toolUseId ? { toolUseId } : {}
|
|
37162
|
+
});
|
|
37163
|
+
});
|
|
37164
|
+
try {
|
|
37165
|
+
const { result } = await runAgent({
|
|
37166
|
+
...args,
|
|
37167
|
+
checkPermission: wrappedCheckPermission
|
|
37168
|
+
});
|
|
37169
|
+
const finalMessage = result.content.map((b) => b.text).join("");
|
|
37170
|
+
enqueueAgentNotification({
|
|
37171
|
+
taskId: agentId,
|
|
37172
|
+
description,
|
|
37173
|
+
status: "completed",
|
|
37174
|
+
finalMessage: finalMessage || undefined,
|
|
37175
|
+
usage: {
|
|
37176
|
+
totalTokens: result.totalTokens,
|
|
37177
|
+
toolUses: result.totalToolUseCount,
|
|
37178
|
+
durationMs: result.totalDurationMs
|
|
37179
|
+
},
|
|
37180
|
+
...toolUseId ? { toolUseId } : {}
|
|
37181
|
+
});
|
|
37182
|
+
} catch (err) {
|
|
37183
|
+
if (signal?.aborted) {
|
|
37184
|
+
enqueueAgentNotification({
|
|
37185
|
+
taskId: agentId,
|
|
37186
|
+
description,
|
|
37187
|
+
status: "killed",
|
|
37188
|
+
...toolUseId ? { toolUseId } : {}
|
|
37189
|
+
});
|
|
37190
|
+
return;
|
|
37191
|
+
}
|
|
37192
|
+
enqueueAgentNotification({
|
|
37193
|
+
taskId: agentId,
|
|
37194
|
+
description,
|
|
37195
|
+
status: "failed",
|
|
37196
|
+
error: err instanceof Error ? err.message : String(err),
|
|
37197
|
+
...toolUseId ? { toolUseId } : {}
|
|
37198
|
+
});
|
|
37199
|
+
}
|
|
37200
|
+
}
|
|
37094
37201
|
var init_runAgent = __esm(() => {
|
|
37095
37202
|
init_query2();
|
|
37096
37203
|
init_agentToolUtils();
|
|
37204
|
+
init_localAgentTask();
|
|
37097
37205
|
});
|
|
37098
37206
|
|
|
37099
37207
|
// src/engine/tools/agent/AgentTool.ts
|
|
@@ -37119,6 +37227,8 @@ var init_AgentTool = __esm(() => {
|
|
|
37119
37227
|
init_prompt();
|
|
37120
37228
|
init_runAgent();
|
|
37121
37229
|
init_coordinator();
|
|
37230
|
+
init_task2();
|
|
37231
|
+
init_localAgentTask();
|
|
37122
37232
|
AGENT_TOOL_INPUT_SCHEMA = {
|
|
37123
37233
|
type: "object",
|
|
37124
37234
|
properties: {
|
|
@@ -37137,6 +37247,10 @@ var init_AgentTool = __esm(() => {
|
|
|
37137
37247
|
model: {
|
|
37138
37248
|
enum: ["small", "premium", "fast"],
|
|
37139
37249
|
description: "Optional model override for this agent. Takes precedence over the agent definition's model. If omitted, inherits from the parent."
|
|
37250
|
+
},
|
|
37251
|
+
run_in_background: {
|
|
37252
|
+
type: "boolean",
|
|
37253
|
+
description: "Set to true to run this agent in the background. You will be notified when it completes."
|
|
37140
37254
|
}
|
|
37141
37255
|
},
|
|
37142
37256
|
required: ["description", "prompt"]
|
|
@@ -37173,6 +37287,13 @@ var init_AgentTool = __esm(() => {
|
|
|
37173
37287
|
` + text
|
|
37174
37288
|
};
|
|
37175
37289
|
}
|
|
37290
|
+
if (c && c.status === "async_launched") {
|
|
37291
|
+
return {
|
|
37292
|
+
type: "tool_result",
|
|
37293
|
+
tool_use_id: toolUseID,
|
|
37294
|
+
content: "[agent launched in background] agentId=" + (c.agentId ?? "") + " output=" + (c.outputFile ?? "")
|
|
37295
|
+
};
|
|
37296
|
+
}
|
|
37176
37297
|
return {
|
|
37177
37298
|
type: "tool_result",
|
|
37178
37299
|
tool_use_id: toolUseID,
|
|
@@ -37190,6 +37311,38 @@ var init_AgentTool = __esm(() => {
|
|
|
37190
37311
|
const allowFanOut = isCoordinatorMode() && childSpawnDepth < MAX_WORKER_SPAWN_DEPTH;
|
|
37191
37312
|
const resolvedTools = resolveAgentTools(agentDefinition, availableTools, allowFanOut).resolvedTools;
|
|
37192
37313
|
const agentId = "agent-" + randomUUID5();
|
|
37314
|
+
if (input.run_in_background) {
|
|
37315
|
+
const outputFile = getTaskOutputPath(agentId);
|
|
37316
|
+
runAsyncAgentLifecycle({
|
|
37317
|
+
agentDefinition,
|
|
37318
|
+
prompt: input.prompt,
|
|
37319
|
+
tools: resolvedTools,
|
|
37320
|
+
modelProvider,
|
|
37321
|
+
parentRole,
|
|
37322
|
+
overrideRole: input.model,
|
|
37323
|
+
agentId,
|
|
37324
|
+
spawnDepth: childSpawnDepth,
|
|
37325
|
+
signal: ctx.signal,
|
|
37326
|
+
checkPermission: ctx.checkPermission,
|
|
37327
|
+
description: input.description
|
|
37328
|
+
}).catch((err) => {
|
|
37329
|
+
enqueueAgentNotification({
|
|
37330
|
+
taskId: agentId,
|
|
37331
|
+
description: input.description,
|
|
37332
|
+
status: "failed",
|
|
37333
|
+
error: err instanceof Error ? err.message : String(err)
|
|
37334
|
+
});
|
|
37335
|
+
});
|
|
37336
|
+
return {
|
|
37337
|
+
data: {
|
|
37338
|
+
status: "async_launched",
|
|
37339
|
+
agentId,
|
|
37340
|
+
description: input.description,
|
|
37341
|
+
prompt: input.prompt,
|
|
37342
|
+
outputFile
|
|
37343
|
+
}
|
|
37344
|
+
};
|
|
37345
|
+
}
|
|
37193
37346
|
const { result } = await runAgent({
|
|
37194
37347
|
agentDefinition,
|
|
37195
37348
|
prompt: input.prompt,
|
|
@@ -79576,24 +79729,27 @@ function enqueueAgentNotification({
|
|
|
79576
79729
|
usage,
|
|
79577
79730
|
toolUseId,
|
|
79578
79731
|
worktreePath,
|
|
79579
|
-
worktreeBranch
|
|
79732
|
+
worktreeBranch,
|
|
79733
|
+
inputRequest
|
|
79580
79734
|
}) {
|
|
79581
|
-
|
|
79582
|
-
|
|
79583
|
-
|
|
79584
|
-
|
|
79735
|
+
if (setAppState && status !== "needs_input") {
|
|
79736
|
+
let shouldEnqueue = false;
|
|
79737
|
+
updateTaskState(taskId, setAppState, (task) => {
|
|
79738
|
+
if (task.notified) {
|
|
79739
|
+
return task;
|
|
79740
|
+
}
|
|
79741
|
+
shouldEnqueue = true;
|
|
79742
|
+
return {
|
|
79743
|
+
...task,
|
|
79744
|
+
notified: true
|
|
79745
|
+
};
|
|
79746
|
+
});
|
|
79747
|
+
if (!shouldEnqueue) {
|
|
79748
|
+
return;
|
|
79585
79749
|
}
|
|
79586
|
-
shouldEnqueue = true;
|
|
79587
|
-
return {
|
|
79588
|
-
...task,
|
|
79589
|
-
notified: true
|
|
79590
|
-
};
|
|
79591
|
-
});
|
|
79592
|
-
if (!shouldEnqueue) {
|
|
79593
|
-
return;
|
|
79594
79750
|
}
|
|
79595
79751
|
const escapedDescription = escapeXml(description);
|
|
79596
|
-
const summary = status === "completed" ? `Agent "${escapedDescription}" completed` : status === "failed" ? `Agent "${escapedDescription}" failed: ${escapeXml(error || "Unknown error")}` : `Agent "${escapedDescription}" was stopped`;
|
|
79752
|
+
const summary = status === "completed" ? `Agent "${escapedDescription}" completed` : status === "failed" ? `Agent "${escapedDescription}" failed: ${escapeXml(error || "Unknown error")}` : status === "killed" ? `Agent "${escapedDescription}" was stopped` : status === "needs_input" ? `Agent "${escapedDescription}" needs input: ${escapeXml(inputRequest || "Permission request or question pending")}` : `Agent "${escapedDescription}" ${escapeXml(status)}`;
|
|
79597
79753
|
const outputPath = getTaskOutputPath(taskId);
|
|
79598
79754
|
const toolUseIdLine = toolUseId ? `
|
|
79599
79755
|
<${TOOL_USE_ID_TAG}>${escapeXml(toolUseId)}</${TOOL_USE_ID_TAG}>` : "";
|
|
@@ -180576,6 +180732,7 @@ __export(exports_engineCompat, {
|
|
|
180576
180732
|
roughTokenCountEstimationForContent: () => roughTokenCountEstimationForContent,
|
|
180577
180733
|
roughTokenCountEstimationForMessages: () => roughTokenCountEstimationForMessages,
|
|
180578
180734
|
runAgent: () => runAgent,
|
|
180735
|
+
runAsyncAgentLifecycle: () => runAsyncAgentLifecycle,
|
|
180579
180736
|
runCleanupFunctions: () => runCleanupFunctions2,
|
|
180580
180737
|
runHooksStream: () => runHooksStream,
|
|
180581
180738
|
runPostCompactCleanup: () => runPostCompactCleanup,
|
|
@@ -180667,6 +180824,7 @@ __export(exports_engineCompat, {
|
|
|
180667
180824
|
waitForSessionMemoryExtraction: () => waitForSessionMemoryExtraction,
|
|
180668
180825
|
waitForTeammatesToBecomeIdle: () => waitForTeammatesToBecomeIdle,
|
|
180669
180826
|
worktreeBranchName: () => worktreeBranchName,
|
|
180827
|
+
wrapPermissionGateForBackground: () => wrapPermissionGateForBackground,
|
|
180670
180828
|
writeCronTasks: () => writeCronTasks,
|
|
180671
180829
|
writeToMailbox: () => writeToMailbox
|
|
180672
180830
|
});
|
|
@@ -275816,7 +275974,7 @@ function extractPartialResult(messages) {
|
|
|
275816
275974
|
}
|
|
275817
275975
|
return;
|
|
275818
275976
|
}
|
|
275819
|
-
async function
|
|
275977
|
+
async function runAsyncAgentLifecycle2({
|
|
275820
275978
|
taskId,
|
|
275821
275979
|
abortController,
|
|
275822
275980
|
makeStream,
|
|
@@ -311087,7 +311245,7 @@ async function resumeAgentBackground({
|
|
|
311087
311245
|
invocationEmitted: false
|
|
311088
311246
|
};
|
|
311089
311247
|
const wrapWithCwd = (fn) => resumedWorktreePath ? runWithCwdOverride(resumedWorktreePath, fn) : fn();
|
|
311090
|
-
runWithAgentContext(asyncAgentContext, () => wrapWithCwd(() =>
|
|
311248
|
+
runWithAgentContext(asyncAgentContext, () => wrapWithCwd(() => runAsyncAgentLifecycle2({
|
|
311091
311249
|
taskId: agentBackgroundTask.agentId,
|
|
311092
311250
|
abortController: agentBackgroundTask.abortController,
|
|
311093
311251
|
makeStream: (onCacheSafeParams) => runAgent2({
|
|
@@ -321015,6 +321173,10 @@ function buildAgentLoopParams(m) {
|
|
|
321015
321173
|
toolUseContext: m.toolUseContext
|
|
321016
321174
|
}),
|
|
321017
321175
|
toolContext: m.toolUseContext,
|
|
321176
|
+
hasPendingBackgroundTasks: () => {
|
|
321177
|
+
const tasks = m.toolUseContext?.getAppState?.()?.tasks;
|
|
321178
|
+
return tasks ? hasNonTerminalTasks(tasks) : false;
|
|
321179
|
+
},
|
|
321018
321180
|
hooks: createLoopHooks({
|
|
321019
321181
|
options: {
|
|
321020
321182
|
sessionId: getSessionId(),
|
|
@@ -321046,6 +321208,7 @@ function buildAgentLoopParams(m) {
|
|
|
321046
321208
|
var init_agentLoopDeps = __esm(() => {
|
|
321047
321209
|
init_modelprovider2();
|
|
321048
321210
|
init_engine();
|
|
321211
|
+
init_Task();
|
|
321049
321212
|
init_settings3();
|
|
321050
321213
|
init_shared();
|
|
321051
321214
|
init_bootstrap();
|
|
@@ -366288,6 +366451,25 @@ var init_GlimmerMessage = __esm(() => {
|
|
|
366288
366451
|
};
|
|
366289
366452
|
});
|
|
366290
366453
|
|
|
366454
|
+
// src/tui/components/Spinner/spinnerGates.ts
|
|
366455
|
+
function getSpinnerDisplayGates(input) {
|
|
366456
|
+
const { verbose, hasRunningTeammates, effectiveElapsedMs } = input;
|
|
366457
|
+
const forceShow = verbose || hasRunningTeammates;
|
|
366458
|
+
const wantsTimer = forceShow || effectiveElapsedMs > SHOW_TIMER_AFTER_MS;
|
|
366459
|
+
return {
|
|
366460
|
+
wantsTimer,
|
|
366461
|
+
wantsTokens: forceShow || effectiveElapsedMs > SHOW_TOKENS_AFTER_MS,
|
|
366462
|
+
wantsStatusIndicator: wantsTimer
|
|
366463
|
+
};
|
|
366464
|
+
}
|
|
366465
|
+
function computeStallState(input) {
|
|
366466
|
+
const { timeSinceLastToken, currentResponseLength, hasActiveTools } = input;
|
|
366467
|
+
const isStalled = timeSinceLastToken > STALL_AFTER_MS && !hasActiveTools && currentResponseLength > 0;
|
|
366468
|
+
const stalledIntensity = isStalled ? Math.min((timeSinceLastToken - STALL_AFTER_MS) / STALL_FADE_MS, 1) : 0;
|
|
366469
|
+
return { isStalled, stalledIntensity };
|
|
366470
|
+
}
|
|
366471
|
+
var SHOW_TIMER_AFTER_MS = 1000, SHOW_TOKENS_AFTER_MS = 5000, STALL_AFTER_MS = 3000, STALL_FADE_MS = 2000;
|
|
366472
|
+
|
|
366291
366473
|
// src/tui/components/Spinner/useStalledAnimation.ts
|
|
366292
366474
|
function useStalledAnimation(time, currentResponseLength, hasActiveTools = false, reducedMotion = false) {
|
|
366293
366475
|
const lastTokenTime = import_react103.useRef(time);
|
|
@@ -366310,8 +366492,11 @@ function useStalledAnimation(time, currentResponseLength, hasActiveTools = false
|
|
|
366310
366492
|
} else {
|
|
366311
366493
|
timeSinceLastToken = time - mountTime.current;
|
|
366312
366494
|
}
|
|
366313
|
-
const isStalled
|
|
366314
|
-
|
|
366495
|
+
const { isStalled, stalledIntensity: intensity } = computeStallState({
|
|
366496
|
+
timeSinceLastToken,
|
|
366497
|
+
currentResponseLength,
|
|
366498
|
+
hasActiveTools
|
|
366499
|
+
});
|
|
366315
366500
|
if (!reducedMotion && (intensity > 0 || stalledIntensityRef.current > 0)) {
|
|
366316
366501
|
const dt = time - lastSmoothTime.current;
|
|
366317
366502
|
if (dt >= 50) {
|
|
@@ -366340,17 +366525,6 @@ var init_useStalledAnimation = __esm(() => {
|
|
|
366340
366525
|
import_react103 = __toESM(require_react(), 1);
|
|
366341
366526
|
});
|
|
366342
366527
|
|
|
366343
|
-
// src/tui/components/Spinner/spinnerGates.ts
|
|
366344
|
-
function getSpinnerDisplayGates(input) {
|
|
366345
|
-
const { verbose, hasRunningTeammates, effectiveElapsedMs } = input;
|
|
366346
|
-
const forceShow = verbose || hasRunningTeammates;
|
|
366347
|
-
return {
|
|
366348
|
-
wantsTimer: forceShow || effectiveElapsedMs > SHOW_TIMER_AFTER_MS,
|
|
366349
|
-
wantsTokens: forceShow || effectiveElapsedMs > SHOW_TOKENS_AFTER_MS
|
|
366350
|
-
};
|
|
366351
|
-
}
|
|
366352
|
-
var SHOW_TIMER_AFTER_MS = 1000, SHOW_TOKENS_AFTER_MS = 5000;
|
|
366353
|
-
|
|
366354
366528
|
// src/tui/components/Spinner/SpinnerAnimationRow.tsx
|
|
366355
366529
|
function SpinnerAnimationRow({
|
|
366356
366530
|
mode,
|
|
@@ -366389,7 +366563,8 @@ function SpinnerAnimationRow({
|
|
|
366389
366563
|
} = useStalledAnimation(time, currentResponseLength, hasActiveTools || leaderIsIdle, reducedMotion);
|
|
366390
366564
|
const frame = reducedMotion ? 0 : Math.floor(time / 120);
|
|
366391
366565
|
const glimmerSpeed = mode === "requesting" ? 50 : 200;
|
|
366392
|
-
const
|
|
366566
|
+
const displayMessage = mode === "requesting" ? message + "…" : message;
|
|
366567
|
+
const glimmerMessageWidth = import_react104.useMemo(() => stringWidth2(displayMessage), [displayMessage]);
|
|
366393
366568
|
const cycleLength = glimmerMessageWidth + 20;
|
|
366394
366569
|
const cyclePosition = Math.floor(time / glimmerSpeed);
|
|
366395
366570
|
const glimmerIndex = reducedMotion ? -100 : isStalled ? -100 : mode === "requesting" ? cyclePosition % cycleLength - 10 : glimmerMessageWidth + 10 - cyclePosition % cycleLength;
|
|
@@ -366425,7 +366600,7 @@ function SpinnerAnimationRow({
|
|
|
366425
366600
|
const messageWidth = glimmerMessageWidth + 2;
|
|
366426
366601
|
const sep = SEP_WIDTH;
|
|
366427
366602
|
const wantsThinking = thinkingStatus !== null;
|
|
366428
|
-
const { wantsTimer, wantsTokens } = getSpinnerDisplayGates({
|
|
366603
|
+
const { wantsTimer, wantsTokens, wantsStatusIndicator } = getSpinnerDisplayGates({
|
|
366429
366604
|
verbose,
|
|
366430
366605
|
hasRunningTeammates,
|
|
366431
366606
|
effectiveElapsedMs
|
|
@@ -366443,7 +366618,8 @@ function SpinnerAnimationRow({
|
|
|
366443
366618
|
const showTimer = wantsTimer && availableSpace > usedAfterThinking + timerWidth;
|
|
366444
366619
|
const usedAfterTimer = usedAfterThinking + (showTimer ? timerWidth + sep : 0);
|
|
366445
366620
|
const showTokens = wantsTokens && totalTokens > 0 && availableSpace > usedAfterTimer + tokensWidth;
|
|
366446
|
-
const
|
|
366621
|
+
const showStatusIndicator = !showTokens && wantsStatusIndicator && mode === "requesting" && !hasRunningTeammates && availableSpace > usedAfterTimer + 2;
|
|
366622
|
+
const thinkingOnly = showThinking && thinkingStatus === "thinking" && !spinnerSuffix && !showTimer && !showTokens && !showStatusIndicator && true;
|
|
366447
366623
|
const thinkingElapsedSec = (time - THINKING_DELAY_MS) / 1000;
|
|
366448
366624
|
const thinkingOpacity = time < THINKING_DELAY_MS ? 0 : (Math.sin(thinkingElapsedSec * Math.PI * 2 / THINKING_GLOW_PERIOD_S) + 1) / 2;
|
|
366449
366625
|
const thinkingShimmerColor = toRGBColor(interpolateColor(THINKING_INACTIVE, THINKING_INACTIVE_SHIMMER, thinkingOpacity));
|
|
@@ -366467,7 +366643,9 @@ function SpinnerAnimationRow({
|
|
|
366467
366643
|
]
|
|
366468
366644
|
}, undefined, true, undefined, this)
|
|
366469
366645
|
]
|
|
366470
|
-
}, "tokens", true, undefined, this)] : [], ...
|
|
366646
|
+
}, "tokens", true, undefined, this)] : [], ...showStatusIndicator ? [/* @__PURE__ */ jsx_dev_runtime184.jsxDEV(SpinnerModeGlyph, {
|
|
366647
|
+
mode
|
|
366648
|
+
}, "statusGlyph", false, undefined, this)] : [], ...showThinking && thinkingText ? [thinkingStatus === "thinking" && !reducedMotion ? /* @__PURE__ */ jsx_dev_runtime184.jsxDEV(ThemedText, {
|
|
366471
366649
|
color: thinkingShimmerColor,
|
|
366472
366650
|
children: thinkingOnly ? `(${thinkingText})` : thinkingText
|
|
366473
366651
|
}, "thinking", false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime184.jsxDEV(ThemedText, {
|
|
@@ -366521,7 +366699,7 @@ function SpinnerAnimationRow({
|
|
|
366521
366699
|
time
|
|
366522
366700
|
}, undefined, false, undefined, this),
|
|
366523
366701
|
/* @__PURE__ */ jsx_dev_runtime184.jsxDEV(GlimmerMessage, {
|
|
366524
|
-
message,
|
|
366702
|
+
message: displayMessage,
|
|
366525
366703
|
mode,
|
|
366526
366704
|
messageColor,
|
|
366527
366705
|
glimmerIndex,
|
|
@@ -425223,6 +425401,9 @@ import { randomBytes as randomBytes22 } from "crypto";
|
|
|
425223
425401
|
function isTerminalTaskStatus2(status) {
|
|
425224
425402
|
return status === "completed" || status === "failed" || status === "killed";
|
|
425225
425403
|
}
|
|
425404
|
+
function hasNonTerminalTasks(tasks) {
|
|
425405
|
+
return Object.values(tasks).some((t) => !isTerminalTaskStatus2(t.status));
|
|
425406
|
+
}
|
|
425226
425407
|
function getTaskIdPrefix(type) {
|
|
425227
425408
|
return TASK_ID_PREFIXES[type] ?? "x";
|
|
425228
425409
|
}
|
|
@@ -479281,7 +479462,8 @@ Error: sandbox required but unavailable: ${reason}
|
|
|
479281
479462
|
} catch (error) {
|
|
479282
479463
|
logError3(error);
|
|
479283
479464
|
const llmTimeoutHint = llmTimeoutRemediationHint(error, getCurrentLlmTimeoutMs());
|
|
479284
|
-
const
|
|
479465
|
+
const endpointLabel = getCurrentEndpointLabel(mainLoopModelParam);
|
|
479466
|
+
const gwHint = gatewayUnreachableRemediationHint(error, endpointLabel);
|
|
479285
479467
|
setMessages((prev) => [...prev, createSystemMessage(`本轮执行出错:${errorMessage2(error)}。${llmTimeoutHint ? `${llmTimeoutHint} ` : ""}${gwHint ? `${gwHint} ` : ""}请重试。`, "error")]);
|
|
479286
479468
|
} finally {
|
|
479287
479469
|
if (queryGuard.end(thisGeneration)) {
|
package/package.json
CHANGED