dsclaw 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/dist/cli/index.js +1901 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.ts +707 -0
- package/dist/index.js +40149 -0
- package/dist/index.js.map +1 -0
- package/dist/web/chat.html +406 -0
- package/openclaw.plugin.json +19 -0
- package/package.json +73 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,707 @@
|
|
|
1
|
+
import pino from 'pino';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import CircuitBreaker from 'opossum';
|
|
4
|
+
import pLimit from 'p-limit';
|
|
5
|
+
import { Job } from 'bullmq';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Structured error classification for DropClaw.
|
|
9
|
+
* Every error flowing through the system must have a category
|
|
10
|
+
* so upstream layers (agents, channels) know how to react.
|
|
11
|
+
*/
|
|
12
|
+
declare const ErrorCategory: {
|
|
13
|
+
readonly RETRYABLE: "RETRYABLE";
|
|
14
|
+
readonly NEEDS_HUMAN: "NEEDS_HUMAN";
|
|
15
|
+
readonly NEEDS_DATA: "NEEDS_DATA";
|
|
16
|
+
readonly FATAL: "FATAL";
|
|
17
|
+
readonly DEGRADED: "DEGRADED";
|
|
18
|
+
};
|
|
19
|
+
type ErrorCategory = (typeof ErrorCategory)[keyof typeof ErrorCategory];
|
|
20
|
+
interface StructuredError {
|
|
21
|
+
category: ErrorCategory;
|
|
22
|
+
code: string;
|
|
23
|
+
message: string;
|
|
24
|
+
retryable: boolean;
|
|
25
|
+
details?: Record<string, unknown>;
|
|
26
|
+
cause?: Error;
|
|
27
|
+
}
|
|
28
|
+
declare class DropClawError extends Error {
|
|
29
|
+
readonly category: ErrorCategory;
|
|
30
|
+
readonly code: string;
|
|
31
|
+
readonly retryable: boolean;
|
|
32
|
+
readonly details?: Record<string, unknown>;
|
|
33
|
+
constructor(opts: StructuredError);
|
|
34
|
+
toJSON(): StructuredError;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Structured logger powered by pino.
|
|
39
|
+
* Automatically injects traceId from AsyncLocalStorage.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
declare function createLogger(module: string): pino.Logger;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Request-scoped tracing via AsyncLocalStorage.
|
|
46
|
+
* Every inbound message gets a traceId that propagates
|
|
47
|
+
* through agents, tools, API calls, and logs.
|
|
48
|
+
*/
|
|
49
|
+
interface TraceContext {
|
|
50
|
+
traceId: string;
|
|
51
|
+
userId?: string;
|
|
52
|
+
channelId?: string;
|
|
53
|
+
sessionId?: string;
|
|
54
|
+
agentId?: string;
|
|
55
|
+
}
|
|
56
|
+
declare function runWithTrace<T>(ctx: Partial<TraceContext>, fn: () => T): T;
|
|
57
|
+
declare function getTraceContext(): TraceContext;
|
|
58
|
+
declare function getTraceId(): string;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Generate an idempotency key from operation parameters.
|
|
62
|
+
* Uses a 5-minute time bucket so the same operation within
|
|
63
|
+
* 5 minutes is considered duplicate.
|
|
64
|
+
*/
|
|
65
|
+
declare function idempotencyKey(userId: string, action: string, params: Record<string, unknown>): string;
|
|
66
|
+
/**
|
|
67
|
+
* Sleep for a given number of milliseconds.
|
|
68
|
+
*/
|
|
69
|
+
declare function sleep(ms: number): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Parse Retry-After header value to milliseconds.
|
|
72
|
+
* Supports both seconds (integer) and HTTP-date formats.
|
|
73
|
+
*/
|
|
74
|
+
declare function parseRetryAfter(value: string | null): number | null;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Audit log for tracking all write operations.
|
|
78
|
+
* Every action an agent takes is recorded so the user
|
|
79
|
+
* can always answer "what did the bot do?"
|
|
80
|
+
*/
|
|
81
|
+
interface AuditEntry {
|
|
82
|
+
timestamp: string;
|
|
83
|
+
traceId: string;
|
|
84
|
+
userId: string;
|
|
85
|
+
agentId: string;
|
|
86
|
+
action: string;
|
|
87
|
+
target: string;
|
|
88
|
+
params?: Record<string, unknown>;
|
|
89
|
+
result: "success" | "failed" | "pending";
|
|
90
|
+
error?: string;
|
|
91
|
+
}
|
|
92
|
+
declare function writeAuditLog(entry: Omit<AuditEntry, "timestamp" | "traceId">): void;
|
|
93
|
+
declare function auditFilePath(date: string): string;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Minimal configuration — defaults work out of the box.
|
|
97
|
+
* Web chat starts automatically; Telegram is optional.
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
declare const ConfigSchema: z.ZodObject<{
|
|
101
|
+
port: z.ZodDefault<z.ZodNumber>;
|
|
102
|
+
telegramBotToken: z.ZodOptional<z.ZodString>;
|
|
103
|
+
}, z.core.$strip>;
|
|
104
|
+
type DropClawConfig = z.infer<typeof ConfigSchema>;
|
|
105
|
+
declare function loadConfig(path?: string): DropClawConfig;
|
|
106
|
+
declare function saveConfig(config: DropClawConfig): void;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* User session state machine + encrypted credential storage.
|
|
110
|
+
* Each Telegram user has their own session with DSers + LLM credentials.
|
|
111
|
+
* Credentials are AES-256-GCM encrypted, bound to machine identity.
|
|
112
|
+
*/
|
|
113
|
+
type SessionState = "new" | "onboard_demo" | "onboard_dsers_email" | "onboard_dsers_password" | "onboard_llm" | "ready";
|
|
114
|
+
interface UserSessionData {
|
|
115
|
+
state: SessionState;
|
|
116
|
+
dspiEmail?: string;
|
|
117
|
+
dspiPassword?: string;
|
|
118
|
+
llmProvider?: string;
|
|
119
|
+
llmApiKey?: string;
|
|
120
|
+
llmModel?: string;
|
|
121
|
+
language?: string;
|
|
122
|
+
}
|
|
123
|
+
declare function loadSession(userId: string): UserSessionData;
|
|
124
|
+
declare function saveSession(userId: string, session: UserSessionData): void;
|
|
125
|
+
declare function deleteSession(userId: string): void;
|
|
126
|
+
declare function isOnboarding(state: SessionState): boolean;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* DropClaw Gateway — central orchestrator.
|
|
130
|
+
*
|
|
131
|
+
* Flow:
|
|
132
|
+
* 1. User opens web chat (or sends Telegram message)
|
|
133
|
+
* 2. Gateway loads user session (encrypted on disk)
|
|
134
|
+
* 3. If not "ready": handle onboarding conversation (no LLM needed)
|
|
135
|
+
* 4. If "ready": route to AI agent with streaming (web) or batch (Telegram)
|
|
136
|
+
*
|
|
137
|
+
* Web chat is the default channel (zero config).
|
|
138
|
+
* Telegram is optional (requires bot token in config).
|
|
139
|
+
*/
|
|
140
|
+
|
|
141
|
+
declare class DropClawGateway {
|
|
142
|
+
private config;
|
|
143
|
+
private channels;
|
|
144
|
+
private webChannel;
|
|
145
|
+
private memory;
|
|
146
|
+
private agents;
|
|
147
|
+
private dsersClients;
|
|
148
|
+
private running;
|
|
149
|
+
constructor(config: DropClawConfig);
|
|
150
|
+
start(): Promise<void>;
|
|
151
|
+
private handleMessage;
|
|
152
|
+
private handleOnboarding;
|
|
153
|
+
private onboardWelcome;
|
|
154
|
+
private onboardEmail;
|
|
155
|
+
private onboardPassword;
|
|
156
|
+
private onboardLLM;
|
|
157
|
+
private handleReady;
|
|
158
|
+
private handleReadyStreaming;
|
|
159
|
+
private handleReadyBatch;
|
|
160
|
+
private getOrCreateAgent;
|
|
161
|
+
stop(): Promise<void>;
|
|
162
|
+
isRunning(): boolean;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Unified channel adapter interface.
|
|
167
|
+
* Every messaging platform (Telegram, WhatsApp, Feishu)
|
|
168
|
+
* implements this contract so the gateway is platform-agnostic.
|
|
169
|
+
*/
|
|
170
|
+
interface NormalizedMessage {
|
|
171
|
+
traceId: string;
|
|
172
|
+
channelId: string;
|
|
173
|
+
channelName: string;
|
|
174
|
+
userId: string;
|
|
175
|
+
userName?: string;
|
|
176
|
+
text: string;
|
|
177
|
+
attachments?: Attachment[];
|
|
178
|
+
replyTo?: string;
|
|
179
|
+
timestamp: Date;
|
|
180
|
+
metadata: Record<string, unknown>;
|
|
181
|
+
}
|
|
182
|
+
interface Attachment {
|
|
183
|
+
type: "image" | "file" | "link";
|
|
184
|
+
url?: string;
|
|
185
|
+
data?: Buffer;
|
|
186
|
+
mimeType?: string;
|
|
187
|
+
fileName?: string;
|
|
188
|
+
}
|
|
189
|
+
interface ActionCard {
|
|
190
|
+
title: string;
|
|
191
|
+
summary: string;
|
|
192
|
+
actions: ActionButton[];
|
|
193
|
+
jobId?: string;
|
|
194
|
+
progress?: number;
|
|
195
|
+
}
|
|
196
|
+
interface ActionButton {
|
|
197
|
+
label: string;
|
|
198
|
+
callbackData: string;
|
|
199
|
+
}
|
|
200
|
+
interface OutboundMessage {
|
|
201
|
+
text?: string;
|
|
202
|
+
card?: ActionCard;
|
|
203
|
+
replyToMessageId?: string;
|
|
204
|
+
}
|
|
205
|
+
type MessageHandler = (message: NormalizedMessage) => Promise<void>;
|
|
206
|
+
interface ChannelAdapter {
|
|
207
|
+
readonly name: string;
|
|
208
|
+
readonly connected: boolean;
|
|
209
|
+
connect(config: Record<string, unknown>): Promise<void>;
|
|
210
|
+
disconnect(): Promise<void>;
|
|
211
|
+
reconnect(): Promise<void>;
|
|
212
|
+
onMessage(handler: MessageHandler): void;
|
|
213
|
+
send(targetUserId: string, message: OutboundMessage): Promise<void>;
|
|
214
|
+
sendCard(targetUserId: string, card: ActionCard): Promise<void>;
|
|
215
|
+
deleteMessage(chatId: string | number, messageId: number): Promise<void>;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Web Chat Server — HTTP + WebSocket.
|
|
220
|
+
* Serves chat.html and handles real-time messaging via WebSocket.
|
|
221
|
+
* Implements ChannelAdapter for gateway integration.
|
|
222
|
+
* Supports streaming for Claude-like token-by-token output.
|
|
223
|
+
*/
|
|
224
|
+
|
|
225
|
+
declare class WebChatServer implements ChannelAdapter {
|
|
226
|
+
readonly name = "web";
|
|
227
|
+
private server;
|
|
228
|
+
private wss;
|
|
229
|
+
private handler;
|
|
230
|
+
private connections;
|
|
231
|
+
private _connected;
|
|
232
|
+
private port;
|
|
233
|
+
get connected(): boolean;
|
|
234
|
+
connect(config: Record<string, unknown>): Promise<void>;
|
|
235
|
+
disconnect(): Promise<void>;
|
|
236
|
+
reconnect(): Promise<void>;
|
|
237
|
+
onMessage(handler: MessageHandler): void;
|
|
238
|
+
send(targetUserId: string, message: OutboundMessage): Promise<void>;
|
|
239
|
+
sendCard(targetUserId: string, card: ActionCard): Promise<void>;
|
|
240
|
+
deleteMessage(): Promise<void>;
|
|
241
|
+
sendStreamStart(userId: string): void;
|
|
242
|
+
sendStreamDelta(userId: string, delta: string): void;
|
|
243
|
+
sendStreamEnd(userId: string): void;
|
|
244
|
+
sendTyping(userId: string, active: boolean): void;
|
|
245
|
+
sendClearInput(userId: string): void;
|
|
246
|
+
sendSetInputType(userId: string, inputType: "text" | "password"): void;
|
|
247
|
+
private wsSendTo;
|
|
248
|
+
private wsSend;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* DSers API configuration.
|
|
253
|
+
* Uses email + password auth (matching actual DSers login flow).
|
|
254
|
+
*/
|
|
255
|
+
interface DSersClientConfig {
|
|
256
|
+
baseUrl: string;
|
|
257
|
+
email: string;
|
|
258
|
+
password: string;
|
|
259
|
+
sessionFile: string;
|
|
260
|
+
sessionId?: string;
|
|
261
|
+
sessionState?: string;
|
|
262
|
+
}
|
|
263
|
+
declare function createDSersConfig(email: string, password: string, baseUrl?: string): DSersClientConfig;
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Enhanced DSers HTTP client with:
|
|
267
|
+
* - 429 Retry-After handling
|
|
268
|
+
* - 5xx exponential backoff (max 2 retries)
|
|
269
|
+
* - Structured error classification
|
|
270
|
+
* - traceId injection
|
|
271
|
+
* - Session auto-refresh on 400 auth errors
|
|
272
|
+
*/
|
|
273
|
+
|
|
274
|
+
declare class DSersClient {
|
|
275
|
+
private config;
|
|
276
|
+
private auth;
|
|
277
|
+
private limiter;
|
|
278
|
+
constructor(config: DSersClientConfig);
|
|
279
|
+
request(method: string, path: string, opts?: {
|
|
280
|
+
params?: Record<string, unknown>;
|
|
281
|
+
json?: Record<string, unknown>;
|
|
282
|
+
}, attempt?: number): Promise<Record<string, unknown>>;
|
|
283
|
+
get(path: string, params?: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
284
|
+
post(path: string, json?: Record<string, unknown>, params?: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
285
|
+
put(path: string, json?: Record<string, unknown>, params?: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
286
|
+
del(path: string, params?: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Core DSers domain types extracted from the OpenAPI spec.
|
|
291
|
+
* Covers the essential entities for the DropClaw workflow.
|
|
292
|
+
*/
|
|
293
|
+
interface DSersStore {
|
|
294
|
+
id: string;
|
|
295
|
+
name: string;
|
|
296
|
+
platform: string;
|
|
297
|
+
url?: string;
|
|
298
|
+
status?: string;
|
|
299
|
+
}
|
|
300
|
+
interface DSersProduct {
|
|
301
|
+
id: string;
|
|
302
|
+
title: string;
|
|
303
|
+
supplyProductId?: string;
|
|
304
|
+
supplyAppId?: number;
|
|
305
|
+
variants?: DSersVariant[];
|
|
306
|
+
images?: string[];
|
|
307
|
+
tags?: string[];
|
|
308
|
+
description?: string;
|
|
309
|
+
}
|
|
310
|
+
interface DSersVariant {
|
|
311
|
+
id: string;
|
|
312
|
+
title: string;
|
|
313
|
+
price: number;
|
|
314
|
+
compareAtPrice?: number;
|
|
315
|
+
cost?: number;
|
|
316
|
+
sku?: string;
|
|
317
|
+
inventory?: number;
|
|
318
|
+
image?: string;
|
|
319
|
+
}
|
|
320
|
+
interface DSersOrder {
|
|
321
|
+
id: string;
|
|
322
|
+
orderNumber?: string;
|
|
323
|
+
status: string;
|
|
324
|
+
storeId: string;
|
|
325
|
+
totalPrice?: number;
|
|
326
|
+
currency?: string;
|
|
327
|
+
createdAt?: string;
|
|
328
|
+
items?: DSersOrderItem[];
|
|
329
|
+
}
|
|
330
|
+
interface DSersOrderItem {
|
|
331
|
+
productId: string;
|
|
332
|
+
variantId: string;
|
|
333
|
+
title: string;
|
|
334
|
+
quantity: number;
|
|
335
|
+
price: number;
|
|
336
|
+
}
|
|
337
|
+
interface PushResult {
|
|
338
|
+
eventId: string;
|
|
339
|
+
status: "pending" | "processing" | "completed" | "failed";
|
|
340
|
+
successCount?: number;
|
|
341
|
+
failedCount?: number;
|
|
342
|
+
errors?: string[];
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Agent base interface and types.
|
|
347
|
+
* All agents (Navigator, Claw-Ops, or the combined prototype)
|
|
348
|
+
* implement this contract.
|
|
349
|
+
*/
|
|
350
|
+
interface AgentMessage {
|
|
351
|
+
role: "user" | "assistant" | "system";
|
|
352
|
+
content: string;
|
|
353
|
+
}
|
|
354
|
+
interface AgentTool {
|
|
355
|
+
name: string;
|
|
356
|
+
description: string;
|
|
357
|
+
parameters: Record<string, unknown>;
|
|
358
|
+
execute: (params: Record<string, unknown>) => Promise<AgentToolResult>;
|
|
359
|
+
}
|
|
360
|
+
interface AgentToolResult {
|
|
361
|
+
success: boolean;
|
|
362
|
+
data?: unknown;
|
|
363
|
+
error?: string;
|
|
364
|
+
}
|
|
365
|
+
interface AgentResponse {
|
|
366
|
+
text: string;
|
|
367
|
+
toolCalls?: Array<{
|
|
368
|
+
tool: string;
|
|
369
|
+
params: Record<string, unknown>;
|
|
370
|
+
result: AgentToolResult;
|
|
371
|
+
}>;
|
|
372
|
+
}
|
|
373
|
+
interface AgentContext {
|
|
374
|
+
userId: string;
|
|
375
|
+
sessionId: string;
|
|
376
|
+
channelId: string;
|
|
377
|
+
storeId?: string;
|
|
378
|
+
history: AgentMessage[];
|
|
379
|
+
}
|
|
380
|
+
interface AgentBase {
|
|
381
|
+
readonly id: string;
|
|
382
|
+
readonly name: string;
|
|
383
|
+
registerTool(tool: AgentTool): void;
|
|
384
|
+
removeTool(name: string): void;
|
|
385
|
+
getTools(): AgentTool[];
|
|
386
|
+
process(message: string, context: AgentContext): Promise<AgentResponse>;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Unified memory provider interface.
|
|
391
|
+
* Implementations: FileMemoryProvider (Plan B), Mem0CloudProvider (Plan C).
|
|
392
|
+
* The interface stays the same — swap implementations without changing agents.
|
|
393
|
+
*/
|
|
394
|
+
interface MemoryMeta {
|
|
395
|
+
userId: string;
|
|
396
|
+
sessionId?: string;
|
|
397
|
+
agentId?: string;
|
|
398
|
+
category: MemoryCategory;
|
|
399
|
+
tags?: string[];
|
|
400
|
+
}
|
|
401
|
+
type MemoryCategory = "preference" | "pattern" | "fact";
|
|
402
|
+
interface Memory {
|
|
403
|
+
id: string;
|
|
404
|
+
content: string;
|
|
405
|
+
metadata: MemoryMeta;
|
|
406
|
+
score?: number;
|
|
407
|
+
createdAt: Date;
|
|
408
|
+
updatedAt: Date;
|
|
409
|
+
}
|
|
410
|
+
interface MemoryFilter {
|
|
411
|
+
userId?: string;
|
|
412
|
+
sessionId?: string;
|
|
413
|
+
category?: MemoryCategory;
|
|
414
|
+
tags?: string[];
|
|
415
|
+
limit?: number;
|
|
416
|
+
}
|
|
417
|
+
interface MemoryProvider {
|
|
418
|
+
readonly name: string;
|
|
419
|
+
readonly degraded: boolean;
|
|
420
|
+
add(content: string, metadata: MemoryMeta): Promise<string>;
|
|
421
|
+
search(query: string, filters: MemoryFilter): Promise<Memory[]>;
|
|
422
|
+
getAll(filters: MemoryFilter): Promise<Memory[]>;
|
|
423
|
+
update(id: string, content: string): Promise<void>;
|
|
424
|
+
delete(id: string): Promise<void>;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* DropClaw Core Agent — unified prototype agent using Vercel AI SDK.
|
|
429
|
+
* Created per-user with their own DSers client and LLM config.
|
|
430
|
+
* System prompt targets zero-technical-ability dropshipping users.
|
|
431
|
+
*/
|
|
432
|
+
|
|
433
|
+
interface LLMConfig {
|
|
434
|
+
provider: string;
|
|
435
|
+
apiKey: string;
|
|
436
|
+
model: string;
|
|
437
|
+
}
|
|
438
|
+
declare function getDefaultModel(provider: string): string;
|
|
439
|
+
declare class DropClawCoreAgent implements AgentBase {
|
|
440
|
+
readonly id = "dropclaw-core";
|
|
441
|
+
readonly name = "DropClaw Core Agent";
|
|
442
|
+
private dsers;
|
|
443
|
+
private memory;
|
|
444
|
+
private llm;
|
|
445
|
+
private customTools;
|
|
446
|
+
constructor(dsers: DSersClient, memory: MemoryProvider, llm: LLMConfig);
|
|
447
|
+
registerTool(t: AgentTool): void;
|
|
448
|
+
removeTool(name: string): void;
|
|
449
|
+
getTools(): AgentTool[];
|
|
450
|
+
process(message: string, context: AgentContext): Promise<AgentResponse>;
|
|
451
|
+
/**
|
|
452
|
+
* Streaming version of process() — yields text chunks for real-time display.
|
|
453
|
+
* Returns textStream (async iterable) + response promise (resolves after completion).
|
|
454
|
+
*/
|
|
455
|
+
processStream(message: string, context: AgentContext): {
|
|
456
|
+
textStream: AsyncIterable<string>;
|
|
457
|
+
response: Promise<AgentResponse>;
|
|
458
|
+
};
|
|
459
|
+
private buildAITools;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Telegram channel adapter using grammY.
|
|
464
|
+
* Normalizes messages, supports inline keyboards, auto-reconnects,
|
|
465
|
+
* and can delete sensitive messages (passwords, API keys).
|
|
466
|
+
*/
|
|
467
|
+
|
|
468
|
+
declare class TelegramAdapter implements ChannelAdapter {
|
|
469
|
+
readonly name = "telegram";
|
|
470
|
+
private bot;
|
|
471
|
+
private handler;
|
|
472
|
+
private _connected;
|
|
473
|
+
private botToken;
|
|
474
|
+
get connected(): boolean;
|
|
475
|
+
connect(config: Record<string, unknown>): Promise<void>;
|
|
476
|
+
disconnect(): Promise<void>;
|
|
477
|
+
reconnect(): Promise<void>;
|
|
478
|
+
onMessage(handler: MessageHandler): void;
|
|
479
|
+
send(targetUserId: string, message: OutboundMessage): Promise<void>;
|
|
480
|
+
sendCard(targetUserId: string, card: ActionCard): Promise<void>;
|
|
481
|
+
deleteMessage(chatId: string | number, messageId: number): Promise<void>;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Local JSON-based memory provider.
|
|
486
|
+
* Stores memories as JSONL files, one per user.
|
|
487
|
+
* Simple keyword-based search (no vector embeddings).
|
|
488
|
+
* Replaced by mem0 in Plan C for production use.
|
|
489
|
+
*/
|
|
490
|
+
|
|
491
|
+
declare class FileMemoryProvider implements MemoryProvider {
|
|
492
|
+
readonly name = "file";
|
|
493
|
+
readonly degraded = false;
|
|
494
|
+
constructor();
|
|
495
|
+
add(content: string, metadata: MemoryMeta): Promise<string>;
|
|
496
|
+
search(query: string, filters: MemoryFilter): Promise<Memory[]>;
|
|
497
|
+
getAll(filters: MemoryFilter): Promise<Memory[]>;
|
|
498
|
+
update(id: string, content: string): Promise<void>;
|
|
499
|
+
delete(id: string): Promise<void>;
|
|
500
|
+
private userFile;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Circuit breaker factory wrapping opossum.
|
|
505
|
+
* Each external dependency (DSers, LLM, mem0) gets its own breaker
|
|
506
|
+
* so a single bad dependency cannot take down the entire system.
|
|
507
|
+
*/
|
|
508
|
+
|
|
509
|
+
interface BreakerOptions {
|
|
510
|
+
timeout?: number;
|
|
511
|
+
errorThresholdPercentage?: number;
|
|
512
|
+
resetTimeout?: number;
|
|
513
|
+
volumeThreshold?: number;
|
|
514
|
+
name: string;
|
|
515
|
+
}
|
|
516
|
+
declare function createCircuitBreaker<TArgs extends unknown[], TResult>(name: string, fn: (...args: TArgs) => Promise<TResult>, customOpts?: Partial<BreakerOptions>): CircuitBreaker<TArgs, TResult>;
|
|
517
|
+
declare function getAllBreakerStatus(): Record<string, {
|
|
518
|
+
state: string;
|
|
519
|
+
stats: CircuitBreaker.Stats;
|
|
520
|
+
}>;
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Generic retry with exponential backoff + jitter.
|
|
524
|
+
* Respects workspace rule: same error no more than 2 retries.
|
|
525
|
+
*/
|
|
526
|
+
|
|
527
|
+
interface RetryOptions {
|
|
528
|
+
maxRetries?: number;
|
|
529
|
+
baseDelay?: number;
|
|
530
|
+
maxDelay?: number;
|
|
531
|
+
retryableCategories?: ErrorCategory[];
|
|
532
|
+
}
|
|
533
|
+
declare function withRetry<T>(fn: () => Promise<T>, opts?: RetryOptions): Promise<T>;
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Three-layer rate limiting:
|
|
537
|
+
* L1 Inbound: per-IP / per-channel flood protection
|
|
538
|
+
* L2 Tenant: per-userId session serialization + debounce
|
|
539
|
+
* L3 Outbound: per-service concurrency cap (DSers, LLM, mem0)
|
|
540
|
+
*/
|
|
541
|
+
|
|
542
|
+
interface OutboundLimits {
|
|
543
|
+
dsers: number;
|
|
544
|
+
llm: number;
|
|
545
|
+
mem0: number;
|
|
546
|
+
}
|
|
547
|
+
declare function getOutboundLimiter(service: keyof OutboundLimits, customLimits?: Partial<OutboundLimits>): ReturnType<typeof pLimit>;
|
|
548
|
+
/**
|
|
549
|
+
* Ensure messages from the same user are processed serially.
|
|
550
|
+
* Returns a release function to call when processing is done.
|
|
551
|
+
*/
|
|
552
|
+
declare function acquireUserLock(userId: string): Promise<() => void>;
|
|
553
|
+
/**
|
|
554
|
+
* Debounce rapid-fire messages from the same user.
|
|
555
|
+
* Resolves after `delayMs` of silence.
|
|
556
|
+
*/
|
|
557
|
+
declare function debounceUser(userId: string, delayMs?: number): Promise<void>;
|
|
558
|
+
/**
|
|
559
|
+
* Check if an inbound source has exceeded the rate limit.
|
|
560
|
+
* @returns true if the request should be allowed, false if throttled.
|
|
561
|
+
*/
|
|
562
|
+
declare function checkInboundLimit(sourceId: string, maxRequests?: number, windowMs?: number): boolean;
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Degradation strategies for when external services are unavailable.
|
|
566
|
+
* Each service has a defined fallback path.
|
|
567
|
+
*/
|
|
568
|
+
type ServiceName = "dsers" | "llm" | "mem0";
|
|
569
|
+
interface DegradationState {
|
|
570
|
+
service: ServiceName;
|
|
571
|
+
degraded: boolean;
|
|
572
|
+
reason?: string;
|
|
573
|
+
since?: Date;
|
|
574
|
+
fallbackActive: boolean;
|
|
575
|
+
}
|
|
576
|
+
declare function markDegraded(service: ServiceName, reason: string): void;
|
|
577
|
+
declare function markRecovered(service: ServiceName): void;
|
|
578
|
+
declare function isDegraded(service: ServiceName): boolean;
|
|
579
|
+
declare function getDegradationStatus(): DegradationState[];
|
|
580
|
+
/**
|
|
581
|
+
* Produce a user-friendly degradation message for channel output.
|
|
582
|
+
*/
|
|
583
|
+
declare function degradationMessage(service: ServiceName): string;
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Job manager interface for BullMQ task queue.
|
|
587
|
+
* Two queues: high-priority (queries, alerts) and low-priority (batch ops).
|
|
588
|
+
*/
|
|
589
|
+
type JobPriority = "high" | "low";
|
|
590
|
+
interface JobPayload {
|
|
591
|
+
type: string;
|
|
592
|
+
userId: string;
|
|
593
|
+
agentId: string;
|
|
594
|
+
params: Record<string, unknown>;
|
|
595
|
+
idempotencyKey?: string;
|
|
596
|
+
}
|
|
597
|
+
interface JobStatus {
|
|
598
|
+
id: string;
|
|
599
|
+
state: "waiting" | "active" | "completed" | "failed" | "delayed";
|
|
600
|
+
progress: number;
|
|
601
|
+
result?: unknown;
|
|
602
|
+
error?: string;
|
|
603
|
+
createdAt: Date;
|
|
604
|
+
finishedAt?: Date;
|
|
605
|
+
}
|
|
606
|
+
interface JobManager {
|
|
607
|
+
enqueue(payload: JobPayload, priority?: JobPriority): Promise<string>;
|
|
608
|
+
getStatus(jobId: string): Promise<JobStatus | null>;
|
|
609
|
+
cancel(jobId: string): Promise<boolean>;
|
|
610
|
+
onComplete(handler: (jobId: string, result: unknown) => Promise<void>): void;
|
|
611
|
+
onFailed(handler: (jobId: string, error: string) => Promise<void>): void;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* BullMQ queue manager — dual queues with priority separation.
|
|
616
|
+
* High: queries, alerts, short tasks (timeout 10s)
|
|
617
|
+
* Low: batch imports, sync, bulk operations (timeout 5min)
|
|
618
|
+
*/
|
|
619
|
+
|
|
620
|
+
declare class BullMQJobManager implements JobManager {
|
|
621
|
+
private highQueue;
|
|
622
|
+
private lowQueue;
|
|
623
|
+
private connection;
|
|
624
|
+
private highWorker?;
|
|
625
|
+
private lowWorker?;
|
|
626
|
+
private completeHandlers;
|
|
627
|
+
private failedHandlers;
|
|
628
|
+
constructor(redisUrl: string);
|
|
629
|
+
connect(): Promise<void>;
|
|
630
|
+
startWorkers(processor: (job: Job<JobPayload>) => Promise<unknown>): void;
|
|
631
|
+
enqueue(payload: JobPayload, priority?: JobPriority): Promise<string>;
|
|
632
|
+
getStatus(jobId: string): Promise<JobStatus | null>;
|
|
633
|
+
cancel(jobId: string): Promise<boolean>;
|
|
634
|
+
onComplete(handler: (jobId: string, result: unknown) => Promise<void>): void;
|
|
635
|
+
onFailed(handler: (jobId: string, error: string) => Promise<void>): void;
|
|
636
|
+
shutdown(): Promise<void>;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* Rule engine interface for deterministic operations.
|
|
641
|
+
* Rules bypass the LLM — they execute predictable logic
|
|
642
|
+
* like price tracking, inventory thresholds, and format validation.
|
|
643
|
+
*/
|
|
644
|
+
interface Rule {
|
|
645
|
+
id: string;
|
|
646
|
+
name: string;
|
|
647
|
+
type: RuleType;
|
|
648
|
+
conditions: RuleCondition[];
|
|
649
|
+
actions: RuleAction[];
|
|
650
|
+
enabled: boolean;
|
|
651
|
+
priority: number;
|
|
652
|
+
}
|
|
653
|
+
type RuleType = "pricing" | "inventory" | "format" | "guard";
|
|
654
|
+
interface RuleCondition {
|
|
655
|
+
field: string;
|
|
656
|
+
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "contains" | "in";
|
|
657
|
+
value: unknown;
|
|
658
|
+
}
|
|
659
|
+
interface RuleAction {
|
|
660
|
+
type: string;
|
|
661
|
+
params: Record<string, unknown>;
|
|
662
|
+
}
|
|
663
|
+
interface RuleEvaluationResult {
|
|
664
|
+
matched: Rule[];
|
|
665
|
+
actions: RuleAction[];
|
|
666
|
+
warnings: string[];
|
|
667
|
+
blocked: string[];
|
|
668
|
+
}
|
|
669
|
+
interface RuleEngine {
|
|
670
|
+
addRule(rule: Rule): void;
|
|
671
|
+
removeRule(id: string): void;
|
|
672
|
+
getRules(): Rule[];
|
|
673
|
+
evaluate(context: Record<string, unknown>, ruleTypes?: RuleType[]): RuleEvaluationResult;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* OpenClaw plugin manifest and version compatibility.
|
|
678
|
+
* DropClaw registers as an OpenClaw plugin via Plugin SDK
|
|
679
|
+
* when running inside an OpenClaw gateway.
|
|
680
|
+
*/
|
|
681
|
+
interface PluginManifest {
|
|
682
|
+
id: string;
|
|
683
|
+
name: string;
|
|
684
|
+
description: string;
|
|
685
|
+
version: string;
|
|
686
|
+
configSchema: Record<string, unknown>;
|
|
687
|
+
kind?: "context-engine";
|
|
688
|
+
channels: string[];
|
|
689
|
+
providers: string[];
|
|
690
|
+
skills: string[];
|
|
691
|
+
}
|
|
692
|
+
declare const DROPCLAW_MANIFEST: PluginManifest;
|
|
693
|
+
|
|
694
|
+
/**
|
|
695
|
+
* Version compatibility check against OpenClaw runtime.
|
|
696
|
+
* Maintains a compatibility matrix to ensure safe upgrades.
|
|
697
|
+
*/
|
|
698
|
+
interface CompatEntry {
|
|
699
|
+
openclawVersion: string;
|
|
700
|
+
dropclawVersion: string;
|
|
701
|
+
status: "tested" | "untested" | "incompatible";
|
|
702
|
+
notes?: string;
|
|
703
|
+
}
|
|
704
|
+
declare const COMPAT_MATRIX: CompatEntry[];
|
|
705
|
+
declare function checkCompatibility(openclawVersion: string): CompatEntry | null;
|
|
706
|
+
|
|
707
|
+
export { type ActionCard, type AgentBase, type AgentContext, type AgentResponse, type AgentTool, BullMQJobManager, COMPAT_MATRIX, type ChannelAdapter, ConfigSchema, DROPCLAW_MANIFEST, DSersClient, type DSersClientConfig, type DSersOrder, type DSersProduct, type DSersStore, type DSersVariant, type DropClawConfig, DropClawCoreAgent, DropClawError, DropClawGateway, ErrorCategory, FileMemoryProvider, type JobManager, type JobPayload, type JobStatus, type LLMConfig, type Memory, type MemoryFilter, type MemoryMeta, type MemoryProvider, type NormalizedMessage, type OutboundMessage, type PushResult, type RetryOptions, type Rule, type RuleEngine, type RuleEvaluationResult, type SessionState, type StructuredError, TelegramAdapter, type UserSessionData, WebChatServer, acquireUserLock, auditFilePath, checkCompatibility, checkInboundLimit, createCircuitBreaker, createDSersConfig, createLogger, debounceUser, degradationMessage, deleteSession, getAllBreakerStatus, getDefaultModel, getDegradationStatus, getOutboundLimiter, getTraceContext, getTraceId, idempotencyKey, isDegraded, isOnboarding, loadConfig, loadSession, markDegraded, markRecovered, parseRetryAfter, runWithTrace, saveConfig, saveSession, sleep, withRetry, writeAuditLog };
|