@keyou007/agent-bot 0.1.12 → 0.1.13-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/README.md +23 -10
- package/README.zh.md +23 -10
- package/config.example.yaml +0 -24
- package/dist/cli/AgentPrerequisites.js +262 -0
- package/dist/cli/AgentPrerequisites.js.map +1 -0
- package/dist/cli/DefaultAgentSelection.js +47 -0
- package/dist/cli/DefaultAgentSelection.js.map +1 -0
- package/dist/cli/Initializer.js +165 -2
- package/dist/cli/Initializer.js.map +1 -1
- package/dist/cli/help.js +4 -4
- package/dist/cli.js +194 -4
- package/dist/cli.js.map +1 -1
- package/dist/codex/AppServerConnection.js +3 -3
- package/dist/codex/AppServerConnection.js.map +1 -1
- package/dist/codex/CodexProcessManager.js +4 -4
- package/dist/codex/CodexProcessManager.js.map +1 -1
- package/dist/codex/CodexRuntime.js +28 -16
- package/dist/codex/CodexRuntime.js.map +1 -1
- package/dist/config/loadConfig.js +0 -24
- package/dist/config/loadConfig.js.map +1 -1
- package/dist/console/ConsoleConnector.js +2 -2
- package/dist/console/ConsoleConnector.js.map +1 -1
- package/dist/feishu/CardRenderer.js +8 -8
- package/dist/feishu/CardRenderer.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/proxy/ProxySessionController.js +51 -51
- package/dist/proxy/ProxySessionController.js.map +1 -1
- package/dist/runtime/AcpRuntimeAdapter.js +3 -2
- package/dist/runtime/AcpRuntimeAdapter.js.map +1 -1
- package/docs/technical-reference.md +32 -17
- package/docs/technical-reference.zh.md +32 -17
- package/npm-shrinkwrap.json +2 -2
- package/package.json +7 -3
- package/skills/agent-bot/SKILL.md +12 -6
- package/src/cli/AgentPrerequisites.ts +377 -0
- package/src/cli/DefaultAgentSelection.ts +56 -0
- package/src/cli/Initializer.ts +204 -3
- package/src/cli/help.ts +4 -4
- package/src/cli.ts +293 -5
- package/src/codex/AppServerConnection.ts +3 -3
- package/src/codex/CodexProcessManager.ts +4 -4
- package/src/codex/CodexRuntime.ts +38 -18
- package/src/config/loadConfig.ts +0 -24
- package/src/console/ConsoleConnector.ts +2 -2
- package/src/feishu/CardRenderer.ts +8 -8
- package/src/index.ts +1 -1
- package/src/proxy/ProxySessionController.ts +52 -52
- package/src/runtime/AcpRuntimeAdapter.ts +3 -1
|
@@ -375,7 +375,7 @@ export class ProxySessionController {
|
|
|
375
375
|
remote = await runtime.readRemoteSession(record.remoteSessionId);
|
|
376
376
|
}
|
|
377
377
|
catch (error) {
|
|
378
|
-
this.logger.warn({ error, sessionId: record.localSessionId }, "Failed to inspect
|
|
378
|
+
this.logger.warn({ error, sessionId: record.localSessionId }, "Failed to inspect App Server task status for CLI.");
|
|
379
379
|
}
|
|
380
380
|
}
|
|
381
381
|
}
|
|
@@ -468,7 +468,7 @@ export class ProxySessionController {
|
|
|
468
468
|
const agentName = requestedAgentName?.trim() || source.agentName;
|
|
469
469
|
const agent = this.ensureAgent(agentName);
|
|
470
470
|
if (forceProjectless && agent.kind !== "app-server") {
|
|
471
|
-
throw new Error("task newgroup --nodir is only available for
|
|
471
|
+
throw new Error("task newgroup --nodir is only available for App Server agents.");
|
|
472
472
|
}
|
|
473
473
|
const sourceContextKey = this.outbound.getSessionContextKey(localSessionId) ?? source.contextKey;
|
|
474
474
|
const replyTarget = this.outbound.getSessionReplyTarget(localSessionId);
|
|
@@ -654,7 +654,7 @@ export class ProxySessionController {
|
|
|
654
654
|
}
|
|
655
655
|
async prompt(contextKey, text, messageId, replyTarget, localImagePaths) {
|
|
656
656
|
if (!text.trim())
|
|
657
|
-
throw new Error("请输入要交给
|
|
657
|
+
throw new Error("请输入要交给 Agent 的内容。");
|
|
658
658
|
let record = this.currentSession(contextKey);
|
|
659
659
|
if (!record) {
|
|
660
660
|
const context = this.store.getOrCreateUserContext(contextKey, this.config.defaults.agent);
|
|
@@ -711,7 +711,7 @@ export class ProxySessionController {
|
|
|
711
711
|
return;
|
|
712
712
|
}
|
|
713
713
|
catch (error) {
|
|
714
|
-
this.logger.debug({ error, sessionId: record.localSessionId, activeTurnId }, "Steering failed; reconciling the
|
|
714
|
+
this.logger.debug({ error, sessionId: record.localSessionId, activeTurnId }, "Steering failed; reconciling the App Server thread.");
|
|
715
715
|
let current = loaded.runtime.getSession(record.localSessionId);
|
|
716
716
|
try {
|
|
717
717
|
current = await loaded.runtime.synchronizeSession(record.localSessionId);
|
|
@@ -734,7 +734,7 @@ export class ProxySessionController {
|
|
|
734
734
|
return;
|
|
735
735
|
}
|
|
736
736
|
catch (retryError) {
|
|
737
|
-
this.logger.warn({ error: retryError, sessionId: record.localSessionId, activeTurnId: current.activeTurnId }, "Failed to steer the reconciled
|
|
737
|
+
this.logger.warn({ error: retryError, sessionId: record.localSessionId, activeTurnId: current.activeTurnId }, "Failed to steer the reconciled App Server turn; queueing prompt.");
|
|
738
738
|
}
|
|
739
739
|
}
|
|
740
740
|
this.persistQueuedPrompt(record.localSessionId, contextKey, text, {
|
|
@@ -879,7 +879,7 @@ export class ProxySessionController {
|
|
|
879
879
|
const agent = this.ensureAgent(source.agentName);
|
|
880
880
|
const runtime = this.runtimes.forAgent(source.agentName);
|
|
881
881
|
if (runtime.kind !== "codex" || !runtime.forkSession) {
|
|
882
|
-
throw new Error("当前
|
|
882
|
+
throw new Error("当前 App Server Agent 不支持 fork 任务。");
|
|
883
883
|
}
|
|
884
884
|
const context = this.store.getOrCreateUserContext(message.contextKey, source.agentName);
|
|
885
885
|
if (context.currentSessionId && this.store.getSession(context.currentSessionId))
|
|
@@ -948,13 +948,13 @@ export class ProxySessionController {
|
|
|
948
948
|
.map((messageId) => this.store.findTurnAnchorByMessageId(messageId))
|
|
949
949
|
.find((candidate) => candidate !== undefined);
|
|
950
950
|
if (!anchor) {
|
|
951
|
-
throw new Error("无法确定这个话题对应的
|
|
951
|
+
throw new Error("无法确定这个话题对应的 App Server 轮次,因此没有创建分支任务。请从该轮的用户消息、思考卡片或最终回答创建话题。");
|
|
952
952
|
}
|
|
953
953
|
const source = anchor.contextKey
|
|
954
954
|
? this.store.getSessionForContext(anchor.localSessionId, anchor.contextKey)
|
|
955
955
|
: this.store.getSession(anchor.localSessionId);
|
|
956
956
|
if (!source || !source.remoteSessionId || !this.isCodexSession(source)) {
|
|
957
|
-
throw new Error("这个话题的来源不是可 fork 的
|
|
957
|
+
throw new Error("这个话题的来源不是可 fork 的 App Server 任务。");
|
|
958
958
|
}
|
|
959
959
|
if (baseChatContextKey(anchor.contextKey ?? source.contextKey) !== `chat_id:${message.chatId}`) {
|
|
960
960
|
throw new Error("话题来源任务不属于当前会话,已拒绝创建分支。");
|
|
@@ -962,7 +962,7 @@ export class ProxySessionController {
|
|
|
962
962
|
const snapshot = turnViewSnapshot(this.store.getTurnSnapshot(anchor.turnId));
|
|
963
963
|
if (isTurnStillRunning(snapshot?.status)
|
|
964
964
|
|| (source.lastTurnId === anchor.turnId && source.lastTurnStatus === "running")) {
|
|
965
|
-
throw new Error("话题对应的轮次仍在执行,
|
|
965
|
+
throw new Error("话题对应的轮次仍在执行,App Server 暂时不能从这一轮 fork。请等待该轮完成后再在话题中发送消息。");
|
|
966
966
|
}
|
|
967
967
|
return { anchor, source, snapshot };
|
|
968
968
|
}
|
|
@@ -992,7 +992,7 @@ export class ProxySessionController {
|
|
|
992
992
|
source = global ? { ...global, contextKey } : undefined;
|
|
993
993
|
}
|
|
994
994
|
if (source && (!source.remoteSessionId || !this.isCodexSession(source))) {
|
|
995
|
-
throw new Error(`${sourceLabel}不是可 fork 的
|
|
995
|
+
throw new Error(`${sourceLabel}不是可 fork 的 App Server 任务。`);
|
|
996
996
|
}
|
|
997
997
|
let runtime;
|
|
998
998
|
let agentName;
|
|
@@ -1003,20 +1003,20 @@ export class ProxySessionController {
|
|
|
1003
1003
|
}
|
|
1004
1004
|
else {
|
|
1005
1005
|
if (!taskId)
|
|
1006
|
-
throw new Error("缺少要 fork 的
|
|
1006
|
+
throw new Error("缺少要 fork 的 App Server 任务 ID。");
|
|
1007
1007
|
const resolved = await this.resolveRemoteCodexSession(taskId);
|
|
1008
1008
|
agentName = resolved.agentName;
|
|
1009
1009
|
runtime = resolved.runtime;
|
|
1010
1010
|
remote = resolved.remote;
|
|
1011
1011
|
}
|
|
1012
1012
|
if (runtime.kind !== "codex" || !runtime.forkSession) {
|
|
1013
|
-
throw new Error("当前
|
|
1013
|
+
throw new Error("当前 App Server Agent 不支持 fork 任务。");
|
|
1014
1014
|
}
|
|
1015
1015
|
const remoteSessionId = source?.remoteSessionId ?? remote?.id ?? taskId;
|
|
1016
1016
|
if (!remoteSessionId)
|
|
1017
|
-
throw new Error("当前任务尚未创建
|
|
1017
|
+
throw new Error("当前任务尚未创建 App Server 任务 ID,暂时不能 fork。");
|
|
1018
1018
|
if (!runtime.readRemoteSession && !source) {
|
|
1019
|
-
throw new Error("当前
|
|
1019
|
+
throw new Error("当前 App Server Agent 不支持读取指定任务。");
|
|
1020
1020
|
}
|
|
1021
1021
|
remote ??= runtime.readRemoteSession
|
|
1022
1022
|
? await runtime.readRemoteSession(remoteSessionId)
|
|
@@ -1039,7 +1039,7 @@ export class ProxySessionController {
|
|
|
1039
1039
|
const forkedFromHistoricalTurn = isRunning && lastTurnId !== latestTurnId;
|
|
1040
1040
|
const cwd = remote?.cwd || source?.cwd;
|
|
1041
1041
|
if (!cwd)
|
|
1042
|
-
throw new Error("指定的
|
|
1042
|
+
throw new Error("指定的 App Server 任务没有可用的工作目录,暂时不能 fork。");
|
|
1043
1043
|
const sourceTitle = remote?.title ?? source?.title ?? remote?.preview;
|
|
1044
1044
|
const forkTitle = normalizeTaskTitle(requestedTitle) ?? this.store.nextForkTitle(sourceTitle);
|
|
1045
1045
|
const modelProvider = remote?.modelProvider ?? source?.modelProvider;
|
|
@@ -1096,15 +1096,15 @@ export class ProxySessionController {
|
|
|
1096
1096
|
}
|
|
1097
1097
|
prepareForkSessionFromTurn(source, lastTurnId, requestedTitle, sourceLabel) {
|
|
1098
1098
|
if (!source.remoteSessionId || !this.isCodexSession(source)) {
|
|
1099
|
-
throw new Error(`${sourceLabel}不是可 fork 的
|
|
1099
|
+
throw new Error(`${sourceLabel}不是可 fork 的 App Server 任务。`);
|
|
1100
1100
|
}
|
|
1101
1101
|
const runtime = this.runtimes.forAgent(source.agentName);
|
|
1102
1102
|
if (runtime.kind !== "codex" || !runtime.forkSession) {
|
|
1103
|
-
throw new Error("当前
|
|
1103
|
+
throw new Error("当前 App Server Agent 不支持 fork 任务。");
|
|
1104
1104
|
}
|
|
1105
1105
|
const snapshot = turnViewSnapshot(this.store.getTurnSnapshot(lastTurnId));
|
|
1106
1106
|
if (isTurnStillRunning(snapshot?.status)) {
|
|
1107
|
-
throw new Error(`${sourceLabel}仍在执行,
|
|
1107
|
+
throw new Error(`${sourceLabel}仍在执行,App Server 暂时不能从这一轮 fork。`);
|
|
1108
1108
|
}
|
|
1109
1109
|
const sourceWasRunning = Boolean(runtime.getSession(source.localSessionId)?.activeTurnId
|
|
1110
1110
|
|| source.lastTurnStatus === "running"
|
|
@@ -1205,7 +1205,7 @@ export class ProxySessionController {
|
|
|
1205
1205
|
}
|
|
1206
1206
|
const source = direct ?? this.findStoredSessionByReference(taskId);
|
|
1207
1207
|
if (source && !this.isCodexSession(source)) {
|
|
1208
|
-
throw new Error("指定任务不是
|
|
1208
|
+
throw new Error("指定任务不是 App Server 任务,暂时不能按项目创建新任务。");
|
|
1209
1209
|
}
|
|
1210
1210
|
let agentName;
|
|
1211
1211
|
let runtime;
|
|
@@ -1233,7 +1233,7 @@ export class ProxySessionController {
|
|
|
1233
1233
|
}
|
|
1234
1234
|
const cwd = remote?.cwd || source?.cwd;
|
|
1235
1235
|
if (!cwd) {
|
|
1236
|
-
throw new Error("指定的
|
|
1236
|
+
throw new Error("指定的 App Server 任务没有可用的工作目录,暂时不能按项目创建新任务。");
|
|
1237
1237
|
}
|
|
1238
1238
|
const executionSettings = {
|
|
1239
1239
|
modelProvider: remote?.modelProvider ?? source?.modelProvider,
|
|
@@ -1363,7 +1363,7 @@ export class ProxySessionController {
|
|
|
1363
1363
|
"群和新任务已创建。",
|
|
1364
1364
|
`当前任务:${taskDescription}`,
|
|
1365
1365
|
`当前 Project 目录:${boundProjectCwd ?? "未绑定(Projectless)"}`,
|
|
1366
|
-
`当前 Provider:${task.modelProvider ?? "
|
|
1366
|
+
`当前 Provider:${task.modelProvider ?? "Agent 默认"}`,
|
|
1367
1367
|
`当前模型:${task.model ?? "默认"}`,
|
|
1368
1368
|
`思考强度:${task.reasoningEffort ?? "自动"}`,
|
|
1369
1369
|
`权限类型:${task.permissionMode === "confirm" ? "执行前确认" : "自动执行"}`,
|
|
@@ -1409,7 +1409,7 @@ export class ProxySessionController {
|
|
|
1409
1409
|
`已从${prepared.sourceDescription}创建分支。`,
|
|
1410
1410
|
`当前任务:${taskDescription}`,
|
|
1411
1411
|
`当前 Project 目录:${boundProjectCwd ?? "未绑定(Projectless)"}`,
|
|
1412
|
-
`当前 Provider:${forked.session.modelProvider ?? "
|
|
1412
|
+
`当前 Provider:${forked.session.modelProvider ?? "Agent 默认"}`,
|
|
1413
1413
|
`当前模型:${forked.session.model ?? "默认"}`,
|
|
1414
1414
|
`思考强度:${forked.session.reasoningEffort ?? "自动"}`,
|
|
1415
1415
|
`权限类型:${forked.session.permissionMode === "confirm" ? "执行前确认" : "自动执行"}`,
|
|
@@ -1479,7 +1479,7 @@ export class ProxySessionController {
|
|
|
1479
1479
|
catch (error) {
|
|
1480
1480
|
if (!(agent.kind === "app-server" && !record.lastTurnId && isMissingRolloutError(error)))
|
|
1481
1481
|
throw error;
|
|
1482
|
-
this.logger.warn({ error, sessionId: record.localSessionId }, "
|
|
1482
|
+
this.logger.warn({ error, sessionId: record.localSessionId }, "App Server task has no rollout; creating a replacement task.");
|
|
1483
1483
|
session = await runtime.createSession({
|
|
1484
1484
|
localSessionId: record.localSessionId,
|
|
1485
1485
|
agentName: record.agentName,
|
|
@@ -1682,7 +1682,7 @@ export class ProxySessionController {
|
|
|
1682
1682
|
await runtime.setGoal(record.localSessionId, { status: "paused" });
|
|
1683
1683
|
}
|
|
1684
1684
|
catch (error) {
|
|
1685
|
-
this.logger.warn({ error, sessionId: record.localSessionId }, "Failed to pause the active
|
|
1685
|
+
this.logger.warn({ error, sessionId: record.localSessionId }, "Failed to pause the active Agent goal before interrupting its turn.");
|
|
1686
1686
|
}
|
|
1687
1687
|
}
|
|
1688
1688
|
let turnId = runtime.getSession(record.localSessionId)?.activeTurnId;
|
|
@@ -1694,7 +1694,7 @@ export class ProxySessionController {
|
|
|
1694
1694
|
: undefined;
|
|
1695
1695
|
}
|
|
1696
1696
|
catch (error) {
|
|
1697
|
-
this.logger.warn({ error, sessionId: record.localSessionId, remoteSessionId: record.remoteSessionId }, "Failed to inspect the current
|
|
1697
|
+
this.logger.warn({ error, sessionId: record.localSessionId, remoteSessionId: record.remoteSessionId }, "Failed to inspect the current App Server turn before interrupting; using the locally tracked turn.");
|
|
1698
1698
|
}
|
|
1699
1699
|
}
|
|
1700
1700
|
if (!turnId) {
|
|
@@ -1707,7 +1707,7 @@ export class ProxySessionController {
|
|
|
1707
1707
|
remoteSessionId: record.remoteSessionId,
|
|
1708
1708
|
turnId,
|
|
1709
1709
|
});
|
|
1710
|
-
await this.outbound.sendText(record.contextKey, `已向
|
|
1710
|
+
await this.outbound.sendText(record.contextKey, `已向 Agent 发送 Interrupt 请求:${turnId}`);
|
|
1711
1711
|
return;
|
|
1712
1712
|
}
|
|
1713
1713
|
const loaded = await this.loadSession(record);
|
|
@@ -2002,7 +2002,7 @@ export class ProxySessionController {
|
|
|
2002
2002
|
}
|
|
2003
2003
|
const loaded = await this.loadSession(record);
|
|
2004
2004
|
if (loaded.runtime.kind !== "codex" || !loaded.runtime.getGoal || !loaded.runtime.setGoal || !loaded.runtime.clearGoal) {
|
|
2005
|
-
throw new Error("
|
|
2005
|
+
throw new Error("当前 Agent 不支持 Goal 模式。");
|
|
2006
2006
|
}
|
|
2007
2007
|
if (command.action === "show") {
|
|
2008
2008
|
await this.sendGoalCard(contextKey, await loaded.runtime.getGoal(record.localSessionId));
|
|
@@ -2025,7 +2025,7 @@ export class ProxySessionController {
|
|
|
2025
2025
|
const goal = await loaded.runtime.setGoal(record.localSessionId, { status });
|
|
2026
2026
|
await this.sendGoalCard(contextKey, goal, command.action === "pause"
|
|
2027
2027
|
? "Goal 已暂停;当前轮次可以完成,但不会继续自动执行。"
|
|
2028
|
-
: "Goal 已恢复,
|
|
2028
|
+
: "Goal 已恢复,Agent 会继续自动执行。", record);
|
|
2029
2029
|
return;
|
|
2030
2030
|
}
|
|
2031
2031
|
if (objective === undefined)
|
|
@@ -2041,7 +2041,7 @@ export class ProxySessionController {
|
|
|
2041
2041
|
status: command.action === "edit" ? current.status : "active",
|
|
2042
2042
|
...(command.action === "edit" ? { tokenBudget: current.tokenBudget } : {}),
|
|
2043
2043
|
});
|
|
2044
|
-
await this.sendGoalCard(contextKey, goal, command.action === "edit" ? "Goal 已更新。" : "Goal 已启动,
|
|
2044
|
+
await this.sendGoalCard(contextKey, goal, command.action === "edit" ? "Goal 已更新。" : "Goal 已启动,Agent 会持续执行直到完成、暂停或遇到阻塞。", record);
|
|
2045
2045
|
}
|
|
2046
2046
|
async sendGoalCard(contextKey, goal, notice, record = this.currentSession(contextKey)) {
|
|
2047
2047
|
const sections = [];
|
|
@@ -2055,7 +2055,7 @@ export class ProxySessionController {
|
|
|
2055
2055
|
title: "任务",
|
|
2056
2056
|
lines: [
|
|
2057
2057
|
`**标题**:${cardText(record.title ?? "未命名任务")}`,
|
|
2058
|
-
`**
|
|
2058
|
+
`**App Server 任务 ID**:${cardText(record.remoteSessionId ?? "尚未创建")}`,
|
|
2059
2059
|
],
|
|
2060
2060
|
});
|
|
2061
2061
|
}
|
|
@@ -2066,7 +2066,7 @@ export class ProxySessionController {
|
|
|
2066
2066
|
"**/goal edit <新目标>** 修改 **/goal clear** 清除",
|
|
2067
2067
|
],
|
|
2068
2068
|
});
|
|
2069
|
-
await this.outbound.sendInteractiveCard(contextKey, this.cardRenderer.renderSectionsCard("
|
|
2069
|
+
await this.outbound.sendInteractiveCard(contextKey, this.cardRenderer.renderSectionsCard("Agent Goal", sections));
|
|
2070
2070
|
}
|
|
2071
2071
|
async runShellCommand(contextKey, command) {
|
|
2072
2072
|
const cwd = this.currentSession(contextKey)?.cwd ?? this.config.defaults.cwd;
|
|
@@ -2202,7 +2202,7 @@ export class ProxySessionController {
|
|
|
2202
2202
|
remoteHasMore ||= Boolean(page.nextCursor);
|
|
2203
2203
|
}
|
|
2204
2204
|
catch (error) {
|
|
2205
|
-
this.logger.warn({ error, contextKey, agentName }, "Failed to list
|
|
2205
|
+
this.logger.warn({ error, contextKey, agentName }, "Failed to list App Server sessions for an Agent.");
|
|
2206
2206
|
remoteErrors.push(`${agentName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
2207
2207
|
}
|
|
2208
2208
|
}));
|
|
@@ -2292,7 +2292,7 @@ export class ProxySessionController {
|
|
|
2292
2292
|
actions,
|
|
2293
2293
|
};
|
|
2294
2294
|
});
|
|
2295
|
-
const card = this.cardRenderer.renderTaskListCard(searchTerm ? `
|
|
2295
|
+
const card = this.cardRenderer.renderTaskListCard(searchTerm ? `App Server 任务:${searchTerm}` : "App Server 任务", activeCount > 0 ? `任务(${activeCount} 个活跃)` : "任务", cardEntries, [
|
|
2296
2296
|
...(remoteHint ? [remoteHint] : []),
|
|
2297
2297
|
"点击 **New** 在对应任务的项目中创建新任务;点击 **Switch** 快速切换;点击 **Fork** 从任务最新已完成轮次创建分支;外部正在运行的任务显示 **Stop**,点击后发送 Interrupt 并变为 **Switch**。",
|
|
2298
2298
|
"点击 **NewGroup** 在对应任务的项目中创建新群和新任务;点击 **ForkGroup** 从对应任务最新已完成轮次创建分支群。",
|
|
@@ -2352,7 +2352,7 @@ export class ProxySessionController {
|
|
|
2352
2352
|
? [[scoped.agentName, this.runtimes.forAgent(scoped.agentName)]]
|
|
2353
2353
|
: this.runtimes.entries("codex");
|
|
2354
2354
|
if (candidates.length === 0)
|
|
2355
|
-
throw new Error("未配置
|
|
2355
|
+
throw new Error("未配置 App Server Agent。");
|
|
2356
2356
|
const reads = await Promise.allSettled(candidates.map(async ([agentName, runtime]) => {
|
|
2357
2357
|
if (runtime.kind !== "codex" || !runtime.readRemoteSession) {
|
|
2358
2358
|
throw new Error(`Agent ${agentName} 不支持读取远端任务。`);
|
|
@@ -2377,7 +2377,7 @@ export class ProxySessionController {
|
|
|
2377
2377
|
: undefined)
|
|
2378
2378
|
.filter((detail) => Boolean(detail))
|
|
2379
2379
|
.join(";");
|
|
2380
|
-
throw new Error(`找不到
|
|
2380
|
+
throw new Error(`找不到 App Server 任务:${scoped?.remoteSessionId ?? reference}${details ? `(${details})` : ""}`);
|
|
2381
2381
|
}
|
|
2382
2382
|
async switchSession(contextKey, reference) {
|
|
2383
2383
|
this.store.getOrCreateUserContext(contextKey, this.config.defaults.agent);
|
|
@@ -2398,10 +2398,10 @@ export class ProxySessionController {
|
|
|
2398
2398
|
}
|
|
2399
2399
|
const { agentName, remote } = await this.resolveRemoteCodexSession(taskId);
|
|
2400
2400
|
if (remote.status === "active" || remote.lastTurnStatus === "inProgress") {
|
|
2401
|
-
throw new Error(`这个任务正在外部
|
|
2401
|
+
throw new Error(`这个任务正在外部 Agent 中执行,当前不会切换。可使用 /status ${taskId} 查看进度。`);
|
|
2402
2402
|
}
|
|
2403
2403
|
if (!remote.cwd)
|
|
2404
|
-
throw new Error("这个
|
|
2404
|
+
throw new Error("这个 App Server 任务没有可用的工作目录,暂时无法切换。");
|
|
2405
2405
|
const localSessionId = createId("sess");
|
|
2406
2406
|
this.store.createSession({
|
|
2407
2407
|
localSessionId,
|
|
@@ -2437,7 +2437,7 @@ export class ProxySessionController {
|
|
|
2437
2437
|
}
|
|
2438
2438
|
const { runtime, remote } = await this.resolveRemoteCodexSession(taskId);
|
|
2439
2439
|
if (!runtime.readRemoteSession || !runtime.interruptRemoteTurn) {
|
|
2440
|
-
throw new Error("当前
|
|
2440
|
+
throw new Error("当前 App Server Agent 不支持停止外部任务。");
|
|
2441
2441
|
}
|
|
2442
2442
|
const turnId = remote.status === "active" || remote.lastTurnStatus === "inProgress"
|
|
2443
2443
|
? remote.lastTurnId
|
|
@@ -2452,7 +2452,7 @@ export class ProxySessionController {
|
|
|
2452
2452
|
turnId,
|
|
2453
2453
|
source: "sessions_card",
|
|
2454
2454
|
});
|
|
2455
|
-
await this.outbound.sendText(contextKey, `已向
|
|
2455
|
+
await this.outbound.sendText(contextKey, `已向 Agent 发送 Interrupt 请求:${turnId}`);
|
|
2456
2456
|
}
|
|
2457
2457
|
resolveSessionReference(contextKey, reference) {
|
|
2458
2458
|
if (reference === undefined) {
|
|
@@ -2494,7 +2494,7 @@ export class ProxySessionController {
|
|
|
2494
2494
|
&& activity.activeTurnId === record.lastTurnId;
|
|
2495
2495
|
const botOwnsActiveTurn = runtimeOwnsActiveTurn || persistedTurnMatches;
|
|
2496
2496
|
if (activity.active && !botOwnsActiveTurn) {
|
|
2497
|
-
throw new Error("这个任务正在外部
|
|
2497
|
+
throw new Error("这个任务正在外部 Agent 中执行。Agent Bot 不会接管或追加消息,请等待外部执行完成。");
|
|
2498
2498
|
}
|
|
2499
2499
|
return activity;
|
|
2500
2500
|
}
|
|
@@ -2503,7 +2503,7 @@ export class ProxySessionController {
|
|
|
2503
2503
|
remote = await runtime.readRemoteSession(record.remoteSessionId);
|
|
2504
2504
|
}
|
|
2505
2505
|
catch (error) {
|
|
2506
|
-
//
|
|
2506
|
+
// App Server does not materialize a new thread until its first user message.
|
|
2507
2507
|
// Such a thread has no turn to take over, so allow turn/start to create it.
|
|
2508
2508
|
if (!record.lastTurnId && isUnmaterializedCodexThreadError(error))
|
|
2509
2509
|
return;
|
|
@@ -2511,7 +2511,7 @@ export class ProxySessionController {
|
|
|
2511
2511
|
}
|
|
2512
2512
|
const botOwnsActiveTurn = isBotOwnedActiveTurn(record, remote);
|
|
2513
2513
|
if ((remote.status === "active" || remote.lastTurnStatus === "inProgress") && !botOwnsActiveTurn) {
|
|
2514
|
-
throw new Error("这个任务正在外部
|
|
2514
|
+
throw new Error("这个任务正在外部 Agent 中执行。Agent Bot 不会接管或追加消息,请等待外部执行完成。");
|
|
2515
2515
|
}
|
|
2516
2516
|
return undefined;
|
|
2517
2517
|
}
|
|
@@ -2567,7 +2567,7 @@ export class ProxySessionController {
|
|
|
2567
2567
|
remote = await runtime.readRemoteSession(current.remoteSessionId);
|
|
2568
2568
|
}
|
|
2569
2569
|
catch (error) {
|
|
2570
|
-
this.logger.warn({ error, sessionId: current.localSessionId }, "Failed to inspect
|
|
2570
|
+
this.logger.warn({ error, sessionId: current.localSessionId }, "Failed to inspect App Server task status.");
|
|
2571
2571
|
}
|
|
2572
2572
|
}
|
|
2573
2573
|
if (runtime.kind === "codex" && runtime.getGoal) {
|
|
@@ -2576,7 +2576,7 @@ export class ProxySessionController {
|
|
|
2576
2576
|
goal = await runtime.getGoal(loaded.localSessionId);
|
|
2577
2577
|
}
|
|
2578
2578
|
catch (error) {
|
|
2579
|
-
this.logger.warn({ error, sessionId: current.localSessionId }, "Failed to inspect
|
|
2579
|
+
this.logger.warn({ error, sessionId: current.localSessionId }, "Failed to inspect Agent goal status.");
|
|
2580
2580
|
}
|
|
2581
2581
|
}
|
|
2582
2582
|
}
|
|
@@ -2587,7 +2587,7 @@ export class ProxySessionController {
|
|
|
2587
2587
|
let activeTurnId;
|
|
2588
2588
|
let queued = 0;
|
|
2589
2589
|
if (!current) {
|
|
2590
|
-
taskLines.push("无。直接发送消息即可创建一个未指定项目的
|
|
2590
|
+
taskLines.push("无。直接发送消息即可创建一个未指定项目的 Agent 任务。");
|
|
2591
2591
|
}
|
|
2592
2592
|
else {
|
|
2593
2593
|
const agent = this.ensureAgent(current.agentName);
|
|
@@ -2603,7 +2603,7 @@ export class ProxySessionController {
|
|
|
2603
2603
|
const resultLabel = remoteActive
|
|
2604
2604
|
? "执行中"
|
|
2605
2605
|
: remoteTurnStatusLabel(remote?.lastTurnStatus ?? current.lastTurnStatus);
|
|
2606
|
-
taskLines.push(`**标题**:${cardCode(current.title ?? "未命名任务")}`, `**工作目录**:${cardCode(current.cwd)}`, `**Provider / 模型 / 思考强度**:${cardCode(current.modelProvider ?? "
|
|
2606
|
+
taskLines.push(`**标题**:${cardCode(current.title ?? "未命名任务")}`, `**工作目录**:${cardCode(current.cwd)}`, `**Provider / 模型 / 思考强度**:${cardCode(current.modelProvider ?? "Agent 默认")} / ${cardCode(current.model ?? "默认")} / ${cardCode(current.reasoningEffort ?? "自动")}`, `**状态 / 最近结果**:${statusLabel} / ${resultLabel}`, `**Agent**:${cardCode(agent.title)}`, `**权限 / 任务范围**:${current.permissionMode === "confirm" ? "执行前确认" : "自动执行"} / ${detectProjectlessWorkspace(current.cwd) ? "未指定项目" : "指定项目"}`, `**App Server 任务 ID**:${cardCode(current.remoteSessionId ?? "尚未创建")}`, `**当前执行 / 排队消息**:${activeTurnId ? cardCode(activeTurnId) : "无"} / ${queued} 条`, `**创建时间 / 最近活动**:${formatStatusTime(current.createdAt)} / ${formatStatusTime(current.updatedAt)}`);
|
|
2607
2607
|
}
|
|
2608
2608
|
const sections = [
|
|
2609
2609
|
{ title: targetSessionId ? "指定任务" : "当前任务", lines: taskLines },
|
|
@@ -2630,8 +2630,8 @@ export class ProxySessionController {
|
|
|
2630
2630
|
},
|
|
2631
2631
|
];
|
|
2632
2632
|
const title = targetSessionId && current
|
|
2633
|
-
? `
|
|
2634
|
-
: "
|
|
2633
|
+
? `Agent 状态:${truncateText((current.title ?? current.remoteSessionId ?? current.localSessionId).replace(/\s+/g, " "), 40)}`
|
|
2634
|
+
: "Agent 状态";
|
|
2635
2635
|
const taskId = current?.remoteSessionId
|
|
2636
2636
|
? remoteSessionReference(current.agentName, current.remoteSessionId)
|
|
2637
2637
|
: current?.localSessionId;
|
|
@@ -2670,7 +2670,7 @@ export class ProxySessionController {
|
|
|
2670
2670
|
`**工作目录**:${cardCode(remote.cwd || "目录未知")}`,
|
|
2671
2671
|
`**状态 / 当前任务**:${remoteSessionDetailStatus(remote)} / 未切换`,
|
|
2672
2672
|
`**Agent**:${cardCode(agentName)}`,
|
|
2673
|
-
`**
|
|
2673
|
+
`**App Server 任务 ID**:${cardCode(remote.id)}`,
|
|
2674
2674
|
`**最近回合**:${cardCode(remote.lastTurnId ?? "无")} ${remoteTurnStatusLabel(remote.lastTurnStatus)}`,
|
|
2675
2675
|
`**创建时间 / 最近活动**:${formatRemoteTime(remote.createdAt)} / ${formatRemoteTime(latestRemoteTimestamp(remote.recencyAt, remote.updatedAt))}`,
|
|
2676
2676
|
],
|
|
@@ -2681,14 +2681,14 @@ export class ProxySessionController {
|
|
|
2681
2681
|
lines: [
|
|
2682
2682
|
`**当前 / 最后步骤**:${statusExcerpt(remote.lastActivity ?? remoteStatusStep(remote), 500)}`,
|
|
2683
2683
|
isRemoteSessionActive(remote)
|
|
2684
|
-
? "外部
|
|
2684
|
+
? "外部 Agent 正在执行;Agent Bot 只读取状态,不会接管。"
|
|
2685
2685
|
: `发送 **/switch ${cardText(remote.id)}** 切换到此任务。`,
|
|
2686
2686
|
],
|
|
2687
2687
|
collapsible: true,
|
|
2688
2688
|
elementId: "status_execution_details",
|
|
2689
2689
|
},
|
|
2690
2690
|
];
|
|
2691
|
-
const title = `
|
|
2691
|
+
const title = `Agent 状态:${truncateText((remote.title ?? remote.preview ?? remote.id).replace(/\s+/g, " "), 40)}`;
|
|
2692
2692
|
const showStop = isRemoteSessionActive(remote)
|
|
2693
2693
|
&& options.forceSwitchTaskId !== actionReference
|
|
2694
2694
|
&& options.forceSwitchTaskId !== remote.id;
|