@nextclaw/nextclaw-ncp-runtime-codex-sdk 0.1.54 → 0.1.55-beta.1

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.
Files changed (34) hide show
  1. package/dist/index.d.ts +5 -1
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +15 -5
  4. package/dist/index.js.map +1 -1
  5. package/dist/services/codex-app-server-client.service.js +242 -0
  6. package/dist/services/codex-app-server-client.service.js.map +1 -0
  7. package/dist/services/codex-app-server-ncp-agent-runtime.service.d.ts +32 -0
  8. package/dist/services/codex-app-server-ncp-agent-runtime.service.d.ts.map +1 -0
  9. package/dist/services/codex-app-server-ncp-agent-runtime.service.js +410 -0
  10. package/dist/services/codex-app-server-ncp-agent-runtime.service.js.map +1 -0
  11. package/dist/services/codex-desktop-thread-index-sync.service.d.ts +47 -0
  12. package/dist/services/codex-desktop-thread-index-sync.service.d.ts.map +1 -0
  13. package/dist/services/codex-desktop-thread-index-sync.service.js +256 -0
  14. package/dist/services/codex-desktop-thread-index-sync.service.js.map +1 -0
  15. package/dist/types/codex-app-server-runtime.types.d.ts +26 -0
  16. package/dist/types/codex-app-server-runtime.types.d.ts.map +1 -0
  17. package/dist/utils/codex-app-server-item-mapper.utils.js +67 -0
  18. package/dist/utils/codex-app-server-item-mapper.utils.js.map +1 -0
  19. package/dist/utils/codex-app-server-request.utils.js +49 -0
  20. package/dist/utils/codex-app-server-request.utils.js.map +1 -0
  21. package/dist/{codex-openai-responses-bridge-assistant-output.utils.js → utils/codex-openai-responses-bridge-assistant-output.utils.js} +2 -2
  22. package/dist/utils/codex-openai-responses-bridge-assistant-output.utils.js.map +1 -0
  23. package/dist/utils/codex-openai-responses-bridge-request.utils.js.map +1 -1
  24. package/dist/utils/codex-openai-responses-bridge-stream.utils.js +1 -1
  25. package/dist/utils/codex-openai-responses-bridge-stream.utils.js.map +1 -1
  26. package/dist/utils/codex-openai-responses-bridge.utils.js.map +1 -1
  27. package/dist/utils/codex-openai-responses-stream-writer.utils.d.ts.map +1 -1
  28. package/dist/utils/codex-openai-responses-stream-writer.utils.js +2 -9
  29. package/dist/utils/codex-openai-responses-stream-writer.utils.js.map +1 -1
  30. package/dist/utils/codex-openai-sse-chunks.utils.js.map +1 -1
  31. package/dist/utils/codex-rollout-thread-summary.utils.js +121 -0
  32. package/dist/utils/codex-rollout-thread-summary.utils.js.map +1 -0
  33. package/package.json +4 -3
  34. package/dist/codex-openai-responses-bridge-assistant-output.utils.js.map +0 -1
