@nextclaw/nextclaw-ncp-runtime-codex-sdk 0.1.57 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/services/codex-app-server-ncp-agent-runtime.service.d.ts.map +1 -1
- package/dist/services/codex-app-server-ncp-agent-runtime.service.js +43 -41
- package/dist/services/codex-app-server-ncp-agent-runtime.service.js.map +1 -1
- package/dist/services/codex-ncp-run-event-emitter.service.js +30 -16
- package/dist/services/codex-ncp-run-event-emitter.service.js.map +1 -1
- package/dist/utils/codex-sdk-ncp-event-mapper.utils.js +15 -15
- package/dist/utils/codex-sdk-ncp-event-mapper.utils.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-app-server-ncp-agent-runtime.service.d.ts","names":[],"sources":["../../src/services/codex-app-server-ncp-agent-runtime.service.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"codex-app-server-ncp-agent-runtime.service.d.ts","names":[],"sources":["../../src/services/codex-app-server-ncp-agent-runtime.service.ts"],"mappings":";;;;cAuCa,6BAAA,YAAyC,eAAA;EAAA,iBAOvB,MAAA;EAAA,iBANZ,YAAA;EAAA,iBACA,eAAA;EAAA,iBACA,sBAAA;EAAA,QACT,aAAA;EAAA,QACA,QAAA;cAEqB,MAAA,EAAQ,mCAAA;EASrC,GAAA,GACE,IAAA,EAAM,6BAAA,EACN,KAAA,EAAO,gBAAA,EACP,OAAA,GAAU,kBAAA,KACT,cAAA,CAAe,gBAAA;EAAA,QA+DV,aAAA;EAAA,QAQA,aAAA;EAAA,QAkBA,oBAAA;EAAA,QAaA,kBAAA;EAAA,QAYA,cAAA;EAAA,QASA,kBAAA;EAAA,QAsFA,mBAAA;EAAA,QAOA,aAAA;EAAA,QA0BA,kBAAA;EAAA,QA0BA,mBAAA;EAAA,QAwDA,sBAAA;EAAA,QAmCA,mBAAA;EAAA,QAqCA,cAAA;EAAA,QAuCA,cAAA;EAAA,QAkBA,sBAAA;AAAA"}
|
|
@@ -4,7 +4,7 @@ import { isAppServerToolLikeItem, readAppServerReasoningText, readAppServerToolA
|
|
|
4
4
|
import { compactObject, normalizeSandbox, splitModelRoute, toAppServerInput } from "../utils/codex-app-server-request.utils.js";
|
|
5
5
|
import { CodexAppServerClient } from "./codex-app-server-client.service.js";
|
|
6
6
|
import { CodexDesktopThreadIndexSyncService } from "./codex-desktop-thread-index-sync.service.js";
|
|
7
|
-
import { NcpEventType } from "@nextclaw/ncp";
|
|
7
|
+
import { NcpEventType, createNcpEndpointEvent } from "@nextclaw/ncp";
|
|
8
8
|
//#region src/services/codex-app-server-ncp-agent-runtime.service.ts
|
|
9
9
|
var CodexAppServerNcpAgentRuntime = class {
|
|
10
10
|
eventEmitter;
|
|
@@ -42,16 +42,25 @@ var CodexAppServerNcpAgentRuntime = class {
|
|
|
42
42
|
if (turnId && this.threadId) client.request("turn/interrupt", {
|
|
43
43
|
threadId: this.threadId,
|
|
44
44
|
turnId
|
|
45
|
-
}, 5e3).catch(() =>
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
else client.dispose();
|
|
45
|
+
}, 5e3).catch(() => void 0);
|
|
46
|
+
client.dispose();
|
|
47
|
+
this.clientPromise = null;
|
|
49
48
|
};
|
|
50
49
|
signal?.addEventListener("abort", abortListener, { once: true });
|
|
51
50
|
try {
|
|
52
51
|
while (true) {
|
|
53
|
-
if (signal?.aborted) throw toAbortError(signal.reason);
|
|
54
52
|
const next = await client.nextNotification();
|
|
53
|
+
if (signal?.aborted) {
|
|
54
|
+
yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({
|
|
55
|
+
type: NcpEventType.MessageAbort,
|
|
56
|
+
payload: {
|
|
57
|
+
sessionId: input.sessionId,
|
|
58
|
+
messageId,
|
|
59
|
+
correlationId: input.correlationId
|
|
60
|
+
}
|
|
61
|
+
}));
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
55
64
|
if (next.done) return;
|
|
56
65
|
if (yield* this.handleNotification({
|
|
57
66
|
notification: next.value,
|
|
@@ -176,46 +185,46 @@ var CodexAppServerNcpAgentRuntime = class {
|
|
|
176
185
|
const itemId = readString(params.params.itemId) ?? "agent-message";
|
|
177
186
|
if (!textState.has(itemId)) {
|
|
178
187
|
textState.add(itemId);
|
|
179
|
-
yield* this.eventEmitter.emitEvent({
|
|
188
|
+
yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({
|
|
180
189
|
type: NcpEventType.MessageTextStart,
|
|
181
190
|
payload: {
|
|
182
191
|
sessionId,
|
|
183
192
|
messageId
|
|
184
193
|
}
|
|
185
|
-
});
|
|
194
|
+
}));
|
|
186
195
|
}
|
|
187
196
|
textDeltaState.add(itemId);
|
|
188
|
-
yield* this.eventEmitter.emitEvent({
|
|
197
|
+
yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({
|
|
189
198
|
type: NcpEventType.MessageTextDelta,
|
|
190
199
|
payload: {
|
|
191
200
|
sessionId,
|
|
192
201
|
messageId,
|
|
193
202
|
delta: readRawString(params.params.delta) ?? ""
|
|
194
203
|
}
|
|
195
|
-
});
|
|
204
|
+
}));
|
|
196
205
|
};
|
|
197
206
|
emitReasoningDelta = async function* (params) {
|
|
198
207
|
const { messageId, reasoningDeltaState, reasoningState, sessionId } = params;
|
|
199
208
|
const itemId = readString(params.params.itemId) ?? "reasoning";
|
|
200
209
|
if (!reasoningState.has(itemId)) {
|
|
201
210
|
reasoningState.add(itemId);
|
|
202
|
-
yield* this.eventEmitter.emitEvent({
|
|
211
|
+
yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({
|
|
203
212
|
type: NcpEventType.MessageReasoningStart,
|
|
204
213
|
payload: {
|
|
205
214
|
sessionId,
|
|
206
215
|
messageId
|
|
207
216
|
}
|
|
208
|
-
});
|
|
217
|
+
}));
|
|
209
218
|
}
|
|
210
219
|
reasoningDeltaState.add(itemId);
|
|
211
|
-
yield* this.eventEmitter.emitEvent({
|
|
220
|
+
yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({
|
|
212
221
|
type: NcpEventType.MessageReasoningDelta,
|
|
213
222
|
payload: {
|
|
214
223
|
sessionId,
|
|
215
224
|
messageId,
|
|
216
225
|
delta: readRawString(params.params.delta) ?? ""
|
|
217
226
|
}
|
|
218
|
-
});
|
|
227
|
+
}));
|
|
219
228
|
};
|
|
220
229
|
handleItemLifecycle = async function* (params) {
|
|
221
230
|
const { eventType, item, messageId, reasoningDeltaState, reasoningState, sessionId, textDeltaState, textState, toolState } = params;
|
|
@@ -258,65 +267,65 @@ var CodexAppServerNcpAgentRuntime = class {
|
|
|
258
267
|
const { eventType, item, itemId, messageId, sessionId, textDeltaState, textState } = params;
|
|
259
268
|
if (!textState.has(itemId)) {
|
|
260
269
|
textState.add(itemId);
|
|
261
|
-
yield* this.eventEmitter.emitEvent({
|
|
270
|
+
yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({
|
|
262
271
|
type: NcpEventType.MessageTextStart,
|
|
263
272
|
payload: {
|
|
264
273
|
sessionId,
|
|
265
274
|
messageId
|
|
266
275
|
}
|
|
267
|
-
});
|
|
276
|
+
}));
|
|
268
277
|
}
|
|
269
278
|
const text = readRawString(item.text);
|
|
270
|
-
if (text && !textDeltaState.has(itemId)) yield* this.eventEmitter.emitEvent({
|
|
279
|
+
if (text && !textDeltaState.has(itemId)) yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({
|
|
271
280
|
type: NcpEventType.MessageTextDelta,
|
|
272
281
|
payload: {
|
|
273
282
|
sessionId,
|
|
274
283
|
messageId,
|
|
275
284
|
delta: text
|
|
276
285
|
}
|
|
277
|
-
});
|
|
278
|
-
if (eventType === "item/completed") yield* this.eventEmitter.emitEvent({
|
|
286
|
+
}));
|
|
287
|
+
if (eventType === "item/completed") yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({
|
|
279
288
|
type: NcpEventType.MessageTextEnd,
|
|
280
289
|
payload: {
|
|
281
290
|
sessionId,
|
|
282
291
|
messageId
|
|
283
292
|
}
|
|
284
|
-
});
|
|
293
|
+
}));
|
|
285
294
|
};
|
|
286
295
|
handleReasoningItem = async function* (params) {
|
|
287
296
|
const { eventType, item, itemId, messageId, reasoningDeltaState, reasoningState, sessionId } = params;
|
|
288
297
|
const reasoningText = readAppServerReasoningText(item);
|
|
289
298
|
if (!reasoningState.has(itemId) && (eventType === "item/started" || reasoningText)) {
|
|
290
299
|
reasoningState.add(itemId);
|
|
291
|
-
yield* this.eventEmitter.emitEvent({
|
|
300
|
+
yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({
|
|
292
301
|
type: NcpEventType.MessageReasoningStart,
|
|
293
302
|
payload: {
|
|
294
303
|
sessionId,
|
|
295
304
|
messageId
|
|
296
305
|
}
|
|
297
|
-
});
|
|
306
|
+
}));
|
|
298
307
|
}
|
|
299
|
-
if (!reasoningDeltaState.has(itemId) && reasoningText) yield* this.eventEmitter.emitEvent({
|
|
308
|
+
if (!reasoningDeltaState.has(itemId) && reasoningText) yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({
|
|
300
309
|
type: NcpEventType.MessageReasoningDelta,
|
|
301
310
|
payload: {
|
|
302
311
|
sessionId,
|
|
303
312
|
messageId,
|
|
304
313
|
delta: reasoningText
|
|
305
314
|
}
|
|
306
|
-
});
|
|
307
|
-
if (eventType === "item/completed" && reasoningState.has(itemId)) yield* this.eventEmitter.emitEvent({
|
|
315
|
+
}));
|
|
316
|
+
if (eventType === "item/completed" && reasoningState.has(itemId)) yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({
|
|
308
317
|
type: NcpEventType.MessageReasoningEnd,
|
|
309
318
|
payload: {
|
|
310
319
|
sessionId,
|
|
311
320
|
messageId
|
|
312
321
|
}
|
|
313
|
-
});
|
|
322
|
+
}));
|
|
314
323
|
};
|
|
315
324
|
handleToolItem = async function* (params) {
|
|
316
325
|
const { eventType, item, itemId, messageId, sessionId, toolState } = params;
|
|
317
326
|
if (!toolState.has(itemId)) {
|
|
318
327
|
toolState.add(itemId);
|
|
319
|
-
yield* this.eventEmitter.emitEvent({
|
|
328
|
+
yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({
|
|
320
329
|
type: NcpEventType.MessageToolCallStart,
|
|
321
330
|
payload: {
|
|
322
331
|
sessionId,
|
|
@@ -324,31 +333,31 @@ var CodexAppServerNcpAgentRuntime = class {
|
|
|
324
333
|
toolCallId: itemId,
|
|
325
334
|
toolName: readAppServerToolName(item)
|
|
326
335
|
}
|
|
327
|
-
});
|
|
328
|
-
yield* this.eventEmitter.emitEvent({
|
|
336
|
+
}));
|
|
337
|
+
yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({
|
|
329
338
|
type: NcpEventType.MessageToolCallArgs,
|
|
330
339
|
payload: {
|
|
331
340
|
sessionId,
|
|
332
341
|
toolCallId: itemId,
|
|
333
342
|
args: stringifyAppServerToolArgs(readAppServerToolArgs(item))
|
|
334
343
|
}
|
|
335
|
-
});
|
|
336
|
-
yield* this.eventEmitter.emitEvent({
|
|
344
|
+
}));
|
|
345
|
+
yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({
|
|
337
346
|
type: NcpEventType.MessageToolCallEnd,
|
|
338
347
|
payload: {
|
|
339
348
|
sessionId,
|
|
340
349
|
toolCallId: itemId
|
|
341
350
|
}
|
|
342
|
-
});
|
|
351
|
+
}));
|
|
343
352
|
}
|
|
344
|
-
if (eventType === "item/completed") yield* this.eventEmitter.emitEvent({
|
|
353
|
+
if (eventType === "item/completed") yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({
|
|
345
354
|
type: NcpEventType.MessageToolCallResult,
|
|
346
355
|
payload: {
|
|
347
356
|
sessionId,
|
|
348
357
|
toolCallId: itemId,
|
|
349
358
|
content: readAppServerToolResult(item)
|
|
350
359
|
}
|
|
351
|
-
});
|
|
360
|
+
}));
|
|
352
361
|
};
|
|
353
362
|
updateThreadId = async (nextThreadId) => {
|
|
354
363
|
const normalizedThreadId = nextThreadId.trim();
|
|
@@ -394,13 +403,6 @@ function readRawString(value) {
|
|
|
394
403
|
function buildThreadModelScope(config) {
|
|
395
404
|
return readString(config.threadOptions?.model) ?? readString(config.model) ?? "__nextclaw_runtime_default__";
|
|
396
405
|
}
|
|
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
406
|
function formatError(error) {
|
|
405
407
|
return error instanceof Error ? error.message : String(error);
|
|
406
408
|
}
|
|
@@ -1 +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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"}
|
|
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 createNcpEndpointEvent,\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(() => undefined);\n }\n client.dispose();\n this.clientPromise = null;\n };\n signal?.addEventListener(\"abort\", abortListener, { once: true });\n try {\n while (true) {\n const next = await client.nextNotification();\n if (signal?.aborted) {\n yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({\n type: NcpEventType.MessageAbort,\n payload: { sessionId: input.sessionId, messageId, correlationId: input.correlationId },\n }));\n return;\n }\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(createNcpEndpointEvent({\n type: NcpEventType.MessageTextStart,\n payload: { sessionId, messageId },\n }));\n }\n textDeltaState.add(itemId);\n yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({\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(createNcpEndpointEvent({\n type: NcpEventType.MessageReasoningStart,\n payload: { sessionId, messageId },\n }));\n }\n reasoningDeltaState.add(itemId);\n yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({\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(createNcpEndpointEvent({\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(createNcpEndpointEvent({\n type: NcpEventType.MessageTextDelta,\n payload: { sessionId, messageId, delta: text },\n }));\n }\n if (eventType === \"item/completed\") {\n yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({\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(createNcpEndpointEvent({\n type: NcpEventType.MessageReasoningStart,\n payload: { sessionId, messageId },\n }));\n }\n if (!reasoningDeltaState.has(itemId) && reasoningText) {\n yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({\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(createNcpEndpointEvent({\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(createNcpEndpointEvent({\n type: NcpEventType.MessageToolCallStart,\n payload: { sessionId, messageId, toolCallId: itemId, toolName: readAppServerToolName(item) },\n }));\n yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({\n type: NcpEventType.MessageToolCallArgs,\n payload: {\n sessionId,\n toolCallId: itemId,\n args: stringifyAppServerToolArgs(readAppServerToolArgs(item)),\n },\n }));\n yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({\n type: NcpEventType.MessageToolCallEnd,\n payload: { sessionId, toolCallId: itemId },\n }));\n }\n if (eventType === \"item/completed\") {\n yield* this.eventEmitter.emitEvent(createNcpEndpointEvent({\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 formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { buildCompletedAssistantMessage } from "../completed-assistant-message.utils.js";
|
|
2
|
-
import { NcpEventType } from "@nextclaw/ncp";
|
|
2
|
+
import { NcpEventType, createNcpEndpointEvent } from "@nextclaw/ncp";
|
|
3
3
|
//#region src/services/codex-ncp-run-event-emitter.service.ts
|
|
4
4
|
var CodexNcpRunEventEmitter = class {
|
|
5
|
+
runStartedAtByRunId = /* @__PURE__ */ new Map();
|
|
5
6
|
constructor(stateManager) {
|
|
6
7
|
this.stateManager = stateManager;
|
|
7
8
|
}
|
|
@@ -10,17 +11,20 @@ var CodexNcpRunEventEmitter = class {
|
|
|
10
11
|
yield event;
|
|
11
12
|
};
|
|
12
13
|
emitRunStarted = async function* (sessionId, messageId, runId) {
|
|
13
|
-
|
|
14
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
15
|
+
this.runStartedAtByRunId.set(runId, startedAt);
|
|
16
|
+
yield* this.emitEvent(createNcpEndpointEvent({
|
|
14
17
|
type: NcpEventType.RunStarted,
|
|
15
18
|
payload: {
|
|
16
19
|
sessionId,
|
|
17
20
|
messageId,
|
|
18
|
-
runId
|
|
21
|
+
runId,
|
|
22
|
+
startedAt
|
|
19
23
|
}
|
|
20
|
-
});
|
|
24
|
+
}, startedAt));
|
|
21
25
|
};
|
|
22
26
|
emitReadyMetadata = async function* (sessionId, messageId, runId) {
|
|
23
|
-
yield* this.emitEvent({
|
|
27
|
+
yield* this.emitEvent(createNcpEndpointEvent({
|
|
24
28
|
type: NcpEventType.RunMetadata,
|
|
25
29
|
payload: {
|
|
26
30
|
sessionId,
|
|
@@ -33,21 +37,26 @@ var CodexNcpRunEventEmitter = class {
|
|
|
33
37
|
supportsAbort: true
|
|
34
38
|
}
|
|
35
39
|
}
|
|
36
|
-
});
|
|
40
|
+
}));
|
|
37
41
|
};
|
|
38
42
|
emitRunError = async function* (sessionId, messageId, runId, error) {
|
|
39
|
-
|
|
43
|
+
const endedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
44
|
+
const startedAt = this.runStartedAtByRunId.get(runId);
|
|
45
|
+
this.runStartedAtByRunId.delete(runId);
|
|
46
|
+
yield* this.emitEvent(createNcpEndpointEvent({
|
|
40
47
|
type: NcpEventType.RunError,
|
|
41
48
|
payload: {
|
|
42
49
|
sessionId,
|
|
43
50
|
messageId,
|
|
44
51
|
runId,
|
|
45
|
-
error
|
|
52
|
+
error,
|
|
53
|
+
startedAt,
|
|
54
|
+
endedAt
|
|
46
55
|
}
|
|
47
|
-
});
|
|
56
|
+
}, endedAt));
|
|
48
57
|
};
|
|
49
58
|
emitRunCompleted = async function* (sessionId, messageId, runId) {
|
|
50
|
-
yield* this.emitEvent({
|
|
59
|
+
yield* this.emitEvent(createNcpEndpointEvent({
|
|
51
60
|
type: NcpEventType.RunMetadata,
|
|
52
61
|
payload: {
|
|
53
62
|
sessionId,
|
|
@@ -58,8 +67,8 @@ var CodexNcpRunEventEmitter = class {
|
|
|
58
67
|
sessionId
|
|
59
68
|
}
|
|
60
69
|
}
|
|
61
|
-
});
|
|
62
|
-
yield* this.emitEvent({
|
|
70
|
+
}));
|
|
71
|
+
yield* this.emitEvent(createNcpEndpointEvent({
|
|
63
72
|
type: NcpEventType.MessageCompleted,
|
|
64
73
|
payload: {
|
|
65
74
|
sessionId,
|
|
@@ -69,15 +78,20 @@ var CodexNcpRunEventEmitter = class {
|
|
|
69
78
|
messageId
|
|
70
79
|
})
|
|
71
80
|
}
|
|
72
|
-
});
|
|
73
|
-
|
|
81
|
+
}));
|
|
82
|
+
const endedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
83
|
+
const startedAt = this.runStartedAtByRunId.get(runId);
|
|
84
|
+
this.runStartedAtByRunId.delete(runId);
|
|
85
|
+
yield* this.emitEvent(createNcpEndpointEvent({
|
|
74
86
|
type: NcpEventType.RunFinished,
|
|
75
87
|
payload: {
|
|
76
88
|
sessionId,
|
|
77
89
|
messageId,
|
|
78
|
-
runId
|
|
90
|
+
runId,
|
|
91
|
+
startedAt,
|
|
92
|
+
endedAt
|
|
79
93
|
}
|
|
80
|
-
});
|
|
94
|
+
}, endedAt));
|
|
81
95
|
};
|
|
82
96
|
};
|
|
83
97
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-ncp-run-event-emitter.service.js","names":[],"sources":["../../src/services/codex-ncp-run-event-emitter.service.ts"],"sourcesContent":["import {\n type NcpAgentConversationStateManager,\n type NcpEndpointEvent,\n NcpEventType,\n} from \"@nextclaw/ncp\";\nimport { buildCompletedAssistantMessage } from \"@/completed-assistant-message.utils.js\";\n\nexport class CodexNcpRunEventEmitter {\n constructor(private readonly stateManager?: NcpAgentConversationStateManager) {}\n\n emitEvent = async function* (\n this: CodexNcpRunEventEmitter,\n event: NcpEndpointEvent,\n ): AsyncGenerator<NcpEndpointEvent> {\n await this.stateManager?.dispatch(event);\n yield event;\n };\n\n emitRunStarted = async function* (\n this: CodexNcpRunEventEmitter,\n sessionId: string,\n messageId: string,\n runId: string,\n ): AsyncGenerator<NcpEndpointEvent> {\n yield* this.emitEvent({\n type: NcpEventType.RunStarted,\n payload: { sessionId, messageId, runId },\n });\n };\n\n emitReadyMetadata = async function* (\n this: CodexNcpRunEventEmitter,\n sessionId: string,\n messageId: string,\n runId: string,\n ): AsyncGenerator<NcpEndpointEvent> {\n yield* this.emitEvent({\n type: NcpEventType.RunMetadata,\n payload: {\n sessionId,\n messageId,\n runId,\n metadata: { kind: \"ready\", runId, sessionId, supportsAbort: true },\n },\n });\n };\n\n emitRunError = async function* (\n this: CodexNcpRunEventEmitter,\n sessionId: string,\n messageId: string,\n runId: string,\n error: string,\n ): AsyncGenerator<NcpEndpointEvent> {\n yield* this.emitEvent({\n type: NcpEventType.RunError,\n payload: { sessionId, messageId, runId, error },\n });\n };\n\n emitRunCompleted = async function* (\n this: CodexNcpRunEventEmitter,\n sessionId: string,\n messageId: string,\n runId: string,\n ): AsyncGenerator<NcpEndpointEvent> {\n yield* this.emitEvent({\n type: NcpEventType.RunMetadata,\n payload: {\n sessionId,\n messageId,\n runId,\n metadata: { kind: \"final\", sessionId },\n },\n });\n yield* this.emitEvent({\n type: NcpEventType.MessageCompleted,\n payload: {\n sessionId,\n message: buildCompletedAssistantMessage({\n stateManager: this.stateManager,\n sessionId,\n messageId,\n }),\n },\n });\n yield* this.emitEvent({\n type: NcpEventType.RunFinished,\n payload: { sessionId, messageId, runId },\n });\n };\n}\n"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"codex-ncp-run-event-emitter.service.js","names":[],"sources":["../../src/services/codex-ncp-run-event-emitter.service.ts"],"sourcesContent":["import {\n createNcpEndpointEvent,\n type NcpAgentConversationStateManager,\n type NcpEndpointEvent,\n NcpEventType,\n} from \"@nextclaw/ncp\";\nimport { buildCompletedAssistantMessage } from \"@/completed-assistant-message.utils.js\";\n\nexport class CodexNcpRunEventEmitter {\n private readonly runStartedAtByRunId = new Map<string, string>();\n\n constructor(private readonly stateManager?: NcpAgentConversationStateManager) {}\n\n emitEvent = async function* (\n this: CodexNcpRunEventEmitter,\n event: NcpEndpointEvent,\n ): AsyncGenerator<NcpEndpointEvent> {\n await this.stateManager?.dispatch(event);\n yield event;\n };\n\n emitRunStarted = async function* (\n this: CodexNcpRunEventEmitter,\n sessionId: string,\n messageId: string,\n runId: string,\n ): AsyncGenerator<NcpEndpointEvent> {\n const startedAt = new Date().toISOString();\n this.runStartedAtByRunId.set(runId, startedAt);\n yield* this.emitEvent(createNcpEndpointEvent({\n type: NcpEventType.RunStarted,\n payload: { sessionId, messageId, runId, startedAt },\n }, startedAt));\n };\n\n emitReadyMetadata = async function* (\n this: CodexNcpRunEventEmitter,\n sessionId: string,\n messageId: string,\n runId: string,\n ): AsyncGenerator<NcpEndpointEvent> {\n yield* this.emitEvent(createNcpEndpointEvent({\n type: NcpEventType.RunMetadata,\n payload: {\n sessionId,\n messageId,\n runId,\n metadata: { kind: \"ready\", runId, sessionId, supportsAbort: true },\n },\n }));\n };\n\n emitRunError = async function* (\n this: CodexNcpRunEventEmitter,\n sessionId: string,\n messageId: string,\n runId: string,\n error: string,\n ): AsyncGenerator<NcpEndpointEvent> {\n const endedAt = new Date().toISOString();\n const startedAt = this.runStartedAtByRunId.get(runId);\n this.runStartedAtByRunId.delete(runId);\n yield* this.emitEvent(createNcpEndpointEvent({\n type: NcpEventType.RunError,\n payload: { sessionId, messageId, runId, error, startedAt, endedAt },\n }, endedAt));\n };\n\n emitRunCompleted = async function* (\n this: CodexNcpRunEventEmitter,\n sessionId: string,\n messageId: string,\n runId: string,\n ): AsyncGenerator<NcpEndpointEvent> {\n yield* this.emitEvent(createNcpEndpointEvent({\n type: NcpEventType.RunMetadata,\n payload: {\n sessionId,\n messageId,\n runId,\n metadata: { kind: \"final\", sessionId },\n },\n }));\n yield* this.emitEvent(createNcpEndpointEvent({\n type: NcpEventType.MessageCompleted,\n payload: {\n sessionId,\n message: buildCompletedAssistantMessage({\n stateManager: this.stateManager,\n sessionId,\n messageId,\n }),\n },\n }));\n const endedAt = new Date().toISOString();\n const startedAt = this.runStartedAtByRunId.get(runId);\n this.runStartedAtByRunId.delete(runId);\n yield* this.emitEvent(createNcpEndpointEvent({\n type: NcpEventType.RunFinished,\n payload: { sessionId, messageId, runId, startedAt, endedAt },\n }, endedAt));\n };\n}\n"],"mappings":";;;AAQA,IAAa,0BAAb,MAAqC;CACnC,sCAAuC,IAAI,KAAqB;CAEhE,YAAY,cAAkE;AAAjD,OAAA,eAAA;;CAE7B,YAAY,iBAEV,OACkC;AAClC,QAAM,KAAK,cAAc,SAAS,MAAM;AACxC,QAAM;;CAGR,iBAAiB,iBAEf,WACA,WACA,OACkC;EAClC,MAAM,6BAAY,IAAI,MAAM,EAAC,aAAa;AAC1C,OAAK,oBAAoB,IAAI,OAAO,UAAU;AAC9C,SAAO,KAAK,UAAU,uBAAuB;GAC3C,MAAM,aAAa;GACnB,SAAS;IAAE;IAAW;IAAW;IAAO;IAAW;GACpD,EAAE,UAAU,CAAC;;CAGhB,oBAAoB,iBAElB,WACA,WACA,OACkC;AAClC,SAAO,KAAK,UAAU,uBAAuB;GAC3C,MAAM,aAAa;GACnB,SAAS;IACP;IACA;IACA;IACA,UAAU;KAAE,MAAM;KAAS;KAAO;KAAW,eAAe;KAAM;IACnE;GACF,CAAC,CAAC;;CAGL,eAAe,iBAEb,WACA,WACA,OACA,OACkC;EAClC,MAAM,2BAAU,IAAI,MAAM,EAAC,aAAa;EACxC,MAAM,YAAY,KAAK,oBAAoB,IAAI,MAAM;AACrD,OAAK,oBAAoB,OAAO,MAAM;AACtC,SAAO,KAAK,UAAU,uBAAuB;GAC3C,MAAM,aAAa;GACnB,SAAS;IAAE;IAAW;IAAW;IAAO;IAAO;IAAW;IAAS;GACpE,EAAE,QAAQ,CAAC;;CAGd,mBAAmB,iBAEjB,WACA,WACA,OACkC;AAClC,SAAO,KAAK,UAAU,uBAAuB;GAC3C,MAAM,aAAa;GACnB,SAAS;IACP;IACA;IACA;IACA,UAAU;KAAE,MAAM;KAAS;KAAW;IACvC;GACF,CAAC,CAAC;AACH,SAAO,KAAK,UAAU,uBAAuB;GAC3C,MAAM,aAAa;GACnB,SAAS;IACP;IACA,SAAS,+BAA+B;KACtC,cAAc,KAAK;KACnB;KACA;KACD,CAAC;IACH;GACF,CAAC,CAAC;EACH,MAAM,2BAAU,IAAI,MAAM,EAAC,aAAa;EACxC,MAAM,YAAY,KAAK,oBAAoB,IAAI,MAAM;AACrD,OAAK,oBAAoB,OAAO,MAAM;AACtC,SAAO,KAAK,UAAU,uBAAuB;GAC3C,MAAM,aAAa;GACnB,SAAS;IAAE;IAAW;IAAW;IAAO;IAAW;IAAS;GAC7D,EAAE,QAAQ,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NcpEventType } from "@nextclaw/ncp";
|
|
1
|
+
import { NcpEventType, createNcpEndpointEvent } from "@nextclaw/ncp";
|
|
2
2
|
//#region src/utils/codex-sdk-ncp-event-mapper.utils.ts
|
|
3
3
|
const TEXT_DELTA_CHUNK_SIZE = 32;
|
|
4
4
|
const TOOL_LIKE_ITEM_TYPES = new Set([
|
|
@@ -81,35 +81,35 @@ function* mapTextSnapshotDelta(params) {
|
|
|
81
81
|
text: "",
|
|
82
82
|
started: false
|
|
83
83
|
};
|
|
84
|
-
if (!previous.started) yield {
|
|
84
|
+
if (!previous.started) yield createNcpEndpointEvent({
|
|
85
85
|
type: params.startType,
|
|
86
86
|
payload: {
|
|
87
87
|
sessionId,
|
|
88
88
|
messageId
|
|
89
89
|
}
|
|
90
|
-
};
|
|
90
|
+
});
|
|
91
91
|
if (currentText.length > previous.text.length) {
|
|
92
92
|
const delta = currentText.slice(previous.text.length);
|
|
93
|
-
for (const chunk of splitTextDelta(delta)) yield {
|
|
93
|
+
for (const chunk of splitTextDelta(delta)) yield createNcpEndpointEvent({
|
|
94
94
|
type: params.deltaType,
|
|
95
95
|
payload: {
|
|
96
96
|
sessionId,
|
|
97
97
|
messageId,
|
|
98
98
|
delta: chunk
|
|
99
99
|
}
|
|
100
|
-
};
|
|
100
|
+
});
|
|
101
101
|
}
|
|
102
102
|
itemTextById.set(itemId, {
|
|
103
103
|
text: currentText,
|
|
104
104
|
started: true
|
|
105
105
|
});
|
|
106
|
-
if (params.eventType === "item.completed") yield {
|
|
106
|
+
if (params.eventType === "item.completed") yield createNcpEndpointEvent({
|
|
107
107
|
type: params.endType,
|
|
108
108
|
payload: {
|
|
109
109
|
sessionId,
|
|
110
110
|
messageId
|
|
111
111
|
}
|
|
112
|
-
};
|
|
112
|
+
});
|
|
113
113
|
}
|
|
114
114
|
async function* mapCodexItemEvent(params) {
|
|
115
115
|
const { sessionId, messageId, event, itemTextById, toolStateById } = params;
|
|
@@ -137,7 +137,7 @@ async function* mapCodexItemEvent(params) {
|
|
|
137
137
|
};
|
|
138
138
|
const descriptor = buildToolDescriptor(item);
|
|
139
139
|
if (!previous.started) {
|
|
140
|
-
yield {
|
|
140
|
+
yield createNcpEndpointEvent({
|
|
141
141
|
type: NcpEventType.MessageToolCallStart,
|
|
142
142
|
payload: {
|
|
143
143
|
sessionId,
|
|
@@ -145,38 +145,38 @@ async function* mapCodexItemEvent(params) {
|
|
|
145
145
|
toolCallId: item.id,
|
|
146
146
|
toolName: descriptor.toolName
|
|
147
147
|
}
|
|
148
|
-
};
|
|
148
|
+
});
|
|
149
149
|
previous.started = true;
|
|
150
150
|
}
|
|
151
151
|
if (!previous.argsEmitted) {
|
|
152
|
-
yield {
|
|
152
|
+
yield createNcpEndpointEvent({
|
|
153
153
|
type: NcpEventType.MessageToolCallArgs,
|
|
154
154
|
payload: {
|
|
155
155
|
sessionId,
|
|
156
156
|
toolCallId: item.id,
|
|
157
157
|
args: stringifyToolArgs(descriptor.args)
|
|
158
158
|
}
|
|
159
|
-
};
|
|
159
|
+
});
|
|
160
160
|
previous.argsEmitted = true;
|
|
161
161
|
}
|
|
162
162
|
if (!previous.ended) {
|
|
163
|
-
yield {
|
|
163
|
+
yield createNcpEndpointEvent({
|
|
164
164
|
type: NcpEventType.MessageToolCallEnd,
|
|
165
165
|
payload: {
|
|
166
166
|
sessionId,
|
|
167
167
|
toolCallId: item.id
|
|
168
168
|
}
|
|
169
|
-
};
|
|
169
|
+
});
|
|
170
170
|
previous.ended = true;
|
|
171
171
|
}
|
|
172
|
-
if (event.type === "item.updated" || event.type === "item.completed") yield {
|
|
172
|
+
if (event.type === "item.updated" || event.type === "item.completed") yield createNcpEndpointEvent({
|
|
173
173
|
type: NcpEventType.MessageToolCallResult,
|
|
174
174
|
payload: {
|
|
175
175
|
sessionId,
|
|
176
176
|
toolCallId: item.id,
|
|
177
177
|
content: buildToolResult(item)
|
|
178
178
|
}
|
|
179
|
-
};
|
|
179
|
+
});
|
|
180
180
|
toolStateById.set(item.id, previous);
|
|
181
181
|
}
|
|
182
182
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-sdk-ncp-event-mapper.utils.js","names":[],"sources":["../../src/utils/codex-sdk-ncp-event-mapper.utils.ts"],"sourcesContent":["import type { ThreadEvent, ThreadItem } from \"@openai/codex-sdk\";\nimport { type NcpEndpointEvent, NcpEventType } from \"@nextclaw/ncp\";\n\ntype ToolLikeItem = Extract<\n ThreadItem,\n { type: \"mcp_tool_call\" | \"command_execution\" | \"web_search\" | \"file_change\" | \"todo_list\" }\n>;\n\nexport type ItemTextSnapshot = {\n text: string;\n started: boolean;\n};\n\nexport type ToolSnapshot = {\n started: boolean;\n argsEmitted: boolean;\n ended: boolean;\n};\n\nconst TEXT_DELTA_CHUNK_SIZE = 32;\nconst TOOL_LIKE_ITEM_TYPES = new Set<ThreadItem[\"type\"]>([\n \"mcp_tool_call\",\n \"command_execution\",\n \"web_search\",\n \"file_change\",\n \"todo_list\",\n]);\n\nfunction buildToolDescriptor(item: ToolLikeItem): { toolName: string; args: unknown } {\n switch (item.type) {\n case \"mcp_tool_call\":\n return {\n toolName: item.server ? `mcp:${item.server}.${item.tool}` : `mcp:${item.tool}`,\n args: item.arguments,\n };\n case \"command_execution\":\n return { toolName: \"command_execution\", args: { command: item.command } };\n case \"web_search\":\n return { toolName: \"web_search\", args: { query: item.query } };\n case \"file_change\":\n return { toolName: \"file_change\", args: { changes: item.changes } };\n case \"todo_list\":\n return { toolName: \"todo_list\", args: { items: item.items } };\n }\n}\n\nfunction buildToolResult(item: ToolLikeItem): unknown {\n switch (item.type) {\n case \"mcp_tool_call\":\n return item.status === \"failed\"\n ? { ok: false, error: item.error ?? { message: \"MCP tool call failed.\" } }\n : {\n ok: item.status === \"completed\",\n status: item.status,\n result: item.result ?? null,\n };\n case \"command_execution\":\n return {\n status: item.status,\n command: item.command,\n aggregated_output: item.aggregated_output,\n ...(typeof item.exit_code === \"number\" ? { exit_code: item.exit_code } : {}),\n };\n case \"web_search\":\n return { status: \"completed\", query: item.query };\n case \"file_change\":\n return { status: item.status, changes: item.changes };\n case \"todo_list\":\n return { status: \"completed\", items: item.items };\n }\n}\n\nfunction stringifyToolArgs(args: unknown): string {\n try {\n return JSON.stringify(args ?? {});\n } catch {\n return JSON.stringify({\n __serialization_error__: \"tool arguments are not JSON serializable\",\n });\n }\n}\n\nfunction isToolLikeItem(item: ThreadItem): item is ToolLikeItem {\n return TOOL_LIKE_ITEM_TYPES.has(item.type);\n}\n\nfunction splitTextDelta(delta: string): string[] {\n return Array.from(\n { length: Math.ceil(delta.length / TEXT_DELTA_CHUNK_SIZE) },\n (_, index) =>\n delta.slice(index * TEXT_DELTA_CHUNK_SIZE, (index + 1) * TEXT_DELTA_CHUNK_SIZE),\n );\n}\n\nfunction* mapTextSnapshotDelta(params: {\n currentText: string;\n deltaType: typeof NcpEventType.MessageTextDelta | typeof NcpEventType.MessageReasoningDelta;\n endType: typeof NcpEventType.MessageTextEnd | typeof NcpEventType.MessageReasoningEnd;\n eventType: \"item.started\" | \"item.updated\" | \"item.completed\";\n itemId: string;\n itemTextById: Map<string, ItemTextSnapshot>;\n messageId: string;\n sessionId: string;\n startType: typeof NcpEventType.MessageTextStart | typeof NcpEventType.MessageReasoningStart;\n}): Generator<NcpEndpointEvent> {\n const { currentText, itemId, itemTextById, messageId, sessionId } = params;\n const previous = itemTextById.get(itemId) ?? { text: \"\", started: false };\n if (!previous.started) {\n yield {\n type: params.startType,\n payload: { sessionId, messageId },\n };\n }\n if (currentText.length > previous.text.length) {\n const delta = currentText.slice(previous.text.length);\n for (const chunk of splitTextDelta(delta)) {\n yield {\n type: params.deltaType,\n payload: { sessionId, messageId, delta: chunk },\n };\n }\n }\n itemTextById.set(itemId, { text: currentText, started: true });\n if (params.eventType === \"item.completed\") {\n yield {\n type: params.endType,\n payload: { sessionId, messageId },\n };\n }\n}\n\nexport async function* mapCodexItemEvent(params: {\n sessionId: string;\n messageId: string;\n event: Extract<ThreadEvent, { type: \"item.started\" | \"item.updated\" | \"item.completed\" }>;\n itemTextById: Map<string, ItemTextSnapshot>;\n toolStateById: Map<string, ToolSnapshot>;\n}): AsyncGenerator<NcpEndpointEvent> {\n const { sessionId, messageId, event, itemTextById, toolStateById } = params;\n const { item } = event;\n\n if (item.type === \"agent_message\" || item.type === \"reasoning\") {\n const isReasoning = item.type === \"reasoning\";\n yield* mapTextSnapshotDelta({\n currentText: item.text ?? \"\",\n deltaType: isReasoning\n ? NcpEventType.MessageReasoningDelta\n : NcpEventType.MessageTextDelta,\n endType: isReasoning ? NcpEventType.MessageReasoningEnd : NcpEventType.MessageTextEnd,\n eventType: event.type,\n itemId: item.id,\n itemTextById,\n messageId,\n sessionId,\n startType: isReasoning\n ? NcpEventType.MessageReasoningStart\n : NcpEventType.MessageTextStart,\n });\n return;\n }\n\n if (!isToolLikeItem(item)) {\n return;\n }\n\n const previous = toolStateById.get(item.id) ?? {\n started: false,\n argsEmitted: false,\n ended: false,\n };\n const descriptor = buildToolDescriptor(item);\n\n if (!previous.started) {\n yield {\n type: NcpEventType.MessageToolCallStart,\n payload: {\n sessionId,\n messageId,\n toolCallId: item.id,\n toolName: descriptor.toolName,\n },\n };\n previous.started = true;\n }\n\n if (!previous.argsEmitted) {\n yield {\n type: NcpEventType.MessageToolCallArgs,\n payload: {\n sessionId,\n toolCallId: item.id,\n args: stringifyToolArgs(descriptor.args),\n },\n };\n previous.argsEmitted = true;\n }\n\n if (!previous.ended) {\n yield {\n type: NcpEventType.MessageToolCallEnd,\n payload: {\n sessionId,\n toolCallId: item.id,\n },\n };\n previous.ended = true;\n }\n\n if (event.type === \"item.updated\" || event.type === \"item.completed\") {\n yield {\n type: NcpEventType.MessageToolCallResult,\n payload: {\n sessionId,\n toolCallId: item.id,\n content: buildToolResult(item),\n },\n };\n }\n\n toolStateById.set(item.id, previous);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"codex-sdk-ncp-event-mapper.utils.js","names":[],"sources":["../../src/utils/codex-sdk-ncp-event-mapper.utils.ts"],"sourcesContent":["import type { ThreadEvent, ThreadItem } from \"@openai/codex-sdk\";\nimport { createNcpEndpointEvent, type NcpEndpointEvent, NcpEventType } from \"@nextclaw/ncp\";\n\ntype ToolLikeItem = Extract<\n ThreadItem,\n { type: \"mcp_tool_call\" | \"command_execution\" | \"web_search\" | \"file_change\" | \"todo_list\" }\n>;\n\nexport type ItemTextSnapshot = {\n text: string;\n started: boolean;\n};\n\nexport type ToolSnapshot = {\n started: boolean;\n argsEmitted: boolean;\n ended: boolean;\n};\n\nconst TEXT_DELTA_CHUNK_SIZE = 32;\nconst TOOL_LIKE_ITEM_TYPES = new Set<ThreadItem[\"type\"]>([\n \"mcp_tool_call\",\n \"command_execution\",\n \"web_search\",\n \"file_change\",\n \"todo_list\",\n]);\n\nfunction buildToolDescriptor(item: ToolLikeItem): { toolName: string; args: unknown } {\n switch (item.type) {\n case \"mcp_tool_call\":\n return {\n toolName: item.server ? `mcp:${item.server}.${item.tool}` : `mcp:${item.tool}`,\n args: item.arguments,\n };\n case \"command_execution\":\n return { toolName: \"command_execution\", args: { command: item.command } };\n case \"web_search\":\n return { toolName: \"web_search\", args: { query: item.query } };\n case \"file_change\":\n return { toolName: \"file_change\", args: { changes: item.changes } };\n case \"todo_list\":\n return { toolName: \"todo_list\", args: { items: item.items } };\n }\n}\n\nfunction buildToolResult(item: ToolLikeItem): unknown {\n switch (item.type) {\n case \"mcp_tool_call\":\n return item.status === \"failed\"\n ? { ok: false, error: item.error ?? { message: \"MCP tool call failed.\" } }\n : {\n ok: item.status === \"completed\",\n status: item.status,\n result: item.result ?? null,\n };\n case \"command_execution\":\n return {\n status: item.status,\n command: item.command,\n aggregated_output: item.aggregated_output,\n ...(typeof item.exit_code === \"number\" ? { exit_code: item.exit_code } : {}),\n };\n case \"web_search\":\n return { status: \"completed\", query: item.query };\n case \"file_change\":\n return { status: item.status, changes: item.changes };\n case \"todo_list\":\n return { status: \"completed\", items: item.items };\n }\n}\n\nfunction stringifyToolArgs(args: unknown): string {\n try {\n return JSON.stringify(args ?? {});\n } catch {\n return JSON.stringify({\n __serialization_error__: \"tool arguments are not JSON serializable\",\n });\n }\n}\n\nfunction isToolLikeItem(item: ThreadItem): item is ToolLikeItem {\n return TOOL_LIKE_ITEM_TYPES.has(item.type);\n}\n\nfunction splitTextDelta(delta: string): string[] {\n return Array.from(\n { length: Math.ceil(delta.length / TEXT_DELTA_CHUNK_SIZE) },\n (_, index) =>\n delta.slice(index * TEXT_DELTA_CHUNK_SIZE, (index + 1) * TEXT_DELTA_CHUNK_SIZE),\n );\n}\n\nfunction* mapTextSnapshotDelta(params: {\n currentText: string;\n deltaType: typeof NcpEventType.MessageTextDelta | typeof NcpEventType.MessageReasoningDelta;\n endType: typeof NcpEventType.MessageTextEnd | typeof NcpEventType.MessageReasoningEnd;\n eventType: \"item.started\" | \"item.updated\" | \"item.completed\";\n itemId: string;\n itemTextById: Map<string, ItemTextSnapshot>;\n messageId: string;\n sessionId: string;\n startType: typeof NcpEventType.MessageTextStart | typeof NcpEventType.MessageReasoningStart;\n}): Generator<NcpEndpointEvent> {\n const { currentText, itemId, itemTextById, messageId, sessionId } = params;\n const previous = itemTextById.get(itemId) ?? { text: \"\", started: false };\n if (!previous.started) {\n yield createNcpEndpointEvent({\n type: params.startType,\n payload: { sessionId, messageId },\n });\n }\n if (currentText.length > previous.text.length) {\n const delta = currentText.slice(previous.text.length);\n for (const chunk of splitTextDelta(delta)) {\n yield createNcpEndpointEvent({\n type: params.deltaType,\n payload: { sessionId, messageId, delta: chunk },\n });\n }\n }\n itemTextById.set(itemId, { text: currentText, started: true });\n if (params.eventType === \"item.completed\") {\n yield createNcpEndpointEvent({\n type: params.endType,\n payload: { sessionId, messageId },\n });\n }\n}\n\nexport async function* mapCodexItemEvent(params: {\n sessionId: string;\n messageId: string;\n event: Extract<ThreadEvent, { type: \"item.started\" | \"item.updated\" | \"item.completed\" }>;\n itemTextById: Map<string, ItemTextSnapshot>;\n toolStateById: Map<string, ToolSnapshot>;\n}): AsyncGenerator<NcpEndpointEvent> {\n const { sessionId, messageId, event, itemTextById, toolStateById } = params;\n const { item } = event;\n\n if (item.type === \"agent_message\" || item.type === \"reasoning\") {\n const isReasoning = item.type === \"reasoning\";\n yield* mapTextSnapshotDelta({\n currentText: item.text ?? \"\",\n deltaType: isReasoning\n ? NcpEventType.MessageReasoningDelta\n : NcpEventType.MessageTextDelta,\n endType: isReasoning ? NcpEventType.MessageReasoningEnd : NcpEventType.MessageTextEnd,\n eventType: event.type,\n itemId: item.id,\n itemTextById,\n messageId,\n sessionId,\n startType: isReasoning\n ? NcpEventType.MessageReasoningStart\n : NcpEventType.MessageTextStart,\n });\n return;\n }\n\n if (!isToolLikeItem(item)) {\n return;\n }\n\n const previous = toolStateById.get(item.id) ?? {\n started: false,\n argsEmitted: false,\n ended: false,\n };\n const descriptor = buildToolDescriptor(item);\n\n if (!previous.started) {\n yield createNcpEndpointEvent({\n type: NcpEventType.MessageToolCallStart,\n payload: {\n sessionId,\n messageId,\n toolCallId: item.id,\n toolName: descriptor.toolName,\n },\n });\n previous.started = true;\n }\n\n if (!previous.argsEmitted) {\n yield createNcpEndpointEvent({\n type: NcpEventType.MessageToolCallArgs,\n payload: {\n sessionId,\n toolCallId: item.id,\n args: stringifyToolArgs(descriptor.args),\n },\n });\n previous.argsEmitted = true;\n }\n\n if (!previous.ended) {\n yield createNcpEndpointEvent({\n type: NcpEventType.MessageToolCallEnd,\n payload: {\n sessionId,\n toolCallId: item.id,\n },\n });\n previous.ended = true;\n }\n\n if (event.type === \"item.updated\" || event.type === \"item.completed\") {\n yield createNcpEndpointEvent({\n type: NcpEventType.MessageToolCallResult,\n payload: {\n sessionId,\n toolCallId: item.id,\n content: buildToolResult(item),\n },\n });\n }\n\n toolStateById.set(item.id, previous);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/nextclaw-ncp-runtime-codex-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Optional NCP runtime adapter backed by OpenAI Codex SDK.",
|
|
6
6
|
"type": "module",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@openai/codex-sdk": "^0.139.0",
|
|
21
|
-
"@nextclaw/ncp": "0.
|
|
21
|
+
"@nextclaw/ncp": "0.7.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/node": "^20.17.6",
|