@diegoaltoworks/chatter 0.47.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 +3 -4
- 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/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 +1146 -32444
- package/dist/index.mjs +1082 -32410
- 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 +678 -528
- package/dist/server.mjs +678 -528
- package/dist/types.d.ts +87 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +22 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"securityHeaders.d.ts","sourceRoot":"","sources":["../../src/middleware/securityHeaders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAiB9C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,OAKlC,OAAO,QAAQ,IAAI,mBAQrC"}
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* Session key validation middleware
|
|
3
3
|
*/
|
|
4
4
|
import type { Context, Next } from "hono";
|
|
5
|
+
import { type Logger } from "../core/logger";
|
|
5
6
|
/**
|
|
6
7
|
* Middleware to validate session-based temporary API keys
|
|
7
8
|
* Session keys start with "session_" prefix
|
|
8
9
|
*/
|
|
9
|
-
export declare function validateSessionKey(): (c: Context, next: Next) => Promise<(Response & import("hono").TypedResponse<{
|
|
10
|
+
export declare function validateSessionKey(logger?: Logger): (c: Context, next: Next) => Promise<(Response & import("hono").TypedResponse<{
|
|
10
11
|
error: string;
|
|
11
12
|
}, 401, "json">) | undefined>;
|
|
12
13
|
export declare const createSessionMiddleware: typeof validateSessionKey;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/middleware/session.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/middleware/session.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAGlE;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,GAAE,MAA8B,OACtD,OAAO,QAAQ,IAAI;;8BAkCrC;AAGD,eAAO,MAAM,uBAAuB,2BAAqB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixed-window request counter with self-eviction. Every fixed-window
|
|
3
|
+
* limiter in this codebase used to key a plain `Map` by caller-supplied
|
|
4
|
+
* identity (IP, session id) and only ever reset an entry when that same key
|
|
5
|
+
* came back — a key that never returns (e.g. an attacker rotating a fake
|
|
6
|
+
* `X-Forwarded-For` per request) stayed in the map forever, an unbounded
|
|
7
|
+
* memory sink. This sweeps expired entries on write instead, so map size
|
|
8
|
+
* stays bounded by the number of distinct keys active within roughly the
|
|
9
|
+
* last two windows — a sweep only runs once per window and only on a
|
|
10
|
+
* write, so an entry can sit stale for up to one extra window before the
|
|
11
|
+
* next sweep clears it.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createWindowBucketLimiter(windowMs: number, now?: () => number): {
|
|
14
|
+
/** Records one hit for `key` and reports whether it's still within `limit`. */
|
|
15
|
+
hit(key: string, limit: number): boolean;
|
|
16
|
+
/** Current map size — for tests asserting eviction actually happened. */
|
|
17
|
+
size(): number;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=windowBucket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"windowBucket.d.ts","sourceRoot":"","sources":["../../src/middleware/windowBucket.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,MAAiB;IAapF,+EAA+E;IAC/E,GAAG,MAAM,MAAM,SAAS,MAAM,GAAG,OAAO;IAYxC,yEAAyE;IACzE,IAAI,IAAI,MAAM;EAIjB"}
|
package/dist/personas/index.js
CHANGED
|
@@ -56,6 +56,24 @@ function createGreeter({
|
|
|
56
56
|
// src/personas/resolver.ts
|
|
57
57
|
var import_node_fs = require("node:fs");
|
|
58
58
|
var import_node_path = require("node:path");
|
|
59
|
+
|
|
60
|
+
// src/core/logger.ts
|
|
61
|
+
var LEVEL_ORDER = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
62
|
+
function createConsoleLogger(level = "info") {
|
|
63
|
+
const threshold = LEVEL_ORDER[level];
|
|
64
|
+
const write = (at) => (...args) => {
|
|
65
|
+
if (LEVEL_ORDER[at] < threshold) return;
|
|
66
|
+
console.error(`[${at}]`, ...args);
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
debug: write("debug"),
|
|
70
|
+
info: write("info"),
|
|
71
|
+
warn: write("warn"),
|
|
72
|
+
error: write("error")
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// src/personas/resolver.ts
|
|
59
77
|
var DEFAULT_WINDOW_MINUTES = 10;
|
|
60
78
|
var DEFAULT_PROBABILITY = 0.5;
|
|
61
79
|
function interpolate(template, vars) {
|
|
@@ -71,6 +89,7 @@ function createPersonaResolver(options = {}) {
|
|
|
71
89
|
const random = options.random ?? Math.random;
|
|
72
90
|
const now = options.now ?? Date.now;
|
|
73
91
|
const vars = options.vars ?? {};
|
|
92
|
+
const logger = options.logger ?? createConsoleLogger();
|
|
74
93
|
const promptsDir = options.promptsDir ?? (options.registryPath ? (0, import_node_path.dirname)(options.registryPath) : process.cwd());
|
|
75
94
|
let registry = options.registry;
|
|
76
95
|
let registryLoadError;
|
|
@@ -80,7 +99,7 @@ function createPersonaResolver(options = {}) {
|
|
|
80
99
|
function warnOnce(kind, message, error) {
|
|
81
100
|
if (warned.has(kind)) return;
|
|
82
101
|
warned.add(kind);
|
|
83
|
-
|
|
102
|
+
logger.warn(message, error);
|
|
84
103
|
}
|
|
85
104
|
function loadRegistry() {
|
|
86
105
|
if (registry) return registry;
|
package/dist/personas/index.mjs
CHANGED
|
@@ -28,6 +28,24 @@ function createGreeter({
|
|
|
28
28
|
// src/personas/resolver.ts
|
|
29
29
|
import { readFileSync } from "node:fs";
|
|
30
30
|
import { dirname, resolve } from "node:path";
|
|
31
|
+
|
|
32
|
+
// src/core/logger.ts
|
|
33
|
+
var LEVEL_ORDER = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
34
|
+
function createConsoleLogger(level = "info") {
|
|
35
|
+
const threshold = LEVEL_ORDER[level];
|
|
36
|
+
const write = (at) => (...args) => {
|
|
37
|
+
if (LEVEL_ORDER[at] < threshold) return;
|
|
38
|
+
console.error(`[${at}]`, ...args);
|
|
39
|
+
};
|
|
40
|
+
return {
|
|
41
|
+
debug: write("debug"),
|
|
42
|
+
info: write("info"),
|
|
43
|
+
warn: write("warn"),
|
|
44
|
+
error: write("error")
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/personas/resolver.ts
|
|
31
49
|
var DEFAULT_WINDOW_MINUTES = 10;
|
|
32
50
|
var DEFAULT_PROBABILITY = 0.5;
|
|
33
51
|
function interpolate(template, vars) {
|
|
@@ -43,6 +61,7 @@ function createPersonaResolver(options = {}) {
|
|
|
43
61
|
const random = options.random ?? Math.random;
|
|
44
62
|
const now = options.now ?? Date.now;
|
|
45
63
|
const vars = options.vars ?? {};
|
|
64
|
+
const logger = options.logger ?? createConsoleLogger();
|
|
46
65
|
const promptsDir = options.promptsDir ?? (options.registryPath ? dirname(options.registryPath) : process.cwd());
|
|
47
66
|
let registry = options.registry;
|
|
48
67
|
let registryLoadError;
|
|
@@ -52,7 +71,7 @@ function createPersonaResolver(options = {}) {
|
|
|
52
71
|
function warnOnce(kind, message, error) {
|
|
53
72
|
if (warned.has(kind)) return;
|
|
54
73
|
warned.add(kind);
|
|
55
|
-
|
|
74
|
+
logger.warn(message, error);
|
|
56
75
|
}
|
|
57
76
|
function loadRegistry() {
|
|
58
77
|
if (registry) return registry;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* degrades to `null` (the caller's default layer) rather than throwing into
|
|
6
6
|
* a chat request.
|
|
7
7
|
*/
|
|
8
|
+
import { type Logger } from "../core/logger";
|
|
8
9
|
export interface PersonaDefinition {
|
|
9
10
|
name: string;
|
|
10
11
|
/** Path to the persona's prompt file, resolved against `promptsDir`. */
|
|
@@ -42,6 +43,8 @@ export interface PersonaResolverOptions {
|
|
|
42
43
|
now?: () => number;
|
|
43
44
|
/** Template vars (`{{name}}`) interpolated into loaded prompt files. */
|
|
44
45
|
vars?: Record<string, string>;
|
|
46
|
+
/** Logger for registry/prompt load failures. Default: a console logger writing to stderr. */
|
|
47
|
+
logger?: Logger;
|
|
45
48
|
}
|
|
46
49
|
export interface PersonaResolver {
|
|
47
50
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/personas/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/personas/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAElE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,cAAc,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,8EAA8E;IAC9E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,sBAAsB;IACrC,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0HAA0H;IAC1H,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,sDAAsD;IACtD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,6FAA6F;IAC7F,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAChD;;;;OAIG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACtD,8EAA8E;IAC9E,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;IACzD,6CAA6C;IAC7C,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;IAC1D,wEAAwE;IACxE,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAAC;CACnC;AAYD,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,CAgI3F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../../src/routes/demo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../../src/routes/demo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAY5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAuFnD,wBAAgB,UAAU,CAAC,IAAI,EAAE,kBAAkB,8EAoHlD"}
|
|
@@ -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;AAU5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAsDnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,8EA8JpD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"private.d.ts","sourceRoot":"","sources":["../../src/routes/private.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"private.d.ts","sourceRoot":"","sources":["../../src/routes/private.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAS5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,aAAa,CAAC,IAAI,EAAE,kBAAkB,8EAuErD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/routes/public.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/routes/public.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAW5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AASnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,8EAuEpD"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type OpenAI from "openai";
|
|
2
2
|
import type { AnswerFn } from "../core/answer";
|
|
3
|
+
import { type Logger } from "../core/logger";
|
|
3
4
|
import type { PipelineMessage, PipelineMode } from "../core/pipeline";
|
|
4
5
|
import type { ComposeFn, ScheduleEntry } from "./types";
|
|
5
6
|
/**
|
|
@@ -7,7 +8,7 @@ import type { ComposeFn, ScheduleEntry } from "./types";
|
|
|
7
8
|
* missing compose function, a blank result, or a throwing/rejecting compose
|
|
8
9
|
* all fall back to `fallbackMessage` rather than blocking delivery.
|
|
9
10
|
*/
|
|
10
|
-
export declare function composeMessage(entry: ScheduleEntry, compose: ComposeFn | undefined, fallbackMessage: string): Promise<string>;
|
|
11
|
+
export declare function composeMessage(entry: ScheduleEntry, compose: ComposeFn | undefined, fallbackMessage: string, logger?: Logger): Promise<string>;
|
|
11
12
|
export interface AnswerComposeOptions {
|
|
12
13
|
client: OpenAI;
|
|
13
14
|
system: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../src/scheduler/compose.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,SAAS,GAAG,SAAS,EAC9B,eAAe,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../src/scheduler/compose.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,SAAS,GAAG,SAAS,EAC9B,eAAe,EAAE,MAAM,EACvB,MAAM,GAAE,MAA8B,GACrC,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,mFAAmF;IACnF,aAAa,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,eAAe,EAAE,CAAC;IAC3D,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,4IAA4I;AAC5I,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAa5E"}
|
package/dist/scheduler/index.js
CHANGED
|
@@ -146,8 +146,8 @@ async function completeOnce({
|
|
|
146
146
|
|
|
147
147
|
// src/core/answer.ts
|
|
148
148
|
var noUsage = () => ({ prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 });
|
|
149
|
-
async function runAnswerFn(answerFn, { system, messages, mode, sender }) {
|
|
150
|
-
const result = await answerFn({ system, messages, mode, sender });
|
|
149
|
+
async function runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }) {
|
|
150
|
+
const result = await answerFn({ system, messages, mode, sender, conversationId });
|
|
151
151
|
const raw = typeof result === "string" ? result : result?.content;
|
|
152
152
|
const usage = typeof result === "string" ? void 0 : result?.usage;
|
|
153
153
|
return {
|
|
@@ -162,23 +162,40 @@ async function answerOnce({
|
|
|
162
162
|
messages,
|
|
163
163
|
mode,
|
|
164
164
|
sender,
|
|
165
|
+
conversationId,
|
|
165
166
|
temperature,
|
|
166
167
|
model
|
|
167
168
|
}) {
|
|
168
169
|
if (answerFn) {
|
|
169
|
-
return runAnswerFn(answerFn, { system, messages, mode, sender });
|
|
170
|
+
return runAnswerFn(answerFn, { system, messages, mode, sender, conversationId });
|
|
170
171
|
}
|
|
171
172
|
return completeOnce({ client, system, messages, temperature, model });
|
|
172
173
|
}
|
|
173
174
|
|
|
175
|
+
// src/core/logger.ts
|
|
176
|
+
var LEVEL_ORDER = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
177
|
+
function createConsoleLogger(level = "info") {
|
|
178
|
+
const threshold = LEVEL_ORDER[level];
|
|
179
|
+
const write = (at) => (...args) => {
|
|
180
|
+
if (LEVEL_ORDER[at] < threshold) return;
|
|
181
|
+
console.error(`[${at}]`, ...args);
|
|
182
|
+
};
|
|
183
|
+
return {
|
|
184
|
+
debug: write("debug"),
|
|
185
|
+
info: write("info"),
|
|
186
|
+
warn: write("warn"),
|
|
187
|
+
error: write("error")
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
174
191
|
// src/scheduler/compose.ts
|
|
175
|
-
async function composeMessage(entry, compose, fallbackMessage) {
|
|
192
|
+
async function composeMessage(entry, compose, fallbackMessage, logger = createConsoleLogger()) {
|
|
176
193
|
if (!compose) return fallbackMessage;
|
|
177
194
|
try {
|
|
178
195
|
const result = await compose(entry);
|
|
179
196
|
return result.trim().length > 0 ? result : fallbackMessage;
|
|
180
197
|
} catch (error) {
|
|
181
|
-
|
|
198
|
+
logger.warn(`Scheduler compose failed for entry "${entry.id}":`, error);
|
|
182
199
|
return fallbackMessage;
|
|
183
200
|
}
|
|
184
201
|
}
|
|
@@ -222,6 +239,7 @@ function staleDrops(entries, now, graceMs) {
|
|
|
222
239
|
|
|
223
240
|
// src/scheduler/tick.ts
|
|
224
241
|
async function runTick(entries, options) {
|
|
242
|
+
const logger = options.logger ?? createConsoleLogger();
|
|
225
243
|
const result = { sent: [], notClaimed: [], stale: [], failed: [] };
|
|
226
244
|
for (const entry of staleDrops(entries, options.now, options.graceMs)) {
|
|
227
245
|
result.stale.push(entry.id);
|
|
@@ -233,7 +251,7 @@ async function runTick(entries, options) {
|
|
|
233
251
|
continue;
|
|
234
252
|
}
|
|
235
253
|
try {
|
|
236
|
-
const message = await composeMessage(entry, options.compose, options.fallbackMessage);
|
|
254
|
+
const message = await composeMessage(entry, options.compose, options.fallbackMessage, logger);
|
|
237
255
|
const delivered = await deliver(entry, message, {
|
|
238
256
|
senders: options.senders,
|
|
239
257
|
voiceAttempted: options.voiceAttempted
|
|
@@ -245,7 +263,7 @@ async function runTick(entries, options) {
|
|
|
245
263
|
result.failed.push(entry.id);
|
|
246
264
|
}
|
|
247
265
|
} catch (error) {
|
|
248
|
-
|
|
266
|
+
logger.warn(`Scheduler delivery failed for entry "${entry.id}":`, error);
|
|
249
267
|
await options.claims.release(entry.id);
|
|
250
268
|
result.failed.push(entry.id);
|
|
251
269
|
}
|
|
@@ -273,6 +291,7 @@ function createScheduler(config) {
|
|
|
273
291
|
const fallbackMessage = config.fallbackMessage ?? DEFAULT_FALLBACK_MESSAGE;
|
|
274
292
|
const now = config.now ?? Date.now;
|
|
275
293
|
const schedule = config.schedule ?? defaultSchedule;
|
|
294
|
+
const logger = config.logger ?? createConsoleLogger();
|
|
276
295
|
let running;
|
|
277
296
|
let ticking = false;
|
|
278
297
|
async function tickOnce() {
|
|
@@ -284,7 +303,8 @@ function createScheduler(config) {
|
|
|
284
303
|
graceMs,
|
|
285
304
|
fallbackMessage,
|
|
286
305
|
compose: config.compose,
|
|
287
|
-
voiceAttempted: config.voiceAttempted
|
|
306
|
+
voiceAttempted: config.voiceAttempted,
|
|
307
|
+
logger
|
|
288
308
|
});
|
|
289
309
|
config.onTick?.(result);
|
|
290
310
|
return result;
|
|
@@ -297,7 +317,7 @@ function createScheduler(config) {
|
|
|
297
317
|
ticking = true;
|
|
298
318
|
tickOnce().catch((error) => {
|
|
299
319
|
if (config.onError) config.onError(error);
|
|
300
|
-
else
|
|
320
|
+
else logger.warn("Scheduler tick failed:", error);
|
|
301
321
|
}).finally(() => {
|
|
302
322
|
ticking = false;
|
|
303
323
|
});
|
package/dist/scheduler/index.mjs
CHANGED
|
@@ -105,8 +105,8 @@ async function completeOnce({
|
|
|
105
105
|
|
|
106
106
|
// src/core/answer.ts
|
|
107
107
|
var noUsage = () => ({ prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 });
|
|
108
|
-
async function runAnswerFn(answerFn, { system, messages, mode, sender }) {
|
|
109
|
-
const result = await answerFn({ system, messages, mode, sender });
|
|
108
|
+
async function runAnswerFn(answerFn, { system, messages, mode, sender, conversationId }) {
|
|
109
|
+
const result = await answerFn({ system, messages, mode, sender, conversationId });
|
|
110
110
|
const raw = typeof result === "string" ? result : result?.content;
|
|
111
111
|
const usage = typeof result === "string" ? void 0 : result?.usage;
|
|
112
112
|
return {
|
|
@@ -121,23 +121,40 @@ async function answerOnce({
|
|
|
121
121
|
messages,
|
|
122
122
|
mode,
|
|
123
123
|
sender,
|
|
124
|
+
conversationId,
|
|
124
125
|
temperature,
|
|
125
126
|
model
|
|
126
127
|
}) {
|
|
127
128
|
if (answerFn) {
|
|
128
|
-
return runAnswerFn(answerFn, { system, messages, mode, sender });
|
|
129
|
+
return runAnswerFn(answerFn, { system, messages, mode, sender, conversationId });
|
|
129
130
|
}
|
|
130
131
|
return completeOnce({ client, system, messages, temperature, model });
|
|
131
132
|
}
|
|
132
133
|
|
|
134
|
+
// src/core/logger.ts
|
|
135
|
+
var LEVEL_ORDER = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
136
|
+
function createConsoleLogger(level = "info") {
|
|
137
|
+
const threshold = LEVEL_ORDER[level];
|
|
138
|
+
const write = (at) => (...args) => {
|
|
139
|
+
if (LEVEL_ORDER[at] < threshold) return;
|
|
140
|
+
console.error(`[${at}]`, ...args);
|
|
141
|
+
};
|
|
142
|
+
return {
|
|
143
|
+
debug: write("debug"),
|
|
144
|
+
info: write("info"),
|
|
145
|
+
warn: write("warn"),
|
|
146
|
+
error: write("error")
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
133
150
|
// src/scheduler/compose.ts
|
|
134
|
-
async function composeMessage(entry, compose, fallbackMessage) {
|
|
151
|
+
async function composeMessage(entry, compose, fallbackMessage, logger = createConsoleLogger()) {
|
|
135
152
|
if (!compose) return fallbackMessage;
|
|
136
153
|
try {
|
|
137
154
|
const result = await compose(entry);
|
|
138
155
|
return result.trim().length > 0 ? result : fallbackMessage;
|
|
139
156
|
} catch (error) {
|
|
140
|
-
|
|
157
|
+
logger.warn(`Scheduler compose failed for entry "${entry.id}":`, error);
|
|
141
158
|
return fallbackMessage;
|
|
142
159
|
}
|
|
143
160
|
}
|
|
@@ -181,6 +198,7 @@ function staleDrops(entries, now, graceMs) {
|
|
|
181
198
|
|
|
182
199
|
// src/scheduler/tick.ts
|
|
183
200
|
async function runTick(entries, options) {
|
|
201
|
+
const logger = options.logger ?? createConsoleLogger();
|
|
184
202
|
const result = { sent: [], notClaimed: [], stale: [], failed: [] };
|
|
185
203
|
for (const entry of staleDrops(entries, options.now, options.graceMs)) {
|
|
186
204
|
result.stale.push(entry.id);
|
|
@@ -192,7 +210,7 @@ async function runTick(entries, options) {
|
|
|
192
210
|
continue;
|
|
193
211
|
}
|
|
194
212
|
try {
|
|
195
|
-
const message = await composeMessage(entry, options.compose, options.fallbackMessage);
|
|
213
|
+
const message = await composeMessage(entry, options.compose, options.fallbackMessage, logger);
|
|
196
214
|
const delivered = await deliver(entry, message, {
|
|
197
215
|
senders: options.senders,
|
|
198
216
|
voiceAttempted: options.voiceAttempted
|
|
@@ -204,7 +222,7 @@ async function runTick(entries, options) {
|
|
|
204
222
|
result.failed.push(entry.id);
|
|
205
223
|
}
|
|
206
224
|
} catch (error) {
|
|
207
|
-
|
|
225
|
+
logger.warn(`Scheduler delivery failed for entry "${entry.id}":`, error);
|
|
208
226
|
await options.claims.release(entry.id);
|
|
209
227
|
result.failed.push(entry.id);
|
|
210
228
|
}
|
|
@@ -232,6 +250,7 @@ function createScheduler(config) {
|
|
|
232
250
|
const fallbackMessage = config.fallbackMessage ?? DEFAULT_FALLBACK_MESSAGE;
|
|
233
251
|
const now = config.now ?? Date.now;
|
|
234
252
|
const schedule = config.schedule ?? defaultSchedule;
|
|
253
|
+
const logger = config.logger ?? createConsoleLogger();
|
|
235
254
|
let running;
|
|
236
255
|
let ticking = false;
|
|
237
256
|
async function tickOnce() {
|
|
@@ -243,7 +262,8 @@ function createScheduler(config) {
|
|
|
243
262
|
graceMs,
|
|
244
263
|
fallbackMessage,
|
|
245
264
|
compose: config.compose,
|
|
246
|
-
voiceAttempted: config.voiceAttempted
|
|
265
|
+
voiceAttempted: config.voiceAttempted,
|
|
266
|
+
logger
|
|
247
267
|
});
|
|
248
268
|
config.onTick?.(result);
|
|
249
269
|
return result;
|
|
@@ -256,7 +276,7 @@ function createScheduler(config) {
|
|
|
256
276
|
ticking = true;
|
|
257
277
|
tickOnce().catch((error) => {
|
|
258
278
|
if (config.onError) config.onError(error);
|
|
259
|
-
else
|
|
279
|
+
else logger.warn("Scheduler tick failed:", error);
|
|
260
280
|
}).finally(() => {
|
|
261
281
|
ticking = false;
|
|
262
282
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Client } from "@libsql/client";
|
|
2
2
|
import type { ChannelSenderRegistry } from "../channels/senders";
|
|
3
|
+
import { type Logger } from "../core/logger";
|
|
3
4
|
import type { ComposeFn, ScheduleEntry, TickResult } from "./types";
|
|
4
5
|
export declare const DEFAULT_GRACE_MS: number;
|
|
5
6
|
export declare const DEFAULT_INTERVAL_MS = 60000;
|
|
@@ -25,6 +26,8 @@ export interface SchedulerConfig {
|
|
|
25
26
|
};
|
|
26
27
|
/** Injectable for tests; defaults to `Date.now`. */
|
|
27
28
|
now?: () => number;
|
|
29
|
+
/** Logger for tick/delivery failures. Default: a console logger writing to stderr. */
|
|
30
|
+
logger?: Logger;
|
|
28
31
|
}
|
|
29
32
|
export interface Scheduler {
|
|
30
33
|
/** Starts ticking on `intervalMs`. No-op if already started. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/scheduler/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/scheduler/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAOlE,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEpE,eAAO,MAAM,gBAAgB,QAAa,CAAC;AAC3C,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAC1C,eAAO,MAAM,wBAAwB,kCAAkC,CAAC;AAExE,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,qBAAqB,CAAC;IAC/B,sGAAsG;IACtG,YAAY,EAAE,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC,GAAG,aAAa,EAAE,CAAC;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;IAChE,oDAAoD;IACpD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,gEAAgE;IAChE,KAAK,IAAI,IAAI,CAAC;IACd,2CAA2C;IAC3C,IAAI,IAAI,IAAI,CAAC;IACb,8FAA8F;IAC9F,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;CACjC;AAQD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAwDlE"}
|
package/dist/scheduler/tick.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ChannelSenderRegistry } from "../channels/senders";
|
|
2
|
+
import { type Logger } from "../core/logger";
|
|
2
3
|
import type { ComposeFn, ScheduleClaimStore, ScheduleEntry, TickResult } from "./types";
|
|
3
4
|
export interface TickOptions {
|
|
4
5
|
claims: ScheduleClaimStore;
|
|
@@ -8,6 +9,7 @@ export interface TickOptions {
|
|
|
8
9
|
fallbackMessage: string;
|
|
9
10
|
compose?: ComposeFn;
|
|
10
11
|
voiceAttempted?: boolean;
|
|
12
|
+
logger?: Logger;
|
|
11
13
|
}
|
|
12
14
|
/**
|
|
13
15
|
* One scheduler tick over caller-supplied candidate entries. Chatter stores
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tick.d.ts","sourceRoot":"","sources":["../../src/scheduler/tick.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"tick.d.ts","sourceRoot":"","sources":["../../src/scheduler/tick.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAIlE,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAExF,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,OAAO,EAAE,qBAAqB,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAuCjG"}
|
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;AAIH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAgB5B,OAAO,KAAK,EAAE,aAAa,EAAsB,MAAM,SAAS,CAAC;AAEjE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG;IAAE,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AAEtE;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CA6N7E"}
|