@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.
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -5
- package/dist/index.js.map +1 -1
- package/dist/services/codex-app-server-client.service.js +242 -0
- package/dist/services/codex-app-server-client.service.js.map +1 -0
- package/dist/services/codex-app-server-ncp-agent-runtime.service.d.ts +32 -0
- package/dist/services/codex-app-server-ncp-agent-runtime.service.d.ts.map +1 -0
- package/dist/services/codex-app-server-ncp-agent-runtime.service.js +410 -0
- package/dist/services/codex-app-server-ncp-agent-runtime.service.js.map +1 -0
- package/dist/services/codex-desktop-thread-index-sync.service.d.ts +47 -0
- package/dist/services/codex-desktop-thread-index-sync.service.d.ts.map +1 -0
- package/dist/services/codex-desktop-thread-index-sync.service.js +256 -0
- package/dist/services/codex-desktop-thread-index-sync.service.js.map +1 -0
- package/dist/types/codex-app-server-runtime.types.d.ts +26 -0
- package/dist/types/codex-app-server-runtime.types.d.ts.map +1 -0
- package/dist/utils/codex-app-server-item-mapper.utils.js +67 -0
- package/dist/utils/codex-app-server-item-mapper.utils.js.map +1 -0
- package/dist/utils/codex-app-server-request.utils.js +49 -0
- package/dist/utils/codex-app-server-request.utils.js.map +1 -0
- package/dist/{codex-openai-responses-bridge-assistant-output.utils.js → utils/codex-openai-responses-bridge-assistant-output.utils.js} +2 -2
- package/dist/utils/codex-openai-responses-bridge-assistant-output.utils.js.map +1 -0
- package/dist/utils/codex-openai-responses-bridge-request.utils.js.map +1 -1
- package/dist/utils/codex-openai-responses-bridge-stream.utils.js +1 -1
- package/dist/utils/codex-openai-responses-bridge-stream.utils.js.map +1 -1
- package/dist/utils/codex-openai-responses-bridge.utils.js.map +1 -1
- package/dist/utils/codex-openai-responses-stream-writer.utils.d.ts.map +1 -1
- package/dist/utils/codex-openai-responses-stream-writer.utils.js +2 -9
- package/dist/utils/codex-openai-responses-stream-writer.utils.js.map +1 -1
- package/dist/utils/codex-openai-sse-chunks.utils.js.map +1 -1
- package/dist/utils/codex-rollout-thread-summary.utils.js +121 -0
- package/dist/utils/codex-rollout-thread-summary.utils.js.map +1 -0
- package/package.json +4 -3
- package/dist/codex-openai-responses-bridge-assistant-output.utils.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-openai-responses-bridge.utils.js","names":[],"sources":["../../src/utils/codex-openai-responses-bridge.utils.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport {\n buildOpenAiCompatibleUpstreamRequest,\n callOpenAiCompatibleUpstream,\n} from \"./codex-openai-responses-bridge-request.utils.js\";\nimport {\n buildBridgeResponsePayload,\n writeStreamError,\n} from \"./codex-openai-responses-bridge-stream.utils.js\";\nimport { writeResponsesUpstreamStream } from \"./codex-openai-responses-stream-writer.utils.js\";\nimport {\n readBoolean,\n readRecord,\n type BridgeEntry,\n type CodexOpenAiResponsesBridgeConfig,\n type CodexOpenAiResponsesBridgeResult,\n} from \"
|
|
1
|
+
{"version":3,"file":"codex-openai-responses-bridge.utils.js","names":[],"sources":["../../src/utils/codex-openai-responses-bridge.utils.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport {\n buildOpenAiCompatibleUpstreamRequest,\n callOpenAiCompatibleUpstream,\n} from \"./codex-openai-responses-bridge-request.utils.js\";\nimport {\n buildBridgeResponsePayload,\n writeStreamError,\n} from \"./codex-openai-responses-bridge-stream.utils.js\";\nimport { writeResponsesUpstreamStream } from \"./codex-openai-responses-stream-writer.utils.js\";\nimport {\n readBoolean,\n readRecord,\n type BridgeEntry,\n type CodexOpenAiResponsesBridgeConfig,\n type CodexOpenAiResponsesBridgeResult,\n} from \"@/codex-openai-responses-bridge-shared.utils.js\";\nimport type { CodexOpenAiResponsesOutputObserver } from \"./codex-openai-responses-stream-writer.utils.js\";\n\nconst bridgeCache = new Map<string, BridgeEntry>();\n\nexport type CodexOpenAiResponsesBridgeRuntimeConfig = CodexOpenAiResponsesBridgeConfig & {\n outputObserver?: CodexOpenAiResponsesOutputObserver;\n};\n\nfunction toBridgeCacheKey(config: CodexOpenAiResponsesBridgeConfig): string {\n return JSON.stringify({\n upstreamApiBase: config.upstreamApiBase,\n upstreamApiKey: config.upstreamApiKey ?? \"\",\n upstreamExtraHeaders: config.upstreamExtraHeaders ?? {},\n defaultModel: config.defaultModel ?? \"\",\n modelPrefixes: (config.modelPrefixes ?? []).map((prefix) => prefix.trim().toLowerCase()),\n upstreamReasoningSplit: config.upstreamReasoningSplit === true,\n });\n}\n\nasync function readJsonBody(request: IncomingMessage): Promise<Record<string, unknown> | null> {\n const chunks: Buffer[] = [];\n for await (const chunk of request) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n const rawText = Buffer.concat(chunks).toString(\"utf8\").trim();\n if (!rawText) {\n return {};\n }\n try {\n return readRecord(JSON.parse(rawText)) ?? null;\n } catch {\n return null;\n }\n}\n\nasync function handleResponsesRequest(\n request: IncomingMessage,\n response: ServerResponse,\n config: CodexOpenAiResponsesBridgeRuntimeConfig,\n): Promise<void> {\n await new CodexResponsesBridgeRequestHandler(request, response, config).handle();\n}\n\nclass JsonResponseWriter {\n constructor(private readonly response: ServerResponse) {}\n\n write = (statusCode: number, body: Record<string, unknown>): void => {\n this.response.statusCode = statusCode;\n this.response.setHeader(\"content-type\", \"application/json\");\n this.response.end(JSON.stringify(body));\n };\n}\n\nclass CodexResponsesBridgeRequestHandler {\n private readonly jsonWriter: JsonResponseWriter;\n\n constructor(\n private readonly request: IncomingMessage,\n private readonly response: ServerResponse,\n private readonly config: CodexOpenAiResponsesBridgeRuntimeConfig,\n ) {\n this.jsonWriter = new JsonResponseWriter(response);\n }\n\n handle = async (): Promise<void> => {\n const body = await readJsonBody(this.request);\n if (!body) {\n this.writeErrorJson(400, \"Invalid JSON payload.\");\n return;\n }\n\n try {\n if (readBoolean(body.stream) !== false) {\n await this.writeStreamingResponse(body);\n return;\n }\n await this.writeJsonResponse(body);\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"Codex OpenAI bridge request failed.\";\n if (readBoolean(body.stream) !== false) {\n writeStreamError(this.response, message);\n return;\n }\n this.writeErrorJson(400, message);\n }\n };\n\n private writeStreamingResponse = async (body: Record<string, unknown>): Promise<void> => {\n const responseId = randomUUID();\n const upstream = buildOpenAiCompatibleUpstreamRequest({\n config: this.config,\n body,\n stream: true,\n });\n const upstreamResponse = await fetch(upstream.request.url, upstream.request.init);\n if (!upstreamResponse.ok) {\n throw new Error((await upstreamResponse.text()).slice(0, 240));\n }\n await writeResponsesUpstreamStream({\n response: this.response,\n responseId,\n model: upstream.model,\n outputObserver: this.config.outputObserver,\n upstreamResponse,\n });\n };\n\n private writeJsonResponse = async (body: Record<string, unknown>): Promise<void> => {\n const responseId = randomUUID();\n const upstream = await callOpenAiCompatibleUpstream({\n config: this.config,\n body,\n });\n const { responseResource } = buildBridgeResponsePayload({\n responseId,\n model: upstream.model,\n response: upstream.response,\n });\n\n this.jsonWriter.write(200, responseResource);\n };\n\n private writeErrorJson = (statusCode: number, message: string): void => {\n this.jsonWriter.write(statusCode, {\n error: {\n message,\n },\n });\n };\n}\n\nasync function createCodexOpenAiResponsesBridge(\n config: CodexOpenAiResponsesBridgeRuntimeConfig,\n): Promise<CodexOpenAiResponsesBridgeResult> {\n const server = createServer((request, response) => {\n const pathname = request.url\n ? new URL(request.url, \"http://127.0.0.1\").pathname\n : \"/\";\n if (\n request.method === \"POST\" &&\n (pathname === \"/responses\" || pathname === \"/v1/responses\")\n ) {\n void handleResponsesRequest(request, response, config);\n return;\n }\n\n new JsonResponseWriter(response).write(404, {\n error: {\n message: `Unsupported Codex bridge path: ${pathname}`,\n },\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, \"127.0.0.1\", () => resolve());\n });\n\n const address = server.address();\n if (!address || typeof address === \"string\") {\n throw new Error(\"Codex bridge failed to bind a loopback port.\");\n }\n\n return {\n baseUrl: `http://127.0.0.1:${address.port}`,\n };\n}\n\nexport async function ensureCodexOpenAiResponsesBridge(\n config: CodexOpenAiResponsesBridgeRuntimeConfig,\n): Promise<CodexOpenAiResponsesBridgeResult> {\n if (config.outputObserver) {\n return await createCodexOpenAiResponsesBridge(config);\n }\n\n const key = toBridgeCacheKey(config);\n const existing = bridgeCache.get(key);\n if (existing) {\n return await existing.promise;\n }\n\n const promise = createCodexOpenAiResponsesBridge(config);\n bridgeCache.set(key, { promise });\n try {\n return await promise;\n } catch (error) {\n bridgeCache.delete(key);\n throw error;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-openai-responses-stream-writer.utils.d.ts","names":[],"sources":["../../src/utils/codex-openai-responses-stream-writer.utils.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"codex-openai-responses-stream-writer.utils.d.ts","names":[],"sources":["../../src/utils/codex-openai-responses-stream-writer.utils.ts"],"mappings":";KA2CY,kCAAA;EACV,MAAA;EACA,gBAAA,GAAmB,KAAA;EACnB,eAAA;EACA,WAAA,GAAc,KAAA;EACd,UAAA;AAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { nextSequenceNumber, readArray, readNumber, readRecord, readString, writeSseEvent } from "../codex-openai-responses-bridge-shared.utils.js";
|
|
1
|
+
import { nextSequenceNumber, readArray, readNumber, readRawString, readRecord, readString, writeSseEvent } from "../codex-openai-responses-bridge-shared.utils.js";
|
|
2
2
|
import { buildResponseResource, buildUsage } from "./codex-openai-responses-bridge-stream.utils.js";
|
|
3
3
|
import { extractContentText, extractReasoningText, readOpenAiSseChunks } from "./codex-openai-sse-chunks.utils.js";
|
|
4
4
|
//#region src/utils/codex-openai-responses-stream-writer.utils.ts
|
|
@@ -162,13 +162,6 @@ var CodexResponsesOpenAiStreamWriter = class {
|
|
|
162
162
|
summary_index: 0,
|
|
163
163
|
delta: reasoningDelta
|
|
164
164
|
});
|
|
165
|
-
this.writeEvent("response.reasoning_text.delta", {
|
|
166
|
-
type: "response.reasoning_text.delta",
|
|
167
|
-
output_index: state.outputIndex,
|
|
168
|
-
item_id: state.itemId,
|
|
169
|
-
content_index: 0,
|
|
170
|
-
delta: reasoningDelta
|
|
171
|
-
});
|
|
172
165
|
};
|
|
173
166
|
writeTextDelta = (textDelta) => {
|
|
174
167
|
if (!textDelta) return;
|
|
@@ -188,7 +181,7 @@ var CodexResponsesOpenAiStreamWriter = class {
|
|
|
188
181
|
const fn = readRecord(toolCall?.function);
|
|
189
182
|
const state = this.ensureToolCallState(toolIndex, toolCall ?? {});
|
|
190
183
|
state.name = readString(fn?.name) ?? state.name;
|
|
191
|
-
const argumentsDelta =
|
|
184
|
+
const argumentsDelta = readRawString(fn?.arguments) ?? "";
|
|
192
185
|
state.argumentsText += argumentsDelta;
|
|
193
186
|
if (!argumentsDelta) return;
|
|
194
187
|
this.writeEvent("response.function_call_arguments.delta", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-openai-responses-stream-writer.utils.js","names":[],"sources":["../../src/utils/codex-openai-responses-stream-writer.utils.ts"],"sourcesContent":["import type { ServerResponse } from \"node:http\";\nimport {\n buildResponseResource,\n buildUsage,\n} from \"./codex-openai-responses-bridge-stream.utils.js\";\nimport {\n nextSequenceNumber,\n readArray,\n readNumber,\n readRecord,\n readString,\n writeSseEvent,\n type OpenResponsesOutputItem,\n type StreamSequenceState,\n} from \"../codex-openai-responses-bridge-shared.utils.js\";\nimport {\n extractContentText,\n extractReasoningText,\n readOpenAiSseChunks,\n type OpenAiStreamChunk,\n} from \"./codex-openai-sse-chunks.utils.js\";\n\ntype TextStreamState = {\n outputIndex: number;\n itemId: string;\n text: string;\n};\n\ntype ReasoningStreamState = {\n outputIndex: number;\n itemId: string;\n text: string;\n};\n\ntype ToolCallStreamState = {\n outputIndex: number;\n itemId: string;\n callId: string;\n name: string;\n argumentsText: string;\n};\n\nexport type CodexOpenAiResponsesOutputObserver = {\n onDone: () => void;\n onReasoningDelta: (delta: string) => void;\n onReasoningDone: () => void;\n onTextDelta: (delta: string) => void;\n onTextDone: () => void;\n};\n\nexport async function writeResponsesUpstreamStream(params: {\n response: ServerResponse;\n responseId: string;\n model: string;\n outputObserver?: CodexOpenAiResponsesOutputObserver;\n upstreamResponse: Response;\n}): Promise<void> {\n await new CodexResponsesOpenAiStreamWriter(params).write();\n}\n\nclass CodexResponsesOpenAiStreamWriter {\n private readonly sequenceState: StreamSequenceState = { value: 0 };\n private readonly outputItems: OpenResponsesOutputItem[] = [];\n private readonly toolCalls = new Map<number, ToolCallStreamState>();\n private outputCount = 0;\n private textState: TextStreamState | null = null;\n private reasoningState: ReasoningStreamState | null = null;\n private usage: Record<string, unknown> = {};\n\n constructor(\n private readonly params: {\n response: ServerResponse;\n responseId: string;\n model: string;\n outputObserver?: CodexOpenAiResponsesOutputObserver;\n upstreamResponse: Response;\n },\n ) {}\n\n write = async (): Promise<void> => {\n this.writeHeaders();\n this.writeCreatedEvent();\n for await (const chunk of readOpenAiSseChunks(this.params.upstreamResponse)) {\n this.handleChunk(chunk);\n }\n this.finishReasoning();\n this.finishText();\n this.finishToolCalls();\n this.writeCompletedEvent();\n this.params.outputObserver?.onDone();\n this.params.response.end();\n };\n\n private nextOutputIndex = (): number => {\n const value = this.outputCount;\n this.outputCount += 1;\n return value;\n };\n\n private writeEvent = (eventType: string, payload: Record<string, unknown>): void => {\n writeSseEvent(this.params.response, eventType, {\n ...payload,\n sequence_number: nextSequenceNumber(this.sequenceState),\n });\n };\n\n private writeHeaders = (): void => {\n this.params.response.statusCode = 200;\n this.params.response.setHeader(\"content-type\", \"text/event-stream; charset=utf-8\");\n this.params.response.setHeader(\"cache-control\", \"no-cache, no-transform\");\n this.params.response.setHeader(\"connection\", \"keep-alive\");\n };\n\n private writeCreatedEvent = (): void => {\n this.writeEvent(\"response.created\", {\n type: \"response.created\",\n response: buildResponseResource({\n responseId: this.params.responseId,\n model: this.params.model,\n outputItems: [],\n usage: buildUsage({ usage: {} }),\n status: \"in_progress\",\n }),\n });\n };\n\n private ensureTextState = (): TextStreamState => {\n if (this.textState) {\n return this.textState;\n }\n this.textState = {\n outputIndex: this.nextOutputIndex(),\n itemId: `${this.params.responseId}:message:${this.outputCount}`,\n text: \"\",\n };\n this.writeEvent(\"response.output_item.added\", {\n type: \"response.output_item.added\",\n output_index: this.textState.outputIndex,\n item: {\n type: \"message\",\n id: this.textState.itemId,\n role: \"assistant\",\n status: \"in_progress\",\n content: [],\n },\n });\n this.writeEvent(\"response.content_part.added\", {\n type: \"response.content_part.added\",\n output_index: this.textState.outputIndex,\n item_id: this.textState.itemId,\n content_index: 0,\n part: { type: \"output_text\", text: \"\", annotations: [] },\n });\n return this.textState;\n };\n\n private ensureReasoningState = (): ReasoningStreamState => {\n if (this.reasoningState) {\n return this.reasoningState;\n }\n this.reasoningState = {\n outputIndex: this.nextOutputIndex(),\n itemId: `${this.params.responseId}:reasoning:${this.outputCount}`,\n text: \"\",\n };\n this.writeEvent(\"response.output_item.added\", {\n type: \"response.output_item.added\",\n output_index: this.reasoningState.outputIndex,\n item: {\n type: \"reasoning\",\n id: this.reasoningState.itemId,\n status: \"in_progress\",\n content: [],\n summary: [],\n },\n });\n this.writeEvent(\"response.reasoning_summary_part.added\", {\n type: \"response.reasoning_summary_part.added\",\n output_index: this.reasoningState.outputIndex,\n item_id: this.reasoningState.itemId,\n summary_index: 0,\n part: { type: \"summary_text\", text: \"\" },\n });\n return this.reasoningState;\n };\n\n private ensureToolCallState = (\n index: number,\n delta: Record<string, unknown>,\n ): ToolCallStreamState => {\n const existing = this.toolCalls.get(index);\n if (existing) {\n return existing;\n }\n const fn = readRecord(delta.function);\n const state = {\n outputIndex: this.nextOutputIndex(),\n itemId: `${this.params.responseId}:function:${this.outputCount}`,\n callId: readString(delta.id) ?? `${this.params.responseId}:call:${index}`,\n name: readString(fn?.name) ?? \"tool\",\n argumentsText: \"\",\n };\n this.toolCalls.set(index, state);\n this.writeEvent(\"response.output_item.added\", {\n type: \"response.output_item.added\",\n output_index: state.outputIndex,\n item: {\n type: \"function_call\",\n id: state.itemId,\n call_id: state.callId,\n name: state.name,\n arguments: \"\",\n status: \"in_progress\",\n },\n });\n return state;\n };\n\n private handleChunk = (chunk: OpenAiStreamChunk): void => {\n this.usage = chunk.usage ?? this.usage;\n const delta = chunk.choices?.[0]?.delta;\n this.writeReasoningDelta(extractReasoningText(delta));\n this.writeTextDelta(extractContentText(delta?.content));\n for (const rawToolCall of readArray(delta?.tool_calls)) {\n this.writeToolCallDelta(readRecord(rawToolCall));\n }\n };\n\n private writeReasoningDelta = (reasoningDelta: string): void => {\n if (!reasoningDelta) {\n return;\n }\n const state = this.ensureReasoningState();\n state.text += reasoningDelta;\n this.params.outputObserver?.onReasoningDelta(reasoningDelta);\n this.writeEvent(\"response.reasoning_summary_text.delta\", {\n type: \"response.reasoning_summary_text.delta\",\n output_index: state.outputIndex,\n item_id: state.itemId,\n summary_index: 0,\n delta: reasoningDelta,\n });\n this.writeEvent(\"response.reasoning_text.delta\", {\n type: \"response.reasoning_text.delta\",\n output_index: state.outputIndex,\n item_id: state.itemId,\n content_index: 0,\n delta: reasoningDelta,\n });\n };\n\n private writeTextDelta = (textDelta: string): void => {\n if (!textDelta) {\n return;\n }\n const state = this.ensureTextState();\n state.text += textDelta;\n this.params.outputObserver?.onTextDelta(textDelta);\n this.writeEvent(\"response.output_text.delta\", {\n type: \"response.output_text.delta\",\n output_index: state.outputIndex,\n item_id: state.itemId,\n content_index: 0,\n delta: textDelta,\n });\n };\n\n private writeToolCallDelta = (toolCall: Record<string, unknown> | undefined): void => {\n const toolIndex = Math.trunc(readNumber(toolCall?.index) ?? this.toolCalls.size);\n const fn = readRecord(toolCall?.function);\n const state = this.ensureToolCallState(toolIndex, toolCall ?? {});\n state.name = readString(fn?.name) ?? state.name;\n const argumentsDelta = readString(fn?.arguments) ?? \"\";\n state.argumentsText += argumentsDelta;\n if (!argumentsDelta) {\n return;\n }\n this.writeEvent(\"response.function_call_arguments.delta\", {\n type: \"response.function_call_arguments.delta\",\n output_index: state.outputIndex,\n item_id: state.itemId,\n delta: argumentsDelta,\n });\n };\n\n private finishReasoning = (): void => {\n if (!this.reasoningState) {\n return;\n }\n const item = {\n type: \"reasoning\",\n id: this.reasoningState.itemId,\n summary: [{ type: \"summary_text\", text: this.reasoningState.text }],\n content: [{ type: \"reasoning_text\", text: this.reasoningState.text }],\n status: \"completed\",\n };\n this.outputItems[this.reasoningState.outputIndex] = item;\n this.writeEvent(\"response.reasoning_summary_text.done\", {\n type: \"response.reasoning_summary_text.done\",\n output_index: this.reasoningState.outputIndex,\n item_id: this.reasoningState.itemId,\n summary_index: 0,\n text: this.reasoningState.text,\n });\n this.writeEvent(\"response.reasoning_summary_part.done\", {\n type: \"response.reasoning_summary_part.done\",\n output_index: this.reasoningState.outputIndex,\n item_id: this.reasoningState.itemId,\n summary_index: 0,\n part: { type: \"summary_text\", text: this.reasoningState.text },\n });\n this.writeEvent(\"response.reasoning_text.done\", {\n type: \"response.reasoning_text.done\",\n output_index: this.reasoningState.outputIndex,\n item_id: this.reasoningState.itemId,\n content_index: 0,\n text: this.reasoningState.text,\n });\n this.writeEvent(\"response.output_item.done\", {\n type: \"response.output_item.done\",\n output_index: this.reasoningState.outputIndex,\n item,\n });\n this.params.outputObserver?.onReasoningDone();\n };\n\n private finishText = (): void => {\n if (!this.textState) {\n return;\n }\n const item = {\n type: \"message\",\n id: this.textState.itemId,\n role: \"assistant\",\n status: \"completed\",\n content: [{ type: \"output_text\", text: this.textState.text, annotations: [] }],\n };\n this.outputItems[this.textState.outputIndex] = item;\n this.writeEvent(\"response.output_text.done\", {\n type: \"response.output_text.done\",\n output_index: this.textState.outputIndex,\n item_id: this.textState.itemId,\n content_index: 0,\n text: this.textState.text,\n });\n this.writeEvent(\"response.content_part.done\", {\n type: \"response.content_part.done\",\n output_index: this.textState.outputIndex,\n item_id: this.textState.itemId,\n content_index: 0,\n part: { type: \"output_text\", text: this.textState.text, annotations: [] },\n });\n this.writeEvent(\"response.output_item.done\", {\n type: \"response.output_item.done\",\n output_index: this.textState.outputIndex,\n item,\n });\n this.params.outputObserver?.onTextDone();\n };\n\n private finishToolCalls = (): void => {\n for (const state of [...this.toolCalls.values()].sort((a, b) => a.outputIndex - b.outputIndex)) {\n const item = {\n type: \"function_call\",\n id: state.itemId,\n call_id: state.callId,\n name: state.name,\n arguments: state.argumentsText,\n status: \"completed\",\n };\n this.outputItems[state.outputIndex] = item;\n this.writeEvent(\"response.function_call_arguments.done\", {\n type: \"response.function_call_arguments.done\",\n output_index: state.outputIndex,\n item_id: state.itemId,\n arguments: state.argumentsText,\n });\n this.writeEvent(\"response.output_item.done\", {\n type: \"response.output_item.done\",\n output_index: state.outputIndex,\n item,\n });\n }\n };\n\n private writeCompletedEvent = (): void => {\n this.writeEvent(\"response.completed\", {\n type: \"response.completed\",\n response: buildResponseResource({\n responseId: this.params.responseId,\n model: this.params.model,\n outputItems: this.outputItems.filter(Boolean),\n usage: buildUsage({ usage: this.usage }),\n }),\n });\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"codex-openai-responses-stream-writer.utils.js","names":[],"sources":["../../src/utils/codex-openai-responses-stream-writer.utils.ts"],"sourcesContent":["import type { ServerResponse } from \"node:http\";\nimport {\n buildResponseResource,\n buildUsage,\n} from \"./codex-openai-responses-bridge-stream.utils.js\";\nimport {\n nextSequenceNumber,\n readArray,\n readNumber,\n readRecord,\n readRawString,\n readString,\n writeSseEvent,\n type OpenResponsesOutputItem,\n type StreamSequenceState,\n} from \"@/codex-openai-responses-bridge-shared.utils.js\";\nimport {\n extractContentText,\n extractReasoningText,\n readOpenAiSseChunks,\n type OpenAiStreamChunk,\n} from \"./codex-openai-sse-chunks.utils.js\";\n\ntype TextStreamState = {\n outputIndex: number;\n itemId: string;\n text: string;\n};\n\ntype ReasoningStreamState = {\n outputIndex: number;\n itemId: string;\n text: string;\n};\n\ntype ToolCallStreamState = {\n outputIndex: number;\n itemId: string;\n callId: string;\n name: string;\n argumentsText: string;\n};\n\nexport type CodexOpenAiResponsesOutputObserver = {\n onDone: () => void;\n onReasoningDelta: (delta: string) => void;\n onReasoningDone: () => void;\n onTextDelta: (delta: string) => void;\n onTextDone: () => void;\n};\n\nexport async function writeResponsesUpstreamStream(params: {\n response: ServerResponse;\n responseId: string;\n model: string;\n outputObserver?: CodexOpenAiResponsesOutputObserver;\n upstreamResponse: Response;\n}): Promise<void> {\n await new CodexResponsesOpenAiStreamWriter(params).write();\n}\n\nclass CodexResponsesOpenAiStreamWriter {\n private readonly sequenceState: StreamSequenceState = { value: 0 };\n private readonly outputItems: OpenResponsesOutputItem[] = [];\n private readonly toolCalls = new Map<number, ToolCallStreamState>();\n private outputCount = 0;\n private textState: TextStreamState | null = null;\n private reasoningState: ReasoningStreamState | null = null;\n private usage: Record<string, unknown> = {};\n\n constructor(\n private readonly params: {\n response: ServerResponse;\n responseId: string;\n model: string;\n outputObserver?: CodexOpenAiResponsesOutputObserver;\n upstreamResponse: Response;\n },\n ) {}\n\n write = async (): Promise<void> => {\n this.writeHeaders();\n this.writeCreatedEvent();\n for await (const chunk of readOpenAiSseChunks(this.params.upstreamResponse)) {\n this.handleChunk(chunk);\n }\n this.finishReasoning();\n this.finishText();\n this.finishToolCalls();\n this.writeCompletedEvent();\n this.params.outputObserver?.onDone();\n this.params.response.end();\n };\n\n private nextOutputIndex = (): number => {\n const value = this.outputCount;\n this.outputCount += 1;\n return value;\n };\n\n private writeEvent = (eventType: string, payload: Record<string, unknown>): void => {\n writeSseEvent(this.params.response, eventType, {\n ...payload,\n sequence_number: nextSequenceNumber(this.sequenceState),\n });\n };\n\n private writeHeaders = (): void => {\n this.params.response.statusCode = 200;\n this.params.response.setHeader(\"content-type\", \"text/event-stream; charset=utf-8\");\n this.params.response.setHeader(\"cache-control\", \"no-cache, no-transform\");\n this.params.response.setHeader(\"connection\", \"keep-alive\");\n };\n\n private writeCreatedEvent = (): void => {\n this.writeEvent(\"response.created\", {\n type: \"response.created\",\n response: buildResponseResource({\n responseId: this.params.responseId,\n model: this.params.model,\n outputItems: [],\n usage: buildUsage({ usage: {} }),\n status: \"in_progress\",\n }),\n });\n };\n\n private ensureTextState = (): TextStreamState => {\n if (this.textState) {\n return this.textState;\n }\n this.textState = {\n outputIndex: this.nextOutputIndex(),\n itemId: `${this.params.responseId}:message:${this.outputCount}`,\n text: \"\",\n };\n this.writeEvent(\"response.output_item.added\", {\n type: \"response.output_item.added\",\n output_index: this.textState.outputIndex,\n item: {\n type: \"message\",\n id: this.textState.itemId,\n role: \"assistant\",\n status: \"in_progress\",\n content: [],\n },\n });\n this.writeEvent(\"response.content_part.added\", {\n type: \"response.content_part.added\",\n output_index: this.textState.outputIndex,\n item_id: this.textState.itemId,\n content_index: 0,\n part: { type: \"output_text\", text: \"\", annotations: [] },\n });\n return this.textState;\n };\n\n private ensureReasoningState = (): ReasoningStreamState => {\n if (this.reasoningState) {\n return this.reasoningState;\n }\n this.reasoningState = {\n outputIndex: this.nextOutputIndex(),\n itemId: `${this.params.responseId}:reasoning:${this.outputCount}`,\n text: \"\",\n };\n this.writeEvent(\"response.output_item.added\", {\n type: \"response.output_item.added\",\n output_index: this.reasoningState.outputIndex,\n item: {\n type: \"reasoning\",\n id: this.reasoningState.itemId,\n status: \"in_progress\",\n content: [],\n summary: [],\n },\n });\n this.writeEvent(\"response.reasoning_summary_part.added\", {\n type: \"response.reasoning_summary_part.added\",\n output_index: this.reasoningState.outputIndex,\n item_id: this.reasoningState.itemId,\n summary_index: 0,\n part: { type: \"summary_text\", text: \"\" },\n });\n return this.reasoningState;\n };\n\n private ensureToolCallState = (\n index: number,\n delta: Record<string, unknown>,\n ): ToolCallStreamState => {\n const existing = this.toolCalls.get(index);\n if (existing) {\n return existing;\n }\n const fn = readRecord(delta.function);\n const state = {\n outputIndex: this.nextOutputIndex(),\n itemId: `${this.params.responseId}:function:${this.outputCount}`,\n callId: readString(delta.id) ?? `${this.params.responseId}:call:${index}`,\n name: readString(fn?.name) ?? \"tool\",\n argumentsText: \"\",\n };\n this.toolCalls.set(index, state);\n this.writeEvent(\"response.output_item.added\", {\n type: \"response.output_item.added\",\n output_index: state.outputIndex,\n item: {\n type: \"function_call\",\n id: state.itemId,\n call_id: state.callId,\n name: state.name,\n arguments: \"\",\n status: \"in_progress\",\n },\n });\n return state;\n };\n\n private handleChunk = (chunk: OpenAiStreamChunk): void => {\n this.usage = chunk.usage ?? this.usage;\n const delta = chunk.choices?.[0]?.delta;\n this.writeReasoningDelta(extractReasoningText(delta));\n this.writeTextDelta(extractContentText(delta?.content));\n for (const rawToolCall of readArray(delta?.tool_calls)) {\n this.writeToolCallDelta(readRecord(rawToolCall));\n }\n };\n\n private writeReasoningDelta = (reasoningDelta: string): void => {\n if (!reasoningDelta) {\n return;\n }\n const state = this.ensureReasoningState();\n state.text += reasoningDelta;\n this.params.outputObserver?.onReasoningDelta(reasoningDelta);\n this.writeEvent(\"response.reasoning_summary_text.delta\", {\n type: \"response.reasoning_summary_text.delta\",\n output_index: state.outputIndex,\n item_id: state.itemId,\n summary_index: 0,\n delta: reasoningDelta,\n });\n };\n\n private writeTextDelta = (textDelta: string): void => {\n if (!textDelta) {\n return;\n }\n const state = this.ensureTextState();\n state.text += textDelta;\n this.params.outputObserver?.onTextDelta(textDelta);\n this.writeEvent(\"response.output_text.delta\", {\n type: \"response.output_text.delta\",\n output_index: state.outputIndex,\n item_id: state.itemId,\n content_index: 0,\n delta: textDelta,\n });\n };\n\n private writeToolCallDelta = (toolCall: Record<string, unknown> | undefined): void => {\n const toolIndex = Math.trunc(readNumber(toolCall?.index) ?? this.toolCalls.size);\n const fn = readRecord(toolCall?.function);\n const state = this.ensureToolCallState(toolIndex, toolCall ?? {});\n state.name = readString(fn?.name) ?? state.name;\n const argumentsDelta = readRawString(fn?.arguments) ?? \"\";\n state.argumentsText += argumentsDelta;\n if (!argumentsDelta) {\n return;\n }\n this.writeEvent(\"response.function_call_arguments.delta\", {\n type: \"response.function_call_arguments.delta\",\n output_index: state.outputIndex,\n item_id: state.itemId,\n delta: argumentsDelta,\n });\n };\n\n private finishReasoning = (): void => {\n if (!this.reasoningState) {\n return;\n }\n const item = {\n type: \"reasoning\",\n id: this.reasoningState.itemId,\n summary: [{ type: \"summary_text\", text: this.reasoningState.text }],\n content: [{ type: \"reasoning_text\", text: this.reasoningState.text }],\n status: \"completed\",\n };\n this.outputItems[this.reasoningState.outputIndex] = item;\n this.writeEvent(\"response.reasoning_summary_text.done\", {\n type: \"response.reasoning_summary_text.done\",\n output_index: this.reasoningState.outputIndex,\n item_id: this.reasoningState.itemId,\n summary_index: 0,\n text: this.reasoningState.text,\n });\n this.writeEvent(\"response.reasoning_summary_part.done\", {\n type: \"response.reasoning_summary_part.done\",\n output_index: this.reasoningState.outputIndex,\n item_id: this.reasoningState.itemId,\n summary_index: 0,\n part: { type: \"summary_text\", text: this.reasoningState.text },\n });\n this.writeEvent(\"response.reasoning_text.done\", {\n type: \"response.reasoning_text.done\",\n output_index: this.reasoningState.outputIndex,\n item_id: this.reasoningState.itemId,\n content_index: 0,\n text: this.reasoningState.text,\n });\n this.writeEvent(\"response.output_item.done\", {\n type: \"response.output_item.done\",\n output_index: this.reasoningState.outputIndex,\n item,\n });\n this.params.outputObserver?.onReasoningDone();\n };\n\n private finishText = (): void => {\n if (!this.textState) {\n return;\n }\n const item = {\n type: \"message\",\n id: this.textState.itemId,\n role: \"assistant\",\n status: \"completed\",\n content: [{ type: \"output_text\", text: this.textState.text, annotations: [] }],\n };\n this.outputItems[this.textState.outputIndex] = item;\n this.writeEvent(\"response.output_text.done\", {\n type: \"response.output_text.done\",\n output_index: this.textState.outputIndex,\n item_id: this.textState.itemId,\n content_index: 0,\n text: this.textState.text,\n });\n this.writeEvent(\"response.content_part.done\", {\n type: \"response.content_part.done\",\n output_index: this.textState.outputIndex,\n item_id: this.textState.itemId,\n content_index: 0,\n part: { type: \"output_text\", text: this.textState.text, annotations: [] },\n });\n this.writeEvent(\"response.output_item.done\", {\n type: \"response.output_item.done\",\n output_index: this.textState.outputIndex,\n item,\n });\n this.params.outputObserver?.onTextDone();\n };\n\n private finishToolCalls = (): void => {\n for (const state of [...this.toolCalls.values()].sort((a, b) => a.outputIndex - b.outputIndex)) {\n const item = {\n type: \"function_call\",\n id: state.itemId,\n call_id: state.callId,\n name: state.name,\n arguments: state.argumentsText,\n status: \"completed\",\n };\n this.outputItems[state.outputIndex] = item;\n this.writeEvent(\"response.function_call_arguments.done\", {\n type: \"response.function_call_arguments.done\",\n output_index: state.outputIndex,\n item_id: state.itemId,\n arguments: state.argumentsText,\n });\n this.writeEvent(\"response.output_item.done\", {\n type: \"response.output_item.done\",\n output_index: state.outputIndex,\n item,\n });\n }\n };\n\n private writeCompletedEvent = (): void => {\n this.writeEvent(\"response.completed\", {\n type: \"response.completed\",\n response: buildResponseResource({\n responseId: this.params.responseId,\n model: this.params.model,\n outputItems: this.outputItems.filter(Boolean),\n usage: buildUsage({ usage: this.usage }),\n }),\n });\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-openai-sse-chunks.utils.js","names":[],"sources":["../../src/utils/codex-openai-sse-chunks.utils.ts"],"sourcesContent":["import {\n readArray,\n readRawString,\n readRecord,\n} from \"
|
|
1
|
+
{"version":3,"file":"codex-openai-sse-chunks.utils.js","names":[],"sources":["../../src/utils/codex-openai-sse-chunks.utils.ts"],"sourcesContent":["import {\n readArray,\n readRawString,\n readRecord,\n} from \"@/codex-openai-responses-bridge-shared.utils.js\";\n\nexport type OpenAiStreamChoiceDelta = Record<string, unknown> & {\n tool_calls?: unknown;\n};\n\nexport type OpenAiStreamChunk = {\n choices?: Array<{\n delta?: OpenAiStreamChoiceDelta;\n finish_reason?: unknown;\n }>;\n usage?: Record<string, unknown>;\n};\n\nexport function extractContentText(content: unknown): string {\n if (typeof content === \"string\") {\n return content;\n }\n return readArray(content)\n .map((entry) => {\n const record = readRecord(entry);\n return readRawString(record?.text) ?? readRawString(record?.content) ?? \"\";\n })\n .join(\"\");\n}\n\nexport function extractReasoningText(delta: OpenAiStreamChoiceDelta | undefined): string {\n return (\n readRawString(delta?.reasoning_content) ??\n readRawString(delta?.reasoning) ??\n readRawString(delta?.thinking) ??\n \"\"\n );\n}\n\nexport async function* readOpenAiSseChunks(\n upstreamResponse: Response,\n): AsyncGenerator<OpenAiStreamChunk> {\n const stream = upstreamResponse.body;\n if (!stream) {\n return;\n }\n const decoder = new TextDecoder();\n let buffer = \"\";\n for await (const rawChunk of stream as unknown as AsyncIterable<Uint8Array>) {\n buffer += decoder.decode(rawChunk, { stream: true }).replaceAll(\"\\r\\n\", \"\\n\");\n const blocks = buffer.split(\"\\n\\n\");\n buffer = blocks.pop() ?? \"\";\n for (const block of blocks) {\n const data = block\n .split(\"\\n\")\n .filter((line) => line.startsWith(\"data:\"))\n .map((line) => line.slice(5).trimStart())\n .join(\"\\n\")\n .trim();\n if (!data || data === \"[DONE]\") {\n continue;\n }\n yield JSON.parse(data) as OpenAiStreamChunk;\n }\n }\n}\n"],"mappings":";;AAkBA,SAAgB,mBAAmB,SAA0B;AAC3D,KAAI,OAAO,YAAY,SACrB,QAAO;AAET,QAAO,UAAU,QAAQ,CACtB,KAAK,UAAU;EACd,MAAM,SAAS,WAAW,MAAM;AAChC,SAAO,cAAc,QAAQ,KAAK,IAAI,cAAc,QAAQ,QAAQ,IAAI;GACxE,CACD,KAAK,GAAG;;AAGb,SAAgB,qBAAqB,OAAoD;AACvF,QACE,cAAc,OAAO,kBAAkB,IACvC,cAAc,OAAO,UAAU,IAC/B,cAAc,OAAO,SAAS,IAC9B;;AAIJ,gBAAuB,oBACrB,kBACmC;CACnC,MAAM,SAAS,iBAAiB;AAChC,KAAI,CAAC,OACH;CAEF,MAAM,UAAU,IAAI,aAAa;CACjC,IAAI,SAAS;AACb,YAAW,MAAM,YAAY,QAAgD;AAC3E,YAAU,QAAQ,OAAO,UAAU,EAAE,QAAQ,MAAM,CAAC,CAAC,WAAW,QAAQ,KAAK;EAC7E,MAAM,SAAS,OAAO,MAAM,OAAO;AACnC,WAAS,OAAO,KAAK,IAAI;AACzB,OAAK,MAAM,SAAS,QAAQ;GAC1B,MAAM,OAAO,MACV,MAAM,KAAK,CACX,QAAQ,SAAS,KAAK,WAAW,QAAQ,CAAC,CAC1C,KAAK,SAAS,KAAK,MAAM,EAAE,CAAC,WAAW,CAAC,CACxC,KAAK,KAAK,CACV,MAAM;AACT,OAAI,CAAC,QAAQ,SAAS,SACpB;AAEF,SAAM,KAAK,MAAM,KAAK"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
3
|
+
//#region src/utils/codex-rollout-thread-summary.utils.ts
|
|
4
|
+
function readCodexRolloutSummary(rolloutPath) {
|
|
5
|
+
let createdAtMs;
|
|
6
|
+
let firstEventUserMessage;
|
|
7
|
+
let firstResponseUserMessage;
|
|
8
|
+
let hasUserEvent = false;
|
|
9
|
+
let sessionMeta;
|
|
10
|
+
let tokensUsed;
|
|
11
|
+
let updatedAtMs;
|
|
12
|
+
for (const line of readFileSync(rolloutPath, "utf8").split(/\r?\n/)) {
|
|
13
|
+
const entry = readRolloutEntry(line);
|
|
14
|
+
if (!entry) continue;
|
|
15
|
+
const timestampMs = readTimestampMs(entry.timestamp);
|
|
16
|
+
createdAtMs ??= timestampMs;
|
|
17
|
+
updatedAtMs = timestampMs ?? updatedAtMs;
|
|
18
|
+
const payload = isRecord(entry.payload) ? entry.payload : void 0;
|
|
19
|
+
if (entry.type === "session_meta" && isRecord(payload)) {
|
|
20
|
+
sessionMeta = readRolloutSessionMeta(payload);
|
|
21
|
+
createdAtMs ??= sessionMeta.timestampMs;
|
|
22
|
+
updatedAtMs ??= sessionMeta.timestampMs;
|
|
23
|
+
}
|
|
24
|
+
if (entry.type === "event_msg" && isRecord(payload)) {
|
|
25
|
+
hasUserEvent = hasUserEvent || payload.type === "user_message";
|
|
26
|
+
firstEventUserMessage ??= payload.type === "user_message" ? readString(payload.message) : void 0;
|
|
27
|
+
tokensUsed = payload.type === "token_count" ? readTokenCount(payload) ?? tokensUsed : tokensUsed;
|
|
28
|
+
}
|
|
29
|
+
if (isResponseUserMessage(entry, payload)) {
|
|
30
|
+
hasUserEvent = true;
|
|
31
|
+
firstResponseUserMessage ??= readResponseUserMessage(payload);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
createdAtMs,
|
|
36
|
+
firstUserMessage: firstEventUserMessage ?? firstResponseUserMessage,
|
|
37
|
+
hasUserEvent,
|
|
38
|
+
sessionMeta,
|
|
39
|
+
tokensUsed,
|
|
40
|
+
updatedAtMs
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function isResponseUserMessage(entry, payload) {
|
|
44
|
+
return entry.type === "response_item" && isRecord(payload) && payload.role === "user";
|
|
45
|
+
}
|
|
46
|
+
function findCodexRolloutPathForThreadId(sessionsDirectory, threadId) {
|
|
47
|
+
if (!existsSync(sessionsDirectory)) return;
|
|
48
|
+
const directories = [sessionsDirectory];
|
|
49
|
+
while (directories.length > 0) {
|
|
50
|
+
const directory = directories.pop();
|
|
51
|
+
if (!directory) continue;
|
|
52
|
+
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
|
53
|
+
const entryPath = join(directory, entry.name);
|
|
54
|
+
if (entry.isDirectory()) {
|
|
55
|
+
directories.push(entryPath);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (entry.isFile() && entry.name.endsWith(".jsonl") && entry.name.includes(threadId)) return entryPath;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function readRolloutEntry(line) {
|
|
63
|
+
const trimmed = line.trim();
|
|
64
|
+
if (!trimmed) return;
|
|
65
|
+
const entry = JSON.parse(trimmed);
|
|
66
|
+
return isRecord(entry) ? entry : void 0;
|
|
67
|
+
}
|
|
68
|
+
function readRolloutSessionMeta(payload) {
|
|
69
|
+
return {
|
|
70
|
+
approvalMode: readString(payload.approval_mode),
|
|
71
|
+
cliVersion: readString(payload.cli_version),
|
|
72
|
+
cwd: readString(payload.cwd),
|
|
73
|
+
memoryMode: readString(payload.memory_mode),
|
|
74
|
+
model: readString(payload.model),
|
|
75
|
+
modelProvider: readString(payload.model_provider),
|
|
76
|
+
reasoningEffort: readString(payload.reasoning_effort),
|
|
77
|
+
sandboxPolicy: readStringOrJson(payload.sandbox_policy),
|
|
78
|
+
source: readString(payload.source),
|
|
79
|
+
timestampMs: readTimestampMs(payload.timestamp)
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function readResponseUserMessage(payload) {
|
|
83
|
+
const content = Array.isArray(payload.content) ? payload.content : void 0;
|
|
84
|
+
const parts = [];
|
|
85
|
+
for (const item of content ?? []) {
|
|
86
|
+
if (!isRecord(item)) continue;
|
|
87
|
+
const text = readString(item.text);
|
|
88
|
+
if (text) parts.push(text);
|
|
89
|
+
}
|
|
90
|
+
return readString(parts.join("\n"));
|
|
91
|
+
}
|
|
92
|
+
function readTokenCount(payload) {
|
|
93
|
+
const info = isRecord(payload.info) ? payload.info : void 0;
|
|
94
|
+
return readNumber((isRecord(info?.total_token_usage) ? info.total_token_usage : void 0)?.total_tokens);
|
|
95
|
+
}
|
|
96
|
+
function readStringOrJson(value) {
|
|
97
|
+
const stringValue = readString(value);
|
|
98
|
+
if (stringValue) return stringValue;
|
|
99
|
+
return isRecord(value) ? JSON.stringify(value) : void 0;
|
|
100
|
+
}
|
|
101
|
+
function readTimestampMs(value) {
|
|
102
|
+
const timestamp = readString(value);
|
|
103
|
+
if (!timestamp) return;
|
|
104
|
+
const timestampMs = Date.parse(timestamp);
|
|
105
|
+
return Number.isFinite(timestampMs) ? timestampMs : void 0;
|
|
106
|
+
}
|
|
107
|
+
function readNumber(value) {
|
|
108
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
109
|
+
}
|
|
110
|
+
function readString(value) {
|
|
111
|
+
if (typeof value !== "string") return;
|
|
112
|
+
const trimmed = value.trim();
|
|
113
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
114
|
+
}
|
|
115
|
+
function isRecord(value) {
|
|
116
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
export { findCodexRolloutPathForThreadId, readCodexRolloutSummary };
|
|
120
|
+
|
|
121
|
+
//# sourceMappingURL=codex-rollout-thread-summary.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-rollout-thread-summary.utils.js","names":[],"sources":["../../src/utils/codex-rollout-thread-summary.utils.ts"],"sourcesContent":["import { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport type CodexRolloutSessionMeta = {\n approvalMode?: string;\n cliVersion?: string;\n cwd?: string;\n memoryMode?: string;\n model?: string;\n modelProvider?: string;\n reasoningEffort?: string;\n sandboxPolicy?: string;\n source?: string;\n timestampMs?: number;\n};\n\nexport type CodexRolloutSummary = {\n createdAtMs?: number;\n firstUserMessage?: string;\n hasUserEvent: boolean;\n sessionMeta?: CodexRolloutSessionMeta;\n tokensUsed?: number;\n updatedAtMs?: number;\n};\n\nexport function readCodexRolloutSummary(\n rolloutPath: string,\n): CodexRolloutSummary {\n let createdAtMs: number | undefined;\n let firstEventUserMessage: string | undefined;\n let firstResponseUserMessage: string | undefined;\n let hasUserEvent = false;\n let sessionMeta: CodexRolloutSessionMeta | undefined;\n let tokensUsed: number | undefined;\n let updatedAtMs: number | undefined;\n for (const line of readFileSync(rolloutPath, \"utf8\").split(/\\r?\\n/)) {\n const entry = readRolloutEntry(line);\n if (!entry) {\n continue;\n }\n const timestampMs = readTimestampMs(entry.timestamp);\n createdAtMs ??= timestampMs;\n updatedAtMs = timestampMs ?? updatedAtMs;\n const payload = isRecord(entry.payload) ? entry.payload : undefined;\n if (entry.type === \"session_meta\" && isRecord(payload)) {\n sessionMeta = readRolloutSessionMeta(payload);\n createdAtMs ??= sessionMeta.timestampMs;\n updatedAtMs ??= sessionMeta.timestampMs;\n }\n if (entry.type === \"event_msg\" && isRecord(payload)) {\n hasUserEvent = hasUserEvent || payload.type === \"user_message\";\n firstEventUserMessage ??=\n payload.type === \"user_message\"\n ? readString(payload.message)\n : undefined;\n tokensUsed =\n payload.type === \"token_count\"\n ? readTokenCount(payload) ?? tokensUsed\n : tokensUsed;\n }\n if (isResponseUserMessage(entry, payload)) {\n hasUserEvent = true;\n firstResponseUserMessage ??= readResponseUserMessage(payload);\n }\n }\n return {\n createdAtMs,\n firstUserMessage: firstEventUserMessage ?? firstResponseUserMessage,\n hasUserEvent,\n sessionMeta,\n tokensUsed,\n updatedAtMs,\n };\n}\n\nfunction isResponseUserMessage(\n entry: Record<string, unknown>,\n payload: Record<string, unknown> | undefined,\n): payload is Record<string, unknown> {\n return (\n entry.type === \"response_item\" &&\n isRecord(payload) &&\n payload.role === \"user\"\n );\n}\n\nexport function findCodexRolloutPathForThreadId(\n sessionsDirectory: string,\n threadId: string,\n): string | undefined {\n if (!existsSync(sessionsDirectory)) {\n return undefined;\n }\n const directories = [sessionsDirectory];\n while (directories.length > 0) {\n const directory = directories.pop();\n if (!directory) {\n continue;\n }\n for (const entry of readdirSync(directory, { withFileTypes: true })) {\n const entryPath = join(directory, entry.name);\n if (entry.isDirectory()) {\n directories.push(entryPath);\n continue;\n }\n if (\n entry.isFile() &&\n entry.name.endsWith(\".jsonl\") &&\n entry.name.includes(threadId)\n ) {\n return entryPath;\n }\n }\n }\n return undefined;\n}\n\nfunction readRolloutEntry(line: string): Record<string, unknown> | undefined {\n const trimmed = line.trim();\n if (!trimmed) {\n return undefined;\n }\n const entry = JSON.parse(trimmed) as unknown;\n return isRecord(entry) ? entry : undefined;\n}\n\nfunction readRolloutSessionMeta(\n payload: Record<string, unknown>,\n): CodexRolloutSessionMeta {\n return {\n approvalMode: readString(payload.approval_mode),\n cliVersion: readString(payload.cli_version),\n cwd: readString(payload.cwd),\n memoryMode: readString(payload.memory_mode),\n model: readString(payload.model),\n modelProvider: readString(payload.model_provider),\n reasoningEffort: readString(payload.reasoning_effort),\n sandboxPolicy: readStringOrJson(payload.sandbox_policy),\n source: readString(payload.source),\n timestampMs: readTimestampMs(payload.timestamp),\n };\n}\n\nfunction readResponseUserMessage(\n payload: Record<string, unknown>,\n): string | undefined {\n const content = Array.isArray(payload.content) ? payload.content : undefined;\n const parts: string[] = [];\n for (const item of content ?? []) {\n if (!isRecord(item)) {\n continue;\n }\n const text = readString(item.text);\n if (text) {\n parts.push(text);\n }\n }\n return readString(parts.join(\"\\n\"));\n}\n\nfunction readTokenCount(payload: Record<string, unknown>): number | undefined {\n const info = isRecord(payload.info) ? payload.info : undefined;\n const usage = isRecord(info?.total_token_usage)\n ? info.total_token_usage\n : undefined;\n return readNumber(usage?.total_tokens);\n}\n\nfunction readStringOrJson(value: unknown): string | undefined {\n const stringValue = readString(value);\n if (stringValue) {\n return stringValue;\n }\n return isRecord(value) ? JSON.stringify(value) : undefined;\n}\n\nfunction readTimestampMs(value: unknown): number | undefined {\n const timestamp = readString(value);\n if (!timestamp) {\n return undefined;\n }\n const timestampMs = Date.parse(timestamp);\n return Number.isFinite(timestampMs) ? timestampMs : undefined;\n}\n\nfunction readNumber(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\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 isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/nextclaw-ncp-runtime-codex-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.55-beta.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Optional NCP runtime adapter backed by OpenAI Codex SDK.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": {
|
|
9
|
+
"import": "./dist/index.js",
|
|
9
10
|
"types": "./dist/index.d.ts",
|
|
10
11
|
"default": "./dist/index.js"
|
|
11
12
|
}
|
|
@@ -17,7 +18,7 @@
|
|
|
17
18
|
],
|
|
18
19
|
"dependencies": {
|
|
19
20
|
"@openai/codex-sdk": "^0.139.0",
|
|
20
|
-
"@nextclaw/ncp": "0.6.
|
|
21
|
+
"@nextclaw/ncp": "0.6.4-beta.1"
|
|
21
22
|
},
|
|
22
23
|
"devDependencies": {
|
|
23
24
|
"@types/node": "^20.17.6",
|
|
@@ -27,7 +28,7 @@
|
|
|
27
28
|
"scripts": {
|
|
28
29
|
"build": "tsdown src/index.ts --dts.sourcemap --clean --target es2022 --no-fixedExtension --unbundle",
|
|
29
30
|
"lint": "eslint .",
|
|
30
|
-
"test": "vitest run src/services/codex-sdk-runtime-thread-metadata.service.test.ts src/utils/codex-model-provider.utils.test.ts src/utils/codex-sdk-ncp-event-mapper.utils.test.ts src/services/codex-live-output-stream.service.test.ts src/utils/codex-openai-sse-chunks.utils.test.ts",
|
|
31
|
+
"test": "vitest run src/services/codex-sdk-runtime-thread-metadata.service.test.ts src/services/codex-desktop-thread-index-sync.service.test.ts src/utils/codex-model-provider.utils.test.ts src/utils/codex-sdk-ncp-event-mapper.utils.test.ts src/services/codex-live-output-stream.service.test.ts src/utils/codex-openai-sse-chunks.utils.test.ts src/utils/codex-openai-responses-stream-writer.utils.test.ts",
|
|
31
32
|
"tsc": "tsc -p tsconfig.json"
|
|
32
33
|
}
|
|
33
34
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"codex-openai-responses-bridge-assistant-output.utils.js","names":[],"sources":["../src/codex-openai-responses-bridge-assistant-output.utils.ts"],"sourcesContent":["import type { ServerResponse } from \"node:http\";\nimport { normalizeAssistantText } from \"@nextclaw/ncp\";\nimport {\n nextSequenceNumber,\n readArray,\n readRecord,\n readRawString,\n readString,\n writeSseEvent,\n type OpenAiChatCompletionChoiceMessage,\n type OpenResponsesOutputItem,\n type StreamSequenceState,\n} from \"./codex-openai-responses-bridge-shared.utils.js\";\n\nfunction extractAssistantText(content: unknown): string {\n if (typeof content === \"string\") {\n return content;\n }\n if (!Array.isArray(content)) {\n return \"\";\n }\n return content\n .map((entry) => {\n const record = readRecord(entry);\n if (!record) {\n return \"\";\n }\n const type = readString(record.type);\n if (type === \"text\" || type === \"output_text\") {\n return readString(record.text) ?? \"\";\n }\n return \"\";\n })\n .filter(Boolean)\n .join(\"\");\n}\n\ntype ReasoningExtraction = {\n present: boolean;\n text: string;\n};\n\nfunction readReasoningRecordText(value: unknown): string {\n const record = readRecord(value);\n if (!record) {\n return \"\";\n }\n return (\n readRawString(record.text) ??\n readRawString(record.content) ??\n readRawString(record.reasoning) ??\n readRawString(record.reasoning_content) ??\n readRawString(record.thinking) ??\n \"\"\n );\n}\n\nfunction extractReasoningDetailsText(value: unknown): ReasoningExtraction | undefined {\n const rawString = readRawString(value);\n if (rawString !== undefined) {\n return {\n present: true,\n text: rawString,\n };\n }\n\n const record = readRecord(value);\n if (record) {\n return {\n present: true,\n text: readReasoningRecordText(record),\n };\n }\n\n if (!Array.isArray(value)) {\n return undefined;\n }\n\n const text = readArray(value)\n .map((entry) => readReasoningRecordText(entry))\n .join(\"\");\n return {\n present: true,\n text,\n };\n}\n\nfunction extractContentReasoningText(content: unknown): string {\n if (!Array.isArray(content)) {\n return \"\";\n }\n return content\n .map((entry) => {\n const record = readRecord(entry);\n if (!record) {\n return \"\";\n }\n const type = readString(record.type);\n if (\n type === \"reasoning\" ||\n type === \"reasoning_text\" ||\n type === \"thinking\" ||\n type === \"thinking_text\"\n ) {\n return readReasoningRecordText(record);\n }\n return \"\";\n })\n .join(\"\");\n}\n\nfunction extractExplicitReasoning(\n message: OpenAiChatCompletionChoiceMessage | undefined,\n): ReasoningExtraction | undefined {\n const candidates = [\n message?.reasoning_content,\n message?.reasoning,\n message?.thinking,\n message?.reasoning_details,\n ];\n\n for (const candidate of candidates) {\n const extracted = extractReasoningDetailsText(candidate);\n if (extracted) {\n return extracted;\n }\n }\n\n const contentReasoning = extractContentReasoningText(message?.content);\n return contentReasoning\n ? {\n present: true,\n text: contentReasoning,\n }\n : undefined;\n}\n\nfunction extractAssistantOutput(message: OpenAiChatCompletionChoiceMessage | undefined): {\n text: string;\n reasoning: string;\n reasoningPresent: boolean;\n} {\n const rawText = extractAssistantText(message?.content);\n const normalized = normalizeAssistantText(rawText, \"think-tags\");\n const explicitReasoning = extractExplicitReasoning(message);\n const reasoning = explicitReasoning?.text ?? readString(normalized.reasoning) ?? \"\";\n const reasoningPresent = explicitReasoning?.present === true || Boolean(normalized.reasoning);\n const text =\n explicitReasoning?.present === true\n ? readString(normalized.text) ?? readString(rawText) ?? \"\"\n : normalized.reasoning\n ? readString(normalized.text) ?? \"\"\n : readString(rawText) ?? \"\";\n\n return {\n text,\n reasoning,\n reasoningPresent,\n };\n}\n\nfunction buildInProgressReasoningItem(item: OpenResponsesOutputItem): OpenResponsesOutputItem {\n return {\n ...structuredClone(item),\n status: \"in_progress\",\n content: [],\n summary: [],\n };\n}\n\nexport function buildAssistantOutputItems(params: {\n message: OpenAiChatCompletionChoiceMessage | undefined;\n responseId: string;\n}): OpenResponsesOutputItem[] {\n const { reasoning, reasoningPresent, text } = extractAssistantOutput(params.message);\n const outputItems: OpenResponsesOutputItem[] = [];\n\n if (reasoningPresent) {\n outputItems.push({\n type: \"reasoning\",\n id: `${params.responseId}:reasoning:0`,\n summary: [\n {\n type: \"summary_text\",\n text: reasoning,\n },\n ],\n content: [\n {\n type: \"reasoning_text\",\n text: reasoning,\n },\n ],\n status: \"completed\",\n });\n }\n\n if (text) {\n outputItems.push({\n type: \"message\",\n id: `${params.responseId}:message:${outputItems.length}`,\n role: \"assistant\",\n status: \"completed\",\n content: [\n {\n type: \"output_text\",\n text,\n annotations: [],\n },\n ],\n });\n }\n\n return outputItems;\n}\n\nexport function writeReasoningOutputItemEvents(params: {\n response: ServerResponse;\n item: OpenResponsesOutputItem;\n outputIndex: number;\n sequenceState: StreamSequenceState;\n}): void {\n const itemId = readString(params.item.id);\n const content = readArray(params.item.content);\n const textPart = content.find((entry) => readString(readRecord(entry)?.type) === \"reasoning_text\");\n const text = readString(readRecord(textPart)?.text) ?? \"\";\n const summary = readArray(params.item.summary);\n const summaryIndex = summary.findIndex((entry) => readString(readRecord(entry)?.type) === \"summary_text\");\n const summaryText =\n summaryIndex >= 0 ? readString(readRecord(summary[summaryIndex])?.text) ?? \"\" : \"\";\n\n writeSseEvent(params.response, \"response.output_item.added\", {\n type: \"response.output_item.added\",\n sequence_number: nextSequenceNumber(params.sequenceState),\n output_index: params.outputIndex,\n item: buildInProgressReasoningItem(params.item),\n });\n\n if (itemId && summaryText) {\n writeSseEvent(params.response, \"response.reasoning_summary_part.added\", {\n type: \"response.reasoning_summary_part.added\",\n sequence_number: nextSequenceNumber(params.sequenceState),\n output_index: params.outputIndex,\n item_id: itemId,\n summary_index: summaryIndex,\n part: {\n type: \"summary_text\",\n text: \"\",\n },\n });\n writeSseEvent(params.response, \"response.reasoning_summary_text.delta\", {\n type: \"response.reasoning_summary_text.delta\",\n sequence_number: nextSequenceNumber(params.sequenceState),\n output_index: params.outputIndex,\n item_id: itemId,\n summary_index: summaryIndex,\n delta: summaryText,\n });\n writeSseEvent(params.response, \"response.reasoning_summary_text.done\", {\n type: \"response.reasoning_summary_text.done\",\n sequence_number: nextSequenceNumber(params.sequenceState),\n output_index: params.outputIndex,\n item_id: itemId,\n summary_index: summaryIndex,\n text: summaryText,\n });\n writeSseEvent(params.response, \"response.reasoning_summary_part.done\", {\n type: \"response.reasoning_summary_part.done\",\n sequence_number: nextSequenceNumber(params.sequenceState),\n output_index: params.outputIndex,\n item_id: itemId,\n summary_index: summaryIndex,\n part: {\n type: \"summary_text\",\n text: summaryText,\n },\n });\n }\n\n if (itemId && text) {\n writeSseEvent(params.response, \"response.reasoning_text.delta\", {\n type: \"response.reasoning_text.delta\",\n sequence_number: nextSequenceNumber(params.sequenceState),\n output_index: params.outputIndex,\n item_id: itemId,\n content_index: 0,\n delta: text,\n });\n }\n\n if (itemId) {\n writeSseEvent(params.response, \"response.reasoning_text.done\", {\n type: \"response.reasoning_text.done\",\n sequence_number: nextSequenceNumber(params.sequenceState),\n output_index: params.outputIndex,\n item_id: itemId,\n content_index: 0,\n text,\n });\n }\n\n writeSseEvent(params.response, \"response.output_item.done\", {\n type: \"response.output_item.done\",\n sequence_number: nextSequenceNumber(params.sequenceState),\n output_index: params.outputIndex,\n item: params.item,\n });\n}\n"],"mappings":";;;AAcA,SAAS,qBAAqB,SAA0B;AACtD,KAAI,OAAO,YAAY,SACrB,QAAO;AAET,KAAI,CAAC,MAAM,QAAQ,QAAQ,CACzB,QAAO;AAET,QAAO,QACJ,KAAK,UAAU;EACd,MAAM,SAAS,WAAW,MAAM;AAChC,MAAI,CAAC,OACH,QAAO;EAET,MAAM,OAAO,WAAW,OAAO,KAAK;AACpC,MAAI,SAAS,UAAU,SAAS,cAC9B,QAAO,WAAW,OAAO,KAAK,IAAI;AAEpC,SAAO;GACP,CACD,OAAO,QAAQ,CACf,KAAK,GAAG;;AAQb,SAAS,wBAAwB,OAAwB;CACvD,MAAM,SAAS,WAAW,MAAM;AAChC,KAAI,CAAC,OACH,QAAO;AAET,QACE,cAAc,OAAO,KAAK,IAC1B,cAAc,OAAO,QAAQ,IAC7B,cAAc,OAAO,UAAU,IAC/B,cAAc,OAAO,kBAAkB,IACvC,cAAc,OAAO,SAAS,IAC9B;;AAIJ,SAAS,4BAA4B,OAAiD;CACpF,MAAM,YAAY,cAAc,MAAM;AACtC,KAAI,cAAc,KAAA,EAChB,QAAO;EACL,SAAS;EACT,MAAM;EACP;CAGH,MAAM,SAAS,WAAW,MAAM;AAChC,KAAI,OACF,QAAO;EACL,SAAS;EACT,MAAM,wBAAwB,OAAO;EACtC;AAGH,KAAI,CAAC,MAAM,QAAQ,MAAM,CACvB;AAMF,QAAO;EACL,SAAS;EACT,MALW,UAAU,MAAM,CAC1B,KAAK,UAAU,wBAAwB,MAAM,CAAC,CAC9C,KAAK,GAAG;EAIV;;AAGH,SAAS,4BAA4B,SAA0B;AAC7D,KAAI,CAAC,MAAM,QAAQ,QAAQ,CACzB,QAAO;AAET,QAAO,QACJ,KAAK,UAAU;EACd,MAAM,SAAS,WAAW,MAAM;AAChC,MAAI,CAAC,OACH,QAAO;EAET,MAAM,OAAO,WAAW,OAAO,KAAK;AACpC,MACE,SAAS,eACT,SAAS,oBACT,SAAS,cACT,SAAS,gBAET,QAAO,wBAAwB,OAAO;AAExC,SAAO;GACP,CACD,KAAK,GAAG;;AAGb,SAAS,yBACP,SACiC;CACjC,MAAM,aAAa;EACjB,SAAS;EACT,SAAS;EACT,SAAS;EACT,SAAS;EACV;AAED,MAAK,MAAM,aAAa,YAAY;EAClC,MAAM,YAAY,4BAA4B,UAAU;AACxD,MAAI,UACF,QAAO;;CAIX,MAAM,mBAAmB,4BAA4B,SAAS,QAAQ;AACtE,QAAO,mBACH;EACE,SAAS;EACT,MAAM;EACP,GACD,KAAA;;AAGN,SAAS,uBAAuB,SAI9B;CACA,MAAM,UAAU,qBAAqB,SAAS,QAAQ;CACtD,MAAM,aAAa,uBAAuB,SAAS,aAAa;CAChE,MAAM,oBAAoB,yBAAyB,QAAQ;CAC3D,MAAM,YAAY,mBAAmB,QAAQ,WAAW,WAAW,UAAU,IAAI;CACjF,MAAM,mBAAmB,mBAAmB,YAAY,QAAQ,QAAQ,WAAW,UAAU;AAQ7F,QAAO;EACL,MAPA,mBAAmB,YAAY,OAC3B,WAAW,WAAW,KAAK,IAAI,WAAW,QAAQ,IAAI,KACtD,WAAW,YACT,WAAW,WAAW,KAAK,IAAI,KAC/B,WAAW,QAAQ,IAAI;EAI7B;EACA;EACD;;AAYH,SAAgB,0BAA0B,QAGZ;CAC5B,MAAM,EAAE,WAAW,kBAAkB,SAAS,uBAAuB,OAAO,QAAQ;CACpF,MAAM,cAAyC,EAAE;AAEjD,KAAI,iBACF,aAAY,KAAK;EACf,MAAM;EACN,IAAI,GAAG,OAAO,WAAW;EACzB,SAAS,CACP;GACE,MAAM;GACN,MAAM;GACP,CACF;EACD,SAAS,CACP;GACE,MAAM;GACN,MAAM;GACP,CACF;EACD,QAAQ;EACT,CAAC;AAGJ,KAAI,KACF,aAAY,KAAK;EACf,MAAM;EACN,IAAI,GAAG,OAAO,WAAW,WAAW,YAAY;EAChD,MAAM;EACN,QAAQ;EACR,SAAS,CACP;GACE,MAAM;GACN;GACA,aAAa,EAAE;GAChB,CACF;EACF,CAAC;AAGJ,QAAO"}
|