@nextclaw/ncp-http-agent-server 0.3.20 → 0.3.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +65 -1
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -19,7 +19,7 @@ async function parseRequestEnvelope(request) {
19
19
  try {
20
20
  const payload = await request.json();
21
21
  if (!isRecord$1(payload)) return null;
22
- if (typeof payload.sessionId !== "string" || !payload.sessionId.trim()) return null;
22
+ if (Object.prototype.hasOwnProperty.call(payload, "sessionId") && (typeof payload.sessionId !== "string" || !payload.sessionId.trim())) return null;
23
23
  if (!isRecord$1(payload.message)) return null;
24
24
  return payload;
25
25
  } catch {
@@ -246,6 +246,61 @@ async function* createForwardSseEvents(options) {
246
246
  stop();
247
247
  }
248
248
  }
249
+ function createSendStreamResponse(options) {
250
+ const { requestSignal } = options;
251
+ return buildSseResponse(createSseEventStream(createSendStreamSseEvents(options), requestSignal));
252
+ }
253
+ async function* createSendStreamSseEvents(options) {
254
+ const { endpoint, envelope, requestSignal, timeoutMs } = options;
255
+ const queue = createAsyncQueue();
256
+ let timeoutId = null;
257
+ let unsubscribe = null;
258
+ let stopped = false;
259
+ let sessionId = envelope.sessionId?.trim() || null;
260
+ const push = (frame) => {
261
+ if (!stopped) queue.push(frame);
262
+ };
263
+ const stop = () => {
264
+ if (stopped) return;
265
+ stopped = true;
266
+ if (timeoutId) {
267
+ clearTimeout(timeoutId);
268
+ timeoutId = null;
269
+ }
270
+ if (unsubscribe) {
271
+ unsubscribe();
272
+ unsubscribe = null;
273
+ }
274
+ requestSignal.removeEventListener("abort", stop);
275
+ queue.close();
276
+ };
277
+ requestSignal.addEventListener("abort", stop, { once: true });
278
+ if (timeoutMs !== null) timeoutId = setTimeout(() => {
279
+ push(toErrorFrame("TIMEOUT", "NCP HTTP send stream timed out before terminal event."));
280
+ stop();
281
+ }, timeoutMs);
282
+ unsubscribe = endpoint.subscribe((event) => {
283
+ const payload = "payload" in event ? event.payload : null;
284
+ const eventSessionId = payload && typeof payload === "object" && "sessionId" in payload && typeof payload.sessionId === "string" ? payload.sessionId : null;
285
+ if (sessionId && eventSessionId && eventSessionId !== sessionId) return;
286
+ if (!sessionId && eventSessionId) sessionId = eventSessionId;
287
+ push(toNcpEventFrame(event));
288
+ });
289
+ endpoint.emit({
290
+ type: NcpEventType.MessageRequest,
291
+ payload: envelope
292
+ }).catch((error) => {
293
+ push(toErrorFrame("EMIT_FAILED", errorMessage(error)));
294
+ stop();
295
+ }).finally(() => {
296
+ if (!requestSignal.aborted) queueMicrotask(stop);
297
+ });
298
+ try {
299
+ for await (const frame of queue.iterable) yield frame;
300
+ } finally {
301
+ stop();
302
+ }
303
+ }
249
304
  function createLiveStreamResponse(options) {
250
305
  const { signal } = options;
251
306
  return buildSseResponse(createSseEventStream(createLiveStreamSseEvents(options), signal));
@@ -284,6 +339,12 @@ var NcpHttpAgentController = class {
284
339
  message: "Invalid NCP request envelope."
285
340
  }
286
341
  }, 400);
342
+ if (acceptsEventStream(request)) return createSendStreamResponse({
343
+ endpoint: agentClientEndpoint,
344
+ envelope,
345
+ requestSignal: request.signal,
346
+ timeoutMs: this.options.timeoutMs
347
+ });
287
348
  await agentClientEndpoint.send(envelope);
288
349
  return jsonResponse({ ok: true });
289
350
  }
@@ -327,6 +388,9 @@ var NcpHttpAgentController = class {
327
388
  return jsonResponse({ ok: true });
328
389
  }
329
390
  };
391
+ function acceptsEventStream(request) {
392
+ return request.headers.get("accept")?.includes("text/event-stream") ?? false;
393
+ }
330
394
  //#endregion
331
395
  //#region src/router.ts
332
396
  function createNcpHttpAgentRouter(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/ncp-http-agent-server",
3
- "version": "0.3.20",
3
+ "version": "0.3.22",
4
4
  "private": false,
5
5
  "description": "HTTP/SSE server transport adapter for NCP agent endpoints.",
6
6
  "type": "module",
@@ -16,7 +16,7 @@
16
16
  ],
17
17
  "dependencies": {
18
18
  "hono": "^4.9.8",
19
- "@nextclaw/ncp": "0.5.8"
19
+ "@nextclaw/ncp": "0.5.10"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@types/node": "^20.17.6",