tellrun 1.3.3 → 1.3.5

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/README.md CHANGED
@@ -57,7 +57,7 @@ At startup, Tellrun registers an English command menu. Use the menu button besid
57
57
  | `/new` | Start a new conversation while keeping the working directory |
58
58
  | `/model` | Show the current selection and choose model and reasoning effort |
59
59
  | `/permissions` | Choose the permission mode for subsequent tasks |
60
- | `/status` | Show connection, conversation, directory, and task status |
60
+ | `/status` | Show connection, directory, model, permissions, and task status |
61
61
  | `/last` | Show the latest finished task's status and result |
62
62
  | `/stop` | Request that the current task stop and pause new tasks |
63
63
  | `/resume` | Accept new tasks again without rerunning an interrupted task |
@@ -66,8 +66,6 @@ Wait for the current task to finish before changing directories or starting a ne
66
66
 
67
67
  `/permissions` offers the four presets from Codex CLI 0.165.0: Ask for approval (default), Approve for me (Codex automatic review), Full Access (no Codex sandbox or execution approvals), and Read Only (approval required for edits or network access). Full Access remains subject to operating system permissions.
68
68
 
69
- Selections apply to subsequently submitted tasks; the current task and its follow-up messages retain their original mode. `/status` shows both modes when they differ. Selections survive service restarts and `/new`; changing the working directory resets the mode to its default. Menus expire after 10 minutes and are invalidated when reopened, on a new conversation, on a directory change, or after a restart. Codex validates the selected mode when starting a task. If it rejects the configuration or returns different settings, the task does not start.
70
-
71
69
  ## Terminal commands
72
70
 
73
71
  Run these commands in the terminal on the computer or server running Tellrun.
package/README.zh-CN.md CHANGED
@@ -57,7 +57,7 @@ tellrun setup
57
57
  | `/new` | 开始新会话,保留工作目录 |
58
58
  | `/model` | 查看当前选择,通过按钮选择模型和推理强度 |
59
59
  | `/permissions` | 选择后续任务的权限模式 |
60
- | `/status` | 查看连接、会话、目录和任务状态 |
60
+ | `/status` | 查看连接、目录、模型、权限和任务状态 |
61
61
  | `/last` | 查看最近已结束任务的状态与结果 |
62
62
  | `/stop` | 请求停止当前任务,并暂停接收新任务 |
63
63
  | `/resume` | 恢复接收新任务,不会重新执行此前中断的任务 |
@@ -66,8 +66,6 @@ tellrun setup
66
66
 
67
67
  `/permissions` 提供与 Codex CLI 0.165.0 对应的四种模式:Ask for approval(默认,额外权限由你审批)、Approve for me(由 Codex 自动审查)、Full Access(不使用 Codex 沙箱和执行审批)、Read Only(只读,修改或联网时请求审批)。Full Access 仍受系统用户权限约束。
68
68
 
69
- 选择在下一次提交任务时使用,当前任务及其补充消息保留原权限;`/status` 会在两者不同时分别显示。选择跨服务重启保留,`/new` 沿用选择,切换工作目录恢复默认。菜单有效期为 10 分钟,重新打开、新建会话、切换目录或重启后旧按钮失效。模式受本机 Codex 版本与托管策略限制,启动任务时由 Codex 校验;被拒绝或返回设置不符时不启动任务。
70
-
71
69
  ## 终端命令
72
70
 
73
71
  在运行 Tellrun 的电脑或服务器上执行以下命令。
@@ -6,19 +6,51 @@ export const fileChangesSchema = z.array(z.object({
6
6
  kind: z.object({ type: z.enum(["add", "delete", "update"]), move_path: z.string().nullish() }),
7
7
  diff: z.string(),
8
8
  }));
9
+ /** 只接受已知命令审批格式;规则内容必须来自当前请求,不能由按钮构造。 */
10
+ const commandDecisionSchema = z.union([
11
+ z.enum(["accept", "acceptForSession", "decline", "cancel"]),
12
+ z.strictObject({
13
+ acceptWithExecpolicyAmendment: z.strictObject({
14
+ execpolicy_amendment: z.array(z.string()).min(1),
15
+ }),
16
+ }),
17
+ ]);
9
18
  /** 转换审批与提问请求;格式错误抛出异常,中断原因交给调用方应答并清理任务。 */
