@m6d/cortex-server 1.7.0 → 2.0.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 +8 -3
- package/contracts/README.md +23 -0
- package/contracts/graph/embed.ts +50 -0
- package/{src → contracts}/graph/helpers.ts +4 -10
- package/{src → contracts}/graph/neo4j.ts +14 -27
- package/contracts/graph/schema.ts +65 -0
- package/{src → contracts}/graph/types.ts +2 -29
- package/contracts/graph.ts +36 -0
- package/contracts/runtime.ts +208 -0
- package/contracts/wire.ts +143 -0
- package/dist/contracts/graph/embed.d.ts +22 -0
- package/dist/{src → contracts}/graph/helpers.d.ts +14 -12
- package/dist/{src → contracts}/graph/neo4j.d.ts +5 -5
- package/dist/contracts/graph/schema.d.ts +62 -0
- package/dist/{src → contracts}/graph/types.d.ts +1 -1
- package/dist/contracts/graph.d.ts +14 -0
- package/dist/contracts/runtime.d.ts +278 -0
- package/dist/contracts/wire.d.ts +120 -0
- package/dist/index.d.ts +1 -1
- package/dist/src/lib/adapters/database/index.d.ts +61 -0
- package/dist/src/lib/adapters/database/message-content.d.ts +30 -0
- package/dist/src/lib/adapters/database/mssql/attachments.d.ts +100 -0
- package/dist/src/lib/adapters/database/mssql/client.d.ts +8 -0
- package/dist/src/lib/adapters/database/mssql/index.d.ts +194 -0
- package/dist/src/lib/adapters/database/mssql/llm-requests.d.ts +17 -0
- package/dist/src/lib/adapters/database/mssql/messages.d.ts +37 -0
- package/dist/src/lib/adapters/database/mssql/threads.d.ts +50 -0
- package/dist/src/lib/adapters/database/postgres/attachments.d.ts +113 -0
- package/dist/src/lib/adapters/database/postgres/client.d.ts +8 -0
- package/dist/src/lib/adapters/database/postgres/index.d.ts +207 -0
- package/dist/src/lib/adapters/database/postgres/llm-requests.d.ts +17 -0
- package/dist/src/lib/adapters/database/postgres/messages.d.ts +37 -0
- package/dist/src/lib/adapters/database/postgres/threads.d.ts +50 -0
- package/{src/adapters/storage.ts → dist/src/lib/adapters/storage/index.d.ts} +1 -1
- package/dist/src/{adapters → lib/adapters/storage}/minio.d.ts +1 -1
- package/dist/src/lib/ai/active-runs.d.ts +63 -0
- package/dist/src/lib/ai/attachments.d.ts +30 -0
- package/dist/src/lib/ai/backend-url.d.ts +16 -0
- package/dist/src/lib/ai/cc-runtime.d.ts +61 -0
- package/dist/src/lib/ai/commit-gate.d.ts +21 -0
- package/dist/src/{ai → lib/ai}/context/builder.d.ts +6 -7
- package/dist/src/lib/ai/context/compression-middleware.d.ts +15 -0
- package/dist/src/lib/ai/context/compressor.d.ts +7 -0
- package/dist/src/lib/ai/context/intra-turn-compressor.d.ts +24 -0
- package/dist/src/lib/ai/context/optimize-thread-context.d.ts +9 -0
- package/dist/src/lib/ai/context/summarizer.d.ts +5 -0
- package/dist/src/{ai → lib/ai}/context/token-estimator.d.ts +5 -8
- package/dist/src/{ai → lib/ai}/context/types.d.ts +2 -0
- package/dist/src/{ai → lib/ai}/fetch.d.ts +1 -1
- package/dist/src/lib/ai/finish-turn.d.ts +23 -0
- package/dist/src/lib/ai/helpers.d.ts +38 -0
- package/dist/src/lib/ai/index.d.ts +7 -0
- package/dist/src/lib/ai/inspector.d.ts +41 -0
- package/dist/src/lib/ai/interceptors/request-interceptor.d.ts +13 -0
- package/dist/src/{ai → lib/ai}/prompt.d.ts +5 -4
- package/dist/src/lib/ai/redis-runs.d.ts +41 -0
- package/dist/src/lib/ai/redis-stream-log.d.ts +39 -0
- package/dist/src/lib/ai/tools/execute-code.tool.d.ts +18 -0
- package/dist/src/lib/ai/tools/query-graph.tool.d.ts +13 -0
- package/dist/src/lib/ai/tools/read-attachment.tool.d.ts +21 -0
- package/dist/src/lib/ai/tools/search-common.d.ts +17 -0
- package/dist/src/lib/ai/tools/search-knowledge.tool.d.ts +15 -0
- package/dist/src/lib/ai/tools/search-services.tool.d.ts +12 -0
- package/dist/src/lib/ai/tools/search-tools.tool.d.ts +12 -0
- package/dist/src/lib/ai/turn-tools.d.ts +39 -0
- package/dist/src/lib/ai/vision/rasterize-pdf.d.ts +26 -0
- package/dist/src/lib/ai/vision/rasterize-pdf.worker.d.ts +1 -0
- package/dist/src/lib/ai/vision/vision-reader.d.ts +45 -0
- package/dist/src/lib/cc/client.d.ts +183 -0
- package/dist/src/lib/cc/config-cache.d.ts +20 -0
- package/dist/src/lib/cc/format.d.ts +23 -0
- package/dist/src/lib/cc/registry.d.ts +34 -0
- package/dist/src/lib/cc/types.d.ts +27 -0
- package/dist/src/lib/config.d.ts +170 -0
- package/dist/src/lib/db/drizzle.config.mssql.d.ts +2 -0
- package/dist/src/lib/db/drizzle.config.pg.d.ts +2 -0
- package/dist/src/lib/db/migrate.d.ts +7 -0
- package/dist/src/{db/schema.d.ts → lib/db/schema.mssql.d.ts} +236 -24
- package/dist/src/lib/db/schema.pg.d.ts +546 -0
- package/dist/src/{factory.d.ts → lib/factory.d.ts} +2 -12
- package/dist/src/lib/graph/index.d.ts +10 -0
- package/dist/src/{graph → lib/graph}/resolver.d.ts +2 -3
- package/dist/src/{index.d.ts → lib/index.d.ts} +3 -4
- package/dist/src/lib/redis.d.ts +19 -0
- package/dist/src/{routes → lib/routes}/chat.d.ts +1 -1
- package/dist/src/{routes → lib/routes}/files.d.ts +1 -1
- package/dist/src/lib/routes/owned-thread.d.ts +17 -0
- package/dist/src/{routes → lib/routes}/threads.d.ts +1 -1
- package/dist/src/{routes → lib/routes}/ws.d.ts +1 -1
- package/dist/src/lib/types.d.ts +58 -0
- package/dist/src/{ws → lib/ws}/connections.d.ts +2 -1
- package/index.ts +1 -1
- package/package.json +35 -15
- package/src/lib/adapters/database/index.ts +78 -0
- package/src/lib/adapters/database/message-content.ts +39 -0
- package/src/lib/adapters/database/mssql/attachments.ts +90 -0
- package/src/lib/adapters/database/mssql/client.ts +11 -0
- package/src/lib/adapters/database/mssql/index.ts +23 -0
- package/src/lib/adapters/database/mssql/llm-requests.ts +43 -0
- package/src/lib/adapters/database/mssql/messages.ts +92 -0
- package/src/lib/adapters/database/mssql/threads.ts +83 -0
- package/src/lib/adapters/database/postgres/attachments.ts +88 -0
- package/src/lib/adapters/database/postgres/client.ts +11 -0
- package/src/lib/adapters/database/postgres/index.ts +23 -0
- package/src/lib/adapters/database/postgres/llm-requests.ts +45 -0
- package/src/lib/adapters/database/postgres/messages.ts +92 -0
- package/src/lib/adapters/database/postgres/threads.ts +84 -0
- package/{dist/src/adapters/storage.d.ts → src/lib/adapters/storage/index.ts} +1 -1
- package/src/{adapters → lib/adapters/storage}/minio.ts +7 -6
- package/src/lib/ai/active-runs.ts +157 -0
- package/src/lib/ai/attachments.ts +144 -0
- package/src/lib/ai/backend-url.ts +27 -0
- package/src/lib/ai/cc-runtime.ts +63 -0
- package/src/lib/ai/commit-gate.ts +116 -0
- package/src/{ai → lib/ai}/context/builder.ts +12 -14
- package/src/lib/ai/context/compression-middleware.ts +44 -0
- package/src/lib/ai/context/compressor.ts +267 -0
- package/src/lib/ai/context/intra-turn-compressor.ts +181 -0
- package/src/lib/ai/context/optimize-thread-context.ts +50 -0
- package/src/lib/ai/context/summarizer.ts +48 -0
- package/src/lib/ai/context/token-estimator.ts +65 -0
- package/src/{ai → lib/ai}/context/types.ts +4 -1
- package/src/{ai → lib/ai}/fetch.ts +10 -5
- package/src/lib/ai/finish-turn.ts +75 -0
- package/src/lib/ai/helpers.ts +100 -0
- package/src/lib/ai/index.ts +408 -0
- package/src/lib/ai/inspector.ts +112 -0
- package/src/lib/ai/interceptors/request-interceptor.ts +89 -0
- package/src/lib/ai/prompt.ts +355 -0
- package/src/lib/ai/redis-runs.ts +167 -0
- package/src/lib/ai/redis-stream-log.ts +219 -0
- package/src/lib/ai/tools/execute-code.tool.ts +267 -0
- package/src/{ai → lib/ai}/tools/query-graph.tool.ts +7 -8
- package/src/lib/ai/tools/read-attachment.tool.ts +59 -0
- package/src/lib/ai/tools/search-common.ts +15 -0
- package/src/lib/ai/tools/search-knowledge.tool.ts +33 -0
- package/src/lib/ai/tools/search-services.tool.ts +31 -0
- package/src/lib/ai/tools/search-tools.tool.ts +29 -0
- package/src/lib/ai/turn-tools.ts +154 -0
- package/src/lib/ai/vision/rasterize-pdf.ts +69 -0
- package/src/lib/ai/vision/rasterize-pdf.worker.ts +81 -0
- package/src/lib/ai/vision/vision-reader.ts +130 -0
- package/src/{auth → lib/auth}/middleware.ts +12 -3
- package/src/lib/cc/client.ts +273 -0
- package/src/lib/cc/config-cache.ts +32 -0
- package/src/lib/cc/format.ts +96 -0
- package/src/lib/cc/registry.ts +62 -0
- package/src/lib/cc/types.ts +44 -0
- package/src/lib/config.ts +212 -0
- package/src/lib/db/drizzle.config.mssql.ts +9 -0
- package/src/lib/db/drizzle.config.pg.ts +9 -0
- package/src/lib/db/migrate.ts +56 -0
- package/src/{db/migrations/20260309012148_cloudy_maria_hill → lib/db/migrations/mssql/20260326231647_nice_speedball}/migration.sql +12 -0
- package/src/{db/migrations/20260309012148_cloudy_maria_hill → lib/db/migrations/mssql/20260326231647_nice_speedball}/snapshot.json +106 -1
- package/src/lib/db/migrations/mssql/20260729092726_talented_wilson_fisk/migration.sql +20 -0
- package/src/lib/db/migrations/mssql/20260729092726_talented_wilson_fisk/snapshot.json +497 -0
- package/src/lib/db/migrations/mssql/20260801003652_perpetual_blue_shield/migration.sql +1 -0
- package/src/lib/db/migrations/mssql/20260801003652_perpetual_blue_shield/snapshot.json +516 -0
- package/src/lib/db/migrations/mssql/20260812174642_user_id_text/migration.sql +2 -0
- package/src/lib/db/migrations/mssql/20260812174642_user_id_text/snapshot.json +516 -0
- package/src/lib/db/migrations/pg/20260801084117_thick_ben_grimm/migration.sql +53 -0
- package/src/lib/db/migrations/pg/20260801084117_thick_ben_grimm/snapshot.json +584 -0
- package/src/lib/db/migrations/pg/20260812174622_user_id_text/migration.sql +2 -0
- package/src/lib/db/migrations/pg/20260812174622_user_id_text/snapshot.json +584 -0
- package/src/lib/db/schema.mssql.ts +94 -0
- package/src/lib/db/schema.pg.ts +95 -0
- package/src/lib/factory.ts +127 -0
- package/src/lib/graph/index.ts +19 -0
- package/src/lib/graph/resolver.ts +387 -0
- package/src/{index.ts → lib/index.ts} +13 -5
- package/src/lib/redis.ts +44 -0
- package/src/lib/routes/chat.ts +115 -0
- package/src/lib/routes/files.ts +129 -0
- package/src/lib/routes/owned-thread.ts +17 -0
- package/src/{routes → lib/routes}/threads.ts +22 -31
- package/src/{routes → lib/routes}/ws.ts +9 -3
- package/src/lib/types.ts +76 -0
- package/src/{ws → lib/ws}/connections.ts +9 -1
- package/tsconfig.json +48 -0
- package/dist/src/adapters/database.d.ts +0 -30
- package/dist/src/adapters/mssql.d.ts +0 -3
- package/dist/src/ai/active-streams.d.ts +0 -14
- package/dist/src/ai/context/compressor.d.ts +0 -7
- package/dist/src/ai/context/index.d.ts +0 -15
- package/dist/src/ai/context/summarizer.d.ts +0 -5
- package/dist/src/ai/helpers.d.ts +0 -5
- package/dist/src/ai/index.d.ts +0 -4
- package/dist/src/ai/interceptors/request-interceptor.d.ts +0 -12
- package/dist/src/ai/tools/call-endpoint.tool.d.ts +0 -7
- package/dist/src/ai/tools/capture-files.tool.d.ts +0 -6
- package/dist/src/ai/tools/execute-code.tool.d.ts +0 -4
- package/dist/src/ai/tools/query-graph.tool.d.ts +0 -5
- package/dist/src/cli/extract-endpoints.d.ts +0 -6
- package/dist/src/config.d.ts +0 -165
- package/dist/src/db/migrate.d.ts +0 -1
- package/dist/src/graph/expand-domains.d.ts +0 -2
- package/dist/src/graph/generate-cypher.d.ts +0 -22
- package/dist/src/graph/index.d.ts +0 -11
- package/dist/src/graph/seed.d.ts +0 -19
- package/dist/src/graph/validate.d.ts +0 -2
- package/dist/src/routes/index.d.ts +0 -4
- package/dist/src/types.d.ts +0 -74
- package/dist/src/ws/events.d.ts +0 -39
- package/dist/src/ws/index.d.ts +0 -3
- package/dist/src/ws/notify.d.ts +0 -2
- package/src/adapters/database.ts +0 -29
- package/src/adapters/mssql.ts +0 -195
- package/src/ai/active-streams.ts +0 -123
- package/src/ai/context/compressor.ts +0 -47
- package/src/ai/context/index.ts +0 -75
- package/src/ai/context/summarizer.ts +0 -50
- package/src/ai/context/token-estimator.ts +0 -60
- package/src/ai/helpers.ts +0 -32
- package/src/ai/index.ts +0 -277
- package/src/ai/interceptors/request-interceptor.ts +0 -61
- package/src/ai/prompt.ts +0 -126
- package/src/ai/tools/call-endpoint.tool.ts +0 -89
- package/src/ai/tools/capture-files.tool.ts +0 -20
- package/src/ai/tools/execute-code.tool.ts +0 -153
- package/src/cli/extract-endpoints.ts +0 -550
- package/src/config.ts +0 -182
- package/src/db/migrate.ts +0 -21
- package/src/db/migrations/20260315000000_add_context_meta/migration.sql +0 -1
- package/src/db/schema.ts +0 -70
- package/src/factory.ts +0 -171
- package/src/graph/expand-domains.ts +0 -276
- package/src/graph/generate-cypher.ts +0 -192
- package/src/graph/index.ts +0 -47
- package/src/graph/resolver.ts +0 -357
- package/src/graph/seed.ts +0 -162
- package/src/graph/validate.ts +0 -78
- package/src/routes/chat.ts +0 -86
- package/src/routes/files.ts +0 -100
- package/src/routes/index.ts +0 -4
- package/src/types.ts +0 -74
- package/src/ws/events.ts +0 -39
- package/src/ws/index.ts +0 -11
- package/src/ws/notify.ts +0 -9
- /package/dist/src/{auth → lib/auth}/middleware.d.ts +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# @m6d/cortex-server
|
|
2
2
|
|
|
3
|
-
Multi-agent AI chat server built on Hono + Bun. Supports MSSQL persistence, MinIO file storage, Neo4j knowledge graphs, and AI streaming with tool execution.
|
|
3
|
+
Multi-agent AI chat server built on Hono + Bun. Supports MSSQL or Postgres persistence, MinIO file storage, Neo4j knowledge graphs, and AI streaming with tool execution.
|
|
4
|
+
|
|
5
|
+
This package is a **runtime** library: it serves requests, resolves against the knowledge graph on every prompt, and exports the `define*` helpers you author domains with. Generation and seeding are not here — seeding the graph and generating endpoint schemas from Swagger are [`@m6d/cortex-cli`](https://www.npmjs.com/package/@m6d/cortex-cli) commands (`cortex graph seed`, `cortex swagger sync`). What the two share is the graph contract — `GRAPH_SCHEMA`, `GRAPH_SCHEMA_VERSION`, the `define*` helpers and their types, the Neo4j client and the embedder — which lives in the private `@cortex/contracts` workspace package (`internal/contracts`) and is vendored into this package's tarball at pack time. It is all re-exported from here, so authoring your domains stays one import. The CLI stamps the schema version it seeded onto the graph; this package reads that stamp on its first resolve and refuses a graph it cannot read, instead of quietly retrieving nothing.
|
|
4
6
|
|
|
5
7
|
## Usage
|
|
6
8
|
|
|
@@ -9,6 +11,7 @@ import { createCortex } from "@m6d/cortex-server";
|
|
|
9
11
|
|
|
10
12
|
const cortex = createCortex({
|
|
11
13
|
database: {
|
|
14
|
+
// Or `type: "postgres"` with a postgres:// connection string.
|
|
12
15
|
type: "mssql",
|
|
13
16
|
connectionString: process.env.DB_CONNECTION_STRING!,
|
|
14
17
|
},
|
|
@@ -35,7 +38,7 @@ const cortex = createCortex({
|
|
|
35
38
|
dimension: 1536,
|
|
36
39
|
},
|
|
37
40
|
neo4j: {
|
|
38
|
-
url: "
|
|
41
|
+
url: "http://localhost:7474",
|
|
39
42
|
user: "neo4j",
|
|
40
43
|
password: "password",
|
|
41
44
|
},
|
|
@@ -55,7 +58,9 @@ export default {
|
|
|
55
58
|
};
|
|
56
59
|
```
|
|
57
60
|
|
|
58
|
-
`cortex.serve()` is async — it runs database migrations on startup.
|
|
61
|
+
`cortex.serve()` is async — it runs database migrations on startup, from the migration history belonging to the configured dialect.
|
|
62
|
+
|
|
63
|
+
Only `database`, `model`, and `agents` are required for a minimal setup. `storage` enables attachment uploads/downloads, `embedding` is only required when `neo4j` graph features are configured, and agent `systemPrompt` defaults to an empty prompt when omitted. An optional `redis: { url, streamTtlSeconds? }` backs resumable streams with Redis so runs survive reconnects, reloads, and multiple server instances; without it an in-memory, single-process fallback is used.
|
|
59
64
|
|
|
60
65
|
Each key in `agents` becomes a route prefix (e.g. `assistant` → `/agents/assistant/...`). Agents can define per-agent `systemPrompt`, `tools`, `backendFetch`, `loadSessionData`, `resolveRequestContext`, and lifecycle hooks (`onToolCall`, `onStreamFinish`).
|
|
61
66
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# @cortex/contracts
|
|
2
|
+
|
|
3
|
+
The shapes both sides of a cortex boundary must agree on. Private on purpose —
|
|
4
|
+
it never publishes; each publishable package carries its own copy:
|
|
5
|
+
|
|
6
|
+
- `@m6d/cortex-server` and `@m6d/cortex-cli` publish raw source, so their
|
|
7
|
+
`prepack` vendors a copy of this directory into the tarball (`contracts/` and
|
|
8
|
+
`src/contracts/` respectively), resolved there by their shipped tsconfig paths.
|
|
9
|
+
- `@m6d/cortex-angular` and `@m6d/cortex-react` compile the parts they import
|
|
10
|
+
into their build artifacts.
|
|
11
|
+
|
|
12
|
+
Three boundaries, one subpath each:
|
|
13
|
+
|
|
14
|
+
| import | boundary |
|
|
15
|
+
| --------------------------- | ------------------------------------------------------------- |
|
|
16
|
+
| `@cortex/contracts/wire` | chat client ↔ server (HTTP/WebSocket types) |
|
|
17
|
+
| `@cortex/contracts/runtime` | cortex-cc console ↔ server runtime API (zod schemas) |
|
|
18
|
+
| `@cortex/contracts/graph` | graph authoring (cli) ↔ server (vocabulary, helpers, clients) |
|
|
19
|
+
|
|
20
|
+
Everything is consumed as TypeScript source — no build, no dist. Nothing here
|
|
21
|
+
has a runtime dependency beyond zod (for `/runtime`), and nothing here may grow
|
|
22
|
+
one: these files are compiled into an Angular library, a React library, a CLI
|
|
23
|
+
and a Bun server alike.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embeddings, which both halves of the graph need: `@m6d/cortex-cli` embeds every
|
|
3
|
+
* concept description as it seeds, `@m6d/cortex-server` embeds every prompt as it
|
|
4
|
+
* resolves. Two embedders would mean two vector spaces, so there is one.
|
|
5
|
+
*
|
|
6
|
+
* TanStack AI removed embeddings, and the graph only ever needed the plain
|
|
7
|
+
* OpenAI-compatible `/embeddings` call cortex is already configured for — so this
|
|
8
|
+
* is a bare `fetch`, and this package keeps its zero dependencies.
|
|
9
|
+
*
|
|
10
|
+
* Everything under `./graph` is written to the oldest target any consumer builds
|
|
11
|
+
* against — an Angular library compiles these sources directly — and imports
|
|
12
|
+
* siblings by their `.js` specifier so one emit serves both `dist` and source.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** Everything cortex needs to reach one OpenAI-compatible embeddings endpoint. */
|
|
16
|
+
export type EmbeddingProviderConfig = {
|
|
17
|
+
baseURL: string;
|
|
18
|
+
apiKey: string;
|
|
19
|
+
modelName: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/** Turns a batch of strings into their vectors, in the order given. */
|
|
23
|
+
export type EmbedFn = (values: string[]) => Promise<number[][]>;
|
|
24
|
+
|
|
25
|
+
export function createEmbedder(config: EmbeddingProviderConfig) {
|
|
26
|
+
const url = `${config.baseURL.replace(/\/+$/, "")}/embeddings`;
|
|
27
|
+
|
|
28
|
+
return async function embed(values: string[]) {
|
|
29
|
+
const response = await fetch(url, {
|
|
30
|
+
method: "POST",
|
|
31
|
+
headers: {
|
|
32
|
+
"Content-Type": "application/json",
|
|
33
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
34
|
+
},
|
|
35
|
+
body: JSON.stringify({ model: config.modelName, input: values }),
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
if (!response.ok) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Embedding request failed (${response.status}): ${await response.text()}`,
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// The API is free to return entries out of order; `index` is authoritative.
|
|
45
|
+
const body = (await response.json()) as { data: { index: number; embedding: number[] }[] };
|
|
46
|
+
return [...body.data]
|
|
47
|
+
.sort((left, right) => left.index - right.index)
|
|
48
|
+
.map((entry) => entry.embedding);
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Helper functions for building knowledge graph seed data.
|
|
2
|
+
* Helper functions for building knowledge graph seed data. Projects author
|
|
3
|
+
* domains with these; `@m6d/cortex-server` re-exports them so authoring needs
|
|
4
|
+
* exactly one import path.
|
|
3
5
|
*/
|
|
4
6
|
|
|
5
7
|
import type {
|
|
@@ -9,11 +11,7 @@ import type {
|
|
|
9
11
|
EndpointInput,
|
|
10
12
|
RuleDef,
|
|
11
13
|
ServiceDef,
|
|
12
|
-
} from "./types
|
|
13
|
-
|
|
14
|
-
// ---------------------------------------------------------------------------
|
|
15
|
-
// Identity helpers
|
|
16
|
-
// ---------------------------------------------------------------------------
|
|
14
|
+
} from "./types";
|
|
17
15
|
|
|
18
16
|
export function defineConcept(def: Omit<ConceptDef, "__brand">) {
|
|
19
17
|
return { __brand: "concept" as const, ...def };
|
|
@@ -31,10 +29,6 @@ export function defineDomain(def: Omit<DomainDef, "__brand">) {
|
|
|
31
29
|
return { __brand: "domain" as const, ...def };
|
|
32
30
|
}
|
|
33
31
|
|
|
34
|
-
// ---------------------------------------------------------------------------
|
|
35
|
-
// Endpoint builder
|
|
36
|
-
// ---------------------------------------------------------------------------
|
|
37
|
-
|
|
38
32
|
export function defineEndpoint(input: EndpointInput) {
|
|
39
33
|
const propertiesDescriptions = Object.fromEntries(
|
|
40
34
|
Object.entries({
|
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Configurable Neo4j HTTP client.
|
|
2
|
+
* Configurable Neo4j HTTP client, shared by the graph's writer and its reader.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* All configuration is passed explicitly — no environment variables are read —
|
|
5
|
+
* and the transport is `fetch`, so this package stays dependency-free.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type {
|
|
9
|
-
import { embed } from "ai";
|
|
10
|
-
|
|
11
|
-
// ---------------------------------------------------------------------------
|
|
12
|
-
// Config types
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
8
|
+
import type { EmbedFn } from "./embed";
|
|
14
9
|
|
|
15
10
|
export type Neo4jConfig = {
|
|
16
11
|
url: string;
|
|
@@ -22,33 +17,21 @@ export type Neo4jClient = {
|
|
|
22
17
|
query(cypher: string, parameters?: Record<string, unknown>): Promise<string>;
|
|
23
18
|
};
|
|
24
19
|
|
|
25
|
-
|
|
26
|
-
// Client factory
|
|
27
|
-
// ---------------------------------------------------------------------------
|
|
28
|
-
|
|
29
|
-
export function createNeo4jClient(config: Neo4jConfig, embeddingModel?: EmbeddingModel) {
|
|
20
|
+
export function createNeo4jClient(config: Neo4jConfig, embed?: EmbedFn) {
|
|
30
21
|
async function query(cypher: string, parameters?: Record<string, unknown>) {
|
|
31
22
|
// Auto-embed parameters whose keys start with '#'
|
|
32
23
|
const embeddedParams = Object.keys(parameters ?? {}).filter((x) => x.startsWith("#"));
|
|
33
24
|
|
|
34
25
|
if (embeddedParams.length) {
|
|
35
|
-
if (!
|
|
36
|
-
throw new Error("An
|
|
26
|
+
if (!embed) {
|
|
27
|
+
throw new Error("An embedder is required when using # parameters");
|
|
37
28
|
}
|
|
38
29
|
|
|
39
|
-
const
|
|
40
|
-
embeddedParams.map(
|
|
41
|
-
async (x) =>
|
|
42
|
-
await embed({
|
|
43
|
-
model: embeddingModel,
|
|
44
|
-
value: parameters![x] as string,
|
|
45
|
-
}),
|
|
46
|
-
),
|
|
47
|
-
);
|
|
30
|
+
const embeddings = await embed(embeddedParams.map((k) => parameters![k] as string));
|
|
48
31
|
|
|
49
32
|
embeddedParams.forEach((k, idx) => {
|
|
50
33
|
delete parameters![k];
|
|
51
|
-
parameters![k.slice(1)] =
|
|
34
|
+
parameters![k.slice(1)] = embeddings[idx]!;
|
|
52
35
|
});
|
|
53
36
|
}
|
|
54
37
|
|
|
@@ -77,13 +60,17 @@ export function createNeo4jClient(config: Neo4jConfig, embeddingModel?: Embeddin
|
|
|
77
60
|
}
|
|
78
61
|
|
|
79
62
|
const result = (await response.json()) as {
|
|
80
|
-
errors?: { message: string }[];
|
|
63
|
+
errors?: { code?: string; message: string }[];
|
|
81
64
|
results: { columns: string[]; data: { row: unknown[] }[] }[];
|
|
82
65
|
};
|
|
83
66
|
|
|
84
67
|
if (result.errors && result.errors.length > 0) {
|
|
68
|
+
// `code` rides alongside the message rather than inside it: it is the
|
|
69
|
+
// one-line identifier a report shows, and existing readers of
|
|
70
|
+
// `message` keep seeing exactly what they saw before.
|
|
85
71
|
return JSON.stringify({
|
|
86
72
|
error: true,
|
|
73
|
+
code: result.errors[0]!.code,
|
|
87
74
|
message: result.errors.map((e) => e.message).join("; "),
|
|
88
75
|
});
|
|
89
76
|
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The contract between the graph's writer and its reader.
|
|
3
|
+
*
|
|
4
|
+
* Seeding lives in `@m6d/cortex-cli` and resolution lives in `@m6d/cortex-server`,
|
|
5
|
+
* two packages a project installs and upgrades separately. The labels, relationship
|
|
6
|
+
* types, property names and index name they agree on are this module, here, so
|
|
7
|
+
* neither side owns the vocabulary the other has to match.
|
|
8
|
+
*
|
|
9
|
+
* A mismatch between the two is invisible at runtime: the resolver's Cypher
|
|
10
|
+
* matches nothing and retrieval comes back empty rather than failing. That is what
|
|
11
|
+
* `GRAPH_SCHEMA_VERSION` is for — bump it on any change to the shape below. The
|
|
12
|
+
* CLI stamps the version it wrote onto the graph and the server checks that stamp
|
|
13
|
+
* on its first resolve, so skew surfaces as an error instead of as silence.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export const GRAPH_SCHEMA_VERSION = 1;
|
|
17
|
+
|
|
18
|
+
export const GRAPH_SCHEMA = {
|
|
19
|
+
label: {
|
|
20
|
+
domain: "Domain",
|
|
21
|
+
concept: "Concept",
|
|
22
|
+
endpoint: "Endpoint",
|
|
23
|
+
service: "Service",
|
|
24
|
+
rule: "Rule",
|
|
25
|
+
/** Stamped with the version above, so a stale graph is detectable later. */
|
|
26
|
+
marker: "CortexGraph",
|
|
27
|
+
},
|
|
28
|
+
rel: {
|
|
29
|
+
belongsTo: "BELONGS_TO",
|
|
30
|
+
specializes: "SPECIALIZES",
|
|
31
|
+
queriedVia: "QUERIED_VIA",
|
|
32
|
+
mutatedVia: "MUTATED_VIA",
|
|
33
|
+
returns: "RETURNS",
|
|
34
|
+
dependsOn: "DEPENDS_ON",
|
|
35
|
+
governs: "GOVERNS",
|
|
36
|
+
requestedVia: "REQUESTED_VIA",
|
|
37
|
+
},
|
|
38
|
+
prop: {
|
|
39
|
+
name: "name",
|
|
40
|
+
description: "description",
|
|
41
|
+
aliases: "aliases",
|
|
42
|
+
metadata: "metadata",
|
|
43
|
+
path: "path",
|
|
44
|
+
method: "method",
|
|
45
|
+
params: "params",
|
|
46
|
+
body: "body",
|
|
47
|
+
response: "response",
|
|
48
|
+
propertiesDescriptions: "propertiesDescriptions",
|
|
49
|
+
successStatus: "successStatus",
|
|
50
|
+
errorStatuses: "errorStatuses",
|
|
51
|
+
builtInId: "builtInId",
|
|
52
|
+
embedding: "embedding",
|
|
53
|
+
/** On a RETURNS edge: which part of the response carries the concept. */
|
|
54
|
+
field: "field",
|
|
55
|
+
/** On a DEPENDS_ON edge. */
|
|
56
|
+
paramName: "paramName",
|
|
57
|
+
fromField: "fromField",
|
|
58
|
+
/** On the marker node. */
|
|
59
|
+
version: "version",
|
|
60
|
+
},
|
|
61
|
+
/** Created by the CLI's seeder, queried by name in the resolver's first hop. */
|
|
62
|
+
conceptEmbeddingsIndex: "concept_embeddings",
|
|
63
|
+
} as const;
|
|
64
|
+
|
|
65
|
+
export type GraphSchema = typeof GRAPH_SCHEMA;
|
|
@@ -7,10 +7,6 @@
|
|
|
7
7
|
* - Services are concept associations (no hardcoded endpoint steps).
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
// ---------------------------------------------------------------------------
|
|
11
|
-
// Endpoint property model (v2)
|
|
12
|
-
// ---------------------------------------------------------------------------
|
|
13
|
-
|
|
14
10
|
export type EndpointScalarType =
|
|
15
11
|
| "uuid"
|
|
16
12
|
| "number"
|
|
@@ -24,7 +20,8 @@ export type EndpointScalarType =
|
|
|
24
20
|
export type EndpointProperty = {
|
|
25
21
|
readonly name: string;
|
|
26
22
|
readonly required: boolean;
|
|
27
|
-
|
|
23
|
+
// NonNullable<unknown> keeps the literal union visible to autocomplete.
|
|
24
|
+
readonly type: EndpointScalarType | (string & NonNullable<unknown>);
|
|
28
25
|
readonly isArray?: boolean;
|
|
29
26
|
readonly properties?: readonly EndpointProperty[];
|
|
30
27
|
readonly description?: string;
|
|
@@ -41,10 +38,6 @@ export type AutoGenerated = {
|
|
|
41
38
|
readonly responseKind?: ResponseKind;
|
|
42
39
|
};
|
|
43
40
|
|
|
44
|
-
// ---------------------------------------------------------------------------
|
|
45
|
-
// Concept descriptor
|
|
46
|
-
// ---------------------------------------------------------------------------
|
|
47
|
-
|
|
48
41
|
export type ConceptDef = {
|
|
49
42
|
readonly __brand: "concept";
|
|
50
43
|
name: string;
|
|
@@ -55,10 +48,6 @@ export type ConceptDef = {
|
|
|
55
48
|
metadata?: Record<string, unknown>;
|
|
56
49
|
};
|
|
57
50
|
|
|
58
|
-
// ---------------------------------------------------------------------------
|
|
59
|
-
// Endpoint descriptor (v2)
|
|
60
|
-
// ---------------------------------------------------------------------------
|
|
61
|
-
|
|
62
51
|
export type EndpointDef = {
|
|
63
52
|
readonly __brand: "endpoint";
|
|
64
53
|
name: string;
|
|
@@ -88,10 +77,6 @@ export type EndpointDef = {
|
|
|
88
77
|
metadata?: Record<string, unknown>;
|
|
89
78
|
};
|
|
90
79
|
|
|
91
|
-
// ---------------------------------------------------------------------------
|
|
92
|
-
// EndpointInput
|
|
93
|
-
// ---------------------------------------------------------------------------
|
|
94
|
-
|
|
95
80
|
export type EndpointInput = {
|
|
96
81
|
name: string;
|
|
97
82
|
path: string;
|
|
@@ -117,10 +102,6 @@ export type EndpointInput = {
|
|
|
117
102
|
metadata?: Record<string, unknown>;
|
|
118
103
|
};
|
|
119
104
|
|
|
120
|
-
// ---------------------------------------------------------------------------
|
|
121
|
-
// Service descriptor (v2)
|
|
122
|
-
// ---------------------------------------------------------------------------
|
|
123
|
-
|
|
124
105
|
export type ServiceDef = {
|
|
125
106
|
readonly __brand: "service";
|
|
126
107
|
name: string;
|
|
@@ -131,10 +112,6 @@ export type ServiceDef = {
|
|
|
131
112
|
metadata?: Record<string, unknown>;
|
|
132
113
|
};
|
|
133
114
|
|
|
134
|
-
// ---------------------------------------------------------------------------
|
|
135
|
-
// Rule descriptor
|
|
136
|
-
// ---------------------------------------------------------------------------
|
|
137
|
-
|
|
138
115
|
export type RuleDef = {
|
|
139
116
|
readonly __brand: "rule";
|
|
140
117
|
name: string;
|
|
@@ -142,10 +119,6 @@ export type RuleDef = {
|
|
|
142
119
|
metadata?: Record<string, unknown>;
|
|
143
120
|
};
|
|
144
121
|
|
|
145
|
-
// ---------------------------------------------------------------------------
|
|
146
|
-
// Domain descriptor
|
|
147
|
-
// ---------------------------------------------------------------------------
|
|
148
|
-
|
|
149
122
|
export type DomainDef = {
|
|
150
123
|
readonly __brand: "domain";
|
|
151
124
|
name: string;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The graph contract — the knowledge-graph vocabulary, authoring types and
|
|
3
|
+
* clients that `@m6d/cortex-cli` writes with and `@m6d/cortex-server` reads
|
|
4
|
+
* with. `@m6d/cortex-server` re-exports all of it, so a project authoring
|
|
5
|
+
* domains still has exactly one import path.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type { GraphSchema } from "./graph/schema";
|
|
9
|
+
export { GRAPH_SCHEMA, GRAPH_SCHEMA_VERSION } from "./graph/schema";
|
|
10
|
+
|
|
11
|
+
export type {
|
|
12
|
+
EndpointScalarType,
|
|
13
|
+
EndpointProperty,
|
|
14
|
+
ResponseKind,
|
|
15
|
+
AutoGenerated,
|
|
16
|
+
ConceptDef,
|
|
17
|
+
EndpointDef,
|
|
18
|
+
EndpointInput,
|
|
19
|
+
ServiceDef,
|
|
20
|
+
RuleDef,
|
|
21
|
+
DomainDef,
|
|
22
|
+
} from "./graph/types";
|
|
23
|
+
|
|
24
|
+
export {
|
|
25
|
+
defineConcept,
|
|
26
|
+
defineRule,
|
|
27
|
+
defineService,
|
|
28
|
+
defineDomain,
|
|
29
|
+
defineEndpoint,
|
|
30
|
+
} from "./graph/helpers";
|
|
31
|
+
|
|
32
|
+
export type { Neo4jConfig, Neo4jClient } from "./graph/neo4j";
|
|
33
|
+
export { createNeo4jClient } from "./graph/neo4j";
|
|
34
|
+
|
|
35
|
+
export type { EmbedFn, EmbeddingProviderConfig } from "./graph/embed";
|
|
36
|
+
export { createEmbedder } from "./graph/embed";
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* The HTTP contract of the cortex-cc runtime API: the console (`apps/cortex-cc`)
|
|
5
|
+
* validates requests against these schemas and `@m6d/cortex-server` validates the
|
|
6
|
+
* responses it gets back. Request types use `z.input` because the callers build
|
|
7
|
+
* payloads the runtime's parser then fills defaults into.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Runtime contract §1.1: the `:id` path param, validated on both sides of the wire. */
|
|
11
|
+
export const AGENT_SLUG_PATTERN = /^[a-z0-9][a-z0-9-]{0,62}$/;
|
|
12
|
+
|
|
13
|
+
/** Runtime contract §5: tool names become `tools.<name>()` sandbox bindings. */
|
|
14
|
+
export const TOOL_NAME_PATTERN = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
15
|
+
|
|
16
|
+
export const PROMPT_VARIABLES = ["userName", "channel", "locale"] as const;
|
|
17
|
+
|
|
18
|
+
export const RUNTIME_ERROR_KINDS = [
|
|
19
|
+
"timeout",
|
|
20
|
+
"upstream_4xx",
|
|
21
|
+
"upstream_5xx",
|
|
22
|
+
"schema_mismatch",
|
|
23
|
+
"rate_limited",
|
|
24
|
+
"not_found",
|
|
25
|
+
"unauthorized",
|
|
26
|
+
"invalid_request",
|
|
27
|
+
"egress_blocked",
|
|
28
|
+
"internal",
|
|
29
|
+
] as const;
|
|
30
|
+
|
|
31
|
+
/** The ways an execute output may disagree with the tool's declared schema. */
|
|
32
|
+
export const JSON_SCHEMA_ISSUE_KINDS = ["missing", "unexpected", "type_mismatch"] as const;
|
|
33
|
+
|
|
34
|
+
export const agentSlugSchema = z.string().regex(AGENT_SLUG_PATTERN);
|
|
35
|
+
export const localeSchema = z.enum(["en", "ar"]);
|
|
36
|
+
export const catalogVersionSchema = z.string().regex(/^[0-9a-f]{16}$/);
|
|
37
|
+
|
|
38
|
+
export const sharedShapeSchema = z.object({
|
|
39
|
+
ref: z.string().regex(/^\$R\d+$/),
|
|
40
|
+
shape: z.string(),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export const knowledgeChunkSchema = z.object({
|
|
44
|
+
chunkId: z.uuid(),
|
|
45
|
+
text: z.string(),
|
|
46
|
+
score: z.number(),
|
|
47
|
+
citation: z.object({
|
|
48
|
+
documentId: z.uuid(),
|
|
49
|
+
documentTitle: z.string(),
|
|
50
|
+
page: z.number().int().positive().nullable(),
|
|
51
|
+
section: z.string().nullable(),
|
|
52
|
+
uri: z.url().nullable(),
|
|
53
|
+
service: z.string().nullable(),
|
|
54
|
+
}),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
export const toolSignatureSchema = z.object({
|
|
58
|
+
toolId: z.uuid(),
|
|
59
|
+
name: z.string().regex(TOOL_NAME_PATTERN),
|
|
60
|
+
version: z.number().int().positive(),
|
|
61
|
+
readOnly: z.boolean(),
|
|
62
|
+
tags: z.array(z.string()),
|
|
63
|
+
signature: z.string(),
|
|
64
|
+
score: z.number().nullable(),
|
|
65
|
+
pinned: z.boolean(),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
export const serviceCardSchema = z.object({
|
|
69
|
+
serviceId: z.uuid(),
|
|
70
|
+
key: z
|
|
71
|
+
.string()
|
|
72
|
+
.regex(/^[a-z0-9]+(-[a-z0-9]+)*$/)
|
|
73
|
+
.max(64),
|
|
74
|
+
name: z.string(),
|
|
75
|
+
card: z.string(),
|
|
76
|
+
score: z.number(),
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
export const runtimeAgentConfigSchema = z.object({
|
|
80
|
+
agentId: agentSlugSchema,
|
|
81
|
+
systemPrompt: z.string(),
|
|
82
|
+
promptVariables: z.array(z.enum(PROMPT_VARIABLES)),
|
|
83
|
+
catalogBlurb: z.string(),
|
|
84
|
+
defaultLocale: localeSchema,
|
|
85
|
+
metaTools: z.object({
|
|
86
|
+
searchKnowledge: z.boolean(),
|
|
87
|
+
searchTools: z.boolean(),
|
|
88
|
+
searchServices: z.boolean(),
|
|
89
|
+
}),
|
|
90
|
+
limits: z.object({
|
|
91
|
+
resolveTokenBudget: z.number().int().positive(),
|
|
92
|
+
executeTimeoutMs: z.number().int().positive(),
|
|
93
|
+
maxResponseBytes: z.number().int().positive(),
|
|
94
|
+
}),
|
|
95
|
+
catalogVersion: catalogVersionSchema,
|
|
96
|
+
publishedAt: z.iso.datetime(),
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
export const resolveRequestSchema = z.object({
|
|
100
|
+
query: z.string().trim().min(1).max(4000),
|
|
101
|
+
locale: localeSchema.optional(),
|
|
102
|
+
hints: z
|
|
103
|
+
.object({
|
|
104
|
+
threadId: z.string().max(128).optional(),
|
|
105
|
+
recentToolNames: z.array(z.string()).max(20).default([]),
|
|
106
|
+
turnIndex: z.number().int().min(0).optional(),
|
|
107
|
+
})
|
|
108
|
+
.optional(),
|
|
109
|
+
tokenBudget: z.number().int().min(500).max(20000).optional(),
|
|
110
|
+
limits: z
|
|
111
|
+
.object({
|
|
112
|
+
knowledge: z.number().int().min(0).max(20).default(6),
|
|
113
|
+
tools: z.number().int().min(0).max(20).default(8),
|
|
114
|
+
services: z.number().int().min(0).max(20).default(5),
|
|
115
|
+
})
|
|
116
|
+
.optional(),
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
export const resolveResponseSchema = z.object({
|
|
120
|
+
resolveId: z.uuid(),
|
|
121
|
+
catalogVersion: catalogVersionSchema,
|
|
122
|
+
locale: localeSchema,
|
|
123
|
+
knowledge: z.array(knowledgeChunkSchema),
|
|
124
|
+
tools: z.array(toolSignatureSchema),
|
|
125
|
+
services: z.array(serviceCardSchema),
|
|
126
|
+
sharedShapes: z.array(sharedShapeSchema),
|
|
127
|
+
budget: z.object({
|
|
128
|
+
requested: z.number().int(),
|
|
129
|
+
used: z.number().int(),
|
|
130
|
+
truncated: z.boolean(),
|
|
131
|
+
}),
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
export const searchRequestSchema = z.object({
|
|
135
|
+
query: z.string().trim().min(1).max(4000),
|
|
136
|
+
limit: z.number().int().min(1).max(20).default(5),
|
|
137
|
+
locale: localeSchema.optional(),
|
|
138
|
+
threadId: z.string().max(128).optional(),
|
|
139
|
+
service: z.string().max(64).optional(),
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
export const searchToolsResponseSchema = z.object({
|
|
143
|
+
catalogVersion: catalogVersionSchema,
|
|
144
|
+
tools: z.array(toolSignatureSchema),
|
|
145
|
+
sharedShapes: z.array(sharedShapeSchema),
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
export const searchServicesResponseSchema = z.object({
|
|
149
|
+
catalogVersion: catalogVersionSchema,
|
|
150
|
+
services: z.array(serviceCardSchema),
|
|
151
|
+
tools: z.array(toolSignatureSchema),
|
|
152
|
+
sharedShapes: z.array(sharedShapeSchema),
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
export const searchKnowledgeResponseSchema = z.object({
|
|
156
|
+
catalogVersion: catalogVersionSchema,
|
|
157
|
+
knowledge: z.array(knowledgeChunkSchema),
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
export const executeRequestSchema = z.object({
|
|
161
|
+
input: z.record(z.string(), z.unknown()).default({}),
|
|
162
|
+
context: z
|
|
163
|
+
.object({
|
|
164
|
+
threadId: z.string().max(128).optional(),
|
|
165
|
+
userId: z.string().max(128).optional(),
|
|
166
|
+
locale: localeSchema.optional(),
|
|
167
|
+
})
|
|
168
|
+
.optional(),
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
export const executeResponseSchema = z.object({
|
|
172
|
+
toolId: z.uuid(),
|
|
173
|
+
name: z.string(),
|
|
174
|
+
version: z.number().int().positive(),
|
|
175
|
+
output: z.unknown(),
|
|
176
|
+
meta: z.object({
|
|
177
|
+
upstreamStatus: z.number().int().min(100).max(599),
|
|
178
|
+
durationMs: z.number().int().min(0),
|
|
179
|
+
replayed: z.boolean(),
|
|
180
|
+
truncated: z.boolean(),
|
|
181
|
+
truncatedPaths: z.array(z.string()),
|
|
182
|
+
drift: z.array(
|
|
183
|
+
z.object({
|
|
184
|
+
path: z.string(),
|
|
185
|
+
kind: z.enum(JSON_SCHEMA_ISSUE_KINDS),
|
|
186
|
+
}),
|
|
187
|
+
),
|
|
188
|
+
}),
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
const runtimeErrorKindSchema = z.enum(RUNTIME_ERROR_KINDS);
|
|
192
|
+
export type RuntimeErrorKind = z.infer<typeof runtimeErrorKindSchema>;
|
|
193
|
+
|
|
194
|
+
export const runtimeErrorSchema = z.object({
|
|
195
|
+
error: z.object({
|
|
196
|
+
kind: runtimeErrorKindSchema,
|
|
197
|
+
detail: z.string().max(512),
|
|
198
|
+
retryable: z.boolean(),
|
|
199
|
+
retryAfterSeconds: z.number().int().positive().optional(),
|
|
200
|
+
upstreamStatus: z.number().int().min(100).max(599).optional(),
|
|
201
|
+
}),
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
export type RuntimeAgentConfig = z.infer<typeof runtimeAgentConfigSchema>;
|
|
205
|
+
export type ResolveRequest = z.input<typeof resolveRequestSchema>;
|
|
206
|
+
export type ResolveResponse = z.infer<typeof resolveResponseSchema>;
|
|
207
|
+
export type SearchRequest = z.input<typeof searchRequestSchema>;
|
|
208
|
+
export type ExecuteRequest = z.input<typeof executeRequestSchema>;
|