@leoustc/ai-runner-codex 0.1.1 → 0.1.2

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/AGENTS.md CHANGED
@@ -141,6 +141,11 @@ For each valid payload, reply to the Hub as:
141
141
  { "requestId": "...", "type": "end", "name": "agent-name" }
142
142
  ```
143
143
 
144
+ Large Codex reply text must be split into multiple `message` frames before the
145
+ matching `end`. Each `message.text` chunk should be at most 8 KiB encoded as
146
+ UTF-8. Include `message.chunk` metadata with `index`, `total`, and `maxBytes`
147
+ when a reply has more than one chunk.
148
+
144
149
  Errors use:
145
150
 
146
151
  ```json
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leoustc/ai-runner-codex",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "private": false,
5
5
  "description": "Codex app-server backed Agent Runner Hub CLI connector",
6
6
  "license": "MIT",
package/src/hub.js CHANGED
@@ -1,4 +1,4 @@
1
- import { codexRequest, codexText, heartbeat, isRoomPayload, registration, reply } from "./protocol.js";
1
+ import { codexRequest, codexText, heartbeat, isRoomPayload, messageReplies, registration, reply } from "./protocol.js";
2
2
  import { requestCodex } from "./codex.js";
3
3
  import { ensureCodexLogin, isCodexAuthError } from "./login.js";
4
4
 
@@ -94,10 +94,10 @@ export class HubClient {
94
94
  try {
95
95
  const response = await this.requestCodexWithLogin(value);
96
96
  const text = codexText(response) || "Codex returned no text.";
97
- this.send(reply(value, this.config, "message", {
97
+ this.sendMessages(value, {
98
98
  model: this.config.model,
99
99
  text,
100
- }));
100
+ });
101
101
  } catch (error) {
102
102
  this.send(reply(value, this.config, "error", {
103
103
  error: error instanceof Error ? error.message : String(error),
@@ -118,10 +118,10 @@ export class HubClient {
118
118
  }
119
119
 
120
120
  await ensureCodexLogin(this.config, this.log, async (text) => {
121
- this.send(reply(value, this.config, "message", {
121
+ this.sendMessages(value, {
122
122
  codexLogin: true,
123
123
  text,
124
- }));
124
+ });
125
125
  });
126
126
 
127
127
  return await requestCodex(this.config, request);
@@ -210,6 +210,12 @@ export class HubClient {
210
210
  }
211
211
  }
212
212
 
213
+ sendMessages(payload, message) {
214
+ for (const value of messageReplies(payload, this.config, message)) {
215
+ this.send(value);
216
+ }
217
+ }
218
+
213
219
  sendNow(value) {
214
220
  if (this.socket?.readyState !== WebSocket.OPEN) {
215
221
  return false;
package/src/protocol.js CHANGED
@@ -36,6 +36,30 @@ export function reply(payload, config, type, message) {
36
36
  };
37
37
  }
38
38
 
39
+ export function messageReplies(payload, config, message, maxBytes = 8 * 1024) {
40
+ if (typeof message?.text !== "string") {
41
+ return [reply(payload, config, "message", message)];
42
+ }
43
+
44
+ const chunks = splitUtf8Chunks(message.text, maxBytes);
45
+
46
+ return chunks.map((chunk, index) =>
47
+ reply(payload, config, "message", {
48
+ ...message,
49
+ text: chunk,
50
+ ...(chunks.length > 1
51
+ ? {
52
+ chunk: {
53
+ index,
54
+ total: chunks.length,
55
+ maxBytes,
56
+ },
57
+ }
58
+ : {}),
59
+ }),
60
+ );
61
+ }
62
+
39
63
  export function codexRequest(payload, config) {
40
64
  return {
41
65
  requestId: payload.requestId,
@@ -80,3 +104,28 @@ function parseMessage(message) {
80
104
  }
81
105
  }
82
106
 
107
+ function splitUtf8Chunks(text, maxBytes) {
108
+ const encoder = new TextEncoder();
109
+ const chunks = [];
110
+ let current = "";
111
+ let currentBytes = 0;
112
+
113
+ for (const character of text) {
114
+ const characterBytes = encoder.encode(character).byteLength;
115
+
116
+ if (current && currentBytes + characterBytes > maxBytes) {
117
+ chunks.push(current);
118
+ current = "";
119
+ currentBytes = 0;
120
+ }
121
+
122
+ current += character;
123
+ currentBytes += characterBytes;
124
+ }
125
+
126
+ if (current || chunks.length === 0) {
127
+ chunks.push(current);
128
+ }
129
+
130
+ return chunks;
131
+ }