@@ -0,0 +1,410 @@
1
+ import { CodexNcpRunEventEmitter } from "./codex-ncp-run-event-emitter.service.js";
2
+ import { buildCodexTurnInputFromRunInput } from "../codex-input.utils.js";
3
+ import { isAppServerToolLikeItem, readAppServerReasoningText, readAppServerToolArgs, readAppServerToolName, readAppServerToolResult, stringifyAppServerToolArgs } from "../utils/codex-app-server-item-mapper.utils.js";
4
+ import { compactObject, normalizeSandbox, splitModelRoute, toAppServerInput } from "../utils/codex-app-server-request.utils.js";
5
+ import { CodexAppServerClient } from "./codex-app-server-client.service.js";
6
+ import { CodexDesktopThreadIndexSyncService } from "./codex-desktop-thread-index-sync.service.js";
7
+ import { NcpEventType } from "@nextclaw/ncp";
8
+ //#region src/services/codex-app-server-ncp-agent-runtime.service.ts
9
+ var CodexAppServerNcpAgentRuntime = class {
10
+ eventEmitter;
11
+ sessionMetadata;
12
+ desktopThreadIndexSync;
13
+ clientPromise = null;
14
+ threadId;
15
+ constructor(config) {
16
+ this.config = config;
17
+ this.eventEmitter = new CodexNcpRunEventEmitter(config.stateManager);
18
+ this.desktopThreadIndexSync = resolveDesktopThreadIndexSync(config);
19
+ this.threadId = config.threadId?.trim() || null;
20
+ this.sessionMetadata = { ...config.sessionMetadata ? structuredClone(config.sessionMetadata) : {} };
21
+ }
22
+ run = async function* (input, options) {
23
+ const signal = options?.signal;
24
+ const messageId = createId("codex-message");
25
+ const runId = input.runId ?? createId("codex-run");
26
+ const textState = /* @__PURE__ */ new Set();
27
+ const textDeltaState = /* @__PURE__ */ new Set();
28
+ const reasoningState = /* @__PURE__ */ new Set();
29
+ const reasoningDeltaState = /* @__PURE__ */ new Set();
30
+ const toolState = /* @__PURE__ */ new Set();
31
+ yield* this.eventEmitter.emitRunStarted(input.sessionId, messageId, runId);
32
+ yield* this.eventEmitter.emitReadyMetadata(input.sessionId, messageId, runId);
33
+ const client = await this.resolveClient();
34
+ await this.resolveThread(client);
35
+ const turnInput = await this.buildTurnInput(input);
36
+ const turnId = readString((await client.request("turn/start", {
37
+ threadId: this.threadId ?? "",
38
+ input: toAppServerInput(turnInput),
39
+ ...this.buildTurnOverrides()
40
+ })).turn?.id);
41
+ const abortListener = () => {
42
+ if (turnId && this.threadId) client.request("turn/interrupt", {
43
+ threadId: this.threadId,
44
+ turnId
45
+ }, 5e3).catch(() => {
46
+ client.dispose();
47
+ });
48
+ else client.dispose();
49
+ };
50
+ signal?.addEventListener("abort", abortListener, { once: true });
51
+ try {
52
+ while (true) {
53
+ if (signal?.aborted) throw toAbortError(signal.reason);
54
+ const next = await client.nextNotification();
55
+ if (next.done) return;
56
+ if (yield* this.handleNotification({
57
+ notification: next.value,
58
+ sessionId: input.sessionId,
59
+ messageId,
60
+ runId,
61
+ textState,
62
+ textDeltaState,
63
+ reasoningState,
64
+ reasoningDeltaState,
65
+ toolState
66
+ })) return;
67
+ }
68
+ } finally {
69
+ signal?.removeEventListener("abort", abortListener);
70
+ }
71
+ };
72
+ resolveClient = async () => {
73
+ if (!this.clientPromise) {
74
+ const client = new CodexAppServerClient(this.config);
75
+ this.clientPromise = client.initialize().then(() => client);
76
+ }
77
+ return this.clientPromise;
78
+ };
79
+ resolveThread = async (client) => {
80
+ if (this.threadId) {
81
+ const response = await client.request("thread/resume", {
82
+ threadId: this.threadId,
83
+ ...this.buildThreadOverrides()
84
+ });
85
+ await this.updateThreadId(readString(response.thread?.id) ?? this.threadId);
86
+ return;
87
+ }
88
+ const nextThreadId = readString((await client.request("thread/start", { ...this.buildThreadOverrides() })).thread?.id);
89
+ if (nextThreadId) await this.updateThreadId(nextThreadId);
90
+ };
91
+ buildThreadOverrides = () => {
92
+ const threadOptions = this.config.threadOptions;
93
+ const route = splitModelRoute(threadOptions?.model ?? this.config.model);
94
+ return compactObject({
95
+ cwd: threadOptions?.workingDirectory,
96
+ model: route.model,
97
+ modelProvider: route.modelProvider,
98
+ approvalPolicy: threadOptions?.approvalPolicy,
99
+ sandbox: normalizeSandbox(threadOptions?.sandboxMode),
100
+ config: this.config.cliConfig
101
+ });
102
+ };
103
+ buildTurnOverrides = () => {
104
+ const threadOptions = this.config.threadOptions;
105
+ const route = splitModelRoute(threadOptions?.model ?? this.config.model);
106
+ return compactObject({
107
+ cwd: threadOptions?.workingDirectory,
108
+ model: route.model,
109
+ effort: threadOptions?.modelReasoningEffort,
110
+ sandboxPolicy: normalizeSandbox(threadOptions?.sandboxMode),
111
+ approvalPolicy: threadOptions?.approvalPolicy
112
+ });
113
+ };
114
+ buildTurnInput = async (input) => {
115
+ if (this.config.inputBuilder) return await this.config.inputBuilder(input);
116
+ return await buildCodexTurnInputFromRunInput(input, { resolveAssetContentPath: this.config.resolveAssetContentPath });
117
+ };
118
+ handleNotification = async function* (params) {
119
+ const { messageId, notification, reasoningDeltaState, reasoningState, runId, sessionId, textDeltaState, textState, toolState } = params;
120
+ if (notification.method === "thread/started") {
121
+ await this.handleThreadStarted(notification.params);
122
+ return false;
123
+ }
124
+ if (notification.method === "item/agentMessage/delta") {
125
+ yield* this.emitTextDelta({
126
+ messageId,
127
+ params: notification.params,
128
+ sessionId,
129
+ textDeltaState,
130
+ textState
131
+ });
132
+ return false;
133
+ }
134
+ if (notification.method === "item/reasoning/textDelta" || notification.method === "item/reasoning/summaryTextDelta") {
135
+ yield* this.emitReasoningDelta({
136
+ messageId,
137
+ params: notification.params,
138
+ reasoningDeltaState,
139
+ reasoningState,
140
+ sessionId
141
+ });
142
+ return false;
143
+ }
144
+ if (notification.method === "item/started" || notification.method === "item/completed") {
145
+ const item = notification.params.item;
146
+ if (item) yield* this.handleItemLifecycle({
147
+ item,
148
+ eventType: notification.method,
149
+ sessionId,
150
+ messageId,
151
+ reasoningDeltaState,
152
+ textState,
153
+ textDeltaState,
154
+ reasoningState,
155
+ toolState
156
+ });
157
+ return false;
158
+ }
159
+ if (notification.method === "turn/completed") {
160
+ yield* this.eventEmitter.emitRunCompleted(sessionId, messageId, runId);
161
+ await this.syncDesktopThreadIndex();
162
+ return true;
163
+ }
164
+ if (notification.method === "turn/failed") {
165
+ yield* this.eventEmitter.emitRunError(sessionId, messageId, runId, readString(notification.params.error) ?? "Codex turn failed.");
166
+ return true;
167
+ }
168
+ return false;
169
+ };
170
+ handleThreadStarted = async (params) => {
171
+ const threadId = readString(params.thread?.id);
172
+ if (threadId) await this.updateThreadId(threadId);
173
+ };
174
+ emitTextDelta = async function* (params) {
175
+ const { messageId, sessionId, textDeltaState, textState } = params;
176
+ const itemId = readString(params.params.itemId) ?? "agent-message";
177
+ if (!textState.has(itemId)) {
178
+ textState.add(itemId);
179
+ yield* this.eventEmitter.emitEvent({
180
+ type: NcpEventType.MessageTextStart,
181
+ payload: {
182
+ sessionId,
183
+ messageId
184
+ }
185
+ });
186
+ }
187
+ textDeltaState.add(itemId);
188
+ yield* this.eventEmitter.emitEvent({
189
+ type: NcpEventType.MessageTextDelta,
190
+ payload: {
191
+ sessionId,
192
+ messageId,
193
+ delta: readRawString(params.params.delta) ?? ""
194
+ }
195
+ });
196
+ };
197
+ emitReasoningDelta = async function* (params) {
198
+ const { messageId, reasoningDeltaState, reasoningState, sessionId } = params;
199
+ const itemId = readString(params.params.itemId) ?? "reasoning";
200
+ if (!reasoningState.has(itemId)) {
201
+ reasoningState.add(itemId);
202
+ yield* this.eventEmitter.emitEvent({
203
+ type: NcpEventType.MessageReasoningStart,
204
+ payload: {
205
+ sessionId,
206
+ messageId
207
+ }
208
+ });
209
+ }
210
+ reasoningDeltaState.add(itemId);
211
+ yield* this.eventEmitter.emitEvent({
212
+ type: NcpEventType.MessageReasoningDelta,
213
+ payload: {
214
+ sessionId,
215
+ messageId,
216
+ delta: readRawString(params.params.delta) ?? ""
217
+ }
218
+ });
219
+ };
220
+ handleItemLifecycle = async function* (params) {
221
+ const { eventType, item, messageId, reasoningDeltaState, reasoningState, sessionId, textDeltaState, textState, toolState } = params;
222
+ const itemId = readString(item.id) ?? createId("codex-item");
223
+ if (item.type === "agentMessage") {
224
+ yield* this.handleAgentMessageItem({
225
+ eventType,
226
+ item,
227
+ itemId,
228
+ messageId,
229
+ sessionId,
230
+ textDeltaState,
231
+ textState
232
+ });
233
+ return;
234
+ }
235
+ if (item.type === "reasoning") {
236
+ yield* this.handleReasoningItem({
237
+ eventType,
238
+ item,
239
+ itemId,
240
+ messageId,
241
+ reasoningDeltaState,
242
+ reasoningState,
243
+ sessionId
244
+ });
245
+ return;
246
+ }
247
+ if (!isAppServerToolLikeItem(item.type)) return;
248
+ yield* this.handleToolItem({
249
+ eventType,
250
+ item,
251
+ itemId,
252
+ messageId,
253
+ sessionId,
254
+ toolState
255
+ });
256
+ };
257
+ handleAgentMessageItem = async function* (params) {
258
+ const { eventType, item, itemId, messageId, sessionId, textDeltaState, textState } = params;
259
+ if (!textState.has(itemId)) {
260
+ textState.add(itemId);
261
+ yield* this.eventEmitter.emitEvent({
262
+ type: NcpEventType.MessageTextStart,
263
+ payload: {
264
+ sessionId,
265
+ messageId
266
+ }
267
+ });
268
+ }
269
+ const text = readRawString(item.text);
270
+ if (text && !textDeltaState.has(itemId)) yield* this.eventEmitter.emitEvent({
271
+ type: NcpEventType.MessageTextDelta,
272
+ payload: {
273
+ sessionId,
274
+ messageId,
275
+ delta: text
276
+ }
277
+ });
278
+ if (eventType === "item/completed") yield* this.eventEmitter.emitEvent({
279
+ type: NcpEventType.MessageTextEnd,
280
+ payload: {
281
+ sessionId,
282
+ messageId
283
+ }
284
+ });
285
+ };
286
+ handleReasoningItem = async function* (params) {
287
+ const { eventType, item, itemId, messageId, reasoningDeltaState, reasoningState, sessionId } = params;
288
+ const reasoningText = readAppServerReasoningText(item);
289
+ if (!reasoningState.has(itemId) && (eventType === "item/started" || reasoningText)) {
290
+ reasoningState.add(itemId);
291
+ yield* this.eventEmitter.emitEvent({
292
+ type: NcpEventType.MessageReasoningStart,
293
+ payload: {
294
+ sessionId,
295
+ messageId
296
+ }
297
+ });
298
+ }
299
+ if (!reasoningDeltaState.has(itemId) && reasoningText) yield* this.eventEmitter.emitEvent({
300
+ type: NcpEventType.MessageReasoningDelta,
301
+ payload: {
302
+ sessionId,
303
+ messageId,
304
+ delta: reasoningText
305
+ }
306
+ });
307
+ if (eventType === "item/completed" && reasoningState.has(itemId)) yield* this.eventEmitter.emitEvent({
308
+ type: NcpEventType.MessageReasoningEnd,
309
+ payload: {
310
+ sessionId,
311
+ messageId
312
+ }
313
+ });
314
+ };
315
+ handleToolItem = async function* (params) {
316
+ const { eventType, item, itemId, messageId, sessionId, toolState } = params;
317
+ if (!toolState.has(itemId)) {
318
+ toolState.add(itemId);
319
+ yield* this.eventEmitter.emitEvent({
320
+ type: NcpEventType.MessageToolCallStart,
321
+ payload: {
322
+ sessionId,
323
+ messageId,
324
+ toolCallId: itemId,
325
+ toolName: readAppServerToolName(item)
326
+ }
327
+ });
328
+ yield* this.eventEmitter.emitEvent({
329
+ type: NcpEventType.MessageToolCallArgs,
330
+ payload: {
331
+ sessionId,
332
+ toolCallId: itemId,
333
+ args: stringifyAppServerToolArgs(readAppServerToolArgs(item))
334
+ }
335
+ });
336
+ yield* this.eventEmitter.emitEvent({
337
+ type: NcpEventType.MessageToolCallEnd,
338
+ payload: {
339
+ sessionId,
340
+ toolCallId: itemId
341
+ }
342
+ });
343
+ }
344
+ if (eventType === "item/completed") yield* this.eventEmitter.emitEvent({
345
+ type: NcpEventType.MessageToolCallResult,
346
+ payload: {
347
+ sessionId,
348
+ toolCallId: itemId,
349
+ content: readAppServerToolResult(item)
350
+ }
351
+ });
352
+ };
353
+ updateThreadId = async (nextThreadId) => {
354
+ const normalizedThreadId = nextThreadId.trim();
355
+ if (!normalizedThreadId || normalizedThreadId === this.threadId) return;
356
+ this.threadId = normalizedThreadId;
357
+ const nextMetadata = {
358
+ ...this.sessionMetadata,
359
+ session_type: "codex",
360
+ codex_thread_id: normalizedThreadId,
361
+ codex_thread_model: buildThreadModelScope(this.config)
362
+ };
363
+ this.sessionMetadata.codex_thread_id = normalizedThreadId;
364
+ this.sessionMetadata.codex_thread_model = nextMetadata.codex_thread_model;
365
+ this.sessionMetadata.session_type = "codex";
366
+ await this.config.setSessionMetadata?.(nextMetadata);
367
+ };
368
+ syncDesktopThreadIndex = async () => {
369
+ try {
370
+ await this.desktopThreadIndexSync?.syncThread({ threadId: this.threadId });
371
+ } catch (error) {
372
+ console.error(`[nextclaw-codex-app-server] failed to run Codex Desktop thread index sync: ${formatError(error)}`);
373
+ }
374
+ };
375
+ };
376
+ function createId(prefix) {
377
+ return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
378
+ }
379
+ function resolveDesktopThreadIndexSync(config) {
380
+ if (config.desktopThreadIndexSync === false) return null;
381
+ return config.desktopThreadIndexSync ?? new CodexDesktopThreadIndexSyncService({ env: {
382
+ ...process.env,
383
+ ...config.env
384
+ } });
385
+ }
386
+ function readString(value) {
387
+ if (typeof value !== "string") return;
388
+ const trimmed = value.trim();
389
+ return trimmed.length > 0 ? trimmed : void 0;
390
+ }
391
+ function readRawString(value) {
392
+ return typeof value === "string" ? value : void 0;
393
+ }
394
+ function buildThreadModelScope(config) {
395
+ return readString(config.threadOptions?.model) ?? readString(config.model) ?? "__nextclaw_runtime_default__";
396
+ }
397
+ function toAbortError(reason) {
398
+ if (reason instanceof Error) return reason;
399
+ const message = typeof reason === "string" && reason.trim() ? reason.trim() : "operation aborted";
400
+ const error = new Error(message);
401
+ error.name = "AbortError";
402
+ return error;
403
+ }
404
+ function formatError(error) {
405
+ return error instanceof Error ? error.message : String(error);
406
+ }
407
+ //#endregion
408
+ export { CodexAppServerNcpAgentRuntime };
409
+
410
+ //# sourceMappingURL=codex-app-server-ncp-agent-runtime.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-app-server-ncp-agent-runtime.service.js","names":[],"sources":["../../src/services/codex-app-server-ncp-agent-runtime.service.ts"],"sourcesContent":["import {\n type NcpAgentRunInput,\n type NcpAgentRunOptions,\n type NcpAgentRuntime,\n type NcpEndpointEvent,\n NcpEventType,\n} from \"@nextclaw/ncp\";\nimport {\n buildCodexTurnInputFromRunInput,\n type CodexThreadInput,\n} from \"@/codex-input.utils.js\";\nimport {\n isAppServerToolLikeItem,\n readAppServerReasoningText,\n readAppServerToolArgs,\n readAppServerToolName,\n readAppServerToolResult,\n stringifyAppServerToolArgs,\n} from \"@/utils/codex-app-server-item-mapper.utils.js\";\nimport {\n compactObject,\n normalizeSandbox,\n splitModelRoute,\n toAppServerInput,\n} from \"@/utils/codex-app-server-request.utils.js\";\nimport { CodexAppServerClient } from \"./codex-app-server-client.service.js\";\nimport type {\n AppServerNotification,\n AppServerThreadItem,\n CodexAppServerNcpAgentRuntimeConfig,\n JsonObject,\n} from \"@/types/codex-app-server-runtime.types.js\";\nimport { CodexNcpRunEventEmitter } from \"./codex-ncp-run-event-emitter.service.js\";\nimport {\n CodexDesktopThreadIndexSyncService,\n type CodexDesktopThreadIndexSync,\n} from \"./codex-desktop-thread-index-sync.service.js\";\n\nexport class CodexAppServerNcpAgentRuntime implements NcpAgentRuntime {\n private readonly eventEmitter: CodexNcpRunEventEmitter;\n private readonly sessionMetadata: Record<string, unknown>;\n private readonly desktopThreadIndexSync: CodexDesktopThreadIndexSync | null;\n private clientPromise: Promise<CodexAppServerClient> | null = null;\n private threadId: string | null;\n\n constructor(private readonly config: CodexAppServerNcpAgentRuntimeConfig) {\n this.eventEmitter = new CodexNcpRunEventEmitter(config.stateManager);\n this.desktopThreadIndexSync = resolveDesktopThreadIndexSync(config);\n this.threadId = config.threadId?.trim() || null;\n this.sessionMetadata = {\n ...(config.sessionMetadata ? structuredClone(config.sessionMetadata) : {}),\n };\n }\n\n run = async function* (\n this: CodexAppServerNcpAgentRuntime,\n input: NcpAgentRunInput,\n options?: NcpAgentRunOptions,\n ): AsyncGenerator<NcpEndpointEvent> {\n const signal = options?.signal;\n const messageId = createId(\"codex-message\");\n const runId = (input as NcpAgentRunInput & { runId?: string }).runId ?? createId(\"codex-run\");\n const textState = new Set<string>();\n const textDeltaState = new Set<string>();\n const reasoningState = new Set<string>();\n const reasoningDeltaState = new Set<string>();\n const toolState = new Set<string>();\n\n yield* this.eventEmitter.emitRunStarted(input.sessionId, messageId, runId);\n yield* this.eventEmitter.emitReadyMetadata(input.sessionId, messageId, runId);\n\n const client = await this.resolveClient();\n await this.resolveThread(client);\n const turnInput = await this.buildTurnInput(input);\n const turn = await client.request<{ turn?: { id?: string } }>(\"turn/start\", {\n threadId: this.threadId ?? \"\",\n input: toAppServerInput(turnInput),\n ...this.buildTurnOverrides(),\n });\n const turnId = readString(turn.turn?.id);\n const abortListener = (): void => {\n if (turnId && this.threadId) {\n void client.request(\"turn/interrupt\", { threadId: this.threadId, turnId }, 5000).catch(() => {\n client.dispose();\n });\n } else {\n client.dispose();\n }\n };\n signal?.addEventListener(\"abort\", abortListener, { once: true });\n try {\n while (true) {\n if (signal?.aborted) {\n throw toAbortError(signal.reason);\n }\n const next = await client.nextNotification();\n if (next.done) {\n return;\n }\n const shouldFinish = yield* this.handleNotification({\n notification: next.value,\n sessionId: input.sessionId,\n messageId,\n runId,\n textState,\n textDeltaState,\n reasoningState,\n reasoningDeltaState,\n toolState,\n });\n if (shouldFinish) {\n return;\n }\n }\n } finally {\n signal?.removeEventListener(\"abort\", abortListener);\n }\n };\n\n private resolveClient = async (): Promise<CodexAppServerClient> => {\n if (!this.clientPromise) {\n const client = new CodexAppServerClient(this.config);\n this.clientPromise = client.initialize().then(() => client);\n }\n return this.clientPromise;\n };\n\n private resolveThread = async (client: CodexAppServerClient): Promise<void> => {\n if (this.threadId) {\n const response = await client.request<{ thread?: { id?: string } }>(\"thread/resume\", {\n threadId: this.threadId,\n ...this.buildThreadOverrides(),\n });\n await this.updateThreadId(readString(response.thread?.id) ?? this.threadId);\n return;\n }\n const response = await client.request<{ thread?: { id?: string } }>(\"thread/start\", {\n ...this.buildThreadOverrides(),\n });\n const nextThreadId = readString(response.thread?.id);\n if (nextThreadId) {\n await this.updateThreadId(nextThreadId);\n }\n };\n\n private buildThreadOverrides = (): JsonObject => {\n const threadOptions = this.config.threadOptions;\n const route = splitModelRoute(threadOptions?.model ?? this.config.model);\n return compactObject({\n cwd: threadOptions?.workingDirectory,\n model: route.model,\n modelProvider: route.modelProvider,\n approvalPolicy: threadOptions?.approvalPolicy,\n sandbox: normalizeSandbox(threadOptions?.sandboxMode),\n config: this.config.cliConfig,\n });\n };\n\n private buildTurnOverrides = (): JsonObject => {\n const threadOptions = this.config.threadOptions;\n const route = splitModelRoute(threadOptions?.model ?? this.config.model);\n return compactObject({\n cwd: threadOptions?.workingDirectory,\n model: route.model,\n effort: threadOptions?.modelReasoningEffort,\n sandboxPolicy: normalizeSandbox(threadOptions?.sandboxMode),\n approvalPolicy: threadOptions?.approvalPolicy,\n });\n };\n\n private buildTurnInput = async (input: NcpAgentRunInput): Promise<CodexThreadInput> => {\n if (this.config.inputBuilder) {\n return await this.config.inputBuilder(input);\n }\n return await buildCodexTurnInputFromRunInput(input, {\n resolveAssetContentPath: this.config.resolveAssetContentPath,\n });\n };\n\n private handleNotification = async function* (\n this: CodexAppServerNcpAgentRuntime,\n params: {\n notification: AppServerNotification;\n sessionId: string;\n messageId: string;\n runId: string;\n textState: Set<string>;\n textDeltaState: Set<string>;\n reasoningState: Set<string>;\n reasoningDeltaState: Set<string>;\n toolState: Set<string>;\n },\n ): AsyncGenerator<NcpEndpointEvent, boolean> {\n const {\n messageId,\n notification,\n reasoningDeltaState,\n reasoningState,\n runId,\n sessionId,\n textDeltaState,\n textState,\n toolState,\n } = params;\n if (notification.method === \"thread/started\") {\n await this.handleThreadStarted(notification.params);\n return false;\n }\n if (notification.method === \"item/agentMessage/delta\") {\n yield* this.emitTextDelta({\n messageId,\n params: notification.params,\n sessionId,\n textDeltaState,\n textState,\n });\n return false;\n }\n if (\n notification.method === \"item/reasoning/textDelta\" ||\n notification.method === \"item/reasoning/summaryTextDelta\"\n ) {\n yield* this.emitReasoningDelta({\n messageId,\n params: notification.params,\n reasoningDeltaState,\n reasoningState,\n sessionId,\n });\n return false;\n }\n if (notification.method === \"item/started\" || notification.method === \"item/completed\") {\n const item = notification.params.item as AppServerThreadItem | undefined;\n if (item) {\n yield* this.handleItemLifecycle({\n item,\n eventType: notification.method,\n sessionId,\n messageId,\n reasoningDeltaState,\n textState,\n textDeltaState,\n reasoningState,\n toolState,\n });\n }\n return false;\n }\n if (notification.method === \"turn/completed\") {\n yield* this.eventEmitter.emitRunCompleted(sessionId, messageId, runId);\n await this.syncDesktopThreadIndex();\n return true;\n }\n if (notification.method === \"turn/failed\") {\n yield* this.eventEmitter.emitRunError(\n sessionId,\n messageId,\n runId,\n readString(notification.params.error) ?? \"Codex turn failed.\",\n );\n return true;\n }\n return false;\n };\n\n private handleThreadStarted = async (params: JsonObject): Promise<void> => {\n const threadId = readString((params.thread as JsonObject | undefined)?.id);\n if (threadId) {\n await this.updateThreadId(threadId);\n }\n };\n\n private emitTextDelta = async function* (\n this: CodexAppServerNcpAgentRuntime,\n params: {\n params: JsonObject;\n sessionId: string;\n messageId: string;\n textState: Set<string>;\n textDeltaState: Set<string>;\n },\n ): AsyncGenerator<NcpEndpointEvent> {\n const { messageId, sessionId, textDeltaState, textState } = params;\n const itemId = readString(params.params.itemId) ?? \"agent-message\";\n if (!textState.has(itemId)) {\n textState.add(itemId);\n yield* this.eventEmitter.emitEvent({\n type: NcpEventType.MessageTextStart,\n payload: { sessionId, messageId },\n });\n }\n textDeltaState.add(itemId);\n yield* this.eventEmitter.emitEvent({\n type: NcpEventType.MessageTextDelta,\n payload: { sessionId, messageId, delta: readRawString(params.params.delta) ?? \"\" },\n });\n };\n\n private emitReasoningDelta = async function* (\n this: CodexAppServerNcpAgentRuntime,\n params: {\n params: JsonObject;\n sessionId: string;\n messageId: string;\n reasoningState: Set<string>;\n reasoningDeltaState: Set<string>;\n },\n ): AsyncGenerator<NcpEndpointEvent> {\n const { messageId, reasoningDeltaState, reasoningState, sessionId } = params;\n const itemId = readString(params.params.itemId) ?? \"reasoning\";\n if (!reasoningState.has(itemId)) {\n reasoningState.add(itemId);\n yield* this.eventEmitter.emitEvent({\n type: NcpEventType.MessageReasoningStart,\n payload: { sessionId, messageId },\n });\n }\n reasoningDeltaState.add(itemId);\n yield* this.eventEmitter.emitEvent({\n type: NcpEventType.MessageReasoningDelta,\n payload: { sessionId, messageId, delta: readRawString(params.params.delta) ?? \"\" },\n });\n };\n\n private handleItemLifecycle = async function* (\n this: CodexAppServerNcpAgentRuntime,\n params: {\n item: AppServerThreadItem;\n eventType: \"item/started\" | \"item/completed\";\n sessionId: string;\n messageId: string;\n textState: Set<string>;\n textDeltaState: Set<string>;\n reasoningState: Set<string>;\n reasoningDeltaState: Set<string>;\n toolState: Set<string>;\n },\n ): AsyncGenerator<NcpEndpointEvent> {\n const {\n eventType,\n item,\n messageId,\n reasoningDeltaState,\n reasoningState,\n sessionId,\n textDeltaState,\n textState,\n toolState,\n } = params;\n const itemId = readString(item.id) ?? createId(\"codex-item\");\n if (item.type === \"agentMessage\") {\n yield* this.handleAgentMessageItem({\n eventType,\n item,\n itemId,\n messageId,\n sessionId,\n textDeltaState,\n textState,\n });\n return;\n }\n if (item.type === \"reasoning\") {\n yield* this.handleReasoningItem({\n eventType,\n item,\n itemId,\n messageId,\n reasoningDeltaState,\n reasoningState,\n sessionId,\n });\n return;\n }\n if (!isAppServerToolLikeItem(item.type)) {\n return;\n }\n yield* this.handleToolItem({ eventType, item, itemId, messageId, sessionId, toolState });\n };\n\n private handleAgentMessageItem = async function* (\n this: CodexAppServerNcpAgentRuntime,\n params: {\n item: AppServerThreadItem;\n itemId: string;\n eventType: \"item/started\" | \"item/completed\";\n sessionId: string;\n messageId: string;\n textState: Set<string>;\n textDeltaState: Set<string>;\n },\n ): AsyncGenerator<NcpEndpointEvent> {\n const { eventType, item, itemId, messageId, sessionId, textDeltaState, textState } = params;\n if (!textState.has(itemId)) {\n textState.add(itemId);\n yield* this.eventEmitter.emitEvent({\n type: NcpEventType.MessageTextStart,\n payload: { sessionId, messageId },\n });\n }\n const text = readRawString(item.text);\n if (text && !textDeltaState.has(itemId)) {\n yield* this.eventEmitter.emitEvent({\n type: NcpEventType.MessageTextDelta,\n payload: { sessionId, messageId, delta: text },\n });\n }\n if (eventType === \"item/completed\") {\n yield* this.eventEmitter.emitEvent({\n type: NcpEventType.MessageTextEnd,\n payload: { sessionId, messageId },\n });\n }\n };\n\n private handleReasoningItem = async function* (\n this: CodexAppServerNcpAgentRuntime,\n params: {\n item: AppServerThreadItem;\n itemId: string;\n eventType: \"item/started\" | \"item/completed\";\n sessionId: string;\n messageId: string;\n reasoningState: Set<string>;\n reasoningDeltaState: Set<string>;\n },\n ): AsyncGenerator<NcpEndpointEvent> {\n const { eventType, item, itemId, messageId, reasoningDeltaState, reasoningState, sessionId } =\n params;\n const reasoningText = readAppServerReasoningText(item);\n const alreadyStarted = reasoningState.has(itemId);\n if (!alreadyStarted && (eventType === \"item/started\" || reasoningText)) {\n reasoningState.add(itemId);\n yield* this.eventEmitter.emitEvent({\n type: NcpEventType.MessageReasoningStart,\n payload: { sessionId, messageId },\n });\n }\n if (!reasoningDeltaState.has(itemId) && reasoningText) {\n yield* this.eventEmitter.emitEvent({\n type: NcpEventType.MessageReasoningDelta,\n payload: { sessionId, messageId, delta: reasoningText },\n });\n }\n if (eventType === \"item/completed\" && reasoningState.has(itemId)) {\n yield* this.eventEmitter.emitEvent({\n type: NcpEventType.MessageReasoningEnd,\n payload: { sessionId, messageId },\n });\n }\n };\n\n private handleToolItem = async function* (\n this: CodexAppServerNcpAgentRuntime,\n params: {\n item: AppServerThreadItem;\n itemId: string;\n eventType: \"item/started\" | \"item/completed\";\n sessionId: string;\n messageId: string;\n toolState: Set<string>;\n },\n ): AsyncGenerator<NcpEndpointEvent> {\n const { eventType, item, itemId, messageId, sessionId, toolState } = params;\n if (!toolState.has(itemId)) {\n toolState.add(itemId);\n yield* this.eventEmitter.emitEvent({\n type: NcpEventType.MessageToolCallStart,\n payload: { sessionId, messageId, toolCallId: itemId, toolName: readAppServerToolName(item) },\n });\n yield* this.eventEmitter.emitEvent({\n type: NcpEventType.MessageToolCallArgs,\n payload: {\n sessionId,\n toolCallId: itemId,\n args: stringifyAppServerToolArgs(readAppServerToolArgs(item)),\n },\n });\n yield* this.eventEmitter.emitEvent({\n type: NcpEventType.MessageToolCallEnd,\n payload: { sessionId, toolCallId: itemId },\n });\n }\n if (eventType === \"item/completed\") {\n yield* this.eventEmitter.emitEvent({\n type: NcpEventType.MessageToolCallResult,\n payload: { sessionId, toolCallId: itemId, content: readAppServerToolResult(item) },\n });\n }\n };\n\n private updateThreadId = async (nextThreadId: string): Promise<void> => {\n const normalizedThreadId = nextThreadId.trim();\n if (!normalizedThreadId || normalizedThreadId === this.threadId) {\n return;\n }\n this.threadId = normalizedThreadId;\n const nextMetadata = {\n ...this.sessionMetadata,\n session_type: \"codex\",\n codex_thread_id: normalizedThreadId,\n codex_thread_model: buildThreadModelScope(this.config),\n };\n this.sessionMetadata.codex_thread_id = normalizedThreadId;\n this.sessionMetadata.codex_thread_model = nextMetadata.codex_thread_model;\n this.sessionMetadata.session_type = \"codex\";\n await this.config.setSessionMetadata?.(nextMetadata);\n };\n\n private syncDesktopThreadIndex = async (): Promise<void> => {\n try {\n await this.desktopThreadIndexSync?.syncThread({ threadId: this.threadId });\n } catch (error) {\n console.error(\n `[nextclaw-codex-app-server] failed to run Codex Desktop thread index sync: ${formatError(error)}`,\n );\n }\n };\n}\n\nfunction createId(prefix: string): string {\n return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction resolveDesktopThreadIndexSync(\n config: CodexAppServerNcpAgentRuntimeConfig,\n): CodexDesktopThreadIndexSync | null {\n if (config.desktopThreadIndexSync === false) {\n return null;\n }\n return config.desktopThreadIndexSync ?? new CodexDesktopThreadIndexSyncService({\n env: { ...process.env, ...config.env },\n });\n}\n\nfunction readString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction readRawString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction buildThreadModelScope(config: CodexAppServerNcpAgentRuntimeConfig): string {\n return readString(config.threadOptions?.model) ??\n readString(config.model) ??\n \"__nextclaw_runtime_default__\";\n}\n\nfunction toAbortError(reason: unknown): Error {\n if (reason instanceof Error) {\n return reason;\n }\n const message = typeof reason === \"string\" && reason.trim() ? reason.trim() : \"operation aborted\";\n const error = new Error(message);\n error.name = \"AbortError\";\n return error;\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ //#region src/services/codex-desktop-thread-index-sync.service.d.ts
2
+ type CodexDesktopStatement = {
3
+ all: (...params: unknown[]) => unknown[];
4
+ get: (...params: unknown[]) => unknown;
5
+ run: (...params: unknown[]) => unknown;
6
+ };
7
+ type CodexDesktopDatabase = {
8
+ close: () => void;
9
+ exec: (sql: string) => void;
10
+ prepare: (sql: string) => CodexDesktopStatement;
11
+ };
12
+ type CodexDesktopDatabaseSyncCtor = new (path: string) => CodexDesktopDatabase;
13
+ interface CodexDesktopThreadIndexSync {
14
+ syncThread(params: {
15
+ threadId?: string | null;
16
+ }): Promise<void>;
17
+ }
18
+ interface CodexDesktopThreadIndexSyncServiceOptions {
19
+ databasePath?: string;
20
+ env?: NodeJS.ProcessEnv;
21
+ homeDirectory?: string;
22
+ loadDatabaseSync?: () => Promise<CodexDesktopDatabaseSyncCtor>;
23
+ logger?: Pick<Console, "error" | "warn">;
24
+ sessionsDirectory?: string;
25
+ }
26
+ declare class CodexDesktopThreadIndexSyncService implements CodexDesktopThreadIndexSync {
27
+ private readonly databasePath?;
28
+ private readonly env;
29
+ private readonly homeDirectory;
30
+ private readonly loadDatabaseSync;
31
+ private readonly logger;
32
+ private readonly sessionsDirectory?;
33
+ constructor(options?: CodexDesktopThreadIndexSyncServiceOptions);
34
+ syncThread: (params: {
35
+ threadId?: string | null;
36
+ }) => Promise<void>;
37
+ private syncThreadIndex;
38
+ private insertThreadRow;
39
+ private updateThreadRow;
40
+ private resolveRolloutPath;
41
+ private resolveDatabasePath;
42
+ private resolveSessionsDirectory;
43
+ private resolveCodexHome;
44
+ }
45
+ //#endregion
46
+ export { CodexDesktopThreadIndexSync, CodexDesktopThreadIndexSyncService, CodexDesktopThreadIndexSyncServiceOptions };
47
+ //# sourceMappingURL=codex-desktop-thread-index-sync.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-desktop-thread-index-sync.service.d.ts","names":[],"sources":["../../src/services/codex-desktop-thread-index-sync.service.ts"],"mappings":";KA2CK,qBAAA;EACH,GAAA,MAAS,MAAA;EACT,GAAA,MAAS,MAAA;EACT,GAAA,MAAS,MAAA;AAAA;AAAA,KAGN,oBAAA;EACH,KAAA;EACA,IAAA,GAAO,GAAA;EACP,OAAA,GAAU,GAAA,aAAgB,qBAAA;AAAA;AAAA,KAGvB,4BAAA,QAAoC,IAAA,aAAiB,oBAAA;AAAA,UAUzC,2BAAA;EACf,UAAA,CAAW,MAAA;IAAU,QAAA;EAAA,IAA6B,OAAA;AAAA;AAAA,UAGnC,yCAAA;EACf,YAAA;EACA,GAAA,GAAM,MAAA,CAAO,UAAA;EACb,aAAA;EACA,gBAAA,SAAyB,OAAA,CAAQ,4BAAA;EACjC,MAAA,GAAS,IAAA,CAAK,OAAA;EACd,iBAAA;AAAA;AAAA,cAGW,kCAAA,YAA8C,2BAAA;EAAA,iBACxC,YAAA;EAAA,iBACA,GAAA;EAAA,iBACA,aAAA;EAAA,iBACA,gBAAA;EAAA,iBACA,MAAA;EAAA,iBACA,iBAAA;cAEL,OAAA,GAAS,yCAAA;EAUrB,UAAA,GAAoB,MAAA;IAAU,QAAA;EAAA,MAA6B,OAAA;EAAA,QAiBnD,eAAA;EAAA,QA6CA,eAAA;EAAA,QA2DA,eAAA;EAAA,QA8CA,kBAAA;EAAA,QAcA,mBAAA;EAAA,QAOA,wBAAA;EAAA,QAOA,gBAAA;AAAA"}