mach6-core 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +454 -0
- package/dist/agent/context-monitor.d.ts +40 -0
- package/dist/agent/context-monitor.d.ts.map +1 -0
- package/dist/agent/context-monitor.js +138 -0
- package/dist/agent/context-monitor.js.map +1 -0
- package/dist/agent/context.d.ts +8 -0
- package/dist/agent/context.d.ts.map +1 -0
- package/dist/agent/context.js +197 -0
- package/dist/agent/context.js.map +1 -0
- package/dist/agent/runner.d.ts +42 -0
- package/dist/agent/runner.d.ts.map +1 -0
- package/dist/agent/runner.js +168 -0
- package/dist/agent/runner.js.map +1 -0
- package/dist/agent/system-prompt.d.ts +10 -0
- package/dist/agent/system-prompt.d.ts.map +1 -0
- package/dist/agent/system-prompt.js +120 -0
- package/dist/agent/system-prompt.js.map +1 -0
- package/dist/boot/sequence.d.ts +34 -0
- package/dist/boot/sequence.d.ts.map +1 -0
- package/dist/boot/sequence.js +103 -0
- package/dist/boot/sequence.js.map +1 -0
- package/dist/channels/__test__/integration.test.d.ts +8 -0
- package/dist/channels/__test__/integration.test.d.ts.map +1 -0
- package/dist/channels/__test__/integration.test.js +221 -0
- package/dist/channels/__test__/integration.test.js.map +1 -0
- package/dist/channels/adapter.d.ts +53 -0
- package/dist/channels/adapter.d.ts.map +1 -0
- package/dist/channels/adapter.js +164 -0
- package/dist/channels/adapter.js.map +1 -0
- package/dist/channels/adapters/discord.d.ts +49 -0
- package/dist/channels/adapters/discord.d.ts.map +1 -0
- package/dist/channels/adapters/discord.js +382 -0
- package/dist/channels/adapters/discord.js.map +1 -0
- package/dist/channels/adapters/whatsapp.d.ts +59 -0
- package/dist/channels/adapters/whatsapp.d.ts.map +1 -0
- package/dist/channels/adapters/whatsapp.js +503 -0
- package/dist/channels/adapters/whatsapp.js.map +1 -0
- package/dist/channels/bus.d.ts +55 -0
- package/dist/channels/bus.d.ts.map +1 -0
- package/dist/channels/bus.js +307 -0
- package/dist/channels/bus.js.map +1 -0
- package/dist/channels/formatter.d.ts +16 -0
- package/dist/channels/formatter.d.ts.map +1 -0
- package/dist/channels/formatter.js +226 -0
- package/dist/channels/formatter.js.map +1 -0
- package/dist/channels/presence.d.ts +67 -0
- package/dist/channels/presence.d.ts.map +1 -0
- package/dist/channels/presence.js +209 -0
- package/dist/channels/presence.js.map +1 -0
- package/dist/channels/registry.d.ts +57 -0
- package/dist/channels/registry.d.ts.map +1 -0
- package/dist/channels/registry.js +159 -0
- package/dist/channels/registry.js.map +1 -0
- package/dist/channels/router.d.ts +49 -0
- package/dist/channels/router.d.ts.map +1 -0
- package/dist/channels/router.js +244 -0
- package/dist/channels/router.js.map +1 -0
- package/dist/channels/types.d.ts +279 -0
- package/dist/channels/types.d.ts.map +1 -0
- package/dist/channels/types.js +67 -0
- package/dist/channels/types.js.map +1 -0
- package/dist/cli/brand.d.ts +71 -0
- package/dist/cli/brand.d.ts.map +1 -0
- package/dist/cli/brand.js +194 -0
- package/dist/cli/brand.js.map +1 -0
- package/dist/cli/wizard.d.ts +8 -0
- package/dist/cli/wizard.d.ts.map +1 -0
- package/dist/cli/wizard.js +520 -0
- package/dist/cli/wizard.js.map +1 -0
- package/dist/config/config.d.ts +47 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +63 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/validator.d.ts +18 -0
- package/dist/config/validator.d.ts.map +1 -0
- package/dist/config/validator.js +92 -0
- package/dist/config/validator.js.map +1 -0
- package/dist/cron/budget.d.ts +39 -0
- package/dist/cron/budget.d.ts.map +1 -0
- package/dist/cron/budget.js +98 -0
- package/dist/cron/budget.js.map +1 -0
- package/dist/formatters/markdown.d.ts +6 -0
- package/dist/formatters/markdown.d.ts.map +1 -0
- package/dist/formatters/markdown.js +85 -0
- package/dist/formatters/markdown.js.map +1 -0
- package/dist/gateway/daemon.d.ts +97 -0
- package/dist/gateway/daemon.d.ts.map +1 -0
- package/dist/gateway/daemon.js +772 -0
- package/dist/gateway/daemon.js.map +1 -0
- package/dist/heartbeat/scheduler.d.ts +45 -0
- package/dist/heartbeat/scheduler.d.ts.map +1 -0
- package/dist/heartbeat/scheduler.js +102 -0
- package/dist/heartbeat/scheduler.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +305 -0
- package/dist/index.js.map +1 -0
- package/dist/memory/integrity.d.ts +37 -0
- package/dist/memory/integrity.d.ts.map +1 -0
- package/dist/memory/integrity.js +108 -0
- package/dist/memory/integrity.js.map +1 -0
- package/dist/providers/anthropic.d.ts +3 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +232 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/diagnostics.d.ts +18 -0
- package/dist/providers/diagnostics.d.ts.map +1 -0
- package/dist/providers/diagnostics.js +87 -0
- package/dist/providers/diagnostics.js.map +1 -0
- package/dist/providers/github-copilot.d.ts +3 -0
- package/dist/providers/github-copilot.d.ts.map +1 -0
- package/dist/providers/github-copilot.js +145 -0
- package/dist/providers/github-copilot.js.map +1 -0
- package/dist/providers/gladius.d.ts +3 -0
- package/dist/providers/gladius.d.ts.map +1 -0
- package/dist/providers/gladius.js +16 -0
- package/dist/providers/gladius.js.map +1 -0
- package/dist/providers/openai.d.ts +3 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +161 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/retry.d.ts +2 -0
- package/dist/providers/retry.d.ts.map +1 -0
- package/dist/providers/retry.js +50 -0
- package/dist/providers/retry.js.map +1 -0
- package/dist/providers/types.d.ts +78 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +3 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/security/sanitizer.d.ts +26 -0
- package/dist/security/sanitizer.d.ts.map +1 -0
- package/dist/security/sanitizer.js +115 -0
- package/dist/security/sanitizer.js.map +1 -0
- package/dist/sessions/manager.d.ts +40 -0
- package/dist/sessions/manager.d.ts.map +1 -0
- package/dist/sessions/manager.js +255 -0
- package/dist/sessions/manager.js.map +1 -0
- package/dist/sessions/queue.d.ts +41 -0
- package/dist/sessions/queue.d.ts.map +1 -0
- package/dist/sessions/queue.js +93 -0
- package/dist/sessions/queue.js.map +1 -0
- package/dist/sessions/store.d.ts +12 -0
- package/dist/sessions/store.d.ts.map +1 -0
- package/dist/sessions/store.js +74 -0
- package/dist/sessions/store.js.map +1 -0
- package/dist/sessions/sub-agent.d.ts +18 -0
- package/dist/sessions/sub-agent.d.ts.map +1 -0
- package/dist/sessions/sub-agent.js +117 -0
- package/dist/sessions/sub-agent.js.map +1 -0
- package/dist/sessions/types.d.ts +48 -0
- package/dist/sessions/types.d.ts.map +1 -0
- package/dist/sessions/types.js +3 -0
- package/dist/sessions/types.js.map +1 -0
- package/dist/test/channel-integration.d.ts +10 -0
- package/dist/test/channel-integration.d.ts.map +1 -0
- package/dist/test/channel-integration.js +226 -0
- package/dist/test/channel-integration.js.map +1 -0
- package/dist/test/prompt-test.d.ts +2 -0
- package/dist/test/prompt-test.d.ts.map +1 -0
- package/dist/test/prompt-test.js +33 -0
- package/dist/test/prompt-test.js.map +1 -0
- package/dist/test/smoke.d.ts +8 -0
- package/dist/test/smoke.d.ts.map +1 -0
- package/dist/test/smoke.js +134 -0
- package/dist/test/smoke.js.map +1 -0
- package/dist/tools/builtin/comb.d.ts +4 -0
- package/dist/tools/builtin/comb.d.ts.map +1 -0
- package/dist/tools/builtin/comb.js +50 -0
- package/dist/tools/builtin/comb.js.map +1 -0
- package/dist/tools/builtin/edit.d.ts +3 -0
- package/dist/tools/builtin/edit.d.ts.map +1 -0
- package/dist/tools/builtin/edit.js +42 -0
- package/dist/tools/builtin/edit.js.map +1 -0
- package/dist/tools/builtin/exec.d.ts +3 -0
- package/dist/tools/builtin/exec.d.ts.map +1 -0
- package/dist/tools/builtin/exec.js +75 -0
- package/dist/tools/builtin/exec.js.map +1 -0
- package/dist/tools/builtin/image.d.ts +3 -0
- package/dist/tools/builtin/image.d.ts.map +1 -0
- package/dist/tools/builtin/image.js +208 -0
- package/dist/tools/builtin/image.js.map +1 -0
- package/dist/tools/builtin/memory.d.ts +3 -0
- package/dist/tools/builtin/memory.d.ts.map +1 -0
- package/dist/tools/builtin/memory.js +36 -0
- package/dist/tools/builtin/memory.js.map +1 -0
- package/dist/tools/builtin/message.d.ts +13 -0
- package/dist/tools/builtin/message.d.ts.map +1 -0
- package/dist/tools/builtin/message.js +330 -0
- package/dist/tools/builtin/message.js.map +1 -0
- package/dist/tools/builtin/process.d.ts +43 -0
- package/dist/tools/builtin/process.d.ts.map +1 -0
- package/dist/tools/builtin/process.js +178 -0
- package/dist/tools/builtin/process.js.map +1 -0
- package/dist/tools/builtin/read.d.ts +3 -0
- package/dist/tools/builtin/read.d.ts.map +1 -0
- package/dist/tools/builtin/read.js +36 -0
- package/dist/tools/builtin/read.js.map +1 -0
- package/dist/tools/builtin/spawn.d.ts +8 -0
- package/dist/tools/builtin/spawn.d.ts.map +1 -0
- package/dist/tools/builtin/spawn.js +90 -0
- package/dist/tools/builtin/spawn.js.map +1 -0
- package/dist/tools/builtin/tts.d.ts +3 -0
- package/dist/tools/builtin/tts.d.ts.map +1 -0
- package/dist/tools/builtin/tts.js +77 -0
- package/dist/tools/builtin/tts.js.map +1 -0
- package/dist/tools/builtin/web-fetch.d.ts +3 -0
- package/dist/tools/builtin/web-fetch.d.ts.map +1 -0
- package/dist/tools/builtin/web-fetch.js +46 -0
- package/dist/tools/builtin/web-fetch.js.map +1 -0
- package/dist/tools/builtin/write.d.ts +3 -0
- package/dist/tools/builtin/write.d.ts.map +1 -0
- package/dist/tools/builtin/write.js +31 -0
- package/dist/tools/builtin/write.js.map +1 -0
- package/dist/tools/mcp-bridge.d.ts +42 -0
- package/dist/tools/mcp-bridge.d.ts.map +1 -0
- package/dist/tools/mcp-bridge.js +198 -0
- package/dist/tools/mcp-bridge.js.map +1 -0
- package/dist/tools/policy.d.ts +57 -0
- package/dist/tools/policy.d.ts.map +1 -0
- package/dist/tools/policy.js +106 -0
- package/dist/tools/policy.js.map +1 -0
- package/dist/tools/registry.d.ts +15 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +41 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/sandbox.d.ts +91 -0
- package/dist/tools/sandbox.d.ts.map +1 -0
- package/dist/tools/sandbox.js +279 -0
- package/dist/tools/sandbox.js.map +1 -0
- package/dist/tools/types.d.ts +23 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +3 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/web/http-api.d.ts +61 -0
- package/dist/web/http-api.d.ts.map +1 -0
- package/dist/web/http-api.js +200 -0
- package/dist/web/http-api.js.map +1 -0
- package/dist/web/server.d.ts +7 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +396 -0
- package/dist/web/server.js.map +1 -0
- package/mach6.example.json +50 -0
- package/package.json +58 -0
- package/web/index.html +1370 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// Mach6 — Clean Boot Sequence (fixes Pain #20)
|
|
2
|
+
// Single entry point. Each step has timeout + fallback. Never crash on partial failure.
|
|
3
|
+
//
|
|
4
|
+
// Built by Artifact Virtual.
|
|
5
|
+
import { palette, gradient, divider } from '../cli/brand.js';
|
|
6
|
+
// ── Step Icons ──────────────────────────────────────────────────
|
|
7
|
+
const STEP_ICONS = {
|
|
8
|
+
'config-load': '◈',
|
|
9
|
+
'config-validate': '◈',
|
|
10
|
+
'comb-recall': '◎',
|
|
11
|
+
'hektor-warm': '◉',
|
|
12
|
+
'channel-connect': '◇',
|
|
13
|
+
};
|
|
14
|
+
function stepIcon(name) {
|
|
15
|
+
return STEP_ICONS[name] ?? '›';
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Run the boot sequence. Each step runs in order with timeout.
|
|
19
|
+
* Non-required steps degrade gracefully instead of crashing.
|
|
20
|
+
*/
|
|
21
|
+
export async function runBootSequence(steps) {
|
|
22
|
+
const results = [];
|
|
23
|
+
const degraded = [];
|
|
24
|
+
let fatal = false;
|
|
25
|
+
const title = gradient('BOOT SEQUENCE', [138, 43, 226], [0, 229, 255]);
|
|
26
|
+
console.log(`\n ${palette.bold}${title}${palette.reset}`);
|
|
27
|
+
console.log(divider());
|
|
28
|
+
console.log();
|
|
29
|
+
for (let i = 0; i < steps.length; i++) {
|
|
30
|
+
const step = steps[i];
|
|
31
|
+
if (fatal) {
|
|
32
|
+
results.push({ step: step.name, status: 'pending', durationMs: 0, error: 'Skipped (prior fatal error)' });
|
|
33
|
+
console.log(` ${palette.dim} ○ ${step.name}: skipped${palette.reset}`);
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const start = Date.now();
|
|
37
|
+
const icon = stepIcon(step.name);
|
|
38
|
+
const stepNum = `${palette.dim}[${i + 1}/${steps.length}]${palette.reset}`;
|
|
39
|
+
const spinner = `${palette.violet}${icon}${palette.reset}`;
|
|
40
|
+
process.stdout.write(` ${spinner} ${stepNum} ${palette.white}${step.description}${palette.reset}${palette.dim}...${palette.reset}`);
|
|
41
|
+
try {
|
|
42
|
+
await Promise.race([
|
|
43
|
+
step.execute(),
|
|
44
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`Timeout after ${step.timeoutMs}ms`)), step.timeoutMs)),
|
|
45
|
+
]);
|
|
46
|
+
const duration = Date.now() - start;
|
|
47
|
+
results.push({ step: step.name, status: 'ok', durationMs: duration });
|
|
48
|
+
// Clear the line and rewrite with success
|
|
49
|
+
process.stdout.write(`\r\x1b[2K`);
|
|
50
|
+
console.log(` ${palette.green}●${palette.reset} ${stepNum} ${palette.white}${step.description}${palette.reset} ${palette.dim}${duration}ms${palette.reset}`);
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
const duration = Date.now() - start;
|
|
54
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
55
|
+
process.stdout.write(`\r\x1b[2K`);
|
|
56
|
+
if (step.required) {
|
|
57
|
+
results.push({ step: step.name, status: 'failed', durationMs: duration, error: errMsg });
|
|
58
|
+
console.log(` ${palette.red}✗${palette.reset} ${stepNum} ${palette.white}${step.description}${palette.reset} ${palette.red}FATAL${palette.reset}`);
|
|
59
|
+
console.log(` ${palette.dim}${errMsg}${palette.reset}`);
|
|
60
|
+
fatal = true;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
results.push({ step: step.name, status: 'degraded', durationMs: duration, error: errMsg });
|
|
64
|
+
degraded.push(step.name);
|
|
65
|
+
console.log(` ${palette.yellow}◐${palette.reset} ${stepNum} ${palette.white}${step.description}${palette.reset} ${palette.yellow}degraded${palette.reset}`);
|
|
66
|
+
console.log(` ${palette.dim}${errMsg}${palette.reset}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const ready = !fatal;
|
|
71
|
+
const totalMs = results.reduce((s, r) => s + r.durationMs, 0);
|
|
72
|
+
console.log();
|
|
73
|
+
console.log(divider());
|
|
74
|
+
if (ready) {
|
|
75
|
+
if (degraded.length > 0) {
|
|
76
|
+
const status = gradient('READY', [255, 234, 0], [255, 160, 0]);
|
|
77
|
+
console.log(` ${palette.bold}${palette.yellow}◐${palette.reset} ${palette.bold}${status}${palette.reset} ${palette.dim}(degraded: ${degraded.join(', ')}) — ${totalMs}ms${palette.reset}`);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
const status = gradient('READY', [0, 230, 118], [0, 188, 212]);
|
|
81
|
+
console.log(` ${palette.bold}${palette.green}⚡${palette.reset} ${palette.bold}${status}${palette.reset} ${palette.dim}— ${totalMs}ms${palette.reset}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
const status = gradient('BOOT FAILED', [255, 82, 82], [255, 145, 0]);
|
|
86
|
+
console.log(` ${palette.bold}${palette.red}✗${palette.reset} ${palette.bold}${status}${palette.reset}`);
|
|
87
|
+
}
|
|
88
|
+
console.log();
|
|
89
|
+
return { results, ready, degraded };
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Create standard boot steps for Mach6.
|
|
93
|
+
*/
|
|
94
|
+
export function createDefaultBootSteps(hooks) {
|
|
95
|
+
return [
|
|
96
|
+
{ name: 'config-load', description: 'Loading configuration', timeoutMs: 5_000, required: true, execute: hooks.loadConfig },
|
|
97
|
+
{ name: 'config-validate', description: 'Validating configuration', timeoutMs: 5_000, required: true, execute: hooks.validateConfig },
|
|
98
|
+
{ name: 'comb-recall', description: 'Recalling operational memory (COMB)', timeoutMs: 15_000, required: false, execute: hooks.combRecall },
|
|
99
|
+
{ name: 'hektor-warm', description: 'Warming HEKTOR search index', timeoutMs: 60_000, required: false, execute: hooks.hektorWarm },
|
|
100
|
+
{ name: 'channel-connect', description: 'Connecting channels', timeoutMs: 30_000, required: false, execute: hooks.channelConnect },
|
|
101
|
+
];
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=sequence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sequence.js","sourceRoot":"","sources":["../../src/boot/sequence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.test.d.ts","sourceRoot":"","sources":["../../../src/channels/__test__/integration.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mach6 — Channel System Integration Test
|
|
3
|
+
*
|
|
4
|
+
* Tests the bus, router, and formatter together.
|
|
5
|
+
* Run: npx tsx src/channels/__test__/integration.test.ts
|
|
6
|
+
*/
|
|
7
|
+
import { Mach6Bus } from '../bus.js';
|
|
8
|
+
import { InboundRouter } from '../router.js';
|
|
9
|
+
import { formatForChannel } from '../formatter.js';
|
|
10
|
+
let passed = 0;
|
|
11
|
+
let failed = 0;
|
|
12
|
+
function assert(condition, msg) {
|
|
13
|
+
if (condition) {
|
|
14
|
+
passed++;
|
|
15
|
+
console.log(` ✅ ${msg}`);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
failed++;
|
|
19
|
+
console.log(` ❌ ${msg}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// ─── Test: Message Bus ─────────────────────────────────────────────────────
|
|
23
|
+
console.log('\n🔧 Message Bus');
|
|
24
|
+
{
|
|
25
|
+
const bus = new Mach6Bus({ coalesceWindowMs: 0 }); // Disable coalesce for testing
|
|
26
|
+
const received = [];
|
|
27
|
+
bus.subscribe('session-1', (env) => received.push(env));
|
|
28
|
+
// Publish a message
|
|
29
|
+
bus.publish({
|
|
30
|
+
id: '1',
|
|
31
|
+
timestamp: Date.now(),
|
|
32
|
+
priority: 'normal',
|
|
33
|
+
source: { channelType: 'test', adapterId: 't1', chatId: 'c1', chatType: 'dm', senderId: 'u1' },
|
|
34
|
+
sessionId: 'session-1',
|
|
35
|
+
payload: { type: 'text', text: 'Hello' },
|
|
36
|
+
metadata: {},
|
|
37
|
+
});
|
|
38
|
+
assert(received.length === 1, 'Normal message delivered');
|
|
39
|
+
assert(received[0].payload.text === 'Hello', 'Message content preserved');
|
|
40
|
+
// Test priority ordering
|
|
41
|
+
received.length = 0;
|
|
42
|
+
const bus2 = new Mach6Bus({ coalesceWindowMs: 0 });
|
|
43
|
+
const ordered = [];
|
|
44
|
+
// Publish low then high — high should deliver first when subscription is added
|
|
45
|
+
bus2.publish({
|
|
46
|
+
id: '2', timestamp: Date.now(), priority: 'low',
|
|
47
|
+
source: { channelType: 'test', adapterId: 't1', chatId: 'c1', chatType: 'dm', senderId: 'u1' },
|
|
48
|
+
sessionId: 's2', payload: { type: 'text', text: 'low' }, metadata: {},
|
|
49
|
+
});
|
|
50
|
+
bus2.publish({
|
|
51
|
+
id: '3', timestamp: Date.now(), priority: 'high',
|
|
52
|
+
source: { channelType: 'test', adapterId: 't1', chatId: 'c1', chatType: 'dm', senderId: 'u1' },
|
|
53
|
+
sessionId: 's2', payload: { type: 'text', text: 'high' }, metadata: {},
|
|
54
|
+
});
|
|
55
|
+
bus2.subscribe('s2', (env) => ordered.push(env.payload.text));
|
|
56
|
+
assert(ordered[0] === 'high' && ordered[1] === 'low', 'Priority ordering works (high before low)');
|
|
57
|
+
bus.destroy();
|
|
58
|
+
bus2.destroy();
|
|
59
|
+
}
|
|
60
|
+
// ─── Test: Interrupt ───────────────────────────────────────────────────────
|
|
61
|
+
console.log('\n⚡ Interrupts');
|
|
62
|
+
{
|
|
63
|
+
const bus = new Mach6Bus({ coalesceWindowMs: 0 });
|
|
64
|
+
const interrupts = [];
|
|
65
|
+
bus.onInterrupt('s3', (env) => interrupts.push(env));
|
|
66
|
+
bus.publish({
|
|
67
|
+
id: '4', timestamp: Date.now(), priority: 'interrupt',
|
|
68
|
+
source: { channelType: 'test', adapterId: 't1', chatId: 'c1', chatType: 'dm', senderId: 'u1' },
|
|
69
|
+
sessionId: 's3', payload: { type: 'text', text: 'STOP' }, metadata: {},
|
|
70
|
+
});
|
|
71
|
+
assert(interrupts.length === 1, 'Interrupt delivered to interrupt handler');
|
|
72
|
+
assert(interrupts[0].payload.text === 'STOP', 'Interrupt content preserved');
|
|
73
|
+
// Verify interrupt doesn't go into queue
|
|
74
|
+
const drained = bus.drain('s3');
|
|
75
|
+
assert(drained.length === 0, 'Interrupt bypasses queue (not in drain)');
|
|
76
|
+
bus.destroy();
|
|
77
|
+
}
|
|
78
|
+
// ─── Test: Backpressure ────────────────────────────────────────────────────
|
|
79
|
+
console.log('\n🔴 Backpressure');
|
|
80
|
+
{
|
|
81
|
+
let bpState = false;
|
|
82
|
+
const bus = new Mach6Bus({
|
|
83
|
+
maxQueueDepth: 5,
|
|
84
|
+
coalesceWindowMs: 0,
|
|
85
|
+
onBackpressure: (active) => { bpState = active; },
|
|
86
|
+
});
|
|
87
|
+
// Fill queue beyond max
|
|
88
|
+
for (let i = 0; i < 8; i++) {
|
|
89
|
+
bus.publish({
|
|
90
|
+
id: `bp-${i}`, timestamp: Date.now(), priority: 'normal',
|
|
91
|
+
source: { channelType: 'test', adapterId: 't1', chatId: 'c1', chatType: 'dm', senderId: 'u1' },
|
|
92
|
+
sessionId: 'unsubscribed', // No subscriber → stays in queue
|
|
93
|
+
payload: { type: 'text', text: `msg-${i}` }, metadata: {},
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
assert(bpState === true, 'Backpressure activates at queue limit');
|
|
97
|
+
// Background messages should be dropped under pressure
|
|
98
|
+
const statsBefore = bus.stats();
|
|
99
|
+
bus.publish({
|
|
100
|
+
id: 'bg-drop', timestamp: Date.now(), priority: 'background',
|
|
101
|
+
source: { channelType: 'test', adapterId: 't1', chatId: 'c1', chatType: 'dm', senderId: 'u1' },
|
|
102
|
+
sessionId: 'unsubscribed', payload: { type: 'text', text: 'dropped' }, metadata: {},
|
|
103
|
+
});
|
|
104
|
+
const statsAfter = bus.stats();
|
|
105
|
+
assert(statsAfter.totalDropped > statsBefore.totalDropped, 'Background messages dropped under backpressure');
|
|
106
|
+
bus.destroy();
|
|
107
|
+
}
|
|
108
|
+
// ─── Test: Router Policy ───────────────────────────────────────────────────
|
|
109
|
+
console.log('\n🛡️ Router Policy');
|
|
110
|
+
{
|
|
111
|
+
const bus = new Mach6Bus({ coalesceWindowMs: 0 });
|
|
112
|
+
const router = new InboundRouter(bus, {
|
|
113
|
+
policies: new Map([
|
|
114
|
+
['whatsapp', {
|
|
115
|
+
dmPolicy: 'allowlist',
|
|
116
|
+
groupPolicy: 'mention-only',
|
|
117
|
+
allowedSenders: ['allowed-user'],
|
|
118
|
+
ownerIds: ['owner-1'],
|
|
119
|
+
selfId: 'bot-id',
|
|
120
|
+
}],
|
|
121
|
+
]),
|
|
122
|
+
globalOwnerIds: ['global-owner'],
|
|
123
|
+
});
|
|
124
|
+
const received = [];
|
|
125
|
+
// We need to subscribe to catch routed messages
|
|
126
|
+
// Router assigns session IDs, so we need to know them
|
|
127
|
+
// Let's just check the return value for accept/reject
|
|
128
|
+
const source = {
|
|
129
|
+
channelType: 'whatsapp', adapterId: 'wa-1', chatId: 'dm-1',
|
|
130
|
+
chatType: 'dm', senderId: 'random-user',
|
|
131
|
+
};
|
|
132
|
+
const payload = { type: 'text', text: 'hello' };
|
|
133
|
+
// Random user DM → denied (allowlist mode)
|
|
134
|
+
assert(router.route(source, payload, 'pol-1') === false, 'Random user blocked by allowlist');
|
|
135
|
+
// Allowed user DM → accepted
|
|
136
|
+
assert(router.route({ ...source, senderId: 'allowed-user' }, payload, 'pol-2') === true, 'Allowlisted user accepted');
|
|
137
|
+
// Owner DM → accepted
|
|
138
|
+
assert(router.route({ ...source, senderId: 'owner-1' }, payload, 'pol-3') === true, 'Owner always accepted');
|
|
139
|
+
// Global owner → accepted
|
|
140
|
+
assert(router.route({ ...source, senderId: 'global-owner' }, payload, 'pol-4') === true, 'Global owner accepted');
|
|
141
|
+
// Group without mention → denied
|
|
142
|
+
const groupSource = {
|
|
143
|
+
channelType: 'whatsapp', adapterId: 'wa-1', chatId: 'group-1',
|
|
144
|
+
chatType: 'group', senderId: 'allowed-user', mentions: [],
|
|
145
|
+
};
|
|
146
|
+
assert(router.route(groupSource, payload, 'pol-5') === false, 'Group message without mention blocked');
|
|
147
|
+
// Group with mention → accepted
|
|
148
|
+
assert(router.route({ ...groupSource, mentions: ['bot-id'] }, payload, 'pol-6') === true, 'Group message with @mention accepted');
|
|
149
|
+
bus.destroy();
|
|
150
|
+
}
|
|
151
|
+
// ─── Test: Deduplication ───────────────────────────────────────────────────
|
|
152
|
+
console.log('\n🔄 Deduplication');
|
|
153
|
+
{
|
|
154
|
+
const bus = new Mach6Bus({ coalesceWindowMs: 0 });
|
|
155
|
+
const router = new InboundRouter(bus, {
|
|
156
|
+
policies: new Map([['test', { dmPolicy: 'open', groupPolicy: 'open', ownerIds: [] }]]),
|
|
157
|
+
});
|
|
158
|
+
const source = {
|
|
159
|
+
channelType: 'test', adapterId: 't1', chatId: 'c1', chatType: 'dm', senderId: 'u1',
|
|
160
|
+
};
|
|
161
|
+
const payload = { type: 'text', text: 'hello' };
|
|
162
|
+
assert(router.route(source, payload, 'msg-001') === true, 'First message accepted');
|
|
163
|
+
assert(router.route(source, payload, 'msg-001') === false, 'Duplicate message rejected');
|
|
164
|
+
assert(router.route(source, payload, 'msg-002') === true, 'Different message ID accepted');
|
|
165
|
+
bus.destroy();
|
|
166
|
+
}
|
|
167
|
+
// ─── Test: Formatters ──────────────────────────────────────────────────────
|
|
168
|
+
console.log('\n📝 Formatters');
|
|
169
|
+
{
|
|
170
|
+
const markdown = `# Title
|
|
171
|
+
|
|
172
|
+
**Bold text** and *italic text*.
|
|
173
|
+
|
|
174
|
+
| Col A | Col B |
|
|
175
|
+
|-------|-------|
|
|
176
|
+
| one | two |
|
|
177
|
+
| three | four |
|
|
178
|
+
|
|
179
|
+
[Link](https://example.com)
|
|
180
|
+
|
|
181
|
+
\`\`\`typescript
|
|
182
|
+
const x = 1;
|
|
183
|
+
\`\`\``;
|
|
184
|
+
// WhatsApp
|
|
185
|
+
const waCaps = {
|
|
186
|
+
media: true, reactions: true, messageEdit: false, messageDelete: true,
|
|
187
|
+
threads: false, embeds: false, components: false, voiceNotes: true,
|
|
188
|
+
readReceipts: true, typingIndicator: true, ephemeral: true, polls: true,
|
|
189
|
+
formatting: 'whatsapp', maxMessageLength: 4096, maxMediaSize: 16 * 1024 * 1024,
|
|
190
|
+
rateLimits: {},
|
|
191
|
+
};
|
|
192
|
+
const waResult = formatForChannel(markdown, waCaps);
|
|
193
|
+
assert(!waResult[0].includes('# '), 'WhatsApp: headers converted (no #)');
|
|
194
|
+
assert(!waResult[0].includes('**'), 'WhatsApp: bold converted (no **)');
|
|
195
|
+
assert(waResult[0].includes('•'), 'WhatsApp: table converted to bullets');
|
|
196
|
+
// Discord
|
|
197
|
+
const discordCaps = {
|
|
198
|
+
...waCaps, formatting: 'markdown', maxMessageLength: 2000,
|
|
199
|
+
};
|
|
200
|
+
const discordResult = formatForChannel(markdown, discordCaps);
|
|
201
|
+
assert(discordResult[0].includes('# Title'), 'Discord: headers preserved');
|
|
202
|
+
assert(discordResult[0].includes('```'), 'Discord: tables become code blocks');
|
|
203
|
+
// Telegram
|
|
204
|
+
const tgCaps = {
|
|
205
|
+
...waCaps, formatting: 'html', maxMessageLength: 4096,
|
|
206
|
+
};
|
|
207
|
+
const tgResult = formatForChannel(markdown, tgCaps);
|
|
208
|
+
assert(tgResult[0].includes('<b>'), 'Telegram: converted to HTML bold');
|
|
209
|
+
assert(tgResult[0].includes('<a href='), 'Telegram: links converted to HTML');
|
|
210
|
+
// Split test
|
|
211
|
+
const longText = 'A'.repeat(5000);
|
|
212
|
+
const discordSplit = formatForChannel(longText, discordCaps);
|
|
213
|
+
assert(discordSplit.length > 1, 'Long message split for Discord (2000 limit)');
|
|
214
|
+
assert(discordSplit.every(c => c.length <= 2000), 'All chunks within limit');
|
|
215
|
+
}
|
|
216
|
+
// ─── Summary ───────────────────────────────────────────────────────────────
|
|
217
|
+
console.log(`\n${'─'.repeat(50)}`);
|
|
218
|
+
console.log(`Results: ${passed} passed, ${failed} failed`);
|
|
219
|
+
console.log(`${failed === 0 ? '🟢 All tests passed!' : '🔴 Some tests failed.'}\n`);
|
|
220
|
+
process.exit(failed > 0 ? 1 : 0);
|
|
221
|
+
//# sourceMappingURL=integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.test.js","sourceRoot":"","sources":["../../../src/channels/__test__/integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mach6 — Abstract Channel Adapter Base
|
|
3
|
+
*
|
|
4
|
+
* Provides common infrastructure (health tracking, reconnection logic,
|
|
5
|
+
* rate limiting) so concrete adapters only implement platform-specific I/O.
|
|
6
|
+
*/
|
|
7
|
+
import type { BusEnvelope, ChannelAdapter, ChannelCapabilities, ChannelConfig, ChannelSource, InboundPayload, AdapterHealth, OutboundMessage, SendResult } from './types.js';
|
|
8
|
+
import { HealthTracker } from './types.js';
|
|
9
|
+
export declare class TokenBucketLimiter {
|
|
10
|
+
private tokens;
|
|
11
|
+
private readonly maxTokens;
|
|
12
|
+
private readonly refillRate;
|
|
13
|
+
private lastRefill;
|
|
14
|
+
constructor(maxPerSecond: number, burstSize?: number);
|
|
15
|
+
/** Returns delay in ms before send is allowed. 0 = immediate. */
|
|
16
|
+
check(): number;
|
|
17
|
+
consume(): boolean;
|
|
18
|
+
private refill;
|
|
19
|
+
}
|
|
20
|
+
export declare abstract class BaseAdapter implements ChannelAdapter {
|
|
21
|
+
abstract readonly id: string;
|
|
22
|
+
abstract readonly channelType: string;
|
|
23
|
+
abstract readonly capabilities: ChannelCapabilities;
|
|
24
|
+
protected health: HealthTracker;
|
|
25
|
+
protected rateLimiter?: TokenBucketLimiter;
|
|
26
|
+
protected messageHandler?: (envelope: BusEnvelope) => void;
|
|
27
|
+
protected abortController?: AbortController;
|
|
28
|
+
protected reconnectAttempts: number;
|
|
29
|
+
protected maxReconnectAttempts: number;
|
|
30
|
+
protected reconnectBackoffMs: number;
|
|
31
|
+
connect(config: ChannelConfig, signal?: AbortSignal): Promise<void>;
|
|
32
|
+
disconnect(): Promise<void>;
|
|
33
|
+
reconnect(): Promise<void>;
|
|
34
|
+
getHealth(): AdapterHealth;
|
|
35
|
+
onMessage(handler: (envelope: BusEnvelope) => void): void;
|
|
36
|
+
onHealthChange(handler: (health: AdapterHealth) => void): void;
|
|
37
|
+
send(chatId: string, message: OutboundMessage): Promise<SendResult>;
|
|
38
|
+
/**
|
|
39
|
+
* Emit a normalized inbound message to the bus via the registered handler.
|
|
40
|
+
* Call this from platform event handlers.
|
|
41
|
+
*/
|
|
42
|
+
protected emit(source: ChannelSource, payload: InboundPayload, platformMessageId?: string): void;
|
|
43
|
+
protected isConnectionError(_err: unknown): boolean;
|
|
44
|
+
/** Connect to the platform */
|
|
45
|
+
protected abstract platformConnect(config: ChannelConfig): Promise<void>;
|
|
46
|
+
/** Disconnect from the platform */
|
|
47
|
+
protected abstract platformDisconnect(): Promise<void>;
|
|
48
|
+
/** Reconnect to the platform */
|
|
49
|
+
protected abstract platformReconnect(): Promise<void>;
|
|
50
|
+
/** Send a message on the platform */
|
|
51
|
+
protected abstract platformSend(chatId: string, message: OutboundMessage): Promise<SendResult>;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/channels/adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,cAAc,EACd,aAAa,EACb,eAAe,EACf,UAAU,EACX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAI3C,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,UAAU,CAAS;gBAEf,YAAY,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM;IAOpD,iEAAiE;IACjE,KAAK,IAAI,MAAM;IAMf,OAAO,IAAI,OAAO;IASlB,OAAO,CAAC,MAAM;CAMf;AAID,8BAAsB,WAAY,YAAW,cAAc;IACzD,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAEpD,SAAS,CAAC,MAAM,gBAAuB;IACvC,SAAS,CAAC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IAC3C,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,KAAK,IAAI,CAAC;IAC3D,SAAS,CAAC,eAAe,CAAC,EAAE,eAAe,CAAC;IAC5C,SAAS,CAAC,iBAAiB,SAAK;IAChC,SAAS,CAAC,oBAAoB,SAAM;IACpC,SAAS,CAAC,kBAAkB,SAAQ;IAI9B,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBnE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IA2BhC,SAAS,IAAI,aAAa;IAI1B,SAAS,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI;IAIzD,cAAc,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI;IAMxD,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;IAyBzE;;;OAGG;IACH,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI;IAehG,SAAS,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAOnD,8BAA8B;IAC9B,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IACxE,mCAAmC;IACnC,SAAS,CAAC,QAAQ,CAAC,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IACtD,gCAAgC;IAChC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IACrD,qCAAqC;IACrC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;CAC/F"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mach6 — Abstract Channel Adapter Base
|
|
3
|
+
*
|
|
4
|
+
* Provides common infrastructure (health tracking, reconnection logic,
|
|
5
|
+
* rate limiting) so concrete adapters only implement platform-specific I/O.
|
|
6
|
+
*/
|
|
7
|
+
import { randomUUID } from 'node:crypto';
|
|
8
|
+
import { HealthTracker } from './types.js';
|
|
9
|
+
// ─── Rate Limiter ──────────────────────────────────────────────────────────
|
|
10
|
+
export class TokenBucketLimiter {
|
|
11
|
+
tokens;
|
|
12
|
+
maxTokens;
|
|
13
|
+
refillRate; // tokens per ms
|
|
14
|
+
lastRefill;
|
|
15
|
+
constructor(maxPerSecond, burstSize) {
|
|
16
|
+
this.maxTokens = burstSize ?? maxPerSecond;
|
|
17
|
+
this.tokens = this.maxTokens;
|
|
18
|
+
this.refillRate = maxPerSecond / 1000;
|
|
19
|
+
this.lastRefill = Date.now();
|
|
20
|
+
}
|
|
21
|
+
/** Returns delay in ms before send is allowed. 0 = immediate. */
|
|
22
|
+
check() {
|
|
23
|
+
this.refill();
|
|
24
|
+
if (this.tokens >= 1)
|
|
25
|
+
return 0;
|
|
26
|
+
return Math.ceil((1 - this.tokens) / this.refillRate);
|
|
27
|
+
}
|
|
28
|
+
consume() {
|
|
29
|
+
this.refill();
|
|
30
|
+
if (this.tokens >= 1) {
|
|
31
|
+
this.tokens -= 1;
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
refill() {
|
|
37
|
+
const now = Date.now();
|
|
38
|
+
const elapsed = now - this.lastRefill;
|
|
39
|
+
this.tokens = Math.min(this.maxTokens, this.tokens + elapsed * this.refillRate);
|
|
40
|
+
this.lastRefill = now;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// ─── Abstract Base ─────────────────────────────────────────────────────────
|
|
44
|
+
export class BaseAdapter {
|
|
45
|
+
health = new HealthTracker();
|
|
46
|
+
rateLimiter;
|
|
47
|
+
messageHandler;
|
|
48
|
+
abortController;
|
|
49
|
+
reconnectAttempts = 0;
|
|
50
|
+
maxReconnectAttempts = 10;
|
|
51
|
+
reconnectBackoffMs = 1000;
|
|
52
|
+
// ── Lifecycle ──────────────────────────────────────────────────────────
|
|
53
|
+
async connect(config, signal) {
|
|
54
|
+
this.abortController = new AbortController();
|
|
55
|
+
// Setup rate limiter from capabilities
|
|
56
|
+
const rl = this.capabilities.rateLimits;
|
|
57
|
+
if (rl.messagesPerSecond) {
|
|
58
|
+
this.rateLimiter = new TokenBucketLimiter(rl.messagesPerSecond, rl.burstSize);
|
|
59
|
+
}
|
|
60
|
+
// Forward external abort signal
|
|
61
|
+
if (signal) {
|
|
62
|
+
signal.addEventListener('abort', () => this.abortController?.abort(), { once: true });
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
await this.platformConnect(config);
|
|
66
|
+
this.health.transition('connected');
|
|
67
|
+
this.reconnectAttempts = 0;
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
this.health.transition('disconnected', err instanceof Error ? err.message : String(err));
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async disconnect() {
|
|
75
|
+
this.abortController?.abort();
|
|
76
|
+
try {
|
|
77
|
+
await this.platformDisconnect();
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
this.health.transition('disconnected');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async reconnect() {
|
|
84
|
+
if (this.health.state === 'reconnecting')
|
|
85
|
+
return; // Already reconnecting
|
|
86
|
+
this.health.transition('disconnected');
|
|
87
|
+
this.health.transition('reconnecting');
|
|
88
|
+
while (this.reconnectAttempts < this.maxReconnectAttempts) {
|
|
89
|
+
this.reconnectAttempts++;
|
|
90
|
+
const delay = Math.min(this.reconnectBackoffMs * Math.pow(2, this.reconnectAttempts - 1), 60_000);
|
|
91
|
+
await sleep(delay);
|
|
92
|
+
try {
|
|
93
|
+
await this.platformReconnect();
|
|
94
|
+
this.health.transition('connected');
|
|
95
|
+
this.reconnectAttempts = 0;
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
console.error(`[${this.id}] Reconnect attempt ${this.reconnectAttempts} failed:`, err);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
this.health.transition('disconnected', `Max reconnect attempts (${this.maxReconnectAttempts}) exceeded`);
|
|
103
|
+
}
|
|
104
|
+
getHealth() {
|
|
105
|
+
return this.health.status;
|
|
106
|
+
}
|
|
107
|
+
onMessage(handler) {
|
|
108
|
+
this.messageHandler = handler;
|
|
109
|
+
}
|
|
110
|
+
onHealthChange(handler) {
|
|
111
|
+
this.health.onChange(handler);
|
|
112
|
+
}
|
|
113
|
+
// ── Outbound ───────────────────────────────────────────────────────────
|
|
114
|
+
async send(chatId, message) {
|
|
115
|
+
// Rate limit check
|
|
116
|
+
if (this.rateLimiter) {
|
|
117
|
+
const delay = this.rateLimiter.check();
|
|
118
|
+
if (delay > 0)
|
|
119
|
+
await sleep(delay);
|
|
120
|
+
this.rateLimiter.consume();
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
return await this.platformSend(chatId, message);
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
// Check if it's a connection issue
|
|
127
|
+
if (this.isConnectionError(err)) {
|
|
128
|
+
this.health.transition('degraded');
|
|
129
|
+
// Queue for retry? For now, return error.
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
success: false,
|
|
133
|
+
error: err instanceof Error ? err.message : String(err),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// ── Helpers for subclasses ─────────────────────────────────────────────
|
|
138
|
+
/**
|
|
139
|
+
* Emit a normalized inbound message to the bus via the registered handler.
|
|
140
|
+
* Call this from platform event handlers.
|
|
141
|
+
*/
|
|
142
|
+
emit(source, payload, platformMessageId) {
|
|
143
|
+
if (!this.messageHandler)
|
|
144
|
+
return;
|
|
145
|
+
const envelope = {
|
|
146
|
+
id: randomUUID(),
|
|
147
|
+
timestamp: Date.now(),
|
|
148
|
+
priority: 'normal', // Router will reassign priority
|
|
149
|
+
source,
|
|
150
|
+
payload,
|
|
151
|
+
metadata: { platformMessageId },
|
|
152
|
+
};
|
|
153
|
+
this.messageHandler(envelope);
|
|
154
|
+
}
|
|
155
|
+
isConnectionError(_err) {
|
|
156
|
+
// Subclasses can override with platform-specific checks
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// ─── Utility ───────────────────────────────────────────────────────────────
|
|
161
|
+
function sleep(ms) {
|
|
162
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/channels/adapter.ts"],"names":[],"mappings":"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"}
|