@konneal/engine 0.1.4 → 0.2.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/dist/admin.d.ts +1 -0
- package/dist/ask-47RNGK2R.js +12 -0
- package/dist/chunk-3OXSQH7Y.js +1852 -0
- package/dist/chunk-6GOSMLRH.js +2781 -0
- package/dist/{chunk-EHJEELVB.js → chunk-LNSDBEKS.js} +1 -1
- package/dist/{chunk-35ODH64W.js → chunk-Q327B27J.js} +33 -0
- package/dist/{chunk-OCNLV7Q7.js → chunk-Q6LI4T7M.js} +6 -1
- package/dist/{chunk-ROF3Q7UC.js → chunk-SN3ANQ3Y.js} +2 -2
- package/dist/chunk-VJZLVU3S.js +64 -0
- package/dist/{chunk-CAEHIVG5.js → chunk-WGXATDXY.js} +1 -1
- package/dist/codecs.d.ts +3 -3
- package/dist/completion.d.ts +1 -1
- package/dist/config.d.ts +9 -0
- package/dist/faithfulness.d.ts +1 -0
- package/dist/mcp-proto.d.ts +25 -0
- package/dist/mcp.d.ts +4 -0
- package/dist/openapi-surface.gen.d.ts +9 -0
- package/dist/openapi-types.d.ts +2141 -0
- package/dist/profile.gen.d.ts +1 -0
- package/dist/prompts/system.md +1 -0
- package/dist/quota.d.ts +4 -1
- package/dist/search-OMPBMZT4.js +11 -0
- package/dist/tablecontext.d.ts +7 -0
- package/dist/verdict-parse.d.ts +5 -0
- package/dist/worker_mcp/src/index.js +3 -3
- package/dist/worker_public/src/config.js +4 -2
- package/dist/worker_public/src/index.js +1193 -4932
- package/dist/worker_public/src/profile.js +1 -1
- package/dist/worker_public/src/refusal.js +2 -2
- package/dist/worker_public/src/requestScope.js +3 -3
- package/docs/spec-api.md +27 -13
- package/package.json +12 -3
- package/profile/prompts.yaml +3 -0
- package/workers/shared/router.ts +23 -16
- package/workers/worker_public/migrations/0014_usage_cache.sql +5 -0
- package/workers/worker_public/openapi.yaml +1169 -0
- package/workers/worker_public/prompts/system.md +1 -0
- package/workers/worker_public/schema.sql +3 -1
- package/workers/worker_public/src/admin.ts +51 -7
- package/workers/worker_public/src/ai.ts +10 -2
- package/workers/worker_public/src/ask.ts +94 -22
- package/workers/worker_public/src/codecs.ts +35 -10
- package/workers/worker_public/src/completion.ts +24 -1
- package/workers/worker_public/src/config.ts +10 -0
- package/workers/worker_public/src/faithfulness.ts +10 -17
- package/workers/worker_public/src/grader.ts +2 -2
- package/workers/worker_public/src/index.ts +106 -58
- package/workers/worker_public/src/lib/router.ts +1 -1
- package/workers/worker_public/src/mcp-proto.ts +71 -0
- package/workers/worker_public/src/mcp.ts +47 -0
- package/workers/worker_public/src/openapi-surface.gen.ts +318 -0
- package/workers/worker_public/src/pipeline.ts +4 -2
- package/workers/worker_public/src/profile.gen.ts +1 -0
- package/workers/worker_public/src/projects.ts +4 -2
- package/workers/worker_public/src/quota.ts +4 -2
- package/workers/worker_public/src/research.ts +55 -3
- package/workers/worker_public/src/tablecontext.ts +13 -2
- package/workers/worker_public/src/verdict-parse.ts +60 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
requestSalt,
|
|
3
3
|
resolveRequestScope
|
|
4
|
-
} from "../../chunk-
|
|
5
|
-
import "../../chunk-
|
|
6
|
-
import "../../chunk-
|
|
4
|
+
} from "../../chunk-LNSDBEKS.js";
|
|
5
|
+
import "../../chunk-Q6LI4T7M.js";
|
|
6
|
+
import "../../chunk-Q327B27J.js";
|
|
7
7
|
export {
|
|
8
8
|
requestSalt,
|
|
9
9
|
resolveRequestScope
|
package/docs/spec-api.md
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
# API surface spec
|
|
2
2
|
|
|
3
|
-
The worker's complete HTTP inventory
|
|
4
|
-
|
|
5
|
-
`
|
|
6
|
-
|
|
3
|
+
The worker's complete HTTP inventory. The API routes are generated from
|
|
4
|
+
the OpenAPI document `workers/worker_public/openapi.yaml`
|
|
5
|
+
(`scripts/gen-openapi-routes.mjs` → `src/openapi-surface.gen.ts`), and
|
|
6
|
+
`index.ts`'s `OPENAPI_HANDLERS` binds every operation to its handler;
|
|
7
|
+
`tests/openapi-surface.test.ts` pins the bijection, and the non-API
|
|
8
|
+
routes (pages, unit assets, rendered documents) are declared in
|
|
9
|
+
`INFRA_ROUTES`. Adding a route = the yaml entry + one handler binding +
|
|
10
|
+
regenerate; this document changes with it. Request/response details
|
|
7
11
|
beyond the inventory: [API.md](API.md).
|
|
8
12
|
|
|
9
13
|
## Conventions
|
|
@@ -27,13 +31,19 @@ beyond the inventory: [API.md](API.md).
|
|
|
27
31
|
| `/auth/callback` | GET | none | `handleCallback` | OIDC callback; mints the session cookie; bubble mode postMessages the token to the validated origin. |
|
|
28
32
|
| `/auth/me` | GET | session | `handleMe` | `{ authenticated, name, email, roles, tier }`. |
|
|
29
33
|
| `/auth/logout` | GET, POST | none | `handleLogout` | Clears the session. |
|
|
30
|
-
| `/api/conversations` |
|
|
31
|
-
| `/api/conversations/:id` |
|
|
34
|
+
| `/api/conversations` | GET, POST | session | `conversationsRoute` → `handleConversations` | List / create the signed-in member's conversations. |
|
|
35
|
+
| `/api/conversations/:id` | GET, PATCH, DELETE | session (owner) | `conversationsRoute` | One conversation: read / rename / delete. |
|
|
32
36
|
| `/api/conversations/:id/messages` | POST | session (owner) | `appendMessageRoute` → `handleAppendMessage` | Append a message turn. |
|
|
33
37
|
| `/api/conversations/:id/share` | POST | session (owner) | `shareRoute` → `handleShareConversation` | Publish a conversation to an unlisted share slug. (Was shadowed by the compound conversations branch pre-route-table — the pattern inventory made the collision visible and fixed it.) |
|
|
34
38
|
| `/api/shared/:slug` | GET | none | `getSharedRoute` → `handleGetShared` | Read a shared conversation. |
|
|
39
|
+
| `/api/projects` | GET, POST | session | `projectsRoute` → `handleProjects` | Contexts (#187): list / create / rename by id / file a conversation by `conversation_id` + `project_id` (null unfiles — membership-as-move). |
|
|
40
|
+
| `/api/projects/:id` | DELETE | session (owner) | `projectsRoute` | Delete a context: files detached, conversations returned to the general list. |
|
|
41
|
+
| `/api/projects/:id/files` | GET, POST | session (owner) | `projectFilesRoute` → `handleProjectFiles` | List / attach (or replace by id) a context's files; POST names the context by `project_id` in the body. |
|
|
42
|
+
| `/api/project-files/:id` | DELETE | session (owner) | `projectFilesRoute` | Detach one file. |
|
|
35
43
|
| `/api/datasets` | GET | none (session enriches) | `datasetsRoute` | The corpus catalog + starter questions (the UI's empty state — content from the API, never hardcoded in the client). Session-gated datasets carry `requires` (the estate permission, e.g. `the ai-preview permission (id.oimlsmart.org)`) and `enabled` reflects the permission, not just login. |
|
|
36
|
-
| `/api/memories` |
|
|
44
|
+
| `/api/memories` | GET, POST | session | `memoriesRoute` → `handleMemories` | Personalized memory files (#171): GET list / POST create-or-replace by id (≤10 files × 8k chars) — every query owner-filtered by the session sub. Selected ids ride `/api/ask` as `memories: [id…]` (≤4 per ask, injected as one bounded trusted-user-facts note; the selection salts the answer cache). |
|
|
45
|
+
| `/api/memories/:id` | DELETE | session (owner) | `memoriesRoute` | Delete one memory file. |
|
|
46
|
+
| `/mcp` | POST | tier | `mcpRoute` → `handleMcp` | The Model Context Protocol server (JSON-RPC 2025-06-18, streamable HTTP); tools: `ask`, `retrieve`. |
|
|
37
47
|
| `/health` | GET | none | `healthRoute` | Liveness + deployed `index_version` (the deploy-drift guard reads this). |
|
|
38
48
|
| `/api/ask`, `/v1/ask` | POST | tier | `askRoute` → `handleAsk` | The answer contract: streamed or JSON answer, citations, typed blocks, context echo. Quotas per tier. Optional `datasets: [id…]` narrows the corpora searched (server-intersected with session permissions; an explicitly-empty list is a 400); optional `memories: [id…]` selects the member's memory files to inject. Both selections salt the answer cache — a scoped or memory-flavored answer never serves a plain ask. |
|
|
39
49
|
| `/api/absence`, `/v1/absence` | POST | tier | `absenceRoute` | Provable absence: exhaustive enumeration over a standard's model plane; `{ verdict: absent \| present, enumerated, matches }`. |
|
|
@@ -50,10 +60,11 @@ beyond the inventory: [API.md](API.md).
|
|
|
50
60
|
| `/admin/judge`, `/v1/admin/judge` | POST | ADMIN_TOKEN | `handleJudge` | LLM-as-judge scoring (promotion gates). |
|
|
51
61
|
| `/v1/admin/keys` | POST | ADMIN_TOKEN | `handleCreateKey` | Issue an API key (`oiml_<hex>`, shown once). |
|
|
52
62
|
| `/v1/admin/keys` | GET | ADMIN_TOKEN | `handleListKeys` | List keys (no secrets). |
|
|
63
|
+
| `/v1/admin/keys/:id` | DELETE | ADMIN_TOKEN | `handleRevokeKey` | Revoke a key. |
|
|
53
64
|
| `/v1/admin/stats` | GET | ADMIN_TOKEN | `adminStatsRoute` | 7-day telemetry: queries/day/tier, spend by model, feedback, error rate; prunes >90d rows. |
|
|
54
65
|
| `/docs/:slug.html`, `/docs/:slug.anchors.json` | GET | public | `docsRoute` | Rendered publication documents (metanorma-mirror layer 1) served from R2 under `docs/`, immutable cache; the anchors map (clause number → heading anchor id) powers citation deep links. Public OIML content only. |
|
|
55
66
|
| `/admin/enrich` | POST | ADMIN_TOKEN | `handleEnrich` | modes: default (context+embed+upsert in place), `context` (generate only, KV-cached), `ab` (generate at an explicit effort with NO side effects — the experiment lane; accepts an admin-gated prompt override for judged comparisons). |
|
|
56
|
-
| anything else | any | — | — | `404 not_found`. |
|
|
67
|
+
| anything else | any | — | — | `404 not_found`; a known path under an undeclared method answers `405 method_not_allowed`. |
|
|
57
68
|
|
|
58
69
|
## Request semantics worth naming
|
|
59
70
|
|
|
@@ -63,11 +74,14 @@ beyond the inventory: [API.md](API.md).
|
|
|
63
74
|
## Dispatch semantics
|
|
64
75
|
|
|
65
76
|
`fetch` = OPTIONS preflight (204) → `matchRoute(ROUTES, method, path)` →
|
|
66
|
-
handler with `{ env, req, ctx, url, path, params }` →
|
|
67
|
-
|
|
68
|
-
(
|
|
69
|
-
|
|
70
|
-
|
|
77
|
+
handler with `{ env, req, ctx, url, path, params }` → 405 when the path
|
|
78
|
+
is served under another method → 404. `ROUTES` is `INFRA_ROUTES` +
|
|
79
|
+
`OPENAPI_SURFACE` (generated from the yaml) mapped through
|
|
80
|
+
`OPENAPI_HANDLERS`. Patterns are segment-exact with `:param` capture and
|
|
81
|
+
a trailing `*` wildcard (`/assets/*`); entry order is irrelevant because
|
|
82
|
+
no pattern overlaps another. The `/api` and `/v1` twins deliberately
|
|
83
|
+
share one handler so the tier split can never diverge between the two
|
|
84
|
+
publications.
|
|
71
85
|
|
|
72
86
|
## Isolation invariants (binding lint, `npm run lint:wrangler`)
|
|
73
87
|
|
package/package.json
CHANGED
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"test:ui": "node tests/ui.mjs",
|
|
15
15
|
"test:bridge": "node --test tests/bridge.test.mjs",
|
|
16
16
|
"test:units": "node --test --experimental-strip-types tests/*.test.ts",
|
|
17
|
-
"
|
|
17
|
+
"gen:openapi-types": "node scripts/gen-openapi-types.mjs",
|
|
18
|
+
"build": "rm -rf dist dist-types && esbuild workers/worker_mcp/src/index.ts workers/worker_public/src/index.ts workers/worker_public/src/config.ts workers/worker_public/src/refusal.ts workers/worker_public/src/profile.ts workers/worker_public/src/requestScope.ts --bundle --format=esm --splitting --platform=neutral --outdir=dist --loader:.md=text && tsc -p tsconfig.build.json && cp dist-types/worker_public/src/*.d.ts dist/ && mkdir -p dist/worker_mcp/src && cp dist-types/worker_mcp/src/*.d.ts dist/worker_mcp/src/ && mkdir -p dist/prompts && cp workers/worker_public/prompts/*.md dist/prompts/ && node scripts/gen-openapi-types.mjs",
|
|
18
19
|
"prepare": "npm run build",
|
|
19
20
|
"lint:ports": "node scripts/lint-ports.mjs",
|
|
20
21
|
"lint:publisher": "node scripts/lint-publisher-leak.mjs",
|
|
@@ -24,14 +25,18 @@
|
|
|
24
25
|
"@cloudflare/workers-types": "^5.20260911.1",
|
|
25
26
|
"esbuild": "^0.28.2",
|
|
26
27
|
"jsdom": "^29.1.1",
|
|
28
|
+
"openapi-typescript": "^7.13.0",
|
|
27
29
|
"playwright": "^1.62.1",
|
|
28
30
|
"yaml": "^2.9.1"
|
|
29
31
|
},
|
|
30
32
|
"dependencies": {
|
|
31
33
|
"@astrojs/markdown-satteri": "^0.4.1",
|
|
32
|
-
"@astrojs/mdx": "^4.3.14"
|
|
34
|
+
"@astrojs/mdx": "^4.3.14",
|
|
35
|
+
"@konneal/client": "github:konneal/client#22ce599",
|
|
36
|
+
"@konneal/engine": "github:konneal/engine#2d6c39b",
|
|
37
|
+
"@oimlsmart/oiml-pubid": "^1.2.1"
|
|
33
38
|
},
|
|
34
|
-
"version": "0.1
|
|
39
|
+
"version": "0.2.1",
|
|
35
40
|
"description": "The Konneal engine: the publisher-agnostic build pipeline and API plane for standards intelligence (retrieval, answer contract, verdicts, evaluation).",
|
|
36
41
|
"license": "BSD-3-Clause",
|
|
37
42
|
"type": "module",
|
|
@@ -57,6 +62,10 @@
|
|
|
57
62
|
"types": "./dist/requestScope.d.ts",
|
|
58
63
|
"default": "./dist/worker_public/src/requestScope.js"
|
|
59
64
|
},
|
|
65
|
+
"./openapi": "./workers/worker_public/openapi.yaml",
|
|
66
|
+
"./openapi-types": {
|
|
67
|
+
"types": "./dist/openapi-types.d.ts"
|
|
68
|
+
},
|
|
60
69
|
"./mcp": "./dist/worker_mcp/src/index.js"
|
|
61
70
|
},
|
|
62
71
|
"files": [
|
package/profile/prompts.yaml
CHANGED
package/workers/shared/router.ts
CHANGED
|
@@ -21,25 +21,32 @@ export interface Route {
|
|
|
21
21
|
handler: RouteHandler;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
/** The path half of the match, method-blind: segment-exact with :param
|
|
25
|
+
* capture and a trailing * wildcard. Returns the captured params when
|
|
26
|
+
* the pattern fits, null otherwise. The 405 probe uses it to tell a
|
|
27
|
+
* known path under a wrong method from an unknown path. */
|
|
28
|
+
export function routeMatchesPath(pattern: string, path: string): Record<string, string> | null {
|
|
25
29
|
const segments = path.split("/").filter(Boolean);
|
|
30
|
+
const patternSegs = pattern.split("/").filter(Boolean);
|
|
31
|
+
if (patternSegs.length !== segments.length && !patternSegs[patternSegs.length - 1]?.startsWith("*")) return null;
|
|
32
|
+
const params: Record<string, string> = {};
|
|
33
|
+
for (let i = 0; i < patternSegs.length; i++) {
|
|
34
|
+
const ps = patternSegs[i];
|
|
35
|
+
if (ps.startsWith("*")) return params; // wildcard matches rest
|
|
36
|
+
if (ps.startsWith(":")) {
|
|
37
|
+
params[ps.slice(1)] = segments[i];
|
|
38
|
+
} else if (ps !== segments[i]) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return params;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function matchRoute(routes: Route[], method: string, path: string): { route: Route; params: Record<string, string> } | null {
|
|
26
46
|
for (const route of routes) {
|
|
27
47
|
if (route.method !== method && route.method !== "*") continue;
|
|
28
|
-
const
|
|
29
|
-
if (
|
|
30
|
-
const params: Record<string, string> = {};
|
|
31
|
-
let matched = true;
|
|
32
|
-
for (let i = 0; i < patternSegs.length; i++) {
|
|
33
|
-
const ps = patternSegs[i];
|
|
34
|
-
if (ps.startsWith("*")) break; // wildcard matches rest
|
|
35
|
-
if (ps.startsWith(":")) {
|
|
36
|
-
params[ps.slice(1)] = segments[i];
|
|
37
|
-
} else if (ps !== segments[i]) {
|
|
38
|
-
matched = false;
|
|
39
|
-
break;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
if (matched) return { route, params };
|
|
48
|
+
const params = routeMatchesPath(route.pattern, path);
|
|
49
|
+
if (params) return { route, params };
|
|
43
50
|
}
|
|
44
51
|
return null;
|
|
45
52
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
-- Usage telemetry (2026-09-17): the cache mix on the queries ledger.
|
|
2
|
+
-- 'exact' | 'semantic' for served-from-cache answers, NULL for a live
|
|
3
|
+
-- generation — the answer-cache story (hit rates per tier) becomes
|
|
4
|
+
-- measurable instead of inferred.
|
|
5
|
+
ALTER TABLE queries ADD COLUMN cache TEXT;
|