codex-relay 1.0.1 → 1.0.3

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.
@@ -0,0 +1,1349 @@
1
+ import { z } from "zod";
2
+ //#region src/api-schema.ts
3
+ const IsoDateTimeSchema = z.string().datetime();
4
+ const ThreadStateSchema = z.enum([
5
+ "idle",
6
+ "running",
7
+ "completed",
8
+ "failed"
9
+ ]);
10
+ const ChatMessageRoleSchema = z.enum([
11
+ "user",
12
+ "assistant",
13
+ "status",
14
+ "tool",
15
+ "reasoning",
16
+ "error"
17
+ ]);
18
+ const ChatMessageStateSchema = z.enum([
19
+ "streaming",
20
+ "completed",
21
+ "failed"
22
+ ]);
23
+ const ChatMessageKindSchema = z.enum([
24
+ "chat",
25
+ "thinking",
26
+ "toolActivity",
27
+ "commandExecution",
28
+ "fileChange",
29
+ "plan",
30
+ "approvalRequest",
31
+ "structuredUserInput",
32
+ "subagentAction",
33
+ "webSearch",
34
+ "unknown"
35
+ ]);
36
+ const ApprovalModeSchema = z.enum([
37
+ "on-request",
38
+ "on-failure",
39
+ "never"
40
+ ]);
41
+ const RuntimeModeSchema = z.enum([
42
+ "default",
43
+ "auto",
44
+ "full-access",
45
+ "on-request"
46
+ ]);
47
+ const SandboxModeSchema = z.enum([
48
+ "workspace-write",
49
+ "danger-full-access",
50
+ "read-only"
51
+ ]);
52
+ const ReasoningEffortSchema = z.enum([
53
+ "minimal",
54
+ "low",
55
+ "medium",
56
+ "high",
57
+ "xhigh"
58
+ ]);
59
+ const ThreadCollaborationModeSchema = z.enum(["default", "plan"]);
60
+ const VersionResponseSchema = z.object({
61
+ ok: z.boolean(),
62
+ service: z.literal("codex-relay-server"),
63
+ packageName: z.literal("codex-relay"),
64
+ packageVersion: z.string().min(1)
65
+ });
66
+ const ThreadRunOptionsSchema = z.object({
67
+ model: z.string().trim().min(1).optional(),
68
+ runtimeMode: RuntimeModeSchema.optional(),
69
+ approvalPolicy: ApprovalModeSchema.optional(),
70
+ sandboxMode: SandboxModeSchema.optional(),
71
+ reasoningEffort: ReasoningEffortSchema.optional(),
72
+ collaborationMode: ThreadCollaborationModeSchema.optional()
73
+ });
74
+ const RuntimePreferencesSchema = z.object({
75
+ model: z.string().trim().min(1).optional(),
76
+ runtimeMode: RuntimeModeSchema.default("default"),
77
+ reasoningEffort: ReasoningEffortSchema.optional()
78
+ });
79
+ const RuntimePreferencesByWorkspacePathSchema = z.record(z.string().trim().min(1), RuntimePreferencesSchema);
80
+ const UpdateRuntimePreferencesRequestSchema = z.object({
81
+ model: z.string().trim().min(1).nullable().optional(),
82
+ runtimeMode: RuntimeModeSchema.optional(),
83
+ reasoningEffort: ReasoningEffortSchema.nullable().optional(),
84
+ threadId: z.string().trim().min(1).optional(),
85
+ workspacePath: z.string().trim().min(1).optional()
86
+ });
87
+ const RuntimePreferencesResponseSchema = z.object({
88
+ preferences: RuntimePreferencesSchema,
89
+ runtimePreferencesByWorkspacePath: RuntimePreferencesByWorkspacePathSchema.default({}),
90
+ threadId: z.string().trim().min(1).optional(),
91
+ workspacePath: z.string().trim().min(1).optional()
92
+ });
93
+ const CodexModelSchema = z.object({
94
+ id: z.string().min(1),
95
+ model: z.string().min(1),
96
+ displayName: z.string().min(1),
97
+ description: z.string().optional(),
98
+ isDefault: z.boolean().default(false),
99
+ defaultReasoningEffort: ReasoningEffortSchema.optional(),
100
+ supportedReasoningEfforts: z.array(ReasoningEffortSchema).default([])
101
+ });
102
+ const AgentSkillSourceSchema = z.enum([
103
+ "workspace",
104
+ "personal",
105
+ "system",
106
+ "plugin"
107
+ ]);
108
+ const AgentSkillSchema = z.object({
109
+ id: z.string().min(1),
110
+ name: z.string().min(1),
111
+ displayName: z.string().min(1),
112
+ description: z.string().optional(),
113
+ path: z.string().trim().min(1),
114
+ source: AgentSkillSourceSchema,
115
+ sourceLabel: z.string().min(1)
116
+ });
117
+ const ContextWindowUsageSchema = z.object({
118
+ tokensUsed: z.number().int().nonnegative(),
119
+ tokenLimit: z.number().int().positive()
120
+ });
121
+ const RateLimitWindowSchema = z.object({
122
+ usedPercent: z.number().int().min(0).max(100),
123
+ windowDurationMins: z.number().int().positive().nullable().optional(),
124
+ resetsAt: z.number().int().positive().nullable().optional()
125
+ });
126
+ const RateLimitBucketSchema = z.object({
127
+ limitId: z.string().min(1),
128
+ limitName: z.string().nullable().optional(),
129
+ planType: z.string().nullable().optional(),
130
+ primary: RateLimitWindowSchema.nullable().optional(),
131
+ secondary: RateLimitWindowSchema.nullable().optional(),
132
+ rateLimitReachedType: z.string().nullable().optional()
133
+ });
134
+ const RateLimitsResponseSchema = z.object({ buckets: z.array(RateLimitBucketSchema) });
135
+ const ThreadContextWindowResponseSchema = z.object({
136
+ threadId: z.string().min(1),
137
+ usage: ContextWindowUsageSchema.nullable(),
138
+ rolloutPath: z.string().nullable().optional()
139
+ });
140
+ const PromptAttachmentBaseSchema = z.object({
141
+ type: z.literal("image"),
142
+ mimeType: z.string().trim().startsWith("image/").optional(),
143
+ name: z.string().trim().min(1).max(160).optional(),
144
+ path: z.string().trim().min(1).optional(),
145
+ url: z.string().trim().min(1).optional()
146
+ });
147
+ const PromptAttachmentSchema = PromptAttachmentBaseSchema.refine((attachment) => Boolean(attachment.path || attachment.url), { message: "Image attachments require path or url." });
148
+ const PromptSkillSchema = AgentSkillSchema.pick({
149
+ name: true,
150
+ path: true
151
+ });
152
+ const PromptContextSchema = z.object({
153
+ attachments: z.array(PromptAttachmentSchema).max(6).default([]),
154
+ skills: z.array(PromptSkillSchema).max(12).default([])
155
+ });
156
+ const PromptContextInputSchema = PromptContextSchema.partial();
157
+ const PromptAttachmentSummarySchema = PromptAttachmentBaseSchema.pick({
158
+ mimeType: true,
159
+ name: true,
160
+ path: true,
161
+ type: true,
162
+ url: true
163
+ });
164
+ const ChatMessagePromptDetailsSchema = z.object({ attachments: z.array(PromptAttachmentSummarySchema).max(6).optional() }).passthrough();
165
+ const WorkspaceFileMentionSchema = z.object({
166
+ directory: z.string(),
167
+ kind: z.enum(["directory", "file"]),
168
+ name: z.string().min(1),
169
+ path: z.string().min(1)
170
+ });
171
+ const ListWorkspaceFilesResponseSchema = z.object({
172
+ files: z.array(WorkspaceFileMentionSchema),
173
+ query: z.string(),
174
+ workspacePath: z.string().min(1)
175
+ });
176
+ const PendingInputRequestOptionSchema = z.object({
177
+ label: z.string().min(1),
178
+ description: z.string().optional()
179
+ });
180
+ const PendingInputRequestQuestionSchema = z.object({
181
+ header: z.string().optional(),
182
+ id: z.string().min(1),
183
+ options: z.array(PendingInputRequestOptionSchema).optional(),
184
+ question: z.string().min(1)
185
+ });
186
+ const PendingInputRequestSchema = z.object({
187
+ id: z.string().min(1),
188
+ questions: z.array(PendingInputRequestQuestionSchema),
189
+ threadId: z.string().min(1),
190
+ turnId: z.string().optional()
191
+ });
192
+ const ChatMessageSchema = z.object({
193
+ id: z.string().min(1),
194
+ threadId: z.string().min(1),
195
+ role: ChatMessageRoleSchema,
196
+ kind: ChatMessageKindSchema.default("chat"),
197
+ content: z.string(),
198
+ details: z.record(z.string(), z.unknown()).optional(),
199
+ createdAt: IsoDateTimeSchema,
200
+ updatedAt: IsoDateTimeSchema.optional(),
201
+ turnId: z.string().optional(),
202
+ state: ChatMessageStateSchema.optional()
203
+ });
204
+ const ThreadSummarySchema = z.object({
205
+ id: z.string().min(1),
206
+ title: z.string().min(1),
207
+ createdAt: IsoDateTimeSchema,
208
+ updatedAt: IsoDateTimeSchema,
209
+ state: ThreadStateSchema,
210
+ model: z.string().optional(),
211
+ runtimeMode: RuntimeModeSchema.optional(),
212
+ approvalPolicy: ApprovalModeSchema.optional(),
213
+ sandboxMode: SandboxModeSchema.optional(),
214
+ reasoningEffort: ReasoningEffortSchema.optional(),
215
+ collaborationMode: ThreadCollaborationModeSchema.optional(),
216
+ cwd: z.string().optional(),
217
+ source: z.string().optional(),
218
+ messageCount: z.number().int().nonnegative().default(0),
219
+ lastMessagePreview: z.string().optional(),
220
+ lastActivityAt: IsoDateTimeSchema.optional(),
221
+ lastPrompt: z.string().optional(),
222
+ lastResult: z.string().optional(),
223
+ lastError: z.string().optional()
224
+ });
225
+ const StatusResponseSchema = z.object({
226
+ ok: z.boolean(),
227
+ service: z.literal("codex-relay-server"),
228
+ sdkAvailable: z.boolean(),
229
+ machineName: z.string().min(1),
230
+ workspacePath: z.string(),
231
+ threadCount: z.number().int().nonnegative(),
232
+ appServerAvailable: z.boolean().default(false),
233
+ preferences: RuntimePreferencesSchema.default({ runtimeMode: "default" }),
234
+ runtimePreferencesByWorkspacePath: RuntimePreferencesByWorkspacePathSchema.default({})
235
+ });
236
+ const WorkspaceDirectoryEntrySchema = z.object({
237
+ name: z.string().min(1),
238
+ path: z.string().min(1)
239
+ });
240
+ const ListWorkspaceDirectoriesResponseSchema = z.object({
241
+ rootPath: z.string().min(1),
242
+ path: z.string().min(1),
243
+ parentPath: z.string().min(1).nullable(),
244
+ directories: z.array(WorkspaceDirectoryEntrySchema)
245
+ });
246
+ const WorkspaceChangesResponseSchema = z.object({
247
+ workspacePath: z.string().min(1),
248
+ status: z.string(),
249
+ diff: z.string(),
250
+ hasChanges: z.boolean(),
251
+ currentBranch: z.string().nullable().default(null),
252
+ branches: z.array(z.object({
253
+ current: z.boolean().default(false),
254
+ name: z.string().min(1)
255
+ })).default([]),
256
+ stats: z.object({
257
+ additions: z.number().int().nonnegative(),
258
+ deletions: z.number().int().nonnegative(),
259
+ filesChanged: z.number().int().nonnegative()
260
+ }).default({
261
+ additions: 0,
262
+ deletions: 0,
263
+ filesChanged: 0
264
+ }),
265
+ files: z.array(z.object({
266
+ additions: z.number().int().nonnegative(),
267
+ deletions: z.number().int().nonnegative(),
268
+ isBinary: z.boolean().default(false),
269
+ oldPath: z.string().nullable(),
270
+ path: z.string().min(1),
271
+ patch: z.string(),
272
+ stagedStatus: z.string().nullable(),
273
+ status: z.string().min(1),
274
+ worktreeStatus: z.string().nullable()
275
+ })).default([])
276
+ });
277
+ const WorkspaceSelectionRequestSchema = z.object({ workspacePath: z.string().trim().min(1).optional() });
278
+ const CheckoutWorkspaceBranchRequestSchema = WorkspaceSelectionRequestSchema.extend({ branch: z.string().trim().min(1).refine((branch) => !branch.startsWith("-"), "Branch name cannot start with '-'.") });
279
+ const CommitPushWorkspaceRequestSchema = WorkspaceSelectionRequestSchema.extend({ message: z.string().trim().min(1).max(240) });
280
+ const WorkspaceGitActionResponseSchema = z.object({
281
+ branch: z.string().nullable(),
282
+ message: z.string().min(1),
283
+ output: z.string().default("")
284
+ });
285
+ const WebPreviewTargetSchema = z.object({
286
+ kind: z.literal("web"),
287
+ url: z.string().url(),
288
+ port: z.number().int().positive(),
289
+ label: z.string().min(1).optional(),
290
+ source: z.enum([
291
+ "detected-port",
292
+ "codex-output",
293
+ "user-entered"
294
+ ]),
295
+ confidence: z.enum([
296
+ "low",
297
+ "medium",
298
+ "high"
299
+ ]),
300
+ detectedAt: IsoDateTimeSchema
301
+ });
302
+ const PairRequestSchema = z.object({
303
+ clientSessionId: z.string().trim().min(1).max(120).optional(),
304
+ clientName: z.string().trim().min(1).max(80).optional(),
305
+ secure: z.object({
306
+ clientEphemeralPublicKey: z.string().min(1),
307
+ clientNonce: z.string().min(1),
308
+ protocolVersion: z.literal(1)
309
+ }).optional()
310
+ });
311
+ const PairResponseSchema = z.object({
312
+ approvalCode: z.string().min(1).optional(),
313
+ approvalExpiresAt: IsoDateTimeSchema.optional(),
314
+ clientToken: z.string().min(1).optional(),
315
+ clientTokenExpiresAt: IsoDateTimeSchema.optional(),
316
+ secure: z.object({
317
+ encryptedPayload: z.string().min(1),
318
+ keyEpoch: z.number().int().nonnegative(),
319
+ protocolVersion: z.literal(1),
320
+ serverEphemeralPublicKey: z.string().min(1),
321
+ serverNonce: z.string().min(1),
322
+ serverSignature: z.string().min(1)
323
+ }).optional()
324
+ });
325
+ const EncryptedPayloadSchema = z.object({
326
+ ciphertext: z.string().min(1),
327
+ counter: z.number().int().nonnegative(),
328
+ keyEpoch: z.number().int().nonnegative(),
329
+ protocolVersion: z.literal(1),
330
+ sender: z.enum(["mobile", "server"])
331
+ });
332
+ const PairEncryptedPayloadSchema = z.object({
333
+ clientToken: z.string().min(1),
334
+ clientTokenExpiresAt: IsoDateTimeSchema
335
+ });
336
+ const ErrorResponseSchema = z.object({ error: z.object({
337
+ code: z.string(),
338
+ message: z.string(),
339
+ issues: z.array(z.string()).optional()
340
+ }) });
341
+ const CreateThreadRequestSchema = z.object({
342
+ prompt: z.string().trim().min(1).optional(),
343
+ title: z.string().trim().min(1).max(120).optional(),
344
+ workspacePath: z.string().trim().min(1).optional()
345
+ }).merge(PromptContextInputSchema).merge(ThreadRunOptionsSchema.partial());
346
+ const CreateThreadResponseSchema = z.object({
347
+ thread: ThreadSummarySchema,
348
+ messages: z.array(ChatMessageSchema).default([]),
349
+ result: z.string().optional()
350
+ });
351
+ const RunThreadRequestSchema = z.object({ prompt: z.string().trim().min(1) }).merge(PromptContextInputSchema).merge(ThreadRunOptionsSchema.partial());
352
+ const StreamThreadRunRequestSchema = RunThreadRequestSchema.or(ThreadRunOptionsSchema.partial().extend({ prompt: z.string().trim().min(1).optional() }).merge(PromptContextInputSchema));
353
+ const RunThreadResponseSchema = z.object({
354
+ thread: ThreadSummarySchema,
355
+ messages: z.array(ChatMessageSchema).default([]),
356
+ result: z.string()
357
+ });
358
+ const ImageAttachmentUploadResponseSchema = z.object({ attachments: z.array(PromptAttachmentBaseSchema.pick({
359
+ mimeType: true,
360
+ name: true,
361
+ path: true,
362
+ type: true,
363
+ url: true
364
+ }).required({
365
+ path: true,
366
+ url: true
367
+ })).max(6) });
368
+ const QueuedThreadInputSchema = z.object({
369
+ attachments: PromptContextSchema.shape.attachments,
370
+ id: z.string().min(1),
371
+ prompt: z.string().min(1),
372
+ skills: PromptContextSchema.shape.skills
373
+ });
374
+ const SubmitThreadInputResponseSchema = z.object({
375
+ acceptedAs: z.enum(["steering", "queued"]),
376
+ input: QueuedThreadInputSchema.optional(),
377
+ queueLength: z.number().int().nonnegative(),
378
+ thread: ThreadSummarySchema
379
+ });
380
+ const QueuedThreadInputActionResponseSchema = z.object({
381
+ input: QueuedThreadInputSchema.optional(),
382
+ queueLength: z.number().int().nonnegative(),
383
+ thread: ThreadSummarySchema
384
+ });
385
+ const InterruptThreadRunResponseSchema = z.object({ thread: ThreadSummarySchema });
386
+ const ListQueuedThreadInputsResponseSchema = z.object({
387
+ inputs: z.array(QueuedThreadInputSchema),
388
+ queueLength: z.number().int().nonnegative()
389
+ });
390
+ const ApprovalDecisionSchema = z.enum([
391
+ "approve",
392
+ "approve-for-session",
393
+ "deny",
394
+ "cancel"
395
+ ]);
396
+ const ResolveApprovalRequestSchema = z.object({
397
+ decision: ApprovalDecisionSchema,
398
+ answers: z.array(z.string()).optional()
399
+ });
400
+ const ResolveApprovalResponseSchema = z.object({ ok: z.boolean() });
401
+ const ListThreadsResponseSchema = z.object({
402
+ threads: z.array(ThreadSummarySchema),
403
+ source: z.enum(["app-server", "memory"]).default("memory")
404
+ });
405
+ const ArchiveThreadResponseSchema = z.object({
406
+ archivedThreadId: z.string().min(1),
407
+ threads: z.array(ThreadSummarySchema),
408
+ source: z.enum(["app-server", "memory"]).default("memory")
409
+ });
410
+ const ListModelsResponseSchema = z.object({ models: z.array(CodexModelSchema) });
411
+ const ListSkillsResponseSchema = z.object({ skills: z.array(AgentSkillSchema) });
412
+ const ThreadDetailResponseSchema = z.object({
413
+ thread: ThreadSummarySchema,
414
+ messages: z.array(ChatMessageSchema),
415
+ pendingInputRequests: z.array(PendingInputRequestSchema).default([])
416
+ });
417
+ const ThreadMessageDetailFieldSchema = z.enum(["output", "patch"]);
418
+ const ThreadMessageDetailResponseSchema = z.object({
419
+ field: ThreadMessageDetailFieldSchema,
420
+ messageId: z.string().min(1),
421
+ originalLength: z.number().int().nonnegative(),
422
+ value: z.string()
423
+ });
424
+ const StreamThreadRunEventSchema = z.discriminatedUnion("type", [
425
+ z.object({
426
+ type: z.literal("thread.message.created"),
427
+ thread: ThreadSummarySchema,
428
+ message: ChatMessageSchema
429
+ }),
430
+ z.object({
431
+ type: z.literal("thread.message.delta"),
432
+ threadId: z.string().min(1),
433
+ messageId: z.string().min(1),
434
+ delta: z.string()
435
+ }),
436
+ z.object({
437
+ type: z.literal("thread.message.completed"),
438
+ thread: ThreadSummarySchema,
439
+ message: ChatMessageSchema
440
+ }),
441
+ z.object({
442
+ type: z.literal("thread.state.changed"),
443
+ thread: ThreadSummarySchema
444
+ }),
445
+ z.object({
446
+ type: z.literal("thread.error"),
447
+ thread: ThreadSummarySchema.optional(),
448
+ error: ErrorResponseSchema.shape.error
449
+ }),
450
+ z.object({
451
+ type: z.literal("thread.preview_target.detected"),
452
+ threadId: z.string().min(1),
453
+ target: WebPreviewTargetSchema
454
+ }),
455
+ z.object({
456
+ type: z.literal("thread.input_request.created"),
457
+ request: PendingInputRequestSchema,
458
+ thread: ThreadSummarySchema
459
+ }),
460
+ z.object({
461
+ type: z.literal("thread.input_request.resolved"),
462
+ requestId: z.string().min(1),
463
+ threadId: z.string().min(1)
464
+ })
465
+ ]);
466
+ function normalizePromptContext(input) {
467
+ return PromptContextSchema.parse({
468
+ attachments: input?.attachments ? [...input.attachments] : [],
469
+ skills: input?.skills ? [...input.skills] : []
470
+ });
471
+ }
472
+ function chatMessageDetailsFromPromptContext(input, extraDetails = {}) {
473
+ const context = normalizePromptContext(input);
474
+ const details = { ...extraDetails };
475
+ if (context.attachments.length > 0) details.attachments = context.attachments.map(({ mimeType, name, path, type, url }) => ({
476
+ mimeType,
477
+ name,
478
+ path,
479
+ type,
480
+ url
481
+ }));
482
+ return Object.keys(details).length > 0 ? details : void 0;
483
+ }
484
+ function promptSkillDisplayName(skill) {
485
+ const parts = skill.name.split(/[-_:]/).filter(Boolean);
486
+ return (parts.length === 2 && parts[0]?.toLowerCase() === parts[1]?.toLowerCase() ? [parts[1]] : parts).filter(Boolean).map(formatPromptSkillDisplayPart).join(" ");
487
+ }
488
+ function formatPromptSkillDisplayPart(part) {
489
+ return {
490
+ api: "API",
491
+ github: "GitHub",
492
+ ios: "iOS",
493
+ openai: "OpenAI",
494
+ ota: "OTA",
495
+ pr: "PR",
496
+ qa: "QA",
497
+ ui: "UI",
498
+ ux: "UX"
499
+ }[part.toLowerCase()] ?? `${part.charAt(0).toUpperCase()}${part.slice(1)}`;
500
+ }
501
+ function promptSkillMentionLabel(skill) {
502
+ return `$${skill.name}`;
503
+ }
504
+ function promptSkillMentionMarkdown(skill) {
505
+ return `[${escapePromptSkillMarkdownLabel(promptSkillMentionLabel(skill))}](${skill.path})`;
506
+ }
507
+ function promptMarkdownWithSkills(prompt, skills) {
508
+ const seenSkills = /* @__PURE__ */ new Set();
509
+ const markdown = promptMarkdownWithInlineSkills(prompt, skills, seenSkills).trim();
510
+ return [markdown, skills.filter((skill) => !seenSkills.has(promptSkillKey(skill))).map((skill) => promptSkillMentionMarkdown(skill)).join(" ")].filter(Boolean).join(markdown.includes("\n") ? "\n\n" : " ");
511
+ }
512
+ function promptSkillMentionTextCandidates(skill) {
513
+ const displayName = promptSkillDisplayName(skill);
514
+ return [
515
+ promptSkillMentionLabel(skill),
516
+ skill.name,
517
+ `$${displayName}`,
518
+ displayName
519
+ ];
520
+ }
521
+ function isPromptSkillMarkdownMention(label, url, skills) {
522
+ const mentionText = unescapePromptSkillMarkdownLabel(label).trim();
523
+ const normalizedUrl = safeDecodePromptSkillMarkdownUrl(url);
524
+ return skills.some((skill) => normalizedUrl === skill.path && promptSkillMentionTextCandidates(skill).includes(mentionText));
525
+ }
526
+ function stripPromptSkillMentions(prompt, skills) {
527
+ let nextPrompt = prompt.replace(/\[((?:\\.|[^\]\\])*)\]\(([^)]*)\)/g, (match, label, url) => isPromptSkillMarkdownMention(label, url, skills) ? "" : match);
528
+ for (const skill of skills) for (const candidate of promptSkillMentionTextCandidates(skill)) nextPrompt = nextPrompt.replace(new RegExp(`(^|\\s)${escapePromptSkillRegExp(candidate)}(?=\\s|$)`, "g"), "$1");
529
+ return nextPrompt.replace(/\s{2,}/g, " ").trim();
530
+ }
531
+ function promptMarkdownWithInlineSkills(prompt, skills, seenSkills) {
532
+ let nextPrompt = prompt.replace(/\[((?:\\.|[^\]\\])*)\]\(([^)]*)\)/g, (match, label, url) => {
533
+ const skill = skills.find((candidate) => isPromptSkillMarkdownMention(label, url, [candidate]));
534
+ if (!skill) return match;
535
+ seenSkills.add(promptSkillKey(skill));
536
+ return promptSkillMentionMarkdown(skill);
537
+ });
538
+ for (const skill of skills) for (const candidate of promptSkillMentionTextCandidates(skill)) nextPrompt = replacePromptSkillTextMention(nextPrompt, candidate, skill, seenSkills);
539
+ return nextPrompt;
540
+ }
541
+ function replacePromptSkillTextMention(prompt, candidate, skill, seenSkills) {
542
+ const linkRegex = /\[((?:\\.|[^\]\\])*)\]\([^)]*\)/g;
543
+ let result = "";
544
+ let cursor = 0;
545
+ let linkMatch;
546
+ while (linkMatch = linkRegex.exec(prompt)) {
547
+ result += replacePromptSkillTextMentionSegment(prompt.slice(cursor, linkMatch.index), candidate, skill, seenSkills);
548
+ result += linkMatch[0];
549
+ cursor = linkMatch.index + linkMatch[0].length;
550
+ }
551
+ result += replacePromptSkillTextMentionSegment(prompt.slice(cursor), candidate, skill, seenSkills);
552
+ return result;
553
+ }
554
+ function replacePromptSkillTextMentionSegment(segment, candidate, skill, seenSkills) {
555
+ return segment.replace(new RegExp(`(^|\\s)${escapePromptSkillRegExp(candidate)}(?=\\s|$)`, "g"), (_match, prefix) => {
556
+ seenSkills.add(promptSkillKey(skill));
557
+ return `${prefix}${promptSkillMentionMarkdown(skill)}`;
558
+ });
559
+ }
560
+ function promptSkillKey(skill) {
561
+ return `${skill.name}\n${skill.path}`;
562
+ }
563
+ function unescapePromptSkillMarkdownLabel(value) {
564
+ return value.replace(/\\([\\[\]])/g, "$1");
565
+ }
566
+ function escapePromptSkillMarkdownLabel(value) {
567
+ return value.replaceAll("\\", "\\\\").replaceAll("[", "\\[").replaceAll("]", "\\]");
568
+ }
569
+ function safeDecodePromptSkillMarkdownUrl(value) {
570
+ try {
571
+ return decodeURIComponent(value);
572
+ } catch {
573
+ return value;
574
+ }
575
+ }
576
+ function escapePromptSkillRegExp(value) {
577
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
578
+ }
579
+ const apiPaths = {
580
+ version: "/version",
581
+ pair: "/v1/pair",
582
+ pairApproval: (approvalCode) => `/v1/pair/${encodeURIComponent(approvalCode)}`,
583
+ pairApprove: "/v1/pair/approve",
584
+ sessionRefresh: "/v1/session/refresh",
585
+ status: "/v1/status",
586
+ preferences: "/v1/preferences",
587
+ rateLimits: "/v1/rate-limits",
588
+ models: "/v1/models",
589
+ skills: "/v1/skills",
590
+ workspaceFiles: "/v1/workspace/files",
591
+ workspaceDirectories: "/v1/workspace-directories",
592
+ workspaceChanges: "/v1/workspace/changes",
593
+ workspaceCheckout: "/v1/workspace/checkout",
594
+ workspaceCommitPush: "/v1/workspace/commit-push",
595
+ imageAttachments: "/v1/attachments/images",
596
+ imageAttachment: (attachmentId) => `/v1/attachments/images/${encodeURIComponent(attachmentId)}`,
597
+ threads: "/v1/threads",
598
+ thread: (threadId) => `/v1/threads/${encodeURIComponent(threadId)}`,
599
+ threadArchive: (threadId) => `/v1/threads/${encodeURIComponent(threadId)}`,
600
+ threadContextWindow: (threadId) => `/v1/threads/${encodeURIComponent(threadId)}/context-window`,
601
+ threadMessageDetail: (threadId, messageId, field) => `/v1/threads/${encodeURIComponent(threadId)}/messages/${encodeURIComponent(messageId)}/details/${encodeURIComponent(field)}`,
602
+ approval: (approvalId) => `/v1/approvals/${encodeURIComponent(approvalId)}`,
603
+ threadInput: (threadId) => `/v1/threads/${encodeURIComponent(threadId)}/input`,
604
+ threadQueuedInput: (threadId, inputId) => `/v1/threads/${encodeURIComponent(threadId)}/input/${encodeURIComponent(inputId)}`,
605
+ threadQueuedInputSteer: (threadId, inputId) => `/v1/threads/${encodeURIComponent(threadId)}/input/${encodeURIComponent(inputId)}/steer`,
606
+ threadRuns: (threadId) => `/v1/threads/${encodeURIComponent(threadId)}/runs`,
607
+ threadRunInterrupt: (threadId) => `/v1/threads/${encodeURIComponent(threadId)}/runs/interrupt`,
608
+ threadRunStream: (threadId) => `/v1/threads/${encodeURIComponent(threadId)}/runs/stream`
609
+ };
610
+ function createOpenApiDocument() {
611
+ return {
612
+ openapi: "3.1.0",
613
+ info: {
614
+ title: "Codex Relay Local Codex API",
615
+ version: "0.1.0"
616
+ },
617
+ paths: {
618
+ "/version": { get: {
619
+ summary: "Relay package version",
620
+ responses: { "200": jsonResponse("VersionResponse") }
621
+ } },
622
+ "/v1/status": { get: {
623
+ summary: "Local server status",
624
+ responses: { "200": jsonResponse("StatusResponse") }
625
+ } },
626
+ "/v1/preferences": { patch: {
627
+ summary: "Update default runtime preferences",
628
+ requestBody: jsonRequest("UpdateRuntimePreferencesRequest"),
629
+ responses: {
630
+ "200": jsonResponse("RuntimePreferencesResponse"),
631
+ "400": jsonResponse("ErrorResponse")
632
+ }
633
+ } },
634
+ "/v1/threads": {
635
+ get: {
636
+ summary: "List locally known threads",
637
+ responses: { "200": jsonResponse("ListThreadsResponse") }
638
+ },
639
+ post: {
640
+ summary: "Start a Codex thread",
641
+ requestBody: jsonRequest("CreateThreadRequest"),
642
+ responses: {
643
+ "201": jsonResponse("CreateThreadResponse"),
644
+ "400": jsonResponse("ErrorResponse")
645
+ }
646
+ }
647
+ },
648
+ "/v1/threads/{threadId}": {
649
+ get: {
650
+ summary: "Read a Codex thread with full available message history",
651
+ parameters: [{
652
+ name: "threadId",
653
+ in: "path",
654
+ required: true,
655
+ schema: { type: "string" }
656
+ }],
657
+ responses: {
658
+ "200": jsonResponse("ThreadDetailResponse"),
659
+ "404": jsonResponse("ErrorResponse")
660
+ }
661
+ },
662
+ delete: {
663
+ summary: "Archive a Codex thread",
664
+ parameters: [{
665
+ name: "threadId",
666
+ in: "path",
667
+ required: true,
668
+ schema: { type: "string" }
669
+ }],
670
+ responses: {
671
+ "200": jsonResponse("ArchiveThreadResponse"),
672
+ "404": jsonResponse("ErrorResponse"),
673
+ "502": jsonResponse("ErrorResponse")
674
+ }
675
+ }
676
+ },
677
+ "/v1/workspace-directories": { get: {
678
+ summary: "List directories under the configured workspace",
679
+ responses: {
680
+ "200": jsonResponse("ListWorkspaceDirectoriesResponse"),
681
+ "400": jsonResponse("ErrorResponse")
682
+ }
683
+ } },
684
+ "/v1/threads/{threadId}/runs": { post: {
685
+ summary: "Run a prompt on a Codex thread",
686
+ parameters: [{
687
+ name: "threadId",
688
+ in: "path",
689
+ required: true,
690
+ schema: { type: "string" }
691
+ }],
692
+ requestBody: jsonRequest("RunThreadRequest"),
693
+ responses: {
694
+ "200": jsonResponse("RunThreadResponse"),
695
+ "400": jsonResponse("ErrorResponse"),
696
+ "404": jsonResponse("ErrorResponse")
697
+ }
698
+ } },
699
+ "/v1/threads/{threadId}/runs/interrupt": { post: {
700
+ summary: "Interrupt the active Codex app-server turn",
701
+ parameters: [{
702
+ name: "threadId",
703
+ in: "path",
704
+ required: true,
705
+ schema: { type: "string" }
706
+ }],
707
+ responses: {
708
+ "200": jsonResponse("InterruptThreadRunResponse"),
709
+ "404": jsonResponse("ErrorResponse"),
710
+ "409": jsonResponse("ErrorResponse")
711
+ }
712
+ } },
713
+ "/v1/threads/{threadId}/input": {
714
+ post: {
715
+ summary: "Submit input to an already-running Codex thread",
716
+ requestBody: jsonRequest("RunThreadRequest"),
717
+ responses: {
718
+ "202": jsonResponse("SubmitThreadInputResponse"),
719
+ "400": jsonResponse("ErrorResponse"),
720
+ "404": jsonResponse("ErrorResponse"),
721
+ "409": jsonResponse("ErrorResponse")
722
+ }
723
+ },
724
+ get: {
725
+ summary: "List queued input for an already-running Codex thread",
726
+ responses: {
727
+ "200": jsonResponse("ListQueuedThreadInputsResponse"),
728
+ "404": jsonResponse("ErrorResponse")
729
+ }
730
+ }
731
+ },
732
+ "/v1/threads/{threadId}/runs/stream": { post: {
733
+ summary: "Run a prompt or attach to an already-running Codex thread and stream events",
734
+ requestBody: jsonRequest("StreamThreadRunRequest"),
735
+ responses: {
736
+ "200": {
737
+ description: "Server-sent events containing StreamThreadRunEvent payloads",
738
+ content: { "text/event-stream": { schema: { $ref: "#/components/schemas/StreamThreadRunEvent" } } }
739
+ },
740
+ "400": jsonResponse("ErrorResponse"),
741
+ "404": jsonResponse("ErrorResponse")
742
+ }
743
+ } }
744
+ },
745
+ components: { schemas: {
746
+ ThreadState: {
747
+ type: "string",
748
+ enum: ThreadStateSchema.options
749
+ },
750
+ ChatMessage: {
751
+ type: "object",
752
+ required: [
753
+ "id",
754
+ "threadId",
755
+ "role",
756
+ "content",
757
+ "createdAt"
758
+ ],
759
+ properties: {
760
+ id: { type: "string" },
761
+ threadId: { type: "string" },
762
+ role: {
763
+ type: "string",
764
+ enum: ChatMessageRoleSchema.options
765
+ },
766
+ kind: {
767
+ type: "string",
768
+ enum: ChatMessageKindSchema.options
769
+ },
770
+ content: { type: "string" },
771
+ details: {
772
+ type: "object",
773
+ additionalProperties: true
774
+ },
775
+ createdAt: {
776
+ type: "string",
777
+ format: "date-time"
778
+ },
779
+ updatedAt: {
780
+ type: "string",
781
+ format: "date-time"
782
+ },
783
+ turnId: { type: "string" },
784
+ state: {
785
+ type: "string",
786
+ enum: ChatMessageStateSchema.options
787
+ }
788
+ }
789
+ },
790
+ ThreadSummary: {
791
+ type: "object",
792
+ required: [
793
+ "id",
794
+ "title",
795
+ "createdAt",
796
+ "updatedAt",
797
+ "state",
798
+ "messageCount"
799
+ ],
800
+ properties: {
801
+ id: { type: "string" },
802
+ title: { type: "string" },
803
+ createdAt: {
804
+ type: "string",
805
+ format: "date-time"
806
+ },
807
+ updatedAt: {
808
+ type: "string",
809
+ format: "date-time"
810
+ },
811
+ state: { $ref: "#/components/schemas/ThreadState" },
812
+ messageCount: {
813
+ type: "integer",
814
+ minimum: 0
815
+ },
816
+ model: { type: "string" },
817
+ runtimeMode: { $ref: "#/components/schemas/RuntimeMode" },
818
+ approvalPolicy: {
819
+ type: "string",
820
+ enum: [
821
+ "on-request",
822
+ "on-failure",
823
+ "never"
824
+ ]
825
+ },
826
+ sandboxMode: {
827
+ type: "string",
828
+ enum: [
829
+ "workspace-write",
830
+ "danger-full-access",
831
+ "read-only"
832
+ ]
833
+ },
834
+ reasoningEffort: { $ref: "#/components/schemas/ReasoningEffort" },
835
+ cwd: { type: "string" },
836
+ source: { type: "string" },
837
+ lastMessagePreview: { type: "string" },
838
+ lastActivityAt: {
839
+ type: "string",
840
+ format: "date-time"
841
+ },
842
+ lastPrompt: { type: "string" },
843
+ lastResult: { type: "string" },
844
+ lastError: { type: "string" }
845
+ }
846
+ },
847
+ StatusResponse: {
848
+ type: "object",
849
+ required: [
850
+ "ok",
851
+ "service",
852
+ "sdkAvailable",
853
+ "machineName",
854
+ "workspacePath",
855
+ "threadCount"
856
+ ],
857
+ properties: {
858
+ ok: { type: "boolean" },
859
+ service: {
860
+ type: "string",
861
+ const: "codex-relay-server"
862
+ },
863
+ sdkAvailable: { type: "boolean" },
864
+ machineName: { type: "string" },
865
+ workspacePath: { type: "string" },
866
+ threadCount: {
867
+ type: "integer",
868
+ minimum: 0
869
+ },
870
+ appServerAvailable: { type: "boolean" },
871
+ preferences: { $ref: "#/components/schemas/RuntimePreferences" },
872
+ runtimePreferencesByWorkspacePath: {
873
+ type: "object",
874
+ additionalProperties: { $ref: "#/components/schemas/RuntimePreferences" }
875
+ }
876
+ }
877
+ },
878
+ VersionResponse: {
879
+ type: "object",
880
+ required: [
881
+ "ok",
882
+ "service",
883
+ "packageName",
884
+ "packageVersion"
885
+ ],
886
+ properties: {
887
+ ok: { type: "boolean" },
888
+ service: {
889
+ type: "string",
890
+ const: "codex-relay-server"
891
+ },
892
+ packageName: {
893
+ type: "string",
894
+ const: "codex-relay"
895
+ },
896
+ packageVersion: { type: "string" }
897
+ }
898
+ },
899
+ RuntimePreferences: {
900
+ type: "object",
901
+ required: ["runtimeMode"],
902
+ properties: {
903
+ model: { type: "string" },
904
+ runtimeMode: {
905
+ type: "string",
906
+ enum: [
907
+ "default",
908
+ "auto",
909
+ "full-access",
910
+ "on-request"
911
+ ],
912
+ default: "default"
913
+ },
914
+ reasoningEffort: {
915
+ type: "string",
916
+ enum: [
917
+ "minimal",
918
+ "low",
919
+ "medium",
920
+ "high",
921
+ "xhigh"
922
+ ]
923
+ }
924
+ }
925
+ },
926
+ UpdateRuntimePreferencesRequest: {
927
+ type: "object",
928
+ properties: {
929
+ threadId: { type: "string" },
930
+ workspacePath: { type: "string" },
931
+ model: {
932
+ type: "string",
933
+ nullable: true
934
+ },
935
+ runtimeMode: {
936
+ type: "string",
937
+ enum: [
938
+ "default",
939
+ "auto",
940
+ "full-access",
941
+ "on-request"
942
+ ]
943
+ },
944
+ reasoningEffort: {
945
+ type: "string",
946
+ enum: [
947
+ "minimal",
948
+ "low",
949
+ "medium",
950
+ "high",
951
+ "xhigh"
952
+ ],
953
+ nullable: true
954
+ }
955
+ }
956
+ },
957
+ RuntimePreferencesResponse: {
958
+ type: "object",
959
+ required: ["preferences"],
960
+ properties: {
961
+ preferences: { $ref: "#/components/schemas/RuntimePreferences" },
962
+ runtimePreferencesByWorkspacePath: {
963
+ type: "object",
964
+ additionalProperties: { $ref: "#/components/schemas/RuntimePreferences" }
965
+ },
966
+ threadId: { type: "string" },
967
+ workspacePath: { type: "string" }
968
+ }
969
+ },
970
+ WorkspaceDirectoryEntry: {
971
+ type: "object",
972
+ required: ["name", "path"],
973
+ properties: {
974
+ name: { type: "string" },
975
+ path: { type: "string" }
976
+ }
977
+ },
978
+ ListWorkspaceDirectoriesResponse: {
979
+ type: "object",
980
+ required: [
981
+ "rootPath",
982
+ "path",
983
+ "parentPath",
984
+ "directories"
985
+ ],
986
+ properties: {
987
+ rootPath: { type: "string" },
988
+ path: { type: "string" },
989
+ parentPath: {
990
+ type: "string",
991
+ nullable: true
992
+ },
993
+ directories: {
994
+ type: "array",
995
+ items: { $ref: "#/components/schemas/WorkspaceDirectoryEntry" }
996
+ }
997
+ }
998
+ },
999
+ CreateThreadRequest: {
1000
+ type: "object",
1001
+ properties: {
1002
+ attachments: {
1003
+ type: "array",
1004
+ maxItems: 6,
1005
+ items: { $ref: "#/components/schemas/PromptAttachment" }
1006
+ },
1007
+ prompt: { type: "string" },
1008
+ skills: {
1009
+ type: "array",
1010
+ maxItems: 12,
1011
+ items: { $ref: "#/components/schemas/PromptSkill" }
1012
+ },
1013
+ title: {
1014
+ type: "string",
1015
+ maxLength: 120
1016
+ },
1017
+ workspacePath: { type: "string" },
1018
+ collaborationMode: {
1019
+ type: "string",
1020
+ enum: ["default", "plan"],
1021
+ default: "default"
1022
+ }
1023
+ }
1024
+ },
1025
+ PromptAttachment: {
1026
+ type: "object",
1027
+ required: ["type"],
1028
+ properties: {
1029
+ type: {
1030
+ type: "string",
1031
+ const: "image"
1032
+ },
1033
+ mimeType: {
1034
+ type: "string",
1035
+ pattern: "^image/"
1036
+ },
1037
+ name: {
1038
+ type: "string",
1039
+ maxLength: 160
1040
+ },
1041
+ path: { type: "string" },
1042
+ url: { type: "string" }
1043
+ }
1044
+ },
1045
+ PromptSkill: {
1046
+ type: "object",
1047
+ required: ["name", "path"],
1048
+ properties: {
1049
+ name: { type: "string" },
1050
+ path: { type: "string" }
1051
+ }
1052
+ },
1053
+ CreateThreadResponse: {
1054
+ type: "object",
1055
+ required: ["thread"],
1056
+ properties: {
1057
+ thread: { $ref: "#/components/schemas/ThreadSummary" },
1058
+ messages: {
1059
+ type: "array",
1060
+ items: { $ref: "#/components/schemas/ChatMessage" }
1061
+ },
1062
+ result: { type: "string" }
1063
+ }
1064
+ },
1065
+ RunThreadRequest: {
1066
+ type: "object",
1067
+ required: ["prompt"],
1068
+ properties: {
1069
+ attachments: {
1070
+ type: "array",
1071
+ maxItems: 6,
1072
+ items: { $ref: "#/components/schemas/PromptAttachment" }
1073
+ },
1074
+ prompt: { type: "string" },
1075
+ skills: {
1076
+ type: "array",
1077
+ maxItems: 12,
1078
+ items: { $ref: "#/components/schemas/PromptSkill" }
1079
+ },
1080
+ collaborationMode: {
1081
+ type: "string",
1082
+ enum: ["default", "plan"],
1083
+ default: "default"
1084
+ }
1085
+ }
1086
+ },
1087
+ StreamThreadRunRequest: {
1088
+ type: "object",
1089
+ properties: {
1090
+ attachments: {
1091
+ type: "array",
1092
+ maxItems: 6,
1093
+ items: { $ref: "#/components/schemas/PromptAttachment" }
1094
+ },
1095
+ prompt: { type: "string" },
1096
+ skills: {
1097
+ type: "array",
1098
+ maxItems: 12,
1099
+ items: { $ref: "#/components/schemas/PromptSkill" }
1100
+ },
1101
+ collaborationMode: {
1102
+ type: "string",
1103
+ enum: ["default", "plan"],
1104
+ default: "default"
1105
+ }
1106
+ }
1107
+ },
1108
+ RunThreadResponse: {
1109
+ type: "object",
1110
+ required: ["thread", "result"],
1111
+ properties: {
1112
+ thread: { $ref: "#/components/schemas/ThreadSummary" },
1113
+ messages: {
1114
+ type: "array",
1115
+ items: { $ref: "#/components/schemas/ChatMessage" }
1116
+ },
1117
+ result: { type: "string" }
1118
+ }
1119
+ },
1120
+ SubmitThreadInputResponse: {
1121
+ type: "object",
1122
+ required: [
1123
+ "acceptedAs",
1124
+ "queueLength",
1125
+ "thread"
1126
+ ],
1127
+ properties: {
1128
+ acceptedAs: {
1129
+ type: "string",
1130
+ enum: ["steering", "queued"]
1131
+ },
1132
+ input: { $ref: "#/components/schemas/QueuedThreadInput" },
1133
+ queueLength: {
1134
+ type: "integer",
1135
+ minimum: 0
1136
+ },
1137
+ thread: { $ref: "#/components/schemas/ThreadSummary" }
1138
+ }
1139
+ },
1140
+ QueuedThreadInput: {
1141
+ type: "object",
1142
+ required: [
1143
+ "attachments",
1144
+ "id",
1145
+ "prompt",
1146
+ "skills"
1147
+ ],
1148
+ properties: {
1149
+ attachments: {
1150
+ type: "array",
1151
+ maxItems: 6,
1152
+ items: { $ref: "#/components/schemas/PromptAttachment" }
1153
+ },
1154
+ id: { type: "string" },
1155
+ prompt: { type: "string" },
1156
+ skills: {
1157
+ type: "array",
1158
+ maxItems: 12,
1159
+ items: { $ref: "#/components/schemas/PromptSkill" }
1160
+ }
1161
+ }
1162
+ },
1163
+ QueuedThreadInputActionResponse: {
1164
+ type: "object",
1165
+ required: ["queueLength", "thread"],
1166
+ properties: {
1167
+ input: { $ref: "#/components/schemas/QueuedThreadInput" },
1168
+ queueLength: {
1169
+ type: "integer",
1170
+ minimum: 0
1171
+ },
1172
+ thread: { $ref: "#/components/schemas/ThreadSummary" }
1173
+ }
1174
+ },
1175
+ InterruptThreadRunResponse: {
1176
+ type: "object",
1177
+ required: ["thread"],
1178
+ properties: { thread: { $ref: "#/components/schemas/ThreadSummary" } }
1179
+ },
1180
+ ListQueuedThreadInputsResponse: {
1181
+ type: "object",
1182
+ required: ["inputs", "queueLength"],
1183
+ properties: {
1184
+ inputs: {
1185
+ type: "array",
1186
+ items: { $ref: "#/components/schemas/QueuedThreadInput" }
1187
+ },
1188
+ queueLength: {
1189
+ type: "integer",
1190
+ minimum: 0
1191
+ }
1192
+ }
1193
+ },
1194
+ PendingInputRequest: {
1195
+ type: "object",
1196
+ required: [
1197
+ "id",
1198
+ "questions",
1199
+ "threadId"
1200
+ ],
1201
+ properties: {
1202
+ id: { type: "string" },
1203
+ questions: {
1204
+ type: "array",
1205
+ items: { $ref: "#/components/schemas/PendingInputRequestQuestion" }
1206
+ },
1207
+ threadId: { type: "string" },
1208
+ turnId: { type: "string" }
1209
+ }
1210
+ },
1211
+ PendingInputRequestQuestion: {
1212
+ type: "object",
1213
+ required: ["id", "question"],
1214
+ properties: {
1215
+ header: { type: "string" },
1216
+ id: { type: "string" },
1217
+ options: {
1218
+ type: "array",
1219
+ items: { $ref: "#/components/schemas/PendingInputRequestOption" }
1220
+ },
1221
+ question: { type: "string" }
1222
+ }
1223
+ },
1224
+ PendingInputRequestOption: {
1225
+ type: "object",
1226
+ required: ["label"],
1227
+ properties: {
1228
+ label: { type: "string" },
1229
+ description: { type: "string" }
1230
+ }
1231
+ },
1232
+ ThreadDetailResponse: {
1233
+ type: "object",
1234
+ required: ["thread", "messages"],
1235
+ properties: {
1236
+ thread: { $ref: "#/components/schemas/ThreadSummary" },
1237
+ messages: {
1238
+ type: "array",
1239
+ items: { $ref: "#/components/schemas/ChatMessage" }
1240
+ },
1241
+ pendingInputRequests: {
1242
+ type: "array",
1243
+ items: { $ref: "#/components/schemas/PendingInputRequest" }
1244
+ }
1245
+ }
1246
+ },
1247
+ ThreadMessageDetailResponse: {
1248
+ type: "object",
1249
+ required: [
1250
+ "field",
1251
+ "messageId",
1252
+ "originalLength",
1253
+ "value"
1254
+ ],
1255
+ properties: {
1256
+ field: {
1257
+ type: "string",
1258
+ enum: ["output", "patch"]
1259
+ },
1260
+ messageId: { type: "string" },
1261
+ originalLength: {
1262
+ type: "integer",
1263
+ minimum: 0
1264
+ },
1265
+ value: { type: "string" }
1266
+ }
1267
+ },
1268
+ StreamThreadRunEvent: { oneOf: [
1269
+ {
1270
+ type: "object",
1271
+ properties: { type: { const: "thread.message.created" } }
1272
+ },
1273
+ {
1274
+ type: "object",
1275
+ properties: { type: { const: "thread.message.delta" } }
1276
+ },
1277
+ {
1278
+ type: "object",
1279
+ properties: { type: { const: "thread.message.completed" } }
1280
+ },
1281
+ {
1282
+ type: "object",
1283
+ properties: { type: { const: "thread.state.changed" } }
1284
+ },
1285
+ {
1286
+ type: "object",
1287
+ properties: { type: { const: "thread.error" } }
1288
+ },
1289
+ {
1290
+ type: "object",
1291
+ properties: { type: { const: "thread.preview_target.detected" } }
1292
+ }
1293
+ ] },
1294
+ ListThreadsResponse: {
1295
+ type: "object",
1296
+ required: ["threads"],
1297
+ properties: { threads: {
1298
+ type: "array",
1299
+ items: { $ref: "#/components/schemas/ThreadSummary" }
1300
+ } }
1301
+ },
1302
+ ArchiveThreadResponse: {
1303
+ type: "object",
1304
+ required: ["archivedThreadId", "threads"],
1305
+ properties: {
1306
+ archivedThreadId: { type: "string" },
1307
+ source: {
1308
+ type: "string",
1309
+ enum: ["app-server", "memory"]
1310
+ },
1311
+ threads: {
1312
+ type: "array",
1313
+ items: { $ref: "#/components/schemas/ThreadSummary" }
1314
+ }
1315
+ }
1316
+ },
1317
+ ErrorResponse: {
1318
+ type: "object",
1319
+ required: ["error"],
1320
+ properties: { error: {
1321
+ type: "object",
1322
+ required: ["code", "message"],
1323
+ properties: {
1324
+ code: { type: "string" },
1325
+ message: { type: "string" },
1326
+ issues: {
1327
+ type: "array",
1328
+ items: { type: "string" }
1329
+ }
1330
+ }
1331
+ } }
1332
+ }
1333
+ } }
1334
+ };
1335
+ }
1336
+ function jsonRequest(schemaName) {
1337
+ return {
1338
+ required: true,
1339
+ content: { "application/json": { schema: { $ref: `#/components/schemas/${schemaName}` } } }
1340
+ };
1341
+ }
1342
+ function jsonResponse(schemaName) {
1343
+ return {
1344
+ description: schemaName,
1345
+ content: { "application/json": { schema: { $ref: `#/components/schemas/${schemaName}` } } }
1346
+ };
1347
+ }
1348
+ //#endregion
1349
+ export { SandboxModeSchema as $, PairResponseSchema as A, stripPromptSkillMentions as At, QueuedThreadInputSchema as B, ListQueuedThreadInputsResponseSchema as C, isPromptSkillMarkdownMention as Ct, ListWorkspaceFilesResponseSchema as D, promptSkillMentionLabel as Dt, ListWorkspaceDirectoriesResponseSchema as E, promptSkillDisplayName as Et, PromptAttachmentSummarySchema as F, ResolveApprovalRequestSchema as G, RateLimitWindowSchema as H, PromptContextInputSchema as I, RunThreadResponseSchema as J, ResolveApprovalResponseSchema as K, PromptContextSchema as L, PendingInputRequestQuestionSchema as M, PendingInputRequestSchema as N, PairEncryptedPayloadSchema as O, promptSkillMentionMarkdown as Ot, PromptAttachmentSchema as P, RuntimePreferencesSchema as Q, PromptSkillSchema as R, ListModelsResponseSchema as S, createOpenApiDocument as St, ListThreadsResponseSchema as T, promptMarkdownWithSkills as Tt, RateLimitsResponseSchema as U, RateLimitBucketSchema as V, ReasoningEffortSchema as W, RuntimePreferencesByWorkspacePathSchema as X, RuntimeModeSchema as Y, RuntimePreferencesResponseSchema as Z, EncryptedPayloadSchema as _, WorkspaceFileMentionSchema as _t, ArchiveThreadResponseSchema as a, ThreadContextWindowResponseSchema as at, InterruptThreadRunResponseSchema as b, apiPaths as bt, ChatMessageRoleSchema as c, ThreadMessageDetailResponseSchema as ct, CheckoutWorkspaceBranchRequestSchema as d, ThreadSummarySchema as dt, StatusResponseSchema as et, CodexModelSchema as f, UpdateRuntimePreferencesRequestSchema as ft, CreateThreadResponseSchema as g, WorkspaceDirectoryEntrySchema as gt, CreateThreadRequestSchema as h, WorkspaceChangesResponseSchema as ht, ApprovalModeSchema as i, ThreadCollaborationModeSchema as it, PendingInputRequestOptionSchema as j, PairRequestSchema as k, promptSkillMentionTextCandidates as kt, ChatMessageSchema as l, ThreadRunOptionsSchema as lt, ContextWindowUsageSchema as m, WebPreviewTargetSchema as mt, AgentSkillSourceSchema as n, StreamThreadRunRequestSchema as nt, ChatMessageKindSchema as o, ThreadDetailResponseSchema as ot, CommitPushWorkspaceRequestSchema as p, VersionResponseSchema as pt, RunThreadRequestSchema as q, ApprovalDecisionSchema as r, SubmitThreadInputResponseSchema as rt, ChatMessagePromptDetailsSchema as s, ThreadMessageDetailFieldSchema as st, AgentSkillSchema as t, StreamThreadRunEventSchema as tt, ChatMessageStateSchema as u, ThreadStateSchema as ut, ErrorResponseSchema as v, WorkspaceGitActionResponseSchema as vt, ListSkillsResponseSchema as w, normalizePromptContext as wt, IsoDateTimeSchema as x, chatMessageDetailsFromPromptContext as xt, ImageAttachmentUploadResponseSchema as y, WorkspaceSelectionRequestSchema as yt, QueuedThreadInputActionResponseSchema as z };