@chozzz/vargos 2.0.5 → 2.0.7
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/cli.js +5 -1
- package/dist/cli.js.map +1 -1
- package/dist/edge/mcp/index.d.ts +33 -0
- package/dist/edge/mcp/index.d.ts.map +1 -0
- package/dist/edge/mcp/index.js +217 -0
- package/dist/edge/mcp/index.js.map +1 -0
- package/dist/edge/webhooks/index.d.ts +33 -0
- package/dist/edge/webhooks/index.d.ts.map +1 -0
- package/dist/edge/webhooks/index.js +231 -0
- package/dist/edge/webhooks/index.js.map +1 -0
- package/dist/edge/webhooks/transform.d.ts +8 -0
- package/dist/edge/webhooks/transform.d.ts.map +1 -0
- package/dist/edge/webhooks/transform.js +29 -0
- package/dist/edge/webhooks/transform.js.map +1 -0
- package/dist/gateway/bus.d.ts +48 -0
- package/dist/gateway/bus.d.ts.map +1 -0
- package/dist/gateway/bus.js +2 -0
- package/dist/gateway/bus.js.map +1 -0
- package/dist/gateway/decorators.d.ts +40 -0
- package/dist/gateway/decorators.d.ts.map +1 -0
- package/dist/gateway/decorators.js +43 -0
- package/dist/gateway/decorators.js.map +1 -0
- package/dist/gateway/emitter.d.ts +42 -0
- package/dist/gateway/emitter.d.ts.map +1 -0
- package/dist/gateway/emitter.js +259 -0
- package/dist/gateway/emitter.js.map +1 -0
- package/dist/gateway/events.d.ts +343 -0
- package/dist/gateway/events.d.ts.map +1 -0
- package/dist/gateway/events.js +7 -0
- package/dist/gateway/events.js.map +1 -0
- package/dist/gateway/tcp-server.d.ts +7 -0
- package/dist/gateway/tcp-server.d.ts.map +1 -0
- package/dist/gateway/tcp-server.js +115 -0
- package/dist/gateway/tcp-server.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/scripts/migrate-cron-sessions.d.ts +10 -0
- package/dist/scripts/migrate-cron-sessions.d.ts.map +1 -0
- package/dist/scripts/migrate-cron-sessions.js +139 -0
- package/dist/scripts/migrate-cron-sessions.js.map +1 -0
- package/dist/scripts/seed.d.ts +2 -0
- package/dist/scripts/seed.d.ts.map +1 -0
- package/dist/scripts/seed.js +4 -0
- package/dist/scripts/seed.js.map +1 -0
- package/dist/services/agent/directives.d.ts +14 -0
- package/dist/services/agent/directives.d.ts.map +1 -0
- package/dist/services/agent/directives.js +32 -0
- package/dist/services/agent/directives.js.map +1 -0
- package/dist/services/agent/index.d.ts +104 -0
- package/dist/services/agent/index.d.ts.map +1 -0
- package/dist/services/agent/index.js +534 -0
- package/dist/services/agent/index.js.map +1 -0
- package/dist/services/agent/persona.d.ts +15 -0
- package/dist/services/agent/persona.d.ts.map +1 -0
- package/dist/services/agent/persona.js +63 -0
- package/dist/services/agent/persona.js.map +1 -0
- package/dist/services/agent/prompt-interpolate.d.ts +41 -0
- package/dist/services/agent/prompt-interpolate.d.ts.map +1 -0
- package/dist/services/agent/prompt-interpolate.js +102 -0
- package/dist/services/agent/prompt-interpolate.js.map +1 -0
- package/dist/services/agent/schema.d.ts +10 -0
- package/dist/services/agent/schema.d.ts.map +1 -0
- package/dist/services/agent/schema.js +5 -0
- package/dist/services/agent/schema.js.map +1 -0
- package/dist/services/agent/tools.d.ts +26 -0
- package/dist/services/agent/tools.d.ts.map +1 -0
- package/dist/services/agent/tools.js +85 -0
- package/dist/services/agent/tools.js.map +1 -0
- package/dist/services/channels/base-adapter.d.ts +61 -0
- package/dist/services/channels/base-adapter.d.ts.map +1 -0
- package/dist/services/channels/base-adapter.js +181 -0
- package/dist/services/channels/base-adapter.js.map +1 -0
- package/dist/services/channels/contracts.d.ts +75 -0
- package/dist/services/channels/contracts.d.ts.map +1 -0
- package/dist/services/channels/contracts.js +6 -0
- package/dist/services/channels/contracts.js.map +1 -0
- package/dist/services/channels/debounce.d.ts +22 -0
- package/dist/services/channels/debounce.d.ts.map +1 -0
- package/dist/services/channels/debounce.js +53 -0
- package/dist/services/channels/debounce.js.map +1 -0
- package/dist/services/channels/dedupe.d.ts +19 -0
- package/dist/services/channels/dedupe.d.ts.map +1 -0
- package/dist/services/channels/dedupe.js +52 -0
- package/dist/services/channels/dedupe.js.map +1 -0
- package/dist/services/channels/delivery.d.ts +12 -0
- package/dist/services/channels/delivery.d.ts.map +1 -0
- package/dist/services/channels/delivery.js +53 -0
- package/dist/services/channels/delivery.js.map +1 -0
- package/dist/services/channels/index.d.ts +53 -0
- package/dist/services/channels/index.d.ts.map +1 -0
- package/dist/services/channels/index.js +405 -0
- package/dist/services/channels/index.js.map +1 -0
- package/dist/services/channels/link-expand.d.ts +8 -0
- package/dist/services/channels/link-expand.d.ts.map +1 -0
- package/dist/services/channels/link-expand.js +28 -0
- package/dist/services/channels/link-expand.js.map +1 -0
- package/dist/services/channels/media-extract.d.ts +7 -0
- package/dist/services/channels/media-extract.d.ts.map +1 -0
- package/dist/services/channels/media-extract.js +31 -0
- package/dist/services/channels/media-extract.js.map +1 -0
- package/dist/services/channels/pipeline.d.ts +29 -0
- package/dist/services/channels/pipeline.d.ts.map +1 -0
- package/dist/services/channels/pipeline.js +120 -0
- package/dist/services/channels/pipeline.js.map +1 -0
- package/dist/services/channels/provider-loader.d.ts +7 -0
- package/dist/services/channels/provider-loader.d.ts.map +1 -0
- package/dist/services/channels/provider-loader.js +13 -0
- package/dist/services/channels/provider-loader.js.map +1 -0
- package/dist/services/channels/providers/telegram/adapter.d.ts +34 -0
- package/dist/services/channels/providers/telegram/adapter.d.ts.map +1 -0
- package/dist/services/channels/providers/telegram/adapter.js +278 -0
- package/dist/services/channels/providers/telegram/adapter.js.map +1 -0
- package/dist/services/channels/providers/telegram/index.d.ts +11 -0
- package/dist/services/channels/providers/telegram/index.d.ts.map +1 -0
- package/dist/services/channels/providers/telegram/index.js +11 -0
- package/dist/services/channels/providers/telegram/index.js.map +1 -0
- package/dist/services/channels/providers/telegram/normalizer.d.ts +12 -0
- package/dist/services/channels/providers/telegram/normalizer.d.ts.map +1 -0
- package/dist/services/channels/providers/telegram/normalizer.js +50 -0
- package/dist/services/channels/providers/telegram/normalizer.js.map +1 -0
- package/dist/services/channels/providers/telegram/types.d.ts +72 -0
- package/dist/services/channels/providers/telegram/types.d.ts.map +1 -0
- package/dist/services/channels/providers/telegram/types.js +3 -0
- package/dist/services/channels/providers/telegram/types.js.map +1 -0
- package/dist/services/channels/providers/whatsapp/adapter.d.ts +36 -0
- package/dist/services/channels/providers/whatsapp/adapter.d.ts.map +1 -0
- package/dist/services/channels/providers/whatsapp/adapter.js +261 -0
- package/dist/services/channels/providers/whatsapp/adapter.js.map +1 -0
- package/dist/services/channels/providers/whatsapp/index.d.ts +11 -0
- package/dist/services/channels/providers/whatsapp/index.d.ts.map +1 -0
- package/dist/services/channels/providers/whatsapp/index.js +11 -0
- package/dist/services/channels/providers/whatsapp/index.js.map +1 -0
- package/dist/services/channels/providers/whatsapp/normalizer.d.ts +11 -0
- package/dist/services/channels/providers/whatsapp/normalizer.d.ts.map +1 -0
- package/dist/services/channels/providers/whatsapp/normalizer.js +47 -0
- package/dist/services/channels/providers/whatsapp/normalizer.js.map +1 -0
- package/dist/services/channels/providers/whatsapp/session.d.ts +9 -0
- package/dist/services/channels/providers/whatsapp/session.d.ts.map +1 -0
- package/dist/services/channels/providers/whatsapp/session.js +118 -0
- package/dist/services/channels/providers/whatsapp/session.js.map +1 -0
- package/dist/services/channels/providers/whatsapp/types.d.ts +23 -0
- package/dist/services/channels/providers/whatsapp/types.d.ts.map +1 -0
- package/dist/services/channels/providers/whatsapp/types.js +3 -0
- package/dist/services/channels/providers/whatsapp/types.js.map +1 -0
- package/dist/services/channels/reconnect.d.ts +23 -0
- package/dist/services/channels/reconnect.d.ts.map +1 -0
- package/dist/services/channels/reconnect.js +32 -0
- package/dist/services/channels/reconnect.js.map +1 -0
- package/dist/services/channels/status-reactions.d.ts +27 -0
- package/dist/services/channels/status-reactions.d.ts.map +1 -0
- package/dist/services/channels/status-reactions.js +63 -0
- package/dist/services/channels/status-reactions.js.map +1 -0
- package/dist/services/channels/types.d.ts +16 -0
- package/dist/services/channels/types.d.ts.map +1 -0
- package/dist/services/channels/types.js +2 -0
- package/dist/services/channels/types.js.map +1 -0
- package/dist/services/channels/typing-state.d.ts +22 -0
- package/dist/services/channels/typing-state.d.ts.map +1 -0
- package/dist/services/channels/typing-state.js +88 -0
- package/dist/services/channels/typing-state.js.map +1 -0
- package/dist/services/config/index.d.ts +2426 -0
- package/dist/services/config/index.d.ts.map +1 -0
- package/dist/services/config/index.js +232 -0
- package/dist/services/config/index.js.map +1 -0
- package/dist/services/config/schemas/agent.d.ts +720 -0
- package/dist/services/config/schemas/agent.d.ts.map +1 -0
- package/dist/services/config/schemas/agent.js +86 -0
- package/dist/services/config/schemas/agent.js.map +1 -0
- package/dist/services/config/schemas/auth.d.ts +60 -0
- package/dist/services/config/schemas/auth.d.ts.map +1 -0
- package/dist/services/config/schemas/auth.js +18 -0
- package/dist/services/config/schemas/auth.js.map +1 -0
- package/dist/services/config/schemas/channels.d.ts +117 -0
- package/dist/services/config/schemas/channels.d.ts.map +1 -0
- package/dist/services/config/schemas/channels.js +22 -0
- package/dist/services/config/schemas/channels.js.map +1 -0
- package/dist/services/config/schemas/cron.d.ts +97 -0
- package/dist/services/config/schemas/cron.d.ts.map +1 -0
- package/dist/services/config/schemas/cron.js +18 -0
- package/dist/services/config/schemas/cron.js.map +1 -0
- package/dist/services/config/schemas/features.d.ts +43 -0
- package/dist/services/config/schemas/features.d.ts.map +1 -0
- package/dist/services/config/schemas/features.js +20 -0
- package/dist/services/config/schemas/features.js.map +1 -0
- package/dist/services/config/schemas/index.d.ts +24 -0
- package/dist/services/config/schemas/index.d.ts.map +1 -0
- package/dist/services/config/schemas/index.js +24 -0
- package/dist/services/config/schemas/index.js.map +1 -0
- package/dist/services/config/schemas/mcp.d.ts +31 -0
- package/dist/services/config/schemas/mcp.d.ts.map +1 -0
- package/dist/services/config/schemas/mcp.js +39 -0
- package/dist/services/config/schemas/mcp.js.map +1 -0
- package/dist/services/config/schemas/primitives.d.ts +13 -0
- package/dist/services/config/schemas/primitives.d.ts.map +1 -0
- package/dist/services/config/schemas/primitives.js +17 -0
- package/dist/services/config/schemas/primitives.js.map +1 -0
- package/dist/services/config/schemas/providers.d.ts +335 -0
- package/dist/services/config/schemas/providers.d.ts.map +1 -0
- package/dist/services/config/schemas/providers.js +27 -0
- package/dist/services/config/schemas/providers.js.map +1 -0
- package/dist/services/config/schemas/storage.d.ts +16 -0
- package/dist/services/config/schemas/storage.d.ts.map +1 -0
- package/dist/services/config/schemas/storage.js +9 -0
- package/dist/services/config/schemas/storage.js.map +1 -0
- package/dist/services/config/schemas/webhooks.d.ts +25 -0
- package/dist/services/config/schemas/webhooks.d.ts.map +1 -0
- package/dist/services/config/schemas/webhooks.js +12 -0
- package/dist/services/config/schemas/webhooks.js.map +1 -0
- package/dist/services/cron/index.d.ts +50 -0
- package/dist/services/cron/index.d.ts.map +1 -0
- package/dist/services/cron/index.js +460 -0
- package/dist/services/cron/index.js.map +1 -0
- package/dist/services/log/index.d.ts +14 -0
- package/dist/services/log/index.d.ts.map +1 -0
- package/dist/services/log/index.js +137 -0
- package/dist/services/log/index.js.map +1 -0
- package/dist/services/mcp-client/index.d.ts +37 -0
- package/dist/services/mcp-client/index.d.ts.map +1 -0
- package/dist/services/mcp-client/index.js +258 -0
- package/dist/services/mcp-client/index.js.map +1 -0
- package/dist/services/media/extract-document.d.ts +8 -0
- package/dist/services/media/extract-document.d.ts.map +1 -0
- package/dist/services/media/extract-document.js +85 -0
- package/dist/services/media/extract-document.js.map +1 -0
- package/dist/services/media/index.d.ts +21 -0
- package/dist/services/media/index.d.ts.map +1 -0
- package/dist/services/media/index.js +116 -0
- package/dist/services/media/index.js.map +1 -0
- package/dist/services/media/providers/anthropic.d.ts +6 -0
- package/dist/services/media/providers/anthropic.d.ts.map +1 -0
- package/dist/services/media/providers/anthropic.js +38 -0
- package/dist/services/media/providers/anthropic.js.map +1 -0
- package/dist/services/media/providers/index.d.ts +6 -0
- package/dist/services/media/providers/index.d.ts.map +1 -0
- package/dist/services/media/providers/index.js +15 -0
- package/dist/services/media/providers/index.js.map +1 -0
- package/dist/services/media/providers/openai.d.ts +6 -0
- package/dist/services/media/providers/openai.d.ts.map +1 -0
- package/dist/services/media/providers/openai.js +48 -0
- package/dist/services/media/providers/openai.js.map +1 -0
- package/dist/services/media/providers/provider.d.ts +5 -0
- package/dist/services/media/providers/provider.d.ts.map +1 -0
- package/dist/services/media/providers/provider.js +2 -0
- package/dist/services/media/providers/provider.js.map +1 -0
- package/dist/services/memory/chunker.d.ts +7 -0
- package/dist/services/memory/chunker.d.ts.map +1 -0
- package/dist/services/memory/chunker.js +46 -0
- package/dist/services/memory/chunker.js.map +1 -0
- package/dist/services/memory/context.d.ts +68 -0
- package/dist/services/memory/context.d.ts.map +1 -0
- package/dist/services/memory/context.js +223 -0
- package/dist/services/memory/context.js.map +1 -0
- package/dist/services/memory/embedding.d.ts +9 -0
- package/dist/services/memory/embedding.d.ts.map +1 -0
- package/dist/services/memory/embedding.js +49 -0
- package/dist/services/memory/embedding.js.map +1 -0
- package/dist/services/memory/index.d.ts +24 -0
- package/dist/services/memory/index.d.ts.map +1 -0
- package/dist/services/memory/index.js +140 -0
- package/dist/services/memory/index.js.map +1 -0
- package/dist/services/memory/session-indexer.d.ts +5 -0
- package/dist/services/memory/session-indexer.d.ts.map +1 -0
- package/dist/services/memory/session-indexer.js +62 -0
- package/dist/services/memory/session-indexer.js.map +1 -0
- package/dist/services/memory/sqlite-storage.d.ts +23 -0
- package/dist/services/memory/sqlite-storage.d.ts.map +1 -0
- package/dist/services/memory/sqlite-storage.js +75 -0
- package/dist/services/memory/sqlite-storage.js.map +1 -0
- package/dist/services/memory/types.d.ts +31 -0
- package/dist/services/memory/types.d.ts.map +1 -0
- package/dist/services/memory/types.js +2 -0
- package/dist/services/memory/types.js.map +1 -0
- package/dist/services/web/index.d.ts +9 -0
- package/dist/services/web/index.d.ts.map +1 -0
- package/dist/services/web/index.js +101 -0
- package/dist/services/web/index.js.map +1 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +9 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +2 -8
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt interpolation — replace template variables in prompts with actual paths/values.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - ${WORKSPACE_DIR} → ~/.vargos/workspace
|
|
6
|
+
* - ${DATA_DIR} → ~/.vargos (or $VARGOS_DATA_DIR)
|
|
7
|
+
* - ${SESSIONS_DIR} → ~/.vargos/sessions
|
|
8
|
+
* - ${CACHE_DIR} → ~/.cache/vargos
|
|
9
|
+
* - ${LOGS_DIR} → ~/.vargos/logs
|
|
10
|
+
* - ${CHANNELS_DIR} → ~/.vargos/channels
|
|
11
|
+
* - ${HOME} → user's home directory
|
|
12
|
+
* - ${PWD} → current working directory
|
|
13
|
+
* - ${SESSION_KEY}, ${CHANNEL_ID}, ${CHANNEL_TYPE}, ${CHAT_ID} → session identity
|
|
14
|
+
* - ${USER_ID}, ${USER_NAME}, ${USER_HANDLE} → message sender (from agent metadata)
|
|
15
|
+
* - ${BOT_ID}, ${BOT_NAME}, ${BOT_HANDLE} → bot identity (from agent metadata)
|
|
16
|
+
*
|
|
17
|
+
* Default values use bash-style syntax: ${VAR:-default}
|
|
18
|
+
* - Used when VAR is missing OR an empty string.
|
|
19
|
+
* - Default may be empty: ${VAR:-} resolves to '' if VAR is missing.
|
|
20
|
+
* - Default cannot contain '}' (closes the placeholder).
|
|
21
|
+
*
|
|
22
|
+
* Missing keys without a default fallback to the original ${KEY} placeholder
|
|
23
|
+
* and are logged as warnings.
|
|
24
|
+
*
|
|
25
|
+
* Usage:
|
|
26
|
+
* const prompt = 'Read ${WORKSPACE_DIR}/HEARTBEAT.md as ${BRAND:-Vargos}';
|
|
27
|
+
* const resolved = interpolatePrompt(prompt);
|
|
28
|
+
* // → 'Read /home/user/.vargos/workspace/HEARTBEAT.md as Vargos'
|
|
29
|
+
*/
|
|
30
|
+
export interface InterpolationResult {
|
|
31
|
+
prompt: string;
|
|
32
|
+
missing: string[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Interpolate prompt variables and return the resolved string.
|
|
36
|
+
* Missing variables (without a default) remain as ${KEY} placeholders and are
|
|
37
|
+
* logged as warnings. Context variables (e.g., from channel metadata) are
|
|
38
|
+
* merged into the template variables.
|
|
39
|
+
*/
|
|
40
|
+
export declare function interpolatePrompt(prompt: string, context?: Record<string, string>): string;
|
|
41
|
+
//# sourceMappingURL=prompt-interpolate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-interpolate.d.ts","sourceRoot":"","sources":["../../../services/agent/prompt-interpolate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AASH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAID;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAG1F"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt interpolation — replace template variables in prompts with actual paths/values.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - ${WORKSPACE_DIR} → ~/.vargos/workspace
|
|
6
|
+
* - ${DATA_DIR} → ~/.vargos (or $VARGOS_DATA_DIR)
|
|
7
|
+
* - ${SESSIONS_DIR} → ~/.vargos/sessions
|
|
8
|
+
* - ${CACHE_DIR} → ~/.cache/vargos
|
|
9
|
+
* - ${LOGS_DIR} → ~/.vargos/logs
|
|
10
|
+
* - ${CHANNELS_DIR} → ~/.vargos/channels
|
|
11
|
+
* - ${HOME} → user's home directory
|
|
12
|
+
* - ${PWD} → current working directory
|
|
13
|
+
* - ${SESSION_KEY}, ${CHANNEL_ID}, ${CHANNEL_TYPE}, ${CHAT_ID} → session identity
|
|
14
|
+
* - ${USER_ID}, ${USER_NAME}, ${USER_HANDLE} → message sender (from agent metadata)
|
|
15
|
+
* - ${BOT_ID}, ${BOT_NAME}, ${BOT_HANDLE} → bot identity (from agent metadata)
|
|
16
|
+
*
|
|
17
|
+
* Default values use bash-style syntax: ${VAR:-default}
|
|
18
|
+
* - Used when VAR is missing OR an empty string.
|
|
19
|
+
* - Default may be empty: ${VAR:-} resolves to '' if VAR is missing.
|
|
20
|
+
* - Default cannot contain '}' (closes the placeholder).
|
|
21
|
+
*
|
|
22
|
+
* Missing keys without a default fallback to the original ${KEY} placeholder
|
|
23
|
+
* and are logged as warnings.
|
|
24
|
+
*
|
|
25
|
+
* Usage:
|
|
26
|
+
* const prompt = 'Read ${WORKSPACE_DIR}/HEARTBEAT.md as ${BRAND:-Vargos}';
|
|
27
|
+
* const resolved = interpolatePrompt(prompt);
|
|
28
|
+
* // → 'Read /home/user/.vargos/workspace/HEARTBEAT.md as Vargos'
|
|
29
|
+
*/
|
|
30
|
+
import { getDataPaths } from '../../lib/paths.js';
|
|
31
|
+
import { createLogger } from '../../lib/logger.js';
|
|
32
|
+
import os from 'node:os';
|
|
33
|
+
import process from 'node:process';
|
|
34
|
+
const log = createLogger('interpolate');
|
|
35
|
+
const PATTERN = /\$\{([A-Z_]+)(?::-?([^}]*))?\}/g;
|
|
36
|
+
/**
|
|
37
|
+
* Interpolate prompt variables and return the resolved string.
|
|
38
|
+
* Missing variables (without a default) remain as ${KEY} placeholders and are
|
|
39
|
+
* logged as warnings. Context variables (e.g., from channel metadata) are
|
|
40
|
+
* merged into the template variables.
|
|
41
|
+
*/
|
|
42
|
+
export function interpolatePrompt(prompt, context) {
|
|
43
|
+
const { prompt: resolved } = interpolatePromptWithMissing(prompt, context);
|
|
44
|
+
return resolved;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Interpolate and return both result and missing variable list.
|
|
48
|
+
* Used when you need to know what failed to interpolate.
|
|
49
|
+
*/
|
|
50
|
+
function interpolatePromptWithMissing(prompt, context) {
|
|
51
|
+
const paths = getDataPaths();
|
|
52
|
+
const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
53
|
+
const variables = {
|
|
54
|
+
DATA_DIR: paths.dataDir,
|
|
55
|
+
WORKSPACE_DIR: paths.workspaceDir,
|
|
56
|
+
SESSIONS_DIR: paths.sessionsDir,
|
|
57
|
+
CRON_DIR: paths.cronDir,
|
|
58
|
+
CACHE_DIR: paths.cacheDir,
|
|
59
|
+
LOGS_DIR: paths.logsDir,
|
|
60
|
+
CHANNELS_DIR: paths.channelsDir,
|
|
61
|
+
HOME: os.homedir(),
|
|
62
|
+
PWD: process.cwd(),
|
|
63
|
+
CURRENT_DATE: new Date().toLocaleString(undefined, {
|
|
64
|
+
timeZone: currentTimezone,
|
|
65
|
+
year: 'numeric', month: 'long', day: '2-digit',
|
|
66
|
+
hour: '2-digit', minute: '2-digit', second: '2-digit',
|
|
67
|
+
hour12: false,
|
|
68
|
+
timeZoneName: 'short',
|
|
69
|
+
}),
|
|
70
|
+
CURRENT_TIMEZONE: currentTimezone,
|
|
71
|
+
// Channel context variables — fall back to 'unknown' when not provided.
|
|
72
|
+
// Handles default to '' so templates can override with ${VAR:-fallback}.
|
|
73
|
+
CHANNEL_TYPE: context?.CHANNEL_TYPE || 'unknown',
|
|
74
|
+
CHANNEL_ID: context?.CHANNEL_ID || 'unknown',
|
|
75
|
+
CHAT_ID: context?.CHAT_ID || 'unknown',
|
|
76
|
+
USER_ID: context?.USER_ID || 'unknown',
|
|
77
|
+
USER_NAME: context?.USER_NAME || 'unknown',
|
|
78
|
+
USER_HANDLE: context?.USER_HANDLE || '',
|
|
79
|
+
BOT_ID: context?.BOT_ID || 'unknown',
|
|
80
|
+
BOT_NAME: context?.BOT_NAME || 'unknown',
|
|
81
|
+
BOT_HANDLE: context?.BOT_HANDLE || '',
|
|
82
|
+
// Just in case context is provided, but not all variables are present.
|
|
83
|
+
...context,
|
|
84
|
+
};
|
|
85
|
+
const missing = [];
|
|
86
|
+
const result = prompt.replace(PATTERN, (full, key, defaultValue) => {
|
|
87
|
+
const value = variables[key];
|
|
88
|
+
if (value !== undefined && value !== '') {
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
if (defaultValue !== undefined) {
|
|
92
|
+
return defaultValue;
|
|
93
|
+
}
|
|
94
|
+
missing.push(key);
|
|
95
|
+
return full;
|
|
96
|
+
});
|
|
97
|
+
if (missing.length > 0) {
|
|
98
|
+
log.warn(`Missing interpolation keys: ${missing.join(', ')}`);
|
|
99
|
+
}
|
|
100
|
+
return { prompt: result, missing };
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=prompt-interpolate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-interpolate.js","sourceRoot":"","sources":["../../../services/agent/prompt-interpolate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../services/agent/schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAEhE,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,GAAG,CAAC;IACT,MAAM,EAAE,SAAS,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../services/agent/schema.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent — Bus Tools Integration
|
|
3
|
+
*
|
|
4
|
+
* Converts bus callable events with @register decorators into PiAgent ToolDefinitions.
|
|
5
|
+
*
|
|
6
|
+
* Session key injection:
|
|
7
|
+
* - Every tool closes over the parent sessionKey from getCustomTools().
|
|
8
|
+
* - For agent.execute specifically, sessionKey is injected as ':subagent' suffix
|
|
9
|
+
* so the agent doesn't need to (and can't) provide its own session key.
|
|
10
|
+
* - Other tools inherit the parent sessionKey for context-aware operations
|
|
11
|
+
* (e.g. channel.send delivers to the right recipient).
|
|
12
|
+
*
|
|
13
|
+
* Schema vs EventMap gap:
|
|
14
|
+
* - The agent.execute schema omits sessionKey (it's injected here before bus.call).
|
|
15
|
+
* - EventMap['agent.execute']['params'] still declares sessionKey as required because
|
|
16
|
+
* direct callers (channels, cron, webhooks, TCP clients) must provide it.
|
|
17
|
+
* - This mismatch is intentional — the tool wrapper is the bridge between the agent's
|
|
18
|
+
* view (no sessionKey) and the service's view (sessionKey required).
|
|
19
|
+
*/
|
|
20
|
+
import type { ToolDefinition } from '@mariozechner/pi-coding-agent';
|
|
21
|
+
import type { Bus } from '../../gateway/bus.js';
|
|
22
|
+
/**
|
|
23
|
+
* Create PiAgent custom tools from bus callable events.
|
|
24
|
+
*/
|
|
25
|
+
export declare function createCustomTools(sessionKey: string, bus: Bus): Promise<ToolDefinition[]>;
|
|
26
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../services/agent/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEpE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAgFhD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAK/F"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent — Bus Tools Integration
|
|
3
|
+
*
|
|
4
|
+
* Converts bus callable events with @register decorators into PiAgent ToolDefinitions.
|
|
5
|
+
*
|
|
6
|
+
* Session key injection:
|
|
7
|
+
* - Every tool closes over the parent sessionKey from getCustomTools().
|
|
8
|
+
* - For agent.execute specifically, sessionKey is injected as ':subagent' suffix
|
|
9
|
+
* so the agent doesn't need to (and can't) provide its own session key.
|
|
10
|
+
* - Other tools inherit the parent sessionKey for context-aware operations
|
|
11
|
+
* (e.g. channel.send delivers to the right recipient).
|
|
12
|
+
*
|
|
13
|
+
* Schema vs EventMap gap:
|
|
14
|
+
* - The agent.execute schema omits sessionKey (it's injected here before bus.call).
|
|
15
|
+
* - EventMap['agent.execute']['params'] still declares sessionKey as required because
|
|
16
|
+
* direct callers (channels, cron, webhooks, TCP clients) must provide it.
|
|
17
|
+
* - This mismatch is intentional — the tool wrapper is the bridge between the agent's
|
|
18
|
+
* view (no sessionKey) and the service's view (sessionKey required).
|
|
19
|
+
*/
|
|
20
|
+
import { createLogger } from '../../lib/logger.js';
|
|
21
|
+
import { isToolEvent } from '../../gateway/emitter.js';
|
|
22
|
+
import { toMessage } from '../../lib/error.js';
|
|
23
|
+
import { appendError } from '../../lib/error-store.js';
|
|
24
|
+
const log = createLogger('agent-tools');
|
|
25
|
+
const LARGE_RESULT_TOKEN_THRESHOLD = 5_000;
|
|
26
|
+
/**
|
|
27
|
+
* Wrap a bus event as a PiAgent ToolDefinition.
|
|
28
|
+
*/
|
|
29
|
+
function wrapEventAsToolDefinition(eventName, description, parameters, sessionKey, bus) {
|
|
30
|
+
// Sanitize tool name for anthropic: replace dots with dashes (e.g., agent.execute → agent-execute)
|
|
31
|
+
const sanitizedName = eventName.replace(/\./g, '-');
|
|
32
|
+
return {
|
|
33
|
+
name: sanitizedName,
|
|
34
|
+
label: eventName,
|
|
35
|
+
description,
|
|
36
|
+
parameters: parameters,
|
|
37
|
+
execute: async (_toolCallId, params, _signal, _onUpdate,
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
39
|
+
_ctx) => {
|
|
40
|
+
const paramsObj = params;
|
|
41
|
+
log.debug(`${eventName}: ${Object.entries(paramsObj).map(([k, v]) => `${k}=${JSON.stringify(v).slice(0, 100)}`).join(', ')}`);
|
|
42
|
+
try {
|
|
43
|
+
// Auto-inject sessionKey for agent.execute subagent calls.
|
|
44
|
+
// The agent.execute schema omits sessionKey (it's always injected here).
|
|
45
|
+
if (eventName === 'agent.execute') {
|
|
46
|
+
paramsObj.sessionKey = `${sessionKey}:subagent`;
|
|
47
|
+
}
|
|
48
|
+
const result = await bus.call(eventName, paramsObj);
|
|
49
|
+
let resultText = '';
|
|
50
|
+
if (result && typeof result === 'object') {
|
|
51
|
+
resultText = JSON.stringify(result).slice(0, 10_000);
|
|
52
|
+
}
|
|
53
|
+
else if (result !== undefined && result !== null) {
|
|
54
|
+
resultText = String(result).slice(0, 10_000);
|
|
55
|
+
}
|
|
56
|
+
const resultTokens = Math.ceil(resultText.length / 4);
|
|
57
|
+
log.debug(`${eventName} ok (${resultTokens} tokens): ${resultText.slice(0, 200).replace(/\n/g, ' ')}${resultText.length > 200 ? '...' : ''}`);
|
|
58
|
+
const content = [{ type: 'text', text: resultText }];
|
|
59
|
+
if (resultTokens > LARGE_RESULT_TOKEN_THRESHOLD) {
|
|
60
|
+
const warning = `⚠ Large tool response (~${(resultTokens / 1000).toFixed(1)}k tokens). Extract what you need and avoid additional large calls.\n\n`;
|
|
61
|
+
content[0] = { type: 'text', text: warning + content[0].text };
|
|
62
|
+
log.info(`${eventName}: large result warning (${resultTokens} tokens)`);
|
|
63
|
+
}
|
|
64
|
+
return { content, details: {} };
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
const message = toMessage(err);
|
|
68
|
+
log.debug(`${eventName} error: ${message}`);
|
|
69
|
+
appendError({ tool: eventName, sessionKey, message }).catch(() => { });
|
|
70
|
+
return {
|
|
71
|
+
content: [{ type: 'text', text: `Error: ${message}` }],
|
|
72
|
+
details: { error: message },
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Create PiAgent custom tools from bus callable events.
|
|
80
|
+
*/
|
|
81
|
+
export async function createCustomTools(sessionKey, bus) {
|
|
82
|
+
const metadata = await bus.call('bus.search', {});
|
|
83
|
+
return metadata.filter(isToolEvent).map(m => wrapEventAsToolDefinition(m.event, m.description, m.schema?.params || {}, sessionKey, bus));
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../services/agent/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base channel adapter — shared logic for typing indicators, debounce, dedupe, and media handling.
|
|
3
|
+
*/
|
|
4
|
+
import type { ChannelType, OnInboundMessageFn, InboundMediaSource } from './types.js';
|
|
5
|
+
import type { ChannelAdapter, NormalizedInboundMessage, AdapterDeps } from './contracts.js';
|
|
6
|
+
import type { ChannelStatus } from '../../gateway/events.js';
|
|
7
|
+
import { createMessageDebouncer } from './debounce.js';
|
|
8
|
+
import { TypingStateManager } from './typing-state.js';
|
|
9
|
+
export declare abstract class BaseChannelAdapter implements ChannelAdapter {
|
|
10
|
+
abstract readonly type: ChannelType;
|
|
11
|
+
readonly instanceId: string;
|
|
12
|
+
status: ChannelStatus;
|
|
13
|
+
protected dedupe: import("./dedupe.js").DedupeCache;
|
|
14
|
+
protected debouncer: ReturnType<typeof createMessageDebouncer>;
|
|
15
|
+
protected onInboundMessage?: OnInboundMessageFn;
|
|
16
|
+
protected typingState: TypingStateManager;
|
|
17
|
+
protected readonly log: {
|
|
18
|
+
debug: (msg: string, data?: import("../config/schemas/primitives.js").Json) => void;
|
|
19
|
+
info: (msg: string, data?: import("../config/schemas/primitives.js").Json) => void;
|
|
20
|
+
warn: (msg: string, data?: import("../config/schemas/primitives.js").Json) => void;
|
|
21
|
+
error: (msg: string, data?: import("../config/schemas/primitives.js").Json) => void;
|
|
22
|
+
};
|
|
23
|
+
protected debounceMs: number;
|
|
24
|
+
protected latestMessageId: Map<string, string>;
|
|
25
|
+
protected transcribeFn?: (filePath: string) => Promise<string>;
|
|
26
|
+
protected describeFn?: (filePath: string) => Promise<string>;
|
|
27
|
+
protected extractFn?: (filePath: string, mimeType: string) => Promise<{
|
|
28
|
+
text: string;
|
|
29
|
+
}>;
|
|
30
|
+
constructor(instanceId: string, _channelType: ChannelType, deps: AdapterDeps, debounceMs?: number);
|
|
31
|
+
protected createDebouncer(): ReturnType<typeof createMessageDebouncer>;
|
|
32
|
+
abstract start(): Promise<void>;
|
|
33
|
+
abstract stop(): Promise<void>;
|
|
34
|
+
abstract send(sessionKey: string, text: string): Promise<void>;
|
|
35
|
+
protected abstract sendTypingIndicator(sessionKey: string): Promise<void>;
|
|
36
|
+
/** Extract userId from sessionKey for adapter-specific use. */
|
|
37
|
+
extractUserId(sessionKey: string): string;
|
|
38
|
+
/** Get latest message ID for a user (used for reactions). */
|
|
39
|
+
extractLatestMessageId(userId: string): string | null | undefined;
|
|
40
|
+
startTyping(sessionKey: string, inToolExecution?: boolean): void;
|
|
41
|
+
resumeTyping(sessionKey: string): void;
|
|
42
|
+
stopTyping(sessionKey: string, final?: boolean): void;
|
|
43
|
+
protected handleBatch(id: string, messages: string[], normalizedMsg?: NormalizedInboundMessage): Promise<void>;
|
|
44
|
+
protected buildSessionKey(id: string): string;
|
|
45
|
+
protected cleanupTimers(): void;
|
|
46
|
+
/** Override to handle media resolution for your channel. */
|
|
47
|
+
protected resolveMedia(_msg: unknown): Promise<InboundMediaSource | null>;
|
|
48
|
+
/**
|
|
49
|
+
* Process inbound media message.
|
|
50
|
+
* @param msg - Raw message from channel
|
|
51
|
+
* @param sessionKey - Session key (channel:userId)
|
|
52
|
+
* @param normalizedMsg - Normalized message with flags (skipAgent, etc)
|
|
53
|
+
* @param route - Function to route processed text to onInboundMessage
|
|
54
|
+
*/
|
|
55
|
+
protected processInboundMedia(msg: unknown, sessionKey: string, normalizedMsg: NormalizedInboundMessage, route: (text: string) => Promise<void>): Promise<{
|
|
56
|
+
caption: string;
|
|
57
|
+
savedPath: string;
|
|
58
|
+
mimeType: string;
|
|
59
|
+
}>;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=base-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-adapter.d.ts","sourceRoot":"","sources":["../../../services/channels/base-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base channel adapter — shared logic for typing indicators, debounce, dedupe, and media handling.
|
|
3
|
+
*/
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { createDedupeCache } from './dedupe.js';
|
|
6
|
+
import { createMessageDebouncer } from './debounce.js';
|
|
7
|
+
import { createLogger } from '../../lib/logger.js';
|
|
8
|
+
import { toMessage } from '../../lib/error.js';
|
|
9
|
+
import { parseSessionKey } from '../../lib/subagent.js';
|
|
10
|
+
import { TypingStateManager } from './typing-state.js';
|
|
11
|
+
import { saveMedia } from '../../lib/media.js';
|
|
12
|
+
import { getDataPaths } from '../../lib/paths.js';
|
|
13
|
+
const MEDIA_TYPE_LABELS = {
|
|
14
|
+
audio: 'Voice message',
|
|
15
|
+
video: 'Video message',
|
|
16
|
+
document: 'Document',
|
|
17
|
+
sticker: 'Sticker',
|
|
18
|
+
};
|
|
19
|
+
export class BaseChannelAdapter {
|
|
20
|
+
instanceId;
|
|
21
|
+
status = 'disconnected';
|
|
22
|
+
dedupe = createDedupeCache({ ttlMs: 120_000 });
|
|
23
|
+
debouncer;
|
|
24
|
+
onInboundMessage;
|
|
25
|
+
typingState = new TypingStateManager({ ttlMs: 120_000, failureLimit: 3 });
|
|
26
|
+
log;
|
|
27
|
+
debounceMs;
|
|
28
|
+
latestMessageId = new Map();
|
|
29
|
+
transcribeFn;
|
|
30
|
+
describeFn;
|
|
31
|
+
extractFn;
|
|
32
|
+
constructor(instanceId, _channelType, deps, debounceMs) {
|
|
33
|
+
this.instanceId = instanceId;
|
|
34
|
+
this.onInboundMessage = deps.onInbound;
|
|
35
|
+
this.transcribeFn = deps.transcribe;
|
|
36
|
+
this.describeFn = deps.describe;
|
|
37
|
+
this.extractFn = deps.extract;
|
|
38
|
+
this.log = createLogger(instanceId);
|
|
39
|
+
this.debounceMs = debounceMs ?? 2000;
|
|
40
|
+
this.debouncer = this.createDebouncer();
|
|
41
|
+
}
|
|
42
|
+
createDebouncer() {
|
|
43
|
+
return createMessageDebouncer((id, messages, normalizedMsg) => {
|
|
44
|
+
this.handleBatch(id, messages, normalizedMsg).catch((err) => {
|
|
45
|
+
this.log.error('handleBatch error', { id, error: toMessage(err) });
|
|
46
|
+
});
|
|
47
|
+
}, { delayMs: this.debounceMs });
|
|
48
|
+
}
|
|
49
|
+
/** Extract userId from sessionKey for adapter-specific use. */
|
|
50
|
+
extractUserId(sessionKey) {
|
|
51
|
+
const { id } = parseSessionKey(sessionKey);
|
|
52
|
+
return id;
|
|
53
|
+
}
|
|
54
|
+
/** Get latest message ID for a user (used for reactions). */
|
|
55
|
+
extractLatestMessageId(userId) {
|
|
56
|
+
return this.latestMessageId.get(userId);
|
|
57
|
+
}
|
|
58
|
+
startTyping(sessionKey, inToolExecution = false) {
|
|
59
|
+
this.typingState.start(sessionKey, () => this.sendTypingIndicator(sessionKey), inToolExecution);
|
|
60
|
+
}
|
|
61
|
+
resumeTyping(sessionKey) {
|
|
62
|
+
this.typingState.resume(sessionKey, () => this.sendTypingIndicator(sessionKey));
|
|
63
|
+
}
|
|
64
|
+
stopTyping(sessionKey, final = true) {
|
|
65
|
+
this.typingState.stop(sessionKey, final);
|
|
66
|
+
}
|
|
67
|
+
async handleBatch(id, messages, normalizedMsg) {
|
|
68
|
+
if (!this.onInboundMessage) {
|
|
69
|
+
this.log.error('No inbound message handler');
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (!normalizedMsg) {
|
|
73
|
+
this.log.error('No normalized message provided for batch');
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const text = messages.join('\n');
|
|
77
|
+
this.log.info(`batch for ${this.instanceId}:${id}: "${text.slice(0, 80)}"`);
|
|
78
|
+
await this.onInboundMessage(this.buildSessionKey(id), { ...normalizedMsg, text });
|
|
79
|
+
}
|
|
80
|
+
buildSessionKey(id) {
|
|
81
|
+
return `${this.instanceId}:${id}`;
|
|
82
|
+
}
|
|
83
|
+
cleanupTimers() {
|
|
84
|
+
this.debouncer.flushAll();
|
|
85
|
+
this.typingState.cleanup();
|
|
86
|
+
}
|
|
87
|
+
/** Override to handle media resolution for your channel. */
|
|
88
|
+
async resolveMedia(_msg) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Process inbound media message.
|
|
93
|
+
* @param msg - Raw message from channel
|
|
94
|
+
* @param sessionKey - Session key (channel:userId)
|
|
95
|
+
* @param normalizedMsg - Normalized message with flags (skipAgent, etc)
|
|
96
|
+
* @param route - Function to route processed text to onInboundMessage
|
|
97
|
+
*/
|
|
98
|
+
async processInboundMedia(msg, sessionKey, normalizedMsg, route) {
|
|
99
|
+
const source = await this.resolveMedia(msg);
|
|
100
|
+
const defaultReturn = { caption: '', savedPath: '', mimeType: '' };
|
|
101
|
+
if (!source)
|
|
102
|
+
return defaultReturn;
|
|
103
|
+
const { buffer, mimeType, mediaType, caption, duration } = source;
|
|
104
|
+
const mediaDir = path.join(getDataPaths().dataDir, 'media');
|
|
105
|
+
const savedPath = await saveMedia({ buffer, sessionKey, mimeType, mediaDir });
|
|
106
|
+
// Skip transcription for messages agent won't process (e.g., group mentions)
|
|
107
|
+
if (normalizedMsg.skipAgent) {
|
|
108
|
+
const label = MEDIA_TYPE_LABELS[mediaType] ?? 'Media';
|
|
109
|
+
const durationSuffix = duration != null ? `, ${duration}s` : '';
|
|
110
|
+
const fallbackCaption = caption || `[${label}${durationSuffix}]`;
|
|
111
|
+
await route(`${fallbackCaption}\n\n[${label} saved: ${savedPath}]`);
|
|
112
|
+
return {
|
|
113
|
+
caption: fallbackCaption,
|
|
114
|
+
savedPath,
|
|
115
|
+
mimeType
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
if (mediaType === 'image') {
|
|
119
|
+
if (this.describeFn) {
|
|
120
|
+
try {
|
|
121
|
+
const description = await this.describeFn(savedPath);
|
|
122
|
+
await route(`${description}\n\n[Image described from: ${savedPath}]`);
|
|
123
|
+
return {
|
|
124
|
+
caption: description,
|
|
125
|
+
savedPath,
|
|
126
|
+
mimeType
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
this.log.warn(`Image description failed: ${err}. Falling back to caption.`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const text = caption || 'User sent an image.';
|
|
134
|
+
await route(`${text}\n\n[Image saved: ${savedPath}]`);
|
|
135
|
+
return {
|
|
136
|
+
caption: text,
|
|
137
|
+
savedPath,
|
|
138
|
+
mimeType
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
if (mediaType === 'audio' && this.transcribeFn) {
|
|
142
|
+
try {
|
|
143
|
+
const transcription = await this.transcribeFn(savedPath);
|
|
144
|
+
await route(`${transcription}\n\n[Audio transcribed from: ${savedPath}]`);
|
|
145
|
+
return {
|
|
146
|
+
caption: transcription,
|
|
147
|
+
savedPath,
|
|
148
|
+
mimeType
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
this.log.warn(`Audio transcription failed: ${err}. Falling back to file path.`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (mediaType === 'document' && this.extractFn) {
|
|
156
|
+
try {
|
|
157
|
+
const { text } = await this.extractFn(savedPath, mimeType);
|
|
158
|
+
await route(`${text}\n\n[Document extracted from: ${savedPath}]`);
|
|
159
|
+
return {
|
|
160
|
+
caption: text,
|
|
161
|
+
savedPath,
|
|
162
|
+
mimeType
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
this.log.warn(`Document extraction failed: ${err}. Falling back to file path.`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Default handling for audio (no transcription), documents (no extraction), or other media types
|
|
170
|
+
const label = MEDIA_TYPE_LABELS[mediaType] ?? 'Media';
|
|
171
|
+
const durationSuffix = duration != null ? `, ${duration}s` : '';
|
|
172
|
+
const fallbackCaption = caption || `[${label}${durationSuffix}]`;
|
|
173
|
+
await route(`${fallbackCaption}\n\n[${label} saved: ${savedPath}]`);
|
|
174
|
+
return {
|
|
175
|
+
caption: fallbackCaption,
|
|
176
|
+
savedPath,
|
|
177
|
+
mimeType,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=base-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-adapter.js","sourceRoot":"","sources":["../../../services/channels/base-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel adapter contracts — defines what every channel provider must implement.
|
|
3
|
+
* These interfaces form the boundary between core policy and adapter implementations.
|
|
4
|
+
*/
|
|
5
|
+
import type { ChannelStatus } from '../../gateway/events.js';
|
|
6
|
+
import type { ChannelEntry } from '../config/schemas/channels.js';
|
|
7
|
+
import type { ChannelType, InboundMediaSource } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Required interface all channel adapters must implement.
|
|
10
|
+
* Core calls these methods; adapters call onInboundMessage callback.
|
|
11
|
+
*/
|
|
12
|
+
export interface ChannelAdapter {
|
|
13
|
+
readonly instanceId: string;
|
|
14
|
+
readonly type: ChannelType;
|
|
15
|
+
readonly status: ChannelStatus;
|
|
16
|
+
start(): Promise<void>;
|
|
17
|
+
stop(): Promise<void>;
|
|
18
|
+
send(sessionKey: string, text: string): Promise<void>;
|
|
19
|
+
startTyping(sessionKey: string, withToolFlag: boolean): void;
|
|
20
|
+
stopTyping(sessionKey: string, final?: boolean): void;
|
|
21
|
+
resumeTyping(sessionKey: string): void;
|
|
22
|
+
extractLatestMessageId(userId: string): string | null | undefined;
|
|
23
|
+
sendMedia?: (sessionKey: string, filePath: string, mimeType: string, caption?: string) => Promise<void>;
|
|
24
|
+
react?: (sessionKey: string, messageId: string, emoji: string) => Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Adapter dependencies — passed during construction.
|
|
28
|
+
* Unifies callback injection into a single parameter.
|
|
29
|
+
*/
|
|
30
|
+
export interface AdapterDeps {
|
|
31
|
+
onInbound: OnInboundMessageFn;
|
|
32
|
+
transcribe?: (filePath: string) => Promise<string>;
|
|
33
|
+
describe?: (filePath: string) => Promise<string>;
|
|
34
|
+
extract?: (filePath: string, mimeType: string) => Promise<{
|
|
35
|
+
text: string;
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Provider pattern: factory for creating channel adapters.
|
|
40
|
+
* Generic over the channel entry type for type-safe config passing.
|
|
41
|
+
*/
|
|
42
|
+
export interface ChannelProvider<TEntry extends ChannelEntry = ChannelEntry> {
|
|
43
|
+
readonly type: TEntry['type'];
|
|
44
|
+
createAdapter(instanceId: string, config: TEntry, deps: AdapterDeps): Promise<ChannelAdapter>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Canonical inbound message shape after normalization.
|
|
48
|
+
* All adapters emit this (via normalizers), core policy handles this.
|
|
49
|
+
*/
|
|
50
|
+
export interface NormalizedInboundMessage {
|
|
51
|
+
messageId: string;
|
|
52
|
+
fromUserId: string;
|
|
53
|
+
fromUser: string;
|
|
54
|
+
fromUserHandle?: string;
|
|
55
|
+
chatType: 'private' | 'group';
|
|
56
|
+
isMentioned: boolean;
|
|
57
|
+
channelType: string;
|
|
58
|
+
botUserId?: string;
|
|
59
|
+
botName?: string;
|
|
60
|
+
botHandle?: string;
|
|
61
|
+
skipAgent: boolean;
|
|
62
|
+
text?: string;
|
|
63
|
+
media?: InboundMediaSource;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Callback signature for inbound messages.
|
|
67
|
+
* Adapters call this when a message arrives.
|
|
68
|
+
*/
|
|
69
|
+
export type OnInboundMessageFn = (sessionKey: string, normalizedMessage: NormalizedInboundMessage) => Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Normalizer function: adapter-specific message → canonical NormalizedInboundMessage.
|
|
72
|
+
* Each adapter has a normalizer that handles its raw message type.
|
|
73
|
+
*/
|
|
74
|
+
export type MessageNormalizer<T> = (msg: T, botId: string) => NormalizedInboundMessage | null;
|
|
75
|
+
//# sourceMappingURL=contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../services/channels/contracts.ts"],"names":[],"mappings":"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"}
|