@openclaw/crabline 0.0.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.
Files changed (111) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +226 -0
  3. package/dist/src/bin/crabline.d.ts +2 -0
  4. package/dist/src/bin/crabline.js +7 -0
  5. package/dist/src/bin/crabline.js.map +1 -0
  6. package/dist/src/cli/program.d.ts +5 -0
  7. package/dist/src/cli/program.js +295 -0
  8. package/dist/src/cli/program.js.map +1 -0
  9. package/dist/src/config/load.d.ts +6 -0
  10. package/dist/src/config/load.js +41 -0
  11. package/dist/src/config/load.js.map +1 -0
  12. package/dist/src/config/schema.d.ts +1571 -0
  13. package/dist/src/config/schema.js +528 -0
  14. package/dist/src/config/schema.js.map +1 -0
  15. package/dist/src/core/errors.d.ts +12 -0
  16. package/dist/src/core/errors.js +28 -0
  17. package/dist/src/core/errors.js.map +1 -0
  18. package/dist/src/core/exit-codes.d.ts +13 -0
  19. package/dist/src/core/exit-codes.js +13 -0
  20. package/dist/src/core/exit-codes.js.map +1 -0
  21. package/dist/src/core/matcher.d.ts +2 -0
  22. package/dist/src/core/matcher.js +30 -0
  23. package/dist/src/core/matcher.js.map +1 -0
  24. package/dist/src/core/message-template.d.ts +2 -0
  25. package/dist/src/core/message-template.js +20 -0
  26. package/dist/src/core/message-template.js.map +1 -0
  27. package/dist/src/core/nonces.d.ts +2 -0
  28. package/dist/src/core/nonces.js +11 -0
  29. package/dist/src/core/nonces.js.map +1 -0
  30. package/dist/src/core/reporters.d.ts +3 -0
  31. package/dist/src/core/reporters.js +23 -0
  32. package/dist/src/core/reporters.js.map +1 -0
  33. package/dist/src/core/run.d.ts +30 -0
  34. package/dist/src/core/run.js +240 -0
  35. package/dist/src/core/run.js.map +1 -0
  36. package/dist/src/fake-servers/index.d.ts +10 -0
  37. package/dist/src/fake-servers/index.js +12 -0
  38. package/dist/src/fake-servers/index.js.map +1 -0
  39. package/dist/src/fake-servers/telegram.d.ts +29 -0
  40. package/dist/src/fake-servers/telegram.js +346 -0
  41. package/dist/src/fake-servers/telegram.js.map +1 -0
  42. package/dist/src/index.d.ts +15 -0
  43. package/dist/src/index.js +9 -0
  44. package/dist/src/index.js.map +1 -0
  45. package/dist/src/openclaw.d.ts +102 -0
  46. package/dist/src/openclaw.js +289 -0
  47. package/dist/src/openclaw.js.map +1 -0
  48. package/dist/src/providers/builtin/discord.d.ts +15 -0
  49. package/dist/src/providers/builtin/discord.js +92 -0
  50. package/dist/src/providers/builtin/discord.js.map +1 -0
  51. package/dist/src/providers/builtin/feishu.d.ts +10 -0
  52. package/dist/src/providers/builtin/feishu.js +95 -0
  53. package/dist/src/providers/builtin/feishu.js.map +1 -0
  54. package/dist/src/providers/builtin/googlechat.d.ts +11 -0
  55. package/dist/src/providers/builtin/googlechat.js +83 -0
  56. package/dist/src/providers/builtin/googlechat.js.map +1 -0
  57. package/dist/src/providers/builtin/imessage.d.ts +11 -0
  58. package/dist/src/providers/builtin/imessage.js +67 -0
  59. package/dist/src/providers/builtin/imessage.js.map +1 -0
  60. package/dist/src/providers/builtin/loopback.d.ts +63 -0
  61. package/dist/src/providers/builtin/loopback.js +174 -0
  62. package/dist/src/providers/builtin/loopback.js.map +1 -0
  63. package/dist/src/providers/builtin/matrix.d.ts +21 -0
  64. package/dist/src/providers/builtin/matrix.js +84 -0
  65. package/dist/src/providers/builtin/matrix.js.map +1 -0
  66. package/dist/src/providers/builtin/mattermost.d.ts +11 -0
  67. package/dist/src/providers/builtin/mattermost.js +67 -0
  68. package/dist/src/providers/builtin/mattermost.js.map +1 -0
  69. package/dist/src/providers/builtin/msteams.d.ts +13 -0
  70. package/dist/src/providers/builtin/msteams.js +72 -0
  71. package/dist/src/providers/builtin/msteams.js.map +1 -0
  72. package/dist/src/providers/builtin/native-local-mock.d.ts +48 -0
  73. package/dist/src/providers/builtin/native-local-mock.js +119 -0
  74. package/dist/src/providers/builtin/native-local-mock.js.map +1 -0
  75. package/dist/src/providers/builtin/script.d.ts +39 -0
  76. package/dist/src/providers/builtin/script.js +206 -0
  77. package/dist/src/providers/builtin/script.js.map +1 -0
  78. package/dist/src/providers/builtin/slack.d.ts +6 -0
  79. package/dist/src/providers/builtin/slack.js +106 -0
  80. package/dist/src/providers/builtin/slack.js.map +1 -0
  81. package/dist/src/providers/builtin/telegram.d.ts +21 -0
  82. package/dist/src/providers/builtin/telegram.js +123 -0
  83. package/dist/src/providers/builtin/telegram.js.map +1 -0
  84. package/dist/src/providers/builtin/whatsapp.d.ts +19 -0
  85. package/dist/src/providers/builtin/whatsapp.js +90 -0
  86. package/dist/src/providers/builtin/whatsapp.js.map +1 -0
  87. package/dist/src/providers/builtin/zalo.d.ts +17 -0
  88. package/dist/src/providers/builtin/zalo.js +70 -0
  89. package/dist/src/providers/builtin/zalo.js.map +1 -0
  90. package/dist/src/providers/catalog.d.ts +69 -0
  91. package/dist/src/providers/catalog.js +95 -0
  92. package/dist/src/providers/catalog.js.map +1 -0
  93. package/dist/src/providers/local-mock.d.ts +41 -0
  94. package/dist/src/providers/local-mock.js +243 -0
  95. package/dist/src/providers/local-mock.js.map +1 -0
  96. package/dist/src/providers/recorder.d.ts +19 -0
  97. package/dist/src/providers/recorder.js +160 -0
  98. package/dist/src/providers/recorder.js.map +1 -0
  99. package/dist/src/providers/registry.d.ts +8 -0
  100. package/dist/src/providers/registry.js +171 -0
  101. package/dist/src/providers/registry.js.map +1 -0
  102. package/dist/src/providers/types.d.ts +94 -0
  103. package/dist/src/providers/types.js +2 -0
  104. package/dist/src/providers/types.js.map +1 -0
  105. package/dist/src/providers/webhook-server.d.ts +12 -0
  106. package/dist/src/providers/webhook-server.js +118 -0
  107. package/dist/src/providers/webhook-server.js.map +1 -0
  108. package/docs/channel-setup.md +181 -0
  109. package/fixtures/examples/crabline.example.yaml +195 -0
  110. package/fixtures/examples/openclaw-bridge.yaml +125 -0
  111. package/package.json +64 -0
