codex-relay 1.2.3 → 1.3.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.
@@ -1,2 +1,2 @@
1
- import { $ as SandboxModeSchema, A as PairResponseSchema, At as WorkspaceSelectionRequestSchema, B as QueuedThreadInputSchema, Bt as chatMessageDetailsFromPromptContext, C as ListQueuedThreadInputsResponseSchema, Ct as WorkspaceDirectoryEntrySchema, D as ListWorkspaceFilesResponseSchema, Dt as WorkspaceMarkdownPreviewTargetSchema, E as ListWorkspaceDirectoriesResponseSchema, Et as WorkspaceGitActionResponseSchema, F as PromptAttachmentSummarySchema, Ft as WorkspaceTerminalOutputResponseSchema, G as ResolveApprovalRequestSchema, Gt as promptSkillDisplayName, H as RateLimitWindowSchema, Ht as isPromptSkillMarkdownMention, I as PromptContextInputSchema, It as WorkspaceTerminalResizeRequestSchema, J as RunThreadResponseSchema, Jt as promptSkillMentionTextCandidates, K as ResolveApprovalResponseSchema, Kt as promptSkillMentionLabel, L as PromptContextSchema, Lt as WorkspaceTerminalSessionResponseSchema, M as PendingInputRequestQuestionSchema, Mt as WorkspaceTailscaleServeResponseSchema, N as PendingInputRequestSchema, Nt as WorkspaceTerminalInputRequestSchema, O as PairEncryptedPayloadSchema, Ot as WorkspacePreviewNavigationRequestSchema, P as PromptAttachmentSchema, Pt as WorkspaceTerminalOutputChunkSchema, Q as RuntimePreferencesSchema, R as PromptSkillSchema, Rt as WorkspaceTerminalStartRequestSchema, S as ListModelsResponseSchema, St as WorkspaceChangesResponseSchema, T as ListThreadsResponseSchema, Tt as WorkspaceFileMentionSchema, U as RateLimitsResponseSchema, Ut as normalizePromptContext, V as RateLimitBucketSchema, Vt as createOpenApiDocument, W as ReasoningEffortSchema, Wt as promptMarkdownWithSkills, X as RuntimePreferencesByWorkspacePathSchema, Y as RuntimeModeSchema, Yt as stripPromptSkillMentions, Z as RuntimePreferencesResponseSchema, _ as EncryptedPayloadSchema, _t as UpdateWorkspaceFileContentRequestSchema, a as ArchiveThreadResponseSchema, at as ThreadContextWindowResponseSchema, b as InterruptThreadRunResponseSchema, bt as WORKSPACE_PREVIEW_TAB_VALUES, c as ChatMessageRoleSchema, ct as ThreadGoalSchema, d as CheckoutWorkspaceBranchRequestSchema, dt as ThreadMessageDetailResponseSchema, et as StatusResponseSchema, f as CodexModelSchema, ft as ThreadRunOptionsSchema, g as CreateThreadResponseSchema, gt as UpdateThreadGoalRequestSchema, h as CreateThreadRequestSchema, ht as UpdateRuntimePreferencesRequestSchema, i as ApprovalModeSchema, it as ThreadCollaborationModeSchema, j as PendingInputRequestOptionSchema, jt as WorkspaceTailscaleServeRequestSchema, k as PairRequestSchema, kt as WorkspacePreviewTabSchema, l as ChatMessageSchema, lt as ThreadGoalStatusSchema, m as ContextWindowUsageSchema, mt as ThreadSummarySchema, n as AgentSkillSourceSchema, nt as StreamThreadRunRequestSchema, o as ChatMessageKindSchema, ot as ThreadDetailResponseSchema, p as CommitPushWorkspaceRequestSchema, pt as ThreadStateSchema, q as RunThreadRequestSchema, qt as promptSkillMentionMarkdown, r as ApprovalDecisionSchema, rt as SubmitThreadInputResponseSchema, s as ChatMessagePromptDetailsSchema, st as ThreadGoalResponseSchema, t as AgentSkillSchema, tt as StreamThreadRunEventSchema, u as ChatMessageStateSchema, ut as ThreadMessageDetailFieldSchema, v as ErrorResponseSchema, vt as VersionResponseSchema, w as ListSkillsResponseSchema, wt as WorkspaceFileContentResponseSchema, x as IsoDateTimeSchema, xt as WebPreviewTargetSchema, y as ImageAttachmentUploadResponseSchema, yt as WORKSPACE_PREVIEW_OPEN_PROTOCOL, z as QueuedThreadInputActionResponseSchema, zt as apiPaths } from "./api-schema2.js";
2
- export { AgentSkillSchema, AgentSkillSourceSchema, ApprovalDecisionSchema, ApprovalModeSchema, ArchiveThreadResponseSchema, ChatMessageKindSchema, ChatMessagePromptDetailsSchema, ChatMessageRoleSchema, ChatMessageSchema, ChatMessageStateSchema, CheckoutWorkspaceBranchRequestSchema, CodexModelSchema, CommitPushWorkspaceRequestSchema, ContextWindowUsageSchema, CreateThreadRequestSchema, CreateThreadResponseSchema, EncryptedPayloadSchema, ErrorResponseSchema, ImageAttachmentUploadResponseSchema, InterruptThreadRunResponseSchema, IsoDateTimeSchema, ListModelsResponseSchema, ListQueuedThreadInputsResponseSchema, ListSkillsResponseSchema, ListThreadsResponseSchema, ListWorkspaceDirectoriesResponseSchema, ListWorkspaceFilesResponseSchema, PairEncryptedPayloadSchema, PairRequestSchema, PairResponseSchema, PendingInputRequestOptionSchema, PendingInputRequestQuestionSchema, PendingInputRequestSchema, PromptAttachmentSchema, PromptAttachmentSummarySchema, PromptContextInputSchema, PromptContextSchema, PromptSkillSchema, QueuedThreadInputActionResponseSchema, QueuedThreadInputSchema, RateLimitBucketSchema, RateLimitWindowSchema, RateLimitsResponseSchema, ReasoningEffortSchema, ResolveApprovalRequestSchema, ResolveApprovalResponseSchema, RunThreadRequestSchema, RunThreadResponseSchema, RuntimeModeSchema, RuntimePreferencesByWorkspacePathSchema, RuntimePreferencesResponseSchema, RuntimePreferencesSchema, SandboxModeSchema, StatusResponseSchema, StreamThreadRunEventSchema, StreamThreadRunRequestSchema, SubmitThreadInputResponseSchema, ThreadCollaborationModeSchema, ThreadContextWindowResponseSchema, ThreadDetailResponseSchema, ThreadGoalResponseSchema, ThreadGoalSchema, ThreadGoalStatusSchema, ThreadMessageDetailFieldSchema, ThreadMessageDetailResponseSchema, ThreadRunOptionsSchema, ThreadStateSchema, ThreadSummarySchema, UpdateRuntimePreferencesRequestSchema, UpdateThreadGoalRequestSchema, UpdateWorkspaceFileContentRequestSchema, VersionResponseSchema, WORKSPACE_PREVIEW_OPEN_PROTOCOL, WORKSPACE_PREVIEW_TAB_VALUES, WebPreviewTargetSchema, WorkspaceChangesResponseSchema, WorkspaceDirectoryEntrySchema, WorkspaceFileContentResponseSchema, WorkspaceFileMentionSchema, WorkspaceGitActionResponseSchema, WorkspaceMarkdownPreviewTargetSchema, WorkspacePreviewNavigationRequestSchema, WorkspacePreviewTabSchema, WorkspaceSelectionRequestSchema, WorkspaceTailscaleServeRequestSchema, WorkspaceTailscaleServeResponseSchema, WorkspaceTerminalInputRequestSchema, WorkspaceTerminalOutputChunkSchema, WorkspaceTerminalOutputResponseSchema, WorkspaceTerminalResizeRequestSchema, WorkspaceTerminalSessionResponseSchema, WorkspaceTerminalStartRequestSchema, apiPaths, chatMessageDetailsFromPromptContext, createOpenApiDocument, isPromptSkillMarkdownMention, normalizePromptContext, promptMarkdownWithSkills, promptSkillDisplayName, promptSkillMentionLabel, promptSkillMentionMarkdown, promptSkillMentionTextCandidates, stripPromptSkillMentions };
1
+ import { $ as RuntimePreferencesSchema, A as PairRequestSchema, At as WorkspacePreviewTabSchema, B as QueuedThreadInputActionResponseSchema, Bt as apiPaths, C as ListModelsResponseSchema, Ct as WorkspaceChangesResponseSchema, D as ListWorkspaceDirectoriesResponseSchema, Dt as WorkspaceGitActionResponseSchema, E as ListThreadsResponseSchema, Et as WorkspaceFileMentionSchema, F as PromptAttachmentSchema, Ft as WorkspaceTerminalOutputChunkSchema, G as ReasoningEffortSchema, Gt as promptMarkdownWithSkills, H as RateLimitBucketSchema, Ht as createOpenApiDocument, I as PromptAttachmentSummarySchema, It as WorkspaceTerminalOutputResponseSchema, J as RunThreadRequestSchema, Jt as promptSkillMentionMarkdown, K as ResolveApprovalRequestSchema, Kt as promptSkillDisplayName, L as PromptContextInputSchema, Lt as WorkspaceTerminalResizeRequestSchema, M as PendingInputRequestOptionSchema, Mt as WorkspaceTailscaleServeRequestSchema, N as PendingInputRequestQuestionSchema, Nt as WorkspaceTailscaleServeResponseSchema, O as ListWorkspaceFilesResponseSchema, Ot as WorkspaceMarkdownPreviewTargetSchema, P as PendingInputRequestSchema, Pt as WorkspaceTerminalInputRequestSchema, Q as RuntimePreferencesResponseSchema, R as PromptContextSchema, Rt as WorkspaceTerminalSessionResponseSchema, S as KnownReasoningEffortSchema, St as WebPreviewTargetSchema, T as ListSkillsResponseSchema, Tt as WorkspaceFileContentResponseSchema, U as RateLimitWindowSchema, Ut as isPromptSkillMarkdownMention, V as QueuedThreadInputSchema, Vt as chatMessageDetailsFromPromptContext, W as RateLimitsResponseSchema, Wt as normalizePromptContext, X as RuntimeModeSchema, Xt as stripPromptSkillMentions, Y as RunThreadResponseSchema, Yt as promptSkillMentionTextCandidates, Z as RuntimePreferencesByWorkspacePathSchema, _ as EncryptedPayloadSchema, _t as UpdateThreadGoalRequestSchema, a as ArchiveThreadResponseSchema, at as ThreadCollaborationModeSchema, b as InterruptThreadRunResponseSchema, bt as WORKSPACE_PREVIEW_OPEN_PROTOCOL, c as ChatMessageRoleSchema, ct as ThreadGoalResponseSchema, d as CheckoutWorkspaceBranchRequestSchema, dt as ThreadMessageDetailFieldSchema, et as SandboxModeSchema, f as CodexModelSchema, ft as ThreadMessageDetailResponseSchema, g as CreateThreadResponseSchema, gt as UpdateRuntimePreferencesRequestSchema, h as CreateThreadRequestSchema, ht as ThreadSummarySchema, i as ApprovalModeSchema, it as SubmitThreadInputResponseSchema, j as PairResponseSchema, jt as WorkspaceSelectionRequestSchema, k as PairEncryptedPayloadSchema, kt as WorkspacePreviewNavigationRequestSchema, l as ChatMessageSchema, lt as ThreadGoalSchema, m as ContextWindowUsageSchema, mt as ThreadStateSchema, n as AgentSkillSourceSchema, nt as StreamThreadRunEventSchema, o as ChatMessageKindSchema, ot as ThreadContextWindowResponseSchema, p as CommitPushWorkspaceRequestSchema, pt as ThreadRunOptionsSchema, q as ResolveApprovalResponseSchema, qt as promptSkillMentionLabel, r as ApprovalDecisionSchema, rt as StreamThreadRunRequestSchema, s as ChatMessagePromptDetailsSchema, st as ThreadDetailResponseSchema, t as AgentSkillSchema, tt as StatusResponseSchema, u as ChatMessageStateSchema, ut as ThreadGoalStatusSchema, v as ErrorResponseSchema, vt as UpdateWorkspaceFileContentRequestSchema, w as ListQueuedThreadInputsResponseSchema, wt as WorkspaceDirectoryEntrySchema, x as IsoDateTimeSchema, xt as WORKSPACE_PREVIEW_TAB_VALUES, y as ImageAttachmentUploadResponseSchema, yt as VersionResponseSchema, z as PromptSkillSchema, zt as WorkspaceTerminalStartRequestSchema } from "./api-schema2.js";
2
+ export { AgentSkillSchema, AgentSkillSourceSchema, ApprovalDecisionSchema, ApprovalModeSchema, ArchiveThreadResponseSchema, ChatMessageKindSchema, ChatMessagePromptDetailsSchema, ChatMessageRoleSchema, ChatMessageSchema, ChatMessageStateSchema, CheckoutWorkspaceBranchRequestSchema, CodexModelSchema, CommitPushWorkspaceRequestSchema, ContextWindowUsageSchema, CreateThreadRequestSchema, CreateThreadResponseSchema, EncryptedPayloadSchema, ErrorResponseSchema, ImageAttachmentUploadResponseSchema, InterruptThreadRunResponseSchema, IsoDateTimeSchema, KnownReasoningEffortSchema, ListModelsResponseSchema, ListQueuedThreadInputsResponseSchema, ListSkillsResponseSchema, ListThreadsResponseSchema, ListWorkspaceDirectoriesResponseSchema, ListWorkspaceFilesResponseSchema, PairEncryptedPayloadSchema, PairRequestSchema, PairResponseSchema, PendingInputRequestOptionSchema, PendingInputRequestQuestionSchema, PendingInputRequestSchema, PromptAttachmentSchema, PromptAttachmentSummarySchema, PromptContextInputSchema, PromptContextSchema, PromptSkillSchema, QueuedThreadInputActionResponseSchema, QueuedThreadInputSchema, RateLimitBucketSchema, RateLimitWindowSchema, RateLimitsResponseSchema, ReasoningEffortSchema, ResolveApprovalRequestSchema, ResolveApprovalResponseSchema, RunThreadRequestSchema, RunThreadResponseSchema, RuntimeModeSchema, RuntimePreferencesByWorkspacePathSchema, RuntimePreferencesResponseSchema, RuntimePreferencesSchema, SandboxModeSchema, StatusResponseSchema, StreamThreadRunEventSchema, StreamThreadRunRequestSchema, SubmitThreadInputResponseSchema, ThreadCollaborationModeSchema, ThreadContextWindowResponseSchema, ThreadDetailResponseSchema, ThreadGoalResponseSchema, ThreadGoalSchema, ThreadGoalStatusSchema, ThreadMessageDetailFieldSchema, ThreadMessageDetailResponseSchema, ThreadRunOptionsSchema, ThreadStateSchema, ThreadSummarySchema, UpdateRuntimePreferencesRequestSchema, UpdateThreadGoalRequestSchema, UpdateWorkspaceFileContentRequestSchema, VersionResponseSchema, WORKSPACE_PREVIEW_OPEN_PROTOCOL, WORKSPACE_PREVIEW_TAB_VALUES, WebPreviewTargetSchema, WorkspaceChangesResponseSchema, WorkspaceDirectoryEntrySchema, WorkspaceFileContentResponseSchema, WorkspaceFileMentionSchema, WorkspaceGitActionResponseSchema, WorkspaceMarkdownPreviewTargetSchema, WorkspacePreviewNavigationRequestSchema, WorkspacePreviewTabSchema, WorkspaceSelectionRequestSchema, WorkspaceTailscaleServeRequestSchema, WorkspaceTailscaleServeResponseSchema, WorkspaceTerminalInputRequestSchema, WorkspaceTerminalOutputChunkSchema, WorkspaceTerminalOutputResponseSchema, WorkspaceTerminalResizeRequestSchema, WorkspaceTerminalSessionResponseSchema, WorkspaceTerminalStartRequestSchema, apiPaths, chatMessageDetailsFromPromptContext, createOpenApiDocument, isPromptSkillMarkdownMention, normalizePromptContext, promptMarkdownWithSkills, promptSkillDisplayName, promptSkillMentionLabel, promptSkillMentionMarkdown, promptSkillMentionTextCandidates, stripPromptSkillMentions };
@@ -49,13 +49,16 @@ const SandboxModeSchema = z.enum([
49
49
  "danger-full-access",
50
50
  "read-only"
51
51
  ]);
