sensorium-mcp 2.16.28 → 2.16.30
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/config.d.ts +1 -11
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -49
- package/dist/config.js.map +1 -1
- package/dist/dashboard/presets.d.ts +18 -0
- package/dist/dashboard/presets.d.ts.map +1 -0
- package/dist/dashboard/presets.js +78 -0
- package/dist/dashboard/presets.js.map +1 -0
- package/dist/dashboard/routes.d.ts +33 -0
- package/dist/dashboard/routes.d.ts.map +1 -0
- package/dist/dashboard/routes.js +283 -0
- package/dist/dashboard/routes.js.map +1 -0
- package/dist/dashboard.d.ts +6 -29
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/dashboard.js +6 -1158
- package/dist/dashboard.js.map +1 -1
- package/dist/data/file-storage.d.ts +19 -0
- package/dist/data/file-storage.d.ts.map +1 -0
- package/dist/data/file-storage.js +58 -0
- package/dist/data/file-storage.js.map +1 -0
- package/dist/data/memory/bootstrap.d.ts +40 -0
- package/dist/data/memory/bootstrap.d.ts.map +1 -0
- package/dist/data/memory/bootstrap.js +240 -0
- package/dist/data/memory/bootstrap.js.map +1 -0
- package/dist/data/memory/consolidation.d.ts +12 -0
- package/dist/data/memory/consolidation.d.ts.map +1 -0
- package/dist/data/memory/consolidation.js +248 -0
- package/dist/data/memory/consolidation.js.map +1 -0
- package/dist/data/memory/episodes.d.ts +34 -0
- package/dist/data/memory/episodes.d.ts.map +1 -0
- package/dist/data/memory/episodes.js +89 -0
- package/dist/data/memory/episodes.js.map +1 -0
- package/dist/data/memory/index.d.ts +14 -0
- package/dist/data/memory/index.d.ts.map +1 -0
- package/dist/data/memory/index.js +14 -0
- package/dist/data/memory/index.js.map +1 -0
- package/dist/data/memory/procedures.d.ts +42 -0
- package/dist/data/memory/procedures.d.ts.map +1 -0
- package/dist/data/memory/procedures.js +122 -0
- package/dist/data/memory/procedures.js.map +1 -0
- package/dist/data/memory/schema.d.ts +11 -0
- package/dist/data/memory/schema.d.ts.map +1 -0
- package/dist/data/memory/schema.js +327 -0
- package/dist/data/memory/schema.js.map +1 -0
- package/dist/data/memory/semantic.d.ts +94 -0
- package/dist/data/memory/semantic.d.ts.map +1 -0
- package/dist/data/memory/semantic.js +385 -0
- package/dist/data/memory/semantic.js.map +1 -0
- package/dist/data/memory/voice-sig.d.ts +33 -0
- package/dist/data/memory/voice-sig.d.ts.map +1 -0
- package/dist/data/memory/voice-sig.js +48 -0
- package/dist/data/memory/voice-sig.js.map +1 -0
- package/dist/data/templates.d.ts +19 -0
- package/dist/data/templates.d.ts.map +1 -0
- package/dist/data/templates.js +46 -0
- package/dist/data/templates.js.map +1 -0
- package/dist/dispatcher.d.ts +5 -97
- package/dist/dispatcher.d.ts.map +1 -1
- package/dist/dispatcher.js +5 -525
- package/dist/dispatcher.js.map +1 -1
- package/dist/drive.d.ts.map +1 -1
- package/dist/drive.js +3 -1
- package/dist/drive.js.map +1 -1
- package/dist/index.d.ts +4 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -289
- package/dist/index.js.map +1 -1
- package/dist/integrations/openai/chat.d.ts +29 -0
- package/dist/integrations/openai/chat.d.ts.map +1 -0
- package/dist/integrations/openai/chat.js +84 -0
- package/dist/integrations/openai/chat.js.map +1 -0
- package/dist/integrations/openai/index.d.ts +6 -0
- package/dist/integrations/openai/index.d.ts.map +1 -0
- package/dist/integrations/openai/index.js +6 -0
- package/dist/integrations/openai/index.js.map +1 -0
- package/dist/integrations/openai/speech.d.ts +21 -0
- package/dist/integrations/openai/speech.d.ts.map +1 -0
- package/dist/integrations/openai/speech.js +75 -0
- package/dist/integrations/openai/speech.js.map +1 -0
- package/dist/integrations/openai/video.d.ts +15 -0
- package/dist/integrations/openai/video.d.ts.map +1 -0
- package/dist/integrations/openai/video.js +131 -0
- package/dist/integrations/openai/video.js.map +1 -0
- package/dist/integrations/openai/vision.d.ts +23 -0
- package/dist/integrations/openai/vision.d.ts.map +1 -0
- package/dist/integrations/openai/vision.js +116 -0
- package/dist/integrations/openai/vision.js.map +1 -0
- package/dist/integrations/openai/voice-emotion.d.ts +41 -0
- package/dist/integrations/openai/voice-emotion.d.ts.map +1 -0
- package/dist/integrations/openai/voice-emotion.js +50 -0
- package/dist/integrations/openai/voice-emotion.js.map +1 -0
- package/dist/integrations/telegram/types.d.ts +112 -0
- package/dist/integrations/telegram/types.d.ts.map +1 -0
- package/dist/integrations/telegram/types.js +6 -0
- package/dist/integrations/telegram/types.js.map +1 -0
- package/dist/memory.d.ts +6 -205
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +6 -1357
- package/dist/memory.js.map +1 -1
- package/dist/openai.d.ts +11 -102
- package/dist/openai.d.ts.map +1 -1
- package/dist/openai.js +14 -421
- package/dist/openai.js.map +1 -1
- package/dist/response-builders.d.ts +1 -11
- package/dist/response-builders.d.ts.map +1 -1
- package/dist/response-builders.js +2 -38
- package/dist/response-builders.js.map +1 -1
- package/dist/server/factory.d.ts +17 -0
- package/dist/server/factory.d.ts.map +1 -0
- package/dist/server/factory.js +279 -0
- package/dist/server/factory.js.map +1 -0
- package/dist/services/dispatcher/broker.d.ts +83 -0
- package/dist/services/dispatcher/broker.d.ts.map +1 -0
- package/dist/services/dispatcher/broker.js +175 -0
- package/dist/services/dispatcher/broker.js.map +1 -0
- package/dist/services/dispatcher/index.d.ts +7 -0
- package/dist/services/dispatcher/index.d.ts.map +1 -0
- package/dist/services/dispatcher/index.js +7 -0
- package/dist/services/dispatcher/index.js.map +1 -0
- package/dist/services/dispatcher/lock.d.ts +25 -0
- package/dist/services/dispatcher/lock.d.ts.map +1 -0
- package/dist/services/dispatcher/lock.js +111 -0
- package/dist/services/dispatcher/lock.js.map +1 -0
- package/dist/services/dispatcher/poller.d.ts +19 -0
- package/dist/services/dispatcher/poller.d.ts.map +1 -0
- package/dist/services/dispatcher/poller.js +269 -0
- package/dist/services/dispatcher/poller.js.map +1 -0
- package/dist/telegram.d.ts +2 -88
- package/dist/telegram.d.ts.map +1 -1
- package/dist/telegram.js +2 -0
- package/dist/telegram.js.map +1 -1
- package/dist/tool-definitions.d.ts +1 -14
- package/dist/tool-definitions.d.ts.map +1 -1
- package/dist/tool-definitions.js +1 -403
- package/dist/tool-definitions.js.map +1 -1
- package/dist/tools/definitions.d.ts +15 -0
- package/dist/tools/definitions.d.ts.map +1 -0
- package/dist/tools/definitions.js +404 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/start-session-tool.d.ts.map +1 -1
- package/dist/tools/start-session-tool.js +2 -0
- package/dist/tools/start-session-tool.js.map +1 -1
- package/dist/tools/wait/drive-handler.d.ts +61 -0
- package/dist/tools/wait/drive-handler.d.ts.map +1 -0
- package/dist/tools/wait/drive-handler.js +138 -0
- package/dist/tools/wait/drive-handler.js.map +1 -0
- package/dist/tools/wait/index.d.ts +8 -0
- package/dist/tools/wait/index.d.ts.map +1 -0
- package/dist/tools/wait/index.js +8 -0
- package/dist/tools/wait/index.js.map +1 -0
- package/dist/tools/wait/media-processor.d.ts +52 -0
- package/dist/tools/wait/media-processor.d.ts.map +1 -0
- package/dist/tools/wait/media-processor.js +261 -0
- package/dist/tools/wait/media-processor.js.map +1 -0
- package/dist/tools/wait/message-delivery.d.ts +63 -0
- package/dist/tools/wait/message-delivery.d.ts.map +1 -0
- package/dist/tools/wait/message-delivery.js +281 -0
- package/dist/tools/wait/message-delivery.js.map +1 -0
- package/dist/tools/wait/poll-loop.d.ts +72 -0
- package/dist/tools/wait/poll-loop.d.ts.map +1 -0
- package/dist/tools/wait/poll-loop.js +280 -0
- package/dist/tools/wait/poll-loop.js.map +1 -0
- package/dist/tools/wait/reaction-handler.d.ts +49 -0
- package/dist/tools/wait/reaction-handler.d.ts.map +1 -0
- package/dist/tools/wait/reaction-handler.js +126 -0
- package/dist/tools/wait/reaction-handler.js.map +1 -0
- package/dist/tools/wait/task-handler.d.ts +40 -0
- package/dist/tools/wait/task-handler.d.ts.map +1 -0
- package/dist/tools/wait/task-handler.js +41 -0
- package/dist/tools/wait/task-handler.js.map +1 -0
- package/dist/tools/wait-tool.d.ts +3 -69
- package/dist/tools/wait-tool.d.ts.map +1 -1
- package/dist/tools/wait-tool.js +3 -876
- package/dist/tools/wait-tool.js.map +1 -1
- package/package.json +1 -1
- package/templates/daily-review.default.md +26 -0
- package/templates/drive-dispatcher.default.md +2 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drive activation and auto-consolidation logic extracted from wait-tool.ts.
|
|
3
|
+
*
|
|
4
|
+
* Contains:
|
|
5
|
+
* - runAutoConsolidation(): 3 strategies (idle, episode-count, time-based)
|
|
6
|
+
* - checkDriveActivation(): 3-phase autonomous drive (phase 1/2/3)
|
|
7
|
+
*/
|
|
8
|
+
import { formatDrivePrompt, PHASE3_APPROVAL_PROMPT } from "../../drive.js";
|
|
9
|
+
import { log } from "../../logger.js";
|
|
10
|
+
import { runIntelligentConsolidation } from "../../memory.js";
|
|
11
|
+
import { getReminders } from "../../response-builders.js";
|
|
12
|
+
import { backfillEmbeddings } from "../memory-tools.js";
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Auto-consolidation (3 strategies)
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
/**
|
|
17
|
+
* Checks three consolidation strategies and fires runIntelligentConsolidation
|
|
18
|
+
* + backfillEmbeddings as fire-and-forget when conditions are met.
|
|
19
|
+
*
|
|
20
|
+
* Strategies:
|
|
21
|
+
* 1. Idle-based — 15 min idle, 30 min cooldown
|
|
22
|
+
* 2. Episode-count — ≥15 unconsolidated episodes, 30 min cooldown
|
|
23
|
+
* 3. Time-based — every 4 hours regardless
|
|
24
|
+
*/
|
|
25
|
+
export function runAutoConsolidation(ctx) {
|
|
26
|
+
const { state, effectiveThreadId, getMemoryDb } = ctx;
|
|
27
|
+
// Strategy 1: Idle-based consolidation
|
|
28
|
+
try {
|
|
29
|
+
const idleMs = Date.now() - state.lastOperatorMessageAt;
|
|
30
|
+
if (idleMs > 15 * 60 * 1000 && effectiveThreadId !== undefined && Date.now() - state.lastConsolidationAt > 30 * 60 * 1000) {
|
|
31
|
+
state.lastConsolidationAt = Date.now();
|
|
32
|
+
const db = getMemoryDb();
|
|
33
|
+
void runIntelligentConsolidation(db, effectiveThreadId).then(async (report) => {
|
|
34
|
+
if (report.episodesProcessed > 0) {
|
|
35
|
+
log.info(`[memory] Consolidation: ${report.episodesProcessed} episodes → ${report.notesCreated} notes`);
|
|
36
|
+
}
|
|
37
|
+
await backfillEmbeddings(db);
|
|
38
|
+
}).catch(err => {
|
|
39
|
+
log.error(`[memory] Consolidation error: ${err instanceof Error ? err.message : String(err)}`);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch (_) { /* consolidation failure is non-fatal */ }
|
|
44
|
+
// Strategy 2: Episode-count consolidation — don't wait for idle.
|
|
45
|
+
// If many episodes accumulated during active use, consolidate now.
|
|
46
|
+
// This prevents stale/contradictory knowledge from persisting.
|
|
47
|
+
try {
|
|
48
|
+
if (effectiveThreadId !== undefined && Date.now() - state.lastConsolidationAt > 30 * 60 * 1000) {
|
|
49
|
+
const db = getMemoryDb();
|
|
50
|
+
const uncons = db.prepare("SELECT COUNT(*) as c FROM episodes WHERE consolidated = 0 AND thread_id = ?").get(effectiveThreadId);
|
|
51
|
+
if (uncons.c >= 15) {
|
|
52
|
+
state.lastConsolidationAt = Date.now();
|
|
53
|
+
void runIntelligentConsolidation(db, effectiveThreadId).then(async (report) => {
|
|
54
|
+
if (report.episodesProcessed > 0) {
|
|
55
|
+
log.info(`[memory] Episode-count consolidation: ${report.episodesProcessed} episodes → ${report.notesCreated} notes`);
|
|
56
|
+
}
|
|
57
|
+
await backfillEmbeddings(db);
|
|
58
|
+
}).catch(err => {
|
|
59
|
+
log.error(`[memory] Episode-count consolidation error: ${err instanceof Error ? err.message : String(err)}`);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (_) { /* non-fatal */ }
|
|
65
|
+
// Strategy 3: Time-based consolidation — every 4 hours regardless.
|
|
66
|
+
// Ensures stale knowledge gets cleaned up even during low-activity periods.
|
|
67
|
+
try {
|
|
68
|
+
const TIME_CONSOLIDATION_INTERVAL = 4 * 60 * 60 * 1000; // 4 hours
|
|
69
|
+
if (effectiveThreadId !== undefined && Date.now() - state.lastConsolidationAt > TIME_CONSOLIDATION_INTERVAL) {
|
|
70
|
+
state.lastConsolidationAt = Date.now();
|
|
71
|
+
const db = getMemoryDb();
|
|
72
|
+
log.info(`[memory] Time-based consolidation triggered (4h since last)`);
|
|
73
|
+
void runIntelligentConsolidation(db, effectiveThreadId).then(async (report) => {
|
|
74
|
+
if (report.episodesProcessed > 0) {
|
|
75
|
+
log.info(`[memory] Time-based consolidation: ${report.episodesProcessed} episodes → ${report.notesCreated} notes`);
|
|
76
|
+
}
|
|
77
|
+
await backfillEmbeddings(db);
|
|
78
|
+
}).catch(err => {
|
|
79
|
+
log.error(`[memory] Time-based consolidation error: ${err instanceof Error ? err.message : String(err)}`);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch (_) { /* non-fatal */ }
|
|
84
|
+
}
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
// 3-Phase Autonomous Drive
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
const DRIVE_COOLDOWN_MS = 30 * 60 * 1000; // 30 minutes between probability rolls
|
|
89
|
+
/**
|
|
90
|
+
* Checks and handles the 3-phase autonomous drive logic.
|
|
91
|
+
*
|
|
92
|
+
* - Phase 3: If `drivePhase2Fired` → return PHASE3_APPROVAL_PROMPT
|
|
93
|
+
* - Phase 1+2: If idle > threshold and cooldown elapsed → formatDrivePrompt()
|
|
94
|
+
* → if activated, set drivePhase2Fired=true, return drive prompt
|
|
95
|
+
*
|
|
96
|
+
* Returns a ToolResult if drive activated, or null if nothing to do.
|
|
97
|
+
*/
|
|
98
|
+
export function checkDriveActivation(ctx) {
|
|
99
|
+
const { state, effectiveThreadId, config, memoryRefresh, scheduleHint } = ctx;
|
|
100
|
+
const DRIVE_ACTIVATION_MS = config.DMN_ACTIVATION_HOURS * 60 * 60 * 1000;
|
|
101
|
+
const idleMs = Date.now() - state.lastOperatorMessageAt;
|
|
102
|
+
// Phase 3: If Phase 2 just fired and the agent came back without engaging
|
|
103
|
+
if (state.drivePhase2Fired) {
|
|
104
|
+
state.drivePhase2Fired = false; // Reset — only approve once
|
|
105
|
+
return {
|
|
106
|
+
content: [
|
|
107
|
+
{
|
|
108
|
+
type: "text",
|
|
109
|
+
text: PHASE3_APPROVAL_PROMPT +
|
|
110
|
+
memoryRefresh +
|
|
111
|
+
scheduleHint +
|
|
112
|
+
getReminders(effectiveThreadId, state.sessionStartedAt, config.AUTONOMOUS_MODE),
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
// Phase 1: Probability gate (only if past threshold and cooldown elapsed)
|
|
118
|
+
if (idleMs >= DRIVE_ACTIVATION_MS && Date.now() - state.lastDriveAttemptAt >= DRIVE_COOLDOWN_MS) {
|
|
119
|
+
state.lastDriveAttemptAt = Date.now();
|
|
120
|
+
const driveResult = formatDrivePrompt(idleMs, config.DMN_ACTIVATION_HOURS);
|
|
121
|
+
if (driveResult.activated && driveResult.prompt) {
|
|
122
|
+
// Phase 2: Intention Elicitation — give the agent full autonomy
|
|
123
|
+
state.drivePhase2Fired = true;
|
|
124
|
+
return {
|
|
125
|
+
content: [
|
|
126
|
+
{
|
|
127
|
+
type: "text",
|
|
128
|
+
text: driveResult.prompt,
|
|
129
|
+
},
|
|
130
|
+
...(memoryRefresh ? [{ type: "text", text: memoryRefresh.replace(/^\n\n/, "") }] : []),
|
|
131
|
+
{ type: "text", text: scheduleHint + getReminders(effectiveThreadId, state.sessionStartedAt, config.AUTONOMOUS_MODE) },
|
|
132
|
+
],
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=drive-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drive-handler.js","sourceRoot":"","sources":["../../../src/tools/wait/drive-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Barrel re-export for the wait-tool subsystem.
|
|
3
|
+
*
|
|
4
|
+
* All wait-related modules live under src/tools/wait/.
|
|
5
|
+
* External consumers should import from this barrel.
|
|
6
|
+
*/
|
|
7
|
+
export { handleWaitForInstructions, type WaitToolContext, type WaitToolExtra } from "./poll-loop.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/wait/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,yBAAyB,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Barrel re-export for the wait-tool subsystem.
|
|
3
|
+
*
|
|
4
|
+
* All wait-related modules live under src/tools/wait/.
|
|
5
|
+
* External consumers should import from this barrel.
|
|
6
|
+
*/
|
|
7
|
+
export { handleWaitForInstructions } from "./poll-loop.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/wait/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,yBAAyB,EAA4C,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media processing handlers extracted from wait-tool.ts (Phase 4).
|
|
3
|
+
*
|
|
4
|
+
* Handles voice messages, animations/GIFs, and video notes —
|
|
5
|
+
* downloading, transcribing, analyzing, and building content blocks.
|
|
6
|
+
*/
|
|
7
|
+
import type { StoredMessage } from "../../dispatcher.js";
|
|
8
|
+
import { type Database } from "../../memory.js";
|
|
9
|
+
import type { TelegramClient } from "../../telegram.js";
|
|
10
|
+
export type ContentBlock = {
|
|
11
|
+
type: "text";
|
|
12
|
+
text: string;
|
|
13
|
+
} | {
|
|
14
|
+
type: "image";
|
|
15
|
+
data: string;
|
|
16
|
+
mimeType: string;
|
|
17
|
+
};
|
|
18
|
+
/** Focused context that media processors need — not the full WaitToolContext. */
|
|
19
|
+
export interface MediaContext {
|
|
20
|
+
telegram: TelegramClient;
|
|
21
|
+
openaiApiKey: string;
|
|
22
|
+
voiceAnalysisUrl: string;
|
|
23
|
+
effectiveThreadId: number;
|
|
24
|
+
sessionStartedAt: number;
|
|
25
|
+
getMemoryDb: () => Database;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Process a voice message: download → parallel transcription + VANPY →
|
|
29
|
+
* build tags → text block → save episode + voice signature.
|
|
30
|
+
*
|
|
31
|
+
* @returns Content blocks to append, and whether an episode was auto-saved.
|
|
32
|
+
*/
|
|
33
|
+
export declare function processVoice(msg: StoredMessage, ctx: MediaContext): Promise<{
|
|
34
|
+
blocks: ContentBlock[];
|
|
35
|
+
episodeSaved: boolean;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* Process an animation/GIF: download → disk save → extractVideoFrames →
|
|
39
|
+
* analyzeVideoFrames → text block.
|
|
40
|
+
*/
|
|
41
|
+
export declare function processAnimation(msg: StoredMessage, ctx: MediaContext): Promise<ContentBlock[]>;
|
|
42
|
+
/**
|
|
43
|
+
* Process a video note (circle video): download → parallel(frames, transcribe,
|
|
44
|
+
* VANPY) → vision analysis → tags → text block → save episode + voice signature.
|
|
45
|
+
*
|
|
46
|
+
* @returns Content blocks to append, and whether an episode was auto-saved.
|
|
47
|
+
*/
|
|
48
|
+
export declare function processVideoNote(msg: StoredMessage, ctx: MediaContext): Promise<{
|
|
49
|
+
blocks: ContentBlock[];
|
|
50
|
+
episodeSaved: boolean;
|
|
51
|
+
}>;
|
|
52
|
+
//# sourceMappingURL=media-processor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-processor.d.ts","sourceRoot":"","sources":["../../../src/tools/wait/media-processor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAGL,KAAK,QAAQ,EACd,MAAM,iBAAiB,CAAC;AAQzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOxD,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,iFAAiF;AACjF,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,cAAc,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,QAAQ,CAAC;CAC7B;AAMD;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,aAAa,EAClB,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC;IAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAAC,CA6E5D;AAMD;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,aAAa,EAClB,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,YAAY,EAAE,CAAC,CAsDzB;AAMD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,aAAa,EAClB,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC;IAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAAC,CAkG5D"}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media processing handlers extracted from wait-tool.ts (Phase 4).
|
|
3
|
+
*
|
|
4
|
+
* Handles voice messages, animations/GIFs, and video notes —
|
|
5
|
+
* downloading, transcribing, analyzing, and building content blocks.
|
|
6
|
+
*/
|
|
7
|
+
import { saveFileToDisk } from "../../config.js";
|
|
8
|
+
import { log } from "../../logger.js";
|
|
9
|
+
import { saveEpisode, saveVoiceSignature, } from "../../memory.js";
|
|
10
|
+
import { analyzeVideoFrames, analyzeVoiceEmotion, extractVideoFrames, transcribeAudio, } from "../../openai.js";
|
|
11
|
+
import { buildAnalysisTags } from "../../response-builders.js";
|
|
12
|
+
import { errorMessage } from "../../utils.js";
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Voice handler
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
/**
|
|
17
|
+
* Process a voice message: download → parallel transcription + VANPY →
|
|
18
|
+
* build tags → text block → save episode + voice signature.
|
|
19
|
+
*
|
|
20
|
+
* @returns Content blocks to append, and whether an episode was auto-saved.
|
|
21
|
+
*/
|
|
22
|
+
export async function processVoice(msg, ctx) {
|
|
23
|
+
const voice = msg.message.voice;
|
|
24
|
+
const blocks = [];
|
|
25
|
+
if (!ctx.openaiApiKey) {
|
|
26
|
+
blocks.push({
|
|
27
|
+
type: "text",
|
|
28
|
+
text: `[Voice message received — ${voice.duration}s — cannot transcribe: OPENAI_API_KEY not set]`,
|
|
29
|
+
});
|
|
30
|
+
return { blocks, episodeSaved: false };
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
log.verbose("voice", `Downloading voice file ${voice.file_id}...`);
|
|
34
|
+
const { buffer } = await ctx.telegram.downloadFileAsBuffer(voice.file_id);
|
|
35
|
+
log.verbose("voice", `Downloaded ${buffer.length} bytes. Starting transcription + analysis...`);
|
|
36
|
+
// Run transcription and voice analysis in parallel.
|
|
37
|
+
const [transcript, analysis] = await Promise.all([
|
|
38
|
+
transcribeAudio(buffer, ctx.openaiApiKey),
|
|
39
|
+
ctx.voiceAnalysisUrl
|
|
40
|
+
? analyzeVoiceEmotion(buffer, ctx.voiceAnalysisUrl)
|
|
41
|
+
: Promise.resolve(null),
|
|
42
|
+
]);
|
|
43
|
+
// Build rich voice analysis tag from VANPY results.
|
|
44
|
+
const tags = buildAnalysisTags(analysis);
|
|
45
|
+
const analysisTag = tags.length > 0 ? ` | ${tags.join(", ")}` : "";
|
|
46
|
+
blocks.push({
|
|
47
|
+
type: "text",
|
|
48
|
+
text: transcript
|
|
49
|
+
? `[Voice message — ${voice.duration}s${analysisTag}, transcribed]: ${transcript}`
|
|
50
|
+
: `[Voice message — ${voice.duration}s${analysisTag}, transcribed]: (empty — no speech detected)`,
|
|
51
|
+
});
|
|
52
|
+
// Auto-save voice signature
|
|
53
|
+
let episodeSaved = false;
|
|
54
|
+
if (analysis && ctx.effectiveThreadId !== undefined) {
|
|
55
|
+
try {
|
|
56
|
+
const db = ctx.getMemoryDb();
|
|
57
|
+
const sessionId = `session_${ctx.sessionStartedAt}`;
|
|
58
|
+
const epId = saveEpisode(db, {
|
|
59
|
+
sessionId,
|
|
60
|
+
threadId: ctx.effectiveThreadId,
|
|
61
|
+
type: "operator_message",
|
|
62
|
+
modality: "voice",
|
|
63
|
+
content: { text: transcript ?? "", duration: voice.duration },
|
|
64
|
+
importance: 0.6,
|
|
65
|
+
});
|
|
66
|
+
saveVoiceSignature(db, {
|
|
67
|
+
episodeId: epId,
|
|
68
|
+
emotion: analysis.emotion ?? undefined,
|
|
69
|
+
arousal: analysis.arousal ?? undefined,
|
|
70
|
+
dominance: analysis.dominance ?? undefined,
|
|
71
|
+
valence: analysis.valence ?? undefined,
|
|
72
|
+
speechRate: analysis.paralinguistics?.speech_rate ?? undefined,
|
|
73
|
+
meanPitchHz: analysis.paralinguistics?.mean_pitch_hz ?? undefined,
|
|
74
|
+
pitchStdHz: analysis.paralinguistics?.pitch_std_hz ?? undefined,
|
|
75
|
+
jitter: analysis.paralinguistics?.jitter ?? undefined,
|
|
76
|
+
shimmer: analysis.paralinguistics?.shimmer ?? undefined,
|
|
77
|
+
hnrDb: analysis.paralinguistics?.hnr_db ?? undefined,
|
|
78
|
+
audioEvents: analysis.audio_events?.map(e => ({ label: e.label, confidence: e.score })),
|
|
79
|
+
durationSec: voice.duration,
|
|
80
|
+
});
|
|
81
|
+
episodeSaved = true;
|
|
82
|
+
}
|
|
83
|
+
catch (_) { /* non-fatal */ }
|
|
84
|
+
}
|
|
85
|
+
return { blocks, episodeSaved };
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
blocks.push({
|
|
89
|
+
type: "text",
|
|
90
|
+
text: `[Voice message — ${voice.duration}s — transcription failed: ${errorMessage(err)}]`,
|
|
91
|
+
});
|
|
92
|
+
return { blocks, episodeSaved: false };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
// Animation / GIF handler
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
/**
|
|
99
|
+
* Process an animation/GIF: download → disk save → extractVideoFrames →
|
|
100
|
+
* analyzeVideoFrames → text block.
|
|
101
|
+
*/
|
|
102
|
+
export async function processAnimation(msg, ctx) {
|
|
103
|
+
const anim = msg.message.animation;
|
|
104
|
+
const animDuration = anim.duration ?? 3; // default to 3s if Telegram omits duration
|
|
105
|
+
const blocks = [];
|
|
106
|
+
if (!ctx.openaiApiKey) {
|
|
107
|
+
blocks.push({
|
|
108
|
+
type: "text",
|
|
109
|
+
text: `(The operator sent a GIF — cannot analyze: OPENAI_API_KEY not set)`,
|
|
110
|
+
});
|
|
111
|
+
return blocks;
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
log.verbose("gif", `Downloading animation ${anim.file_id} (~${animDuration}s)...`);
|
|
115
|
+
const { buffer } = await ctx.telegram.downloadFileAsBuffer(anim.file_id);
|
|
116
|
+
const diskPath = saveFileToDisk(buffer, "gif-animation.mp4");
|
|
117
|
+
log.verbose("gif", `Downloaded ${buffer.length} bytes. Extracting frames...`);
|
|
118
|
+
// Extract frames with ffmpeg (same as video_notes).
|
|
119
|
+
const frames = await extractVideoFrames(buffer, animDuration).catch((err) => {
|
|
120
|
+
log.error(`[gif] Frame extraction failed: ${errorMessage(err)}`);
|
|
121
|
+
return [];
|
|
122
|
+
});
|
|
123
|
+
// Analyze frames with GPT-4o-mini vision (same as video_notes).
|
|
124
|
+
let sceneDescription = null;
|
|
125
|
+
if (frames.length > 0) {
|
|
126
|
+
try {
|
|
127
|
+
log.verbose("gif", `Analyzing ${frames.length} frames with GPT-4o-mini vision...`);
|
|
128
|
+
sceneDescription = await analyzeVideoFrames(frames, animDuration, ctx.openaiApiKey);
|
|
129
|
+
log.verbose("gif", `Vision analysis complete.`);
|
|
130
|
+
}
|
|
131
|
+
catch (visionErr) {
|
|
132
|
+
log.error(`[gif] Vision analysis failed: ${visionErr}`);
|
|
133
|
+
sceneDescription = null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const caption = msg.message.caption || "";
|
|
137
|
+
const parts = [];
|
|
138
|
+
parts.push(`(The operator sent a GIF — ${animDuration}s)`);
|
|
139
|
+
if (sceneDescription)
|
|
140
|
+
parts.push(`Scene: ${sceneDescription}`);
|
|
141
|
+
if (!sceneDescription)
|
|
142
|
+
parts.push("(no visual content could be extracted)");
|
|
143
|
+
parts.push(`Saved to: ${diskPath}`);
|
|
144
|
+
if (caption)
|
|
145
|
+
parts.push(`Caption: ${caption}`);
|
|
146
|
+
blocks.push({ type: "text", text: parts.join("\n") });
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
blocks.push({
|
|
150
|
+
type: "text",
|
|
151
|
+
text: `(The operator sent a GIF — analysis failed: ${errorMessage(err)})`,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return blocks;
|
|
155
|
+
}
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
// Video note handler
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
/**
|
|
160
|
+
* Process a video note (circle video): download → parallel(frames, transcribe,
|
|
161
|
+
* VANPY) → vision analysis → tags → text block → save episode + voice signature.
|
|
162
|
+
*
|
|
163
|
+
* @returns Content blocks to append, and whether an episode was auto-saved.
|
|
164
|
+
*/
|
|
165
|
+
export async function processVideoNote(msg, ctx) {
|
|
166
|
+
const vn = msg.message.video_note;
|
|
167
|
+
const blocks = [];
|
|
168
|
+
if (!ctx.openaiApiKey) {
|
|
169
|
+
blocks.push({
|
|
170
|
+
type: "text",
|
|
171
|
+
text: `[Video note received — ${vn.duration}s — cannot analyze: OPENAI_API_KEY not set]`,
|
|
172
|
+
});
|
|
173
|
+
return { blocks, episodeSaved: false };
|
|
174
|
+
}
|
|
175
|
+
try {
|
|
176
|
+
log.verbose("video-note", `Downloading circle video ${vn.file_id} (${vn.duration}s)...`);
|
|
177
|
+
const { buffer } = await ctx.telegram.downloadFileAsBuffer(vn.file_id);
|
|
178
|
+
log.verbose("video-note", `Downloaded ${buffer.length} bytes. Extracting frames + transcribing...`);
|
|
179
|
+
// Run frame extraction, audio transcription, and voice analysis in parallel.
|
|
180
|
+
const [frames, transcript, analysis] = await Promise.all([
|
|
181
|
+
extractVideoFrames(buffer, vn.duration).catch((err) => {
|
|
182
|
+
log.error(`[video-note] Frame extraction failed: ${errorMessage(err)}`);
|
|
183
|
+
return [];
|
|
184
|
+
}),
|
|
185
|
+
transcribeAudio(buffer, ctx.openaiApiKey, "video.mp4").catch(() => ""),
|
|
186
|
+
ctx.voiceAnalysisUrl
|
|
187
|
+
? analyzeVoiceEmotion(buffer, ctx.voiceAnalysisUrl, {
|
|
188
|
+
mimeType: "video/mp4",
|
|
189
|
+
filename: "video.mp4",
|
|
190
|
+
}).catch(() => null)
|
|
191
|
+
: Promise.resolve(null),
|
|
192
|
+
]);
|
|
193
|
+
// Analyze frames with GPT-4o-mini vision.
|
|
194
|
+
let sceneDescription = "";
|
|
195
|
+
if (frames.length > 0) {
|
|
196
|
+
try {
|
|
197
|
+
log.verbose("video-note", `Analyzing ${frames.length} frames with GPT-4o-mini vision...`);
|
|
198
|
+
sceneDescription = await analyzeVideoFrames(frames, vn.duration, ctx.openaiApiKey);
|
|
199
|
+
log.verbose("video-note", `Vision analysis complete.`);
|
|
200
|
+
}
|
|
201
|
+
catch (visionErr) {
|
|
202
|
+
log.error(`[video-note] Vision analysis failed: ${visionErr}`);
|
|
203
|
+
sceneDescription = null;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Build analysis tags (same as voice messages).
|
|
207
|
+
const tags = buildAnalysisTags(analysis);
|
|
208
|
+
const analysisTag = tags.length > 0 ? ` | ${tags.join(", ")}` : "";
|
|
209
|
+
const parts = [];
|
|
210
|
+
parts.push(`[Video note — ${vn.duration}s${analysisTag}]`);
|
|
211
|
+
if (sceneDescription)
|
|
212
|
+
parts.push(`Scene: ${sceneDescription}`);
|
|
213
|
+
if (transcript)
|
|
214
|
+
parts.push(`Audio: "${transcript}"`);
|
|
215
|
+
if (!sceneDescription && !transcript)
|
|
216
|
+
parts.push("(no visual or audio content could be extracted)");
|
|
217
|
+
blocks.push({ type: "text", text: parts.join("\n") });
|
|
218
|
+
// Auto-save voice signature for video notes
|
|
219
|
+
let episodeSaved = false;
|
|
220
|
+
if (analysis && ctx.effectiveThreadId !== undefined) {
|
|
221
|
+
try {
|
|
222
|
+
const db = ctx.getMemoryDb();
|
|
223
|
+
const sessionId = `session_${ctx.sessionStartedAt}`;
|
|
224
|
+
const epId = saveEpisode(db, {
|
|
225
|
+
sessionId,
|
|
226
|
+
threadId: ctx.effectiveThreadId,
|
|
227
|
+
type: "operator_message",
|
|
228
|
+
modality: "video_note",
|
|
229
|
+
content: { text: transcript ?? "", scene: sceneDescription ?? "", duration: vn.duration },
|
|
230
|
+
importance: 0.6,
|
|
231
|
+
});
|
|
232
|
+
saveVoiceSignature(db, {
|
|
233
|
+
episodeId: epId,
|
|
234
|
+
emotion: analysis.emotion ?? undefined,
|
|
235
|
+
arousal: analysis.arousal ?? undefined,
|
|
236
|
+
dominance: analysis.dominance ?? undefined,
|
|
237
|
+
valence: analysis.valence ?? undefined,
|
|
238
|
+
speechRate: analysis.paralinguistics?.speech_rate ?? undefined,
|
|
239
|
+
meanPitchHz: analysis.paralinguistics?.mean_pitch_hz ?? undefined,
|
|
240
|
+
pitchStdHz: analysis.paralinguistics?.pitch_std_hz ?? undefined,
|
|
241
|
+
jitter: analysis.paralinguistics?.jitter ?? undefined,
|
|
242
|
+
shimmer: analysis.paralinguistics?.shimmer ?? undefined,
|
|
243
|
+
hnrDb: analysis.paralinguistics?.hnr_db ?? undefined,
|
|
244
|
+
audioEvents: analysis.audio_events?.map(e => ({ label: e.label, confidence: e.score })),
|
|
245
|
+
durationSec: vn.duration,
|
|
246
|
+
});
|
|
247
|
+
episodeSaved = true;
|
|
248
|
+
}
|
|
249
|
+
catch (_) { /* non-fatal */ }
|
|
250
|
+
}
|
|
251
|
+
return { blocks, episodeSaved };
|
|
252
|
+
}
|
|
253
|
+
catch (err) {
|
|
254
|
+
blocks.push({
|
|
255
|
+
type: "text",
|
|
256
|
+
text: `[Video note — ${vn.duration}s — analysis failed: ${errorMessage(err)}]`,
|
|
257
|
+
});
|
|
258
|
+
return { blocks, episodeSaved: false };
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=media-processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-processor.js","sourceRoot":"","sources":["../../../src/tools/wait/media-processor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message delivery logic extracted from wait-tool.ts (Phase 4).
|
|
3
|
+
*
|
|
4
|
+
* Handles:
|
|
5
|
+
* - Simple message processing (photo, document, text, sticker)
|
|
6
|
+
* - Auto-ingesting episodes for messages not saved by media handlers
|
|
7
|
+
* - Smart context injection (embedding search + GPT-4o-mini filter)
|
|
8
|
+
* - Intent classification and final operator response assembly
|
|
9
|
+
*/
|
|
10
|
+
import type { StoredMessage } from "../../dispatcher.js";
|
|
11
|
+
import { type initMemoryDb } from "../../memory.js";
|
|
12
|
+
import type { TelegramClient } from "../../telegram.js";
|
|
13
|
+
type TextBlock = {
|
|
14
|
+
type: "text";
|
|
15
|
+
text: string;
|
|
16
|
+
};
|
|
17
|
+
type ImageBlock = {
|
|
18
|
+
type: "image";
|
|
19
|
+
data: string;
|
|
20
|
+
mimeType: string;
|
|
21
|
+
};
|
|
22
|
+
type ContentBlock = TextBlock | ImageBlock;
|
|
23
|
+
type ToolResult = {
|
|
24
|
+
content: Array<ContentBlock>;
|
|
25
|
+
isError?: boolean;
|
|
26
|
+
};
|
|
27
|
+
export interface MessageDeliveryContext {
|
|
28
|
+
telegram: TelegramClient;
|
|
29
|
+
getMemoryDb: () => ReturnType<typeof initMemoryDb>;
|
|
30
|
+
effectiveThreadId: number;
|
|
31
|
+
sessionStartedAt: number;
|
|
32
|
+
autonomousMode: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Process non-media message types for a single StoredMessage.
|
|
36
|
+
* Handles: photo, document, text, sticker.
|
|
37
|
+
* Returns content blocks for the processed parts.
|
|
38
|
+
*/
|
|
39
|
+
export declare function processSimpleMessage(msg: StoredMessage, telegram: TelegramClient): Promise<ContentBlock[]>;
|
|
40
|
+
/**
|
|
41
|
+
* If contentBlocks is empty after processing all messages, push an
|
|
42
|
+
* unsupported-type placeholder and log the message fields for debugging.
|
|
43
|
+
*/
|
|
44
|
+
export declare function handleEmptyContent(contentBlocks: ContentBlock[], stored: StoredMessage[]): void;
|
|
45
|
+
/**
|
|
46
|
+
* Auto-ingest episodes for messages that were not already saved by
|
|
47
|
+
* voice/video handlers (identified by savedEpisodeUpdateIds).
|
|
48
|
+
*/
|
|
49
|
+
export declare function autoIngestEpisodes(stored: StoredMessage[], savedEpisodeUpdateIds: Set<number>, ctx: Pick<MessageDeliveryContext, "getMemoryDb" | "effectiveThreadId" | "sessionStartedAt">): void;
|
|
50
|
+
/**
|
|
51
|
+
* Smart context injection: retrieves candidate memory notes via embedding
|
|
52
|
+
* search, then uses GPT-4o-mini to select ONLY the notes truly relevant
|
|
53
|
+
* to the operator's message. Falls back to keyword search if embedding
|
|
54
|
+
* fails, and to raw top-3 if the LLM filter fails.
|
|
55
|
+
*/
|
|
56
|
+
export declare function buildSmartContext(operatorText: string, ctx: Pick<MessageDeliveryContext, "getMemoryDb" | "effectiveThreadId">): Promise<string>;
|
|
57
|
+
/**
|
|
58
|
+
* Build the final operator message response: intent classification,
|
|
59
|
+
* reminder selection, and the `<<< OPERATOR MESSAGE >>>` envelope.
|
|
60
|
+
*/
|
|
61
|
+
export declare function assembleOperatorResponse(contentBlocks: ContentBlock[], operatorText: string, hasVoiceMessages: boolean, autoMemoryContext: string, ctx: Pick<MessageDeliveryContext, "effectiveThreadId" | "sessionStartedAt" | "autonomousMode">): ToolResult;
|
|
62
|
+
export {};
|
|
63
|
+
//# sourceMappingURL=message-delivery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-delivery.d.ts","sourceRoot":"","sources":["../../../src/tools/wait/message-delivery.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGzD,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,iBAAiB,CAAC;AAMzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOxD,KAAK,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAChD,KAAK,UAAU,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AACpE,KAAK,YAAY,GAAG,SAAS,GAAG,UAAU,CAAC;AAC3C,KAAK,UAAU,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEtE,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,EAAE,MAAM,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;IACnD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;CACzB;AAMD;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,aAAa,EAClB,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,YAAY,EAAE,CAAC,CAkFzB;AAMD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,YAAY,EAAE,EAC7B,MAAM,EAAE,aAAa,EAAE,GACtB,IAAI,CAWN;AAMD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,aAAa,EAAE,EACvB,qBAAqB,EAAE,GAAG,CAAC,MAAM,CAAC,EAClC,GAAG,EAAE,IAAI,CAAC,sBAAsB,EAAE,aAAa,GAAG,mBAAmB,GAAG,kBAAkB,CAAC,GAC1F,IAAI,CA0BN;AAMD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,IAAI,CAAC,sBAAsB,EAAE,aAAa,GAAG,mBAAmB,CAAC,GACrE,OAAO,CAAC,MAAM,CAAC,CAsFjB;AAMD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,YAAY,EAAE,EAC7B,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,OAAO,EACzB,iBAAiB,EAAE,MAAM,EACzB,GAAG,EAAE,IAAI,CAAC,sBAAsB,EAAE,mBAAmB,GAAG,kBAAkB,GAAG,gBAAgB,CAAC,GAC7F,UAAU,CA4BZ"}
|