@vincemakes/kiso-server 0.42.3 → 0.44.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/README.md CHANGED
@@ -88,7 +88,7 @@ factory. The service is the part that was the same in every host.
88
88
 
89
89
  ## The HTTP + SSE transport — `@vincemakes/kiso-server/http`
90
90
 
91
- `createHttpHandler(service, { authorize, augment?, prepareInput?, projection?, keepaliveMs? })`
91
+ `createHttpHandler(service, { authorize, augment?, frames?, prepareInput?, projection?, keepaliveMs? })`
92
92
  returns a `handle(req, res)` a host mounts in front of its own routes; it
93
93
  answers the agent routes under `prefix` (default `/v1/sessions`) and
94
94
  returns false for everything else. Status codes and framing are decided
@@ -96,8 +96,18 @@ here once: `id: <seq>` / `event: <type>` / `data: <WireEvent>`, an `: open`
96
96
  preamble, `Last-Event-ID` and `?after`, a keepalive; `in_flight` and
97
97
  `open_run` are 409, `draining` 503, `forbidden` 403. Wire events are the
98
98
  projection in `@vincemakes/kiso-protocol` — never the durable event.
99
- `authorize` is required: there is no default that allows. `prepareInput`
99
+ `authorize` is required: there is no default that allows. `openRun`, `openRuns`, and `events()` on a session the service has not opened read the durable store and THROW when its log is unreadable; they never disguise corruption as an empty result — call them inside a try/catch in a host callback. `highWater()` is process-local and does not read the store. `prepareInput`
100
100
  may answer a request itself — write the product's own status and body to
101
101
  the response it receives and return `{ handled: true }`; nothing is opened
102
102
  and no run starts (a gate, a quota, an attachment check, in the product's
103
103
  own shape).
104
+
105
+ `frames` (0.43.0) is the host's own frame source: called once per open
106
+ stream with a `push`, and whatever the host pushes — a long tool's
107
+ progress, a retry banner — is written on the same ordered chain as the
108
+ wire events, on `/run?stream=1` and on `GET /events` alike, so a frame
109
+ pushed between two events lands between them. `augment` fires only
110
+ beside a durable event; `frames` is for the minutes in which nothing
111
+ durable happens. The function it returns is called when the stream
112
+ ends. Nothing pushed is durable: a client that reconnects sees the
113
+ events again, never these frames.
package/dist/http.d.ts CHANGED
@@ -33,6 +33,15 @@ export interface HttpHandlerOptions {
33
33
  readonly authorize: (req: IncomingMessage, sessionId: string) => Promise<boolean> | boolean;
34
34
  /** Frames a product adds beside a wire event on the same connection. */
35
35
  readonly augment?: (event: Event, sessionId: string) => readonly WireFrame[] | Promise<readonly WireFrame[]>;
36
+ /** 0.43.0 (#4): the host's own frame source. Called once per open
37
+ * stream with a `push`; whatever the host pushes — a tool's progress,
38
+ * a retry banner — is written on the SAME ordered chain as the wire
39
+ * events, so a frame pushed between two events lands between them,
40
+ * on `/run?stream=1` and on `GET /events` alike. The returned function
41
+ * is called when the stream ends; a push after that is dropped.
42
+ * Nothing here is durable: a reconnecting client sees events again,
43
+ * never these frames. */
44
+ readonly frames?: (sessionId: string, push: (frame: WireFrame) => void) => (() => void) | void;
36
45
  /** The product's turn preparation; default: `body.input` as given.
37
46
  * 0.42.0: it may instead ANSWER the request itself — write the
38
47
  * product's own status and body to `res` and return `{ handled: true }`;
package/dist/http.js CHANGED
@@ -113,6 +113,15 @@ export function createHttpHandler(service, options) {
113
113
  res.write(text);
114
114
  });
115
115
  });
116
+ // 0.43.0 (#4): the host's frames ride the same chain — ordered with
117
+ // the events, dropped once the stream has ended.
118
+ const push = (frame) => {
119
+ chain = chain.then(() => {
120
+ if (!closed)
121
+ res.write(`event: ${frame.event}\ndata: ${JSON.stringify(frame.data)}\n\n`);
122
+ });
123
+ };
124
+ const stopFrames = options.frames?.(sessionId, push) ?? undefined;
116
125
  const keepalive = keepaliveMs > 0 ? setInterval(() => res.write(": keepalive\n\n"), keepaliveMs) : undefined;
117
126
  keepalive?.unref();
118
127
  const end = () => {
@@ -121,6 +130,7 @@ export function createHttpHandler(service, options) {
121
130
  closed = true;
122
131
  if (keepalive !== undefined)
123
132
  clearInterval(keepalive);
133
+ stopFrames?.();
124
134
  unsubscribe();
125
135
  };
126
136
  req.on("close", end);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vincemakes/kiso-server",
3
- "version": "0.42.3",
3
+ "version": "0.44.0",
4
4
  "description": "kiso server — the hosted-session service: many durable sessions in one process, observers with exact replay from a sequence number, approve / abort / resume routed to the right run, drain and close. No transport; a product supplies the agent factory.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,12 +25,12 @@
25
25
  "test": "vitest run"
26
26
  },
27
27
  "dependencies": {
28
- "@vincemakes/kiso-core": "0.42.3",
29
- "@vincemakes/kiso-protocol": "0.42.3",
30
- "@vincemakes/kiso-runtime": "0.42.3"
28
+ "@vincemakes/kiso-core": "0.44.0",
29
+ "@vincemakes/kiso-protocol": "0.44.0",
30
+ "@vincemakes/kiso-runtime": "0.44.0"
31
31
  },
32
32
  "devDependencies": {
33
- "@vincemakes/kiso-evals": "0.42.3",
33
+ "@vincemakes/kiso-evals": "0.44.0",
34
34
  "@types/node": "^26.1.2",
35
35
  "typescript": "^5.7.2",
36
36
  "vitest": "^3.0.0"