10
19
  export function parseCodexInteraction(method, value, cwd, fileChanges) {
11
20
  const interaction = {
12
21
  id: randomUUID(),
13
22
  kind: "approval",
14
23
  text: "",
15
- expiresAt: Date.now() + 10 * 60_000,
24
+ expiresAt: null,
16
25
  blocking: true,
17
- choices: ["accept", "decline"],
26
+ choices: [],
18
27
  questions: [],
19
28
  };
20
- let permissions;
29
+ const approvals = new Map();
21
30
  let fileReview;
31
+ /** 展示选项与完整响应同步登记,核心层只传回选项标识。 */
32
+ function offer(id, label, result, approved) {
33
+ if (approvals.has(id))
34
+ return;
35
+ interaction.choices.push({ id, label });
36
+ approvals.set(id, { result, approved });
37
+ }
38
+ /** 原生取消直接回传 Codex,不转换为 Tellrun 的停止和暂停接收。 */
39
+ function offerDecision(decision, index) {
40
+ if (typeof decision === "string") {
41
+ const labels = {
42
+ accept: "Allow once",
43
+ acceptForSession: "Allow for session",
44
+ decline: "Decline",
45
+ cancel: "Cancel",
46
+ };
47
+ offer(decision, labels[decision], { decision }, decision.startsWith("accept"));
48
+ }
49
+ else {
50
+ interaction.text += `\nCommand rule ${index + 1}: ${JSON.stringify(decision.acceptWithExecpolicyAmendment.execpolicy_amendment)}`;
51
+ offer(`rule-${index}`, `Allow & remember rule ${index + 1}`, { decision }, true);
52
+ }
53
+ }
22
54
  if (method === "item/commandExecution/requestApproval") {
23
55
  const params = z
24
56
  .object({
@@ -30,11 +62,38 @@ export function parseCodexInteraction(method, value, cwd, fileChanges) {
30
62
  networkApprovalContext: z.object({ host: z.string(), protocol: z.string() }).nullish(),
31
63
  additionalPermissions: z.unknown().optional(),
32
64
  availableDecisions: z.array(z.unknown()).nullish(),
65
+ proposedExecpolicyAmendment: z.array(z.string()).nullish(),
33
66
  })
34
67
  .parse(value);
35
68
  interaction.text = `${params.kind === "writeStdin" ? "Terminal input" : "Command"}\nDirectory: ${params.cwd ?? cwd}\n${params.command ?? "Command unavailable."}${params.reason ? `\nReason: ${params.reason}` : ""}${params.networkApprovalContext ? `\nNetwork: ${params.networkApprovalContext.protocol}://${params.networkApprovalContext.host}` : ""}${params.additionalPermissions ? `\nPermissions: ${JSON.stringify(params.additionalPermissions, null, 2)}` : ""}`;
36
- interaction.choices = interaction.choices.filter((choice) => (params.availableDecisions == null || params.availableDecisions.includes(choice)) &&
37
- (choice !== "accept" || !!params.command || !!params.networkApprovalContext));
69
+ /** 显式选项具有优先权;旧服务未返回列表时使用协议的基本决定与所提规则。 */
70
+ const decisions = params.availableDecisions ?? [
71
+ "accept",
72
+ "acceptForSession",
73
+ ...(params.proposedExecpolicyAmendment?.length
74
+ ? [
75
+ {
76
+ acceptWithExecpolicyAmendment: {
77
+ execpolicy_amendment: params.proposedExecpolicyAmendment,
78
+ },
79
+ },
80
+ ]
81
+ : []),
82
+ "decline",
83
+ "cancel",
84
+ ];
85
+ for (const [index, value] of decisions.entries()) {
86
+ const parsed = commandDecisionSchema.safeParse(value);
87
+ if (!parsed.success)
88
+ continue;
89
+ const decision = parsed.data;
90
+ if (decision !== "decline" &&
91
+ decision !== "cancel" &&
92
+ !params.command &&
93
+ !params.networkApprovalContext)
94
+ continue;
95
+ offerDecision(decision, index);
96
+ }
38
97
  }
39
98
  else if (method === "item/fileChange/requestApproval") {
40
99
  const params = z
@@ -48,9 +107,12 @@ export function parseCodexInteraction(method, value, cwd, fileChanges) {
48
107
  const changes = fileChanges.get(params.itemId);
49
108
  if (changes?.length)
50
109
  fileReview = { itemId: params.itemId, changes: JSON.stringify(changes) };
51
- interaction.text = `File changes\nDirectory: ${cwd}${params.reason ? `\nReason: ${params.reason}` : ""}${params.grantRoot ? `\nWrite access: ${params.grantRoot}` : ""}\n${changes?.length ? changes.map((change) => `${change.kind.type}: ${change.path}${change.kind.move_path ? ` → ${change.kind.move_path}` : ""}\n${change.diff}`).join("\n\n") : "Details unavailable. Decline or stop."}`;
52
- if (!changes?.length)
53
- interaction.choices = ["decline"];
110
+ interaction.text = `File changes\nDirectory: ${cwd}${params.reason ? `\nReason: ${params.reason}` : ""}${params.grantRoot ? `\nWrite access: ${params.grantRoot}` : ""}\n${changes?.length ? changes.map((change) => `${change.kind.type}: ${change.path}${change.kind.move_path ? ` → ${change.kind.move_path}` : ""}\n${change.diff}`).join("\n\n") : "Details unavailable. Decline or cancel."}`;
111
+ for (const decision of ["accept", "acceptForSession", "decline", "cancel"]) {
112
+ if (!changes?.length && decision.startsWith("accept"))
113
+ continue;
114
+ offerDecision(decision, interaction.choices.length);
115
+ }
54
116
  }
55
117
  else if (method === "item/permissions/requestApproval") {
56
118
  const params = z
@@ -71,8 +133,11 @@ export function parseCodexInteraction(method, value, cwd, fileChanges) {
71
133
  }),
72
134
  })
73
135
  .parse(value);
74
- permissions = Object.fromEntries(Object.entries(params.permissions).filter(([, value]) => value != null));
75
- interaction.text = `Permissions (this turn only)\nDirectory: ${params.cwd}${params.reason ? `\nReason: ${params.reason}` : ""}\n${JSON.stringify(permissions, null, 2)}`;
136
+ const permissions = Object.fromEntries(Object.entries(params.permissions).filter(([, value]) => value != null));
137
+ interaction.text = `Permissions\nDirectory: ${params.cwd}${params.reason ? `\nReason: ${params.reason}` : ""}\n${JSON.stringify(permissions, null, 2)}`;
138
+ offer("accept", "Allow this turn", { permissions, scope: "turn" }, true);
139
+ offer("acceptForSession", "Allow for session", { permissions, scope: "session" }, true);
140
+ offer("decline", "Decline", { permissions: {}, scope: "turn" }, false);
76
141
  }
