botinabox 2.9.1 → 2.9.3
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 +2 -1
- package/bin/botinabox.mjs +1 -1
- package/dist/channels/discord/adapter.d.ts +32 -0
- package/dist/channels/discord/inbound.d.ts +25 -0
- package/dist/channels/discord/index.d.ts +8 -84
- package/dist/channels/discord/models.d.ts +8 -0
- package/dist/channels/discord/outbound.d.ts +14 -0
- package/dist/channels/slack/adapter.d.ts +33 -0
- package/dist/channels/slack/bolt-adapter.d.ts +31 -0
- package/dist/channels/slack/enrichers/enrich.d.ts +12 -0
- package/dist/channels/slack/enrichers/image-enricher.d.ts +10 -0
- package/dist/channels/slack/enrichers/index.d.ts +4 -0
- package/dist/channels/slack/enrichers/pdf-enricher.d.ts +8 -0
- package/dist/channels/slack/enrichers/types.d.ts +33 -0
- package/dist/channels/slack/inbound.d.ts +59 -0
- package/dist/channels/slack/index.d.ts +13 -252
- package/dist/channels/slack/media-type.d.ts +14 -0
- package/dist/channels/slack/models.d.ts +9 -0
- package/dist/channels/slack/outbound.d.ts +12 -0
- package/dist/channels/slack/transcribe.d.ts +41 -0
- package/dist/channels/webhook/adapter.d.ts +23 -0
- package/dist/channels/webhook/hmac.d.ts +13 -0
- package/dist/channels/webhook/index.d.ts +7 -70
- package/dist/channels/webhook/models.d.ts +9 -0
- package/dist/channels/webhook/server.d.ts +20 -0
- package/dist/cli/templates/config.yml.d.ts +7 -0
- package/dist/cli/templates/env.d.ts +1 -0
- package/dist/cli/templates/index.ts.d.ts +2 -0
- package/dist/cli/templates/package.json.d.ts +5 -0
- package/dist/cli.d.ts +1 -3
- package/dist/connectors/google/calendar-connector.d.ts +40 -0
- package/dist/connectors/google/drive-connector.d.ts +43 -0
- package/dist/connectors/google/drive-read.d.ts +81 -0
- package/dist/connectors/google/gmail-connector.d.ts +42 -0
- package/dist/connectors/google/index.d.ts +10 -369
- package/dist/connectors/google/oauth.d.ts +48 -0
- package/dist/connectors/google/types.d.ts +110 -0
- package/dist/core/chat/auto-discovery.d.ts +16 -0
- package/dist/core/chat/channel-registry.d.ts +45 -0
- package/dist/core/chat/chat-pipeline-v2.d.ts +138 -0
- package/dist/core/chat/chat-pipeline.d.ts +116 -0
- package/dist/core/chat/chat-responder.d.ts +94 -0
- package/dist/core/chat/formatter.d.ts +11 -0
- package/dist/core/chat/index.d.ts +26 -0
- package/dist/core/chat/message-interpreter.d.ts +91 -0
- package/dist/core/chat/message-store.d.ts +71 -0
- package/dist/core/chat/notification-queue.d.ts +34 -0
- package/dist/core/chat/pipeline.d.ts +38 -0
- package/dist/core/chat/policies.d.ts +16 -0
- package/dist/core/chat/routing.d.ts +17 -0
- package/dist/core/chat/session-key.d.ts +30 -0
- package/dist/core/chat/session-manager.d.ts +17 -0
- package/dist/core/chat/text-chunker.d.ts +9 -0
- package/dist/core/chat/triage-router.d.ts +75 -0
- package/dist/core/chat/types.d.ts +5 -0
- package/dist/core/config/defaults.d.ts +2 -0
- package/dist/core/config/index.d.ts +6 -0
- package/dist/core/config/interpolate.d.ts +5 -0
- package/dist/core/config/loader.d.ts +24 -0
- package/dist/core/config/schema.d.ts +5 -0
- package/dist/core/data/context-builder.d.ts +27 -0
- package/dist/core/data/core-entity-contexts.d.ts +14 -0
- package/dist/core/data/core-migrations.d.ts +5 -0
- package/dist/core/data/core-schema.d.ts +6 -0
- package/dist/core/data/data-store.d.ts +67 -0
- package/dist/core/data/domain-entity-contexts.d.ts +35 -0
- package/dist/core/data/domain-schema.d.ts +36 -0
- package/dist/core/data/index.d.ts +8 -0
- package/dist/core/data/types.d.ts +111 -0
- package/dist/core/hooks/hook-bus.d.ts +24 -0
- package/dist/core/hooks/index.d.ts +2 -0
- package/dist/core/hooks/types.d.ts +19 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/llm/auto-discovery.d.ts +11 -0
- package/dist/core/llm/cost-tracker.d.ts +6 -0
- package/dist/core/llm/default-llm-call.d.ts +35 -0
- package/dist/core/llm/index.d.ts +6 -0
- package/dist/core/llm/model-router.d.ts +25 -0
- package/dist/core/llm/provider-registry.d.ts +9 -0
- package/dist/core/llm/types.d.ts +2 -0
- package/dist/core/orchestrator/adapters/api-adapter.d.ts +34 -0
- package/dist/core/orchestrator/adapters/cli-adapter.d.ts +62 -0
- package/dist/core/orchestrator/adapters/deterministic-adapter.d.ts +35 -0
- package/dist/core/orchestrator/adapters/env-whitelist.d.ts +4 -0
- package/dist/core/orchestrator/adapters/output-extractor.d.ts +11 -0
- package/dist/core/orchestrator/adapters/process-manager.d.ts +15 -0
- package/dist/core/orchestrator/adapters/tool-loop.d.ts +22 -0
- package/dist/core/orchestrator/agent-registry.d.ts +31 -0
- package/dist/core/orchestrator/budget-controller.d.ts +19 -0
- package/dist/core/orchestrator/chain-guard.d.ts +14 -0
- package/dist/core/orchestrator/circuit-breaker.d.ts +65 -0
- package/dist/core/orchestrator/claude-stream-parser.d.ts +31 -0
- package/dist/core/orchestrator/config-revisions.d.ts +6 -0
- package/dist/core/orchestrator/dependency-resolver.d.ts +20 -0
- package/dist/core/orchestrator/execution-engine.d.ts +99 -0
- package/dist/core/orchestrator/governance-gate.d.ts +110 -0
- package/dist/core/orchestrator/learning-pipeline.d.ts +112 -0
- package/dist/core/orchestrator/loop-detector.d.ts +51 -0
- package/dist/core/orchestrator/ndjson-logger.d.ts +6 -0
- package/dist/core/orchestrator/permission-relay.d.ts +72 -0
- package/dist/core/orchestrator/run-manager.d.ts +31 -0
- package/dist/core/orchestrator/scheduler.d.ts +74 -0
- package/dist/core/orchestrator/secret-store.d.ts +57 -0
- package/dist/core/orchestrator/session-manager.d.ts +13 -0
- package/dist/core/orchestrator/task-queue.d.ts +34 -0
- package/dist/core/orchestrator/template-interpolate.d.ts +5 -0
- package/dist/core/orchestrator/tools/file-ops.d.ts +12 -0
- package/dist/core/orchestrator/tools/index.d.ts +47 -0
- package/dist/core/orchestrator/tools/management.d.ts +12 -0
- package/dist/core/orchestrator/tools/messaging.d.ts +21 -0
- package/dist/core/orchestrator/tools/read-file.d.ts +5 -0
- package/dist/core/orchestrator/tools/resolve-agent.d.ts +9 -0
- package/dist/core/orchestrator/tools/roster.d.ts +16 -0
- package/dist/core/orchestrator/tools/send-file.d.ts +5 -0
- package/dist/core/orchestrator/tools/status.d.ts +20 -0
- package/dist/core/orchestrator/tools/task-ops.d.ts +13 -0
- package/dist/core/orchestrator/user-registry.d.ts +47 -0
- package/dist/core/orchestrator/wakeup-queue.d.ts +9 -0
- package/dist/core/orchestrator/workflow-engine.d.ts +47 -0
- package/dist/core/security/audit.d.ts +20 -0
- package/dist/core/security/column-validator.d.ts +20 -0
- package/dist/core/security/index.d.ts +5 -0
- package/dist/core/security/process-env.d.ts +13 -0
- package/dist/core/security/sanitizer.d.ts +11 -0
- package/dist/core/security/types.d.ts +11 -0
- package/dist/core/update/auto-update.d.ts +21 -0
- package/dist/core/update/backup-manager.d.ts +7 -0
- package/dist/core/update/index.d.ts +8 -0
- package/dist/core/update/migration-hooks.d.ts +11 -0
- package/dist/core/update/types.d.ts +11 -0
- package/dist/core/update/update-checker.d.ts +11 -0
- package/dist/core/update/update-manager.d.ts +25 -0
- package/dist/core/update/version-utils.d.ts +6 -0
- package/dist/index.d.ts +38 -2366
- package/dist/index.js +117 -10
- package/dist/providers/anthropic/index.d.ts +5 -20
- package/dist/providers/anthropic/models.d.ts +2 -0
- package/dist/providers/anthropic/provider.d.ts +13 -0
- package/dist/providers/anthropic/tool-converter.d.ts +10 -0
- package/dist/providers/ollama/index.d.ts +4 -22
- package/dist/providers/ollama/provider.d.ts +17 -0
- package/dist/providers/openai/index.d.ts +5 -20
- package/dist/providers/openai/models.d.ts +2 -0
- package/dist/providers/openai/provider.d.ts +13 -0
- package/dist/providers/openai/tool-converter.d.ts +10 -0
- package/dist/shared/constants.d.ts +50 -0
- package/dist/shared/index.d.ts +14 -0
- package/dist/shared/types/agent.d.ts +36 -0
- package/dist/{channel-CVm1AWUF.d.ts → shared/types/channel.d.ts} +13 -17
- package/dist/shared/types/config.d.ts +160 -0
- package/dist/shared/types/connector.d.ts +77 -0
- package/dist/shared/types/execution.d.ts +29 -0
- package/dist/{provider-BHkqkSdq.d.ts → shared/types/provider.d.ts} +10 -12
- package/dist/shared/types/task.d.ts +47 -0
- package/dist/shared/types/workflow.d.ts +39 -0
- package/dist/shared/utils.d.ts +6 -0
- package/dist/update-check.d.ts +5 -0
- package/package.json +3 -3
- package/dist/channel-DziSPayj.d.ts +0 -73
- package/dist/chat-pipeline-BGgmH_ap.d.ts +0 -655
- package/dist/chat-pipeline-BWrtVqEP.d.ts +0 -652
- package/dist/chat-pipeline-aBSj7a4E.d.ts +0 -655
package/README.md
CHANGED
|
@@ -13,7 +13,8 @@ A modular TypeScript framework for building multi-agent bots with LLM orchestrat
|
|
|
13
13
|
- **Message interpretation** -- Async structured extraction from messages into tasks, memories, files, and user context. Pluggable extractors for custom data types. Programmatic task creation (no LLM dependency).
|
|
14
14
|
- **Triage routing** -- Content-aware message routing with keyword/regex matching, priority rules, and LLM fallback. Ownership chain logging for every routing decision.
|
|
15
15
|
- **Multi-agent orchestration** -- Define agents with different models, roles, and execution adapters. Task queue with priority scheduling, retry policies, and followup chains.
|
|
16
|
-
- **Loop detection and circuit breakers** -- Pattern-based loop detection (self-loops, ping-pong, blocked re-entry) plus circuit breakers with automatic human escalation.
|
|
16
|
+
- **Loop detection and circuit breakers** -- Pattern-based loop detection (self-loops, ping-pong, blocked re-entry) plus circuit breakers with automatic human escalation. Scheduler connector syncs are circuit-broken per key — persistent connector failures trip the breaker instead of retrying endlessly.
|
|
17
|
+
- **Safe tool merging** -- `mergeTools(nativeTools, localSkills)` deduplicates tool arrays with last-wins semantics. Prevents Anthropic API 400 errors from duplicate tool names when combining built-in and custom tools.
|
|
17
18
|
- **Learning pipeline** -- Structured feedback capture with auto-promotion: 3+ similar records become a playbook, 3+ agents become a reusable skill.
|
|
18
19
|
- **Governance gates** -- Independent QA, quality, and drift gates that validate agent output and report to the human operator.
|
|
19
20
|
- **Permission relay** -- Remote approval via messaging platforms (Slack, Discord, Telegram). Dual approval: local + remote, first wins.
|
package/bin/botinabox.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
import('../dist/cli.js').then(m => m.main(process.argv.slice(2)));
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DiscordAdapter — ChannelAdapter implementation for Discord.
|
|
3
|
+
* Story 4.6
|
|
4
|
+
*/
|
|
5
|
+
import type { ChannelAdapter, ChannelCapabilities, ChannelMeta, ChannelConfig, InboundMessage, OutboundPayload, SendResult, HealthStatus } from "../../shared/index.js";
|
|
6
|
+
/** Minimal Discord client interface for mockability. */
|
|
7
|
+
export interface DiscordClient {
|
|
8
|
+
sendMessage(channelId: string, content: string): Promise<{
|
|
9
|
+
id: string;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
export declare class DiscordAdapter implements ChannelAdapter {
|
|
13
|
+
readonly id = "discord";
|
|
14
|
+
readonly meta: ChannelMeta;
|
|
15
|
+
readonly capabilities: ChannelCapabilities;
|
|
16
|
+
onMessage?: (message: InboundMessage) => Promise<void>;
|
|
17
|
+
private connected;
|
|
18
|
+
private config;
|
|
19
|
+
private client;
|
|
20
|
+
constructor(client?: DiscordClient);
|
|
21
|
+
connect(config: ChannelConfig): Promise<void>;
|
|
22
|
+
disconnect(): Promise<void>;
|
|
23
|
+
healthCheck(): Promise<HealthStatus>;
|
|
24
|
+
send(target: {
|
|
25
|
+
peerId: string;
|
|
26
|
+
threadId?: string;
|
|
27
|
+
}, payload: OutboundPayload): Promise<SendResult>;
|
|
28
|
+
/** Simulate receiving an inbound message (for testing/webhooks). */
|
|
29
|
+
receive(event: Record<string, unknown>): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
/** Factory function — default export for auto-discovery. */
|
|
32
|
+
export default function createDiscordAdapter(client?: DiscordClient): DiscordAdapter;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discord inbound message parsing.
|
|
3
|
+
* Story 4.6
|
|
4
|
+
*/
|
|
5
|
+
import type { InboundMessage } from "../../shared/index.js";
|
|
6
|
+
export interface DiscordEvent {
|
|
7
|
+
id?: string;
|
|
8
|
+
channel_id?: string;
|
|
9
|
+
guild_id?: string;
|
|
10
|
+
author?: {
|
|
11
|
+
id?: string;
|
|
12
|
+
username?: string;
|
|
13
|
+
};
|
|
14
|
+
content?: string;
|
|
15
|
+
message_reference?: {
|
|
16
|
+
message_id?: string;
|
|
17
|
+
channel_id?: string;
|
|
18
|
+
};
|
|
19
|
+
timestamp?: string;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Parse a Discord message event into an InboundMessage.
|
|
24
|
+
*/
|
|
25
|
+
export declare function parseDiscordEvent(event: DiscordEvent): InboundMessage;
|
|
@@ -1,87 +1,11 @@
|
|
|
1
|
-
import { C as ChannelAdapter, d as ChannelMeta, b as ChannelCapabilities, I as InboundMessage, c as ChannelConfig, H as HealthStatus, O as OutboundPayload, S as SendResult } from '../../channel-CVm1AWUF.js';
|
|
2
|
-
import '../../provider-BHkqkSdq.js';
|
|
3
|
-
|
|
4
1
|
/**
|
|
5
|
-
*
|
|
2
|
+
* @botinabox/channel-discord — Discord channel adapter.
|
|
6
3
|
* Story 4.6
|
|
7
4
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
declare class DiscordAdapter implements ChannelAdapter {
|
|
16
|
-
readonly id = "discord";
|
|
17
|
-
readonly meta: ChannelMeta;
|
|
18
|
-
readonly capabilities: ChannelCapabilities;
|
|
19
|
-
onMessage?: (message: InboundMessage) => Promise<void>;
|
|
20
|
-
private connected;
|
|
21
|
-
private config;
|
|
22
|
-
private client;
|
|
23
|
-
constructor(client?: DiscordClient);
|
|
24
|
-
connect(config: ChannelConfig): Promise<void>;
|
|
25
|
-
disconnect(): Promise<void>;
|
|
26
|
-
healthCheck(): Promise<HealthStatus>;
|
|
27
|
-
send(target: {
|
|
28
|
-
peerId: string;
|
|
29
|
-
threadId?: string;
|
|
30
|
-
}, payload: OutboundPayload): Promise<SendResult>;
|
|
31
|
-
/** Simulate receiving an inbound message (for testing/webhooks). */
|
|
32
|
-
receive(event: Record<string, unknown>): Promise<void>;
|
|
33
|
-
}
|
|
34
|
-
/** Factory function — default export for auto-discovery. */
|
|
35
|
-
declare function createDiscordAdapter(client?: DiscordClient): DiscordAdapter;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Discord inbound message parsing.
|
|
39
|
-
* Story 4.6
|
|
40
|
-
*/
|
|
41
|
-
|
|
42
|
-
interface DiscordEvent {
|
|
43
|
-
id?: string;
|
|
44
|
-
channel_id?: string;
|
|
45
|
-
guild_id?: string;
|
|
46
|
-
author?: {
|
|
47
|
-
id?: string;
|
|
48
|
-
username?: string;
|
|
49
|
-
};
|
|
50
|
-
content?: string;
|
|
51
|
-
message_reference?: {
|
|
52
|
-
message_id?: string;
|
|
53
|
-
channel_id?: string;
|
|
54
|
-
};
|
|
55
|
-
timestamp?: string;
|
|
56
|
-
[key: string]: unknown;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Parse a Discord message event into an InboundMessage.
|
|
60
|
-
*/
|
|
61
|
-
declare function parseDiscordEvent(event: DiscordEvent): InboundMessage;
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Discord outbound formatting.
|
|
65
|
-
* Discord uses native markdown — just enforce the 2000-char limit.
|
|
66
|
-
* Story 4.6
|
|
67
|
-
*/
|
|
68
|
-
/**
|
|
69
|
-
* Split text into Discord-compatible chunks (2000 char max each).
|
|
70
|
-
*/
|
|
71
|
-
declare function chunkForDiscord(text: string): string[];
|
|
72
|
-
/**
|
|
73
|
-
* Discord uses native markdown — no conversion needed.
|
|
74
|
-
* Returns the text unchanged (Discord renders it natively).
|
|
75
|
-
*/
|
|
76
|
-
declare function formatForDiscord(text: string): string;
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Discord channel configuration types.
|
|
80
|
-
* Story 4.6
|
|
81
|
-
*/
|
|
82
|
-
interface DiscordConfig {
|
|
83
|
-
token: string;
|
|
84
|
-
guildId?: string;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export { DiscordAdapter, type DiscordClient, type DiscordConfig, type DiscordEvent, chunkForDiscord, createDiscordAdapter as default, formatForDiscord, parseDiscordEvent };
|
|
5
|
+
export { DiscordAdapter } from "./adapter.js";
|
|
6
|
+
export type { DiscordClient } from "./adapter.js";
|
|
7
|
+
export { parseDiscordEvent } from "./inbound.js";
|
|
8
|
+
export type { DiscordEvent } from "./inbound.js";
|
|
9
|
+
export { formatForDiscord, chunkForDiscord } from "./outbound.js";
|
|
10
|
+
export type { DiscordConfig } from "./models.js";
|
|
11
|
+
export { default } from "./adapter.js";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discord outbound formatting.
|
|
3
|
+
* Discord uses native markdown — just enforce the 2000-char limit.
|
|
4
|
+
* Story 4.6
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Split text into Discord-compatible chunks (2000 char max each).
|
|
8
|
+
*/
|
|
9
|
+
export declare function chunkForDiscord(text: string): string[];
|
|
10
|
+
/**
|
|
11
|
+
* Discord uses native markdown — no conversion needed.
|
|
12
|
+
* Returns the text unchanged (Discord renders it natively).
|
|
13
|
+
*/
|
|
14
|
+
export declare function formatForDiscord(text: string): string;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SlackAdapter — ChannelAdapter implementation for Slack.
|
|
3
|
+
* Story 4.5
|
|
4
|
+
*/
|
|
5
|
+
import type { ChannelAdapter, ChannelCapabilities, ChannelMeta, ChannelConfig, InboundMessage, OutboundPayload, SendResult, HealthStatus } from "../../shared/index.js";
|
|
6
|
+
/** Minimal Bolt-compatible client interface for mockability. */
|
|
7
|
+
export interface BoltClient {
|
|
8
|
+
postMessage(channel: string, text: string, threadTs?: string): Promise<{
|
|
9
|
+
ok: boolean;
|
|
10
|
+
ts?: string;
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
13
|
+
export declare class SlackAdapter implements ChannelAdapter {
|
|
14
|
+
readonly id = "slack";
|
|
15
|
+
readonly meta: ChannelMeta;
|
|
16
|
+
readonly capabilities: ChannelCapabilities;
|
|
17
|
+
onMessage?: (message: InboundMessage) => Promise<void>;
|
|
18
|
+
private connected;
|
|
19
|
+
private config;
|
|
20
|
+
private client;
|
|
21
|
+
constructor(client?: BoltClient);
|
|
22
|
+
connect(config: ChannelConfig): Promise<void>;
|
|
23
|
+
disconnect(): Promise<void>;
|
|
24
|
+
healthCheck(): Promise<HealthStatus>;
|
|
25
|
+
send(target: {
|
|
26
|
+
peerId: string;
|
|
27
|
+
threadId?: string;
|
|
28
|
+
}, payload: OutboundPayload): Promise<SendResult>;
|
|
29
|
+
/** Simulate receiving an inbound message (for testing/webhooks). */
|
|
30
|
+
receive(event: Record<string, unknown>): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
/** Factory function — default export for auto-discovery. */
|
|
33
|
+
export default function createSlackAdapter(client?: BoltClient): SlackAdapter;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SlackBoltAdapter — real Bolt Socket Mode integration for botinabox.
|
|
3
|
+
*
|
|
4
|
+
* Handles:
|
|
5
|
+
* - Bolt app lifecycle (start, stop)
|
|
6
|
+
* - Inbound message parsing + self-filtering
|
|
7
|
+
* - response.ready → Slack message delivery
|
|
8
|
+
* - file.deliver → Slack file upload
|
|
9
|
+
*
|
|
10
|
+
* Apps just instantiate and start:
|
|
11
|
+
* const slack = new SlackBoltAdapter({ botToken, appToken, hooks, pipeline });
|
|
12
|
+
* await slack.start();
|
|
13
|
+
*/
|
|
14
|
+
import type { HookBus } from '../../core/hooks/hook-bus.js';
|
|
15
|
+
import type { ChatPipeline } from '../../core/chat/chat-pipeline.js';
|
|
16
|
+
import type { AttachmentEnricherMap } from './enrichers/types.js';
|
|
17
|
+
export interface SlackBoltAdapterConfig {
|
|
18
|
+
botToken: string;
|
|
19
|
+
appToken: string;
|
|
20
|
+
hooks: HookBus;
|
|
21
|
+
pipeline: ChatPipeline;
|
|
22
|
+
/** Optional per-type attachment enrichers. */
|
|
23
|
+
attachmentEnrichers?: AttachmentEnricherMap;
|
|
24
|
+
}
|
|
25
|
+
export declare class SlackBoltAdapter {
|
|
26
|
+
private app;
|
|
27
|
+
private config;
|
|
28
|
+
constructor(config: SlackBoltAdapterConfig);
|
|
29
|
+
start(): Promise<void>;
|
|
30
|
+
stop(): Promise<void>;
|
|
31
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { InboundMessage } from "../../../shared/types/channel.js";
|
|
2
|
+
import type { AttachmentEnricherMap, EnrichmentContext } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Run enrichers over each attachment on an InboundMessage. Text blocks get
|
|
5
|
+
* appended to `body`; image/document blocks get stored on `attachmentBlocks`
|
|
6
|
+
* so ChatPipeline can assemble a multimodal user message.
|
|
7
|
+
*
|
|
8
|
+
* Enrichers that throw or return empty arrays fall back to a plain
|
|
9
|
+
* `[Attached: <filename>]` breadcrumb — the LLM still sees the attachment
|
|
10
|
+
* was there, just without content.
|
|
11
|
+
*/
|
|
12
|
+
export declare function enrichAttachments(msg: InboundMessage, ctx: EnrichmentContext, enrichers: AttachmentEnricherMap): Promise<InboundMessage>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AttachmentEnricher } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Slack image enricher. Downloads the image via the Slack bot token and
|
|
4
|
+
* returns a single `image` ContentBlock containing the base64 data. No
|
|
5
|
+
* intermediate vision API call — the downstream Anthropic provider sees
|
|
6
|
+
* the raw image and processes it natively.
|
|
7
|
+
*
|
|
8
|
+
* Consumers wire this as `attachmentEnrichers.image = createSlackImageEnricher()`.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createSlackImageEnricher(): AttachmentEnricher;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type { AttachmentEnricher, AttachmentEnricherMap, EnrichmentContext, EnrichedMessage, } from "./types.js";
|
|
2
|
+
export { enrichAttachments } from "./enrich.js";
|
|
3
|
+
export { createSlackImageEnricher } from "./image-enricher.js";
|
|
4
|
+
export { createSlackPdfEnricher } from "./pdf-enricher.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AttachmentEnricher } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Slack PDF enricher. Downloads the PDF via the Slack bot token and returns
|
|
4
|
+
* a single `document` ContentBlock containing the base64 data. No intermediate
|
|
5
|
+
* document-extraction API call — the downstream Anthropic provider ingests
|
|
6
|
+
* the PDF natively.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createSlackPdfEnricher(): AttachmentEnricher;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Attachment, AttachmentMediaType, InboundMessage } from "../../../shared/types/channel.js";
|
|
2
|
+
import type { ContentBlock } from "../../../shared/types/provider.js";
|
|
3
|
+
/**
|
|
4
|
+
* Transport-specific context passed to every enricher. Extensible — add a new
|
|
5
|
+
* optional sub-context when wiring a new source (gmail, drive, dropbox, etc.)
|
|
6
|
+
* and enrichers that need it can type-guard.
|
|
7
|
+
*/
|
|
8
|
+
export interface EnrichmentContext {
|
|
9
|
+
slack?: {
|
|
10
|
+
botToken: string;
|
|
11
|
+
};
|
|
12
|
+
drive?: {
|
|
13
|
+
client: unknown;
|
|
14
|
+
};
|
|
15
|
+
gmail?: {
|
|
16
|
+
client: unknown;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* An AttachmentEnricher downloads an attachment and returns Claude content
|
|
21
|
+
* blocks representing it. Text blocks become part of the message body; image
|
|
22
|
+
* and document blocks flow through to the Anthropic provider unchanged.
|
|
23
|
+
*
|
|
24
|
+
* Enrichers throw on failure. The framework catches and falls back to a
|
|
25
|
+
* plain `[Attached: <filename>]` breadcrumb in the message body.
|
|
26
|
+
*/
|
|
27
|
+
export type AttachmentEnricher = (attachment: Attachment, ctx: EnrichmentContext) => Promise<ContentBlock[]>;
|
|
28
|
+
export type AttachmentEnricherMap = Partial<Record<AttachmentMediaType, AttachmentEnricher>>;
|
|
29
|
+
/** Internal: the result of running enrichAttachments on a message. */
|
|
30
|
+
export interface EnrichedMessage extends InboundMessage {
|
|
31
|
+
body: string;
|
|
32
|
+
}
|
|
33
|
+
export type { InboundMessage };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slack inbound message parsing.
|
|
3
|
+
* Story 4.5
|
|
4
|
+
*/
|
|
5
|
+
import type { InboundMessage } from "../../shared/index.js";
|
|
6
|
+
export interface SlackFile {
|
|
7
|
+
id?: string;
|
|
8
|
+
filetype?: string;
|
|
9
|
+
subtype?: string;
|
|
10
|
+
url_private?: string;
|
|
11
|
+
preview?: string;
|
|
12
|
+
transcription?: {
|
|
13
|
+
status?: string;
|
|
14
|
+
preview?: {
|
|
15
|
+
content?: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
}
|
|
20
|
+
export interface SlackEvent {
|
|
21
|
+
type: string;
|
|
22
|
+
subtype?: string;
|
|
23
|
+
client_msg_id?: string;
|
|
24
|
+
ts?: string;
|
|
25
|
+
event_ts?: string;
|
|
26
|
+
channel?: string;
|
|
27
|
+
user?: string;
|
|
28
|
+
text?: string;
|
|
29
|
+
thread_ts?: string;
|
|
30
|
+
files?: SlackFile[];
|
|
31
|
+
[key: string]: unknown;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Extract the text content from a voice message file.
|
|
35
|
+
* Prefers the transcription preview; falls back to the file preview text.
|
|
36
|
+
* Returns null if the file is not a voice message or has no transcript.
|
|
37
|
+
*/
|
|
38
|
+
export declare function extractVoiceTranscript(file: SlackFile): string | null;
|
|
39
|
+
/**
|
|
40
|
+
* Parse a Slack event into an InboundMessage.
|
|
41
|
+
*
|
|
42
|
+
* Handles standard text messages and voice messages (file_share subtype
|
|
43
|
+
* with audio files). Voice message transcripts are extracted and prefixed
|
|
44
|
+
* with `[Voice message]`.
|
|
45
|
+
*/
|
|
46
|
+
export declare function parseSlackEvent(event: SlackEvent): InboundMessage;
|
|
47
|
+
/**
|
|
48
|
+
* Enrich a voice message with local transcription when Slack's built-in
|
|
49
|
+
* transcription is unavailable.
|
|
50
|
+
*
|
|
51
|
+
* Downloads the audio file from Slack using the bot token, converts to WAV,
|
|
52
|
+
* and transcribes locally via whisper-node. Returns the original message
|
|
53
|
+
* unchanged if transcription fails or is not needed.
|
|
54
|
+
*
|
|
55
|
+
* @param msg - The parsed inbound message (from parseSlackEvent)
|
|
56
|
+
* @param botToken - Slack bot token for authenticated file download
|
|
57
|
+
* @returns The message with body replaced by transcript, or original on failure
|
|
58
|
+
*/
|
|
59
|
+
export declare function enrichVoiceMessage(msg: InboundMessage, botToken: string): Promise<InboundMessage>;
|
|
@@ -1,255 +1,16 @@
|
|
|
1
|
-
import { C as ChannelAdapter, d as ChannelMeta, b as ChannelCapabilities, I as InboundMessage, c as ChannelConfig, H as HealthStatus, O as OutboundPayload, S as SendResult, A as Attachment, a as AttachmentMediaType } from '../../channel-CVm1AWUF.js';
|
|
2
|
-
import { H as HookBus, c as ChatPipeline } from '../../chat-pipeline-aBSj7a4E.js';
|
|
3
|
-
import { c as ContentBlock } from '../../provider-BHkqkSdq.js';
|
|
4
|
-
import 'better-sqlite3';
|
|
5
|
-
|
|
6
1
|
/**
|
|
7
|
-
*
|
|
2
|
+
* @botinabox/channel-slack — Slack channel adapter.
|
|
8
3
|
* Story 4.5
|
|
9
4
|
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
onMessage?: (message: InboundMessage) => Promise<void>;
|
|
23
|
-
private connected;
|
|
24
|
-
private config;
|
|
25
|
-
private client;
|
|
26
|
-
constructor(client?: BoltClient);
|
|
27
|
-
connect(config: ChannelConfig): Promise<void>;
|
|
28
|
-
disconnect(): Promise<void>;
|
|
29
|
-
healthCheck(): Promise<HealthStatus>;
|
|
30
|
-
send(target: {
|
|
31
|
-
peerId: string;
|
|
32
|
-
threadId?: string;
|
|
33
|
-
}, payload: OutboundPayload): Promise<SendResult>;
|
|
34
|
-
/** Simulate receiving an inbound message (for testing/webhooks). */
|
|
35
|
-
receive(event: Record<string, unknown>): Promise<void>;
|
|
36
|
-
}
|
|
37
|
-
/** Factory function — default export for auto-discovery. */
|
|
38
|
-
declare function createSlackAdapter(client?: BoltClient): SlackAdapter;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Slack inbound message parsing.
|
|
42
|
-
* Story 4.5
|
|
43
|
-
*/
|
|
44
|
-
|
|
45
|
-
interface SlackFile {
|
|
46
|
-
id?: string;
|
|
47
|
-
filetype?: string;
|
|
48
|
-
subtype?: string;
|
|
49
|
-
url_private?: string;
|
|
50
|
-
preview?: string;
|
|
51
|
-
transcription?: {
|
|
52
|
-
status?: string;
|
|
53
|
-
preview?: {
|
|
54
|
-
content?: string;
|
|
55
|
-
};
|
|
56
|
-
};
|
|
57
|
-
[key: string]: unknown;
|
|
58
|
-
}
|
|
59
|
-
interface SlackEvent {
|
|
60
|
-
type: string;
|
|
61
|
-
subtype?: string;
|
|
62
|
-
client_msg_id?: string;
|
|
63
|
-
ts?: string;
|
|
64
|
-
event_ts?: string;
|
|
65
|
-
channel?: string;
|
|
66
|
-
user?: string;
|
|
67
|
-
text?: string;
|
|
68
|
-
thread_ts?: string;
|
|
69
|
-
files?: SlackFile[];
|
|
70
|
-
[key: string]: unknown;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Extract the text content from a voice message file.
|
|
74
|
-
* Prefers the transcription preview; falls back to the file preview text.
|
|
75
|
-
* Returns null if the file is not a voice message or has no transcript.
|
|
76
|
-
*/
|
|
77
|
-
declare function extractVoiceTranscript(file: SlackFile): string | null;
|
|
78
|
-
/**
|
|
79
|
-
* Parse a Slack event into an InboundMessage.
|
|
80
|
-
*
|
|
81
|
-
* Handles standard text messages and voice messages (file_share subtype
|
|
82
|
-
* with audio files). Voice message transcripts are extracted and prefixed
|
|
83
|
-
* with `[Voice message]`.
|
|
84
|
-
*/
|
|
85
|
-
declare function parseSlackEvent(event: SlackEvent): InboundMessage;
|
|
86
|
-
/**
|
|
87
|
-
* Enrich a voice message with local transcription when Slack's built-in
|
|
88
|
-
* transcription is unavailable.
|
|
89
|
-
*
|
|
90
|
-
* Downloads the audio file from Slack using the bot token, converts to WAV,
|
|
91
|
-
* and transcribes locally via whisper-node. Returns the original message
|
|
92
|
-
* unchanged if transcription fails or is not needed.
|
|
93
|
-
*
|
|
94
|
-
* @param msg - The parsed inbound message (from parseSlackEvent)
|
|
95
|
-
* @param botToken - Slack bot token for authenticated file download
|
|
96
|
-
* @returns The message with body replaced by transcript, or original on failure
|
|
97
|
-
*/
|
|
98
|
-
declare function enrichVoiceMessage(msg: InboundMessage, botToken: string): Promise<InboundMessage>;
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Local voice transcription via whisper-node (whisper.cpp bindings).
|
|
102
|
-
*
|
|
103
|
-
* whisper-node is an optional dependency — if not installed, transcription
|
|
104
|
-
* degrades gracefully (returns null). Requires ffmpeg on the system PATH
|
|
105
|
-
* for audio format conversion.
|
|
106
|
-
*
|
|
107
|
-
* Setup:
|
|
108
|
-
* npm install whisper-node
|
|
109
|
-
* npx whisper-node download # download a model (e.g. base.en)
|
|
110
|
-
* brew install ffmpeg # or equivalent for your platform
|
|
111
|
-
*/
|
|
112
|
-
interface TranscribeOptions {
|
|
113
|
-
/** Whisper model name (default: "base.en"). Run `npx whisper-node download` to get models. */
|
|
114
|
-
modelName?: string;
|
|
115
|
-
/** Language code (default: "auto"). Use "en" for English-only models. */
|
|
116
|
-
language?: string;
|
|
117
|
-
}
|
|
118
|
-
interface TranscribeResult {
|
|
119
|
-
/** The full transcribed text */
|
|
120
|
-
text: string;
|
|
121
|
-
/** Individual segments with timestamps */
|
|
122
|
-
segments: Array<{
|
|
123
|
-
start: string;
|
|
124
|
-
end: string;
|
|
125
|
-
speech: string;
|
|
126
|
-
}>;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Transcribe an audio buffer using whisper-node.
|
|
130
|
-
*
|
|
131
|
-
* @param audioBuffer - Raw audio data (any format ffmpeg can decode)
|
|
132
|
-
* @param filename - Original filename (used for temp file extension)
|
|
133
|
-
* @param opts - Transcription options
|
|
134
|
-
* @returns Transcribed text, or null if transcription fails or whisper-node is not installed
|
|
135
|
-
*/
|
|
136
|
-
declare function transcribeAudio(audioBuffer: Buffer, filename: string, opts?: TranscribeOptions): Promise<string | null>;
|
|
137
|
-
/**
|
|
138
|
-
* Download an audio file from a URL with bearer token authentication.
|
|
139
|
-
*/
|
|
140
|
-
declare function downloadAudio(url: string, token: string): Promise<Buffer | null>;
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Slack outbound formatting.
|
|
144
|
-
* Story 4.5
|
|
145
|
-
*/
|
|
146
|
-
/**
|
|
147
|
-
* Convert standard markdown to Slack's mrkdwn format.
|
|
148
|
-
* - **bold** → *bold*
|
|
149
|
-
* - _italic_ preserved
|
|
150
|
-
* - `code` preserved
|
|
151
|
-
* - ```code block``` preserved
|
|
152
|
-
*/
|
|
153
|
-
declare function formatForSlack(text: string): string;
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Slack channel configuration types.
|
|
157
|
-
* Story 4.5
|
|
158
|
-
*/
|
|
159
|
-
interface SlackConfig {
|
|
160
|
-
botToken: string;
|
|
161
|
-
appToken?: string;
|
|
162
|
-
signingSecret?: string;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Transport-specific context passed to every enricher. Extensible — add a new
|
|
167
|
-
* optional sub-context when wiring a new source (gmail, drive, dropbox, etc.)
|
|
168
|
-
* and enrichers that need it can type-guard.
|
|
169
|
-
*/
|
|
170
|
-
interface EnrichmentContext {
|
|
171
|
-
slack?: {
|
|
172
|
-
botToken: string;
|
|
173
|
-
};
|
|
174
|
-
drive?: {
|
|
175
|
-
client: unknown;
|
|
176
|
-
};
|
|
177
|
-
gmail?: {
|
|
178
|
-
client: unknown;
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* An AttachmentEnricher downloads an attachment and returns Claude content
|
|
183
|
-
* blocks representing it. Text blocks become part of the message body; image
|
|
184
|
-
* and document blocks flow through to the Anthropic provider unchanged.
|
|
185
|
-
*
|
|
186
|
-
* Enrichers throw on failure. The framework catches and falls back to a
|
|
187
|
-
* plain `[Attached: <filename>]` breadcrumb in the message body.
|
|
188
|
-
*/
|
|
189
|
-
type AttachmentEnricher = (attachment: Attachment, ctx: EnrichmentContext) => Promise<ContentBlock[]>;
|
|
190
|
-
type AttachmentEnricherMap = Partial<Record<AttachmentMediaType, AttachmentEnricher>>;
|
|
191
|
-
/** Internal: the result of running enrichAttachments on a message. */
|
|
192
|
-
interface EnrichedMessage extends InboundMessage {
|
|
193
|
-
body: string;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* SlackBoltAdapter — real Bolt Socket Mode integration for botinabox.
|
|
198
|
-
*
|
|
199
|
-
* Handles:
|
|
200
|
-
* - Bolt app lifecycle (start, stop)
|
|
201
|
-
* - Inbound message parsing + self-filtering
|
|
202
|
-
* - response.ready → Slack message delivery
|
|
203
|
-
* - file.deliver → Slack file upload
|
|
204
|
-
*
|
|
205
|
-
* Apps just instantiate and start:
|
|
206
|
-
* const slack = new SlackBoltAdapter({ botToken, appToken, hooks, pipeline });
|
|
207
|
-
* await slack.start();
|
|
208
|
-
*/
|
|
209
|
-
|
|
210
|
-
interface SlackBoltAdapterConfig {
|
|
211
|
-
botToken: string;
|
|
212
|
-
appToken: string;
|
|
213
|
-
hooks: HookBus;
|
|
214
|
-
pipeline: ChatPipeline;
|
|
215
|
-
/** Optional per-type attachment enrichers. */
|
|
216
|
-
attachmentEnrichers?: AttachmentEnricherMap;
|
|
217
|
-
}
|
|
218
|
-
declare class SlackBoltAdapter {
|
|
219
|
-
private app;
|
|
220
|
-
private config;
|
|
221
|
-
constructor(config: SlackBoltAdapterConfig);
|
|
222
|
-
start(): Promise<void>;
|
|
223
|
-
stop(): Promise<void>;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Run enrichers over each attachment on an InboundMessage. Text blocks get
|
|
228
|
-
* appended to `body`; image/document blocks get stored on `attachmentBlocks`
|
|
229
|
-
* so ChatPipeline can assemble a multimodal user message.
|
|
230
|
-
*
|
|
231
|
-
* Enrichers that throw or return empty arrays fall back to a plain
|
|
232
|
-
* `[Attached: <filename>]` breadcrumb — the LLM still sees the attachment
|
|
233
|
-
* was there, just without content.
|
|
234
|
-
*/
|
|
235
|
-
declare function enrichAttachments(msg: InboundMessage, ctx: EnrichmentContext, enrichers: AttachmentEnricherMap): Promise<InboundMessage>;
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* Slack image enricher. Downloads the image via the Slack bot token and
|
|
239
|
-
* returns a single `image` ContentBlock containing the base64 data. No
|
|
240
|
-
* intermediate vision API call — the downstream Anthropic provider sees
|
|
241
|
-
* the raw image and processes it natively.
|
|
242
|
-
*
|
|
243
|
-
* Consumers wire this as `attachmentEnrichers.image = createSlackImageEnricher()`.
|
|
244
|
-
*/
|
|
245
|
-
declare function createSlackImageEnricher(): AttachmentEnricher;
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Slack PDF enricher. Downloads the PDF via the Slack bot token and returns
|
|
249
|
-
* a single `document` ContentBlock containing the base64 data. No intermediate
|
|
250
|
-
* document-extraction API call — the downstream Anthropic provider ingests
|
|
251
|
-
* the PDF natively.
|
|
252
|
-
*/
|
|
253
|
-
declare function createSlackPdfEnricher(): AttachmentEnricher;
|
|
254
|
-
|
|
255
|
-
export { type AttachmentEnricher, type AttachmentEnricherMap, type BoltClient, type EnrichedMessage, type EnrichmentContext, SlackAdapter, SlackBoltAdapter, type SlackBoltAdapterConfig, type SlackConfig, type SlackEvent, type SlackFile, type TranscribeOptions, type TranscribeResult, createSlackImageEnricher, createSlackPdfEnricher, createSlackAdapter as default, downloadAudio, enrichAttachments, enrichVoiceMessage, extractVoiceTranscript, formatForSlack, parseSlackEvent, transcribeAudio };
|
|
5
|
+
export { SlackAdapter } from "./adapter.js";
|
|
6
|
+
export type { BoltClient } from "./adapter.js";
|
|
7
|
+
export { parseSlackEvent, extractVoiceTranscript, enrichVoiceMessage } from "./inbound.js";
|
|
8
|
+
export type { SlackEvent, SlackFile } from "./inbound.js";
|
|
9
|
+
export { transcribeAudio, downloadAudio } from "./transcribe.js";
|
|
10
|
+
export type { TranscribeOptions, TranscribeResult } from "./transcribe.js";
|
|
11
|
+
export { formatForSlack } from "./outbound.js";
|
|
12
|
+
export type { SlackConfig } from "./models.js";
|
|
13
|
+
export { SlackBoltAdapter } from "./bolt-adapter.js";
|
|
14
|
+
export type { SlackBoltAdapterConfig } from "./bolt-adapter.js";
|
|
15
|
+
export { default } from "./adapter.js";
|
|
16
|
+
export * from "./enrichers/index.js";
|