@diegoaltoworks/chatter 0.21.0 → 0.22.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.
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Brain hook — the seam where a consumer replaces the completion call.
3
+ *
4
+ * Every chat surface (widget routes, OpenAI-compatible routes, channels,
5
+ * programmatic use) asks for an answer through `answerOnce`/`answerStream`
6
+ * instead of calling `completeOnce`/`completeStream` directly. When
7
+ * `ChatterConfig.answerFn` is set it produces the answer — an agent
8
+ * framework, a graph runtime, a remote service, anything — and Chatter keeps
9
+ * owning the rest: retrieval and prompt assembly upstream, auth, rate
10
+ * limiting, transports and output guardrails around it.
11
+ *
12
+ * With no `answerFn` configured these are thin pass-throughs, so behaviour is
13
+ * exactly what it has always been.
14
+ */
15
+ import type OpenAI from "openai";
16
+ import type { PipelineMessage, PipelineMode } from "./pipeline";
17
+ /** Token accounting in the OpenAI wire shape */
18
+ export interface AnswerUsage {
19
+ prompt_tokens: number;
20
+ completion_tokens: number;
21
+ total_tokens: number;
22
+ }
23
+ /** What a brain is given: the assembled prompt plus who is asking */
24
+ export interface AnswerFnInput {
25
+ /** Fully assembled system prompt from `prepareChat` */
26
+ system: string;
27
+ /** Conversation messages */
28
+ messages: PipelineMessage[];
29
+ /** Which pipeline the answer is for */
30
+ mode: PipelineMode;
31
+ /** Channel-specific sender identity, when the surface knows one */
32
+ sender?: string;
33
+ }
34
+ /**
35
+ * What a brain returns: the answer text, optionally with token usage for
36
+ * surfaces that report it.
37
+ */
38
+ export type AnswerFnResult = string | {
39
+ content: string;
40
+ usage?: AnswerUsage;
41
+ };
42
+ /**
43
+ * Replaces the completion call on every chat surface. Rejections propagate to
44
+ * the caller like any other completion failure.
45
+ */
46
+ export type AnswerFn = (input: AnswerFnInput) => Promise<AnswerFnResult> | AnswerFnResult;
47
+ export interface AnswerOptions {
48
+ /** Caller-supplied brain; falls back to the built-in completion when unset */
49
+ answerFn?: AnswerFn;
50
+ /** Used by the built-in completion; untouched when `answerFn` answers */
51
+ client: OpenAI;
52
+ system: string;
53
+ messages: PipelineMessage[];
54
+ mode: PipelineMode;
55
+ sender?: string;
56
+ temperature?: number;
57
+ model?: string;
58
+ }
59
+ /**
60
+ * Produce one complete answer, from `answerFn` when configured.
61
+ */
62
+ export declare function answerOnce({ answerFn, client, system, messages, mode, sender, temperature, model, }: AnswerOptions): Promise<{
63
+ content: string;
64
+ usage: AnswerUsage;
65
+ }>;
66
+ /**
67
+ * Stream an answer. A brain that returns a plain string cannot stream, so its
68
+ * answer degrades to a single chunk followed by the stream's normal end —
69
+ * streaming surfaces keep their wire format either way.
70
+ *
71
+ * Because a brain's answer arrives whole, it gets the full guardrails; the
72
+ * built-in stream only scrubs each delta, since leakage detection needs text
73
+ * no streamed chunk has yet.
74
+ */
75
+ export declare function answerStream({ answerFn, client, system, messages, mode, sender, temperature, model, }: AnswerOptions): AsyncGenerator<string>;
76
+ //# sourceMappingURL=answer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"answer.d.ts","sourceRoot":"","sources":["../../src/core/answer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAGjC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEhE,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB;AAKD,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,uCAAuC;IACvC,IAAI,EAAE,YAAY,CAAC;IACnB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,WAAW,CAAA;CAAE,CAAC;AAE/E;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC;AAE1F,MAAM,WAAW,aAAa;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAqBD;;GAEG;AACH,wBAAsB,UAAU,CAAC,EAC/B,QAAQ,EACR,MAAM,EACN,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,WAAW,EACX,KAAK,GACN,EAAE,aAAa,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC,CAKlE;AAED;;;;;;;;GAQG;AACH,wBAAuB,YAAY,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,WAAW,EACX,KAAK,GACN,EAAE,aAAa,GAAG,cAAc,CAAC,MAAM,CAAC,CAOxC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Brain hook tests
3
+ *
4
+ * Uses a faked OpenAI client so both the built-in completion path and the
5
+ * `answerFn` path can be asserted without touching OpenAI.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=answer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"answer.test.d.ts","sourceRoot":"","sources":["../../src/core/answer.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -1,3 +1,11 @@
1
1
  export declare function detectLeakage(text: string): boolean;
2
2
  export declare function scrubOutput(text: string): string;
3
+ /**
4
+ * Apply the full output guardrails to a complete answer: refuse leaked
5
+ * instructions outright, then scrub credentials from whatever remains.
6
+ *
7
+ * Used for every non-streamed answer, whoever produced it — the built-in
8
+ * completion or a caller-supplied brain (`answerFn`).
9
+ */
10
+ export declare function guardOutput(text: string): string;
3
11
  //# sourceMappingURL=guardrails.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"guardrails.d.ts","sourceRoot":"","sources":["../../src/core/guardrails.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CASnD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIhD"}
1
+ {"version":3,"file":"guardrails.d.ts","sourceRoot":"","sources":["../../src/core/guardrails.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CASnD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIhD;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKhD"}
@@ -1 +1 @@
1
- {"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/core/llm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAGjC,eAAO,MAAM,aAAa,WAAW,CAAC;AAEtC,wBAAsB,YAAY,CAAC,EACjC,MAAM,EACN,MAAM,EACN,QAAQ,EACR,WAAiB,EACjB,KAAqB,GACtB,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;;;GAaA;AAGD,wBAAuB,cAAc,CAAC,EACpC,MAAM,EACN,MAAM,EACN,QAAQ,EACR,WAAiB,EACjB,KAAqB,GACtB,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,yCAYA"}
1
+ {"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/core/llm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAGjC,eAAO,MAAM,aAAa,WAAW,CAAC;AAEtC,wBAAsB,YAAY,CAAC,EACjC,MAAM,EACN,MAAM,EACN,QAAQ,EACR,WAAiB,EACjB,KAAqB,GACtB,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;;;GAWA;AAGD,wBAAuB,cAAc,CAAC,EACpC,MAAM,EACN,MAAM,EACN,QAAQ,EACR,WAAiB,EACjB,KAAqB,GACtB,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,yCAYA"}
@@ -4,7 +4,9 @@
4
4
  * This is the single place where a conversation is turned into a
5
5
  * retrieval-augmented completion request. Every surface (widget routes,
6
6
  * OpenAI-compatible routes, MCP, programmatic use) should go through here
7
- * so behaviour stays identical regardless of how the chat is consumed.
7
+ * so behaviour stays identical regardless of how the chat is consumed, and
8
+ * then ask for the answer via `answerOnce`/`answerStream` (see ./answer.ts)
9
+ * so a caller-supplied brain is honoured.
8
10
  */
9
11
  import type { PromptLoader } from "./prompts";
10
12
  import type { VectorStore } from "./retrieval";
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,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;;;;;;;;;;;;GAYG;AACH,wBAAsB,WAAW,CAAC,EAChC,KAAK,EACL,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,WAAW,GACZ,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;CACtB,GAAG,OAAO,CAAC,YAAY,CAAC,CAmBxB"}
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,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;;;;;;;;;;;;GAYG;AACH,wBAAsB,WAAW,CAAC,EAChC,KAAK,EACL,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,WAAW,GACZ,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;CACtB,GAAG,OAAO,CAAC,YAAY,CAAC,CAmBxB"}
package/dist/index.d.ts CHANGED
@@ -14,7 +14,9 @@ export type { ApiKeyOptions, ApiKeyPayload, VerifyResult } from "./auth";
14
14
  export { ApiKeyManager } from "./auth";
15
15
  export type { ChatBotConfig, ChatButtonConfig, ChatConfig, ChatMessage, ChatMode, StreamCallbacks, } from "./client";
16
16
  export { Chat, ChatBot, ChatButton } from "./client";
17
- export { detectLeakage, scrubOutput } from "./core/guardrails";
17
+ export type { AnswerFn, AnswerFnInput, AnswerFnResult, AnswerOptions, AnswerUsage, } from "./core/answer";
18
+ export { answerOnce, answerStream } from "./core/answer";
19
+ export { detectLeakage, guardOutput, scrubOutput } from "./core/guardrails";
18
20
  export { completeOnce, completeStream, DEFAULT_MODEL } from "./core/llm";
19
21
  export { loadKnowledge } from "./core/loaders";
20
22
  export type { PipelineMessage, PipelineMode, PreparedChat } from "./core/pipeline";
@@ -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,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC/D,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;AAE9C,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;AACvD,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,cAAc,EACd,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,SAAS,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,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;AAE9C,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;AACvD,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,cAAc,EACd,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -7537,6 +7537,8 @@ __export(index_exports, {
7537
7537
  DEFAULT_MODEL: () => DEFAULT_MODEL,
7538
7538
  PromptLoader: () => PromptLoader,
7539
7539
  VectorStore: () => VectorStore,
7540
+ answerOnce: () => answerOnce,
7541
+ answerStream: () => answerStream,
7540
7542
  completeOnce: () => completeOnce,
7541
7543
  completeStream: () => completeStream,
7542
7544
  cors: () => cors,
@@ -7552,6 +7554,7 @@ __export(index_exports, {
7552
7554
  detectLeakage: () => detectLeakage,
7553
7555
  getActiveSessions: () => getActiveSessions,
7554
7556
  getSessionInfo: () => getSessionInfo,
7557
+ guardOutput: () => guardOutput,
7555
7558
  loadKnowledge: () => loadKnowledge,
7556
7559
  openaiRoutes: () => openaiRoutes,
7557
7560
  prepareChat: () => prepareChat,
@@ -7690,6 +7693,12 @@ function detectLeakage(text) {
7690
7693
  function scrubOutput(text) {
7691
7694
  return text.replace(/sk-[A-Za-z0-9]{15,}/g, "[REDACTED]").replace(/AIza[0-9A-Za-z_-]{30,}/g, "[REDACTED]");
7692
7695
  }
7696
+ function guardOutput(text) {
7697
+ if (detectLeakage(text)) {
7698
+ return "Sorry, I can't share internal instructions. How else can I help?";
7699
+ }
7700
+ return scrubOutput(text);
7701
+ }
7693
7702
 
7694
7703
  // src/core/llm.ts
7695
7704
  var DEFAULT_MODEL = "gpt-4o";
@@ -7705,11 +7714,9 @@ async function completeOnce({
7705
7714
  temperature,
7706
7715
  messages: [{ role: "system", content: system }, ...messages]
7707
7716
  });
7708
- let text = res.choices[0]?.message?.content ?? "";
7709
- if (detectLeakage(text))
7710
- text = "Sorry, I can't share internal instructions. How else can I help?";
7717
+ const text = res.choices[0]?.message?.content ?? "";
7711
7718
  return {
7712
- content: scrubOutput(text),
7719
+ content: guardOutput(text),
7713
7720
  usage: res.usage || { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 }
7714
7721
  };
7715
7722
  }
@@ -7732,6 +7739,50 @@ async function* completeStream({
7732
7739
  }
7733
7740
  }
7734
7741
 
7742
+ // src/core/answer.ts
7743
+ var noUsage = () => ({ prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 });
7744
+ async function runAnswerFn(answerFn, { system, messages, mode, sender }) {
7745
+ const result = await answerFn({ system, messages, mode, sender });
7746
+ const raw = typeof result === "string" ? result : result?.content;
7747
+ const usage = typeof result === "string" ? void 0 : result?.usage;
7748
+ return {
7749
+ content: guardOutput(typeof raw === "string" ? raw : ""),
7750
+ usage: usage ?? noUsage()
7751
+ };
7752
+ }
7753
+ async function answerOnce({
7754
+ answerFn,
7755
+ client,
7756
+ system,
7757
+ messages,
7758
+ mode,
7759
+ sender,
7760
+ temperature,
7761
+ model
7762
+ }) {
7763
+ if (answerFn) {
7764
+ return runAnswerFn(answerFn, { system, messages, mode, sender });
7765
+ }
7766
+ return completeOnce({ client, system, messages, temperature, model });
7767
+ }
7768
+ async function* answerStream({
7769
+ answerFn,
7770
+ client,
7771
+ system,
7772
+ messages,
7773
+ mode,
7774
+ sender,
7775
+ temperature,
7776
+ model
7777
+ }) {
7778
+ if (answerFn) {
7779
+ const { content } = await runAnswerFn(answerFn, { system, messages, mode, sender });
7780
+ if (content) yield content;
7781
+ return;
7782
+ }
7783
+ yield* completeStream({ client, system, messages, temperature, model });
7784
+ }
7785
+
7735
7786
  // src/core/loaders.ts
7736
7787
  var import_node_fs = require("node:fs");
7737
7788
  var import_node_path = require("node:path");
@@ -32248,10 +32299,12 @@ async function createMCPServer(config2) {
32248
32299
  `Context:
32249
32300
  ${ctx.join("\n\n")}`
32250
32301
  ].join("\n\n");
32251
- const result = await completeOnce({
32302
+ const result = await answerOnce({
32303
+ answerFn: config2.answerFn,
32252
32304
  client,
32253
32305
  system,
32254
- messages: conversationMessages
32306
+ messages: conversationMessages,
32307
+ mode: "public"
32255
32308
  });
32256
32309
  const cost = calculateCost(result.usage);
32257
32310
  const duration3 = Date.now() - startTime;
@@ -32332,10 +32385,12 @@ ${ctx.join("\n\n")}`
32332
32385
  `Internal Context:
32333
32386
  ${ctx.join("\n\n")}`
32334
32387
  ].join("\n\n");
32335
- const result = await completeOnce({
32388
+ const result = await answerOnce({
32389
+ answerFn: config2.answerFn,
32336
32390
  client,
32337
32391
  system,
32338
- messages: conversationMessages
32392
+ messages: conversationMessages,
32393
+ mode: "private"
32339
32394
  });
32340
32395
  const cost = calculateCost(result.usage);
32341
32396
  const duration3 = Date.now() - startTime;
@@ -32753,7 +32808,13 @@ ${ctx.join("\n\n")}`
32753
32808
  const wantsStream3 = url2.searchParams.get("stream") === "1";
32754
32809
  if (wantsStream3) {
32755
32810
  return (0, import_streaming.stream)(c, async (s) => {
32756
- for await (const delta of completeStream({ client, system, messages })) {
32811
+ for await (const delta of answerStream({
32812
+ answerFn: config2.answerFn,
32813
+ client,
32814
+ system,
32815
+ messages,
32816
+ mode: "public"
32817
+ })) {
32757
32818
  await s.write(`data: ${JSON.stringify({ delta })}
32758
32819
 
32759
32820
  `);
@@ -32761,7 +32822,13 @@ ${ctx.join("\n\n")}`
32761
32822
  await s.write("event: end\ndata: {}\n\n");
32762
32823
  });
32763
32824
  }
32764
- const out = await completeOnce({ client, system, messages });
32825
+ const out = await answerOnce({
32826
+ answerFn: config2.answerFn,
32827
+ client,
32828
+ system,
32829
+ messages,
32830
+ mode: "public"
32831
+ });
32765
32832
  return c.json({ reply: out.content });
32766
32833
  } catch (error51) {
32767
32834
  const err = error51;
@@ -32858,10 +32925,12 @@ function openaiRoutes(deps) {
32858
32925
 
32859
32926
  `;
32860
32927
  await s.write(chunk2({ role: "assistant", content: "" }, null));
32861
- for await (const delta of completeStream({
32928
+ for await (const delta of answerStream({
32929
+ answerFn: config2.answerFn,
32862
32930
  client,
32863
32931
  system,
32864
32932
  messages,
32933
+ mode,
32865
32934
  temperature,
32866
32935
  model: serverModel
32867
32936
  })) {
@@ -32871,7 +32940,15 @@ function openaiRoutes(deps) {
32871
32940
  await s.write("data: [DONE]\n\n");
32872
32941
  });
32873
32942
  }
32874
- const out = await completeOnce({ client, system, messages, temperature, model: serverModel });
32943
+ const out = await answerOnce({
32944
+ answerFn: config2.answerFn,
32945
+ client,
32946
+ system,
32947
+ messages,
32948
+ mode,
32949
+ temperature,
32950
+ model: serverModel
32951
+ });
32875
32952
  return c.json({
32876
32953
  id,
32877
32954
  object: "chat.completion",
@@ -32932,9 +33009,17 @@ function privateRoutes(deps) {
32932
33009
  return c.json({ error: "no user message found in conversation" }, 400);
32933
33010
  }
32934
33011
  const model = config2.openai.model;
33012
+ const answerFn = config2.answerFn;
32935
33013
  if (wantsStream(c)) {
32936
33014
  return (0, import_streaming3.stream)(c, async (s) => {
32937
- for await (const delta of completeStream({ client, system, messages, model })) {
33015
+ for await (const delta of answerStream({
33016
+ answerFn,
33017
+ client,
33018
+ system,
33019
+ messages,
33020
+ mode: "private",
33021
+ model
33022
+ })) {
32938
33023
  await s.write(`data: ${JSON.stringify({ delta })}
32939
33024
 
32940
33025
  `);
@@ -32942,7 +33027,7 @@ function privateRoutes(deps) {
32942
33027
  await s.write("event: end\ndata: {}\n\n");
32943
33028
  });
32944
33029
  }
32945
- const out = await completeOnce({ client, system, messages, model });
33030
+ const out = await answerOnce({ answerFn, client, system, messages, mode: "private", model });
32946
33031
  return c.json({ reply: out.content });
32947
33032
  });
32948
33033
  return app;
@@ -32987,9 +33072,17 @@ function publicRoutes(deps) {
32987
33072
  return c.json({ error: "no user message found in conversation" }, 400);
32988
33073
  }
32989
33074
  const model = config2.openai.model;
33075
+ const answerFn = config2.answerFn;
32990
33076
  if (wantsStream2(c)) {
32991
33077
  return (0, import_streaming4.stream)(c, async (s) => {
32992
- for await (const delta of completeStream({ client, system, messages, model })) {
33078
+ for await (const delta of answerStream({
33079
+ answerFn,
33080
+ client,
33081
+ system,
33082
+ messages,
33083
+ mode: "public",
33084
+ model
33085
+ })) {
32993
33086
  await s.write(`data: ${JSON.stringify({ delta })}
32994
33087
 
32995
33088
  `);
@@ -32997,7 +33090,7 @@ function publicRoutes(deps) {
32997
33090
  await s.write("event: end\ndata: {}\n\n");
32998
33091
  });
32999
33092
  }
33000
- const out = await completeOnce({ client, system, messages, model });
33093
+ const out = await answerOnce({ answerFn, client, system, messages, mode: "public", model });
33001
33094
  return c.json({ reply: out.content });
33002
33095
  });
33003
33096
  return app;
@@ -33158,6 +33251,8 @@ async function createServer(config2) {
33158
33251
  DEFAULT_MODEL,
33159
33252
  PromptLoader,
33160
33253
  VectorStore,
33254
+ answerOnce,
33255
+ answerStream,
33161
33256
  completeOnce,
33162
33257
  completeStream,
33163
33258
  cors,
@@ -33173,6 +33268,7 @@ async function createServer(config2) {
33173
33268
  detectLeakage,
33174
33269
  getActiveSessions,
33175
33270
  getSessionInfo,
33271
+ guardOutput,
33176
33272
  loadKnowledge,
33177
33273
  openaiRoutes,
33178
33274
  prepareChat,
package/dist/index.mjs CHANGED
@@ -7659,6 +7659,12 @@ function detectLeakage(text) {
7659
7659
  function scrubOutput(text) {
7660
7660
  return text.replace(/sk-[A-Za-z0-9]{15,}/g, "[REDACTED]").replace(/AIza[0-9A-Za-z_-]{30,}/g, "[REDACTED]");
7661
7661
  }
7662
+ function guardOutput(text) {
7663
+ if (detectLeakage(text)) {
7664
+ return "Sorry, I can't share internal instructions. How else can I help?";
7665
+ }
7666
+ return scrubOutput(text);
7667
+ }
7662
7668
 
7663
7669
  // src/core/llm.ts
7664
7670
  var DEFAULT_MODEL = "gpt-4o";
@@ -7674,11 +7680,9 @@ async function completeOnce({
7674
7680
  temperature,
7675
7681
  messages: [{ role: "system", content: system }, ...messages]
7676
7682
  });
7677
- let text = res.choices[0]?.message?.content ?? "";
7678
- if (detectLeakage(text))
7679
- text = "Sorry, I can't share internal instructions. How else can I help?";
7683
+ const text = res.choices[0]?.message?.content ?? "";
7680
7684
  return {
7681
- content: scrubOutput(text),
7685
+ content: guardOutput(text),
7682
7686
  usage: res.usage || { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 }
7683
7687
  };
7684
7688
  }
@@ -7701,6 +7705,50 @@ async function* completeStream({
7701
7705
  }
7702
7706
  }
7703
7707
 
7708
+ // src/core/answer.ts
7709
+ var noUsage = () => ({ prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 });
7710
+ async function runAnswerFn(answerFn, { system, messages, mode, sender }) {
7711
+ const result = await answerFn({ system, messages, mode, sender });
7712
+ const raw = typeof result === "string" ? result : result?.content;
7713
+ const usage = typeof result === "string" ? void 0 : result?.usage;
7714
+ return {
7715
+ content: guardOutput(typeof raw === "string" ? raw : ""),
7716
+ usage: usage ?? noUsage()
7717
+ };
7718
+ }
7719
+ async function answerOnce({
7720
+ answerFn,
7721
+ client,
7722
+ system,
7723
+ messages,
7724
+ mode,
7725
+ sender,
7726
+ temperature,
7727
+ model
7728
+ }) {
7729
+ if (answerFn) {
7730
+ return runAnswerFn(answerFn, { system, messages, mode, sender });
7731
+ }
7732
+ return completeOnce({ client, system, messages, temperature, model });
7733
+ }
7734
+ async function* answerStream({
7735
+ answerFn,
7736
+ client,
7737
+ system,
7738
+ messages,
7739
+ mode,
7740
+ sender,
7741
+ temperature,
7742
+ model
7743
+ }) {
7744
+ if (answerFn) {
7745
+ const { content } = await runAnswerFn(answerFn, { system, messages, mode, sender });
7746
+ if (content) yield content;
7747
+ return;
7748
+ }
7749
+ yield* completeStream({ client, system, messages, temperature, model });
7750
+ }
7751
+
7704
7752
  // src/core/loaders.ts
7705
7753
  import { readdirSync, readFileSync, statSync } from "node:fs";
7706
7754
  import { join } from "node:path";
@@ -32217,10 +32265,12 @@ async function createMCPServer(config2) {
32217
32265
  `Context:
32218
32266
  ${ctx.join("\n\n")}`
32219
32267
  ].join("\n\n");
32220
- const result = await completeOnce({
32268
+ const result = await answerOnce({
32269
+ answerFn: config2.answerFn,
32221
32270
  client,
32222
32271
  system,
32223
- messages: conversationMessages
32272
+ messages: conversationMessages,
32273
+ mode: "public"
32224
32274
  });
32225
32275
  const cost = calculateCost(result.usage);
32226
32276
  const duration3 = Date.now() - startTime;
@@ -32301,10 +32351,12 @@ ${ctx.join("\n\n")}`
32301
32351
  `Internal Context:
32302
32352
  ${ctx.join("\n\n")}`
32303
32353
  ].join("\n\n");
32304
- const result = await completeOnce({
32354
+ const result = await answerOnce({
32355
+ answerFn: config2.answerFn,
32305
32356
  client,
32306
32357
  system,
32307
- messages: conversationMessages
32358
+ messages: conversationMessages,
32359
+ mode: "private"
32308
32360
  });
32309
32361
  const cost = calculateCost(result.usage);
32310
32362
  const duration3 = Date.now() - startTime;
@@ -32722,7 +32774,13 @@ ${ctx.join("\n\n")}`
32722
32774
  const wantsStream3 = url2.searchParams.get("stream") === "1";
32723
32775
  if (wantsStream3) {
32724
32776
  return stream(c, async (s) => {
32725
- for await (const delta of completeStream({ client, system, messages })) {
32777
+ for await (const delta of answerStream({
32778
+ answerFn: config2.answerFn,
32779
+ client,
32780
+ system,
32781
+ messages,
32782
+ mode: "public"
32783
+ })) {
32726
32784
  await s.write(`data: ${JSON.stringify({ delta })}
32727
32785
 
32728
32786
  `);
@@ -32730,7 +32788,13 @@ ${ctx.join("\n\n")}`
32730
32788
  await s.write("event: end\ndata: {}\n\n");
32731
32789
  });
32732
32790
  }
32733
- const out = await completeOnce({ client, system, messages });
32791
+ const out = await answerOnce({
32792
+ answerFn: config2.answerFn,
32793
+ client,
32794
+ system,
32795
+ messages,
32796
+ mode: "public"
32797
+ });
32734
32798
  return c.json({ reply: out.content });
32735
32799
  } catch (error51) {
32736
32800
  const err = error51;
@@ -32827,10 +32891,12 @@ function openaiRoutes(deps) {
32827
32891
 
32828
32892
  `;
32829
32893
  await s.write(chunk2({ role: "assistant", content: "" }, null));
32830
- for await (const delta of completeStream({
32894
+ for await (const delta of answerStream({
32895
+ answerFn: config2.answerFn,
32831
32896
  client,
32832
32897
  system,
32833
32898
  messages,
32899
+ mode,
32834
32900
  temperature,
32835
32901
  model: serverModel
32836
32902
  })) {
@@ -32840,7 +32906,15 @@ function openaiRoutes(deps) {
32840
32906
  await s.write("data: [DONE]\n\n");
32841
32907
  });
32842
32908
  }
32843
- const out = await completeOnce({ client, system, messages, temperature, model: serverModel });
32909
+ const out = await answerOnce({
32910
+ answerFn: config2.answerFn,
32911
+ client,
32912
+ system,
32913
+ messages,
32914
+ mode,
32915
+ temperature,
32916
+ model: serverModel
32917
+ });
32844
32918
  return c.json({
32845
32919
  id,
32846
32920
  object: "chat.completion",
@@ -32901,9 +32975,17 @@ function privateRoutes(deps) {
32901
32975
  return c.json({ error: "no user message found in conversation" }, 400);
32902
32976
  }
32903
32977
  const model = config2.openai.model;
32978
+ const answerFn = config2.answerFn;
32904
32979
  if (wantsStream(c)) {
32905
32980
  return stream3(c, async (s) => {
32906
- for await (const delta of completeStream({ client, system, messages, model })) {
32981
+ for await (const delta of answerStream({
32982
+ answerFn,
32983
+ client,
32984
+ system,
32985
+ messages,
32986
+ mode: "private",
32987
+ model
32988
+ })) {
32907
32989
  await s.write(`data: ${JSON.stringify({ delta })}
32908
32990
 
32909
32991
  `);
@@ -32911,7 +32993,7 @@ function privateRoutes(deps) {
32911
32993
  await s.write("event: end\ndata: {}\n\n");
32912
32994
  });
32913
32995
  }
32914
- const out = await completeOnce({ client, system, messages, model });
32996
+ const out = await answerOnce({ answerFn, client, system, messages, mode: "private", model });
32915
32997
  return c.json({ reply: out.content });
32916
32998
  });
32917
32999
  return app;
@@ -32956,9 +33038,17 @@ function publicRoutes(deps) {
32956
33038
  return c.json({ error: "no user message found in conversation" }, 400);
32957
33039
  }
32958
33040
  const model = config2.openai.model;
33041
+ const answerFn = config2.answerFn;
32959
33042
  if (wantsStream2(c)) {
32960
33043
  return stream4(c, async (s) => {
32961
- for await (const delta of completeStream({ client, system, messages, model })) {
33044
+ for await (const delta of answerStream({
33045
+ answerFn,
33046
+ client,
33047
+ system,
33048
+ messages,
33049
+ mode: "public",
33050
+ model
33051
+ })) {
32962
33052
  await s.write(`data: ${JSON.stringify({ delta })}
32963
33053
 
32964
33054
  `);
@@ -32966,7 +33056,7 @@ function publicRoutes(deps) {
32966
33056
  await s.write("event: end\ndata: {}\n\n");
32967
33057
  });
32968
33058
  }
32969
- const out = await completeOnce({ client, system, messages, model });
33059
+ const out = await answerOnce({ answerFn, client, system, messages, mode: "public", model });
32970
33060
  return c.json({ reply: out.content });
32971
33061
  });
32972
33062
  return app;
@@ -33128,6 +33218,8 @@ export {
33128
33218
  DEFAULT_MODEL,
33129
33219
  PromptLoader,
33130
33220
  VectorStore,
33221
+ answerOnce,
33222
+ answerStream,
33131
33223
  completeOnce,
33132
33224
  completeStream,
33133
33225
  cors,
@@ -33143,6 +33235,7 @@ export {
33143
33235
  detectLeakage,
33144
33236
  getActiveSessions,
33145
33237
  getSessionInfo,
33238
+ guardOutput,
33146
33239
  loadKnowledge,
33147
33240
  openaiRoutes,
33148
33241
  prepareChat,
@@ -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;AAYpE,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,sBAuS7D"}
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;AAYpE,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,sBA2S7D"}
@@ -51,6 +51,12 @@ function detectLeakage(text) {
51
51
  function scrubOutput(text) {
52
52
  return text.replace(/sk-[A-Za-z0-9]{15,}/g, "[REDACTED]").replace(/AIza[0-9A-Za-z_-]{30,}/g, "[REDACTED]");
53
53
  }
54
+ function guardOutput(text) {
55
+ if (detectLeakage(text)) {
56
+ return "Sorry, I can't share internal instructions. How else can I help?";
57
+ }
58
+ return scrubOutput(text);
59
+ }
54
60
 
55
61
  // src/core/llm.ts
56
62
  var DEFAULT_MODEL = "gpt-4o";
@@ -66,15 +72,40 @@ async function completeOnce({
66
72
  temperature,
67
73
  messages: [{ role: "system", content: system }, ...messages]
68
74
  });
69
- let text = res.choices[0]?.message?.content ?? "";
70
- if (detectLeakage(text))
71
- text = "Sorry, I can't share internal instructions. How else can I help?";
75
+ const text = res.choices[0]?.message?.content ?? "";
72
76
  return {
73
- content: scrubOutput(text),
77
+ content: guardOutput(text),
74
78
  usage: res.usage || { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 }
75
79
  };
76
80
  }
77
81
 
82
+ // src/core/answer.ts
83
+ var noUsage = () => ({ prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 });
84
+ async function runAnswerFn(answerFn, { system, messages, mode, sender }) {
85
+ const result = await answerFn({ system, messages, mode, sender });
86
+ const raw = typeof result === "string" ? result : result?.content;
87
+ const usage = typeof result === "string" ? void 0 : result?.usage;
88
+ return {
89
+ content: guardOutput(typeof raw === "string" ? raw : ""),
90
+ usage: usage ?? noUsage()
91
+ };
92
+ }
93
+ async function answerOnce({
94
+ answerFn,
95
+ client,
96
+ system,
97
+ messages,
98
+ mode,
99
+ sender,
100
+ temperature,
101
+ model
102
+ }) {
103
+ if (answerFn) {
104
+ return runAnswerFn(answerFn, { system, messages, mode, sender });
105
+ }
106
+ return completeOnce({ client, system, messages, temperature, model });
107
+ }
108
+
78
109
  // src/core/prompts.ts
79
110
  var import_node_fs = require("node:fs");
80
111
  var import_node_path = require("node:path");
@@ -531,10 +562,12 @@ async function createMCPServer(config) {
531
562
  `Context:
532
563
  ${ctx.join("\n\n")}`
533
564
  ].join("\n\n");
534
- const result = await completeOnce({
565
+ const result = await answerOnce({
566
+ answerFn: config.answerFn,
535
567
  client,
536
568
  system,
537
- messages: conversationMessages
569
+ messages: conversationMessages,
570
+ mode: "public"
538
571
  });
539
572
  const cost = calculateCost(result.usage);
540
573
  const duration = Date.now() - startTime;
@@ -615,10 +648,12 @@ ${ctx.join("\n\n")}`
615
648
  `Internal Context:
616
649
  ${ctx.join("\n\n")}`
617
650
  ].join("\n\n");
618
- const result = await completeOnce({
651
+ const result = await answerOnce({
652
+ answerFn: config.answerFn,
619
653
  client,
620
654
  system,
621
- messages: conversationMessages
655
+ messages: conversationMessages,
656
+ mode: "private"
622
657
  });
623
658
  const cost = calculateCost(result.usage);
624
659
  const duration = Date.now() - startTime;
@@ -17,6 +17,12 @@ function detectLeakage(text) {
17
17
  function scrubOutput(text) {
18
18
  return text.replace(/sk-[A-Za-z0-9]{15,}/g, "[REDACTED]").replace(/AIza[0-9A-Za-z_-]{30,}/g, "[REDACTED]");
19
19
  }
20
+ function guardOutput(text) {
21
+ if (detectLeakage(text)) {
22
+ return "Sorry, I can't share internal instructions. How else can I help?";
23
+ }
24
+ return scrubOutput(text);
25
+ }
20
26
 
21
27
  // src/core/llm.ts
22
28
  var DEFAULT_MODEL = "gpt-4o";
@@ -32,15 +38,40 @@ async function completeOnce({
32
38
  temperature,
33
39
  messages: [{ role: "system", content: system }, ...messages]
34
40
  });
35
- let text = res.choices[0]?.message?.content ?? "";
36
- if (detectLeakage(text))
37
- text = "Sorry, I can't share internal instructions. How else can I help?";
41
+ const text = res.choices[0]?.message?.content ?? "";
38
42
  return {
39
- content: scrubOutput(text),
43
+ content: guardOutput(text),
40
44
  usage: res.usage || { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 }
41
45
  };
42
46
  }
43
47
 
48
+ // src/core/answer.ts
49
+ var noUsage = () => ({ prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 });
50
+ async function runAnswerFn(answerFn, { system, messages, mode, sender }) {
51
+ const result = await answerFn({ system, messages, mode, sender });
52
+ const raw = typeof result === "string" ? result : result?.content;
53
+ const usage = typeof result === "string" ? void 0 : result?.usage;
54
+ return {
55
+ content: guardOutput(typeof raw === "string" ? raw : ""),
56
+ usage: usage ?? noUsage()
57
+ };
58
+ }
59
+ async function answerOnce({
60
+ answerFn,
61
+ client,
62
+ system,
63
+ messages,
64
+ mode,
65
+ sender,
66
+ temperature,
67
+ model
68
+ }) {
69
+ if (answerFn) {
70
+ return runAnswerFn(answerFn, { system, messages, mode, sender });
71
+ }
72
+ return completeOnce({ client, system, messages, temperature, model });
73
+ }
74
+
44
75
  // src/core/prompts.ts
45
76
  import { readFileSync } from "node:fs";
46
77
  import { join } from "node:path";
@@ -497,10 +528,12 @@ async function createMCPServer(config) {
497
528
  `Context:
498
529
  ${ctx.join("\n\n")}`
499
530
  ].join("\n\n");
500
- const result = await completeOnce({
531
+ const result = await answerOnce({
532
+ answerFn: config.answerFn,
501
533
  client,
502
534
  system,
503
- messages: conversationMessages
535
+ messages: conversationMessages,
536
+ mode: "public"
504
537
  });
505
538
  const cost = calculateCost(result.usage);
506
539
  const duration = Date.now() - startTime;
@@ -581,10 +614,12 @@ ${ctx.join("\n\n")}`
581
614
  `Internal Context:
582
615
  ${ctx.join("\n\n")}`
583
616
  ].join("\n\n");
584
- const result = await completeOnce({
617
+ const result = await answerOnce({
618
+ answerFn: config.answerFn,
585
619
  client,
586
620
  system,
587
- messages: conversationMessages
621
+ messages: conversationMessages,
622
+ mode: "private"
588
623
  });
589
624
  const cost = calculateCost(result.usage);
590
625
  const duration = Date.now() - startTime;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Widget chat route tests
3
+ *
4
+ * Covers the brain hook on the public and private chat routes with faked
5
+ * dependencies: no OpenAI, no Turso, and a locally generated RS256 keypair
6
+ * for the private route's JWT so real verification runs offline.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=chat.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.test.d.ts","sourceRoot":"","sources":["../../src/routes/chat.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -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;AAI5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAsHnD,wBAAgB,UAAU,CAAC,IAAI,EAAE,kBAAkB,8EAqGlD"}
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;AAI5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAsHnD,wBAAgB,UAAU,CAAC,IAAI,EAAE,kBAAkB,8EAiHlD"}
@@ -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;AAG5B,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,8EAsHpD"}
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;AAI5B,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,8EAgIpD"}
@@ -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;AAM5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,aAAa,CAAC,IAAI,EAAE,kBAAkB,8EAqDrD"}
1
+ {"version":3,"file":"private.d.ts","sourceRoot":"","sources":["../../src/routes/private.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,aAAa,CAAC,IAAI,EAAE,kBAAkB,8EA6DrD"}
@@ -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;AAQ5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,8EA8DpD"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/routes/public.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAQ5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,8EAsEpD"}
package/dist/types.d.ts CHANGED
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import type { Hono } from "hono";
8
8
  import type OpenAI from "openai";
9
+ import type { AnswerFn } from "./core/answer";
9
10
  import type { PromptLoader } from "./core/prompts";
10
11
  import type { VectorStore } from "./core/retrieval";
11
12
  /**
@@ -143,6 +144,17 @@ export interface ChatterConfig {
143
144
  */
144
145
  allowedOrigins?: string[];
145
146
  };
147
+ /**
148
+ * Replaces the completion call on every chat surface with your own brain —
149
+ * an agent framework, a graph runtime, a remote service. Receives the
150
+ * assembled system prompt and conversation from the pipeline and returns
151
+ * the answer text (optionally with token usage).
152
+ *
153
+ * Retrieval, prompt assembly, auth, rate limiting, transports and output
154
+ * guardrails all stay Chatter's. Errors surface as normal completion
155
+ * errors. Unset: the built-in OpenAI completion is used.
156
+ */
157
+ answerFn?: AnswerFn;
146
158
  /** Custom route handler for advanced use cases */
147
159
  customRoutes?: (app: Hono, deps: ServerDependencies) => void;
148
160
  }
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diegoaltoworks/chatter",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "Embeddable AI chatbot framework with RAG, authentication, and customizable widgets",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",