@diegoaltoworks/chatter 0.23.0 → 0.25.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/dist/core/buckets.d.ts +74 -0
- package/dist/core/buckets.d.ts.map +1 -0
- package/dist/core/buckets.test.d.ts +10 -0
- package/dist/core/buckets.test.d.ts.map +1 -0
- package/dist/core/pipeline.d.ts +12 -1
- package/dist/core/pipeline.d.ts.map +1 -1
- package/dist/core/retrieval.d.ts +12 -2
- package/dist/core/retrieval.d.ts.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +81 -14
- package/dist/index.mjs +78 -14
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +47 -3
- package/dist/mcp-server.mjs +47 -3
- package/dist/middleware/jwt.d.ts +10 -0
- package/dist/middleware/jwt.d.ts.map +1 -1
- package/dist/routes/demo.d.ts.map +1 -1
- package/dist/routes/openai.d.ts.map +1 -1
- package/dist/routes/private.d.ts.map +1 -1
- package/dist/routes/public.d.ts.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.test.d.ts +9 -0
- package/dist/server.test.d.ts.map +1 -0
- package/dist/types.d.ts +34 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retrieval bucket resolution — which slices of the knowledge base a single
|
|
3
|
+
* chat turn is allowed to see.
|
|
4
|
+
*
|
|
5
|
+
* Knowledge is ingested into named buckets (see ./loaders). By default a chat
|
|
6
|
+
* turn retrieves from `base` plus the bucket matching its mode, which keeps
|
|
7
|
+
* `private` knowledge off public surfaces. Role-gated deployments need more
|
|
8
|
+
* than that: a signed-in operator may be entitled to buckets an anonymous
|
|
9
|
+
* visitor is not, and the entitlement is only knowable per request.
|
|
10
|
+
*
|
|
11
|
+
* `bucketsFor` is that seam. Surfaces (routes, channels) call
|
|
12
|
+
* {@link resolveBuckets} with whatever sender identity they hold and pass the
|
|
13
|
+
* result to `prepareChat`. The security invariant lives here, in one pure
|
|
14
|
+
* function, rather than being re-derived by every surface:
|
|
15
|
+
*
|
|
16
|
+
* **The hook can only widen retrieval for a caller the surface could name.**
|
|
17
|
+
* Without a sender identity, its answer is clamped to the buckets the mode
|
|
18
|
+
* would have retrieved anyway — so a hook asking for `private` from a public
|
|
19
|
+
* surface gets it dropped, not honoured.
|
|
20
|
+
*
|
|
21
|
+
* Anonymous surfaces run the public pipeline, so their ceiling is the public
|
|
22
|
+
* defaults and private knowledge stays out of reach. Clamping to the mode
|
|
23
|
+
* defaults rather than always to the public ones keeps the two ways a hook can
|
|
24
|
+
* decline to widen — returning the defaults, or returning `undefined` —
|
|
25
|
+
* behaving identically; a ceiling that depended on which one a hook picked
|
|
26
|
+
* would be a trap rather than a guarantee.
|
|
27
|
+
*
|
|
28
|
+
* Narrowing is always allowed — a hook may hand back fewer buckets, or none
|
|
29
|
+
* at all, on any surface.
|
|
30
|
+
*/
|
|
31
|
+
import type { PipelineMode } from "./pipeline";
|
|
32
|
+
/** Buckets a mode retrieves from when nothing overrides it. */
|
|
33
|
+
export declare function defaultBuckets(mode: PipelineMode): string[];
|
|
34
|
+
/** What a surface knows about the caller when it asks for buckets. */
|
|
35
|
+
export interface BucketsForContext {
|
|
36
|
+
/** The pipeline the turn is running through */
|
|
37
|
+
mode: PipelineMode;
|
|
38
|
+
/**
|
|
39
|
+
* Stable identifier for the caller (JWT subject, channel sender id, ...).
|
|
40
|
+
* Absent on anonymous surfaces — see the clamp in {@link resolveBuckets}.
|
|
41
|
+
*/
|
|
42
|
+
sender?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Per-request retrieval bucket policy.
|
|
46
|
+
*
|
|
47
|
+
* Return the buckets this caller may retrieve from, or `undefined` to leave
|
|
48
|
+
* the mode defaults in place. May be async — role lookups usually are.
|
|
49
|
+
*/
|
|
50
|
+
export type BucketsFor = (ctx: BucketsForContext) => string[] | undefined | Promise<string[] | undefined>;
|
|
51
|
+
/**
|
|
52
|
+
* Ask the configured `bucketsFor` hook which buckets this turn may retrieve
|
|
53
|
+
* from, and enforce the anonymous ceiling on its answer.
|
|
54
|
+
*
|
|
55
|
+
* Returns `undefined` when the caller should keep the mode defaults: no hook
|
|
56
|
+
* configured, or a hook that returned `undefined`. An explicitly empty array
|
|
57
|
+
* is honoured as "retrieve nothing" and is never silently widened back to the
|
|
58
|
+
* defaults — that fallback would hand a private-mode caller the `private`
|
|
59
|
+
* bucket precisely when the hook had refused it.
|
|
60
|
+
*
|
|
61
|
+
* Without a sender the answer is filtered down to `defaultBuckets(mode)`, so
|
|
62
|
+
* an unidentified caller can never end up with more than the surface would
|
|
63
|
+
* have retrieved on its own. Pass the sender to unlock the extra buckets an
|
|
64
|
+
* identified caller is entitled to.
|
|
65
|
+
*
|
|
66
|
+
* A rejected hook propagates: retrieval scope is a security decision, and a
|
|
67
|
+
* policy lookup that failed must not silently fall back to the defaults.
|
|
68
|
+
*/
|
|
69
|
+
export declare function resolveBuckets({ mode, sender, bucketsFor, }: {
|
|
70
|
+
mode: PipelineMode;
|
|
71
|
+
sender?: string;
|
|
72
|
+
bucketsFor?: BucketsFor;
|
|
73
|
+
}): Promise<string[] | undefined>;
|
|
74
|
+
//# sourceMappingURL=buckets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buckets.d.ts","sourceRoot":"","sources":["../../src/core/buckets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,EAAE,CAE3D;AAED,sEAAsE;AACtE,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,IAAI,EAAE,YAAY,CAAC;IACnB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,CACvB,GAAG,EAAE,iBAAiB,KACnB,MAAM,EAAE,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;AAsB1D;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,cAAc,CAAC,EACnC,IAAI,EACJ,MAAM,EACN,UAAU,GACX,EAAE;IACD,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,CAYhC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retrieval bucket resolution tests.
|
|
3
|
+
*
|
|
4
|
+
* The security invariant — a hook can never widen retrieval for a caller the
|
|
5
|
+
* surface could not name, which on the public pipeline means private
|
|
6
|
+
* knowledge stays unreachable — is asserted here rather than per-route,
|
|
7
|
+
* because this is the single place that enforces it.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=buckets.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buckets.test.d.ts","sourceRoot":"","sources":["../../src/core/buckets.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
package/dist/core/pipeline.d.ts
CHANGED
|
@@ -32,9 +32,15 @@ export interface PreparedChat {
|
|
|
32
32
|
* optional, and blank (or whitespace-only) values are ignored: omit them and
|
|
33
33
|
* the prompt is exactly what it has always been.
|
|
34
34
|
*
|
|
35
|
+
* `buckets` does the same for retrieval scope. It is taken at face value —
|
|
36
|
+
* this is the low-level primitive, and it trusts its caller. A surface that
|
|
37
|
+
* derives buckets from anything a request controls must run them through
|
|
38
|
+
* `resolveBuckets` (see ./buckets) first, which is where the anonymous
|
|
39
|
+
* ceiling is enforced.
|
|
40
|
+
*
|
|
35
41
|
* @throws if the conversation contains no user message
|
|
36
42
|
*/
|
|
37
|
-
export declare function prepareChat({ store, prompts, mode, messages, personaLayer, channelHint, }: {
|
|
43
|
+
export declare function prepareChat({ store, prompts, mode, messages, personaLayer, channelHint, buckets, }: {
|
|
38
44
|
store: VectorStore;
|
|
39
45
|
prompts: PromptLoader;
|
|
40
46
|
mode: PipelineMode;
|
|
@@ -43,5 +49,10 @@ export declare function prepareChat({ store, prompts, mode, messages, personaLay
|
|
|
43
49
|
personaLayer?: string;
|
|
44
50
|
/** Extra system-prompt section describing the delivery channel */
|
|
45
51
|
channelHint?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Retrieval buckets for this turn, replacing the mode default of
|
|
54
|
+
* `["base", mode]`. An empty array retrieves nothing.
|
|
55
|
+
*/
|
|
56
|
+
buckets?: string[];
|
|
46
57
|
}): Promise<PreparedChat>;
|
|
47
58
|
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAOD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,WAAW,CAAC,EAChC,KAAK,EACL,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,OAAO,GACR,EAAE;IACD,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,GAAG,OAAO,CAAC,YAAY,CAAC,CAmBxB"}
|
package/dist/core/retrieval.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type Client as LibsqlClient } from "@libsql/client";
|
|
2
2
|
import type OpenAI from "openai";
|
|
3
|
-
import { type Bucket } from "./loaders";
|
|
4
3
|
/**
|
|
5
4
|
* How a {@link VectorStore} obtains its database connection: either credentials
|
|
6
5
|
* to open its own, or an existing libsql client to reuse.
|
|
@@ -37,6 +36,17 @@ export declare class VectorStore {
|
|
|
37
36
|
build(): Promise<void>;
|
|
38
37
|
private cleanupStaleChunks;
|
|
39
38
|
private static cosine;
|
|
40
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Retrieve top-k across allowed buckets; compute similarity in app (simple
|
|
41
|
+
* & portable).
|
|
42
|
+
*
|
|
43
|
+
* `allowed` is a bucket-name list rather than the {@link Bucket} union: the
|
|
44
|
+
* `chunks` table constrains nothing, so a deployment that ingests its own
|
|
45
|
+
* buckets can query them (`build` only writes and prunes the three the
|
|
46
|
+
* knowledge loader walks). Names are bound as query parameters, never
|
|
47
|
+
* interpolated. An empty list retrieves nothing, and short-circuits before
|
|
48
|
+
* the embedding call.
|
|
49
|
+
*/
|
|
50
|
+
query(q: string, k?: number, allowed?: string[]): Promise<string[]>;
|
|
41
51
|
}
|
|
42
52
|
//# sourceMappingURL=retrieval.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retrieval.d.ts","sourceRoot":"","sources":["../../src/core/retrieval.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"retrieval.d.ts","sourceRoot":"","sources":["../../src/core/retrieval.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AA0BjC;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,CACA;IACE,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,uBAAuB;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,KAAK,CAAC;CACxB,GACD;IACE,gFAAgF;IAChF,cAAc,EAAE,YAAY,CAAC;IAC7B,WAAW,CAAC,EAAE,KAAK,CAAC;IACpB,iBAAiB,CAAC,EAAE,KAAK,CAAC;CAC3B,CACJ,CAAC;AAEF,qBAAa,WAAW;IAUpB,OAAO,CAAC,MAAM;IAThB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;IAC1B,OAAO,CAAC,YAAY,CAAS;IAE7B,YACU,MAAM,EAAE,MAAM,EACtB,OAAO,EAAE,kBAAkB,EAS5B;IAGK,KAAK,kBA0FV;YAGa,kBAAkB;IA8BhC,OAAO,CAAC,MAAM,CAAC,MAAM;IAYrB;;;;;;;;;;OAUG;IACG,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,SAAI,EAAE,OAAO,GAAE,MAAM,EAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAwB7E;CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export type { ChatBotConfig, ChatButtonConfig, ChatConfig, ChatMessage, ChatMode
|
|
|
16
16
|
export { Chat, ChatBot, ChatButton } from "./client";
|
|
17
17
|
export type { AnswerFn, AnswerFnInput, AnswerFnResult, AnswerOptions, AnswerUsage, } from "./core/answer";
|
|
18
18
|
export { answerOnce, answerStream } from "./core/answer";
|
|
19
|
+
export type { BucketsFor, BucketsForContext } from "./core/buckets";
|
|
20
|
+
export { defaultBuckets, resolveBuckets } from "./core/buckets";
|
|
19
21
|
export { detectLeakage, guardOutput, scrubOutput } from "./core/guardrails";
|
|
20
22
|
export { completeOnce, completeStream, DEFAULT_MODEL } from "./core/llm";
|
|
21
23
|
export { loadKnowledge } from "./core/loaders";
|
|
@@ -29,7 +31,7 @@ export type { MCPServerOptions, MCPTransportMode } from "./mcp-server";
|
|
|
29
31
|
export { createMCPServer } from "./mcp-server";
|
|
30
32
|
export { createAuthMiddleware } from "./middleware/auth";
|
|
31
33
|
export { cors } from "./middleware/cors";
|
|
32
|
-
export { createJWTMiddleware } from "./middleware/jwt";
|
|
34
|
+
export { createJWTMiddleware, jwtSubject } from "./middleware/jwt";
|
|
33
35
|
export { createRateLimiter } from "./middleware/ratelimit";
|
|
34
36
|
export { createReferrerCheck } from "./middleware/referrer";
|
|
35
37
|
export { createSessionMiddleware } from "./middleware/session";
|
|
@@ -38,5 +40,5 @@ export { openaiRoutes } from "./routes/openai";
|
|
|
38
40
|
export { privateRoutes } from "./routes/private";
|
|
39
41
|
export { publicRoutes } from "./routes/public";
|
|
40
42
|
export { createServer } from "./server";
|
|
41
|
-
export type { BotBranding, BotChatConfig, BotIdentity, ChatterConfig, EmbeddingChunk, KnowledgeDocument, ServerDependencies, } from "./types";
|
|
43
|
+
export type { BotBranding, BotChatConfig, BotIdentity, ChatterConfig, CustomRoutes, EmbeddingChunk, KnowledgeDocument, ServerDependencies, } from "./types";
|
|
42
44
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEzE,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,WAAW,EACX,QAAQ,EACR,eAAe,GAChB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACrD,YAAY,EACV,QAAQ,EACR,aAAa,EACb,cAAc,EACd,aAAa,EACb,WAAW,GACZ,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEnF,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEvE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEzE,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,WAAW,EACX,QAAQ,EACR,eAAe,GAChB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACrD,YAAY,EACV,QAAQ,EACR,aAAa,EACb,cAAc,EACd,aAAa,EACb,WAAW,GACZ,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACzD,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEnF,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEvE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,YAAY,EACV,WAAW,EACX,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2847,8 +2847,8 @@ var require_resolve = __commonJS({
|
|
|
2847
2847
|
}
|
|
2848
2848
|
return count;
|
|
2849
2849
|
}
|
|
2850
|
-
function getFullPath(resolver, id = "",
|
|
2851
|
-
if (
|
|
2850
|
+
function getFullPath(resolver, id = "", normalize2) {
|
|
2851
|
+
if (normalize2 !== false)
|
|
2852
2852
|
id = normalizeId(id);
|
|
2853
2853
|
const p = resolver.parse(id);
|
|
2854
2854
|
return _getFullPath(resolver, p);
|
|
@@ -4244,7 +4244,7 @@ var require_fast_uri = __commonJS({
|
|
|
4244
4244
|
"use strict";
|
|
4245
4245
|
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
4246
4246
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
4247
|
-
function
|
|
4247
|
+
function normalize2(uri, options) {
|
|
4248
4248
|
if (typeof uri === "string") {
|
|
4249
4249
|
uri = /** @type {T} */
|
|
4250
4250
|
normalizeString(uri, options);
|
|
@@ -4537,7 +4537,7 @@ var require_fast_uri = __commonJS({
|
|
|
4537
4537
|
}
|
|
4538
4538
|
var fastUri = {
|
|
4539
4539
|
SCHEMES,
|
|
4540
|
-
normalize,
|
|
4540
|
+
normalize: normalize2,
|
|
4541
4541
|
resolve,
|
|
4542
4542
|
resolveComponent,
|
|
4543
4543
|
equal,
|
|
@@ -7550,16 +7550,19 @@ __export(index_exports, {
|
|
|
7550
7550
|
createServer: () => createServer,
|
|
7551
7551
|
createSession: () => createSession,
|
|
7552
7552
|
createSessionMiddleware: () => createSessionMiddleware,
|
|
7553
|
+
defaultBuckets: () => defaultBuckets,
|
|
7553
7554
|
demoRoutes: () => demoRoutes,
|
|
7554
7555
|
detectLeakage: () => detectLeakage,
|
|
7555
7556
|
getActiveSessions: () => getActiveSessions,
|
|
7556
7557
|
getSessionInfo: () => getSessionInfo,
|
|
7557
7558
|
guardOutput: () => guardOutput,
|
|
7559
|
+
jwtSubject: () => jwtSubject,
|
|
7558
7560
|
loadKnowledge: () => loadKnowledge,
|
|
7559
7561
|
openaiRoutes: () => openaiRoutes,
|
|
7560
7562
|
prepareChat: () => prepareChat,
|
|
7561
7563
|
privateRoutes: () => privateRoutes,
|
|
7562
7564
|
publicRoutes: () => publicRoutes,
|
|
7565
|
+
resolveBuckets: () => resolveBuckets,
|
|
7563
7566
|
scrubOutput: () => scrubOutput,
|
|
7564
7567
|
validateSession: () => validateSession
|
|
7565
7568
|
});
|
|
@@ -7783,6 +7786,37 @@ async function* answerStream({
|
|
|
7783
7786
|
yield* completeStream({ client, system, messages, temperature, model });
|
|
7784
7787
|
}
|
|
7785
7788
|
|
|
7789
|
+
// src/core/buckets.ts
|
|
7790
|
+
function defaultBuckets(mode) {
|
|
7791
|
+
return ["base", mode];
|
|
7792
|
+
}
|
|
7793
|
+
function isIdentified(sender) {
|
|
7794
|
+
return typeof sender === "string" && sender.trim().length > 0;
|
|
7795
|
+
}
|
|
7796
|
+
function normalize(buckets) {
|
|
7797
|
+
const out = [];
|
|
7798
|
+
for (const raw of buckets) {
|
|
7799
|
+
if (typeof raw !== "string") continue;
|
|
7800
|
+
const bucket = raw.trim();
|
|
7801
|
+
if (bucket && !out.includes(bucket)) out.push(bucket);
|
|
7802
|
+
}
|
|
7803
|
+
return out;
|
|
7804
|
+
}
|
|
7805
|
+
async function resolveBuckets({
|
|
7806
|
+
mode,
|
|
7807
|
+
sender,
|
|
7808
|
+
bucketsFor
|
|
7809
|
+
}) {
|
|
7810
|
+
if (!bucketsFor) return void 0;
|
|
7811
|
+
const identified = isIdentified(sender);
|
|
7812
|
+
const requested = await bucketsFor(identified ? { mode, sender } : { mode });
|
|
7813
|
+
if (!Array.isArray(requested)) return void 0;
|
|
7814
|
+
const cleaned = normalize(requested);
|
|
7815
|
+
if (identified) return cleaned;
|
|
7816
|
+
const ceiling = new Set(defaultBuckets(mode));
|
|
7817
|
+
return cleaned.filter((bucket) => ceiling.has(bucket));
|
|
7818
|
+
}
|
|
7819
|
+
|
|
7786
7820
|
// src/core/loaders.ts
|
|
7787
7821
|
var import_node_fs = require("node:fs");
|
|
7788
7822
|
var import_node_path = require("node:path");
|
|
@@ -7821,14 +7855,15 @@ async function prepareChat({
|
|
|
7821
7855
|
mode,
|
|
7822
7856
|
messages,
|
|
7823
7857
|
personaLayer,
|
|
7824
|
-
channelHint
|
|
7858
|
+
channelHint,
|
|
7859
|
+
buckets
|
|
7825
7860
|
}) {
|
|
7826
7861
|
const lastUserMsg = [...messages].reverse().find((m) => m.role === "user");
|
|
7827
7862
|
if (!lastUserMsg) {
|
|
7828
7863
|
throw new Error("no user message found in conversation");
|
|
7829
7864
|
}
|
|
7830
7865
|
const { topK, label } = MODE_SETTINGS[mode];
|
|
7831
|
-
const ctx = await store.query(lastUserMsg.content, topK,
|
|
7866
|
+
const ctx = await store.query(lastUserMsg.content, topK, buckets ?? defaultBuckets(mode));
|
|
7832
7867
|
const persona = personaLayer?.trim() || (mode === "private" ? prompts.privatePersona : prompts.publicPersona);
|
|
7833
7868
|
const hint = channelHint?.trim();
|
|
7834
7869
|
const system = [
|
|
@@ -8020,8 +8055,19 @@ var VectorStore = class _VectorStore {
|
|
|
8020
8055
|
}
|
|
8021
8056
|
return dot / (Math.sqrt(na) * Math.sqrt(nb));
|
|
8022
8057
|
}
|
|
8023
|
-
|
|
8058
|
+
/**
|
|
8059
|
+
* Retrieve top-k across allowed buckets; compute similarity in app (simple
|
|
8060
|
+
* & portable).
|
|
8061
|
+
*
|
|
8062
|
+
* `allowed` is a bucket-name list rather than the {@link Bucket} union: the
|
|
8063
|
+
* `chunks` table constrains nothing, so a deployment that ingests its own
|
|
8064
|
+
* buckets can query them (`build` only writes and prunes the three the
|
|
8065
|
+
* knowledge loader walks). Names are bound as query parameters, never
|
|
8066
|
+
* interpolated. An empty list retrieves nothing, and short-circuits before
|
|
8067
|
+
* the embedding call.
|
|
8068
|
+
*/
|
|
8024
8069
|
async query(q, k = 6, allowed = ["base"]) {
|
|
8070
|
+
if (allowed.length === 0) return [];
|
|
8025
8071
|
const qv = (await this.client.embeddings.create({ model: EMB_MODEL, input: [q] })).data[0].embedding;
|
|
8026
8072
|
const placeholders = allowed.map(() => "?").join(",");
|
|
8027
8073
|
const res = await this.db.execute({
|
|
@@ -32297,7 +32343,8 @@ async function createMCPServer(config2) {
|
|
|
32297
32343
|
if (!lastUserMsg) {
|
|
32298
32344
|
throw new Error("No user message found in conversation");
|
|
32299
32345
|
}
|
|
32300
|
-
const
|
|
32346
|
+
const buckets = await resolveBuckets({ mode: "public", bucketsFor: config2.bucketsFor }) ?? defaultBuckets("public");
|
|
32347
|
+
const ctx = await store.query(lastUserMsg.content, 6, buckets);
|
|
32301
32348
|
const system = [
|
|
32302
32349
|
prompts.baseSystemRules,
|
|
32303
32350
|
prompts.publicPersona,
|
|
@@ -32383,7 +32430,8 @@ ${ctx.join("\n\n")}`
|
|
|
32383
32430
|
if (!lastUserMsg) {
|
|
32384
32431
|
throw new Error("No user message found in conversation");
|
|
32385
32432
|
}
|
|
32386
|
-
const
|
|
32433
|
+
const buckets = await resolveBuckets({ mode: "private", bucketsFor: config2.bucketsFor }) ?? defaultBuckets("private");
|
|
32434
|
+
const ctx = await store.query(lastUserMsg.content, 8, buckets);
|
|
32387
32435
|
const system = [
|
|
32388
32436
|
prompts.baseSystemRules,
|
|
32389
32437
|
prompts.privatePersona,
|
|
@@ -32513,6 +32561,10 @@ function resolveOrigin(requestOrigin, allowedOrigins, allowAll) {
|
|
|
32513
32561
|
|
|
32514
32562
|
// src/middleware/jwt.ts
|
|
32515
32563
|
var import_jose2 = require("jose");
|
|
32564
|
+
function jwtSubject(c) {
|
|
32565
|
+
const sub = c.jwtSub;
|
|
32566
|
+
return sub && sub.trim().length > 0 ? sub : void 0;
|
|
32567
|
+
}
|
|
32516
32568
|
function createJWTMiddleware(config2) {
|
|
32517
32569
|
let jwks = null;
|
|
32518
32570
|
let spkiKey = null;
|
|
@@ -32802,7 +32854,8 @@ function demoRoutes(deps) {
|
|
|
32802
32854
|
if (!lastUserMsg) {
|
|
32803
32855
|
return c.json({ error: "no user message found in conversation" }, 400);
|
|
32804
32856
|
}
|
|
32805
|
-
const
|
|
32857
|
+
const buckets = await resolveBuckets({ mode: "public", bucketsFor: config2.bucketsFor }) ?? defaultBuckets("public");
|
|
32858
|
+
const ctx = await store.query(lastUserMsg.content, 6, buckets);
|
|
32806
32859
|
const system = [
|
|
32807
32860
|
prompts.baseSystemRules,
|
|
32808
32861
|
prompts.publicPersona,
|
|
@@ -32908,9 +32961,14 @@ function openaiRoutes(deps) {
|
|
|
32908
32961
|
}
|
|
32909
32962
|
const { stream: wantsStream3, temperature: rawTemperature } = body;
|
|
32910
32963
|
const temperature = typeof rawTemperature === "number" && Number.isFinite(rawTemperature) ? Math.min(Math.max(rawTemperature, 0), 2) : void 0;
|
|
32964
|
+
const buckets = await resolveBuckets({
|
|
32965
|
+
mode,
|
|
32966
|
+
sender: jwtSubject(c),
|
|
32967
|
+
bucketsFor: config2.bucketsFor
|
|
32968
|
+
});
|
|
32911
32969
|
let system;
|
|
32912
32970
|
try {
|
|
32913
|
-
({ system } = await prepareChat({ store, prompts, mode, messages }));
|
|
32971
|
+
({ system } = await prepareChat({ store, prompts, mode, messages, buckets }));
|
|
32914
32972
|
} catch {
|
|
32915
32973
|
return errorJson(c, 400, "Conversation must contain at least one user message");
|
|
32916
32974
|
}
|
|
@@ -33007,9 +33065,14 @@ function privateRoutes(deps) {
|
|
|
33007
33065
|
} else {
|
|
33008
33066
|
return c.json({ error: "either 'message' or 'messages' required" }, 400);
|
|
33009
33067
|
}
|
|
33068
|
+
const buckets = await resolveBuckets({
|
|
33069
|
+
mode: "private",
|
|
33070
|
+
sender: jwtSubject(c),
|
|
33071
|
+
bucketsFor: config2.bucketsFor
|
|
33072
|
+
});
|
|
33010
33073
|
let system;
|
|
33011
33074
|
try {
|
|
33012
|
-
({ system } = await prepareChat({ store, prompts, mode: "private", messages }));
|
|
33075
|
+
({ system } = await prepareChat({ store, prompts, mode: "private", messages, buckets }));
|
|
33013
33076
|
} catch {
|
|
33014
33077
|
return c.json({ error: "no user message found in conversation" }, 400);
|
|
33015
33078
|
}
|
|
@@ -33070,9 +33133,10 @@ function publicRoutes(deps) {
|
|
|
33070
33133
|
} else {
|
|
33071
33134
|
return c.json({ error: "either 'message' or 'messages' required" }, 400);
|
|
33072
33135
|
}
|
|
33136
|
+
const buckets = await resolveBuckets({ mode: "public", bucketsFor: config2.bucketsFor });
|
|
33073
33137
|
let system;
|
|
33074
33138
|
try {
|
|
33075
|
-
({ system } = await prepareChat({ store, prompts, mode: "public", messages }));
|
|
33139
|
+
({ system } = await prepareChat({ store, prompts, mode: "public", messages, buckets }));
|
|
33076
33140
|
} catch {
|
|
33077
33141
|
return c.json({ error: "no user message found in conversation" }, 400);
|
|
33078
33142
|
}
|
|
@@ -33246,7 +33310,7 @@ async function createServer(config2) {
|
|
|
33246
33310
|
app.route("/", openaiRoutes(deps));
|
|
33247
33311
|
}
|
|
33248
33312
|
if (config2.customRoutes) {
|
|
33249
|
-
config2.customRoutes(app, deps);
|
|
33313
|
+
await config2.customRoutes(app, deps);
|
|
33250
33314
|
}
|
|
33251
33315
|
console.log(`\u2705 ${config2.bot.name} server ready`);
|
|
33252
33316
|
return app;
|
|
@@ -33273,16 +33337,19 @@ async function createServer(config2) {
|
|
|
33273
33337
|
createServer,
|
|
33274
33338
|
createSession,
|
|
33275
33339
|
createSessionMiddleware,
|
|
33340
|
+
defaultBuckets,
|
|
33276
33341
|
demoRoutes,
|
|
33277
33342
|
detectLeakage,
|
|
33278
33343
|
getActiveSessions,
|
|
33279
33344
|
getSessionInfo,
|
|
33280
33345
|
guardOutput,
|
|
33346
|
+
jwtSubject,
|
|
33281
33347
|
loadKnowledge,
|
|
33282
33348
|
openaiRoutes,
|
|
33283
33349
|
prepareChat,
|
|
33284
33350
|
privateRoutes,
|
|
33285
33351
|
publicRoutes,
|
|
33352
|
+
resolveBuckets,
|
|
33286
33353
|
scrubOutput,
|
|
33287
33354
|
validateSession
|
|
33288
33355
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -2851,8 +2851,8 @@ var require_resolve = __commonJS({
|
|
|
2851
2851
|
}
|
|
2852
2852
|
return count;
|
|
2853
2853
|
}
|
|
2854
|
-
function getFullPath(resolver, id = "",
|
|
2855
|
-
if (
|
|
2854
|
+
function getFullPath(resolver, id = "", normalize2) {
|
|
2855
|
+
if (normalize2 !== false)
|
|
2856
2856
|
id = normalizeId(id);
|
|
2857
2857
|
const p = resolver.parse(id);
|
|
2858
2858
|
return _getFullPath(resolver, p);
|
|
@@ -4248,7 +4248,7 @@ var require_fast_uri = __commonJS({
|
|
|
4248
4248
|
"use strict";
|
|
4249
4249
|
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
4250
4250
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
4251
|
-
function
|
|
4251
|
+
function normalize2(uri, options) {
|
|
4252
4252
|
if (typeof uri === "string") {
|
|
4253
4253
|
uri = /** @type {T} */
|
|
4254
4254
|
normalizeString(uri, options);
|
|
@@ -4541,7 +4541,7 @@ var require_fast_uri = __commonJS({
|
|
|
4541
4541
|
}
|
|
4542
4542
|
var fastUri = {
|
|
4543
4543
|
SCHEMES,
|
|
4544
|
-
normalize,
|
|
4544
|
+
normalize: normalize2,
|
|
4545
4545
|
resolve,
|
|
4546
4546
|
resolveComponent,
|
|
4547
4547
|
equal,
|
|
@@ -7749,6 +7749,37 @@ async function* answerStream({
|
|
|
7749
7749
|
yield* completeStream({ client, system, messages, temperature, model });
|
|
7750
7750
|
}
|
|
7751
7751
|
|
|
7752
|
+
// src/core/buckets.ts
|
|
7753
|
+
function defaultBuckets(mode) {
|
|
7754
|
+
return ["base", mode];
|
|
7755
|
+
}
|
|
7756
|
+
function isIdentified(sender) {
|
|
7757
|
+
return typeof sender === "string" && sender.trim().length > 0;
|
|
7758
|
+
}
|
|
7759
|
+
function normalize(buckets) {
|
|
7760
|
+
const out = [];
|
|
7761
|
+
for (const raw of buckets) {
|
|
7762
|
+
if (typeof raw !== "string") continue;
|
|
7763
|
+
const bucket = raw.trim();
|
|
7764
|
+
if (bucket && !out.includes(bucket)) out.push(bucket);
|
|
7765
|
+
}
|
|
7766
|
+
return out;
|
|
7767
|
+
}
|
|
7768
|
+
async function resolveBuckets({
|
|
7769
|
+
mode,
|
|
7770
|
+
sender,
|
|
7771
|
+
bucketsFor
|
|
7772
|
+
}) {
|
|
7773
|
+
if (!bucketsFor) return void 0;
|
|
7774
|
+
const identified = isIdentified(sender);
|
|
7775
|
+
const requested = await bucketsFor(identified ? { mode, sender } : { mode });
|
|
7776
|
+
if (!Array.isArray(requested)) return void 0;
|
|
7777
|
+
const cleaned = normalize(requested);
|
|
7778
|
+
if (identified) return cleaned;
|
|
7779
|
+
const ceiling = new Set(defaultBuckets(mode));
|
|
7780
|
+
return cleaned.filter((bucket) => ceiling.has(bucket));
|
|
7781
|
+
}
|
|
7782
|
+
|
|
7752
7783
|
// src/core/loaders.ts
|
|
7753
7784
|
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
7754
7785
|
import { join } from "node:path";
|
|
@@ -7787,14 +7818,15 @@ async function prepareChat({
|
|
|
7787
7818
|
mode,
|
|
7788
7819
|
messages,
|
|
7789
7820
|
personaLayer,
|
|
7790
|
-
channelHint
|
|
7821
|
+
channelHint,
|
|
7822
|
+
buckets
|
|
7791
7823
|
}) {
|
|
7792
7824
|
const lastUserMsg = [...messages].reverse().find((m) => m.role === "user");
|
|
7793
7825
|
if (!lastUserMsg) {
|
|
7794
7826
|
throw new Error("no user message found in conversation");
|
|
7795
7827
|
}
|
|
7796
7828
|
const { topK, label } = MODE_SETTINGS[mode];
|
|
7797
|
-
const ctx = await store.query(lastUserMsg.content, topK,
|
|
7829
|
+
const ctx = await store.query(lastUserMsg.content, topK, buckets ?? defaultBuckets(mode));
|
|
7798
7830
|
const persona = personaLayer?.trim() || (mode === "private" ? prompts.privatePersona : prompts.publicPersona);
|
|
7799
7831
|
const hint = channelHint?.trim();
|
|
7800
7832
|
const system = [
|
|
@@ -7986,8 +8018,19 @@ var VectorStore = class _VectorStore {
|
|
|
7986
8018
|
}
|
|
7987
8019
|
return dot / (Math.sqrt(na) * Math.sqrt(nb));
|
|
7988
8020
|
}
|
|
7989
|
-
|
|
8021
|
+
/**
|
|
8022
|
+
* Retrieve top-k across allowed buckets; compute similarity in app (simple
|
|
8023
|
+
* & portable).
|
|
8024
|
+
*
|
|
8025
|
+
* `allowed` is a bucket-name list rather than the {@link Bucket} union: the
|
|
8026
|
+
* `chunks` table constrains nothing, so a deployment that ingests its own
|
|
8027
|
+
* buckets can query them (`build` only writes and prunes the three the
|
|
8028
|
+
* knowledge loader walks). Names are bound as query parameters, never
|
|
8029
|
+
* interpolated. An empty list retrieves nothing, and short-circuits before
|
|
8030
|
+
* the embedding call.
|
|
8031
|
+
*/
|
|
7990
8032
|
async query(q, k = 6, allowed = ["base"]) {
|
|
8033
|
+
if (allowed.length === 0) return [];
|
|
7991
8034
|
const qv = (await this.client.embeddings.create({ model: EMB_MODEL, input: [q] })).data[0].embedding;
|
|
7992
8035
|
const placeholders = allowed.map(() => "?").join(",");
|
|
7993
8036
|
const res = await this.db.execute({
|
|
@@ -32263,7 +32306,8 @@ async function createMCPServer(config2) {
|
|
|
32263
32306
|
if (!lastUserMsg) {
|
|
32264
32307
|
throw new Error("No user message found in conversation");
|
|
32265
32308
|
}
|
|
32266
|
-
const
|
|
32309
|
+
const buckets = await resolveBuckets({ mode: "public", bucketsFor: config2.bucketsFor }) ?? defaultBuckets("public");
|
|
32310
|
+
const ctx = await store.query(lastUserMsg.content, 6, buckets);
|
|
32267
32311
|
const system = [
|
|
32268
32312
|
prompts.baseSystemRules,
|
|
32269
32313
|
prompts.publicPersona,
|
|
@@ -32349,7 +32393,8 @@ ${ctx.join("\n\n")}`
|
|
|
32349
32393
|
if (!lastUserMsg) {
|
|
32350
32394
|
throw new Error("No user message found in conversation");
|
|
32351
32395
|
}
|
|
32352
|
-
const
|
|
32396
|
+
const buckets = await resolveBuckets({ mode: "private", bucketsFor: config2.bucketsFor }) ?? defaultBuckets("private");
|
|
32397
|
+
const ctx = await store.query(lastUserMsg.content, 8, buckets);
|
|
32353
32398
|
const system = [
|
|
32354
32399
|
prompts.baseSystemRules,
|
|
32355
32400
|
prompts.privatePersona,
|
|
@@ -32479,6 +32524,10 @@ function resolveOrigin(requestOrigin, allowedOrigins, allowAll) {
|
|
|
32479
32524
|
|
|
32480
32525
|
// src/middleware/jwt.ts
|
|
32481
32526
|
import { createRemoteJWKSet, importSPKI, jwtVerify as jwtVerify2 } from "jose";
|
|
32527
|
+
function jwtSubject(c) {
|
|
32528
|
+
const sub = c.jwtSub;
|
|
32529
|
+
return sub && sub.trim().length > 0 ? sub : void 0;
|
|
32530
|
+
}
|
|
32482
32531
|
function createJWTMiddleware(config2) {
|
|
32483
32532
|
let jwks = null;
|
|
32484
32533
|
let spkiKey = null;
|
|
@@ -32768,7 +32817,8 @@ function demoRoutes(deps) {
|
|
|
32768
32817
|
if (!lastUserMsg) {
|
|
32769
32818
|
return c.json({ error: "no user message found in conversation" }, 400);
|
|
32770
32819
|
}
|
|
32771
|
-
const
|
|
32820
|
+
const buckets = await resolveBuckets({ mode: "public", bucketsFor: config2.bucketsFor }) ?? defaultBuckets("public");
|
|
32821
|
+
const ctx = await store.query(lastUserMsg.content, 6, buckets);
|
|
32772
32822
|
const system = [
|
|
32773
32823
|
prompts.baseSystemRules,
|
|
32774
32824
|
prompts.publicPersona,
|
|
@@ -32874,9 +32924,14 @@ function openaiRoutes(deps) {
|
|
|
32874
32924
|
}
|
|
32875
32925
|
const { stream: wantsStream3, temperature: rawTemperature } = body;
|
|
32876
32926
|
const temperature = typeof rawTemperature === "number" && Number.isFinite(rawTemperature) ? Math.min(Math.max(rawTemperature, 0), 2) : void 0;
|
|
32927
|
+
const buckets = await resolveBuckets({
|
|
32928
|
+
mode,
|
|
32929
|
+
sender: jwtSubject(c),
|
|
32930
|
+
bucketsFor: config2.bucketsFor
|
|
32931
|
+
});
|
|
32877
32932
|
let system;
|
|
32878
32933
|
try {
|
|
32879
|
-
({ system } = await prepareChat({ store, prompts, mode, messages }));
|
|
32934
|
+
({ system } = await prepareChat({ store, prompts, mode, messages, buckets }));
|
|
32880
32935
|
} catch {
|
|
32881
32936
|
return errorJson(c, 400, "Conversation must contain at least one user message");
|
|
32882
32937
|
}
|
|
@@ -32973,9 +33028,14 @@ function privateRoutes(deps) {
|
|
|
32973
33028
|
} else {
|
|
32974
33029
|
return c.json({ error: "either 'message' or 'messages' required" }, 400);
|
|
32975
33030
|
}
|
|
33031
|
+
const buckets = await resolveBuckets({
|
|
33032
|
+
mode: "private",
|
|
33033
|
+
sender: jwtSubject(c),
|
|
33034
|
+
bucketsFor: config2.bucketsFor
|
|
33035
|
+
});
|
|
32976
33036
|
let system;
|
|
32977
33037
|
try {
|
|
32978
|
-
({ system } = await prepareChat({ store, prompts, mode: "private", messages }));
|
|
33038
|
+
({ system } = await prepareChat({ store, prompts, mode: "private", messages, buckets }));
|
|
32979
33039
|
} catch {
|
|
32980
33040
|
return c.json({ error: "no user message found in conversation" }, 400);
|
|
32981
33041
|
}
|
|
@@ -33036,9 +33096,10 @@ function publicRoutes(deps) {
|
|
|
33036
33096
|
} else {
|
|
33037
33097
|
return c.json({ error: "either 'message' or 'messages' required" }, 400);
|
|
33038
33098
|
}
|
|
33099
|
+
const buckets = await resolveBuckets({ mode: "public", bucketsFor: config2.bucketsFor });
|
|
33039
33100
|
let system;
|
|
33040
33101
|
try {
|
|
33041
|
-
({ system } = await prepareChat({ store, prompts, mode: "public", messages }));
|
|
33102
|
+
({ system } = await prepareChat({ store, prompts, mode: "public", messages, buckets }));
|
|
33042
33103
|
} catch {
|
|
33043
33104
|
return c.json({ error: "no user message found in conversation" }, 400);
|
|
33044
33105
|
}
|
|
@@ -33211,7 +33272,7 @@ async function createServer(config2) {
|
|
|
33211
33272
|
app.route("/", openaiRoutes(deps));
|
|
33212
33273
|
}
|
|
33213
33274
|
if (config2.customRoutes) {
|
|
33214
|
-
config2.customRoutes(app, deps);
|
|
33275
|
+
await config2.customRoutes(app, deps);
|
|
33215
33276
|
}
|
|
33216
33277
|
console.log(`\u2705 ${config2.bot.name} server ready`);
|
|
33217
33278
|
return app;
|
|
@@ -33240,16 +33301,19 @@ export {
|
|
|
33240
33301
|
createServer,
|
|
33241
33302
|
createSession,
|
|
33242
33303
|
createSessionMiddleware,
|
|
33304
|
+
defaultBuckets,
|
|
33243
33305
|
demoRoutes,
|
|
33244
33306
|
detectLeakage,
|
|
33245
33307
|
getActiveSessions,
|
|
33246
33308
|
getSessionInfo,
|
|
33247
33309
|
guardOutput,
|
|
33310
|
+
jwtSubject,
|
|
33248
33311
|
loadKnowledge,
|
|
33249
33312
|
openaiRoutes,
|
|
33250
33313
|
prepareChat,
|
|
33251
33314
|
privateRoutes,
|
|
33252
33315
|
publicRoutes,
|
|
33316
|
+
resolveBuckets,
|
|
33253
33317
|
scrubOutput,
|
|
33254
33318
|
validateSession
|
|
33255
33319
|
};
|
package/dist/mcp-server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAapE,YAAY,EACV,WAAW,EACX,QAAQ,EACR,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,gBAAgB,sBAkT7D"}
|
package/dist/mcp-server.js
CHANGED
|
@@ -106,6 +106,37 @@ async function answerOnce({
|
|
|
106
106
|
return completeOnce({ client, system, messages, temperature, model });
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
// src/core/buckets.ts
|
|
110
|
+
function defaultBuckets(mode) {
|
|
111
|
+
return ["base", mode];
|
|
112
|
+
}
|
|
113
|
+
function isIdentified(sender) {
|
|
114
|
+
return typeof sender === "string" && sender.trim().length > 0;
|
|
115
|
+
}
|
|
116
|
+
function normalize(buckets) {
|
|
117
|
+
const out = [];
|
|
118
|
+
for (const raw of buckets) {
|
|
119
|
+
if (typeof raw !== "string") continue;
|
|
120
|
+
const bucket = raw.trim();
|
|
121
|
+
if (bucket && !out.includes(bucket)) out.push(bucket);
|
|
122
|
+
}
|
|
123
|
+
return out;
|
|
124
|
+
}
|
|
125
|
+
async function resolveBuckets({
|
|
126
|
+
mode,
|
|
127
|
+
sender,
|
|
128
|
+
bucketsFor
|
|
129
|
+
}) {
|
|
130
|
+
if (!bucketsFor) return void 0;
|
|
131
|
+
const identified = isIdentified(sender);
|
|
132
|
+
const requested = await bucketsFor(identified ? { mode, sender } : { mode });
|
|
133
|
+
if (!Array.isArray(requested)) return void 0;
|
|
134
|
+
const cleaned = normalize(requested);
|
|
135
|
+
if (identified) return cleaned;
|
|
136
|
+
const ceiling = new Set(defaultBuckets(mode));
|
|
137
|
+
return cleaned.filter((bucket) => ceiling.has(bucket));
|
|
138
|
+
}
|
|
139
|
+
|
|
109
140
|
// src/core/prompts.ts
|
|
110
141
|
var import_node_fs = require("node:fs");
|
|
111
142
|
var import_node_path = require("node:path");
|
|
@@ -314,8 +345,19 @@ var VectorStore = class _VectorStore {
|
|
|
314
345
|
}
|
|
315
346
|
return dot / (Math.sqrt(na) * Math.sqrt(nb));
|
|
316
347
|
}
|
|
317
|
-
|
|
348
|
+
/**
|
|
349
|
+
* Retrieve top-k across allowed buckets; compute similarity in app (simple
|
|
350
|
+
* & portable).
|
|
351
|
+
*
|
|
352
|
+
* `allowed` is a bucket-name list rather than the {@link Bucket} union: the
|
|
353
|
+
* `chunks` table constrains nothing, so a deployment that ingests its own
|
|
354
|
+
* buckets can query them (`build` only writes and prunes the three the
|
|
355
|
+
* knowledge loader walks). Names are bound as query parameters, never
|
|
356
|
+
* interpolated. An empty list retrieves nothing, and short-circuits before
|
|
357
|
+
* the embedding call.
|
|
358
|
+
*/
|
|
318
359
|
async query(q, k = 6, allowed = ["base"]) {
|
|
360
|
+
if (allowed.length === 0) return [];
|
|
319
361
|
const qv = (await this.client.embeddings.create({ model: EMB_MODEL, input: [q] })).data[0].embedding;
|
|
320
362
|
const placeholders = allowed.map(() => "?").join(",");
|
|
321
363
|
const res = await this.db.execute({
|
|
@@ -560,7 +602,8 @@ async function createMCPServer(config) {
|
|
|
560
602
|
if (!lastUserMsg) {
|
|
561
603
|
throw new Error("No user message found in conversation");
|
|
562
604
|
}
|
|
563
|
-
const
|
|
605
|
+
const buckets = await resolveBuckets({ mode: "public", bucketsFor: config.bucketsFor }) ?? defaultBuckets("public");
|
|
606
|
+
const ctx = await store.query(lastUserMsg.content, 6, buckets);
|
|
564
607
|
const system = [
|
|
565
608
|
prompts.baseSystemRules,
|
|
566
609
|
prompts.publicPersona,
|
|
@@ -646,7 +689,8 @@ ${ctx.join("\n\n")}`
|
|
|
646
689
|
if (!lastUserMsg) {
|
|
647
690
|
throw new Error("No user message found in conversation");
|
|
648
691
|
}
|
|
649
|
-
const
|
|
692
|
+
const buckets = await resolveBuckets({ mode: "private", bucketsFor: config.bucketsFor }) ?? defaultBuckets("private");
|
|
693
|
+
const ctx = await store.query(lastUserMsg.content, 8, buckets);
|
|
650
694
|
const system = [
|
|
651
695
|
prompts.baseSystemRules,
|
|
652
696
|
prompts.privatePersona,
|
package/dist/mcp-server.mjs
CHANGED
|
@@ -72,6 +72,37 @@ async function answerOnce({
|
|
|
72
72
|
return completeOnce({ client, system, messages, temperature, model });
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
// src/core/buckets.ts
|
|
76
|
+
function defaultBuckets(mode) {
|
|
77
|
+
return ["base", mode];
|
|
78
|
+
}
|
|
79
|
+
function isIdentified(sender) {
|
|
80
|
+
return typeof sender === "string" && sender.trim().length > 0;
|
|
81
|
+
}
|
|
82
|
+
function normalize(buckets) {
|
|
83
|
+
const out = [];
|
|
84
|
+
for (const raw of buckets) {
|
|
85
|
+
if (typeof raw !== "string") continue;
|
|
86
|
+
const bucket = raw.trim();
|
|
87
|
+
if (bucket && !out.includes(bucket)) out.push(bucket);
|
|
88
|
+
}
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
async function resolveBuckets({
|
|
92
|
+
mode,
|
|
93
|
+
sender,
|
|
94
|
+
bucketsFor
|
|
95
|
+
}) {
|
|
96
|
+
if (!bucketsFor) return void 0;
|
|
97
|
+
const identified = isIdentified(sender);
|
|
98
|
+
const requested = await bucketsFor(identified ? { mode, sender } : { mode });
|
|
99
|
+
if (!Array.isArray(requested)) return void 0;
|
|
100
|
+
const cleaned = normalize(requested);
|
|
101
|
+
if (identified) return cleaned;
|
|
102
|
+
const ceiling = new Set(defaultBuckets(mode));
|
|
103
|
+
return cleaned.filter((bucket) => ceiling.has(bucket));
|
|
104
|
+
}
|
|
105
|
+
|
|
75
106
|
// src/core/prompts.ts
|
|
76
107
|
import { readFileSync } from "node:fs";
|
|
77
108
|
import { join } from "node:path";
|
|
@@ -280,8 +311,19 @@ var VectorStore = class _VectorStore {
|
|
|
280
311
|
}
|
|
281
312
|
return dot / (Math.sqrt(na) * Math.sqrt(nb));
|
|
282
313
|
}
|
|
283
|
-
|
|
314
|
+
/**
|
|
315
|
+
* Retrieve top-k across allowed buckets; compute similarity in app (simple
|
|
316
|
+
* & portable).
|
|
317
|
+
*
|
|
318
|
+
* `allowed` is a bucket-name list rather than the {@link Bucket} union: the
|
|
319
|
+
* `chunks` table constrains nothing, so a deployment that ingests its own
|
|
320
|
+
* buckets can query them (`build` only writes and prunes the three the
|
|
321
|
+
* knowledge loader walks). Names are bound as query parameters, never
|
|
322
|
+
* interpolated. An empty list retrieves nothing, and short-circuits before
|
|
323
|
+
* the embedding call.
|
|
324
|
+
*/
|
|
284
325
|
async query(q, k = 6, allowed = ["base"]) {
|
|
326
|
+
if (allowed.length === 0) return [];
|
|
285
327
|
const qv = (await this.client.embeddings.create({ model: EMB_MODEL, input: [q] })).data[0].embedding;
|
|
286
328
|
const placeholders = allowed.map(() => "?").join(",");
|
|
287
329
|
const res = await this.db.execute({
|
|
@@ -526,7 +568,8 @@ async function createMCPServer(config) {
|
|
|
526
568
|
if (!lastUserMsg) {
|
|
527
569
|
throw new Error("No user message found in conversation");
|
|
528
570
|
}
|
|
529
|
-
const
|
|
571
|
+
const buckets = await resolveBuckets({ mode: "public", bucketsFor: config.bucketsFor }) ?? defaultBuckets("public");
|
|
572
|
+
const ctx = await store.query(lastUserMsg.content, 6, buckets);
|
|
530
573
|
const system = [
|
|
531
574
|
prompts.baseSystemRules,
|
|
532
575
|
prompts.publicPersona,
|
|
@@ -612,7 +655,8 @@ ${ctx.join("\n\n")}`
|
|
|
612
655
|
if (!lastUserMsg) {
|
|
613
656
|
throw new Error("No user message found in conversation");
|
|
614
657
|
}
|
|
615
|
-
const
|
|
658
|
+
const buckets = await resolveBuckets({ mode: "private", bucketsFor: config.bucketsFor }) ?? defaultBuckets("private");
|
|
659
|
+
const ctx = await store.query(lastUserMsg.content, 8, buckets);
|
|
616
660
|
const system = [
|
|
617
661
|
prompts.baseSystemRules,
|
|
618
662
|
prompts.privatePersona,
|
package/dist/middleware/jwt.d.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import type { Context, Next } from "hono";
|
|
2
2
|
import type { ChatterConfig } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* The verified JWT subject attached by {@link createJWTMiddleware}, or
|
|
5
|
+
* `undefined` when the request carried no identity (unauthenticated route, or
|
|
6
|
+
* a token whose payload had no `sub`).
|
|
7
|
+
*
|
|
8
|
+
* Surfaces use this as the sender identity for per-request policy such as
|
|
9
|
+
* retrieval bucket gating, where "no identity" must mean anonymous rather
|
|
10
|
+
* than an empty-string user.
|
|
11
|
+
*/
|
|
12
|
+
export declare function jwtSubject(c: Context): string | undefined;
|
|
3
13
|
/**
|
|
4
14
|
* Create JWT authentication middleware for private API endpoints
|
|
5
15
|
* Supports JWKS and public key PEM verification
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/middleware/jwt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAO9C;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,OAwBZ,OAAO,QAAQ,IAAI;;8BAa/D;AAGD,eAAO,MAAM,iBAAiB,MAhBe,OAAO,QAAQ,IAAI;;6BAgBS,CAAC"}
|
|
1
|
+
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/middleware/jwt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAO9C;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAGzD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,OAwBZ,OAAO,QAAQ,IAAI;;8BAa/D;AAGD,eAAO,MAAM,iBAAiB,MAhBe,OAAO,QAAQ,IAAI;;6BAgBS,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../../src/routes/demo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../../src/routes/demo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAsHnD,wBAAgB,UAAU,CAAC,IAAI,EAAE,kBAAkB,8EAqHlD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/routes/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/routes/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,EAAE,KAAK,eAAe,EAAkC,MAAM,kBAAkB,CAAC;AAGxF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,eAAe,EAAE,GAAG,IAAI,CA8BxE;AASD,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,8EAwIpD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"private.d.ts","sourceRoot":"","sources":["../../src/routes/private.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"private.d.ts","sourceRoot":"","sources":["../../src/routes/private.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAO5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,aAAa,CAAC,IAAI,EAAE,kBAAkB,8EAoErD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/routes/public.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/routes/public.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAS5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,8EA0EpD"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAY5B,OAAO,KAAK,EAAE,aAAa,EAAsB,MAAM,SAAS,CAAC;AAEjE;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAY5B,OAAO,KAAK,EAAE,aAAa,EAAsB,MAAM,SAAS,CAAC;AAEjE;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,aAAa,uFA+JvD"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createServer custom-route mounting tests
|
|
3
|
+
*
|
|
4
|
+
* Runs the real server factory against an in-memory libsql database and an
|
|
5
|
+
* empty knowledge directory, so no paid API is reached: with nothing to embed,
|
|
6
|
+
* the vector store build never calls OpenAI.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=server.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.test.d.ts","sourceRoot":"","sources":["../src/server.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
package/dist/types.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import type { Client as LibsqlClient } from "@libsql/client";
|
|
|
8
8
|
import type { Hono } from "hono";
|
|
9
9
|
import type OpenAI from "openai";
|
|
10
10
|
import type { AnswerFn } from "./core/answer";
|
|
11
|
+
import type { BucketsFor } from "./core/buckets";
|
|
11
12
|
import type { PromptLoader } from "./core/prompts";
|
|
12
13
|
import type { VectorStore } from "./core/retrieval";
|
|
13
14
|
/**
|
|
@@ -156,9 +157,40 @@ export interface ChatterConfig {
|
|
|
156
157
|
* errors. Unset: the built-in OpenAI completion is used.
|
|
157
158
|
*/
|
|
158
159
|
answerFn?: AnswerFn;
|
|
159
|
-
/**
|
|
160
|
-
|
|
160
|
+
/**
|
|
161
|
+
* Decides which knowledge buckets each chat turn may retrieve from, given
|
|
162
|
+
* the pipeline mode and — where the surface knows it — the sender's
|
|
163
|
+
* identity. Use it for role-gated knowledge: entitle a signed-in operator
|
|
164
|
+
* to buckets an anonymous visitor cannot see.
|
|
165
|
+
*
|
|
166
|
+
* Consulted by the chat routes, the OpenAI-compatible endpoints, the MCP
|
|
167
|
+
* chat tools and the demo route. Return `undefined` to keep the mode
|
|
168
|
+
* defaults (`base` plus the mode's own bucket). For a caller the surface
|
|
169
|
+
* could not identify, the answer is filtered down to those same defaults —
|
|
170
|
+
* the hook can narrow retrieval for an unnamed caller but never widen it.
|
|
171
|
+
*
|
|
172
|
+
* Unset: the mode defaults apply everywhere.
|
|
173
|
+
*/
|
|
174
|
+
bucketsFor?: BucketsFor;
|
|
175
|
+
/** Custom route handler for advanced use cases. May be async — see {@link CustomRoutes} */
|
|
176
|
+
customRoutes?: CustomRoutes;
|
|
161
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Mounts additional routes on the server's Hono app.
|
|
180
|
+
*
|
|
181
|
+
* May be synchronous or return a promise; `createServer` awaits it, so
|
|
182
|
+
* asynchronous set-up (database migrations, plugin registries, anything the
|
|
183
|
+
* routes depend on) is guaranteed to have finished before the server is handed
|
|
184
|
+
* back and starts serving requests. A rejection fails startup rather than
|
|
185
|
+
* leaving the app half-mounted.
|
|
186
|
+
*
|
|
187
|
+
* Declared as a union of two function types rather than one returning
|
|
188
|
+
* `void | Promise<void>`: TypeScript only ignores a callback's return value
|
|
189
|
+
* when the expected return type is exactly `void`, so the union keeps
|
|
190
|
+
* expression-bodied mounts like `(app) => app.get(...)` — which return the
|
|
191
|
+
* Hono app for chaining — assignable.
|
|
192
|
+
*/
|
|
193
|
+
export type CustomRoutes = ((app: Hono, deps: ServerDependencies) => void) | ((app: Hono, deps: ServerDependencies) => Promise<void>);
|
|
162
194
|
/**
|
|
163
195
|
* Dependencies passed to route factories and middleware
|
|
164
196
|
*/
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED