copilot-hub 0.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 +215 -0
- package/apps/agent-engine/.env.example +41 -0
- package/apps/agent-engine/LICENSE +21 -0
- package/apps/agent-engine/README.md +57 -0
- package/apps/agent-engine/bot-registry.example.json +28 -0
- package/apps/agent-engine/capabilities/example/index.js +3 -0
- package/apps/agent-engine/capabilities/example/manifest.json +14 -0
- package/apps/agent-engine/dist/agent-worker.js +241 -0
- package/apps/agent-engine/dist/config.js +225 -0
- package/apps/agent-engine/dist/index.js +352 -0
- package/apps/agent-engine/dist/test/project-fingerprint.test.js +40 -0
- package/apps/agent-engine/dist/test/thread-id.test.js +12 -0
- package/apps/agent-engine/package.json +28 -0
- package/apps/control-plane/.env.example +25 -0
- package/apps/control-plane/README.md +35 -0
- package/apps/control-plane/bot-registry.example.json +40 -0
- package/apps/control-plane/capabilities/example/index.js +3 -0
- package/apps/control-plane/capabilities/example/manifest.json +14 -0
- package/apps/control-plane/dist/agent-worker.js +243 -0
- package/apps/control-plane/dist/channels/channel-factory.js +21 -0
- package/apps/control-plane/dist/channels/hub-ops-commands.js +752 -0
- package/apps/control-plane/dist/channels/telegram-channel.js +743 -0
- package/apps/control-plane/dist/channels/whatsapp-channel.js +35 -0
- package/apps/control-plane/dist/config.js +230 -0
- package/apps/control-plane/dist/copilot-hub.js +138 -0
- package/apps/control-plane/dist/index.js +349 -0
- package/apps/control-plane/dist/kernel/admin-contract.js +51 -0
- package/apps/control-plane/dist/test/project-fingerprint.test.js +40 -0
- package/apps/control-plane/dist/test/thread-id.test.js +12 -0
- package/apps/control-plane/package.json +27 -0
- package/package.json +89 -0
- package/packages/contracts/README.md +10 -0
- package/packages/contracts/dist/control-plane.d.ts +24 -0
- package/packages/contracts/dist/control-plane.js +37 -0
- package/packages/contracts/dist/control-plane.js.map +1 -0
- package/packages/contracts/dist/index.d.ts +1 -0
- package/packages/contracts/dist/index.js +2 -0
- package/packages/contracts/dist/index.js.map +1 -0
- package/packages/contracts/package.json +27 -0
- package/packages/core/README.md +33 -0
- package/packages/core/dist/agent-supervisor.d.ts +39 -0
- package/packages/core/dist/agent-supervisor.js +552 -0
- package/packages/core/dist/agent-supervisor.js.map +1 -0
- package/packages/core/dist/bot-manager.d.ts +66 -0
- package/packages/core/dist/bot-manager.js +333 -0
- package/packages/core/dist/bot-manager.js.map +1 -0
- package/packages/core/dist/bot-registry.d.ts +60 -0
- package/packages/core/dist/bot-registry.js +381 -0
- package/packages/core/dist/bot-registry.js.map +1 -0
- package/packages/core/dist/bot-runtime.d.ts +135 -0
- package/packages/core/dist/bot-runtime.js +349 -0
- package/packages/core/dist/bot-runtime.js.map +1 -0
- package/packages/core/dist/bridge-service.d.ts +39 -0
- package/packages/core/dist/bridge-service.js +272 -0
- package/packages/core/dist/bridge-service.js.map +1 -0
- package/packages/core/dist/capability-manager.d.ts +18 -0
- package/packages/core/dist/capability-manager.js +335 -0
- package/packages/core/dist/capability-manager.js.map +1 -0
- package/packages/core/dist/capability-scaffold.d.ts +26 -0
- package/packages/core/dist/capability-scaffold.js +118 -0
- package/packages/core/dist/capability-scaffold.js.map +1 -0
- package/packages/core/dist/channel-factory.d.ts +6 -0
- package/packages/core/dist/channel-factory.js +22 -0
- package/packages/core/dist/channel-factory.js.map +1 -0
- package/packages/core/dist/codex-app-client.d.ts +56 -0
- package/packages/core/dist/codex-app-client.js +762 -0
- package/packages/core/dist/codex-app-client.js.map +1 -0
- package/packages/core/dist/codex-provider.d.ts +31 -0
- package/packages/core/dist/codex-provider.js +64 -0
- package/packages/core/dist/codex-provider.js.map +1 -0
- package/packages/core/dist/control-permission.d.ts +19 -0
- package/packages/core/dist/control-permission.js +106 -0
- package/packages/core/dist/control-permission.js.map +1 -0
- package/packages/core/dist/control-plane-actions.d.ts +1 -0
- package/packages/core/dist/control-plane-actions.js +2 -0
- package/packages/core/dist/control-plane-actions.js.map +1 -0
- package/packages/core/dist/example-capability.d.ts +17 -0
- package/packages/core/dist/example-capability.js +22 -0
- package/packages/core/dist/example-capability.js.map +1 -0
- package/packages/core/dist/extension-contract.d.ts +22 -0
- package/packages/core/dist/extension-contract.js +28 -0
- package/packages/core/dist/extension-contract.js.map +1 -0
- package/packages/core/dist/index.d.ts +26 -0
- package/packages/core/dist/index.js +27 -0
- package/packages/core/dist/index.js.map +1 -0
- package/packages/core/dist/instance-lock.d.ts +9 -0
- package/packages/core/dist/instance-lock.js +74 -0
- package/packages/core/dist/instance-lock.js.map +1 -0
- package/packages/core/dist/kernel-control-plane.d.ts +16 -0
- package/packages/core/dist/kernel-control-plane.js +500 -0
- package/packages/core/dist/kernel-control-plane.js.map +1 -0
- package/packages/core/dist/kernel-version.d.ts +1 -0
- package/packages/core/dist/kernel-version.js +2 -0
- package/packages/core/dist/kernel-version.js.map +1 -0
- package/packages/core/dist/project-fingerprint.d.ts +11 -0
- package/packages/core/dist/project-fingerprint.js +33 -0
- package/packages/core/dist/project-fingerprint.js.map +1 -0
- package/packages/core/dist/provider-factory.d.ts +7 -0
- package/packages/core/dist/provider-factory.js +21 -0
- package/packages/core/dist/provider-factory.js.map +1 -0
- package/packages/core/dist/secret-store.d.ts +18 -0
- package/packages/core/dist/secret-store.js +110 -0
- package/packages/core/dist/secret-store.js.map +1 -0
- package/packages/core/dist/state-store.d.ts +50 -0
- package/packages/core/dist/state-store.js +324 -0
- package/packages/core/dist/state-store.js.map +1 -0
- package/packages/core/dist/telegram-channel.d.ts +27 -0
- package/packages/core/dist/telegram-channel.js +951 -0
- package/packages/core/dist/telegram-channel.js.map +1 -0
- package/packages/core/dist/thread-id.d.ts +1 -0
- package/packages/core/dist/thread-id.js +12 -0
- package/packages/core/dist/thread-id.js.map +1 -0
- package/packages/core/dist/whatsapp-channel.d.ts +26 -0
- package/packages/core/dist/whatsapp-channel.js +36 -0
- package/packages/core/dist/whatsapp-channel.js.map +1 -0
- package/packages/core/dist/workspace-paths.d.ts +5 -0
- package/packages/core/dist/workspace-paths.js +77 -0
- package/packages/core/dist/workspace-paths.js.map +1 -0
- package/packages/core/dist/workspace-policy.d.ts +30 -0
- package/packages/core/dist/workspace-policy.js +104 -0
- package/packages/core/dist/workspace-policy.js.map +1 -0
- package/packages/core/package.json +126 -0
- package/scripts/cli.mjs +537 -0
- package/scripts/configure.mjs +254 -0
- package/scripts/ensure-shared-build.mjs +96 -0
- package/scripts/run-node-tests.mjs +52 -0
- package/scripts/supervisor.mjs +332 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Control Plane
|
|
2
|
+
|
|
3
|
+
`control-plane` is the single Telegram hub for Copilot Hub.
|
|
4
|
+
|
|
5
|
+
It handles:
|
|
6
|
+
- simple operations commands (`/help`, `/health`, `/bots`, `/create_agent`, `/cancel`)
|
|
7
|
+
- LLM development requests through normal chat messages
|
|
8
|
+
|
|
9
|
+
## Setup
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install
|
|
13
|
+
# Windows
|
|
14
|
+
copy .env.example .env
|
|
15
|
+
# macOS/Linux
|
|
16
|
+
cp .env.example .env
|
|
17
|
+
npm run start
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Required env:
|
|
21
|
+
- `HUB_TELEGRAM_TOKEN` (or custom `HUB_TELEGRAM_TOKEN_ENV`)
|
|
22
|
+
|
|
23
|
+
Recommended env:
|
|
24
|
+
- `HUB_ENGINE_BASE_URL` (default: `http://127.0.0.1:8787`)
|
|
25
|
+
|
|
26
|
+
## Workspace and policy guards
|
|
27
|
+
|
|
28
|
+
- `HUB_WORKSPACE_ROOT` is validated against shared workspace policy.
|
|
29
|
+
- `HUB_IMMUTABLE_CORE=true` prevents unsafe hub runtime policy combinations.
|
|
30
|
+
- `WORKSPACE_STRICT_MODE` and `WORKSPACE_ALLOWED_ROOTS` follow the same boundary model as `agent-engine`.
|
|
31
|
+
|
|
32
|
+
## Responsibility boundary
|
|
33
|
+
|
|
34
|
+
- `control-plane`: operator chat + development assistant.
|
|
35
|
+
- `agent-engine`: execution of worker agents.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"agents": [
|
|
4
|
+
{
|
|
5
|
+
"id": "admin_agent",
|
|
6
|
+
"name": "Admin Agent",
|
|
7
|
+
"enabled": true,
|
|
8
|
+
"autoStart": true,
|
|
9
|
+
"dataDir": "./data/bots/admin_agent",
|
|
10
|
+
"threadMode": "single",
|
|
11
|
+
"sharedThreadId": "shared-admin",
|
|
12
|
+
"provider": {
|
|
13
|
+
"kind": "codex",
|
|
14
|
+
"options": {}
|
|
15
|
+
},
|
|
16
|
+
"kernelAccess": {
|
|
17
|
+
"enabled": true,
|
|
18
|
+
"allowedActions": [
|
|
19
|
+
"*"
|
|
20
|
+
],
|
|
21
|
+
"allowedChatIds": []
|
|
22
|
+
},
|
|
23
|
+
"channels": [
|
|
24
|
+
{
|
|
25
|
+
"kind": "telegram",
|
|
26
|
+
"id": "telegram_admin",
|
|
27
|
+
"tokenEnv": "TELEGRAM_TOKEN_ADMIN"
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"capabilities": [
|
|
31
|
+
{
|
|
32
|
+
"id": "example",
|
|
33
|
+
"manifestPath": "./capabilities/example/manifest.json",
|
|
34
|
+
"enabled": true,
|
|
35
|
+
"options": {}
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "example-capability",
|
|
3
|
+
"name": "Example Capability",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"entry": "./index.js",
|
|
6
|
+
"minKernelVersion": "1.0.0",
|
|
7
|
+
"timeoutMs": 3000,
|
|
8
|
+
"hooks": [
|
|
9
|
+
"onRuntimeStart",
|
|
10
|
+
"onTurnStart",
|
|
11
|
+
"onTurnResult"
|
|
12
|
+
],
|
|
13
|
+
"permissions": []
|
|
14
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { BotRuntime } from "@copilot-hub/core/bot-runtime";
|
|
3
|
+
import { createChannelAdapter } from "./channels/channel-factory.js";
|
|
4
|
+
const rawBotConfig = String(process.env.AGENT_BOT_CONFIG_JSON ?? "").trim();
|
|
5
|
+
const rawProviderDefaults = String(process.env.AGENT_PROVIDER_DEFAULTS_JSON ?? "").trim();
|
|
6
|
+
const turnActivityTimeoutMs = Number.parseInt(String(process.env.AGENT_TURN_ACTIVITY_TIMEOUT_MS ?? "3600000"), 10);
|
|
7
|
+
const maxMessages = Number.parseInt(String(process.env.AGENT_MAX_MESSAGES ?? "200"), 10);
|
|
8
|
+
const initialWebPublicBaseUrl = String(process.env.AGENT_WEB_PUBLIC_BASE_URL ?? "http://127.0.0.1:8787").trim();
|
|
9
|
+
const kernelRequestTimeoutMs = Number.parseInt(String(process.env.AGENT_KERNEL_REQUEST_TIMEOUT_MS ?? "20000"), 10);
|
|
10
|
+
if (!rawBotConfig) {
|
|
11
|
+
throw new Error("AGENT_BOT_CONFIG_JSON is required.");
|
|
12
|
+
}
|
|
13
|
+
const botConfig = JSON.parse(rawBotConfig);
|
|
14
|
+
const providerDefaults = rawProviderDefaults ? JSON.parse(rawProviderDefaults) : {};
|
|
15
|
+
let nextKernelRequestId = 1;
|
|
16
|
+
const pendingKernelRequests = new Map();
|
|
17
|
+
const runtime = new BotRuntime({
|
|
18
|
+
botConfig,
|
|
19
|
+
providerDefaults,
|
|
20
|
+
turnActivityTimeoutMs,
|
|
21
|
+
maxMessages,
|
|
22
|
+
kernelControl: {
|
|
23
|
+
request: (payload) => requestKernelAction(payload),
|
|
24
|
+
},
|
|
25
|
+
channelAdapterFactory: createChannelAdapter,
|
|
26
|
+
});
|
|
27
|
+
runtime.setWebPublicBaseUrl(initialWebPublicBaseUrl);
|
|
28
|
+
process.on("message", (message) => {
|
|
29
|
+
void handleInboundMessage(message);
|
|
30
|
+
});
|
|
31
|
+
process.on("disconnect", () => {
|
|
32
|
+
void gracefulShutdown(0);
|
|
33
|
+
});
|
|
34
|
+
process.on("SIGINT", () => {
|
|
35
|
+
void gracefulShutdown(0);
|
|
36
|
+
});
|
|
37
|
+
process.on("SIGTERM", () => {
|
|
38
|
+
void gracefulShutdown(0);
|
|
39
|
+
});
|
|
40
|
+
process.on("uncaughtException", (error) => {
|
|
41
|
+
console.error(`Worker uncaught exception: ${sanitizeError(error)}`);
|
|
42
|
+
void gracefulShutdown(1);
|
|
43
|
+
});
|
|
44
|
+
process.on("unhandledRejection", (reason) => {
|
|
45
|
+
console.error(`Worker unhandled rejection: ${sanitizeError(reason)}`);
|
|
46
|
+
void gracefulShutdown(1);
|
|
47
|
+
});
|
|
48
|
+
sendEvent("workerReady", {
|
|
49
|
+
runtimeId: runtime.id,
|
|
50
|
+
name: runtime.name,
|
|
51
|
+
});
|
|
52
|
+
async function handleInboundMessage(message) {
|
|
53
|
+
const type = String(message?.type ?? "request").trim();
|
|
54
|
+
if (type === "kernelResponse") {
|
|
55
|
+
handleKernelResponse(message);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (type !== "request") {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
await handleWorkerRequest(message);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
const requestId = message?.requestId ?? null;
|
|
66
|
+
if (requestId !== null && requestId !== undefined) {
|
|
67
|
+
sendResponse({
|
|
68
|
+
requestId,
|
|
69
|
+
ok: false,
|
|
70
|
+
error: sanitizeError(error),
|
|
71
|
+
});
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
console.error(`Worker inbound message failed: ${sanitizeError(error)}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async function handleWorkerRequest(message) {
|
|
78
|
+
const requestId = message?.requestId;
|
|
79
|
+
const action = String(message?.action ?? "").trim();
|
|
80
|
+
const payload = message?.payload ?? {};
|
|
81
|
+
if (!requestId) {
|
|
82
|
+
throw new Error("requestId is required.");
|
|
83
|
+
}
|
|
84
|
+
if (!action) {
|
|
85
|
+
throw new Error("action is required.");
|
|
86
|
+
}
|
|
87
|
+
let result;
|
|
88
|
+
switch (action) {
|
|
89
|
+
case "getStatus": {
|
|
90
|
+
result = runtime.getStatus();
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
case "startChannels": {
|
|
94
|
+
result = await runtime.startChannels();
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
case "stopChannels": {
|
|
98
|
+
result = await runtime.stopChannels();
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
case "resetWebThread": {
|
|
102
|
+
result = await runtime.resetWebThread();
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
case "listPendingApprovals": {
|
|
106
|
+
const threadId = payload?.threadId ? String(payload.threadId) : undefined;
|
|
107
|
+
result = await runtime.listPendingApprovals(threadId);
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case "resolvePendingApproval": {
|
|
111
|
+
result = await runtime.resolvePendingApproval({
|
|
112
|
+
threadId: String(payload?.threadId ?? ""),
|
|
113
|
+
approvalId: String(payload?.approvalId ?? ""),
|
|
114
|
+
decision: String(payload?.decision ?? ""),
|
|
115
|
+
});
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
case "reloadCapabilities": {
|
|
119
|
+
const capabilityDefinitions = Array.isArray(payload?.capabilityDefinitions)
|
|
120
|
+
? payload.capabilityDefinitions
|
|
121
|
+
: null;
|
|
122
|
+
result = await runtime.reloadCapabilities(capabilityDefinitions);
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
case "setProjectRoot": {
|
|
126
|
+
const projectRoot = String(payload?.projectRoot ?? "").trim();
|
|
127
|
+
if (!projectRoot) {
|
|
128
|
+
throw new Error("projectRoot is required.");
|
|
129
|
+
}
|
|
130
|
+
await runtime.setProjectRoot(projectRoot);
|
|
131
|
+
result = runtime.getStatus();
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
case "setWebPublicBaseUrl": {
|
|
135
|
+
const value = String(payload?.webPublicBaseUrl ?? "").trim();
|
|
136
|
+
if (!value) {
|
|
137
|
+
throw new Error("webPublicBaseUrl is required.");
|
|
138
|
+
}
|
|
139
|
+
runtime.setWebPublicBaseUrl(value);
|
|
140
|
+
result = runtime.getStatus();
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
case "shutdown": {
|
|
144
|
+
await runtime.shutdown();
|
|
145
|
+
result = { ok: true };
|
|
146
|
+
sendResponse({ requestId, ok: true, result });
|
|
147
|
+
process.exit(0);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
default: {
|
|
151
|
+
throw new Error(`Unsupported worker action '${action}'.`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
sendResponse({ requestId, ok: true, result });
|
|
155
|
+
}
|
|
156
|
+
async function gracefulShutdown(exitCode) {
|
|
157
|
+
try {
|
|
158
|
+
await runtime.shutdown();
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// Ignore shutdown errors during process termination.
|
|
162
|
+
}
|
|
163
|
+
for (const pending of pendingKernelRequests.values()) {
|
|
164
|
+
clearTimeout(pending.timer);
|
|
165
|
+
pending.reject(new Error("Worker process is shutting down."));
|
|
166
|
+
}
|
|
167
|
+
pendingKernelRequests.clear();
|
|
168
|
+
process.exit(exitCode);
|
|
169
|
+
}
|
|
170
|
+
function sendResponse(value) {
|
|
171
|
+
if (!process.send) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
process.send({
|
|
175
|
+
type: "response",
|
|
176
|
+
...value,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
function sendEvent(event, payload) {
|
|
180
|
+
if (!process.send) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
process.send({
|
|
184
|
+
type: "event",
|
|
185
|
+
event,
|
|
186
|
+
payload,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
function requestKernelAction({ action, payload, context }) {
|
|
190
|
+
if (!process.send) {
|
|
191
|
+
return Promise.reject(new Error("Kernel IPC is unavailable."));
|
|
192
|
+
}
|
|
193
|
+
const requestId = `kreq_${Date.now()}_${nextKernelRequestId++}`;
|
|
194
|
+
const timeoutMs = Number.isFinite(kernelRequestTimeoutMs) && kernelRequestTimeoutMs >= 1000
|
|
195
|
+
? kernelRequestTimeoutMs
|
|
196
|
+
: 20000;
|
|
197
|
+
return new Promise((resolve, reject) => {
|
|
198
|
+
const timer = setTimeout(() => {
|
|
199
|
+
pendingKernelRequests.delete(requestId);
|
|
200
|
+
reject(new Error(`Kernel request '${String(action ?? "")}' timed out after ${timeoutMs}ms.`));
|
|
201
|
+
}, timeoutMs);
|
|
202
|
+
pendingKernelRequests.set(requestId, {
|
|
203
|
+
resolve,
|
|
204
|
+
reject,
|
|
205
|
+
timer,
|
|
206
|
+
});
|
|
207
|
+
try {
|
|
208
|
+
process.send({
|
|
209
|
+
type: "kernelRequest",
|
|
210
|
+
requestId,
|
|
211
|
+
action,
|
|
212
|
+
payload,
|
|
213
|
+
context,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
clearTimeout(timer);
|
|
218
|
+
pendingKernelRequests.delete(requestId);
|
|
219
|
+
reject(error);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
function handleKernelResponse(message) {
|
|
224
|
+
const requestId = String(message?.requestId ?? "").trim();
|
|
225
|
+
if (!requestId) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
const pending = pendingKernelRequests.get(requestId);
|
|
229
|
+
if (!pending) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
pendingKernelRequests.delete(requestId);
|
|
233
|
+
clearTimeout(pending.timer);
|
|
234
|
+
if (message?.ok) {
|
|
235
|
+
pending.resolve(message.result);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
pending.reject(new Error(String(message?.error ?? "Unknown kernel response error.")));
|
|
239
|
+
}
|
|
240
|
+
function sanitizeError(error) {
|
|
241
|
+
const raw = error instanceof Error ? error.message : String(error);
|
|
242
|
+
return raw.split(/\r?\n/).slice(0, 12).join("\n");
|
|
243
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { TelegramChannel } from "./telegram-channel.js";
|
|
3
|
+
import { WhatsAppChannel } from "./whatsapp-channel.js";
|
|
4
|
+
export function createChannelAdapter({ channelConfig, runtime }) {
|
|
5
|
+
const kind = String(channelConfig?.kind ?? "")
|
|
6
|
+
.trim()
|
|
7
|
+
.toLowerCase();
|
|
8
|
+
if (kind === "telegram") {
|
|
9
|
+
return new TelegramChannel({
|
|
10
|
+
channelConfig,
|
|
11
|
+
runtime,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
if (kind === "whatsapp") {
|
|
15
|
+
return new WhatsAppChannel({
|
|
16
|
+
channelConfig,
|
|
17
|
+
runtime,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
throw new Error(`Unsupported channel kind '${kind}'.`);
|
|
21
|
+
}
|