52
- const ReasoningEffortSchema = z.enum([
52
+ const KnownReasoningEffortSchema = z.enum([
53
53
  "minimal",
54
54
  "low",
55
55
  "medium",
56
56
  "high",
57
- "xhigh"
57
+ "xhigh",
58
+ "max",
59
+ "ultra"
58
60
  ]);
61
+ const ReasoningEffortSchema = z.string().trim().min(1);
59
62
  const ThreadCollaborationModeSchema = z.enum(["default", "plan"]);
60
63
  const ThreadGoalStatusSchema = z.enum([
61
64
  "active",
@@ -109,6 +112,10 @@ const CodexModelSchema = z.object({
109
112
  isDefault: z.boolean().default(false),
110
113
  defaultReasoningEffort: ReasoningEffortSchema.optional(),
111
114
  supportedReasoningEfforts: z.array(ReasoningEffortSchema).default([]),
115
+ reasoningEffortOptions: z.array(z.object({
116
+ reasoningEffort: ReasoningEffortSchema,
117
+ description: z.string().optional()
118
+ })).default([]),
112
119
  serviceTiers: z.array(z.object({
113
120
  id: z.string().min(1),
114
121
  name: z.string().min(1),
@@ -954,6 +961,10 @@ function createOpenApiDocument() {
954
961
  type: "string",
955
962
  enum: ThreadStateSchema.options
956
963
  },
964
+ ReasoningEffort: {
965
+ type: "string",
966
+ minLength: 1
967
+ },
957
968
  ChatMessage: {
958
969
  type: "object",
959
970
  required: [
@@ -1186,13 +1197,7 @@ function createOpenApiDocument() {
1186
1197
  },
1187
1198
  reasoningEffort: {
1188
1199
  type: "string",
1189
- enum: [
1190
- "minimal",
1191
- "low",
1192
- "medium",
1193
- "high",
1194
- "xhigh"
1195
- ]
1200
+ minLength: 1
1196
1201
  }
1197
1202
  }
1198
1203
  },
@@ -1220,13 +1225,7 @@ function createOpenApiDocument() {
1220
1225
  },
1221
1226
  reasoningEffort: {
1222
1227
  type: "string",
1223
- enum: [
1224
- "minimal",
1225
- "low",
1226
- "medium",
1227
- "high",
1228
- "xhigh"
1229
- ],
1228
+ minLength: 1,
1230
1229
  nullable: true
1231
1230
  }
1232
1231
  }
@@ -1726,4 +1725,4 @@ function jsonResponse(schemaName) {
1726
1725
  };
1727
1726
  }
1728
1727
  //#endregion
1729
- export { SandboxModeSchema as $, PairResponseSchema as A, WorkspaceSelectionRequestSchema as At, QueuedThreadInputSchema as B, chatMessageDetailsFromPromptContext as Bt, ListQueuedThreadInputsResponseSchema as C, WorkspaceDirectoryEntrySchema as Ct, ListWorkspaceFilesResponseSchema as D, WorkspaceMarkdownPreviewTargetSchema as Dt, ListWorkspaceDirectoriesResponseSchema as E, WorkspaceGitActionResponseSchema as Et, PromptAttachmentSummarySchema as F, WorkspaceTerminalOutputResponseSchema as Ft, ResolveApprovalRequestSchema as G, promptSkillDisplayName as Gt, RateLimitWindowSchema as H, isPromptSkillMarkdownMention as Ht, PromptContextInputSchema as I, WorkspaceTerminalResizeRequestSchema as It, RunThreadResponseSchema as J, promptSkillMentionTextCandidates as Jt, ResolveApprovalResponseSchema as K, promptSkillMentionLabel as Kt, PromptContextSchema as L, WorkspaceTerminalSessionResponseSchema as Lt, PendingInputRequestQuestionSchema as M, WorkspaceTailscaleServeResponseSchema as Mt, PendingInputRequestSchema as N, WorkspaceTerminalInputRequestSchema as Nt, PairEncryptedPayloadSchema as O, WorkspacePreviewNavigationRequestSchema as Ot, PromptAttachmentSchema as P, WorkspaceTerminalOutputChunkSchema as Pt, RuntimePreferencesSchema as Q, PromptSkillSchema as R, WorkspaceTerminalStartRequestSchema as Rt, ListModelsResponseSchema as S, WorkspaceChangesResponseSchema as St, ListThreadsResponseSchema as T, WorkspaceFileMentionSchema as Tt, RateLimitsResponseSchema as U, normalizePromptContext as Ut, RateLimitBucketSchema as V, createOpenApiDocument as Vt, ReasoningEffortSchema as W, promptMarkdownWithSkills as Wt, RuntimePreferencesByWorkspacePathSchema as X, RuntimeModeSchema as Y, stripPromptSkillMentions as Yt, RuntimePreferencesResponseSchema as Z, EncryptedPayloadSchema as _, UpdateWorkspaceFileContentRequestSchema as _t, ArchiveThreadResponseSchema as a, ThreadContextWindowResponseSchema as at, InterruptThreadRunResponseSchema as b, WORKSPACE_PREVIEW_TAB_VALUES as bt, ChatMessageRoleSchema as c, ThreadGoalSchema as ct, CheckoutWorkspaceBranchRequestSchema as d, ThreadMessageDetailResponseSchema as dt, StatusResponseSchema as et, CodexModelSchema as f, ThreadRunOptionsSchema as ft, CreateThreadResponseSchema as g, UpdateThreadGoalRequestSchema as gt, CreateThreadRequestSchema as h, UpdateRuntimePreferencesRequestSchema as ht, ApprovalModeSchema as i, ThreadCollaborationModeSchema as it, PendingInputRequestOptionSchema as j, WorkspaceTailscaleServeRequestSchema as jt, PairRequestSchema as k, WorkspacePreviewTabSchema as kt, ChatMessageSchema as l, ThreadGoalStatusSchema as lt, ContextWindowUsageSchema as m, ThreadSummarySchema as mt, AgentSkillSourceSchema as n, StreamThreadRunRequestSchema as nt, ChatMessageKindSchema as o, ThreadDetailResponseSchema as ot, CommitPushWorkspaceRequestSchema as p, ThreadStateSchema as pt, RunThreadRequestSchema as q, promptSkillMentionMarkdown as qt, ApprovalDecisionSchema as r, SubmitThreadInputResponseSchema as rt, ChatMessagePromptDetailsSchema as s, ThreadGoalResponseSchema as st, AgentSkillSchema as t, StreamThreadRunEventSchema as tt, ChatMessageStateSchema as u, ThreadMessageDetailFieldSchema as ut, ErrorResponseSchema as v, VersionResponseSchema as vt, ListSkillsResponseSchema as w, WorkspaceFileContentResponseSchema as wt, IsoDateTimeSchema as x, WebPreviewTargetSchema as xt, ImageAttachmentUploadResponseSchema as y, WORKSPACE_PREVIEW_OPEN_PROTOCOL as yt, QueuedThreadInputActionResponseSchema as z, apiPaths as zt };
1728
+ export { RuntimePreferencesSchema as $, PairRequestSchema as A, WorkspacePreviewTabSchema as At, QueuedThreadInputActionResponseSchema as B, apiPaths as Bt, ListModelsResponseSchema as C, WorkspaceChangesResponseSchema as Ct, ListWorkspaceDirectoriesResponseSchema as D, WorkspaceGitActionResponseSchema as Dt, ListThreadsResponseSchema as E, WorkspaceFileMentionSchema as Et, PromptAttachmentSchema as F, WorkspaceTerminalOutputChunkSchema as Ft, ReasoningEffortSchema as G, promptMarkdownWithSkills as Gt, RateLimitBucketSchema as H, createOpenApiDocument as Ht, PromptAttachmentSummarySchema as I, WorkspaceTerminalOutputResponseSchema as It, RunThreadRequestSchema as J, promptSkillMentionMarkdown as Jt, ResolveApprovalRequestSchema as K, promptSkillDisplayName as Kt, PromptContextInputSchema as L, WorkspaceTerminalResizeRequestSchema as Lt, PendingInputRequestOptionSchema as M, WorkspaceTailscaleServeRequestSchema as Mt, PendingInputRequestQuestionSchema as N, WorkspaceTailscaleServeResponseSchema as Nt, ListWorkspaceFilesResponseSchema as O, WorkspaceMarkdownPreviewTargetSchema as Ot, PendingInputRequestSchema as P, WorkspaceTerminalInputRequestSchema as Pt, RuntimePreferencesResponseSchema as Q, PromptContextSchema as R, WorkspaceTerminalSessionResponseSchema as Rt, KnownReasoningEffortSchema as S, WebPreviewTargetSchema as St, ListSkillsResponseSchema as T, WorkspaceFileContentResponseSchema as Tt, RateLimitWindowSchema as U, isPromptSkillMarkdownMention as Ut, QueuedThreadInputSchema as V, chatMessageDetailsFromPromptContext as Vt, RateLimitsResponseSchema as W, normalizePromptContext as Wt, RuntimeModeSchema as X, stripPromptSkillMentions as Xt, RunThreadResponseSchema as Y, promptSkillMentionTextCandidates as Yt, RuntimePreferencesByWorkspacePathSchema as Z, EncryptedPayloadSchema as _, UpdateThreadGoalRequestSchema as _t, ArchiveThreadResponseSchema as a, ThreadCollaborationModeSchema as at, InterruptThreadRunResponseSchema as b, WORKSPACE_PREVIEW_OPEN_PROTOCOL as bt, ChatMessageRoleSchema as c, ThreadGoalResponseSchema as ct, CheckoutWorkspaceBranchRequestSchema as d, ThreadMessageDetailFieldSchema as dt, SandboxModeSchema as et, CodexModelSchema as f, ThreadMessageDetailResponseSchema as ft, CreateThreadResponseSchema as g, UpdateRuntimePreferencesRequestSchema as gt, CreateThreadRequestSchema as h, ThreadSummarySchema as ht, ApprovalModeSchema as i, SubmitThreadInputResponseSchema as it, PairResponseSchema as j, WorkspaceSelectionRequestSchema as jt, PairEncryptedPayloadSchema as k, WorkspacePreviewNavigationRequestSchema as kt, ChatMessageSchema as l, ThreadGoalSchema as lt, ContextWindowUsageSchema as m, ThreadStateSchema as mt, AgentSkillSourceSchema as n, StreamThreadRunEventSchema as nt, ChatMessageKindSchema as o, ThreadContextWindowResponseSchema as ot, CommitPushWorkspaceRequestSchema as p, ThreadRunOptionsSchema as pt, ResolveApprovalResponseSchema as q, promptSkillMentionLabel as qt, ApprovalDecisionSchema as r, StreamThreadRunRequestSchema as rt, ChatMessagePromptDetailsSchema as s, ThreadDetailResponseSchema as st, AgentSkillSchema as t, StatusResponseSchema as tt, ChatMessageStateSchema as u, ThreadGoalStatusSchema as ut, ErrorResponseSchema as v, UpdateWorkspaceFileContentRequestSchema as vt, ListQueuedThreadInputsResponseSchema as w, WorkspaceDirectoryEntrySchema as wt, IsoDateTimeSchema as x, WORKSPACE_PREVIEW_TAB_VALUES as xt, ImageAttachmentUploadResponseSchema as y, VersionResponseSchema as yt, PromptSkillSchema as z, WorkspaceTerminalStartRequestSchema as zt };
package/dist/cli.js CHANGED
@@ -1,14 +1,51 @@
1
1
  #!/usr/bin/env node
2
- import { zt as apiPaths } from "./api-schema2.js";
2
+ import { Bt as apiPaths } from "./api-schema2.js";
3
3
  import { n as codexRelayHome, o as getConnectUrlGuidance, r as legacyCodexRelayDataPath, s as createTursoPairingSessionStore, t as codexRelayDataPath } from "./paths.js";
4
4
  import { Command } from "@commander-js/extra-typings";
5
5
  import qrcode from "qrcode-terminal";
6
- import { spawn } from "node:child_process";
6
+ import { execFile, spawn } from "node:child_process";
7
7
  import { closeSync, openSync } from "node:fs";
8
8
  import { access, mkdir, readFile, rm, unlink } from "node:fs/promises";
9
9
  import { dirname } from "node:path";
10
10
  import { setTimeout } from "node:timers/promises";
11
11
  import { fileURLToPath } from "node:url";
12
+ import { promisify } from "node:util";
13
+ //#region src/background-process.ts
14
+ const execFileAsync = promisify(execFile);
15
+ async function readRunningRelayPid(pidPath, options = {}) {
16
+ const value = await readFile(pidPath, "utf8").catch(() => void 0);
17
+ const pid = value ? Number(value.trim()) : NaN;
18
+ if (!Number.isInteger(pid) || pid <= 0) return;
19
+ if (!(options.isProcessAlive ?? defaultIsProcessAlive)(pid)) return;
20
+ const command = await (options.commandReader ?? readProcessCommand)(pid);
21
+ return command && isRelayProcessCommand(command) ? pid : void 0;
22
+ }
23
+ function defaultIsProcessAlive(pid) {
24
+ try {
25
+ process.kill(pid, 0);
26
+ return true;
27
+ } catch {
28
+ return false;
29
+ }
30
+ }
31
+ async function readProcessCommand(pid) {
32
+ try {
33
+ const { stdout } = await execFileAsync("ps", [
34
+ "-p",
35
+ String(pid),
36
+ "-o",
37
+ "command="
38
+ ]);
39
+ return stdout.trim() || void 0;
40
+ } catch {
41
+ return;
42
+ }
43
+ }
44
+ function isRelayProcessCommand(command) {
45
+ const normalized = command.replaceAll("\\", "/");
46
+ return normalized.includes("codex-relay") || normalized.includes("/src/cli.ts") || normalized.includes(" src/cli.ts");
47
+ }
48
+ //#endregion
12
49
  //#region src/cli.ts
13
50
  const npxCommand = "npx codex-relay@latest";
14
51
  const program = new Command().name("codex-relay").description("Run and approve the codex-relay local CLI bridge.").option("--bg", "run the Codex Relay server in the background").option("--debug", "write verbose relay diagnostics to debug.log").option("--dangerously-auto-approve", "automatically approve mobile pairing requests without a local approval command").addHelpText("after", `
@@ -42,7 +79,7 @@ async function startBackgroundServer() {
42
79
  const debugLogPath = codexRelayDataPath("debug.log");
43
80
  const pidPath = codexRelayDataPath("server.pid");
44
81
  await mkdir(dirname(logPath), { recursive: true });
45
- const existingPid = await readRunningPid(pidPath);
82
+ const existingPid = await readRunningRelayPid(pidPath);
46
83
  if (existingPid) {
47
84
  console.log(`codex-relay is already running in the background (pid ${existingPid}).`);
48
85
  console.log(`Logs: ${logPath}`);
@@ -86,17 +123,6 @@ async function startBackgroundServer() {
86
123
  if (process.env.CODEX_RELAY_DEBUG === "1") console.log(`Debug logs: ${debugLogPath}`);
87
124
  console.log(`Print the pairing QR later with: ${npxCommand} qr`);
88
125
  }
89
- async function readRunningPid(pidPath) {
90
- const value = await readFile(pidPath, "utf8").catch(() => void 0);
91
- const pid = value ? Number(value.trim()) : NaN;
92
- if (!Number.isInteger(pid) || pid <= 0) return;
93
- try {
94
- process.kill(pid, 0);
95
- return pid;
96
- } catch {
97
- return;
98
- }
99
- }
100
126
  function backgroundArgs() {
101
127
  return process.argv.slice(2).filter((arg) => arg !== "--bg");
102
128
  }
@@ -106,7 +132,7 @@ async function waitForBackgroundPid(child, pidPath) {
106
132
  childExited = true;
107
133
  });
108
134
  for (let attempt = 0; attempt < 50; attempt += 1) {
109
- const pid = await readRunningPid(pidPath);
135
+ const pid = await readRunningRelayPid(pidPath);
110
136
  if (pid) return pid;
111
137
  if (childExited) return;
112
138
  await setTimeout(100);
@@ -192,7 +218,7 @@ async function clearDebugLogs() {
192
218
  return removed;
193
219
  }
194
220
  async function hasRunningBackgroundServer() {
195
- return Boolean(await readRunningPid(codexRelayDataPath("server.pid")));
221
+ return Boolean(await readRunningRelayPid(codexRelayDataPath("server.pid")));
196
222
  }
197
223
  async function pathExists(path) {
198
224
  return access(path).then(() => true, () => false);
@@ -238,7 +264,7 @@ async function handleServerStartError(error) {
238
264
  if (!isDatabaseLockError(error)) throw error;
239
265
  const pidPath = codexRelayDataPath("server.pid");
240
266
  const logPath = codexRelayDataPath("server.log");
241
- const existingPid = await readRunningPid(pidPath);
267
+ const existingPid = await readRunningRelayPid(pidPath);
242
268
  const storedState = await readServerState();
243
269
  const state = storedState?.pairingPayload ? storedState : await readServerLogState();
244
270
  console.error("Codex Relay is already using its local pairing database.");
package/dist/src.js CHANGED
@@ -1,13 +1,14 @@
1
- import { A as PairResponseSchema, Bt as chatMessageDetailsFromPromptContext, C as ListQueuedThreadInputsResponseSchema, D as ListWorkspaceFilesResponseSchema, E as ListWorkspaceDirectoriesResponseSchema, Et as WorkspaceGitActionResponseSchema, Ft as WorkspaceTerminalOutputResponseSchema, G as ResolveApprovalRequestSchema, It as WorkspaceTerminalResizeRequestSchema, K as ResolveApprovalResponseSchema, Lt as WorkspaceTerminalSessionResponseSchema, Mt as WorkspaceTailscaleServeResponseSchema, Nt as WorkspaceTerminalInputRequestSchema, Q as RuntimePreferencesSchema, Rt as WorkspaceTerminalStartRequestSchema, S as ListModelsResponseSchema, St as WorkspaceChangesResponseSchema, T as ListThreadsResponseSchema, U as RateLimitsResponseSchema, Ut as normalizePromptContext, Vt as createOpenApiDocument, Wt as promptMarkdownWithSkills, X as RuntimePreferencesByWorkspacePathSchema, Yt as stripPromptSkillMentions, Z as RuntimePreferencesResponseSchema, _ as EncryptedPayloadSchema, _t as UpdateWorkspaceFileContentRequestSchema, a as ArchiveThreadResponseSchema, at as ThreadContextWindowResponseSchema, b as InterruptThreadRunResponseSchema, ct as ThreadGoalSchema, d as CheckoutWorkspaceBranchRequestSchema, dt as ThreadMessageDetailResponseSchema, et as StatusResponseSchema, gt as UpdateThreadGoalRequestSchema, h as CreateThreadRequestSchema, ht as UpdateRuntimePreferencesRequestSchema, jt as WorkspaceTailscaleServeRequestSchema, k as PairRequestSchema, l as ChatMessageSchema, lt as ThreadGoalStatusSchema, m as ContextWindowUsageSchema, mt as ThreadSummarySchema, nt as StreamThreadRunRequestSchema, ot as ThreadDetailResponseSchema, p as CommitPushWorkspaceRequestSchema, q as RunThreadRequestSchema, rt as SubmitThreadInputResponseSchema, st as ThreadGoalResponseSchema, tt as StreamThreadRunEventSchema, ut as ThreadMessageDetailFieldSchema, vt as VersionResponseSchema, w as ListSkillsResponseSchema, wt as WorkspaceFileContentResponseSchema, y as ImageAttachmentUploadResponseSchema, z as QueuedThreadInputActionResponseSchema, zt as apiPaths } from "./api-schema2.js";
1
+ import { $ as RuntimePreferencesSchema, A as PairRequestSchema, B as QueuedThreadInputActionResponseSchema, Bt as apiPaths, C as ListModelsResponseSchema, Ct as WorkspaceChangesResponseSchema, D as ListWorkspaceDirectoriesResponseSchema, Dt as WorkspaceGitActionResponseSchema, E as ListThreadsResponseSchema, G as ReasoningEffortSchema, Gt as promptMarkdownWithSkills, Ht as createOpenApiDocument, It as WorkspaceTerminalOutputResponseSchema, J as RunThreadRequestSchema, K as ResolveApprovalRequestSchema, Lt as WorkspaceTerminalResizeRequestSchema, Mt as WorkspaceTailscaleServeRequestSchema, Nt as WorkspaceTailscaleServeResponseSchema, O as ListWorkspaceFilesResponseSchema, Pt as WorkspaceTerminalInputRequestSchema, Q as RuntimePreferencesResponseSchema, Rt as WorkspaceTerminalSessionResponseSchema, S as KnownReasoningEffortSchema, T as ListSkillsResponseSchema, Tt as WorkspaceFileContentResponseSchema, Vt as chatMessageDetailsFromPromptContext, W as RateLimitsResponseSchema, Wt as normalizePromptContext, Xt as stripPromptSkillMentions, _ as EncryptedPayloadSchema, _t as UpdateThreadGoalRequestSchema, a as ArchiveThreadResponseSchema, b as InterruptThreadRunResponseSchema, ct as ThreadGoalResponseSchema, d as CheckoutWorkspaceBranchRequestSchema, dt as ThreadMessageDetailFieldSchema, ft as ThreadMessageDetailResponseSchema, gt as UpdateRuntimePreferencesRequestSchema, h as CreateThreadRequestSchema, ht as ThreadSummarySchema, it as SubmitThreadInputResponseSchema, j as PairResponseSchema, l as ChatMessageSchema, lt as ThreadGoalSchema, m as ContextWindowUsageSchema, nt as StreamThreadRunEventSchema, ot as ThreadContextWindowResponseSchema, p as CommitPushWorkspaceRequestSchema, q as ResolveApprovalResponseSchema, rt as StreamThreadRunRequestSchema, st as ThreadDetailResponseSchema, tt as StatusResponseSchema, ut as ThreadGoalStatusSchema, vt as UpdateWorkspaceFileContentRequestSchema, w as ListQueuedThreadInputsResponseSchema, y as ImageAttachmentUploadResponseSchema, yt as VersionResponseSchema, zt as WorkspaceTerminalStartRequestSchema } from "./api-schema2.js";
2
2
  import { a as getConnectUrlCandidates, i as createPairingQrPayload, o as getConnectUrlGuidance, r as legacyCodexRelayDataPath, s as createTursoPairingSessionStore, t as codexRelayDataPath } from "./paths.js";
3
3
  import { createRequire } from "node:module";
4
4
  import qrcode from "qrcode-terminal";
5
5
  import { execFile, spawn } from "node:child_process";
6
6
  import fs, { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
7
- import { access, appendFile, copyFile, mkdir, open, readFile, readdir, stat, writeFile } from "node:fs/promises";
7
+ import { access, appendFile, copyFile, mkdir, open, readFile, readdir, realpath, stat, writeFile } from "node:fs/promises";
8
8
  import path, { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
9
9
  import { fileURLToPath } from "node:url";
10
10
  import { z } from "zod";
11
+ import { promisify } from "node:util";
11
12
  import { fromByteArray, toByteArray } from "base64-js";
12
13
  import os, { homedir, hostname, platform } from "node:os";
13
14
  import { serve } from "@hono/node-server";
@@ -16,7 +17,6 @@ import pc from "picocolors";
16
17
  import { openRepository } from "es-git";
17
18
  import { Hono } from "hono";
18
19
  import { cors } from "hono/cors";
19
- import { promisify } from "node:util";
20
20
  import * as pty from "@lydell/node-pty";
21
21
  import { createInterface } from "node:readline";
22
22
  import { Codex } from "@openai/codex-sdk";
@@ -500,9 +500,10 @@ function formatDebugValue(value) {
500
500
  //#endregion
501
501
  //#region src/preferences-store.ts
502
502
  const defaultRuntimePreferences = { runtimeMode: "default" };
503
+ const PersistedRuntimePreferencesSchema = RuntimePreferencesSchema;
503
504
  const RuntimePreferencesFileSchema = z.object({
504
- preferences: RuntimePreferencesSchema.default(defaultRuntimePreferences),
505
- runtimePreferencesByWorkspacePath: RuntimePreferencesByWorkspacePathSchema.default({})
505
+ preferences: PersistedRuntimePreferencesSchema.default(defaultRuntimePreferences),
506
+ runtimePreferencesByWorkspacePath: z.record(z.string().trim().min(1), PersistedRuntimePreferencesSchema).default({})
506
507
  });
507
508
  function createMemoryRuntimePreferencesStore(initial = defaultRuntimePreferences) {
508
509
  let current = {
@@ -523,6 +524,7 @@ function createMemoryRuntimePreferencesStore(initial = defaultRuntimePreferences
523
524
  };
524
525
  }
525
526
  function createFileRuntimePreferencesStore(path) {
527
+ let updateQueue = Promise.resolve();
526
528
  async function readPreferences() {
527
529
  try {
528
530
  return parseRuntimePreferencesFile(JSON.parse(await readFile(path, "utf8")));
@@ -532,17 +534,23 @@ function createFileRuntimePreferencesStore(path) {
532
534
  }
533
535
  return {
534
536
  async read(workspacePath) {
537
+ await updateQueue;
535
538
  const current = await readPreferences();
536
539
  return workspacePath ? current.runtimePreferencesByWorkspacePath[workspacePath] ?? current.preferences : current.preferences;
537
540
  },
538
541
  async readByWorkspacePath() {
542
+ await updateQueue;
539
543
  return (await readPreferences()).runtimePreferencesByWorkspacePath;
540
544
  },
541
- async update(preferences, workspacePath) {
542
- const next = updatePreferencesFile(await readPreferences(), preferences, workspacePath);
543
- await mkdir(dirname(path), { recursive: true });
544
- await writeFile(path, `${JSON.stringify(next, null, 2)}\n`, { mode: 384 });
545
- return workspacePath ? next.runtimePreferencesByWorkspacePath[workspacePath] ?? next.preferences : next.preferences;
545
+ update(preferences, workspacePath) {
546
+ const operation = updateQueue.then(async () => {
547
+ const next = updatePreferencesFile(await readPreferences(), preferences, workspacePath);
548
+ await mkdir(dirname(path), { recursive: true });
549
+ await writeFile(path, `${JSON.stringify(next, null, 2)}\n`, { mode: 384 });
550
+ return workspacePath ? next.runtimePreferencesByWorkspacePath[workspacePath] ?? next.preferences : next.preferences;
551
+ });
552
+ updateQueue = operation.then(() => void 0, () => void 0);
553
+ return operation;
546
554
  }
547
555
  };
548
556
  }
@@ -551,7 +559,7 @@ function parseRuntimePreferencesFile(payload) {
551
559
  const record = payload;
552
560
  if ("preferences" in record || "runtimePreferencesByWorkspacePath" in record) return RuntimePreferencesFileSchema.parse(payload);
553
561
  }
554
- const legacyPreferences = RuntimePreferencesSchema.safeParse(payload);
562
+ const legacyPreferences = PersistedRuntimePreferencesSchema.safeParse(payload);
555
563
  if (legacyPreferences.success) return RuntimePreferencesFileSchema.parse({
556
564
  preferences: legacyPreferences.data,
557
565
  runtimePreferencesByWorkspacePath: {}
@@ -724,12 +732,21 @@ async function listAvailableSkills(options) {
724
732
  }
725
733
  ];
726
734
  const skillPaths = dedupe((await Promise.all(roots.map((root) => findSkillFiles(root)))).flat(), (entry) => entry.path);
727
- return (await Promise.all(skillPaths.map(readSkill))).filter((skill) => Boolean(skill)).sort(compareSkills);
735
+ return dedupe((await Promise.all(skillPaths.map(readSkill))).filter((skill) => Boolean(skill)).sort(compareSkills), skillIdentityKey);
728
736
  }
729
737
  async function findSkillFiles(root) {
730
738
  const found = [];
739
+ const visitedDirectories = /* @__PURE__ */ new Set();
731
740
  async function walk(path, depth) {
732
741
  if (depth < 0) return;
742
+ let realDirectoryPath;
743
+ try {
744
+ realDirectoryPath = await realpath(path);
745
+ } catch {
746
+ return;
747
+ }
748
+ if (visitedDirectories.has(realDirectoryPath)) return;
749
+ visitedDirectories.add(realDirectoryPath);
733
750
  let entries;
734
751
  try {
735
752
  entries = await readdir(path, { withFileTypes: true });
@@ -738,20 +755,34 @@ async function findSkillFiles(root) {
738
755
  }
739
756
  for (const entry of entries) {
740
757
  const entryPath = join(path, entry.name);
741
- if (entry.isFile() && entry.name === "SKILL.md") {
758
+ const kind = await directoryEntryKind(entry, entryPath);
759
+ if (kind === "file" && entry.name === "SKILL.md") {
742
760
  found.push({
743
761
  ...root,
744
762
  path: entryPath
745
763
  });
746
764
  continue;
747
765
  }
748
- if (!entry.isDirectory() || entry.name === "node_modules") continue;
766
+ if (kind !== "directory" || entry.name === "node_modules") continue;
749
767
  await walk(entryPath, depth - 1);
750
768
  }
751
769
  }
752
770
  await walk(root.path, root.maxDepth);
753
771
  return found;
754
772
  }
773
+ async function directoryEntryKind(entry, entryPath) {
774
+ if (entry.isFile()) return "file";
775
+ if (entry.isDirectory()) return "directory";
776
+ if (!entry.isSymbolicLink()) return null;
777
+ try {
778
+ const target = await stat(entryPath);
779
+ if (target.isFile()) return "file";
780
+ if (target.isDirectory()) return "directory";
781
+ } catch {
782
+ return null;
783
+ }
784
+ return null;
785
+ }
755
786
  async function readSkill(entry) {
756
787
  let markdown;
757
788
  try {
@@ -777,7 +808,7 @@ async function readSkill(entry) {
777
808
  }
778
809
  function parseSkillMarkdown(markdown) {
779
810
  const frontmatter = parseFrontmatter(markdown);
780
- const heading = markdown.match(/^#\s+(.+)$/m)?.[1]?.trim();
811
+ const heading = firstMarkdownHeading(markdownBody(markdown));
781
812
  return {
782
813
  description: frontmatter.description,
783
814
  displayName: heading ? cleanHeading(heading) : void 0,
@@ -789,13 +820,59 @@ function parseFrontmatter(markdown) {
789
820
  const end = markdown.indexOf("\n---", 4);
790
821
  if (end < 0) return {};
791
822
  const fields = {};
792
- for (const line of markdown.slice(4, end).split("\n")) {
793
- const match = line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
823
+ const lines = markdown.slice(4, end).split("\n");
824
+ for (let index = 0; index < lines.length; index += 1) {
825
+ const match = lines[index].match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
794
826
  if (!match) continue;
795
- fields[match[1]] = unquoteYamlScalar(match[2].trim());
827
+ const key = match[1];
828
+ const value = match[2].trim();
829
+ if (isBlockScalar(value)) {
830
+ const blockLines = [];
831
+ while (index + 1 < lines.length && (lines[index + 1].trim() === "" || /^\s/.test(lines[index + 1]))) {
832
+ index += 1;
833
+ blockLines.push(lines[index].replace(/^\s+/, ""));
834
+ }
835
+ fields[key] = formatBlockScalar(value, blockLines);
836
+ continue;
837
+ }
838
+ fields[key] = unquoteYamlScalar(value);
796
839
  }
797
840
  return fields;
798
841
  }
842
+ function isBlockScalar(value) {
843
+ return [
844
+ "|",
845
+ "|-",
846
+ "|+",
847
+ ">",
848
+ ">-",
849
+ ">+"
850
+ ].includes(value);
851
+ }
852
+ function formatBlockScalar(marker, lines) {
853
+ const trimmedLines = lines.map((line) => line.trimEnd());
854
+ if (marker.startsWith("|")) return trimmedLines.join("\n").trim();
855
+ return trimmedLines.map((line) => line.trim()).filter(Boolean).join(" ");
856
+ }
857
+ function markdownBody(markdown) {
858
+ if (!markdown.startsWith("---\n")) return markdown;
859
+ const end = markdown.indexOf("\n---", 4);
860
+ if (end < 0) return markdown;
861
+ return markdown.slice(end + 4).replace(/^\r?\n/, "");
862
+ }
863
+ function firstMarkdownHeading(markdown) {
864
+ let fence;
865
+ for (const line of markdown.split("\n")) {
866
+ const fenceMatch = line.match(/^\s*(```|~~~)/);
867
+ if (fenceMatch) {
868
+ fence = fence ? void 0 : fenceMatch[1];
869
+ continue;
870
+ }
871
+ if (fence) continue;
872
+ const heading = line.match(/^#\s+(.+)$/)?.[1]?.trim();
873
+ if (heading) return heading;
874
+ }
875
+ }
799
876
  function unquoteYamlScalar(value) {
800
877
  if (value.startsWith("\"") && value.endsWith("\"") || value.startsWith("'") && value.endsWith("'")) return value.slice(1, -1);
801
878
  return value;
@@ -818,6 +895,9 @@ function compareSkills(a, b) {
818
895
  };
819
896
  return sourceOrder[a.source] - sourceOrder[b.source] || a.displayName.localeCompare(b.displayName, void 0, { sensitivity: "base" });
820
897
  }
898
+ function skillIdentityKey(skill) {
899
+ return [skill.source, skill.name].join("\n");
900
+ }
821
901
  function dedupe(items, keyFor) {
822
902
  const seen = /* @__PURE__ */ new Set();
823
903
  return items.filter((item) => {
@@ -2602,7 +2682,9 @@ function queuedThreadInputSummary(input) {
2602
2682
  async function streamRunningAppServerThread(input) {
2603
2683
  let activeTurnId;
2604
2684
  let assistantMessageId;
2685
+ let observedInputRequest = false;
2605
2686
  let observedTurnActivity = false;
2687
+ let producedTurnOutput = false;
2606
2688
  let threadSummary = input.threads.get(input.threadId);
2607
2689
  const cleanupRequestHandler = input.appServer.onRequest((request) => {
2608
2690
  if (!isApprovalServerRequest(request.method)) {
@@ -2614,6 +2696,7 @@ async function streamRunningAppServerThread(input) {
2614
2696
  input.appServer.rejectRequest(request.id, -32602, "Approval request is malformed.");
2615
2697
  return;
2616
2698
  }
2699
+ observedInputRequest = true;
2617
2700
  if (approval.kind === "structuredUserInput") {
2618
2701
  const pending = {
2619
2702
  appServer: input.appServer,
@@ -2702,6 +2785,7 @@ async function streamRunningAppServerThread(input) {
2702
2785
  if (!item || typeof item !== "object") return;
2703
2786
  const message = upsertAppServerItemMessage(input.messagesByThreadId, input.threadId, firstString(params, ["turnId"]) ?? activeTurnId, item);
2704
2787
  if (!message) return;
2788
+ if (message.role !== "user") producedTurnOutput = true;
2705
2789
  if (message.role === "assistant") assistantMessageId = message.id;
2706
2790
  threadSummary = updateThread(input.threads, input.messagesByThreadId, input.threadId, {
2707
2791
  state: "running",
@@ -2726,6 +2810,7 @@ async function streamRunningAppServerThread(input) {
2726
2810
  turnId: firstString(params, ["turnId"]) ?? activeTurnId
2727
2811
  });
2728
2812
  assistantMessageId = itemId;
2813
+ producedTurnOutput = true;
2729
2814
  const patch = appendMessageDelta(input.messagesByThreadId, input.threadId, itemId, delta);
2730
2815
  const message = patch.message;
2731
2816
  updateThread(input.threads, input.messagesByThreadId, input.threadId, {
@@ -2742,6 +2827,7 @@ async function streamRunningAppServerThread(input) {
2742
2827
  }
2743
2828
  case "turn/plan/updated": {
2744
2829
  observedTurnActivity = true;
2830
+ producedTurnOutput = true;
2745
2831
  const content = planContentFromRecord(params);
2746
2832
  const message = appendMessage(input.messagesByThreadId, input.threadId, {
2747
2833
  role: "status",
@@ -2771,6 +2857,20 @@ async function streamRunningAppServerThread(input) {
2771
2857
  threadId: input.threadId,
2772
2858
  turnId: firstString(params, ["turnId"]) ?? activeTurnId
2773
2859
  });
2860
+ if (state === "completed" && !producedTurnOutput && !observedInputRequest) {
2861
+ sendEmptyAppServerTurnError({
2862
+ activeTurnId,
2863
+ controller: input.controller,
2864
+ encoder: input.encoder,
2865
+ messagesByThreadId: input.messagesByThreadId,
2866
+ secureSession: input.secureSession,
2867
+ threadId: input.threadId,
2868
+ threads: input.threads
2869
+ });
2870
+ cleanupNotificationHandler();
2871
+ resolve();
2872
+ return;
2873
+ }
2774
2874
  if (assistantMessageId) {
2775
2875
  const completedMessage = updateMessage(input.messagesByThreadId, input.threadId, assistantMessageId, { state: "completed" });
2776
2876
  sendSse(input.controller, input.encoder, input.secureSession, {
@@ -2787,11 +2887,25 @@ async function streamRunningAppServerThread(input) {
2787
2887
  type: "thread.state.changed",
2788
2888
  thread: threadSummary
2789
2889
  });
2790
- if (state === "failed") sendSse(input.controller, input.encoder, input.secureSession, {
2791
- type: "thread.error",
2792
- thread: threadSummary,
2793
- error: apiError("codex_run_failed", threadSummary.lastError ?? "Codex turn did not complete.").error
2794
- });
2890
+ if (state === "failed") {
2891
+ const errorBody = apiError("codex_run_failed", threadSummary.lastError ?? "Codex turn did not complete.");
2892
+ const message = appendMessage(input.messagesByThreadId, input.threadId, {
2893
+ role: "error",
2894
+ content: errorBody.error.message,
2895
+ state: "failed",
2896
+ turnId: activeTurnId
2897
+ });
2898
+ sendSse(input.controller, input.encoder, input.secureSession, {
2899
+ type: "thread.message.created",
2900
+ thread: threadSummary,
2901
+ message
2902
+ });
2903
+ sendSse(input.controller, input.encoder, input.secureSession, {
2904
+ type: "thread.error",
2905
+ thread: threadSummary,
2906
+ error: errorBody.error
2907
+ });
2908
+ }
2795
2909
  cleanupNotificationHandler();
2796
2910
  resolve();
2797
2911
  return;
@@ -2836,6 +2950,7 @@ async function runAppServerPromptStreamed(input) {
2836
2950
  const displayPrompt = promptMarkdownWithSkills(promptWithAttachmentReferences(input.prompt, input.attachments), input.skills);
2837
2951
  const prompt = input.prompt;
2838
2952
  let handedOffToQueuedTurn = false;
2953
+ let observedInputRequest = false;
2839
2954
  let producedTurnOutput = false;
2840
2955
  let userMessage = appendMessage(input.messagesByThreadId, activeThreadId, {
2841
2956
  role: "user",
@@ -2869,6 +2984,7 @@ async function runAppServerPromptStreamed(input) {
2869
2984
  input.appServer.rejectRequest(request.id, -32602, "Approval request is malformed.");
2870
2985
  return;
2871
2986
  }
2987
+ observedInputRequest = true;
2872
2988
  if (approval.kind === "structuredUserInput") {
2873
2989
  const pending = {
2874
2990
  appServer: input.appServer,
@@ -2912,7 +3028,141 @@ async function runAppServerPromptStreamed(input) {
2912
3028
  });
2913
3029
  });
2914
3030
  let cleanupNotificationHandler = () => void 0;
3031
+ let resolveCompleted = () => void 0;
3032
+ let rejectCompleted = (_error) => void 0;
3033
+ const finalizedTurnIds = /* @__PURE__ */ new Set();
3034
+ function resetTurnTracking() {
3035
+ activeTurnId = void 0;
3036
+ assistantMessageId = void 0;
3037
+ observedInputRequest = false;
3038
+ producedTurnOutput = false;
3039
+ }
3040
+ function finishTerminalTurn(options) {
3041
+ const terminalTurnId = options.turnId ?? activeTurnId;
3042
+ if (terminalTurnId && finalizedTurnIds.has(terminalTurnId)) return;
3043
+ if (terminalTurnId) {
3044
+ finalizedTurnIds.add(terminalTurnId);
3045
+ activeTurnId = terminalTurnId;
3046
+ }
3047
+ relayDebugLog("app_server.turn.terminal", {
3048
+ method: options.method,
3049
+ state: options.state,
3050
+ threadId: activeThreadId,
3051
+ turnId: terminalTurnId
3052
+ });
3053
+ input.activeAppServerTurnIdsByThreadId.delete(activeThreadId);
3054
+ const hasQueuedInput = (input.queuedInputsByThreadId.get(activeThreadId)?.length ?? 0) > 0;
3055
+ if (options.state === "completed" && !producedTurnOutput && !observedInputRequest && !hasQueuedInput) {
3056
+ sendEmptyAppServerTurnError({
3057
+ activeTurnId: terminalTurnId,
3058
+ controller: input.controller,
3059
+ encoder: input.encoder,
3060
+ messagesByThreadId: input.messagesByThreadId,
3061
+ secureSession: input.secureSession,
3062
+ threadId: activeThreadId,
3063
+ threads: input.threads
3064
+ });
3065
+ input.steeringThreads.delete(activeThreadId);
3066
+ cleanupNotificationHandler();
3067
+ resolveCompleted();
3068
+ return;
3069
+ }
3070
+ if (assistantMessageId) {
3071
+ const completedMessage = updateMessage(input.messagesByThreadId, activeThreadId, assistantMessageId, { state: "completed" });
3072
+ sendSse(input.controller, input.encoder, input.secureSession, {
3073
+ type: "thread.message.completed",
3074
+ thread: threadSummary,
3075
+ message: completedMessage
3076
+ });
3077
+ }
3078
+ const nextQueuedInput = options.state === "completed" ? shiftQueuedInput(input.queuedInputsByThreadId, activeThreadId) : void 0;
3079
+ threadSummary = updateThread(input.threads, input.messagesByThreadId, activeThreadId, {
3080
+ state: nextQueuedInput ? "running" : options.state,
3081
+ lastError: nextQueuedInput ? void 0 : options.lastError,
3082
+ ...nextQueuedInput ? {
3083
+ lastPrompt: promptWithAttachmentReferences(nextQueuedInput.prompt, nextQueuedInput.attachments),
3084
+ ...runtimeMetadataFromOptions(nextQueuedInput.runOptions)
3085
+ } : {}
3086
+ });
3087
+ sendSse(input.controller, input.encoder, input.secureSession, {
3088
+ type: "thread.state.changed",
3089
+ thread: threadSummary
3090
+ });
3091
+ if (options.state === "failed") {
3092
+ const errorBody = apiError("codex_run_failed", options.lastError ?? "Codex turn did not complete.");
3093
+ const message = appendMessage(input.messagesByThreadId, activeThreadId, {
3094
+ role: "error",
3095
+ content: errorBody.error.message,
3096
+ state: "failed",
3097
+ turnId: terminalTurnId
3098
+ });
3099
+ sendSse(input.controller, input.encoder, input.secureSession, {
3100
+ type: "thread.message.created",
3101
+ thread: threadSummary,
3102
+ message
3103
+ });
3104
+ sendSse(input.controller, input.encoder, input.secureSession, {
3105
+ type: "thread.error",
3106
+ thread: threadSummary,
3107
+ error: errorBody.error
3108
+ });
3109
+ input.steeringThreads.delete(activeThreadId);
3110
+ cleanupNotificationHandler();
3111
+ resolveCompleted();
3112
+ return;
3113
+ }
3114
+ if (nextQueuedInput) {
3115
+ handedOffToQueuedTurn = true;
3116
+ resetTurnTracking();
3117
+ input.steeringThreads.add(activeThreadId);
3118
+ startAppServerTurn(input.appServer, activeThreadId, nextQueuedInput).then(processReturnedTurn).catch((error) => {
3119
+ cleanupNotificationHandler();
3120
+ rejectCompleted(error);
3121
+ });
3122
+ return;
3123
+ }
3124
+ input.steeringThreads.delete(activeThreadId);
3125
+ cleanupNotificationHandler();
3126
+ resolveCompleted();
3127
+ }
3128
+ function processReturnedTurn(turn) {
3129
+ if (finalizedTurnIds.has(turn.id)) return;
3130
+ activeTurnId = turn.id;
3131
+ input.activeAppServerTurnIdsByThreadId.set(activeThreadId, turn.id);
3132
+ const turnIsRunning = isAppServerTurnRunning(turn);
3133
+ for (const item of turn.items) {
3134
+ const canonicalUserMessage = replaceDuplicateInitialUserMessage(input.messagesByThreadId, activeThreadId, turn.id, item, userMessage.id, displayPrompt);
3135
+ if (canonicalUserMessage) {
3136
+ userMessage = canonicalUserMessage;
3137
+ continue;
3138
+ }
3139
+ const message = upsertAppServerItemMessage(input.messagesByThreadId, activeThreadId, turn.id, item);
3140
+ if (!message) continue;
3141
+ if (message.role !== "user") producedTurnOutput = true;
3142
+ if (message.role === "assistant" && turnIsRunning) assistantMessageId = message.id;
3143
+ threadSummary = updateThread(input.threads, input.messagesByThreadId, activeThreadId, {
3144
+ state: "running",
3145
+ lastResult: message.role === "assistant" ? message.content : void 0
3146
+ });
3147
+ sendSse(input.controller, input.encoder, input.secureSession, {
3148
+ type: message.role === "assistant" ? "thread.message.completed" : "thread.message.created",
3149
+ thread: threadSummary,
3150
+ message
3151
+ });
3152
+ }
3153
+ if (turnIsRunning) return;
3154
+ const params = { turn };
3155
+ const state = terminalTurnState("turn/completed", params);
3156
+ finishTerminalTurn({
3157
+ lastError: state === "failed" ? turnErrorMessage(params) : void 0,
3158
+ method: "turn/returned",
3159
+ state,
3160
+ turnId: turn.id
3161
+ });
3162
+ }
2915
3163
  const completed = new Promise((resolve, reject) => {
3164
+ resolveCompleted = resolve;
3165
+ rejectCompleted = reject;
2916
3166
  cleanupNotificationHandler = input.appServer.onNotification((notification) => {
2917
3167
  const params = recordParams(notification);
2918
3168
  const threadId = firstString(params, ["threadId"]);
@@ -2957,7 +3207,7 @@ async function runAppServerPromptStreamed(input) {
2957
3207
  const turnId = firstString(params, ["turnId"]) ?? activeTurnId;
2958
3208
  const message = upsertAppServerItemMessage(input.messagesByThreadId, activeThreadId, turnId, item);
2959
3209
  if (!message) return;
2960
- producedTurnOutput = true;
3210
+ if (message.role !== "user") producedTurnOutput = true;
2961
3211
  if (message.role === "assistant") assistantMessageId = message.id;
2962
3212
  threadSummary = updateThread(input.threads, input.messagesByThreadId, activeThreadId, {
2963
3213
  state: "running",
@@ -3020,69 +3270,13 @@ async function runAppServerPromptStreamed(input) {
3020
3270
  case "turn/completed":
3021
3271
  case "turn/failed": {
3022
3272
  const state = terminalTurnState(notification.method, params);
3023
- relayDebugLog("app_server.turn.terminal", {
3273
+ const terminalTurnId = firstString(params, ["turnId"]) ?? turnIdFromParams(params) ?? activeTurnId;
3274
+ finishTerminalTurn({
3275
+ lastError: state === "failed" ? turnErrorMessage(params) : void 0,
3024
3276
  method: notification.method,
3025
3277
  state,
3026
- threadId: activeThreadId,
3027
- turnId: firstString(params, ["turnId"]) ?? activeTurnId
3028
- });
3029
- input.activeAppServerTurnIdsByThreadId.delete(activeThreadId);
3030
- if (assistantMessageId) {
3031
- const completedMessage = updateMessage(input.messagesByThreadId, activeThreadId, assistantMessageId, { state: "completed" });
3032
- sendSse(input.controller, input.encoder, input.secureSession, {
3033
- type: "thread.message.completed",
3034
- thread: threadSummary,
3035
- message: completedMessage
3036
- });
3037
- }
3038
- const lastError = state === "failed" ? turnErrorMessage(params) : void 0;
3039
- const nextQueuedInput = state === "completed" ? shiftQueuedInput(input.queuedInputsByThreadId, activeThreadId) : void 0;
3040
- threadSummary = updateThread(input.threads, input.messagesByThreadId, activeThreadId, {
3041
- state: nextQueuedInput ? "running" : state,
3042
- lastError: nextQueuedInput ? void 0 : lastError,
3043
- ...nextQueuedInput ? {
3044
- lastPrompt: promptWithAttachmentReferences(nextQueuedInput.prompt, nextQueuedInput.attachments),
3045
- ...runtimeMetadataFromOptions(nextQueuedInput.runOptions)
3046
- } : {}
3047
- });
3048
- sendSse(input.controller, input.encoder, input.secureSession, {
3049
- type: "thread.state.changed",
3050
- thread: threadSummary
3278
+ turnId: terminalTurnId
3051
3279
  });
3052
- if (state === "failed") {
3053
- const errorBody = apiError("codex_run_failed", lastError ?? "Codex turn did not complete.");
3054
- appendMessage(input.messagesByThreadId, activeThreadId, {
3055
- role: "error",
3056
- content: errorBody.error.message,
3057
- state: "failed",
3058
- turnId: activeTurnId
3059
- });
3060
- sendSse(input.controller, input.encoder, input.secureSession, {
3061
- type: "thread.error",
3062
- thread: threadSummary,
3063
- error: errorBody.error
3064
- });
3065
- input.steeringThreads.delete(activeThreadId);
3066
- cleanupNotificationHandler();
3067
- resolve();
3068
- return;
3069
- }
3070
- if (nextQueuedInput) {
3071
- handedOffToQueuedTurn = true;
3072
- assistantMessageId = void 0;
3073
- input.steeringThreads.add(activeThreadId);
3074
- startAppServerTurn(input.appServer, activeThreadId, nextQueuedInput).then((turn) => {
3075
- activeTurnId = turn.id;
3076
- input.activeAppServerTurnIdsByThreadId.set(activeThreadId, activeTurnId);
3077
- }).catch((error) => {
3078
- cleanupNotificationHandler();
3079
- reject(error);
3080
- });
3081
- return;
3082
- }
3083
- input.steeringThreads.delete(activeThreadId);
3084
- cleanupNotificationHandler();
3085
- resolve();
3086
3280
  return;
3087
3281
  }
3088
3282
  }
@@ -3182,56 +3376,8 @@ async function runAppServerPromptStreamed(input) {
3182
3376
  workspacePath: input.workspacePath
3183
3377
  });
3184
3378
  }
3185
- activeTurnId = turn.id;
3186
- input.activeAppServerTurnIdsByThreadId.set(activeThreadId, activeTurnId);
3187
- debugStream("start turn complete", activeThreadId, activeTurnId);
3188
- let streamedReturnedItem = false;
3189
- for (const item of turn.items) {
3190
- const canonicalUserMessage = replaceDuplicateInitialUserMessage(input.messagesByThreadId, activeThreadId, activeTurnId, item, userMessage.id, displayPrompt);
3191
- if (canonicalUserMessage) {
3192
- userMessage = canonicalUserMessage;
3193
- continue;
3194
- }
3195
- const message = upsertAppServerItemMessage(input.messagesByThreadId, activeThreadId, activeTurnId, item);
3196
- if (!message) continue;
3197
- streamedReturnedItem = true;
3198
- producedTurnOutput = true;
3199
- if (message.role === "assistant") assistantMessageId = message.id;
3200
- threadSummary = updateThread(input.threads, input.messagesByThreadId, activeThreadId, {
3201
- state: "running",
3202
- lastResult: message.role === "assistant" ? message.content : void 0
3203
- });
3204
- sendSse(input.controller, input.encoder, input.secureSession, {
3205
- type: message.role === "assistant" ? "thread.message.completed" : "thread.message.created",
3206
- thread: threadSummary,
3207
- message
3208
- });
3209
- }
3210
- const returnedState = mapAppServerThreadState(turn.status);
3211
- if (returnedState !== "running") {
3212
- if (!streamedReturnedItem && !producedTurnOutput) {
3213
- sendEmptyAppServerTurnError({
3214
- activeTurnId,
3215
- controller: input.controller,
3216
- encoder: input.encoder,
3217
- messagesByThreadId: input.messagesByThreadId,
3218
- secureSession: input.secureSession,
3219
- threadId: activeThreadId,
3220
- threads: input.threads
3221
- });
3222
- input.steeringThreads.delete(activeThreadId);
3223
- cleanupNotificationHandler();
3224
- return;
3225
- }
3226
- threadSummary = updateThread(input.threads, input.messagesByThreadId, activeThreadId, { state: returnedState });
3227
- sendSse(input.controller, input.encoder, input.secureSession, {
3228
- type: "thread.state.changed",
3229
- thread: threadSummary
3230
- });
3231
- input.steeringThreads.delete(activeThreadId);
3232
- cleanupNotificationHandler();
3233
- return;
3234
- }
3379
+ debugStream("start turn complete", activeThreadId, turn.id);
3380
+ processReturnedTurn(turn);
3235
3381
  await completed;
3236
3382
  } catch (error) {
3237
3383
  debugStream(`failed ${errorMessage(error)}`, activeThreadId, activeTurnId);
@@ -4085,11 +4231,12 @@ function appServerCollaborationMode(options) {
4085
4231
  }
4086
4232
  function buildThreadOptions(base, options) {
4087
4233
  const runtime = resolveRuntimeOptions(options.runtimeMode);
4234
+ const reasoningEffort = KnownReasoningEffortSchema.safeParse(options.reasoningEffort);
4088
4235
  return {
4089
4236
  ...base,
4090
4237
  ...runtime,
4091
4238
  ...options.model ? { model: options.model } : {},
4092
- ...options.reasoningEffort ? { modelReasoningEffort: options.reasoningEffort } : {},
4239
+ ...reasoningEffort.success ? { modelReasoningEffort: reasoningEffort.data } : {},
4093
4240
  ...options.approvalPolicy ? { approvalPolicy: options.approvalPolicy } : {},
4094
4241
  ...options.sandboxMode ? { sandboxMode: options.sandboxMode } : {}
4095
4242
  };
@@ -4809,6 +4956,41 @@ function mapAppServerItem(threadId, turn, item) {
4809
4956
  }
4810
4957
  });
4811
4958
  }
4959
+ case "collabAgentToolCall": {
4960
+ const collabItem = item;
4961
+ return ChatMessageSchema.parse({
4962
+ ...base,
4963
+ role: "tool",
4964
+ kind: "subagentAction",
4965
+ content: appServerCollabAgentToolCallContent(collabItem),
4966
+ details: {
4967
+ type: collabItem.type,
4968
+ tool: collabItem.tool,
4969
+ status: collabItem.status,
4970
+ senderThreadId: collabItem.senderThreadId,
4971
+ receiverThreadIds: collabItem.receiverThreadIds,
4972
+ prompt: collabItem.prompt ?? void 0,
4973
+ model: collabItem.model ?? void 0,
4974
+ reasoningEffort: collabItem.reasoningEffort ?? void 0,
4975
+ agentsStates: collabItem.agentsStates
4976
+ }
4977
+ });
4978
+ }
4979
+ case "subAgentActivity": {
4980
+ const activityItem = item;
4981
+ return ChatMessageSchema.parse({
4982
+ ...base,
4983
+ role: "status",
4984
+ kind: "subagentAction",
4985
+ content: `${activityItem.agentPath || activityItem.agentThreadId} ${activityItem.kind}`,
4986
+ details: {
4987
+ type: activityItem.type,
4988
+ activityKind: activityItem.kind,
4989
+ agentThreadId: activityItem.agentThreadId,
4990
+ agentPath: activityItem.agentPath
4991
+ }
4992
+ });
4993
+ }
4812
4994
  case "webSearch": {
4813
4995
  const searchItem = item;
4814
4996
  return ChatMessageSchema.parse({
@@ -4825,6 +5007,17 @@ function mapAppServerItem(threadId, turn, item) {
4825
5007
  default: return mapUnknownAppServerItem(threadId, turn, item);
4826
5008
  }
4827
5009
  }
5010
+ function appServerCollabAgentToolCallContent(item) {
5011
+ const targetCount = item.receiverThreadIds.length;
5012
+ const target = targetCount === 1 ? "subagent" : `${targetCount} subagents`;
5013
+ switch (item.tool) {
5014
+ case "spawnAgent": return targetCount > 0 ? `Spawned ${target}` : "Spawned subagent";
5015
+ case "sendInput": return `Sent input to ${target}`;
5016
+ case "resumeAgent": return `Resumed ${target}`;
5017
+ case "wait": return targetCount > 0 ? `Waited for ${target}` : "Waited for subagents";
5018
+ case "closeAgent": return `Closed ${target}`;
5019
+ }
5020
+ }
4828
5021
  function mapUnknownAppServerItem(threadId, turn, item) {
4829
5022
  const timestamp = fromUnixSeconds(turn.startedAt ?? turn.completedAt ?? Date.now() / 1e3);
4830
5023
  const type = "type" in item ? String(item.type) : "unknown";
@@ -4854,6 +5047,14 @@ function appServerTurnShell(turnId) {
4854
5047
  };
4855
5048
  }
4856
5049
  function mapAppServerModel(model) {
5050
+ const reasoningEffortOptions = model.supportedReasoningEfforts?.flatMap((effort) => {
5051
+ const parsed = ReasoningEffortSchema.safeParse(effort.reasoningEffort);
5052
+ return parsed.success ? [{
5053
+ reasoningEffort: parsed.data,
5054
+ description: effort.description
5055
+ }] : [];
5056
+ }) ?? [];
5057
+ const defaultReasoningEffort = ReasoningEffortSchema.safeParse(model.defaultReasoningEffort);
4857
5058
  const serviceTiers = model.serviceTiers ?? model.additionalSpeedTiers?.map((tier) => ({
4858
5059
  id: tier,
4859
5060
  name: tier === "fast" ? "Fast" : tier,
@@ -4865,8 +5066,9 @@ function mapAppServerModel(model) {
4865
5066
  displayName: model.displayName,
4866
5067
  description: model.description,
4867
5068
  isDefault: Boolean(model.isDefault),
4868
- defaultReasoningEffort: model.defaultReasoningEffort,
4869
- supportedReasoningEfforts: model.supportedReasoningEfforts?.map((effort) => effort.reasoningEffort) ?? [],
5069
+ defaultReasoningEffort: defaultReasoningEffort.success ? defaultReasoningEffort.data : void 0,
5070
+ supportedReasoningEfforts: reasoningEffortOptions.map((effort) => effort.reasoningEffort),
5071
+ reasoningEffortOptions,
4870
5072
  serviceTiers
4871
5073
  };
4872
5074
  }
@@ -5327,7 +5529,11 @@ function kindFromProtocolType(type) {
5327
5529
  case "approval_request":
5328
5530
  case "approvalRequest": return "approvalRequest";
5329
5531
  case "subagent_action":
5330
- case "subagentAction": return "subagentAction";
5532
+ case "subagentAction":
5533
+ case "collab_agent_tool_call":
5534
+ case "collabAgentToolCall":
5535
+ case "sub_agent_activity":
5536
+ case "subAgentActivity": return "subagentAction";
5331
5537
  default: return;
5332
5538
  }
5333
5539
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-relay",
3
- "version": "1.2.3",
3
+ "version": "1.3.0",
4
4
  "description": "Local Codex Relay CLI bridge for the Codex Relay mobile app.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -40,7 +40,7 @@
40
40
  "@noble/ciphers": "2.2.0",
41
41
  "@noble/curves": "2.2.0",
42
42
  "@noble/hashes": "2.2.0",
43
- "@openai/codex-sdk": "0.141.0",
43
+ "@openai/codex-sdk": "0.144.1",
44
44
  "@tursodatabase/database": "^0.5.3",
45
45
  "base64-js": "1.5.1",
46
46
  "commander": "^14.0.3",
package/src/api-schema.ts CHANGED
@@ -30,7 +30,16 @@ export const ChatMessageKindSchema = z.enum([
30
30
  export const ApprovalModeSchema = z.enum(["on-request", "on-failure", "never"]);
31
31
  export const RuntimeModeSchema = z.enum(["default", "auto", "full-access", "on-request"]);
32
32
  export const SandboxModeSchema = z.enum(["workspace-write", "danger-full-access", "read-only"]);
33
- export const ReasoningEffortSchema = z.enum(["minimal", "low", "medium", "high", "xhigh"]);
33
+ export const KnownReasoningEffortSchema = z.enum([
34
+ "minimal",
35
+ "low",
36
+ "medium",
37
+ "high",
38
+ "xhigh",
39
+ "max",
40
+ "ultra",
41
+ ]);
42
+ export const ReasoningEffortSchema = z.string().trim().min(1);
34
43
  export const ThreadCollaborationModeSchema = z.enum(["default", "plan"]);
35
44
  export const ThreadGoalStatusSchema = z.enum([
36
45
  "active",
@@ -94,6 +103,14 @@ export const CodexModelSchema = z.object({
94
103
  isDefault: z.boolean().default(false),
95
104
  defaultReasoningEffort: ReasoningEffortSchema.optional(),
96
105
  supportedReasoningEfforts: z.array(ReasoningEffortSchema).default([]),
106
+ reasoningEffortOptions: z
107
+ .array(
108
+ z.object({
109
+ reasoningEffort: ReasoningEffortSchema,
110
+ description: z.string().optional(),
111
+ }),
112
+ )
113
+ .default([]),
97
114
  serviceTiers: z
98
115
  .array(
99
116
  z.object({
@@ -718,6 +735,7 @@ export type ChatMessageRole = z.infer<typeof ChatMessageRoleSchema>;
718
735
  export type ChatMessageState = z.infer<typeof ChatMessageStateSchema>;
719
736
  export type ChatMessageKind = z.infer<typeof ChatMessageKindSchema>;
720
737
  export type ApprovalMode = z.infer<typeof ApprovalModeSchema>;
738
+ export type KnownReasoningEffort = z.infer<typeof KnownReasoningEffortSchema>;
721
739
  export type ReasoningEffort = z.infer<typeof ReasoningEffortSchema>;
722
740
  export type RuntimeMode = z.infer<typeof RuntimeModeSchema>;
723
741
  export type SandboxMode = z.infer<typeof SandboxModeSchema>;
@@ -1301,6 +1319,7 @@ export function createOpenApiDocument() {
1301
1319
  components: {
1302
1320
  schemas: {
1303
1321
  ThreadState: { type: "string", enum: ThreadStateSchema.options },
1322
+ ReasoningEffort: { type: "string", minLength: 1 },
1304
1323
  ChatMessage: {
1305
1324
  type: "object",
1306
1325
  required: ["id", "threadId", "role", "content", "createdAt"],
@@ -1437,7 +1456,7 @@ export function createOpenApiDocument() {
1437
1456
  },
1438
1457
  reasoningEffort: {
1439
1458
  type: "string",
1440
- enum: ["minimal", "low", "medium", "high", "xhigh"],
1459
+ minLength: 1,
1441
1460
  },
1442
1461
  },
1443
1462
  },
@@ -1454,7 +1473,7 @@ export function createOpenApiDocument() {
1454
1473
  },
1455
1474
  reasoningEffort: {
1456
1475
  type: "string",
1457
- enum: ["minimal", "low", "medium", "high", "xhigh"],
1476
+ minLength: 1,
1458
1477
  nullable: true,
1459
1478
  },
1460
1479
  },