@skein-js/express 0.8.0 → 0.9.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 +22 -0
- package/dist/index.d.ts +19 -3
- package/dist/index.js +33 -2
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -67,6 +67,25 @@ const { router } = await skeinRouter({ deps: runtime.deps, cors: runtime.cors })
|
|
|
67
67
|
app.use(router);
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
+
## Graphs as plain endpoints (non-chat)
|
|
71
|
+
|
|
72
|
+
For workloads that aren't chat — a classifier, an extractor, a workflow another service calls — there
|
|
73
|
+
is a smaller surface: every graph mounted as `POST /invoke/:graph_id`, where the request body **is**
|
|
74
|
+
the graph input and the response **is** the final state. No threads, assistants, or runs.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { skeinInvokeRouter } from "@skein-js/express";
|
|
78
|
+
import { embedInMemoryGraphs } from "@skein-js/server-kit";
|
|
79
|
+
|
|
80
|
+
const { router } = await skeinInvokeRouter({ deps: embedInMemoryGraphs({ triage }) });
|
|
81
|
+
app.use(router);
|
|
82
|
+
// curl -X POST localhost:2024/invoke/triage -d '{"text":"…"}'
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Send `Accept: text/event-stream` to stream the steps instead. See
|
|
86
|
+
[docs/serving-a-single-graph.md](../../docs/serving-a-single-graph.md) and
|
|
87
|
+
[`examples/invoke-endpoint`](../../examples/invoke-endpoint).
|
|
88
|
+
|
|
70
89
|
## API
|
|
71
90
|
|
|
72
91
|
- **`createExpressServer(options): Promise<SkeinExpressServer>`** — `SkeinExpressServer` =
|
|
@@ -74,6 +93,9 @@ app.use(router);
|
|
|
74
93
|
`"localhost"`, resolves the Node `Server` once bound; `close()` stops the run worker then the HTTP
|
|
75
94
|
server (idempotent).
|
|
76
95
|
- **`skeinRouter(options): Promise<SkeinRouter>`** — `SkeinRouter` = `{ router, runtime }`.
|
|
96
|
+
- **`skeinInvokeRouter(options): Promise<SkeinInvokeRouter>`** — the simplified serving surface
|
|
97
|
+
(`POST /invoke/:graph_id`, body-in / final-state-out). `SkeinInvokeRouter` = `{ router, deps }`;
|
|
98
|
+
options add `prefix` (default `/invoke`) and `streamMode`.
|
|
77
99
|
- **`SkeinRouterOptions`** — common `{ logger?, cors?, warm? }` **plus** either `{ config, importModule? }`
|
|
78
100
|
(in-memory runtime from a `langgraph.json`) **or** `{ deps }` (bring-your-own `ProtocolDeps`).
|
|
79
101
|
`warm: true` eagerly loads graphs at startup; `logger` mounts per-request logging.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ProtocolRuntime, Logger, ProtocolHandlers, ProtocolRequest, ProtocolResponse } from '@skein-js/agent-protocol';
|
|
1
|
+
import { ProtocolRuntime, ProtocolDeps, GraphInvokeOptions, Logger, ProtocolHandlers, ProtocolRequest, ProtocolResponse } from '@skein-js/agent-protocol';
|
|
2
2
|
export { skeinRoutes } from '@skein-js/agent-protocol';
|
|
3
3
|
import { SkeinRuntimeOptions } from '@skein-js/server-kit';
|
|
4
|
-
export { DevStateCounts, DevStateSnapshot, InMemoryRuntimeConfig, LanggraphCorsConfig, ReloadableInMemoryRuntime, corsFromHttpConfig, describeSnapshot, loadInMemoryRuntime, loadReloadableInMemoryRuntime, loadSnapshotIntoStore, readLanggraphDevState, toCorsOptions } from '@skein-js/server-kit';
|
|
4
|
+
export { DevStateCounts, DevStateSnapshot, InMemoryRuntimeConfig, LanggraphCorsConfig, ReloadableInMemoryRuntime, RunWorkerOptions, corsFromHttpConfig, describeSnapshot, loadInMemoryRuntime, loadReloadableInMemoryRuntime, loadSnapshotIntoStore, readLanggraphDevState, toCorsOptions } from '@skein-js/server-kit';
|
|
5
5
|
import { Router, Express, Request, Response } from 'express';
|
|
6
6
|
import { Server } from 'node:http';
|
|
7
7
|
import { CorsOptions } from 'cors';
|
|
@@ -34,6 +34,22 @@ interface SkeinExpressServer {
|
|
|
34
34
|
/** Build an Express server hosting the Agent Protocol, ready to `listen`. */
|
|
35
35
|
declare function createExpressServer(options: SkeinRouterOptions): Promise<SkeinExpressServer>;
|
|
36
36
|
|
|
37
|
+
type SkeinInvokeRouterOptions = SkeinRuntimeOptions & GraphInvokeOptions & {
|
|
38
|
+
/** Path prefix for the endpoint; defaults to `/invoke` (→ `POST /invoke/:graph_id`). */
|
|
39
|
+
prefix?: string;
|
|
40
|
+
};
|
|
41
|
+
interface SkeinInvokeRouter {
|
|
42
|
+
/** Mount on an Express app: `app.use(router)`. */
|
|
43
|
+
router: Router;
|
|
44
|
+
/** The resolved dependencies, so a caller can reuse them (e.g. to also mount `skeinRouter`). */
|
|
45
|
+
deps: ProtocolDeps;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Build a `Router` serving `POST <prefix>/:graph_id`. No assistants are seeded and no background run
|
|
49
|
+
* worker is started — an invoke-only service needs neither.
|
|
50
|
+
*/
|
|
51
|
+
declare function skeinInvokeRouter(options: SkeinInvokeRouterOptions): Promise<SkeinInvokeRouter>;
|
|
52
|
+
|
|
37
53
|
interface HandlerRouterOptions {
|
|
38
54
|
/** Structured logger for unexpected (non-`SkeinHttpError`) faults. */
|
|
39
55
|
logger?: Logger;
|
|
@@ -60,4 +76,4 @@ declare function sendProtocolResponse(response: ProtocolResponse, res: Response)
|
|
|
60
76
|
/** Serialize a caught error onto `res`, using the protocol status when the error carries one. */
|
|
61
77
|
declare function sendErrorResponse(error: unknown, res: Response, logger?: Logger): void;
|
|
62
78
|
|
|
63
|
-
export { type HandlerRouterOptions, type SkeinExpressServer, type SkeinRouter, type SkeinRouterOptions, createExpressServer, createHandlerRouter, sendErrorResponse, sendProtocolResponse, skeinRouter, toProtocolRequest };
|
|
79
|
+
export { type HandlerRouterOptions, type SkeinExpressServer, type SkeinInvokeRouter, type SkeinInvokeRouterOptions, type SkeinRouter, type SkeinRouterOptions, createExpressServer, createHandlerRouter, sendErrorResponse, sendProtocolResponse, skeinInvokeRouter, skeinRouter, toProtocolRequest };
|
package/dist/index.js
CHANGED
|
@@ -122,11 +122,11 @@ function createHandlerRouter(handlers, options = {}) {
|
|
|
122
122
|
|
|
123
123
|
// src/skein-router.ts
|
|
124
124
|
async function skeinRouter(options) {
|
|
125
|
-
const { runtime, cors:
|
|
125
|
+
const { runtime, cors: cors3 } = await resolveProtocolRuntime(options);
|
|
126
126
|
const router = createHandlerRouter(runtime.handlers, {
|
|
127
127
|
logger: options.logger,
|
|
128
128
|
// Explicit option wins; otherwise fall back to the config's `http.cors`, else off.
|
|
129
|
-
cors: options.cors ??
|
|
129
|
+
cors: options.cors ?? cors3 ?? false
|
|
130
130
|
});
|
|
131
131
|
return { router, runtime };
|
|
132
132
|
}
|
|
@@ -180,6 +180,36 @@ async function createExpressServer(options) {
|
|
|
180
180
|
};
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
+
// src/skein-invoke-router.ts
|
|
184
|
+
import {
|
|
185
|
+
createGraphInvokeHandler,
|
|
186
|
+
graphInvokeRoutes
|
|
187
|
+
} from "@skein-js/agent-protocol";
|
|
188
|
+
import { resolveRuntimeDeps } from "@skein-js/server-kit";
|
|
189
|
+
import cors2 from "cors";
|
|
190
|
+
import express3 from "express";
|
|
191
|
+
async function skeinInvokeRouter(options) {
|
|
192
|
+
const { deps, cors: corsFromConfig } = await resolveRuntimeDeps(options);
|
|
193
|
+
const invoke = createGraphInvokeHandler(deps, { streamMode: options.streamMode });
|
|
194
|
+
const router = express3.Router();
|
|
195
|
+
const corsSetting = options.cors ?? corsFromConfig ?? false;
|
|
196
|
+
if (corsSetting) router.use(cors2(corsSetting === true ? { origin: true } : corsSetting));
|
|
197
|
+
router.use(express3.json());
|
|
198
|
+
for (const binding of graphInvokeRoutes(options.prefix)) {
|
|
199
|
+
router[binding.method](binding.path, async (req, res) => {
|
|
200
|
+
const disconnected = new AbortController();
|
|
201
|
+
res.once("close", () => disconnected.abort(new Error("client disconnected")));
|
|
202
|
+
try {
|
|
203
|
+
const request = { ...toProtocolRequest(req), signal: disconnected.signal };
|
|
204
|
+
await sendProtocolResponse(await invoke(request), res);
|
|
205
|
+
} catch (error) {
|
|
206
|
+
sendErrorResponse(error, res, options.logger);
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
return { router, deps };
|
|
211
|
+
}
|
|
212
|
+
|
|
183
213
|
// src/index.ts
|
|
184
214
|
import {
|
|
185
215
|
loadInMemoryRuntime,
|
|
@@ -201,6 +231,7 @@ export {
|
|
|
201
231
|
readLanggraphDevState,
|
|
202
232
|
sendErrorResponse,
|
|
203
233
|
sendProtocolResponse,
|
|
234
|
+
skeinInvokeRouter,
|
|
204
235
|
skeinRouter,
|
|
205
236
|
skeinRoutes2 as skeinRoutes,
|
|
206
237
|
toCorsOptions,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skein-js/express",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Express adapter for skein-js — mount the Agent Protocol on an Express Router.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Maina Wycliffe <wmmaina7@gmail.com>",
|
|
@@ -41,10 +41,10 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"cors": "^2.8.5",
|
|
44
|
-
"@skein-js/
|
|
45
|
-
"@skein-js/
|
|
46
|
-
"@skein-js/
|
|
47
|
-
"@skein-js/
|
|
44
|
+
"@skein-js/agent-protocol": "0.9.1",
|
|
45
|
+
"@skein-js/config": "0.9.1",
|
|
46
|
+
"@skein-js/core": "0.9.1",
|
|
47
|
+
"@skein-js/server-kit": "0.9.1"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"@langchain/langgraph": "^1.4.0",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"@types/cors": "^2.8.17",
|
|
57
57
|
"@types/express": "^5.0.0",
|
|
58
58
|
"express": "^5.2.1",
|
|
59
|
-
"@skein-js/storage-memory": "0.
|
|
59
|
+
"@skein-js/storage-memory": "0.9.1"
|
|
60
60
|
},
|
|
61
61
|
"publishConfig": {
|
|
62
62
|
"access": "public"
|