@nextclaw/nextclaw-ncp-runtime-codex-sdk 0.1.25 → 0.1.26

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.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { buildCompletedAssistantMessage } from "./completed-assistant-message.utils.js";
2
- import { mapCodexItemEvent } from "./codex-sdk-ncp-event-mapper.js";
2
+ import { mapCodexItemEvent } from "./utils/codex-sdk-ncp-event-mapper.utils.js";
3
3
  import { buildCodexCliEnv } from "./codex-cli-env.js";
4
4
  import { buildCodexInputBuilder, buildCodexTurnInputFromRunInput } from "./codex-input.utils.js";
5
5
  import { createRequire } from "node:module";
@@ -1,5 +1,6 @@
1
1
  import { NcpEventType } from "@nextclaw/ncp";
2
- //#region src/codex-sdk-ncp-event-mapper.ts
2
+ //#region src/utils/codex-sdk-ncp-event-mapper.utils.ts
3
+ const TEXT_DELTA_CHUNK_SIZE = 32;
3
4
  function buildToolDescriptor(item) {
4
5
  switch (item.type) {
5
6
  case "mcp_tool_call": return {
@@ -64,81 +65,77 @@ function stringifyToolArgs(args) {
64
65
  function isToolLikeItem(item) {
65
66
  return item.type === "mcp_tool_call" || item.type === "command_execution" || item.type === "web_search" || item.type === "file_change" || item.type === "todo_list";
66
67
  }
67
- async function* mapCodexItemEvent(params) {
68
- const { sessionId, messageId, event, itemTextById, toolStateById } = params;
69
- const { item } = event;
70
- if (item.type === "agent_message") {
71
- const currentText = item.text ?? "";
72
- const previous = itemTextById.get(item.id) ?? {
73
- text: "",
74
- started: false
75
- };
76
- if (!previous.started) yield {
77
- type: NcpEventType.MessageTextStart,
68
+ function splitTextDelta(delta) {
69
+ if (delta.length <= TEXT_DELTA_CHUNK_SIZE) return delta ? [delta] : [];
70
+ const chunks = [];
71
+ for (let index = 0; index < delta.length; index += TEXT_DELTA_CHUNK_SIZE) chunks.push(delta.slice(index, index + TEXT_DELTA_CHUNK_SIZE));
72
+ return chunks;
73
+ }
74
+ function* mapTextSnapshotDelta(params) {
75
+ const { currentText, itemId, itemTextById, messageId, sessionId } = params;
76
+ const previous = itemTextById.get(itemId) ?? {
77
+ text: "",
78
+ started: false
79
+ };
80
+ if (!previous.started) yield {
81
+ type: params.startType,
82
+ payload: {
83
+ sessionId,
84
+ messageId
85
+ }
86
+ };
87
+ if (currentText.length > previous.text.length) {
88
+ const delta = currentText.slice(previous.text.length);
89
+ for (const chunk of splitTextDelta(delta)) yield {
90
+ type: params.deltaType,
78
91
  payload: {
79
92
  sessionId,
80
- messageId
93
+ messageId,
94
+ delta: chunk
81
95
  }
82
96
  };
83
- if (currentText.length > previous.text.length) {
84
- const delta = currentText.slice(previous.text.length);
85
- yield {
86
- type: NcpEventType.MessageTextDelta,
87
- payload: {
88
- sessionId,
89
- messageId,
90
- delta
91
- }
92
- };
97
+ }
98
+ itemTextById.set(itemId, {
99
+ text: currentText,
100
+ started: true
101
+ });
102
+ if (params.eventType === "item.completed") yield {
103
+ type: params.endType,
104
+ payload: {
105
+ sessionId,
106
+ messageId
93
107
  }
94
- itemTextById.set(item.id, {
95
- text: currentText,
96
- started: true
108
+ };
109
+ }
110
+ async function* mapCodexItemEvent(params) {
111
+ const { sessionId, messageId, event, itemTextById, toolStateById } = params;
112
+ const { item } = event;
113
+ if (item.type === "agent_message") {
114
+ yield* mapTextSnapshotDelta({
115
+ currentText: item.text ?? "",
116
+ deltaType: NcpEventType.MessageTextDelta,
117
+ endType: NcpEventType.MessageTextEnd,
118
+ eventType: event.type,
119
+ itemId: item.id,
120
+ itemTextById,
121
+ messageId,
122
+ sessionId,
123
+ startType: NcpEventType.MessageTextStart
97
124
  });
98
- if (event.type === "item.completed") yield {
99
- type: NcpEventType.MessageTextEnd,
100
- payload: {
101
- sessionId,
102
- messageId
103
- }
104
- };
105
125
  return;
106
126
  }
107
127
  if (item.type === "reasoning") {
108
- const currentText = item.text ?? "";
109
- const previous = itemTextById.get(item.id) ?? {
110
- text: "",
111
- started: false
112
- };
113
- if (!previous.started) yield {
114
- type: NcpEventType.MessageReasoningStart,
115
- payload: {
116
- sessionId,
117
- messageId
118
- }
119
- };
120
- if (currentText.length > previous.text.length) {
121
- const delta = currentText.slice(previous.text.length);
122
- yield {
123
- type: NcpEventType.MessageReasoningDelta,
124
- payload: {
125
- sessionId,
126
- messageId,
127
- delta
128
- }
129
- };
130
- }
131
- itemTextById.set(item.id, {
132
- text: currentText,
133
- started: true
128
+ yield* mapTextSnapshotDelta({
129
+ currentText: item.text ?? "",
130
+ deltaType: NcpEventType.MessageReasoningDelta,
131
+ endType: NcpEventType.MessageReasoningEnd,
132
+ eventType: event.type,
133
+ itemId: item.id,
134
+ itemTextById,
135
+ messageId,
136
+ sessionId,
137
+ startType: NcpEventType.MessageReasoningStart
134
138
  });
135
- if (event.type === "item.completed") yield {
136
- type: NcpEventType.MessageReasoningEnd,
137
- payload: {
138
- sessionId,
139
- messageId
140
- }
141
- };
142
139
  return;
143
140
  }
144
141
  if (!isToolLikeItem(item)) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/nextclaw-ncp-runtime-codex-sdk",
3
- "version": "0.1.25",
3
+ "version": "0.1.26",
4
4
  "private": false,
5
5
  "description": "Optional NCP runtime adapter backed by OpenAI Codex SDK.",
6
6
  "type": "module",