@vincemakes/kiso-server 0.41.2 → 0.42.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 +5 -2
- package/dist/http.d.ts +11 -2
- package/dist/http.js +8 -3
- package/package.json +5 -5
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
|
-
|
|
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.
|
|
3
|
+
"version": "0.42.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.
|
|
29
|
-
"@vincemakes/kiso-protocol": "0.
|
|
30
|
-
"@vincemakes/kiso-runtime": "0.
|
|
28
|
+
"@vincemakes/kiso-core": "0.42.0",
|
|
29
|
+
"@vincemakes/kiso-protocol": "0.42.0",
|
|
30
|
+
"@vincemakes/kiso-runtime": "0.42.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@vincemakes/kiso-evals": "0.
|
|
33
|
+
"@vincemakes/kiso-evals": "0.42.0",
|
|
34
34
|
"@types/node": "^26.1.2",
|
|
35
35
|
"typescript": "^5.7.2",
|
|
36
36
|
"vitest": "^3.0.0"
|