@diegoaltoworks/chatter 0.55.0 → 0.57.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/channels/index.js +46 -4
- package/dist/channels/index.mjs +46 -4
- package/dist/channels/pipeline.d.ts +16 -1
- package/dist/channels/pipeline.d.ts.map +1 -1
- package/dist/channels/telegram/channel.d.ts +8 -1
- package/dist/channels/telegram/channel.d.ts.map +1 -1
- package/dist/channels/telegram/index.js +52 -5
- package/dist/channels/telegram/index.mjs +52 -5
- package/dist/channels/whatsapp/inbound.d.ts +11 -1
- package/dist/channels/whatsapp/inbound.d.ts.map +1 -1
- package/dist/channels/whatsapp/index.js +52 -5
- package/dist/channels/whatsapp/index.mjs +52 -5
- package/dist/core/answer.d.ts +31 -0
- package/dist/core/answer.d.ts.map +1 -1
- package/dist/core/pipeline.d.ts +52 -1
- package/dist/core/pipeline.d.ts.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +128 -19
- package/dist/index.mjs +127 -19
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +57 -8
- package/dist/mcp-server.mjs +57 -8
- 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.js +104 -13
- package/dist/server.mjs +104 -13
- package/dist/types.d.ts +42 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -676,6 +676,18 @@ async function answerOnce({
|
|
|
676
676
|
}
|
|
677
677
|
return completeOnce({ client, system, messages, temperature, model });
|
|
678
678
|
}
|
|
679
|
+
async function applyTransformReply(transformReply, input, logger) {
|
|
680
|
+
if (!transformReply) return input.text;
|
|
681
|
+
try {
|
|
682
|
+
return await transformReply(input);
|
|
683
|
+
} catch (error) {
|
|
684
|
+
logger?.error(
|
|
685
|
+
`transformReply threw for channel "${input.channel}"; sending the original reply`,
|
|
686
|
+
error
|
|
687
|
+
);
|
|
688
|
+
return input.text;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
679
691
|
|
|
680
692
|
// src/core/buckets.ts
|
|
681
693
|
function defaultBuckets(mode) {
|
|
@@ -725,14 +737,35 @@ async function prepareChat({
|
|
|
725
737
|
messages,
|
|
726
738
|
personaLayer,
|
|
727
739
|
channelHint,
|
|
728
|
-
buckets
|
|
740
|
+
buckets,
|
|
741
|
+
sender,
|
|
742
|
+
rewriteQuery,
|
|
743
|
+
rerankContext,
|
|
744
|
+
logger
|
|
729
745
|
}) {
|
|
730
746
|
const lastUserMsg = lastUserMessage(messages);
|
|
731
747
|
if (!lastUserMsg) {
|
|
732
748
|
throw new Error("no user message found in conversation");
|
|
733
749
|
}
|
|
734
750
|
const { topK, label } = MODE_SETTINGS[mode];
|
|
735
|
-
|
|
751
|
+
let query = lastUserMsg.content;
|
|
752
|
+
if (rewriteQuery) {
|
|
753
|
+
try {
|
|
754
|
+
const rewritten = await rewriteQuery({ query, mode, sender });
|
|
755
|
+
if (typeof rewritten === "string" && rewritten.trim()) query = rewritten;
|
|
756
|
+
} catch (error) {
|
|
757
|
+
logger?.error("rewriteQuery threw; falling back to the original query", error);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
let ctx = await store.query(query, topK, buckets ?? defaultBuckets(mode));
|
|
761
|
+
if (rerankContext) {
|
|
762
|
+
try {
|
|
763
|
+
const reranked = await rerankContext({ query, chunks: ctx });
|
|
764
|
+
if (Array.isArray(reranked) && reranked.every((c) => typeof c === "string")) ctx = reranked;
|
|
765
|
+
} catch (error) {
|
|
766
|
+
logger?.error("rerankContext threw; falling back to the original chunks", error);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
736
769
|
const persona = personaLayer?.trim() || (mode === "private" ? prompts.privatePersona : prompts.publicPersona);
|
|
737
770
|
const hint = channelHint?.trim();
|
|
738
771
|
const system = [
|
|
@@ -809,9 +842,13 @@ function createInboundPipeline(deps, config) {
|
|
|
809
842
|
messages,
|
|
810
843
|
personaLayer,
|
|
811
844
|
channelHint: config.channelHint,
|
|
812
|
-
buckets
|
|
845
|
+
buckets,
|
|
846
|
+
sender,
|
|
847
|
+
rewriteQuery: config.rewriteQuery,
|
|
848
|
+
rerankContext: config.rerankContext,
|
|
849
|
+
logger: config.logger
|
|
813
850
|
});
|
|
814
|
-
const { content } = await answerOnce({
|
|
851
|
+
const { content: produced } = await answerOnce({
|
|
815
852
|
answerFn: config.answerFn,
|
|
816
853
|
client: deps.client,
|
|
817
854
|
system,
|
|
@@ -821,6 +858,11 @@ function createInboundPipeline(deps, config) {
|
|
|
821
858
|
conversationId,
|
|
822
859
|
model: config.model
|
|
823
860
|
});
|
|
861
|
+
const content = await applyTransformReply(
|
|
862
|
+
config.transformReply,
|
|
863
|
+
{ channel: config.channel ?? "channel", sender, conversationId, text: produced },
|
|
864
|
+
config.logger
|
|
865
|
+
);
|
|
824
866
|
if (!content) {
|
|
825
867
|
return { action: "ignore" };
|
|
826
868
|
}
|
|
@@ -928,8 +970,12 @@ function createWhatsAppInboundHandler(config) {
|
|
|
928
970
|
const pipeline = createInboundPipeline(
|
|
929
971
|
{ client: config.client, store: config.store, prompts: config.prompts },
|
|
930
972
|
{
|
|
973
|
+
channel: "whatsapp",
|
|
931
974
|
answerFn: config.answerFn,
|
|
932
975
|
bucketsFor: config.bucketsFor,
|
|
976
|
+
rewriteQuery: config.rewriteQuery,
|
|
977
|
+
rerankContext: config.rerankContext,
|
|
978
|
+
transformReply: config.transformReply,
|
|
933
979
|
model: config.model,
|
|
934
980
|
channelHint: config.channelHint,
|
|
935
981
|
personaResolver: personaResolver ? ({ sender, text }) => personaResolver({ senderPhone: sender, text }) : void 0,
|
|
@@ -941,7 +987,8 @@ function createWhatsAppInboundHandler(config) {
|
|
|
941
987
|
unmuteReply: config.unmuteReply,
|
|
942
988
|
dmRateLimit: config.dmRateLimit,
|
|
943
989
|
groupRateLimit: config.groupRateLimit,
|
|
944
|
-
now: config.now
|
|
990
|
+
now: config.now,
|
|
991
|
+
logger
|
|
945
992
|
}
|
|
946
993
|
);
|
|
947
994
|
return async function handleWhatsAppMessage(event) {
|
package/dist/core/answer.d.ts
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* exactly what it has always been.
|
|
14
14
|
*/
|
|
15
15
|
import type OpenAI from "openai";
|
|
16
|
+
import type { Logger } from "./logger";
|
|
16
17
|
import type { PipelineMessage, PipelineMode } from "./pipeline";
|
|
17
18
|
/** Token accounting in the OpenAI wire shape */
|
|
18
19
|
export interface AnswerUsage {
|
|
@@ -66,6 +67,36 @@ export declare function answerOnce({ answerFn, client, system, messages, mode, s
|
|
|
66
67
|
content: string;
|
|
67
68
|
usage: AnswerUsage;
|
|
68
69
|
}>;
|
|
70
|
+
/** What a `transformReply` hook receives: the produced answer plus who/where it's going. */
|
|
71
|
+
export interface TransformReplyInput {
|
|
72
|
+
/**
|
|
73
|
+
* Identifies the surface delivering this reply — a channel's own name
|
|
74
|
+
* (e.g. "whatsapp", "telegram") or a fixed identifier for an HTTP surface
|
|
75
|
+
* (e.g. "widget-public", "openai-compat-private").
|
|
76
|
+
*/
|
|
77
|
+
channel: string;
|
|
78
|
+
sender?: string;
|
|
79
|
+
conversationId?: string;
|
|
80
|
+
text: string;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Modifies or vetoes an already-produced reply, after `answerFn`/the built-in
|
|
84
|
+
* completion and guardrails have run. A string result replaces the reply;
|
|
85
|
+
* `null` vetoes it — treated the same as an empty answer by every call site
|
|
86
|
+
* (nothing delivered; the channel pipeline never records an assistant turn
|
|
87
|
+
* for it, though the user's own turn — already appended before answering —
|
|
88
|
+
* stays recorded).
|
|
89
|
+
*
|
|
90
|
+
* Non-streaming surfaces only: a streaming response is delivered incrementally
|
|
91
|
+
* as it's produced, before a final answer exists to transform.
|
|
92
|
+
*/
|
|
93
|
+
export type TransformReply = (input: TransformReplyInput) => string | null | Promise<string | null>;
|
|
94
|
+
/**
|
|
95
|
+
* Runs `transformReply` if configured. A throw/rejection is logged and the
|
|
96
|
+
* ORIGINAL text is returned — the delivery invariant: a bug in a plugin hook
|
|
97
|
+
* must never silently swallow an answer the model already produced.
|
|
98
|
+
*/
|
|
99
|
+
export declare function applyTransformReply(transformReply: TransformReply | undefined, input: TransformReplyInput, logger?: Pick<Logger, "error">): Promise<string | null>;
|
|
69
100
|
/**
|
|
70
101
|
* Stream an answer. A brain that returns a plain string cannot stream, so its
|
|
71
102
|
* answer degrades to a single chunk followed by the stream's normal end —
|
|
@@ -1 +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;IAChB,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;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,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,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,cAAc,EACd,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,cAAc,EACd,WAAW,EACX,KAAK,GACN,EAAE,aAAa,GAAG,cAAc,CAAC,MAAM,CAAC,CAaxC"}
|
|
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,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,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;IAChB,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;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,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,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,cAAc,EACd,WAAW,EACX,KAAK,GACN,EAAE,aAAa,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC,CAKlE;AAED,4FAA4F;AAC5F,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,mBAAmB,KAAK,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAEpG;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,cAAc,EAAE,cAAc,GAAG,SAAS,EAC1C,KAAK,EAAE,mBAAmB,EAC1B,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWxB;AAED;;;;;;;;GAQG;AACH,wBAAuB,YAAY,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,cAAc,EACd,WAAW,EACX,KAAK,GACN,EAAE,aAAa,GAAG,cAAc,CAAC,MAAM,CAAC,CAaxC"}
|
package/dist/core/pipeline.d.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* then ask for the answer via `answerOnce`/`answerStream` (see ./answer.ts)
|
|
9
9
|
* so a caller-supplied brain is honoured.
|
|
10
10
|
*/
|
|
11
|
+
import type { Logger } from "./logger";
|
|
11
12
|
import type { PromptLoader } from "./prompts";
|
|
12
13
|
import type { VectorStore } from "./retrieval";
|
|
13
14
|
export type PipelineMode = "public" | "private";
|
|
@@ -23,6 +24,42 @@ export interface PreparedChat {
|
|
|
23
24
|
/** Raw retrieved chunks, before being folded into `system` — for callers that log or display RAG context alongside the answer */
|
|
24
25
|
context: string[];
|
|
25
26
|
}
|
|
27
|
+
/** What `rewriteQuery` sees for a turn. */
|
|
28
|
+
export interface RewriteQueryArgs {
|
|
29
|
+
/** The latest user message's content — what retrieval would search on unmodified. */
|
|
30
|
+
query: string;
|
|
31
|
+
mode: PipelineMode;
|
|
32
|
+
/** Caller identity, where the surface has one. Absent on anonymous surfaces. */
|
|
33
|
+
sender?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Rewrites the retrieval query before it reaches the vector store — e.g.
|
|
37
|
+
* expanding an ambiguous follow-up ("what about the second one?") into
|
|
38
|
+
* something embeddable on its own. Return the query unchanged to opt out for
|
|
39
|
+
* a given turn. A throw/rejection is caught by `prepareChat`, which falls
|
|
40
|
+
* back to the original query — a broken rewrite must never break retrieval.
|
|
41
|
+
*/
|
|
42
|
+
export type RewriteQuery = (ctx: RewriteQueryArgs) => string | Promise<string>;
|
|
43
|
+
/** What `rerankContext` sees for a turn. */
|
|
44
|
+
export interface RerankContextArgs {
|
|
45
|
+
/** The query retrieval actually ran with — post-`rewriteQuery`, if configured. */
|
|
46
|
+
query: string;
|
|
47
|
+
/** Chunks `store.query` returned, in its own order. */
|
|
48
|
+
chunks: string[];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Reorders, filters, or otherwise post-processes the chunks retrieval
|
|
52
|
+
* returned before they're folded into the system prompt. A throw/rejection
|
|
53
|
+
* is caught by `prepareChat`, which falls back to the original chunks in
|
|
54
|
+
* their original order — a broken reranker must never break retrieval.
|
|
55
|
+
*
|
|
56
|
+
* This is NOT the seam for access control. Because a failure falls back to
|
|
57
|
+
* the unfiltered chunks, a hook that drops chunks a sender shouldn't see
|
|
58
|
+
* would silently un-drop them on its own error — the opposite of safe
|
|
59
|
+
* failure. Scope decisions belong in `bucketsFor` (see ./buckets), which
|
|
60
|
+
* fails closed by design; use this hook for relevance/ordering only.
|
|
61
|
+
*/
|
|
62
|
+
export type RerankContext = (ctx: RerankContextArgs) => string[] | Promise<string[]>;
|
|
26
63
|
/**
|
|
27
64
|
* Run retrieval for the latest user message and assemble the system prompt.
|
|
28
65
|
*
|
|
@@ -40,9 +77,15 @@ export interface PreparedChat {
|
|
|
40
77
|
* `resolveBuckets` (see ./buckets) first, which is where the anonymous
|
|
41
78
|
* ceiling is enforced.
|
|
42
79
|
*
|
|
80
|
+
* `rewriteQuery` and `rerankContext` shape retrieval itself rather than the
|
|
81
|
+
* prompt around it: the former runs before `store.query`, the latter after.
|
|
82
|
+
* Both are optional and fail open — a throw, rejection, or malformed return
|
|
83
|
+
* value falls back to what retrieval would have done unmodified, so a buggy
|
|
84
|
+
* hook degrades relevance rather than breaking the chat path.
|
|
85
|
+
*
|
|
43
86
|
* @throws if the conversation contains no user message
|
|
44
87
|
*/
|
|
45
|
-
export declare function prepareChat({ store, prompts, mode, messages, personaLayer, channelHint, buckets, }: {
|
|
88
|
+
export declare function prepareChat({ store, prompts, mode, messages, personaLayer, channelHint, buckets, sender, rewriteQuery, rerankContext, logger, }: {
|
|
46
89
|
store: VectorStore;
|
|
47
90
|
prompts: PromptLoader;
|
|
48
91
|
mode: PipelineMode;
|
|
@@ -56,5 +99,13 @@ export declare function prepareChat({ store, prompts, mode, messages, personaLay
|
|
|
56
99
|
* `["base", mode]`. An empty array retrieves nothing.
|
|
57
100
|
*/
|
|
58
101
|
buckets?: string[];
|
|
102
|
+
/** Caller identity, passed through to `rewriteQuery`. Absent on anonymous surfaces. */
|
|
103
|
+
sender?: string;
|
|
104
|
+
/** Rewrites the retrieval query before `store.query` runs — see {@link RewriteQuery}. */
|
|
105
|
+
rewriteQuery?: RewriteQuery;
|
|
106
|
+
/** Post-processes retrieved chunks before they're folded into the prompt — see {@link RerankContext}. */
|
|
107
|
+
rerankContext?: RerankContext;
|
|
108
|
+
/** Logs a `rewriteQuery`/`rerankContext` throw before falling back. Unset: the failure is silent. */
|
|
109
|
+
logger?: Pick<Logger, "error">;
|
|
59
110
|
}): Promise<PreparedChat>;
|
|
60
111
|
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,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;IAC5B,iIAAiI;IACjI,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,2CAA2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B,qFAAqF;IACrF,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;IACnB,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,gBAAgB,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAE/E,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB;IAChC,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,iBAAiB,KAAK,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AAOrF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,WAAW,CAAC,EAChC,KAAK,EACL,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,OAAO,EACP,MAAM,EACN,YAAY,EACZ,aAAa,EACb,MAAM,GACP,EAAE;IACD,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,uFAAuF;IACvF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yFAAyF;IACzF,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,yGAAyG;IACzG,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,qGAAqG;IACrG,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,GAAG,OAAO,CAAC,YAAY,CAAC,CAuCxB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,8 +14,8 @@ export type { ApiKeyOptions, ApiKeyPayload, VerifyResult } from "./auth";
|
|
|
14
14
|
export { ApiKeyManager } from "./auth";
|
|
15
15
|
export type { Channel } from "./channels";
|
|
16
16
|
export type { ChatBotConfig, ChatButtonConfig, ChatConfig, ChatMessage, ChatMode, StreamCallbacks, } from "./client";
|
|
17
|
-
export type { AnswerFn, AnswerFnInput, AnswerFnResult, AnswerOptions, AnswerUsage, } from "./core/answer";
|
|
18
|
-
export { answerOnce, answerStream } from "./core/answer";
|
|
17
|
+
export type { AnswerFn, AnswerFnInput, AnswerFnResult, AnswerOptions, AnswerUsage, TransformReply, TransformReplyInput, } from "./core/answer";
|
|
18
|
+
export { answerOnce, answerStream, applyTransformReply } from "./core/answer";
|
|
19
19
|
export type { BucketsFor, BucketsForContext } from "./core/buckets";
|
|
20
20
|
export { defaultBuckets, resolveBuckets } from "./core/buckets";
|
|
21
21
|
export { detectLeakage, guardOutput, scrubOutput } from "./core/guardrails";
|
|
@@ -25,7 +25,7 @@ export type { Logger, LogLevel } from "./core/logger";
|
|
|
25
25
|
export { createConsoleLogger } from "./core/logger";
|
|
26
26
|
export type { NormalizedChatBody } from "./core/messages";
|
|
27
27
|
export { normalizeChatBody, normalizeMessages } from "./core/messages";
|
|
28
|
-
export type { PipelineMessage, PipelineMode, PreparedChat } from "./core/pipeline";
|
|
28
|
+
export type { PipelineMessage, PipelineMode, PreparedChat, RerankContext, RerankContextArgs, RewriteQuery, RewriteQueryArgs, } from "./core/pipeline";
|
|
29
29
|
export { prepareChat } from "./core/pipeline";
|
|
30
30
|
export { PromptLoader } from "./core/prompts";
|
|
31
31
|
export type { VectorStoreOptions } from "./core/retrieval";
|
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;AAIvC,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,WAAW,EACX,QAAQ,EACR,eAAe,GAChB,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,QAAQ,EACR,aAAa,EACb,cAAc,EACd,aAAa,EACb,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -36,6 +36,7 @@ __export(index_exports, {
|
|
|
36
36
|
VectorStore: () => VectorStore,
|
|
37
37
|
answerOnce: () => answerOnce,
|
|
38
38
|
answerStream: () => answerStream,
|
|
39
|
+
applyTransformReply: () => applyTransformReply,
|
|
39
40
|
chatBodyLimit: () => chatBodyLimit,
|
|
40
41
|
completeOnce: () => completeOnce,
|
|
41
42
|
completeStream: () => completeStream,
|
|
@@ -282,6 +283,18 @@ async function answerOnce({
|
|
|
282
283
|
}
|
|
283
284
|
return completeOnce({ client, system, messages, temperature, model });
|
|
284
285
|
}
|
|
286
|
+
async function applyTransformReply(transformReply, input, logger) {
|
|
287
|
+
if (!transformReply) return input.text;
|
|
288
|
+
try {
|
|
289
|
+
return await transformReply(input);
|
|
290
|
+
} catch (error) {
|
|
291
|
+
logger?.error(
|
|
292
|
+
`transformReply threw for channel "${input.channel}"; sending the original reply`,
|
|
293
|
+
error
|
|
294
|
+
);
|
|
295
|
+
return input.text;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
285
298
|
async function* answerStream({
|
|
286
299
|
answerFn,
|
|
287
300
|
client,
|
|
@@ -445,14 +458,35 @@ async function prepareChat({
|
|
|
445
458
|
messages,
|
|
446
459
|
personaLayer,
|
|
447
460
|
channelHint,
|
|
448
|
-
buckets
|
|
461
|
+
buckets,
|
|
462
|
+
sender,
|
|
463
|
+
rewriteQuery,
|
|
464
|
+
rerankContext,
|
|
465
|
+
logger
|
|
449
466
|
}) {
|
|
450
467
|
const lastUserMsg = lastUserMessage(messages);
|
|
451
468
|
if (!lastUserMsg) {
|
|
452
469
|
throw new Error("no user message found in conversation");
|
|
453
470
|
}
|
|
454
471
|
const { topK, label } = MODE_SETTINGS[mode];
|
|
455
|
-
|
|
472
|
+
let query = lastUserMsg.content;
|
|
473
|
+
if (rewriteQuery) {
|
|
474
|
+
try {
|
|
475
|
+
const rewritten = await rewriteQuery({ query, mode, sender });
|
|
476
|
+
if (typeof rewritten === "string" && rewritten.trim()) query = rewritten;
|
|
477
|
+
} catch (error) {
|
|
478
|
+
logger?.error("rewriteQuery threw; falling back to the original query", error);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
let ctx = await store.query(query, topK, buckets ?? defaultBuckets(mode));
|
|
482
|
+
if (rerankContext) {
|
|
483
|
+
try {
|
|
484
|
+
const reranked = await rerankContext({ query, chunks: ctx });
|
|
485
|
+
if (Array.isArray(reranked) && reranked.every((c) => typeof c === "string")) ctx = reranked;
|
|
486
|
+
} catch (error) {
|
|
487
|
+
logger?.error("rerankContext threw; falling back to the original chunks", error);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
456
490
|
const persona = personaLayer?.trim() || (mode === "private" ? prompts.privatePersona : prompts.publicPersona);
|
|
457
491
|
const hint = channelHint?.trim();
|
|
458
492
|
const system = [
|
|
@@ -991,7 +1025,10 @@ async function createMCPServer(config) {
|
|
|
991
1025
|
prompts,
|
|
992
1026
|
mode: "public",
|
|
993
1027
|
messages: conversationMessages,
|
|
994
|
-
buckets
|
|
1028
|
+
buckets,
|
|
1029
|
+
rewriteQuery: config.rewriteQuery,
|
|
1030
|
+
rerankContext: config.rerankContext,
|
|
1031
|
+
logger: log
|
|
995
1032
|
});
|
|
996
1033
|
const result = await answerOnce({
|
|
997
1034
|
answerFn: config.answerFn,
|
|
@@ -1002,6 +1039,11 @@ async function createMCPServer(config) {
|
|
|
1002
1039
|
conversationId: convId,
|
|
1003
1040
|
model
|
|
1004
1041
|
});
|
|
1042
|
+
const replyText = await applyTransformReply(
|
|
1043
|
+
config.transformReply,
|
|
1044
|
+
{ channel: "mcp-public", conversationId: convId, text: result.content },
|
|
1045
|
+
log
|
|
1046
|
+
);
|
|
1005
1047
|
const cost = calculateCost(result.usage, config.openai.pricing);
|
|
1006
1048
|
const duration = Date.now() - startTime;
|
|
1007
1049
|
await logger.logChatInteraction(
|
|
@@ -1009,7 +1051,7 @@ async function createMCPServer(config) {
|
|
|
1009
1051
|
convId,
|
|
1010
1052
|
conversationMessages,
|
|
1011
1053
|
ctx,
|
|
1012
|
-
|
|
1054
|
+
replyText ?? "",
|
|
1013
1055
|
duration,
|
|
1014
1056
|
cost
|
|
1015
1057
|
).catch((err) => log.error("Logging error:", err));
|
|
@@ -1017,7 +1059,7 @@ async function createMCPServer(config) {
|
|
|
1017
1059
|
content: [
|
|
1018
1060
|
{
|
|
1019
1061
|
type: "text",
|
|
1020
|
-
text:
|
|
1062
|
+
text: replyText ?? ""
|
|
1021
1063
|
}
|
|
1022
1064
|
],
|
|
1023
1065
|
_meta: {
|
|
@@ -1072,7 +1114,10 @@ async function createMCPServer(config) {
|
|
|
1072
1114
|
prompts,
|
|
1073
1115
|
mode: "private",
|
|
1074
1116
|
messages: conversationMessages,
|
|
1075
|
-
buckets
|
|
1117
|
+
buckets,
|
|
1118
|
+
rewriteQuery: config.rewriteQuery,
|
|
1119
|
+
rerankContext: config.rerankContext,
|
|
1120
|
+
logger: log
|
|
1076
1121
|
});
|
|
1077
1122
|
const result = await answerOnce({
|
|
1078
1123
|
answerFn: config.answerFn,
|
|
@@ -1083,6 +1128,11 @@ async function createMCPServer(config) {
|
|
|
1083
1128
|
conversationId: convId,
|
|
1084
1129
|
model
|
|
1085
1130
|
});
|
|
1131
|
+
const replyText = await applyTransformReply(
|
|
1132
|
+
config.transformReply,
|
|
1133
|
+
{ channel: "mcp-private", conversationId: convId, text: result.content },
|
|
1134
|
+
log
|
|
1135
|
+
);
|
|
1086
1136
|
const cost = calculateCost(result.usage, config.openai.pricing);
|
|
1087
1137
|
const duration = Date.now() - startTime;
|
|
1088
1138
|
await logger.logChatInteraction(
|
|
@@ -1090,7 +1140,7 @@ async function createMCPServer(config) {
|
|
|
1090
1140
|
convId,
|
|
1091
1141
|
conversationMessages,
|
|
1092
1142
|
ctx,
|
|
1093
|
-
|
|
1143
|
+
replyText ?? "",
|
|
1094
1144
|
duration,
|
|
1095
1145
|
cost
|
|
1096
1146
|
).catch((err) => log.error("Logging error:", err));
|
|
@@ -1098,7 +1148,7 @@ async function createMCPServer(config) {
|
|
|
1098
1148
|
content: [
|
|
1099
1149
|
{
|
|
1100
1150
|
type: "text",
|
|
1101
|
-
text:
|
|
1151
|
+
text: replyText ?? ""
|
|
1102
1152
|
}
|
|
1103
1153
|
],
|
|
1104
1154
|
_meta: {
|
|
@@ -1542,7 +1592,16 @@ function demoRoutes(deps) {
|
|
|
1542
1592
|
return c.json({ error: "no user message found in conversation" }, 400);
|
|
1543
1593
|
}
|
|
1544
1594
|
const buckets = await resolveBuckets({ mode: "public", bucketsFor: config.bucketsFor });
|
|
1545
|
-
const { system } = await prepareChat({
|
|
1595
|
+
const { system } = await prepareChat({
|
|
1596
|
+
store,
|
|
1597
|
+
prompts,
|
|
1598
|
+
mode: "public",
|
|
1599
|
+
messages,
|
|
1600
|
+
buckets,
|
|
1601
|
+
rewriteQuery: config.rewriteQuery,
|
|
1602
|
+
rerankContext: config.rerankContext,
|
|
1603
|
+
logger
|
|
1604
|
+
});
|
|
1546
1605
|
const model = config.openai.model || DEFAULT_MODEL;
|
|
1547
1606
|
const url = new URL(c.req.url);
|
|
1548
1607
|
const wantsStream3 = url.searchParams.get("stream") === "1";
|
|
@@ -1571,7 +1630,12 @@ function demoRoutes(deps) {
|
|
|
1571
1630
|
mode: "public",
|
|
1572
1631
|
model
|
|
1573
1632
|
});
|
|
1574
|
-
|
|
1633
|
+
const reply = await applyTransformReply(
|
|
1634
|
+
config.transformReply,
|
|
1635
|
+
{ channel: "widget-demo", text: out.content },
|
|
1636
|
+
logger
|
|
1637
|
+
);
|
|
1638
|
+
return c.json({ reply: reply ?? "" });
|
|
1575
1639
|
} catch (error) {
|
|
1576
1640
|
const err = error;
|
|
1577
1641
|
logger.error("Demo chat error:", err);
|
|
@@ -1614,7 +1678,7 @@ function oversizedBodyError(message) {
|
|
|
1614
1678
|
return { error: { message, type: "invalid_request_error" } };
|
|
1615
1679
|
}
|
|
1616
1680
|
function openaiRoutes(deps) {
|
|
1617
|
-
const { client, store, config, prompts, apiKeyManager } = deps;
|
|
1681
|
+
const { client, store, config, prompts, apiKeyManager, logger } = deps;
|
|
1618
1682
|
const app = new import_hono2.Hono();
|
|
1619
1683
|
const { limitPublic, limitPrivate } = createRateLimiter2(config);
|
|
1620
1684
|
const requirePrivateJWT = createJWTMiddleware(config);
|
|
@@ -1656,13 +1720,23 @@ function openaiRoutes(deps) {
|
|
|
1656
1720
|
sender: jwtSubject(c),
|
|
1657
1721
|
bucketsFor: config.bucketsFor
|
|
1658
1722
|
});
|
|
1723
|
+
const sender = jwtSubject(c) ?? apiKeySubject(c);
|
|
1659
1724
|
let system;
|
|
1660
1725
|
try {
|
|
1661
|
-
({ system } = await prepareChat({
|
|
1726
|
+
({ system } = await prepareChat({
|
|
1727
|
+
store,
|
|
1728
|
+
prompts,
|
|
1729
|
+
mode,
|
|
1730
|
+
messages,
|
|
1731
|
+
buckets,
|
|
1732
|
+
sender,
|
|
1733
|
+
rewriteQuery: config.rewriteQuery,
|
|
1734
|
+
rerankContext: config.rerankContext,
|
|
1735
|
+
logger
|
|
1736
|
+
}));
|
|
1662
1737
|
} catch {
|
|
1663
1738
|
return errorJson(c, 400, "Conversation must contain at least one user message");
|
|
1664
1739
|
}
|
|
1665
|
-
const sender = jwtSubject(c) ?? apiKeySubject(c);
|
|
1666
1740
|
const conversationId = clientConversationId(c, body) ?? crypto.randomUUID();
|
|
1667
1741
|
c.header("x-conversation-id", conversationId);
|
|
1668
1742
|
const id = `chatcmpl-${crypto.randomUUID()}`;
|
|
@@ -1709,13 +1783,18 @@ function openaiRoutes(deps) {
|
|
|
1709
1783
|
temperature,
|
|
1710
1784
|
model: serverModel
|
|
1711
1785
|
});
|
|
1786
|
+
const reply = await applyTransformReply(
|
|
1787
|
+
config.transformReply,
|
|
1788
|
+
{ channel: `openai-compat-${mode}`, sender, conversationId, text: out.content },
|
|
1789
|
+
logger
|
|
1790
|
+
);
|
|
1712
1791
|
return c.json({
|
|
1713
1792
|
id,
|
|
1714
1793
|
object: "chat.completion",
|
|
1715
1794
|
created,
|
|
1716
1795
|
model: serverModel,
|
|
1717
1796
|
choices: [
|
|
1718
|
-
{ index: 0, message: { role: "assistant", content:
|
|
1797
|
+
{ index: 0, message: { role: "assistant", content: reply ?? "" }, finish_reason: "stop" }
|
|
1719
1798
|
],
|
|
1720
1799
|
usage: out.usage
|
|
1721
1800
|
});
|
|
@@ -1745,7 +1824,7 @@ function wantsStream(c) {
|
|
|
1745
1824
|
return acc.includes("text/event-stream");
|
|
1746
1825
|
}
|
|
1747
1826
|
function privateRoutes(deps) {
|
|
1748
|
-
const { client, store, config, prompts } = deps;
|
|
1827
|
+
const { client, store, config, prompts, logger } = deps;
|
|
1749
1828
|
const app = new import_hono3.Hono();
|
|
1750
1829
|
const requirePrivateJWT = createJWTMiddleware(config);
|
|
1751
1830
|
const { limitPrivate } = createRateLimiter2(config);
|
|
@@ -1767,7 +1846,17 @@ function privateRoutes(deps) {
|
|
|
1767
1846
|
});
|
|
1768
1847
|
let system;
|
|
1769
1848
|
try {
|
|
1770
|
-
({ system } = await prepareChat({
|
|
1849
|
+
({ system } = await prepareChat({
|
|
1850
|
+
store,
|
|
1851
|
+
prompts,
|
|
1852
|
+
mode: "private",
|
|
1853
|
+
messages,
|
|
1854
|
+
buckets,
|
|
1855
|
+
sender,
|
|
1856
|
+
rewriteQuery: config.rewriteQuery,
|
|
1857
|
+
rerankContext: config.rerankContext,
|
|
1858
|
+
logger
|
|
1859
|
+
}));
|
|
1771
1860
|
} catch {
|
|
1772
1861
|
return c.json({ error: "no user message found in conversation" }, 400);
|
|
1773
1862
|
}
|
|
@@ -1800,7 +1889,12 @@ function privateRoutes(deps) {
|
|
|
1800
1889
|
sender,
|
|
1801
1890
|
model
|
|
1802
1891
|
});
|
|
1803
|
-
|
|
1892
|
+
const reply = await applyTransformReply(
|
|
1893
|
+
config.transformReply,
|
|
1894
|
+
{ channel: "widget-private", sender, text: out.content },
|
|
1895
|
+
logger
|
|
1896
|
+
);
|
|
1897
|
+
return c.json({ reply: reply ?? "" });
|
|
1804
1898
|
});
|
|
1805
1899
|
return app;
|
|
1806
1900
|
}
|
|
@@ -1838,7 +1932,16 @@ function publicRoutes(deps) {
|
|
|
1838
1932
|
const buckets = await resolveBuckets({ mode: "public", bucketsFor: config.bucketsFor });
|
|
1839
1933
|
let system;
|
|
1840
1934
|
try {
|
|
1841
|
-
({ system } = await prepareChat({
|
|
1935
|
+
({ system } = await prepareChat({
|
|
1936
|
+
store,
|
|
1937
|
+
prompts,
|
|
1938
|
+
mode: "public",
|
|
1939
|
+
messages,
|
|
1940
|
+
buckets,
|
|
1941
|
+
rewriteQuery: config.rewriteQuery,
|
|
1942
|
+
rerankContext: config.rerankContext,
|
|
1943
|
+
logger
|
|
1944
|
+
}));
|
|
1842
1945
|
} catch {
|
|
1843
1946
|
return c.json({ error: "no user message found in conversation" }, 400);
|
|
1844
1947
|
}
|
|
@@ -1862,7 +1965,12 @@ function publicRoutes(deps) {
|
|
|
1862
1965
|
});
|
|
1863
1966
|
}
|
|
1864
1967
|
const out = await answerOnce({ answerFn, client, system, messages, mode: "public", model });
|
|
1865
|
-
|
|
1968
|
+
const reply = await applyTransformReply(
|
|
1969
|
+
config.transformReply,
|
|
1970
|
+
{ channel: "widget-public", text: out.content },
|
|
1971
|
+
logger
|
|
1972
|
+
);
|
|
1973
|
+
return c.json({ reply: reply ?? "" });
|
|
1866
1974
|
});
|
|
1867
1975
|
return app;
|
|
1868
1976
|
}
|
|
@@ -2201,6 +2309,7 @@ function createShortener(config, fetchImpl = fetch) {
|
|
|
2201
2309
|
VectorStore,
|
|
2202
2310
|
answerOnce,
|
|
2203
2311
|
answerStream,
|
|
2312
|
+
applyTransformReply,
|
|
2204
2313
|
chatBodyLimit,
|
|
2205
2314
|
completeOnce,
|
|
2206
2315
|
completeStream,
|