77
142
  else if (method === "item/tool/requestUserInput") {
78
143
  const params = z
@@ -103,7 +168,9 @@ export function parseCodexInteraction(method, value, cwd, fileChanges) {
103
168
  interaction.kind = "question";
104
169
  interaction.blocking = params.isBlocking;
105
170
  interaction.choices = [];
106
- interaction.expiresAt = Math.min(interaction.expiresAt, Date.now() + (params.autoResolutionMs ?? 10 * 60_000));
171
+ /** 只有提问设置本地期限;审批持续等待用户决定。 */
172
+ interaction.expiresAt =
173
+ Date.now() + Math.min(10 * 60_000, params.autoResolutionMs ?? 10 * 60_000);
107
174
  interaction.questions = params.questions.map((question) => ({
108
175
  id: question.id,
109
176
  header: question.header,
@@ -117,9 +184,11 @@ export function parseCodexInteraction(method, value, cwd, fileChanges) {
117
184
  }
118
185
  if (JSON.stringify(interaction).length > 64_000)
119
186
  return { error: "Request too large. Handle locally, then /resume." };
187
+ if (interaction.kind === "approval" && !interaction.choices.length)
188
+ return { error: "No supported approval options. Handle locally, then /resume." };
120
189
  return {
121
190
  request: interaction,
122
- ...(permissions ? { permissions } : {}),
191
+ approvals,
123
192
  ...(fileReview ? { fileReview } : {}),
124
193
  };
125
194
  }
@@ -1 +1 @@
1
- {"version":3,"file":"codex-interaction.js","sourceRoot":"","sources":["../../src/agents/codex-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,uCAAuC;AACvC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CACtC,CAAC,CAAC,MAAM,CAAC;IACP,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;IAC9F,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;CACjB,CAAC,CACH,CAAC;AAEF,2CAA2C;AAC3C,MAAM,UAAU,qBAAqB,CACnC,MAAc,EACd,KAAc,EACd,GAAW,EACX,WAAmE;IAQnE,MAAM,WAAW,GAAqB;QACpC,EAAE,EAAE,UAAU,EAAE;QAChB,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,EAAE;QACR,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM;QACnC,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;QAC9B,SAAS,EAAE,EAAE;KACd,CAAC;IACF,IAAI,WAAgD,CAAC;IACrD,IAAI,UAA2D,CAAC;IAChE,IAAI,MAAM,KAAK,uCAAuC,EAAE,CAAC;QACvD,MAAM,MAAM,GAAG,CAAC;aACb,MAAM,CAAC;YACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;YAClB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;YAC1D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE;YAC7B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE;YACzB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE;YAC5B,sBAAsB,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE;YACtF,qBAAqB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;YAC7C,kBAAkB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;SACnD,CAAC;aACD,KAAK,CAAC,KAAK,CAAC,CAAC;QAChB,WAAW,CAAC,IAAI,GAAG,GAAG,MAAM,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,gBAAgB,MAAM,CAAC,GAAG,IAAI,GAAG,KAAK,MAAM,CAAC,OAAO,IAAI,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,cAAc,MAAM,CAAC,sBAAsB,CAAC,QAAQ,MAAM,MAAM,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC,kBAAkB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,qBAAqB,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC5c,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAC9C,CAAC,MAAM,EAAE,EAAE,CACT,CAAC,MAAM,CAAC,kBAAkB,IAAI,IAAI,IAAI,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACjF,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAC/E,CAAC;IACJ,CAAC;SAAM,IAAI,MAAM,KAAK,iCAAiC,EAAE,CAAC;QACxD,MAAM,MAAM,GAAG,CAAC;aACb,MAAM,CAAC;YACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;YAClB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;YAClB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE;YAC5B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE;SAChC,CAAC;aACD,KAAK,CAAC,KAAK,CAAC,CAAC;QAChB,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,OAAO,EAAE,MAAM;YAAE,UAAU,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9F,WAAW,CAAC,IAAI,GAAG,4BAA4B,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,mBAAmB,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,uCAAuC,EAAE,CAAC;QAClY,IAAI,CAAC,OAAO,EAAE,MAAM;YAAE,WAAW,CAAC,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC;IAC1D,CAAC;SAAM,IAAI,MAAM,KAAK,kCAAkC,EAAE,CAAC;QACzD,MAAM,MAAM,GAAG,CAAC;aACb,MAAM,CAAC;YACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;YAClB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;YACf,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE;YAC5B,WAAW,EAAE,CAAC,CAAC,YAAY,CAAC;gBAC1B,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE;gBACtE,UAAU,EAAE,CAAC;qBACV,YAAY,CAAC;oBACZ,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;oBACpC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;oBACrC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;oBAC3D,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;iBACzC,CAAC;qBACD,OAAO,EAAE;aACb,CAAC;SACH,CAAC;aACD,KAAK,CAAC,KAAK,CAAC,CAAC;QAChB,WAAW,GAAG,MAAM,CAAC,WAAW,CAC9B,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,CAAC,CACxE,CAAC;QACF,WAAW,CAAC,IAAI,GAAG,4CAA4C,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;IAC3K,CAAC;SAAM,IAAI,MAAM,KAAK,4BAA4B,EAAE,CAAC;QACnD,MAAM,MAAM,GAAG,CAAC;aACb,MAAM,CAAC;YACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;YAClB,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;YACrC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE;YAC1D,SAAS,EAAE,CAAC;iBACT,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;gBACP,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;gBACrB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;gBAClB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;gBACpB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;gBACnC,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;gBACpC,OAAO,EAAE,CAAC;qBACP,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;qBACtE,GAAG,CAAC,EAAE,CAAC;qBACP,QAAQ,EAAE;aACd,CAAC,CACH;iBACA,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,EAAE,CAAC;SACX,CAAC;aACD,KAAK,CAAC,KAAK,CAAC,CAAC;QAChB,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACxD,OAAO,EAAE,KAAK,EAAE,yDAAyD,EAAE,CAAC;QAC9E,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,SAAS,CAAC,MAAM;YAC3F,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC7C,WAAW,CAAC,IAAI,GAAG,UAAU,CAAC;QAC9B,WAAW,CAAC,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC;QACzC,WAAW,CAAC,OAAO,GAAG,EAAE,CAAC;QACzB,WAAW,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAC9B,WAAW,CAAC,SAAS,EACrB,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,gBAAgB,IAAI,EAAE,GAAG,MAAM,CAAC,CACtD,CAAC;QACF,WAAW,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAC1D,EAAE,EAAE,QAAQ,CAAC,EAAE;YACf,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,EAAE;YAC/B,SAAS,EAAE,QAAQ,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM;SACzD,CAAC,CAAC,CAAC;IACN,CAAC;SAAM,CAAC;QACN,OAAO,EAAE,KAAK,EAAE,oDAAoD,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC5F,CAAC;IACD,IAAI,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,MAAM;QAC7C,OAAO,EAAE,KAAK,EAAE,kDAAkD,EAAE,CAAC;IACvE,OAAO;QACL,OAAO,EAAE,WAAW;QACpB,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"codex-interaction.js","sourceRoot":"","sources":["../../src/agents/codex-interaction.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,7 @@ import { promisify } from "node:util";
6
6
  import { JSONRPCErrorException } from "json-rpc-2.0";
7
7
  import WebSocket from "ws";
8
8
  import { z } from "zod";
9
- import { fileChangesSchema, parseCodexInteraction } from "./codex-interaction.js";
9
+ import { fileChangesSchema, parseCodexInteraction, } from "./codex-interaction.js";
10
10
  import { createCodexRpc } from "./codex-rpc.js";
11
11
  /** 由 Codex 0.165.0 的 generate-ts 核对;只校验实际消费的协议字段。 */
12
12
  const turnSchema = z.object({
@@ -101,61 +101,92 @@ export async function createCodexAgent(command = "codex") {
101
101
  }
102
102
  throw new Error("Codex daemon unavailable.");
103
103
  }
104
+ /** 模型菜单与状态共用只读连接;按需读取目录配置,不恢复会话或发起轮次。 */
105
+ async function readModelData(cwd, signal, includeConfig = false) {
106
+ signal = AbortSignal.any([signal, AbortSignal.timeout(15_000)]);
107
+ const rpc = createCodexRpc(await connectServer(cwd, signal));
108
+ /** 取消仅关闭目录查询,不能向正在运行的轮次发送中断。 */
109
+ const abort = () => rpc.close("Codex model query cancelled.");
110
+ signal.addEventListener("abort", abort, { once: true });
111
+ try {
112
+ signal.throwIfAborted();
113
+ await rpc.initialize();
114
+ const config = includeConfig
115
+ ? z
116
+ .object({
117
+ config: z.object({
118
+ model: z.string().min(1).nullish(),
119
+ model_reasoning_effort: z.string().min(1).nullish(),
120
+ }),
121
+ })
122
+ .parse(await rpc.request("config/read", { cwd, includeLayers: false })).config
123
+ : undefined;
124
+ const models = [];
125
+ let defaultModel;
126
+ let cursor = null;
127
+ do {
128
+ signal.throwIfAborted();
129
+ const page = z
130
+ .object({
131
+ data: z.array(z.object({
132
+ model: z.string().min(1),
133
+ displayName: z.string(),
134
+ hidden: z.boolean(),
135
+ isDefault: z.boolean().optional(),
136
+ supportedReasoningEfforts: z.array(z.object({
137
+ reasoningEffort: z.string().min(1),
138
+ description: z.string(),
139
+ })),
140
+ defaultReasoningEffort: z.string().min(1),
141
+ })),
142
+ nextCursor: z.string().nullable(),
143
+ })
144
+ .parse(await rpc.request("model/list", { limit: 100, includeHidden: includeConfig, cursor }));
145
+ for (const model of page.data) {
146
+ if (model.isDefault)
147
+ defaultModel = model.model;
148
+ if ((includeConfig || !model.hidden) &&
149
+ !models.some((option) => option.id === model.model))
150
+ models.push({
151
+ id: model.model,
152
+ label: model.displayName || model.model,
153
+ reasoningEfforts: model.supportedReasoningEfforts.map((effort) => ({
154
+ id: effort.reasoningEffort,
155
+ label: effort.description,
156
+ })),
157
+ defaultReasoningEffort: model.defaultReasoningEffort,
158
+ });
159
+ }
160
+ cursor = page.nextCursor;
161
+ } while (cursor);
162
+ return { models, defaultModel, config };
163
+ }
164
+ catch {
165
+ throw new Error("Codex model query failed. Check the local configuration and connection.");
166
+ }
167
+ finally {
168
+ signal.removeEventListener("abort", abort);
169
+ rpc.close();
170
+ }
171
+ }
104
172
  return {
105
173
  name: "Codex",
106
174
  version: stdout.trim().replace(/^codex-cli /, ""),
107
175
  permissionModes: permissionModes.map(({ id, label }) => ({ id, label })),
108
- /** 分页读取模型目录;不恢复会话、不发起轮次,也不影响任务连接。 */
109
176
  async listModels(cwd, signal) {
110
- signal = AbortSignal.any([signal, AbortSignal.timeout(15_000)]);
111
- const rpc = createCodexRpc(await connectServer(cwd, signal));
112
- /** 取消仅关闭目录查询,不能向正在运行的轮次发送中断。 */
113
- const abort = () => rpc.close("Codex model query cancelled.");
114
- signal.addEventListener("abort", abort, { once: true });
115
- try {
116
- signal.throwIfAborted();
117
- await rpc.initialize();
118
- const models = [];
119
- let cursor = null;
120
- do {
121
- signal.throwIfAborted();
122
- const page = z
123
- .object({
124
- data: z.array(z.object({
125
- model: z.string().min(1),
126
- displayName: z.string(),
127
- hidden: z.boolean(),
128
- supportedReasoningEfforts: z.array(z.object({
129
- reasoningEffort: z.string().min(1),
130
- description: z.string(),
131
- })),
132
- defaultReasoningEffort: z.string().min(1),
133
- })),
134
- nextCursor: z.string().nullable(),
135
- })
136
- .parse(await rpc.request("model/list", { limit: 100, includeHidden: false, cursor }));
137
- for (const model of page.data)
138
- if (!model.hidden && !models.some((option) => option.id === model.model))
139
- models.push({
140
- id: model.model,
141
- label: model.displayName || model.model,
142
- reasoningEfforts: model.supportedReasoningEfforts.map((effort) => ({
143
- id: effort.reasoningEffort,
144
- label: effort.description,
145
- })),
146
- defaultReasoningEffort: model.defaultReasoningEffort,
147
- });
148
- cursor = page.nextCursor;
149
- } while (cursor);
150
- return models;
151
- }
152
- catch {
153
- throw new Error("Codex model query failed. Check the local configuration and connection.");
154
- }
155
- finally {
156
- signal.removeEventListener("abort", abort);
157
- rpc.close();
158
- }
177
+ return (await readModelData(cwd, signal)).models;
178
+ },
179
+ async describeModel(cwd, selection, signal) {
180
+ /** 已选模型可能已从菜单隐藏,状态仍需查询完整目录中的展示名称。 */
181
+ const { models, defaultModel, config } = await readModelData(cwd, signal, true);
182
+ const id = selection.model ?? config?.model ?? defaultModel;
183
+ const model = models.find((option) => option.id === id);
184
+ const reasoningEffort = selection.reasoningEffort ??
185
+ config?.model_reasoning_effort ??
186
+ model?.defaultReasoningEffort;
187
+ if (!id || !reasoningEffort)
188
+ throw new Error("Codex model settings unavailable.");
189
+ return { id, label: model?.label ?? id, reasoningEffort };
159
190
  },
160
191
  async run(input) {
161
192
  if (active)
@@ -183,6 +214,7 @@ export async function createCodexAgent(command = "codex") {
183
214
  };
184
215
  }
185
216
  const completed = Promise.withResolvers();
217
+ /** 按首次出现顺序保存全部回复与文件变更标题,完整事件覆盖同一条增量。 */
186
218
  const messages = new Map();
187
219
  /** 应用随机 ID 隔离每次连接;已见 RPC 编号保留到任务结束,重复请求不生成新按钮。 */
188
220
  const interactions = new Map();
@@ -195,6 +227,8 @@ export async function createCodexAgent(command = "codex") {
195
227
  let runId;
196
228
  let dispatched = Boolean(input.runId);
197
229
  let settled = false;
230
+ /** 原生 Cancel 的已确认中断视为用户取消,不能误报异常并暂停聊天。 */
231
+ let cancelledByApproval = false;
198
232
  let stopTimer;
199
233
  /** 只接受第一个终态,避免退出事件覆盖已经确认的执行结果。 */
200
234
  function finish(result) {
@@ -204,15 +238,25 @@ export async function createCodexAgent(command = "codex") {
204
238
  for (const interaction of interactions.values())
205
239
  clearTimeout(interaction.timer);
206
240
  interactions.clear();
207
- completed.resolve(result);
241
+ completed.resolve(result
242
+ ? {
243
+ ...result,
244
+ text: [formatOutput(), result.text].filter(Boolean).join("\n\n") ||
245
+ "Codex finished with no text output.",
246
+ }
247
+ : undefined);
208
248
  }
209
- /** 增量与完整消息共用输出上限;只推送回复文本,不推送思考或工具原始输出。 */
210
- function publishText(text) {
211
- if ([...messages.values()].reduce((sum, item) => sum + item.text.length, 0) > 256_000) {
212
- fail("Codex output limit exceeded. Task interrupted; check the local session.");
213
- return;
214
- }
215
- input.onText(text);
249
+ /** 预览和结果共用完整内容;保留过程说明、最终回复及文件差异,由 IM 分段发送。 */
250
+ function formatOutput() {
251
+ return [...messages]
252
+ .map(([id, text]) => [
253
+ text,
254
+ ...(fileChanges.get(id) ?? []).map((change) => `${change.kind.type}: ${change.path}${change.kind.move_path ? ` → ${change.kind.move_path}` : ""}\n${change.diff}`),
255
+ ]
256
+ .filter(Boolean)
257
+ .join("\n\n"))
258
+ .filter(Boolean)
259
+ .join("\n\n");
216
260
  }
217
261
  /** 通信故障不等于执行失败;保留不确定状态并结束当前连接。 */
218
262
  function fail(text) {
@@ -321,25 +365,27 @@ export async function createCodexAgent(command = "codex") {
321
365
  interactions.set(interaction.id, {
322
366
  requestId: message.id,
323
367
  ...parsed,
324
- timer: setTimeout(() => {
325
- const pending = interactions.get(interaction.id);
326
- if (!pending)
327
- return;
328
- if (interaction.blocking) {
329
- fail("Request timed out. Check /last, then /resume.");
330
- }
331
- else {
332
- interactions.delete(interaction.id);
333
- /** 非阻塞问题过期只返回空答案,不替用户选择,也不中断正在执行的任务。 */
334
- try {
335
- input.onInteractionClosed(interaction.id, "Question expired. Task continues.");
336
- rpc.write({ id: pending.requestId, result: { answers: {} } });
368
+ timer: interaction.expiresAt === null
369
+ ? undefined
370
+ : setTimeout(() => {
371
+ const pending = interactions.get(interaction.id);
372
+ if (!pending)
373
+ return;
374
+ if (interaction.blocking) {
375
+ fail("Request timed out. Check /last, then /resume.");
337
376
  }
338
- catch {
339
- fail("Cannot save expired question state. Task interrupted.");
377
+ else {
378
+ interactions.delete(interaction.id);
379
+ /** 非阻塞问题过期只返回空答案,不替用户选择,也不中断正在执行的任务。 */
380
+ try {
381
+ input.onInteractionClosed(interaction.id, "Question expired. Task continues.");
382
+ rpc.write({ id: pending.requestId, result: { answers: {} } });
383
+ }
384
+ catch {
385
+ fail("Cannot save expired question state. Task interrupted.");
386
+ }
340
387
  }
341
- }
342
- }, Math.max(0, interaction.expiresAt - Date.now())),
388
+ }, Math.max(0, interaction.expiresAt - Date.now())),
343
389
  });
344
390
  input.onInteraction(interaction);
345
391
  }
@@ -367,8 +413,12 @@ export async function createCodexAgent(command = "codex") {
367
413
  changes: fileChangesSchema,
368
414
  })
369
415
  .parse(message.params);
370
- if (event.threadId === sessionId && event.turnId === runId)
416
+ if (event.threadId === sessionId && event.turnId === runId) {
371
417
  fileChanges.set(event.itemId, event.changes);
418
+ if (!messages.has(event.itemId))
419
+ messages.set(event.itemId, "File changes");
420
+ input.onText(formatOutput());
421
+ }
372
422
  }
373
423
  else if (message.method === "item/agentMessage/delta") {
374
424
  const event = z
@@ -381,10 +431,8 @@ export async function createCodexAgent(command = "codex") {
381
431
  .parse(message.params);
382
432
  if (event.threadId !== sessionId || !recordRun(event.turnId))
383
433
  return;
384
- const item = messages.get(event.itemId) ?? { text: "" };
385
- item.text += event.delta;
386
- messages.set(event.itemId, item);
387
- publishText(item.text);
434
+ messages.set(event.itemId, (messages.get(event.itemId) ?? "") + event.delta);
435
+ input.onText(formatOutput());
388
436
  }
389
437
  else if (message.method === "item/started" || message.method === "item/completed") {
390
438
  const event = z
@@ -395,18 +443,22 @@ export async function createCodexAgent(command = "codex") {
395
443
  type: z.string(),
396
444
  id: z.string(),
397
445
  text: z.string().optional(),
398
- phase: z.string().nullish(),
446
+ status: z.string().optional(),
399
447
  changes: fileChangesSchema.optional(),
400
448
  }),
401
449
  })
402
450
  .parse(message.params);
403
451
  if (event.threadId !== sessionId || !recordRun(event.turnId))
404
452
  return;
405
- if (event.item.type === "fileChange" && event.item.changes)
406
- fileChanges.set(event.item.id, event.item.changes);
453
+ if (event.item.type === "fileChange") {
454
+ if (event.item.changes)
455
+ fileChanges.set(event.item.id, event.item.changes);
456
+ messages.set(event.item.id, `File changes${event.item.status ? ` (${event.item.status})` : ""}`);
457
+ input.onText(formatOutput());
458
+ }
407
459
  if (event.item.type === "agentMessage" && event.item.text !== undefined) {
408
- messages.set(event.item.id, { text: event.item.text, phase: event.item.phase });
409
- publishText(event.item.text);
460
+ messages.set(event.item.id, event.item.text);
461
+ input.onText(formatOutput());
410
462
  }
411
463
  }
412
464
  else if (message.method === "turn/started" || message.method === "turn/completed") {
@@ -416,23 +468,19 @@ export async function createCodexAgent(command = "codex") {
416
468
  if (event.threadId !== sessionId || !recordRun(event.turn.id))
417
469
  return;
418
470
  if (message.method === "turn/completed") {
419
- const final = [...messages.values()].filter((item) => item.phase === "final_answer");
420
471
  finish({
421
472
  status: event.turn.status === "completed"
422
473
  ? "completed"
423
474
  : event.turn.status === "failed"
424
475
  ? "failed"
425
- : controller.signal.aborted
476
+ : controller.signal.aborted || cancelledByApproval
426
477
  ? "cancelled"
427
478
  : "interrupted",
428
- text: (final.length ? final : [...messages.values()])
429
- .map((item) => item.text)
430
- .join("\n\n") ||
431
- (event.turn.status === "completed"
432
- ? "Codex finished with no text output."
433
- : event.turn.status === "failed"
434
- ? "Codex task failed. Check sign-in, model access, and network."
435
- : "Task interrupted. File changes were not reverted."),
479
+ text: event.turn.status === "completed"
480
+ ? ""
481
+ : event.turn.status === "failed"
482
+ ? "Codex task failed. Check sign-in, model access, and network."
483
+ : "Task interrupted. File changes were not reverted.",
436
484
  });
437
485
  }
438
486
  }
@@ -460,12 +508,13 @@ export async function createCodexAgent(command = "codex") {
460
508
  if (!interaction ||
461
509
  settled ||
462
510
  controller.signal.aborted ||
463
- interaction.request.expiresAt <= Date.now())
511
+ (interaction.request.expiresAt !== null && interaction.request.expiresAt <= Date.now()))
464
512
  return false;
513
+ const approval = "decision" in answer ? interaction.approvals.get(answer.decision) : undefined;
465
514
  if (interaction.request.kind === "approval") {
466
- if (!("decision" in answer) || !interaction.request.choices.includes(answer.decision))
515
+ if (!("decision" in answer) || !approval)
467
516
  return false;
468
- if (answer.decision === "accept" &&
517
+ if (approval.approved &&
469
518
  interaction.fileReview &&
470
519
  JSON.stringify(fileChanges.get(interaction.fileReview.itemId)) !==
471
520
  interaction.fileReview.changes) {
@@ -486,16 +535,11 @@ export async function createCodexAgent(command = "codex") {
486
535
  /** 在写入前移除映射,失败也不重发批准;任务终态负责说明不确定结果。 */
487
536
  interactions.delete(id);
488
537
  clearTimeout(interaction.timer);
538
+ if (approval?.result.decision === "cancel")
539
+ cancelledByApproval = true;
489
540
  rpc.write({
490
541
  id: interaction.requestId,
491
- result: interaction.permissions
492
- ? {
493
- permissions: "decision" in answer && answer.decision === "accept"
494
- ? interaction.permissions
495
- : {},
496
- scope: "turn",
497
- }
498
- : answer,
542
+ result: approval ? approval.result : answer,
499
543
  });
500
544
  return !settled;
501
545
  };