@diegoaltoworks/chatter 0.45.0 → 0.48.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/README.md +19 -5
- package/dist/auth/apikeys.d.ts.map +1 -1
- package/dist/auth/secretStrength.d.ts +8 -0
- package/dist/auth/secretStrength.d.ts.map +1 -0
- package/dist/bin/create-apikey.js +22 -3
- package/dist/bin/wa-pair.js +59 -11
- package/dist/channels/gates.d.ts +9 -0
- package/dist/channels/gates.d.ts.map +1 -1
- package/dist/channels/index.d.ts +1 -0
- package/dist/channels/index.d.ts.map +1 -1
- package/dist/channels/index.js +252 -8
- package/dist/channels/index.mjs +250 -8
- package/dist/channels/pipeline.d.ts +106 -0
- package/dist/channels/pipeline.d.ts.map +1 -0
- package/dist/channels/senders.d.ts +2 -1
- package/dist/channels/senders.d.ts.map +1 -1
- package/dist/channels/whatsapp/channel.d.ts +4 -0
- package/dist/channels/whatsapp/channel.d.ts.map +1 -1
- package/dist/channels/whatsapp/crypto.d.ts +17 -3
- package/dist/channels/whatsapp/crypto.d.ts.map +1 -1
- package/dist/channels/whatsapp/inbound.d.ts +34 -4
- package/dist/channels/whatsapp/inbound.d.ts.map +1 -1
- package/dist/channels/whatsapp/index.d.ts +2 -1
- package/dist/channels/whatsapp/index.d.ts.map +1 -1
- package/dist/channels/whatsapp/index.js +395 -159
- package/dist/channels/whatsapp/index.mjs +394 -160
- package/dist/channels/whatsapp/router.d.ts +107 -0
- package/dist/channels/whatsapp/router.d.ts.map +1 -0
- package/dist/core/answer.d.ts +5 -2
- package/dist/core/answer.d.ts.map +1 -1
- package/dist/core/logger.d.ts +23 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/messages.d.ts +8 -0
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/pipeline.d.ts +2 -0
- package/dist/core/pipeline.d.ts.map +1 -1
- package/dist/core/retrieval.d.ts +4 -0
- package/dist/core/retrieval.d.ts.map +1 -1
- package/dist/core/serve-static.d.ts +38 -0
- package/dist/core/serve-static.d.ts.map +1 -0
- package/dist/flows/engine.d.ts +3 -0
- package/dist/flows/engine.d.ts.map +1 -1
- package/dist/flows/index.d.ts +1 -0
- package/dist/flows/index.d.ts.map +1 -1
- package/dist/flows/index.js +91 -25
- package/dist/flows/index.mjs +91 -26
- package/dist/flows/intent.d.ts +2 -1
- package/dist/flows/intent.d.ts.map +1 -1
- package/dist/flows/loader.d.ts +5 -3
- package/dist/flows/loader.d.ts.map +1 -1
- package/dist/flows/types.d.ts +9 -0
- package/dist/flows/types.d.ts.map +1 -1
- package/dist/history/index.d.ts +17 -0
- package/dist/history/index.d.ts.map +1 -0
- package/dist/history/index.js +100 -0
- package/dist/history/index.mjs +73 -0
- package/dist/history/tursoStore.d.ts +26 -0
- package/dist/history/tursoStore.d.ts.map +1 -0
- package/dist/history/types.d.ts +18 -0
- package/dist/history/types.d.ts.map +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1202 -32462
- package/dist/index.mjs +1118 -32414
- package/dist/mcp-server/cost-tracker.d.ts +11 -6
- package/dist/mcp-server/cost-tracker.d.ts.map +1 -1
- package/dist/mcp-server/logger.d.ts +5 -2
- package/dist/mcp-server/logger.d.ts.map +1 -1
- package/dist/mcp-server/sdk.d.ts +23 -0
- package/dist/mcp-server/sdk.d.ts.map +1 -0
- package/dist/mcp-server/tool-input.d.ts +12 -0
- package/dist/mcp-server/tool-input.d.ts.map +1 -0
- package/dist/mcp-server/types.d.ts +10 -3
- package/dist/mcp-server/types.d.ts.map +1 -1
- package/dist/mcp-server.d.ts +1 -2
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +192 -111
- package/dist/mcp-server.mjs +179 -98
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/bodyLimit.d.ts +11 -0
- package/dist/middleware/bodyLimit.d.ts.map +1 -0
- package/dist/middleware/clientKey.d.ts +15 -0
- package/dist/middleware/clientKey.d.ts.map +1 -0
- package/dist/middleware/cors.d.ts.map +1 -1
- package/dist/middleware/jwt.d.ts +0 -3
- package/dist/middleware/jwt.d.ts.map +1 -1
- package/dist/middleware/originMatch.d.ts +27 -0
- package/dist/middleware/originMatch.d.ts.map +1 -0
- package/dist/middleware/ratelimit.d.ts +0 -6
- package/dist/middleware/ratelimit.d.ts.map +1 -1
- package/dist/middleware/referrer.d.ts +5 -1
- package/dist/middleware/referrer.d.ts.map +1 -1
- package/dist/middleware/securityHeaders.d.ts +20 -0
- package/dist/middleware/securityHeaders.d.ts.map +1 -0
- package/dist/middleware/session.d.ts +2 -1
- package/dist/middleware/session.d.ts.map +1 -1
- package/dist/middleware/windowBucket.d.ts +19 -0
- package/dist/middleware/windowBucket.d.ts.map +1 -0
- package/dist/personas/index.js +20 -1
- package/dist/personas/index.mjs +20 -1
- package/dist/personas/resolver.d.ts +3 -0
- package/dist/personas/resolver.d.ts.map +1 -1
- package/dist/routes/demo.d.ts.map +1 -1
- package/dist/routes/openai.d.ts.map +1 -1
- package/dist/routes/private.d.ts.map +1 -1
- package/dist/routes/public.d.ts.map +1 -1
- package/dist/scheduler/compose.d.ts +2 -1
- package/dist/scheduler/compose.d.ts.map +1 -1
- package/dist/scheduler/index.js +29 -9
- package/dist/scheduler/index.mjs +29 -9
- package/dist/scheduler/scheduler.d.ts +3 -0
- package/dist/scheduler/scheduler.d.ts.map +1 -1
- package/dist/scheduler/tick.d.ts +2 -0
- package/dist/scheduler/tick.d.ts.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +726 -538
- package/dist/server.mjs +708 -527
- package/dist/types.d.ts +87 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +30 -9
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compose N transport-specific message detectors behind ONE gate
|
|
3
|
+
* resolution per inbound WhatsApp message.
|
|
4
|
+
*
|
|
5
|
+
* A host running its own interceptors alongside the normal chat reply —
|
|
6
|
+
* a voice-note trigger, a fixed-content reaction, an LLM-extraction reply
|
|
7
|
+
* that replaces the answer — has historically had to re-derive the same
|
|
8
|
+
* boilerplate per interceptor: resolving own-identity jids off the socket,
|
|
9
|
+
* the cross-session loop guard, and the allowlist wiring `decideChannelAction`
|
|
10
|
+
* already owns. Copy-pasted across interceptors, that boilerplate drifts, and
|
|
11
|
+
* nothing stops a handler meant to run *alongside* the real reply
|
|
12
|
+
* (`mode: "parallel"`) from being wired with the *replaces the reply*
|
|
13
|
+
* convention (`mode: "replace"`) instead — silently eating the real answer.
|
|
14
|
+
*
|
|
15
|
+
* `createWhatsAppMessageRouter` resolves identity/gating once via
|
|
16
|
+
* `resolveWaMessage` (the same helper `createWhatsAppInboundHandler` uses),
|
|
17
|
+
* builds one {@link WaDetectorContext} for every detector, then:
|
|
18
|
+
*
|
|
19
|
+
* - fires every matching `"parallel"` detector without awaiting or gating
|
|
20
|
+
* the reply path — a rejection is caught and logged, never surfaces as an
|
|
21
|
+
* unhandled rejection, and never blocks another detector or the fallback.
|
|
22
|
+
* - walks `"replace"` detectors in registration order and stops at the
|
|
23
|
+
* first whose `test` matches, awaiting its `handle` and skipping the
|
|
24
|
+
* fallback entirely; no match runs `fallback` instead.
|
|
25
|
+
*
|
|
26
|
+
* The two modes are distinct at the type level (see {@link MessageDetector}):
|
|
27
|
+
* both `handle` signatures return `Promise<void>`, so there is no
|
|
28
|
+
* boolean-return convention to confuse between them — reaching `handle` at
|
|
29
|
+
* all already means "this detector claims the message" for a `"replace"`
|
|
30
|
+
* detector, or "fire independently" for a `"parallel"` one.
|
|
31
|
+
*
|
|
32
|
+
* `fallback` is deliberately typed the same as `onMessage`/`createWhatsAppInboundHandler`'s
|
|
33
|
+
* return, so an existing single-handler host becomes the router's fallback
|
|
34
|
+
* with zero adaptation — see docs/channels.md. Note that plugging it in this
|
|
35
|
+
* way means `resolveWaMessage` runs a second time inside it (once here for
|
|
36
|
+
* every detector, once more inside the fallback it delegates to) — cheap and
|
|
37
|
+
* side-effect-idempotent (it re-derives the same values and re-writes the
|
|
38
|
+
* same registry entry), but real. "Once per message" below is a guarantee
|
|
39
|
+
* for the detectors, not for whatever the fallback does internally.
|
|
40
|
+
*/
|
|
41
|
+
import type { WAMessage, WASocket } from "@whiskeysockets/baileys";
|
|
42
|
+
import { type Logger } from "../../core/logger";
|
|
43
|
+
import { type ChannelAction, type ChannelMessage, type SessionIdentityRegistry } from "../gates";
|
|
44
|
+
import type { WhatsAppMessageEvent } from "./channel";
|
|
45
|
+
/** Everything a detector needs, already resolved — never a raw Baileys shape to re-derive. */
|
|
46
|
+
export interface WaDetectorContext {
|
|
47
|
+
event: WhatsAppMessageEvent;
|
|
48
|
+
sock: WASocket;
|
|
49
|
+
message: WAMessage;
|
|
50
|
+
msg: ChannelMessage;
|
|
51
|
+
/** This session's own identities (phone + LID, normalized). */
|
|
52
|
+
ownIds: string[];
|
|
53
|
+
senderId: string;
|
|
54
|
+
/** The already-extracted, own-mention-stripped text — see `stripOwnMentions`. */
|
|
55
|
+
text: string;
|
|
56
|
+
/**
|
|
57
|
+
* What `decideChannelAction` would do with this message given THIS
|
|
58
|
+
* router's own `allowedChats`/`mutedChats`/`muteRegex`/`unmuteRegex` —
|
|
59
|
+
* informational; detectors decide independently via their own `test`.
|
|
60
|
+
* If `fallback` is `createWhatsAppInboundHandler`, note it keeps its own
|
|
61
|
+
* private mute set — this `action` will not reflect chats muted there
|
|
62
|
+
* unless the same mute inputs are also configured on the router.
|
|
63
|
+
*/
|
|
64
|
+
action: ChannelAction;
|
|
65
|
+
}
|
|
66
|
+
interface DetectorBase {
|
|
67
|
+
/** Used only in warning logs when a detector throws. */
|
|
68
|
+
name: string;
|
|
69
|
+
test: (ctx: WaDetectorContext) => boolean | Promise<boolean>;
|
|
70
|
+
}
|
|
71
|
+
/** Fires independently of every other detector and of the fallback — never stops the reply path, never treated as "handled". */
|
|
72
|
+
export interface ParallelDetector extends DetectorBase {
|
|
73
|
+
mode: "parallel";
|
|
74
|
+
handle: (ctx: WaDetectorContext) => Promise<void>;
|
|
75
|
+
}
|
|
76
|
+
/** The first matching `"replace"` detector (in registration order) fully owns the message — its `handle` runs and the fallback is skipped. */
|
|
77
|
+
export interface ReplaceDetector extends DetectorBase {
|
|
78
|
+
mode: "replace";
|
|
79
|
+
handle: (ctx: WaDetectorContext) => Promise<void>;
|
|
80
|
+
}
|
|
81
|
+
export type MessageDetector = ParallelDetector | ReplaceDetector;
|
|
82
|
+
export interface WhatsAppMessageRouterConfig {
|
|
83
|
+
/** Shared across every session and every consumer resolving identity from it — see `resolveWaMessage`. */
|
|
84
|
+
registry: SessionIdentityRegistry;
|
|
85
|
+
/** Same meaning as `WhatsAppInboundConfig.allowedChats`: group chats eligible for routing. Empty (default) = every group; has no effect on DMs. Enforced for every detector and the fallback, independently of message text (a caption-less photo/voice note in a non-allowlisted group is dropped too). */
|
|
86
|
+
allowedChats?: string[];
|
|
87
|
+
/** Only consulted to compute `WaDetectorContext.action`; the router itself doesn't act on mute state. */
|
|
88
|
+
mutedChats?: Set<string>;
|
|
89
|
+
muteRegex?: RegExp;
|
|
90
|
+
unmuteRegex?: RegExp;
|
|
91
|
+
/** Checked in the given order for `"replace"`, independently for `"parallel"`. */
|
|
92
|
+
detectors: MessageDetector[];
|
|
93
|
+
/**
|
|
94
|
+
* Runs when no `"replace"` detector matches. Typed identically to
|
|
95
|
+
* `onMessage`/`createWhatsAppInboundHandler`'s return, so an existing
|
|
96
|
+
* single-handler host plugs in unchanged.
|
|
97
|
+
*/
|
|
98
|
+
fallback: (event: WhatsAppMessageEvent) => Promise<void>;
|
|
99
|
+
/** A throwing/rejecting callback here is itself caught and logged at `warn` — it can never produce an unhandled rejection. */
|
|
100
|
+
onDetectorError?: (detectorName: string, error: unknown) => void;
|
|
101
|
+
/** Logger for detector failures. Default: a console logger writing to stderr. */
|
|
102
|
+
logger?: Logger;
|
|
103
|
+
}
|
|
104
|
+
/** Builds the `onMessage` handler for `createWhatsAppChannel` that fans a raw message out to N detectors — see the module docstring. */
|
|
105
|
+
export declare function createWhatsAppMessageRouter(config: WhatsAppMessageRouterConfig): (event: WhatsAppMessageEvent) => Promise<void>;
|
|
106
|
+
export {};
|
|
107
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/channels/whatsapp/router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,cAAc,EAEnB,KAAK,uBAAuB,EAC7B,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAGtD,8FAA8F;AAC9F,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,oBAAoB,CAAC;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,SAAS,CAAC;IACnB,GAAG,EAAE,cAAc,CAAC;IACpB,+DAA+D;IAC/D,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,UAAU,YAAY;IACpB,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9D;AAED,gIAAgI;AAChI,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACpD,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD;AAED,8IAA8I;AAC9I,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD;AAED,MAAM,MAAM,eAAe,GAAG,gBAAgB,GAAG,eAAe,CAAC;AAEjE,MAAM,WAAW,2BAA2B;IAC1C,0GAA0G;IAC1G,QAAQ,EAAE,uBAAuB,CAAC;IAClC,4SAA4S;IAC5S,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,yGAAyG;IACzG,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,8HAA8H;IAC9H,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACjE,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAgDD,wIAAwI;AACxI,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,2BAA2B,GAClC,CAAC,KAAK,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CA4EhD"}
|
package/dist/core/answer.d.ts
CHANGED
|
@@ -30,6 +30,8 @@ export interface AnswerFnInput {
|
|
|
30
30
|
mode: PipelineMode;
|
|
31
31
|
/** Channel-specific sender identity, when the surface knows one */
|
|
32
32
|
sender?: string;
|
|
33
|
+
/** Stable conversation/thread identifier, when the surface has or generates one */
|
|
34
|
+
conversationId?: string;
|
|
33
35
|
}
|
|
34
36
|
/**
|
|
35
37
|
* What a brain returns: the answer text, optionally with token usage for
|
|
@@ -53,13 +55,14 @@ export interface AnswerOptions {
|
|
|
53
55
|
messages: PipelineMessage[];
|
|
54
56
|
mode: PipelineMode;
|
|
55
57
|
sender?: string;
|
|
58
|
+
conversationId?: string;
|
|
56
59
|
temperature?: number;
|
|
57
60
|
model?: string;
|
|
58
61
|
}
|
|
59
62
|
/**
|
|
60
63
|
* Produce one complete answer, from `answerFn` when configured.
|
|
61
64
|
*/
|
|
62
|
-
export declare function answerOnce({ answerFn, client, system, messages, mode, sender, temperature, model, }: AnswerOptions): Promise<{
|
|
65
|
+
export declare function answerOnce({ answerFn, client, system, messages, mode, sender, conversationId, temperature, model, }: AnswerOptions): Promise<{
|
|
63
66
|
content: string;
|
|
64
67
|
usage: AnswerUsage;
|
|
65
68
|
}>;
|
|
@@ -72,5 +75,5 @@ export declare function answerOnce({ answerFn, client, system, messages, mode, s
|
|
|
72
75
|
* built-in stream only scrubs each delta, since leakage detection needs text
|
|
73
76
|
* no streamed chunk has yet.
|
|
74
77
|
*/
|
|
75
|
-
export declare function answerStream({ answerFn, client, system, messages, mode, sender, temperature, model, }: AnswerOptions): AsyncGenerator<string>;
|
|
78
|
+
export declare function answerStream({ answerFn, client, system, messages, mode, sender, conversationId, temperature, model, }: AnswerOptions): AsyncGenerator<string>;
|
|
76
79
|
//# sourceMappingURL=answer.d.ts.map
|
|
@@ -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;
|
|
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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Leveled logging seam. The default implementation never writes to stdout —
|
|
3
|
+
* only stderr — so a host running the stdio MCP transport (which reserves
|
|
4
|
+
* stdout for the JSON-RPC stream) gets a clean channel by default, and so do
|
|
5
|
+
* hosts that simply want their own program output on stdout to stay
|
|
6
|
+
* unpolluted by library logging.
|
|
7
|
+
*/
|
|
8
|
+
export type LogLevel = "debug" | "info" | "warn" | "error";
|
|
9
|
+
export interface Logger {
|
|
10
|
+
debug(...args: unknown[]): void;
|
|
11
|
+
info(...args: unknown[]): void;
|
|
12
|
+
warn(...args: unknown[]): void;
|
|
13
|
+
error(...args: unknown[]): void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Console-backed logger. Every level writes via `console.error` (stderr),
|
|
17
|
+
* gated by `level` (default `"info"`, so `debug` is silent unless a caller
|
|
18
|
+
* opts in) — see the module docstring for why stdout is never touched.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createConsoleLogger(level?: LogLevel): Logger;
|
|
21
|
+
/** Resolves a caller-supplied logger, falling back to the default console logger. */
|
|
22
|
+
export declare function resolveLogger(logger?: Logger, level?: LogLevel): Logger;
|
|
23
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChC,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC/B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CACjC;AAID;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,GAAE,QAAiB,GAAG,MAAM,CAcpE;AAED,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,QAAQ,GAAG,MAAM,CAEvE"}
|
package/dist/core/messages.d.ts
CHANGED
|
@@ -12,6 +12,14 @@
|
|
|
12
12
|
* parts, tool calls, objects, numbers) carries no usable text and is skipped.
|
|
13
13
|
*/
|
|
14
14
|
import type { PipelineMessage } from "./pipeline";
|
|
15
|
+
/**
|
|
16
|
+
* Find the most recent user turn in a conversation. Every chat surface needs
|
|
17
|
+
* this (retrieval query, RAG logging, ...); a shared helper keeps the
|
|
18
|
+
* "search from the end" behaviour from drifting between copies.
|
|
19
|
+
*/
|
|
20
|
+
export declare function lastUserMessage<T extends {
|
|
21
|
+
role: string;
|
|
22
|
+
}>(messages: T[]): T | undefined;
|
|
15
23
|
/**
|
|
16
24
|
* Normalize a raw `messages` array to the pipeline format.
|
|
17
25
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/core/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAWlD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,eAAe,EAAE,GAAG,IAAI,CA8BxE;AAED,yDAAyD;AACzD,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,eAAe,EAAE,CAAA;CAAE,GACzC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,kBAAkB,CA2BnE"}
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/core/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAWlD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,SAAS,CAExF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,eAAe,EAAE,GAAG,IAAI,CA8BxE;AAED,yDAAyD;AACzD,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,eAAe,EAAE,CAAA;CAAE,GACzC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,kBAAkB,CA2BnE"}
|
package/dist/core/pipeline.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ export interface PreparedChat {
|
|
|
20
20
|
system: string;
|
|
21
21
|
/** Conversation messages, unchanged */
|
|
22
22
|
messages: PipelineMessage[];
|
|
23
|
+
/** Raw retrieved chunks, before being folded into `system` — for callers that log or display RAG context alongside the answer */
|
|
24
|
+
context: string[];
|
|
23
25
|
}
|
|
24
26
|
/**
|
|
25
27
|
* Run retrieval for the latest user message and assemble the system prompt.
|
|
@@ -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;AAIH,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;AAOD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,WAAW,CAAC,EAChC,KAAK,EACL,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,OAAO,GACR,EAAE;IACD,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,GAAG,OAAO,CAAC,YAAY,CAAC,CAmBxB"}
|
package/dist/core/retrieval.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Client as LibsqlClient } from "@libsql/client";
|
|
2
2
|
import type OpenAI from "openai";
|
|
3
|
+
import { type Logger } from "./logger";
|
|
3
4
|
/**
|
|
4
5
|
* How a {@link VectorStore} obtains its database connection: either credentials
|
|
5
6
|
* to open its own, or an existing libsql client to reuse.
|
|
@@ -11,6 +12,8 @@ import type OpenAI from "openai";
|
|
|
11
12
|
export type VectorStoreOptions = {
|
|
12
13
|
/** Directory of markdown knowledge files. Default: `./config/knowledge` */
|
|
13
14
|
knowledgeDir?: string;
|
|
15
|
+
/** Logger for build progress. Default: a console logger writing to stderr. */
|
|
16
|
+
logger?: Logger;
|
|
14
17
|
} & ({
|
|
15
18
|
/** Turso database URL */
|
|
16
19
|
databaseUrl: string;
|
|
@@ -32,6 +35,7 @@ export declare class VectorStore {
|
|
|
32
35
|
*/
|
|
33
36
|
readonly db: LibsqlClient;
|
|
34
37
|
private knowledgeDir;
|
|
38
|
+
private logger;
|
|
35
39
|
constructor(client: OpenAI, options: VectorStoreOptions);
|
|
36
40
|
build(): Promise<void>;
|
|
37
41
|
private cleanupStaleChunks;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retrieval.d.ts","sourceRoot":"","sources":["../../src/core/retrieval.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"retrieval.d.ts","sourceRoot":"","sources":["../../src/core/retrieval.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAEjC,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAyB5D;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,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;IAWpB,OAAO,CAAC,MAAM;IAVhB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;IAC1B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAAS;IAEvB,YACU,MAAM,EAAE,MAAM,EACtB,OAAO,EAAE,kBAAkB,EAU5B;IAGK,KAAK,kBA0FV;YAGa,kBAAkB;IA8BhC,OAAO,CAAC,MAAM,CAAC,MAAM;IAYrB;;;;;;;;;;OAUG;IACG,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,SAAI,EAAE,OAAO,GAAE,MAAM,EAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAwB7E;CACF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place the server touches a runtime-specific static-file adapter.
|
|
3
|
+
*
|
|
4
|
+
* `hono/bun`'s `serveStatic` reads the `Bun` global at import time, so a static
|
|
5
|
+
* `import` of it makes the whole package Bun-only: `import("./dist/server.mjs")`
|
|
6
|
+
* under Node throws "Bun is not defined" before a single route is mounted, even
|
|
7
|
+
* in headless mode where no file is ever served. This module keeps both
|
|
8
|
+
* adapters behind lazy, literal dynamic imports and picks one from the runtime
|
|
9
|
+
* actually executing, so the import graph stays runtime-neutral and only a
|
|
10
|
+
* server that really serves files pays for an adapter.
|
|
11
|
+
*
|
|
12
|
+
* Under Node the adapter is `@hono/node-server/serve-static`, an OPTIONAL peer
|
|
13
|
+
* dependency: a Node consumer running headless never needs it, so a missing
|
|
14
|
+
* package must not be an import-time failure.
|
|
15
|
+
*/
|
|
16
|
+
import type { MiddlewareHandler } from "hono";
|
|
17
|
+
/** The subset of both adapters' options this package uses. */
|
|
18
|
+
export interface ServeStaticOptions {
|
|
19
|
+
/** File to serve, relative to `root` (which defaults to the process cwd). */
|
|
20
|
+
path: string;
|
|
21
|
+
root?: string;
|
|
22
|
+
}
|
|
23
|
+
export type ServeStaticFn = (options: ServeStaticOptions) => MiddlewareHandler;
|
|
24
|
+
/** Runtimes we have a static-file adapter for. */
|
|
25
|
+
export type StaticRuntime = "bun" | "node";
|
|
26
|
+
/** Module specifier loaded for each runtime — exported so tests can assert the mapping without importing. */
|
|
27
|
+
export declare const STATIC_ADAPTERS: Record<StaticRuntime, string>;
|
|
28
|
+
/** Which adapter the current process needs. Bun exposes a `Bun` global; nothing else does. */
|
|
29
|
+
export declare function detectRuntime(): StaticRuntime;
|
|
30
|
+
/** Wraps a failed adapter import in an actionable message. Exported separately so the wording is unit-testable without simulating a missing module. */
|
|
31
|
+
export declare function wrapMissingAdapterError(runtime: StaticRuntime, cause: unknown): Error;
|
|
32
|
+
/**
|
|
33
|
+
* Resolve the static-file middleware factory for `runtime`, memoised per
|
|
34
|
+
* runtime. A rejected load is evicted so a later call can retry (the package
|
|
35
|
+
* may have been installed in between), mirroring `loadBaileys()`.
|
|
36
|
+
*/
|
|
37
|
+
export declare function loadServeStatic(runtime?: StaticRuntime): Promise<ServeStaticFn>;
|
|
38
|
+
//# sourceMappingURL=serve-static.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve-static.d.ts","sourceRoot":"","sources":["../../src/core/serve-static.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAE9C,8DAA8D;AAC9D,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,kBAAkB,KAAK,iBAAiB,CAAC;AAE/E,kDAAkD;AAClD,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AAE3C,6GAA6G;AAC7G,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAGzD,CAAC;AAEF,8FAA8F;AAC9F,wBAAgB,aAAa,IAAI,aAAa,CAE7C;AAED,uJAAuJ;AACvJ,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,CAUrF;AAID;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,aAA+B,GAAG,OAAO,CAAC,aAAa,CAAC,CAkBhG"}
|
package/dist/flows/engine.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* channel-specific presentation (see {@link FlowHandlerResult}).
|
|
6
6
|
*/
|
|
7
7
|
import type OpenAI from "openai";
|
|
8
|
+
import { type Logger } from "../core/logger";
|
|
8
9
|
import type { FlowResult, FlowSessionStore, LoadedFlow } from "./types";
|
|
9
10
|
export interface FlowEngineOptions {
|
|
10
11
|
/** OpenAI client used for intent detection and parameter extraction. */
|
|
@@ -36,6 +37,8 @@ export interface FlowEngineOptions {
|
|
|
36
37
|
sessionTtlMs?: number;
|
|
37
38
|
/** Clock, injectable for deterministic tests. */
|
|
38
39
|
now?: () => number;
|
|
40
|
+
/** Logger for load/intent-detection failures. Default: a console logger writing to stderr. */
|
|
41
|
+
logger?: Logger;
|
|
39
42
|
}
|
|
40
43
|
export interface FlowEngine {
|
|
41
44
|
/** Loads (or reloads) every flow directory under `flowsDir`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/flows/engine.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/flows/engine.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAKlE,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGxE,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,uFAAuF;IACvF,QAAQ,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,YAAY,EAAE,gBAAgB,CAAC;IAC/B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2FAA2F;IAC3F,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iDAAiD;IACjD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,gEAAgE;IAChE,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC5C,WAAW,IAAI,UAAU,EAAE,CAAC;IAC5B,wFAAwF;IACxF,OAAO,CACL,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,+EAA+E;QAC/E,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC1C,GACA,OAAO,CAAC,UAAU,CAAC,CAAC;CACxB;AAMD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,UAAU,CA0KvE"}
|
package/dist/flows/index.d.ts
CHANGED
|
@@ -21,5 +21,6 @@ export type { FlowRegistry } from "./registry";
|
|
|
21
21
|
export { createFlowRegistry } from "./registry";
|
|
22
22
|
export { createTursoFlowSessionStore } from "./session";
|
|
23
23
|
export type { FlowDefinition, FlowExtractionResult, FlowHandler, FlowHandlerContext, FlowHandlerResult, FlowPrefill, FlowResult, FlowSchema, FlowSchemaProperty, FlowSessionState, FlowSessionStore, IntentDetection, LoadedFlow, } from "./types";
|
|
24
|
+
export { CURRENT_FLOW_CONTRACT_VERSION } from "./types";
|
|
24
25
|
export { shouldExitFlow } from "./utils";
|
|
25
26
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/flows/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAC;AACxD,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,UAAU,GACX,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/flows/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAC;AACxD,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,UAAU,GACX,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,6BAA6B,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/flows/index.js
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/flows/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
CURRENT_FLOW_CONTRACT_VERSION: () => CURRENT_FLOW_CONTRACT_VERSION,
|
|
23
24
|
createFlowEngine: () => createFlowEngine,
|
|
24
25
|
createFlowRegistry: () => createFlowRegistry,
|
|
25
26
|
createTursoFlowSessionStore: () => createTursoFlowSessionStore,
|
|
@@ -30,8 +31,24 @@ __export(index_exports, {
|
|
|
30
31
|
});
|
|
31
32
|
module.exports = __toCommonJS(index_exports);
|
|
32
33
|
|
|
34
|
+
// src/core/logger.ts
|
|
35
|
+
var LEVEL_ORDER = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
36
|
+
function createConsoleLogger(level = "info") {
|
|
37
|
+
const threshold = LEVEL_ORDER[level];
|
|
38
|
+
const write = (at) => (...args) => {
|
|
39
|
+
if (LEVEL_ORDER[at] < threshold) return;
|
|
40
|
+
console.error(`[${at}]`, ...args);
|
|
41
|
+
};
|
|
42
|
+
return {
|
|
43
|
+
debug: write("debug"),
|
|
44
|
+
info: write("info"),
|
|
45
|
+
warn: write("warn"),
|
|
46
|
+
error: write("error")
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
33
50
|
// src/flows/intent.ts
|
|
34
|
-
async function detectIntent(client, model, message, flows, conversationContext) {
|
|
51
|
+
async function detectIntent(client, model, message, flows, conversationContext, logger = createConsoleLogger()) {
|
|
35
52
|
const contextStr = conversationContext && conversationContext.length > 0 ? `
|
|
36
53
|
|
|
37
54
|
Recent conversation:
|
|
@@ -74,7 +91,7 @@ Rules:
|
|
|
74
91
|
const confidence = typeof raw.confidence === "number" ? raw.confidence : 0;
|
|
75
92
|
return { intent, confidence, reasoning: raw.reasoning };
|
|
76
93
|
} catch (error) {
|
|
77
|
-
|
|
94
|
+
logger.warn(
|
|
78
95
|
`[flows] intent detection failed: ${error instanceof Error ? error.message : String(error)}`
|
|
79
96
|
);
|
|
80
97
|
return { intent: "chatbot", confidence: 0, reasoning: "exception, defaulting to chatbot" };
|
|
@@ -84,68 +101,108 @@ Rules:
|
|
|
84
101
|
// src/flows/loader.ts
|
|
85
102
|
var import_node_fs = require("node:fs");
|
|
86
103
|
var import_node_path = require("node:path");
|
|
104
|
+
|
|
105
|
+
// src/flows/types.ts
|
|
106
|
+
var CURRENT_FLOW_CONTRACT_VERSION = 1;
|
|
107
|
+
|
|
108
|
+
// src/flows/loader.ts
|
|
87
109
|
var SKIPPED_DIR_NAMES = /* @__PURE__ */ new Set(["lib", "tests", "registry"]);
|
|
88
|
-
|
|
110
|
+
var MODULE_EXTENSIONS = ["ts", "js", "mjs"];
|
|
111
|
+
async function loadFlowsFromDirectory(flowsDir, logger = createConsoleLogger()) {
|
|
89
112
|
const flows = /* @__PURE__ */ new Map();
|
|
90
113
|
if (!(0, import_node_fs.existsSync)(flowsDir)) {
|
|
91
|
-
|
|
114
|
+
logger.warn(`[flows] directory does not exist: ${flowsDir}`);
|
|
92
115
|
return flows;
|
|
93
116
|
}
|
|
94
117
|
const flowDirs = (0, import_node_fs.readdirSync)(flowsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).filter((dirent) => !SKIPPED_DIR_NAMES.has(dirent.name)).map((dirent) => dirent.name);
|
|
95
118
|
for (const flowName of flowDirs) {
|
|
96
119
|
try {
|
|
97
|
-
flows.set(flowName, await loadFlow(flowsDir, flowName));
|
|
120
|
+
flows.set(flowName, await loadFlow(flowsDir, flowName, logger));
|
|
98
121
|
} catch (error) {
|
|
99
|
-
|
|
122
|
+
logger.warn(
|
|
100
123
|
`[flows] failed to load "${flowName}": ${error instanceof Error ? error.message : String(error)}`
|
|
101
124
|
);
|
|
102
125
|
}
|
|
103
126
|
}
|
|
104
127
|
return flows;
|
|
105
128
|
}
|
|
106
|
-
|
|
129
|
+
function validateFlowDefinition(raw, flowName) {
|
|
130
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
131
|
+
throw new Error(`flow.json for "${flowName}" must be a JSON object`);
|
|
132
|
+
}
|
|
133
|
+
const definition = raw;
|
|
134
|
+
if (typeof definition.id !== "string" || definition.id.length === 0) {
|
|
135
|
+
throw new Error(`flow.json for "${flowName}": "id" must be a non-empty string`);
|
|
136
|
+
}
|
|
137
|
+
if (!Array.isArray(definition.triggerKeywords) || definition.triggerKeywords.length === 0) {
|
|
138
|
+
throw new Error(`flow.json for "${flowName}": "triggerKeywords" must be a non-empty array`);
|
|
139
|
+
}
|
|
140
|
+
const properties = definition.schema?.properties;
|
|
141
|
+
if (!properties || typeof properties !== "object" || Array.isArray(properties) || Object.keys(properties).length === 0) {
|
|
142
|
+
throw new Error(`flow.json for "${flowName}": "schema.properties" must be a non-empty object`);
|
|
143
|
+
}
|
|
144
|
+
if (definition.contractVersion !== void 0) {
|
|
145
|
+
const version = definition.contractVersion;
|
|
146
|
+
if (!Number.isInteger(version) || version < 1 || version > CURRENT_FLOW_CONTRACT_VERSION) {
|
|
147
|
+
throw new Error(
|
|
148
|
+
`flow.json for "${flowName}": "contractVersion" ${JSON.stringify(version)} is not supported (this loader understands versions 1 through ${CURRENT_FLOW_CONTRACT_VERSION})`
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
async function loadFlow(flowsDir, flowName, logger) {
|
|
107
154
|
const flowPath = (0, import_node_path.resolve)(flowsDir, flowName);
|
|
108
155
|
const definitionPath = (0, import_node_path.join)(flowPath, "flow.json");
|
|
109
156
|
const instructionsPath = (0, import_node_path.join)(flowPath, "instructions.md");
|
|
110
|
-
const handlerPath = (0, import_node_path.join)(flowPath, "handler.ts");
|
|
111
157
|
if (!(0, import_node_fs.existsSync)(definitionPath)) {
|
|
112
158
|
throw new Error(`flow.json not found for ${flowName}`);
|
|
113
159
|
}
|
|
114
160
|
if (!(0, import_node_fs.existsSync)(instructionsPath)) {
|
|
115
161
|
throw new Error(`instructions.md not found for ${flowName}`);
|
|
116
162
|
}
|
|
117
|
-
|
|
118
|
-
|
|
163
|
+
const handlerPath = findModulePath(flowPath, "handler");
|
|
164
|
+
if (!handlerPath) {
|
|
165
|
+
throw new Error(
|
|
166
|
+
`no handler found for ${flowName} (looked for ${MODULE_EXTENSIONS.map((ext) => `handler.${ext}`).join(", ")})`
|
|
167
|
+
);
|
|
119
168
|
}
|
|
120
|
-
const
|
|
169
|
+
const rawDefinition = JSON.parse((0, import_node_fs.readFileSync)(definitionPath, "utf-8"));
|
|
170
|
+
validateFlowDefinition(rawDefinition, flowName);
|
|
171
|
+
const definition = {
|
|
172
|
+
...rawDefinition,
|
|
173
|
+
contractVersion: rawDefinition.contractVersion ?? CURRENT_FLOW_CONTRACT_VERSION
|
|
174
|
+
};
|
|
121
175
|
if (definition.id !== flowName) {
|
|
122
176
|
throw new Error(`Flow id mismatch: ${definition.id} !== ${flowName}`);
|
|
123
177
|
}
|
|
124
|
-
if (!definition.triggerKeywords || definition.triggerKeywords.length === 0) {
|
|
125
|
-
throw new Error(`Flow ${flowName} has no trigger keywords`);
|
|
126
|
-
}
|
|
127
|
-
if (!definition.schema || Object.keys(definition.schema.properties ?? {}).length === 0) {
|
|
128
|
-
throw new Error(`Flow ${flowName} has no schema`);
|
|
129
|
-
}
|
|
130
178
|
const handlerModule = await import(handlerPath);
|
|
131
179
|
const handler = handlerModule.execute;
|
|
132
180
|
if (typeof handler !== "function") {
|
|
133
|
-
throw new Error(`Flow ${flowName}
|
|
181
|
+
throw new Error(`Flow ${flowName} ${(0, import_node_path.basename)(handlerPath)} must export an 'execute' function`);
|
|
134
182
|
}
|
|
135
|
-
const prefillPath = (
|
|
183
|
+
const prefillPath = findModulePath(flowPath, "prefill");
|
|
136
184
|
let prefill;
|
|
137
|
-
if (
|
|
185
|
+
if (prefillPath) {
|
|
138
186
|
const prefillModule = await import(prefillPath);
|
|
139
187
|
if (typeof prefillModule.prefillFromContext === "function") {
|
|
140
188
|
prefill = prefillModule.prefillFromContext;
|
|
141
189
|
} else {
|
|
142
|
-
|
|
143
|
-
`[flows] "${flowName}"
|
|
190
|
+
logger.warn(
|
|
191
|
+
`[flows] "${flowName}" ${(0, import_node_path.basename)(prefillPath)} does not export a prefillFromContext function`
|
|
144
192
|
);
|
|
145
193
|
}
|
|
146
194
|
}
|
|
147
195
|
return { definition, handler, instructionsPath, prefill };
|
|
148
196
|
}
|
|
197
|
+
function findModulePath(flowPath, base) {
|
|
198
|
+
for (const ext of MODULE_EXTENSIONS) {
|
|
199
|
+
const candidate = (0, import_node_path.join)(flowPath, `${base}.${ext}`);
|
|
200
|
+
if ((0, import_node_fs.existsSync)(candidate)) {
|
|
201
|
+
return candidate;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return void 0;
|
|
205
|
+
}
|
|
149
206
|
|
|
150
207
|
// src/flows/params.ts
|
|
151
208
|
var import_node_fs2 = require("node:fs");
|
|
@@ -288,7 +345,8 @@ function createFlowEngine(options) {
|
|
|
288
345
|
cancelMessage = DEFAULT_CANCEL_MESSAGE,
|
|
289
346
|
errorMessage = DEFAULT_ERROR_MESSAGE,
|
|
290
347
|
sessionTtlMs,
|
|
291
|
-
now = Date.now
|
|
348
|
+
now = Date.now,
|
|
349
|
+
logger = createConsoleLogger()
|
|
292
350
|
} = options;
|
|
293
351
|
let registry = createFlowRegistry(/* @__PURE__ */ new Map());
|
|
294
352
|
async function matchFlow(message, conversationContext) {
|
|
@@ -297,7 +355,14 @@ function createFlowEngine(options) {
|
|
|
297
355
|
const allFlows = registry.getAllFlows();
|
|
298
356
|
if (allFlows.length === 0) return void 0;
|
|
299
357
|
const flowMap = new Map(allFlows.map((flow) => [flow.definition.id, flow]));
|
|
300
|
-
const detection = await detectIntent(
|
|
358
|
+
const detection = await detectIntent(
|
|
359
|
+
client,
|
|
360
|
+
model,
|
|
361
|
+
message,
|
|
362
|
+
flowMap,
|
|
363
|
+
conversationContext,
|
|
364
|
+
logger
|
|
365
|
+
);
|
|
301
366
|
if (detection.confidence >= minConfidence) {
|
|
302
367
|
return registry.getFlow(detection.intent);
|
|
303
368
|
}
|
|
@@ -331,7 +396,7 @@ function createFlowEngine(options) {
|
|
|
331
396
|
}
|
|
332
397
|
return {
|
|
333
398
|
async loadFlows() {
|
|
334
|
-
const flows = await loadFlowsFromDirectory(flowsDir);
|
|
399
|
+
const flows = await loadFlowsFromDirectory(flowsDir, logger);
|
|
335
400
|
registry = createFlowRegistry(flows, criticalKeywords);
|
|
336
401
|
},
|
|
337
402
|
getFlow(id) {
|
|
@@ -471,6 +536,7 @@ function createTursoFlowSessionStore(client, tableName = "flow_sessions") {
|
|
|
471
536
|
}
|
|
472
537
|
// Annotate the CommonJS export names for ESM import in node:
|
|
473
538
|
0 && (module.exports = {
|
|
539
|
+
CURRENT_FLOW_CONTRACT_VERSION,
|
|
474
540
|
createFlowEngine,
|
|
475
541
|
createFlowRegistry,
|
|
476
542
|
createTursoFlowSessionStore,
|