@diegoaltoworks/chatter 0.21.0 → 0.23.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/answer.d.ts +76 -0
- package/dist/core/answer.d.ts.map +1 -0
- package/dist/core/answer.test.d.ts +8 -0
- package/dist/core/answer.test.d.ts.map +1 -0
- package/dist/core/guardrails.d.ts +8 -0
- package/dist/core/guardrails.d.ts.map +1 -1
- package/dist/core/llm.d.ts.map +1 -1
- package/dist/core/pipeline.d.ts +3 -1
- package/dist/core/pipeline.d.ts.map +1 -1
- package/dist/core/retrieval.d.ts +31 -6
- package/dist/core/retrieval.d.ts.map +1 -1
- package/dist/core/retrieval.test.d.ts +8 -0
- package/dist/core/retrieval.test.d.ts.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +129 -24
- package/dist/index.mjs +126 -24
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +49 -9
- package/dist/mcp-server.mjs +49 -9
- package/dist/routes/chat.test.d.ts +9 -0
- package/dist/routes/chat.test.d.ts.map +1 -0
- 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/types.d.ts +19 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -1
|
@@ -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 @@
|
|
|
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"}
|
package/dist/core/llm.d.ts.map
CHANGED
|
@@ -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;;;
|
|
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"}
|
package/dist/core/pipeline.d.ts
CHANGED
|
@@ -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
|
|
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/core/retrieval.d.ts
CHANGED
|
@@ -1,14 +1,39 @@
|
|
|
1
|
+
import { type Client as LibsqlClient } from "@libsql/client";
|
|
1
2
|
import type OpenAI from "openai";
|
|
2
3
|
import { type Bucket } from "./loaders";
|
|
4
|
+
/**
|
|
5
|
+
* How a {@link VectorStore} obtains its database connection: either credentials
|
|
6
|
+
* to open its own, or an existing libsql client to reuse.
|
|
7
|
+
*
|
|
8
|
+
* Reusing a client is preferred when the store lives alongside other consumers
|
|
9
|
+
* of the same database (route factories, custom routes) — the process then
|
|
10
|
+
* holds one connection instead of one per consumer.
|
|
11
|
+
*/
|
|
12
|
+
export type VectorStoreOptions = {
|
|
13
|
+
/** Directory of markdown knowledge files. Default: `./config/knowledge` */
|
|
14
|
+
knowledgeDir?: string;
|
|
15
|
+
} & ({
|
|
16
|
+
/** Turso database URL */
|
|
17
|
+
databaseUrl: string;
|
|
18
|
+
/** Turso auth token */
|
|
19
|
+
databaseAuthToken: string;
|
|
20
|
+
databaseClient?: never;
|
|
21
|
+
} | {
|
|
22
|
+
/** An existing libsql client to reuse instead of opening a second connection */
|
|
23
|
+
databaseClient: LibsqlClient;
|
|
24
|
+
databaseUrl?: never;
|
|
25
|
+
databaseAuthToken?: never;
|
|
26
|
+
});
|
|
3
27
|
export declare class VectorStore {
|
|
4
28
|
private client;
|
|
5
|
-
|
|
29
|
+
/**
|
|
30
|
+
* The libsql client backing this store. When a client was injected this is
|
|
31
|
+
* that same instance, so callers holding it (e.g. `ServerDependencies.db`)
|
|
32
|
+
* and the store share one connection.
|
|
33
|
+
*/
|
|
34
|
+
readonly db: LibsqlClient;
|
|
6
35
|
private knowledgeDir;
|
|
7
|
-
constructor(client: OpenAI, options:
|
|
8
|
-
databaseUrl: string;
|
|
9
|
-
databaseAuthToken: string;
|
|
10
|
-
knowledgeDir?: string;
|
|
11
|
-
});
|
|
36
|
+
constructor(client: OpenAI, options: VectorStoreOptions);
|
|
12
37
|
build(): Promise<void>;
|
|
13
38
|
private cleanupStaleChunks;
|
|
14
39
|
private static cosine;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retrieval.d.ts","sourceRoot":"","sources":["../../src/core/retrieval.ts"],"names":[],"mappings":"
|
|
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;AACjC,OAAO,EAAE,KAAK,MAAM,EAAiB,MAAM,WAAW,CAAC;AAyBvD;;;;;;;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;IAaf,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,SAAI,EAAE,OAAO,GAAE,MAAM,EAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAsB7E;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retrieval.test.d.ts","sourceRoot":"","sources":["../../src/core/retrieval.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,12 +14,15 @@ 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 {
|
|
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";
|
|
21
23
|
export { prepareChat } from "./core/pipeline";
|
|
22
24
|
export { PromptLoader } from "./core/prompts";
|
|
25
|
+
export type { VectorStoreOptions } from "./core/retrieval";
|
|
23
26
|
export { VectorStore } from "./core/retrieval";
|
|
24
27
|
export { createSession, getActiveSessions, getSessionInfo, validateSession, } from "./core/session";
|
|
25
28
|
export type { MCPServerOptions, MCPTransportMode } from "./mcp-server";
|
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,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,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;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;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
|
@@ -7531,12 +7531,14 @@ var require_dist2 = __commonJS({
|
|
|
7531
7531
|
var index_exports = {};
|
|
7532
7532
|
__export(index_exports, {
|
|
7533
7533
|
ApiKeyManager: () => ApiKeyManager,
|
|
7534
|
-
Chat: () =>
|
|
7535
|
-
ChatBot: () =>
|
|
7536
|
-
ChatButton: () =>
|
|
7534
|
+
Chat: () => import_client3.Chat,
|
|
7535
|
+
ChatBot: () => import_client3.ChatBot,
|
|
7536
|
+
ChatButton: () => import_client3.ChatButton,
|
|
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,
|
|
@@ -7674,7 +7677,7 @@ var ApiKeyManager = class {
|
|
|
7674
7677
|
};
|
|
7675
7678
|
|
|
7676
7679
|
// src/index.ts
|
|
7677
|
-
var
|
|
7680
|
+
var import_client3 = __toESM(require_dist());
|
|
7678
7681
|
|
|
7679
7682
|
// src/core/guardrails.ts
|
|
7680
7683
|
function detectLeakage(text) {
|
|
@@ -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
|
-
|
|
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:
|
|
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");
|
|
@@ -7848,13 +7899,18 @@ async function sha256(input) {
|
|
|
7848
7899
|
var VectorStore = class _VectorStore {
|
|
7849
7900
|
constructor(client, options) {
|
|
7850
7901
|
this.client = client;
|
|
7851
|
-
this.db = (0, import_client.createClient)({
|
|
7902
|
+
this.db = options.databaseClient ? options.databaseClient : (0, import_client.createClient)({
|
|
7852
7903
|
url: options.databaseUrl,
|
|
7853
7904
|
authToken: options.databaseAuthToken
|
|
7854
7905
|
});
|
|
7855
7906
|
this.knowledgeDir = options.knowledgeDir || "./config/knowledge";
|
|
7856
7907
|
}
|
|
7857
7908
|
client;
|
|
7909
|
+
/**
|
|
7910
|
+
* The libsql client backing this store. When a client was injected this is
|
|
7911
|
+
* that same instance, so callers holding it (e.g. `ServerDependencies.db`)
|
|
7912
|
+
* and the store share one connection.
|
|
7913
|
+
*/
|
|
7858
7914
|
db;
|
|
7859
7915
|
knowledgeDir;
|
|
7860
7916
|
// On boot: ingest new chunks and embed only missing ones.
|
|
@@ -32248,10 +32304,12 @@ async function createMCPServer(config2) {
|
|
|
32248
32304
|
`Context:
|
|
32249
32305
|
${ctx.join("\n\n")}`
|
|
32250
32306
|
].join("\n\n");
|
|
32251
|
-
const result = await
|
|
32307
|
+
const result = await answerOnce({
|
|
32308
|
+
answerFn: config2.answerFn,
|
|
32252
32309
|
client,
|
|
32253
32310
|
system,
|
|
32254
|
-
messages: conversationMessages
|
|
32311
|
+
messages: conversationMessages,
|
|
32312
|
+
mode: "public"
|
|
32255
32313
|
});
|
|
32256
32314
|
const cost = calculateCost(result.usage);
|
|
32257
32315
|
const duration3 = Date.now() - startTime;
|
|
@@ -32332,10 +32390,12 @@ ${ctx.join("\n\n")}`
|
|
|
32332
32390
|
`Internal Context:
|
|
32333
32391
|
${ctx.join("\n\n")}`
|
|
32334
32392
|
].join("\n\n");
|
|
32335
|
-
const result = await
|
|
32393
|
+
const result = await answerOnce({
|
|
32394
|
+
answerFn: config2.answerFn,
|
|
32336
32395
|
client,
|
|
32337
32396
|
system,
|
|
32338
|
-
messages: conversationMessages
|
|
32397
|
+
messages: conversationMessages,
|
|
32398
|
+
mode: "private"
|
|
32339
32399
|
});
|
|
32340
32400
|
const cost = calculateCost(result.usage);
|
|
32341
32401
|
const duration3 = Date.now() - startTime;
|
|
@@ -32753,7 +32813,13 @@ ${ctx.join("\n\n")}`
|
|
|
32753
32813
|
const wantsStream3 = url2.searchParams.get("stream") === "1";
|
|
32754
32814
|
if (wantsStream3) {
|
|
32755
32815
|
return (0, import_streaming.stream)(c, async (s) => {
|
|
32756
|
-
for await (const delta of
|
|
32816
|
+
for await (const delta of answerStream({
|
|
32817
|
+
answerFn: config2.answerFn,
|
|
32818
|
+
client,
|
|
32819
|
+
system,
|
|
32820
|
+
messages,
|
|
32821
|
+
mode: "public"
|
|
32822
|
+
})) {
|
|
32757
32823
|
await s.write(`data: ${JSON.stringify({ delta })}
|
|
32758
32824
|
|
|
32759
32825
|
`);
|
|
@@ -32761,7 +32827,13 @@ ${ctx.join("\n\n")}`
|
|
|
32761
32827
|
await s.write("event: end\ndata: {}\n\n");
|
|
32762
32828
|
});
|
|
32763
32829
|
}
|
|
32764
|
-
const out = await
|
|
32830
|
+
const out = await answerOnce({
|
|
32831
|
+
answerFn: config2.answerFn,
|
|
32832
|
+
client,
|
|
32833
|
+
system,
|
|
32834
|
+
messages,
|
|
32835
|
+
mode: "public"
|
|
32836
|
+
});
|
|
32765
32837
|
return c.json({ reply: out.content });
|
|
32766
32838
|
} catch (error51) {
|
|
32767
32839
|
const err = error51;
|
|
@@ -32858,10 +32930,12 @@ function openaiRoutes(deps) {
|
|
|
32858
32930
|
|
|
32859
32931
|
`;
|
|
32860
32932
|
await s.write(chunk2({ role: "assistant", content: "" }, null));
|
|
32861
|
-
for await (const delta of
|
|
32933
|
+
for await (const delta of answerStream({
|
|
32934
|
+
answerFn: config2.answerFn,
|
|
32862
32935
|
client,
|
|
32863
32936
|
system,
|
|
32864
32937
|
messages,
|
|
32938
|
+
mode,
|
|
32865
32939
|
temperature,
|
|
32866
32940
|
model: serverModel
|
|
32867
32941
|
})) {
|
|
@@ -32871,7 +32945,15 @@ function openaiRoutes(deps) {
|
|
|
32871
32945
|
await s.write("data: [DONE]\n\n");
|
|
32872
32946
|
});
|
|
32873
32947
|
}
|
|
32874
|
-
const out = await
|
|
32948
|
+
const out = await answerOnce({
|
|
32949
|
+
answerFn: config2.answerFn,
|
|
32950
|
+
client,
|
|
32951
|
+
system,
|
|
32952
|
+
messages,
|
|
32953
|
+
mode,
|
|
32954
|
+
temperature,
|
|
32955
|
+
model: serverModel
|
|
32956
|
+
});
|
|
32875
32957
|
return c.json({
|
|
32876
32958
|
id,
|
|
32877
32959
|
object: "chat.completion",
|
|
@@ -32932,9 +33014,17 @@ function privateRoutes(deps) {
|
|
|
32932
33014
|
return c.json({ error: "no user message found in conversation" }, 400);
|
|
32933
33015
|
}
|
|
32934
33016
|
const model = config2.openai.model;
|
|
33017
|
+
const answerFn = config2.answerFn;
|
|
32935
33018
|
if (wantsStream(c)) {
|
|
32936
33019
|
return (0, import_streaming3.stream)(c, async (s) => {
|
|
32937
|
-
for await (const delta of
|
|
33020
|
+
for await (const delta of answerStream({
|
|
33021
|
+
answerFn,
|
|
33022
|
+
client,
|
|
33023
|
+
system,
|
|
33024
|
+
messages,
|
|
33025
|
+
mode: "private",
|
|
33026
|
+
model
|
|
33027
|
+
})) {
|
|
32938
33028
|
await s.write(`data: ${JSON.stringify({ delta })}
|
|
32939
33029
|
|
|
32940
33030
|
`);
|
|
@@ -32942,7 +33032,7 @@ function privateRoutes(deps) {
|
|
|
32942
33032
|
await s.write("event: end\ndata: {}\n\n");
|
|
32943
33033
|
});
|
|
32944
33034
|
}
|
|
32945
|
-
const out = await
|
|
33035
|
+
const out = await answerOnce({ answerFn, client, system, messages, mode: "private", model });
|
|
32946
33036
|
return c.json({ reply: out.content });
|
|
32947
33037
|
});
|
|
32948
33038
|
return app;
|
|
@@ -32987,9 +33077,17 @@ function publicRoutes(deps) {
|
|
|
32987
33077
|
return c.json({ error: "no user message found in conversation" }, 400);
|
|
32988
33078
|
}
|
|
32989
33079
|
const model = config2.openai.model;
|
|
33080
|
+
const answerFn = config2.answerFn;
|
|
32990
33081
|
if (wantsStream2(c)) {
|
|
32991
33082
|
return (0, import_streaming4.stream)(c, async (s) => {
|
|
32992
|
-
for await (const delta of
|
|
33083
|
+
for await (const delta of answerStream({
|
|
33084
|
+
answerFn,
|
|
33085
|
+
client,
|
|
33086
|
+
system,
|
|
33087
|
+
messages,
|
|
33088
|
+
mode: "public",
|
|
33089
|
+
model
|
|
33090
|
+
})) {
|
|
32993
33091
|
await s.write(`data: ${JSON.stringify({ delta })}
|
|
32994
33092
|
|
|
32995
33093
|
`);
|
|
@@ -32997,13 +33095,14 @@ function publicRoutes(deps) {
|
|
|
32997
33095
|
await s.write("event: end\ndata: {}\n\n");
|
|
32998
33096
|
});
|
|
32999
33097
|
}
|
|
33000
|
-
const out = await
|
|
33098
|
+
const out = await answerOnce({ answerFn, client, system, messages, mode: "public", model });
|
|
33001
33099
|
return c.json({ reply: out.content });
|
|
33002
33100
|
});
|
|
33003
33101
|
return app;
|
|
33004
33102
|
}
|
|
33005
33103
|
|
|
33006
33104
|
// src/server.ts
|
|
33105
|
+
var import_client2 = require("@libsql/client");
|
|
33007
33106
|
var import_hono5 = require("hono");
|
|
33008
33107
|
var import_bun = require("hono/bun");
|
|
33009
33108
|
var import_openai2 = __toESM(require("openai"));
|
|
@@ -33050,9 +33149,12 @@ async function createServer(config2) {
|
|
|
33050
33149
|
const client = new import_openai2.default({
|
|
33051
33150
|
apiKey: config2.openai.apiKey
|
|
33052
33151
|
});
|
|
33152
|
+
const db = (0, import_client2.createClient)({
|
|
33153
|
+
url: config2.database.url,
|
|
33154
|
+
authToken: config2.database.authToken
|
|
33155
|
+
});
|
|
33053
33156
|
const store = new VectorStore(client, {
|
|
33054
|
-
|
|
33055
|
-
databaseAuthToken: config2.database.authToken,
|
|
33157
|
+
databaseClient: db,
|
|
33056
33158
|
knowledgeDir
|
|
33057
33159
|
});
|
|
33058
33160
|
await store.build();
|
|
@@ -33130,7 +33232,7 @@ async function createServer(config2) {
|
|
|
33130
33232
|
app.get("/demo/chatbot", (0, import_bun.serveStatic)({ path: `${publicDir}/demo-chatbot.html` }));
|
|
33131
33233
|
app.get("/demo/react", (0, import_bun.serveStatic)({ path: `${publicDir}/react-demo.html` }));
|
|
33132
33234
|
}
|
|
33133
|
-
const deps = { client, store, config: config2, prompts, apiKeyManager };
|
|
33235
|
+
const deps = { client, store, db, config: config2, prompts, apiKeyManager };
|
|
33134
33236
|
if (enablePublic) {
|
|
33135
33237
|
app.route("/", publicRoutes(deps));
|
|
33136
33238
|
}
|
|
@@ -33158,6 +33260,8 @@ async function createServer(config2) {
|
|
|
33158
33260
|
DEFAULT_MODEL,
|
|
33159
33261
|
PromptLoader,
|
|
33160
33262
|
VectorStore,
|
|
33263
|
+
answerOnce,
|
|
33264
|
+
answerStream,
|
|
33161
33265
|
completeOnce,
|
|
33162
33266
|
completeStream,
|
|
33163
33267
|
cors,
|
|
@@ -33173,6 +33277,7 @@ async function createServer(config2) {
|
|
|
33173
33277
|
detectLeakage,
|
|
33174
33278
|
getActiveSessions,
|
|
33175
33279
|
getSessionInfo,
|
|
33280
|
+
guardOutput,
|
|
33176
33281
|
loadKnowledge,
|
|
33177
33282
|
openaiRoutes,
|
|
33178
33283
|
prepareChat,
|
package/dist/index.mjs
CHANGED
|
@@ -7643,7 +7643,7 @@ var ApiKeyManager = class {
|
|
|
7643
7643
|
};
|
|
7644
7644
|
|
|
7645
7645
|
// src/index.ts
|
|
7646
|
-
var
|
|
7646
|
+
var import_client3 = __toESM(require_dist());
|
|
7647
7647
|
|
|
7648
7648
|
// src/core/guardrails.ts
|
|
7649
7649
|
function detectLeakage(text) {
|
|
@@ -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
|
-
|
|
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:
|
|
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";
|
|
@@ -7817,13 +7865,18 @@ async function sha256(input) {
|
|
|
7817
7865
|
var VectorStore = class _VectorStore {
|
|
7818
7866
|
constructor(client, options) {
|
|
7819
7867
|
this.client = client;
|
|
7820
|
-
this.db = createClient({
|
|
7868
|
+
this.db = options.databaseClient ? options.databaseClient : createClient({
|
|
7821
7869
|
url: options.databaseUrl,
|
|
7822
7870
|
authToken: options.databaseAuthToken
|
|
7823
7871
|
});
|
|
7824
7872
|
this.knowledgeDir = options.knowledgeDir || "./config/knowledge";
|
|
7825
7873
|
}
|
|
7826
7874
|
client;
|
|
7875
|
+
/**
|
|
7876
|
+
* The libsql client backing this store. When a client was injected this is
|
|
7877
|
+
* that same instance, so callers holding it (e.g. `ServerDependencies.db`)
|
|
7878
|
+
* and the store share one connection.
|
|
7879
|
+
*/
|
|
7827
7880
|
db;
|
|
7828
7881
|
knowledgeDir;
|
|
7829
7882
|
// On boot: ingest new chunks and embed only missing ones.
|
|
@@ -32217,10 +32270,12 @@ async function createMCPServer(config2) {
|
|
|
32217
32270
|
`Context:
|
|
32218
32271
|
${ctx.join("\n\n")}`
|
|
32219
32272
|
].join("\n\n");
|
|
32220
|
-
const result = await
|
|
32273
|
+
const result = await answerOnce({
|
|
32274
|
+
answerFn: config2.answerFn,
|
|
32221
32275
|
client,
|
|
32222
32276
|
system,
|
|
32223
|
-
messages: conversationMessages
|
|
32277
|
+
messages: conversationMessages,
|
|
32278
|
+
mode: "public"
|
|
32224
32279
|
});
|
|
32225
32280
|
const cost = calculateCost(result.usage);
|
|
32226
32281
|
const duration3 = Date.now() - startTime;
|
|
@@ -32301,10 +32356,12 @@ ${ctx.join("\n\n")}`
|
|
|
32301
32356
|
`Internal Context:
|
|
32302
32357
|
${ctx.join("\n\n")}`
|
|
32303
32358
|
].join("\n\n");
|
|
32304
|
-
const result = await
|
|
32359
|
+
const result = await answerOnce({
|
|
32360
|
+
answerFn: config2.answerFn,
|
|
32305
32361
|
client,
|
|
32306
32362
|
system,
|
|
32307
|
-
messages: conversationMessages
|
|
32363
|
+
messages: conversationMessages,
|
|
32364
|
+
mode: "private"
|
|
32308
32365
|
});
|
|
32309
32366
|
const cost = calculateCost(result.usage);
|
|
32310
32367
|
const duration3 = Date.now() - startTime;
|
|
@@ -32722,7 +32779,13 @@ ${ctx.join("\n\n")}`
|
|
|
32722
32779
|
const wantsStream3 = url2.searchParams.get("stream") === "1";
|
|
32723
32780
|
if (wantsStream3) {
|
|
32724
32781
|
return stream(c, async (s) => {
|
|
32725
|
-
for await (const delta of
|
|
32782
|
+
for await (const delta of answerStream({
|
|
32783
|
+
answerFn: config2.answerFn,
|
|
32784
|
+
client,
|
|
32785
|
+
system,
|
|
32786
|
+
messages,
|
|
32787
|
+
mode: "public"
|
|
32788
|
+
})) {
|
|
32726
32789
|
await s.write(`data: ${JSON.stringify({ delta })}
|
|
32727
32790
|
|
|
32728
32791
|
`);
|
|
@@ -32730,7 +32793,13 @@ ${ctx.join("\n\n")}`
|
|
|
32730
32793
|
await s.write("event: end\ndata: {}\n\n");
|
|
32731
32794
|
});
|
|
32732
32795
|
}
|
|
32733
|
-
const out = await
|
|
32796
|
+
const out = await answerOnce({
|
|
32797
|
+
answerFn: config2.answerFn,
|
|
32798
|
+
client,
|
|
32799
|
+
system,
|
|
32800
|
+
messages,
|
|
32801
|
+
mode: "public"
|
|
32802
|
+
});
|
|
32734
32803
|
return c.json({ reply: out.content });
|
|
32735
32804
|
} catch (error51) {
|
|
32736
32805
|
const err = error51;
|
|
@@ -32827,10 +32896,12 @@ function openaiRoutes(deps) {
|
|
|
32827
32896
|
|
|
32828
32897
|
`;
|
|
32829
32898
|
await s.write(chunk2({ role: "assistant", content: "" }, null));
|
|
32830
|
-
for await (const delta of
|
|
32899
|
+
for await (const delta of answerStream({
|
|
32900
|
+
answerFn: config2.answerFn,
|
|
32831
32901
|
client,
|
|
32832
32902
|
system,
|
|
32833
32903
|
messages,
|
|
32904
|
+
mode,
|
|
32834
32905
|
temperature,
|
|
32835
32906
|
model: serverModel
|
|
32836
32907
|
})) {
|
|
@@ -32840,7 +32911,15 @@ function openaiRoutes(deps) {
|
|
|
32840
32911
|
await s.write("data: [DONE]\n\n");
|
|
32841
32912
|
});
|
|
32842
32913
|
}
|
|
32843
|
-
const out = await
|
|
32914
|
+
const out = await answerOnce({
|
|
32915
|
+
answerFn: config2.answerFn,
|
|
32916
|
+
client,
|
|
32917
|
+
system,
|
|
32918
|
+
messages,
|
|
32919
|
+
mode,
|
|
32920
|
+
temperature,
|
|
32921
|
+
model: serverModel
|
|
32922
|
+
});
|
|
32844
32923
|
return c.json({
|
|
32845
32924
|
id,
|
|
32846
32925
|
object: "chat.completion",
|
|
@@ -32901,9 +32980,17 @@ function privateRoutes(deps) {
|
|
|
32901
32980
|
return c.json({ error: "no user message found in conversation" }, 400);
|
|
32902
32981
|
}
|
|
32903
32982
|
const model = config2.openai.model;
|
|
32983
|
+
const answerFn = config2.answerFn;
|
|
32904
32984
|
if (wantsStream(c)) {
|
|
32905
32985
|
return stream3(c, async (s) => {
|
|
32906
|
-
for await (const delta of
|
|
32986
|
+
for await (const delta of answerStream({
|
|
32987
|
+
answerFn,
|
|
32988
|
+
client,
|
|
32989
|
+
system,
|
|
32990
|
+
messages,
|
|
32991
|
+
mode: "private",
|
|
32992
|
+
model
|
|
32993
|
+
})) {
|
|
32907
32994
|
await s.write(`data: ${JSON.stringify({ delta })}
|
|
32908
32995
|
|
|
32909
32996
|
`);
|
|
@@ -32911,7 +32998,7 @@ function privateRoutes(deps) {
|
|
|
32911
32998
|
await s.write("event: end\ndata: {}\n\n");
|
|
32912
32999
|
});
|
|
32913
33000
|
}
|
|
32914
|
-
const out = await
|
|
33001
|
+
const out = await answerOnce({ answerFn, client, system, messages, mode: "private", model });
|
|
32915
33002
|
return c.json({ reply: out.content });
|
|
32916
33003
|
});
|
|
32917
33004
|
return app;
|
|
@@ -32956,9 +33043,17 @@ function publicRoutes(deps) {
|
|
|
32956
33043
|
return c.json({ error: "no user message found in conversation" }, 400);
|
|
32957
33044
|
}
|
|
32958
33045
|
const model = config2.openai.model;
|
|
33046
|
+
const answerFn = config2.answerFn;
|
|
32959
33047
|
if (wantsStream2(c)) {
|
|
32960
33048
|
return stream4(c, async (s) => {
|
|
32961
|
-
for await (const delta of
|
|
33049
|
+
for await (const delta of answerStream({
|
|
33050
|
+
answerFn,
|
|
33051
|
+
client,
|
|
33052
|
+
system,
|
|
33053
|
+
messages,
|
|
33054
|
+
mode: "public",
|
|
33055
|
+
model
|
|
33056
|
+
})) {
|
|
32962
33057
|
await s.write(`data: ${JSON.stringify({ delta })}
|
|
32963
33058
|
|
|
32964
33059
|
`);
|
|
@@ -32966,13 +33061,14 @@ function publicRoutes(deps) {
|
|
|
32966
33061
|
await s.write("event: end\ndata: {}\n\n");
|
|
32967
33062
|
});
|
|
32968
33063
|
}
|
|
32969
|
-
const out = await
|
|
33064
|
+
const out = await answerOnce({ answerFn, client, system, messages, mode: "public", model });
|
|
32970
33065
|
return c.json({ reply: out.content });
|
|
32971
33066
|
});
|
|
32972
33067
|
return app;
|
|
32973
33068
|
}
|
|
32974
33069
|
|
|
32975
33070
|
// src/server.ts
|
|
33071
|
+
import { createClient as createClient2 } from "@libsql/client";
|
|
32976
33072
|
import { Hono as Hono5 } from "hono";
|
|
32977
33073
|
import { serveStatic } from "hono/bun";
|
|
32978
33074
|
import OpenAI2 from "openai";
|
|
@@ -33018,9 +33114,12 @@ async function createServer(config2) {
|
|
|
33018
33114
|
const client = new OpenAI2({
|
|
33019
33115
|
apiKey: config2.openai.apiKey
|
|
33020
33116
|
});
|
|
33117
|
+
const db = createClient2({
|
|
33118
|
+
url: config2.database.url,
|
|
33119
|
+
authToken: config2.database.authToken
|
|
33120
|
+
});
|
|
33021
33121
|
const store = new VectorStore(client, {
|
|
33022
|
-
|
|
33023
|
-
databaseAuthToken: config2.database.authToken,
|
|
33122
|
+
databaseClient: db,
|
|
33024
33123
|
knowledgeDir
|
|
33025
33124
|
});
|
|
33026
33125
|
await store.build();
|
|
@@ -33098,7 +33197,7 @@ async function createServer(config2) {
|
|
|
33098
33197
|
app.get("/demo/chatbot", serveStatic({ path: `${publicDir}/demo-chatbot.html` }));
|
|
33099
33198
|
app.get("/demo/react", serveStatic({ path: `${publicDir}/react-demo.html` }));
|
|
33100
33199
|
}
|
|
33101
|
-
const deps = { client, store, config: config2, prompts, apiKeyManager };
|
|
33200
|
+
const deps = { client, store, db, config: config2, prompts, apiKeyManager };
|
|
33102
33201
|
if (enablePublic) {
|
|
33103
33202
|
app.route("/", publicRoutes(deps));
|
|
33104
33203
|
}
|
|
@@ -33117,9 +33216,9 @@ async function createServer(config2) {
|
|
|
33117
33216
|
console.log(`\u2705 ${config2.bot.name} server ready`);
|
|
33118
33217
|
return app;
|
|
33119
33218
|
}
|
|
33120
|
-
var export_Chat =
|
|
33121
|
-
var export_ChatBot =
|
|
33122
|
-
var export_ChatButton =
|
|
33219
|
+
var export_Chat = import_client3.Chat;
|
|
33220
|
+
var export_ChatBot = import_client3.ChatBot;
|
|
33221
|
+
var export_ChatButton = import_client3.ChatButton;
|
|
33123
33222
|
export {
|
|
33124
33223
|
ApiKeyManager,
|
|
33125
33224
|
export_Chat as Chat,
|
|
@@ -33128,6 +33227,8 @@ export {
|
|
|
33128
33227
|
DEFAULT_MODEL,
|
|
33129
33228
|
PromptLoader,
|
|
33130
33229
|
VectorStore,
|
|
33230
|
+
answerOnce,
|
|
33231
|
+
answerStream,
|
|
33131
33232
|
completeOnce,
|
|
33132
33233
|
completeStream,
|
|
33133
33234
|
cors,
|
|
@@ -33143,6 +33244,7 @@ export {
|
|
|
33143
33244
|
detectLeakage,
|
|
33144
33245
|
getActiveSessions,
|
|
33145
33246
|
getSessionInfo,
|
|
33247
|
+
guardOutput,
|
|
33146
33248
|
loadKnowledge,
|
|
33147
33249
|
openaiRoutes,
|
|
33148
33250
|
prepareChat,
|
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;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,
|
|
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"}
|
package/dist/mcp-server.js
CHANGED
|
@@ -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
|
-
|
|
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:
|
|
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");
|
|
@@ -162,13 +193,18 @@ async function sha256(input) {
|
|
|
162
193
|
var VectorStore = class _VectorStore {
|
|
163
194
|
constructor(client, options) {
|
|
164
195
|
this.client = client;
|
|
165
|
-
this.db = (0, import_client.createClient)({
|
|
196
|
+
this.db = options.databaseClient ? options.databaseClient : (0, import_client.createClient)({
|
|
166
197
|
url: options.databaseUrl,
|
|
167
198
|
authToken: options.databaseAuthToken
|
|
168
199
|
});
|
|
169
200
|
this.knowledgeDir = options.knowledgeDir || "./config/knowledge";
|
|
170
201
|
}
|
|
171
202
|
client;
|
|
203
|
+
/**
|
|
204
|
+
* The libsql client backing this store. When a client was injected this is
|
|
205
|
+
* that same instance, so callers holding it (e.g. `ServerDependencies.db`)
|
|
206
|
+
* and the store share one connection.
|
|
207
|
+
*/
|
|
172
208
|
db;
|
|
173
209
|
knowledgeDir;
|
|
174
210
|
// On boot: ingest new chunks and embed only missing ones.
|
|
@@ -531,10 +567,12 @@ async function createMCPServer(config) {
|
|
|
531
567
|
`Context:
|
|
532
568
|
${ctx.join("\n\n")}`
|
|
533
569
|
].join("\n\n");
|
|
534
|
-
const result = await
|
|
570
|
+
const result = await answerOnce({
|
|
571
|
+
answerFn: config.answerFn,
|
|
535
572
|
client,
|
|
536
573
|
system,
|
|
537
|
-
messages: conversationMessages
|
|
574
|
+
messages: conversationMessages,
|
|
575
|
+
mode: "public"
|
|
538
576
|
});
|
|
539
577
|
const cost = calculateCost(result.usage);
|
|
540
578
|
const duration = Date.now() - startTime;
|
|
@@ -615,10 +653,12 @@ ${ctx.join("\n\n")}`
|
|
|
615
653
|
`Internal Context:
|
|
616
654
|
${ctx.join("\n\n")}`
|
|
617
655
|
].join("\n\n");
|
|
618
|
-
const result = await
|
|
656
|
+
const result = await answerOnce({
|
|
657
|
+
answerFn: config.answerFn,
|
|
619
658
|
client,
|
|
620
659
|
system,
|
|
621
|
-
messages: conversationMessages
|
|
660
|
+
messages: conversationMessages,
|
|
661
|
+
mode: "private"
|
|
622
662
|
});
|
|
623
663
|
const cost = calculateCost(result.usage);
|
|
624
664
|
const duration = Date.now() - startTime;
|
package/dist/mcp-server.mjs
CHANGED
|
@@ -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
|
-
|
|
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:
|
|
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";
|
|
@@ -128,13 +159,18 @@ async function sha256(input) {
|
|
|
128
159
|
var VectorStore = class _VectorStore {
|
|
129
160
|
constructor(client, options) {
|
|
130
161
|
this.client = client;
|
|
131
|
-
this.db = createClient({
|
|
162
|
+
this.db = options.databaseClient ? options.databaseClient : createClient({
|
|
132
163
|
url: options.databaseUrl,
|
|
133
164
|
authToken: options.databaseAuthToken
|
|
134
165
|
});
|
|
135
166
|
this.knowledgeDir = options.knowledgeDir || "./config/knowledge";
|
|
136
167
|
}
|
|
137
168
|
client;
|
|
169
|
+
/**
|
|
170
|
+
* The libsql client backing this store. When a client was injected this is
|
|
171
|
+
* that same instance, so callers holding it (e.g. `ServerDependencies.db`)
|
|
172
|
+
* and the store share one connection.
|
|
173
|
+
*/
|
|
138
174
|
db;
|
|
139
175
|
knowledgeDir;
|
|
140
176
|
// On boot: ingest new chunks and embed only missing ones.
|
|
@@ -497,10 +533,12 @@ async function createMCPServer(config) {
|
|
|
497
533
|
`Context:
|
|
498
534
|
${ctx.join("\n\n")}`
|
|
499
535
|
].join("\n\n");
|
|
500
|
-
const result = await
|
|
536
|
+
const result = await answerOnce({
|
|
537
|
+
answerFn: config.answerFn,
|
|
501
538
|
client,
|
|
502
539
|
system,
|
|
503
|
-
messages: conversationMessages
|
|
540
|
+
messages: conversationMessages,
|
|
541
|
+
mode: "public"
|
|
504
542
|
});
|
|
505
543
|
const cost = calculateCost(result.usage);
|
|
506
544
|
const duration = Date.now() - startTime;
|
|
@@ -581,10 +619,12 @@ ${ctx.join("\n\n")}`
|
|
|
581
619
|
`Internal Context:
|
|
582
620
|
${ctx.join("\n\n")}`
|
|
583
621
|
].join("\n\n");
|
|
584
|
-
const result = await
|
|
622
|
+
const result = await answerOnce({
|
|
623
|
+
answerFn: config.answerFn,
|
|
585
624
|
client,
|
|
586
625
|
system,
|
|
587
|
-
messages: conversationMessages
|
|
626
|
+
messages: conversationMessages,
|
|
627
|
+
mode: "private"
|
|
588
628
|
});
|
|
589
629
|
const cost = calculateCost(result.usage);
|
|
590
630
|
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,
|
|
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;
|
|
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,
|
|
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,
|
|
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/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
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,uFA8JvD"}
|
package/dist/types.d.ts
CHANGED
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
* Core types for the Chatter chatbot framework.
|
|
5
5
|
* These types define the public API and configuration interface.
|
|
6
6
|
*/
|
|
7
|
+
import type { Client as LibsqlClient } from "@libsql/client";
|
|
7
8
|
import type { Hono } from "hono";
|
|
8
9
|
import type OpenAI from "openai";
|
|
10
|
+
import type { AnswerFn } from "./core/answer";
|
|
9
11
|
import type { PromptLoader } from "./core/prompts";
|
|
10
12
|
import type { VectorStore } from "./core/retrieval";
|
|
11
13
|
/**
|
|
@@ -143,6 +145,17 @@ export interface ChatterConfig {
|
|
|
143
145
|
*/
|
|
144
146
|
allowedOrigins?: string[];
|
|
145
147
|
};
|
|
148
|
+
/**
|
|
149
|
+
* Replaces the completion call on every chat surface with your own brain —
|
|
150
|
+
* an agent framework, a graph runtime, a remote service. Receives the
|
|
151
|
+
* assembled system prompt and conversation from the pipeline and returns
|
|
152
|
+
* the answer text (optionally with token usage).
|
|
153
|
+
*
|
|
154
|
+
* Retrieval, prompt assembly, auth, rate limiting, transports and output
|
|
155
|
+
* guardrails all stay Chatter's. Errors surface as normal completion
|
|
156
|
+
* errors. Unset: the built-in OpenAI completion is used.
|
|
157
|
+
*/
|
|
158
|
+
answerFn?: AnswerFn;
|
|
146
159
|
/** Custom route handler for advanced use cases */
|
|
147
160
|
customRoutes?: (app: Hono, deps: ServerDependencies) => void;
|
|
148
161
|
}
|
|
@@ -154,6 +167,12 @@ export interface ServerDependencies {
|
|
|
154
167
|
client: OpenAI;
|
|
155
168
|
/** Vector store instance */
|
|
156
169
|
store: VectorStore;
|
|
170
|
+
/**
|
|
171
|
+
* The libsql database client, shared with the vector store. Custom routes
|
|
172
|
+
* should use this handle rather than opening their own connection to the
|
|
173
|
+
* same database.
|
|
174
|
+
*/
|
|
175
|
+
db: LibsqlClient;
|
|
157
176
|
/** Chatter configuration */
|
|
158
177
|
config: ChatterConfig;
|
|
159
178
|
/** Prompt loader instance */
|
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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diegoaltoworks/chatter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.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",
|
|
@@ -59,6 +59,13 @@
|
|
|
59
59
|
"security:audit:fix": "bun update",
|
|
60
60
|
"security:check": "bun audit --audit-level=moderate",
|
|
61
61
|
"check": "bun run typecheck && bun run lint && bun run test && bun run security:check",
|
|
62
|
+
"work": "bun ./.claude/work.ts run",
|
|
63
|
+
"work:continuous": "bun ./.claude/work.ts run --continuous",
|
|
64
|
+
"work:status": "bun ./.claude/work.ts status",
|
|
65
|
+
"work:reset": "bun ./.claude/work.ts reset",
|
|
66
|
+
"work:watch": "bun ./.claude/work.ts watch",
|
|
67
|
+
"work:resume": "bun ./.claude/work.ts resume",
|
|
68
|
+
"work:halt": "bun ./.claude/work.ts halt",
|
|
62
69
|
"prepublishOnly": "bun run lint && bun run typecheck && bun run test && bun run security:check && bun run build",
|
|
63
70
|
"prepare": "husky || true"
|
|
64
71
|
},
|