@vincemakes/kiso-server 0.41.2 → 0.42.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/README.md CHANGED
@@ -96,5 +96,8 @@ 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.
100
-
99
+ `authorize` is required: there is no default that allows. `prepareInput`
100
+ may answer a request itself — write the product's own status and body to
101
+ the response it receives and return `{ handled: true }`; nothing is opened
102
+ and no run starts (a gate, a quota, an attachment check, in the product's
103
+ own shape).
package/dist/http.d.ts CHANGED
@@ -33,14 +33,23 @@ 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
- /** The product's turn preparation; default: `body.input` as given. */
37
- readonly prepareInput?: (body: Readonly<Record<string, unknown>>, req: IncomingMessage, sessionId: string) => WireInput | Promise<WireInput>;
36
+ /** The product's turn preparation; default: `body.input` as given.
37
+ * 0.42.0: it may instead ANSWER the request itself — write the
38
+ * product's own status and body to `res` and return `{ handled: true }`;
39
+ * the handler then returns without opening a run, a session, or a 400
40
+ * (a gate, a quota, an attachment check, an empty message — the
41
+ * product's refusals in the product's shape). */
42
+ readonly prepareInput?: (body: Readonly<Record<string, unknown>>, req: IncomingMessage, sessionId: string, res: ServerResponse) => WireInput | Handled | Promise<WireInput | Handled>;
38
43
  readonly projection?: ProjectionOptions;
39
44
  /** `: keepalive` comments on an idle stream. Default 15 s; 0 disables. */
40
45
  readonly keepaliveMs?: number;
41
46
  /** Request-body cap in bytes. Default 1 MiB. */
42
47
  readonly bodyLimit?: number;
43
48
  }
49
+ /** What `prepareInput` returns when it answered the request itself. */
50
+ export interface Handled {
51
+ readonly handled: true;
52
+ }
44
53
  export interface HttpHandler {
45
54
  /** True when the request was an agent route and has been answered. */
46
55
  readonly handle: (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
package/dist/http.js CHANGED
@@ -54,9 +54,9 @@ export function createHttpHandler(service, options) {
54
54
  throw new BadRequest("body must be a JSON object");
55
55
  return parsed;
56
56
  };
57
- const inputOf = async (body, req, sessionId) => {
57
+ const inputOf = async (body, req, sessionId, res) => {
58
58
  if (options.prepareInput !== undefined)
59
- return options.prepareInput(body, req, sessionId);
59
+ return options.prepareInput(body, req, sessionId, res);
60
60
  const input = body["input"];
61
61
  if (typeof input === "string") {
62
62
  if (input.trim() === "")
@@ -191,7 +191,9 @@ export function createHttpHandler(service, options) {
191
191
  if (action === "run" || action === "resume") {
192
192
  let handle;
193
193
  if (action === "run") {
194
- const input = await inputOf(body, req, sessionId);
194
+ const input = await inputOf(body, req, sessionId, res);
195
+ if (isHandled(input))
196
+ return true; // the product answered; nothing opened
195
197
  const source = body["source"];
196
198
  handle = await service.run(sessionId, input, {
197
199
  ...(source === "user" || source === "suggestion" || source === "tool_result" ? { source: source } : {}),
@@ -245,6 +247,9 @@ export function createHttpHandler(service, options) {
245
247
  };
246
248
  return { handle };
247
249
  }
250
+ function isHandled(v) {
251
+ return typeof v === "object" && v !== null && !Array.isArray(v) && v.handled === true;
252
+ }
248
253
  class BadRequest extends Error {
249
254
  constructor(message) {
250
255
  super(message);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vincemakes/kiso-server",
3
- "version": "0.41.2",
3
+ "version": "0.42.1",
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.41.2",
29
- "@vincemakes/kiso-protocol": "0.41.2",
30
- "@vincemakes/kiso-runtime": "0.41.2"
28
+ "@vincemakes/kiso-core": "0.42.1",
29
+ "@vincemakes/kiso-protocol": "0.42.1",
30
+ "@vincemakes/kiso-runtime": "0.42.1"
31
31
  },
32
32
  "devDependencies": {
33
- "@vincemakes/kiso-evals": "0.41.2",
33
+ "@vincemakes/kiso-evals": "0.42.1",
34
34
  "@types/node": "^26.1.2",
35
35
  "typescript": "^5.7.2",
36
36
  "vitest": "^3.0.0"