@@ -0,0 +1,243 @@
1
+ import path from "node:path";
2
+ import { CrablineError, ensureErrorMessage } from "../core/errors.js";
3
+ import { appendRecordedInbound, waitForRecordedInbound, watchRecordedInbound } from "./recorder.js";
4
+ import { startWebhookServer } from "./webhook-server.js";
5
+ export function createGenericLocalMockTargetCodec(platform) {
6
+ const prefix = `${platform}:`;
7
+ const encode = (value) => (value.startsWith(prefix) ? value : `${prefix}${value}`);
8
+ return {
9
+ normalize(target) {
10
+ const normalized = {
11
+ id: target.id,
12
+ metadata: target.metadata,
13
+ };
14
+ if (target.channelId) {
15
+ normalized.channelId = encode(target.channelId);
16
+ }
17
+ else if (!target.threadId) {
18
+ normalized.channelId = encode(target.id);
19
+ }
20
+ if (target.threadId) {
21
+ normalized.channelId ??= encode(target.id);
22
+ normalized.threadId = target.threadId.startsWith(prefix)
23
+ ? target.threadId
24
+ : `${normalized.channelId}:${target.threadId}`;
25
+ }
26
+ return normalized;
27
+ },
28
+ resolveThreadId(target) {
29
+ const normalized = this.normalize(target);
30
+ return normalized.threadId ?? normalized.channelId ?? encode(normalized.id);
31
+ },
32
+ };
33
+ }
34
+ function sleep(ms) {
35
+ return new Promise((resolve) => setTimeout(resolve, ms));
36
+ }
37
+ function isAddressInChannel(threadId, channelId) {
38
+ if (!channelId) {
39
+ return true;
40
+ }
41
+ return threadId === channelId || threadId.startsWith(`${channelId}:`);
42
+ }
43
+ function createMessageId(platform) {
44
+ return `${platform}-mock-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
45
+ }
46
+ function toRecorderPath(providerId, configuredPath) {
47
+ return configuredPath
48
+ ? path.resolve(configuredPath)
49
+ : path.resolve(".crabline", "recorders", `${providerId}.jsonl`);
50
+ }
51
+ function authorFromPayload(payload) {
52
+ const explicit = payload.message?.author ?? payload.author;
53
+ if (explicit) {
54
+ return explicit;
55
+ }
56
+ return (payload.message?.authorIsBot ?? payload.authorIsBot ?? true) ? "assistant" : "user";
57
+ }
58
+ function normalizeWebhookPayload(payload) {
59
+ if (!payload || typeof payload !== "object") {
60
+ throw new CrablineError("mock webhook payload must be an object", { kind: "inbound" });
61
+ }
62
+ return payload;
63
+ }
64
+ function mockReplyText(params) {
65
+ return `[${params.platform} mock] ${params.text}`;
66
+ }
67
+ export class LocalMockProviderAdapter {
68
+ id;
69
+ platform;
70
+ status = "ready";
71
+ supports = ["probe", "send", "roundtrip", "agent"];
72
+ #codec;
73
+ #config;
74
+ #options;
75
+ #recorderPath;
76
+ #server = null;
77
+ constructor(params) {
78
+ this.id = params.id;
79
+ this.platform = params.options.platform;
80
+ this.#codec = params.codec;
81
+ this.#config = params.config;
82
+ this.#options = params.options;
83
+ this.#recorderPath = toRecorderPath(params.id, params.options.recorderPath);
84
+ }
85
+ normalizeTarget(target) {
86
+ return this.#codec.normalize(target);
87
+ }
88
+ async probe(context) {
89
+ const server = await this.#ensureWebhookServer(true);
90
+ const target = this.normalizeTarget(context.fixture.target);
91
+ const details = [
92
+ `${this.platform} local mock ready`,
93
+ `recorder path ${this.#recorderPath}`,
94
+ `${this.#options.endpointLabel} ${server.endpointUrl}`,
95
+ ];
96
+ if (this.#options.publicUrl) {
97
+ details.push(`public webhook ${this.#options.publicUrl}`);
98
+ }
99
+ if (target.threadId) {
100
+ details.push(`thread reachable ${target.threadId}`);
101
+ }
102
+ else if (target.channelId) {
103
+ details.push(`channel reachable ${target.channelId}`);
104
+ }
105
+ else {
106
+ details.push(`dm reachable ${this.#codec.resolveThreadId(context.fixture.target)}`);
107
+ }
108
+ return { details, healthy: true };
109
+ }
110
+ async send(context) {
111
+ const threadId = this.#codec.resolveThreadId(context.fixture.target);
112
+ const messageId = createMessageId(this.platform);
113
+ await appendRecordedInbound(this.#recorderPath, {
114
+ author: "user",
115
+ id: messageId,
116
+ provider: this.id,
117
+ raw: {
118
+ direction: "outbound",
119
+ mode: context.mode,
120
+ platform: this.platform,
121
+ },
122
+ sentAt: new Date().toISOString(),
123
+ text: context.text,
124
+ threadId,
125
+ });
126
+ if (context.mode !== "send" && context.fixture.target.behavior !== "sink") {
127
+ await sleep(this.#config.loopback?.delayMs ?? 25);
128
+ await appendRecordedInbound(this.#recorderPath, {
129
+ author: "assistant",
130
+ id: `${messageId}-reply`,
131
+ provider: this.id,
132
+ raw: {
133
+ direction: "mock-reply",
134
+ mode: context.mode,
135
+ platform: this.platform,
136
+ },
137
+ sentAt: new Date().toISOString(),
138
+ text: mockReplyText({ platform: this.platform, text: context.text }),
139
+ threadId,
140
+ });
141
+ }
142
+ return {
143
+ accepted: true,
144
+ messageId,
145
+ threadId,
146
+ };
147
+ }
148
+ async waitForInbound(context) {
149
+ await this.#ensureWebhookServer(true);
150
+ const target = this.normalizeTarget(context.fixture.target);
151
+ const expectedAuthor = context.fixture.inboundMatch.author;
152
+ return await waitForRecordedInbound({
153
+ filePath: this.#recorderPath,
154
+ matches: (event) => event.provider === this.id &&
155
+ (expectedAuthor === "any" || event.author === expectedAuthor) &&
156
+ isAddressInChannel(event.threadId, context.threadId ?? target.threadId ?? target.channelId),
157
+ since: context.since,
158
+ timeoutMs: context.timeoutMs,
159
+ });
160
+ }
161
+ async *watch(context) {
162
+ await this.#ensureWebhookServer(false);
163
+ const target = this.normalizeTarget(context.fixture.target);
164
+ for await (const event of watchRecordedInbound({
165
+ filePath: this.#recorderPath,
166
+ matches: (entry) => entry.provider === this.id &&
167
+ isAddressInChannel(entry.threadId, target.threadId ?? target.channelId),
168
+ since: context.since,
169
+ })) {
170
+ yield event;
171
+ }
172
+ }
173
+ async cleanup() {
174
+ if (!this.#server) {
175
+ return;
176
+ }
177
+ await this.#server.close();
178
+ this.#server = null;
179
+ }
180
+ async #handleWebhook(request) {
181
+ if (!request.headers.get("content-type")?.includes("application/json")) {
182
+ return new Response("expected application/json", { status: 415 });
183
+ }
184
+ let payload;
185
+ try {
186
+ const rawPayload = await request.json();
187
+ payload = normalizeWebhookPayload(this.#options.normalizeWebhookPayload
188
+ ? this.#options.normalizeWebhookPayload(rawPayload)
189
+ : rawPayload);
190
+ }
191
+ catch (error) {
192
+ return new Response(ensureErrorMessage(error), { status: 400 });
193
+ }
194
+ const id = payload.message?.id ?? payload.id ?? createMessageId(this.platform);
195
+ const threadId = payload.message?.threadId ?? payload.threadId;
196
+ const text = payload.message?.text ?? payload.text;
197
+ if (!threadId || !text) {
198
+ return new Response("payload requires message.threadId and message.text", { status: 400 });
199
+ }
200
+ await appendRecordedInbound(this.#recorderPath, {
201
+ author: authorFromPayload(payload),
202
+ id,
203
+ provider: this.id,
204
+ raw: payload.message?.raw ?? payload.raw ?? payload,
205
+ sentAt: new Date().toISOString(),
206
+ text,
207
+ threadId,
208
+ });
209
+ return new Response(JSON.stringify({ ok: true, id }), {
210
+ headers: { "content-type": "application/json" },
211
+ status: 200,
212
+ });
213
+ }
214
+ async #ensureWebhookServer(allowExisting) {
215
+ if (this.#server) {
216
+ return this.#server;
217
+ }
218
+ const webhook = this.#options.webhook;
219
+ const host = webhook?.host ?? this.#options.defaultWebhook.host;
220
+ const port = webhook?.port ?? this.#options.defaultWebhook.port;
221
+ const webhookPath = webhook?.path ?? this.#options.defaultWebhook.path;
222
+ try {
223
+ this.#server = await startWebhookServer({
224
+ handle: (request) => this.#handleWebhook(request),
225
+ host,
226
+ path: webhookPath,
227
+ port,
228
+ });
229
+ return this.#server;
230
+ }
231
+ catch (error) {
232
+ const code = error.code;
233
+ if (allowExisting && code === "EADDRINUSE") {
234
+ return {
235
+ async close() { },
236
+ endpointUrl: `http://${host}:${port}${webhookPath}`,
237
+ };
238
+ }
239
+ throw new CrablineError(`${this.platform} local mock webhook server failed: ${ensureErrorMessage(error)}`, { cause: error, kind: "connectivity" });
240
+ }
241
+ }
242
+ }
243
+ //# sourceMappingURL=local-mock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-mock.js","sourceRoot":"","sources":["../../../src/providers/local-mock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { InboundEnvelope } from "./types.js";
2
+ export type RecordedInboundEnvelope = InboundEnvelope & {
3
+ recordedAt: string;
4
+ };
5
+ export declare function appendRecordedInbound(filePath: string, event: InboundEnvelope): Promise<RecordedInboundEnvelope>;
6
+ export declare function readRecordedInbound(filePath: string): Promise<RecordedInboundEnvelope[]>;
7
+ export declare function waitForRecordedInbound(params: {
8
+ filePath: string;
9
+ matches: (event: RecordedInboundEnvelope) => boolean;
10
+ pollMs?: number;
11
+ since?: string | undefined;
12
+ timeoutMs: number;
13
+ }): Promise<RecordedInboundEnvelope | null>;
14
+ export declare function watchRecordedInbound(params: {
15
+ filePath: string;
16
+ matches: (event: RecordedInboundEnvelope) => boolean;
17
+ pollMs?: number;
18
+ since?: string | undefined;
19
+ }): AsyncIterable<RecordedInboundEnvelope>;
@@ -0,0 +1,160 @@
1
+ import { appendFile, mkdir, open, readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ function sleep(ms) {
4
+ return new Promise((resolve) => setTimeout(resolve, ms));
5
+ }
6
+ function toRecordKey(event) {
7
+ return `${event.provider}:${event.threadId}:${event.id}`;
8
+ }
9
+ const MAX_WATCH_SEEN_KEYS = 4096;
10
+ async function readRecordedInboundAppend(filePath, state) {
11
+ let handle;
12
+ try {
13
+ handle = await open(filePath, "r");
14
+ }
15
+ catch (error) {
16
+ const code = error.code;
17
+ if (code === "ENOENT") {
18
+ state.offset = 0;
19
+ state.pending = Buffer.alloc(0);
20
+ return [];
21
+ }
22
+ throw error;
23
+ }
24
+ try {
25
+ const size = (await handle.stat()).size;
26
+ if (size < state.offset) {
27
+ state.offset = 0;
28
+ state.pending = Buffer.alloc(0);
29
+ }
30
+ const chunks = [];
31
+ let position = state.offset;
32
+ while (position < size) {
33
+ const chunk = Buffer.alloc(Math.min(64 * 1024, size - position));
34
+ const { bytesRead } = await handle.read(chunk, 0, chunk.length, position);
35
+ if (bytesRead === 0) {
36
+ break;
37
+ }
38
+ chunks.push(chunk.subarray(0, bytesRead));
39
+ position += bytesRead;
40
+ }
41
+ state.offset = position;
42
+ const raw = Buffer.concat([state.pending, ...chunks]);
43
+ const lastNewline = raw.lastIndexOf(0x0a);
44
+ if (lastNewline < 0) {
45
+ state.pending = raw;
46
+ return [];
47
+ }
48
+ state.pending = raw.subarray(lastNewline + 1);
49
+ const lines = raw
50
+ .subarray(0, lastNewline)
51
+ .toString("utf8")
52
+ .split("\n")
53
+ .filter((line) => line.trim().length > 0);
54
+ const events = [];
55
+ for (const [index, line] of lines.entries()) {
56
+ try {
57
+ events.push(JSON.parse(line));
58
+ }
59
+ catch (error) {
60
+ if (index === lines.length - 1 && state.pending.length === 0) {
61
+ continue;
62
+ }
63
+ throw error;
64
+ }
65
+ }
66
+ return events;
67
+ }
68
+ finally {
69
+ await handle.close();
70
+ }
71
+ }
72
+ export async function appendRecordedInbound(filePath, event) {
73
+ await mkdir(path.dirname(filePath), { recursive: true });
74
+ const recorded = {
75
+ ...event,
76
+ recordedAt: new Date().toISOString(),
77
+ };
78
+ await appendFile(filePath, `${JSON.stringify(recorded)}\n`, "utf8");
79
+ return recorded;
80
+ }
81
+ export async function readRecordedInbound(filePath) {
82
+ let raw = "";
83
+ try {
84
+ raw = await readFile(filePath, "utf8");
85
+ }
86
+ catch (error) {
87
+ const code = error.code;
88
+ if (code === "ENOENT") {
89
+ return [];
90
+ }
91
+ throw error;
92
+ }
93
+ const lines = raw.split("\n").filter((line) => line.trim().length > 0);
94
+ const events = [];
95
+ for (const [index, line] of lines.entries()) {
96
+ try {
97
+ events.push(JSON.parse(line));
98
+ }
99
+ catch (error) {
100
+ if (index === lines.length - 1) {
101
+ continue;
102
+ }
103
+ throw error;
104
+ }
105
+ }
106
+ return events;
107
+ }
108
+ export async function waitForRecordedInbound(params) {
109
+ const deadline = Date.now() + params.timeoutMs;
110
+ const seen = new Set();
111
+ while (Date.now() <= deadline) {
112
+ const events = await readRecordedInbound(params.filePath);
113
+ for (const event of events) {
114
+ const key = toRecordKey(event);
115
+ if (seen.has(key)) {
116
+ continue;
117
+ }
118
+ seen.add(key);
119
+ if (params.since && new Date(event.sentAt).getTime() < new Date(params.since).getTime()) {
120
+ continue;
121
+ }
122
+ if (params.matches(event)) {
123
+ return event;
124
+ }
125
+ }
126
+ await sleep(params.pollMs ?? 200);
127
+ }
128
+ return null;
129
+ }
130
+ export async function* watchRecordedInbound(params) {
131
+ const state = {
132
+ offset: 0,
133
+ pending: Buffer.alloc(0),
134
+ };
135
+ const seen = new Set();
136
+ while (true) {
137
+ const events = await readRecordedInboundAppend(params.filePath, state);
138
+ for (const event of events) {
139
+ const key = toRecordKey(event);
140
+ if (seen.has(key)) {
141
+ continue;
142
+ }
143
+ seen.add(key);
144
+ if (seen.size > MAX_WATCH_SEEN_KEYS) {
145
+ const oldest = seen.values().next().value;
146
+ if (oldest !== undefined) {
147
+ seen.delete(oldest);
148
+ }
149
+ }
150
+ if (params.since && new Date(event.sentAt).getTime() < new Date(params.since).getTime()) {
151
+ continue;
152
+ }
153
+ if (params.matches(event)) {
154
+ yield event;
155
+ }
156
+ }
157
+ await sleep(params.pollMs ?? 250);
158
+ }
159
+ }
160
+ //# sourceMappingURL=recorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../../src/providers/recorder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { ManifestDefinition } from "../config/schema.js";
2
+ import { OPENCLAW_SUPPORT_CATALOG } from "./catalog.js";
3
+ import type { ProviderAdapter } from "./types.js";
4
+ export type Registry = {
5
+ catalog: typeof OPENCLAW_SUPPORT_CATALOG;
6
+ resolve(providerId: string, fixtureId: string): ProviderAdapter;
7
+ };
8
+ export declare function createRegistry(manifest: ManifestDefinition, manifestPath: string): Registry;
@@ -0,0 +1,171 @@
1
+ import { CrablineError } from "../core/errors.js";
2
+ import { ScriptProviderAdapter } from "./builtin/script.js";
3
+ import { OPENCLAW_SUPPORT_CATALOG } from "./catalog.js";
4
+ const COMMON_PROVIDER_SUPPORT = [
5
+ "probe",
6
+ "send",
7
+ "roundtrip",
8
+ "agent",
9
+ ];
10
+ const LAZY_PROVIDER_FACTORIES = {
11
+ async discord({ config, providerId, userName }) {
12
+ const { DiscordProviderAdapter } = await import("./builtin/discord.js");
13
+ return new DiscordProviderAdapter(providerId, config, userName);
14
+ },
15
+ async feishu({ config, providerId, userName }) {
16
+ const { FeishuProviderAdapter } = await import("./builtin/feishu.js");
17
+ return new FeishuProviderAdapter(providerId, config, userName);
18
+ },
19
+ async googlechat({ config, providerId, userName }) {
20
+ const { GoogleChatProviderAdapter } = await import("./builtin/googlechat.js");
21
+ return new GoogleChatProviderAdapter(providerId, config, userName);
22
+ },
23
+ async imessage({ config, providerId, userName }) {
24
+ const { IMessageProviderAdapter } = await import("./builtin/imessage.js");
25
+ return new IMessageProviderAdapter(providerId, config, userName);
26
+ },
27
+ async loopback({ config, providerId, userName }) {
28
+ const { LoopbackProviderAdapter } = await import("./builtin/loopback.js");
29
+ return new LoopbackProviderAdapter(providerId, config, userName);
30
+ },
31
+ async matrix({ config, providerId, userName }) {
32
+ const { MatrixProviderAdapter } = await import("./builtin/matrix.js");
33
+ return new MatrixProviderAdapter(providerId, config, userName);
34
+ },
35
+ async mattermost({ config, providerId, userName }) {
36
+ const { MattermostProviderAdapter } = await import("./builtin/mattermost.js");
37
+ return new MattermostProviderAdapter(providerId, config, userName);
38
+ },
39
+ async msteams({ config, providerId, userName }) {
40
+ const { MsTeamsProviderAdapter } = await import("./builtin/msteams.js");
41
+ return new MsTeamsProviderAdapter(providerId, config, userName);
42
+ },
43
+ async slack({ config, providerId, userName }) {
44
+ const { SlackProviderAdapter } = await import("./builtin/slack.js");
45
+ return new SlackProviderAdapter(providerId, config, userName);
46
+ },
47
+ async telegram({ config, providerId, userName }) {
48
+ const { TelegramProviderAdapter } = await import("./builtin/telegram.js");
49
+ return new TelegramProviderAdapter(providerId, config, userName);
50
+ },
51
+ async whatsapp({ config, providerId, userName }) {
52
+ const { WhatsAppProviderAdapter } = await import("./builtin/whatsapp.js");
53
+ return new WhatsAppProviderAdapter(providerId, config, userName);
54
+ },
55
+ async zalo({ config, providerId, userName }) {
56
+ const { ZaloProviderAdapter } = await import("./builtin/zalo.js");
57
+ return new ZaloProviderAdapter(providerId, config, userName);
58
+ },
59
+ };
60
+ function isLazyAdapter(adapter) {
61
+ return adapter in LAZY_PROVIDER_FACTORIES;
62
+ }
63
+ function normalizeTarget(target) {
64
+ const normalized = { id: target.id, metadata: target.metadata };
65
+ if (target.channelId) {
66
+ normalized.channelId = target.channelId;
67
+ }
68
+ if (target.threadId) {
69
+ normalized.threadId = target.threadId;
70
+ }
71
+ return normalized;
72
+ }
73
+ function createLazyProvider(params) {
74
+ return new LazyProviderAdapter({
75
+ adapterName: params.adapter,
76
+ factory: () => LAZY_PROVIDER_FACTORIES[params.adapter](params),
77
+ id: params.providerId,
78
+ platform: params.config.platform,
79
+ status: "ready",
80
+ supports: COMMON_PROVIDER_SUPPORT,
81
+ });
82
+ }
83
+ class LazyProviderAdapter {
84
+ id;
85
+ platform;
86
+ status;
87
+ supports;
88
+ #adapterName;
89
+ #factory;
90
+ #providerPromise = null;
91
+ constructor(params) {
92
+ this.#adapterName = params.adapterName;
93
+ this.#factory = params.factory;
94
+ this.id = params.id;
95
+ this.platform = params.platform;
96
+ this.status = params.status;
97
+ this.supports = params.supports;
98
+ }
99
+ normalizeTarget(target) {
100
+ return normalizeTarget(target);
101
+ }
102
+ async probe(context) {
103
+ return await (await this.#provider()).probe(context);
104
+ }
105
+ async send(context) {
106
+ return await (await this.#provider()).send(context);
107
+ }
108
+ async waitForInbound(context) {
109
+ return await (await this.#provider()).waitForInbound(context);
110
+ }
111
+ watch(context) {
112
+ return this.#watch(context);
113
+ }
114
+ async cleanup() {
115
+ if (!this.#providerPromise) {
116
+ return;
117
+ }
118
+ await (await this.#providerPromise).cleanup?.();
119
+ }
120
+ async #provider() {
121
+ this.#providerPromise ??= this.#factory().catch((error) => {
122
+ this.#providerPromise = null;
123
+ throw new CrablineError(`Provider adapter "${this.#adapterName}" could not load. Install its optional peer dependencies before using this adapter.`, { cause: error, kind: "config" });
124
+ });
125
+ return await this.#providerPromise;
126
+ }
127
+ async *#watch(context) {
128
+ const provider = await this.#provider();
129
+ if (!provider.watch) {
130
+ throw new CrablineError(`Provider "${this.id}" does not implement watch.`, {
131
+ kind: "config",
132
+ });
133
+ }
134
+ yield* provider.watch(context);
135
+ }
136
+ }
137
+ export function createRegistry(manifest, manifestPath) {
138
+ return {
139
+ catalog: OPENCLAW_SUPPORT_CATALOG,
140
+ resolve(providerId, fixtureId) {
141
+ const fixture = manifest.fixtures.find((entry) => entry.id === fixtureId);
142
+ if (!fixture) {
143
+ throw new CrablineError(`Unknown fixture: ${fixtureId}`, { kind: "config" });
144
+ }
145
+ const config = manifest.providers[providerId];
146
+ if (!config) {
147
+ throw new CrablineError(`Unknown provider: ${providerId}`, { kind: "config" });
148
+ }
149
+ if (config.status === "disabled") {
150
+ throw new CrablineError(`Provider "${providerId}" is disabled.`, { kind: "config" });
151
+ }
152
+ const context = {
153
+ config,
154
+ fixture,
155
+ manifestPath,
156
+ providerId,
157
+ userName: manifest.userName,
158
+ };
159
+ if (isLazyAdapter(config.adapter)) {
160
+ return createLazyProvider({
161
+ adapter: config.adapter,
162
+ config,
163
+ providerId,
164
+ userName: manifest.userName,
165
+ });
166
+ }
167
+ return new ScriptProviderAdapter(context);
168
+ },
169
+ };
170
+ }
171
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/providers/registry.ts"],"names":[],"mappings":"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"}