@questionbase/deskfree 0.3.0-alpha.9 → 0.4.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/bin.d.ts +1 -0
- package/dist/bin.js +14119 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli/install.d.ts +3 -0
- package/dist/cli/install.js +53 -0
- package/dist/cli/install.js.map +1 -0
- package/dist/cli/uninstall.d.ts +3 -0
- package/dist/cli/uninstall.js +36 -0
- package/dist/cli/uninstall.js.map +1 -0
- package/dist/index.d.ts +381 -689
- package/dist/index.js +9592 -4834
- package/dist/index.js.map +1 -1
- package/package.json +37 -47
- package/README.md +0 -137
- package/openclaw.plugin.json +0 -8
- package/skills/deskfree/SKILL.md +0 -243
- package/skills/deskfree/references/tools.md +0 -102
package/dist/index.d.ts
CHANGED
|
@@ -1,727 +1,419 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PluginLogger, DeskFreeClient, DeskFreeTool, ChatMessage, RuntimeBootstrapConfig } from '@deskfree/core';
|
|
2
|
+
import * as _anthropic_ai_claude_agent_sdk from '@anthropic-ai/claude-agent-sdk';
|
|
3
|
+
import { McpSdkServerConfigWithInstance, SDKMessage, SDKUserMessage, Query, tool } from '@anthropic-ai/claude-agent-sdk';
|
|
2
4
|
|
|
5
|
+
interface StartAgentOptions {
|
|
6
|
+
log?: PluginLogger;
|
|
7
|
+
}
|
|
8
|
+
/** Dispose function returned by startAgent — call to shut down cleanly. */
|
|
9
|
+
type DisposeAgent = () => void;
|
|
3
10
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
11
|
+
* Full agent startup sequence:
|
|
12
|
+
*
|
|
13
|
+
* 1. Load local config (token + apiUrl from env)
|
|
14
|
+
* 2. Create DeskFree client
|
|
15
|
+
* 3. Bootstrap: fetch config from API (wsUrl, model, region, tools)
|
|
16
|
+
* 4. Install enabled tool packages
|
|
17
|
+
* 5. Configure Agent SDK env vars (Bedrock, region, model)
|
|
18
|
+
* 6. Create MCP servers
|
|
19
|
+
* 7. Start health server + WS gateway + heartbeat
|
|
8
20
|
*/
|
|
21
|
+
declare function startAgent(opts?: StartAgentOptions): Promise<DisposeAgent>;
|
|
9
22
|
|
|
10
|
-
interface
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
content: Array<{
|
|
16
|
-
type: string;
|
|
17
|
-
text?: string;
|
|
18
|
-
}>;
|
|
19
|
-
}>;
|
|
20
|
-
optional?: boolean;
|
|
21
|
-
}
|
|
22
|
-
interface OpenClawPluginToolContext {
|
|
23
|
-
config?: unknown;
|
|
24
|
-
messageChannel?: unknown;
|
|
25
|
-
agentAccountId?: string;
|
|
26
|
-
sandboxed?: boolean;
|
|
27
|
-
}
|
|
28
|
-
type OpenClawPluginToolFactory = (ctx: OpenClawPluginToolContext) => AnyAgentTool | AnyAgentTool[] | null | undefined;
|
|
29
|
-
interface OpenClawPluginToolOptions {
|
|
30
|
-
optional?: boolean;
|
|
31
|
-
}
|
|
32
|
-
interface OpenClawConfig {
|
|
33
|
-
channels?: {
|
|
34
|
-
deskfree?: DeskFreeChannelConfig;
|
|
35
|
-
[key: string]: unknown;
|
|
36
|
-
};
|
|
37
|
-
plugins?: {
|
|
38
|
-
entries?: {
|
|
39
|
-
[pluginId: string]: {
|
|
40
|
-
enabled?: boolean;
|
|
41
|
-
[key: string]: unknown;
|
|
42
|
-
};
|
|
43
|
-
};
|
|
44
|
-
[key: string]: unknown;
|
|
45
|
-
};
|
|
46
|
-
[key: string]: unknown;
|
|
47
|
-
}
|
|
48
|
-
interface OpenClawPluginApi {
|
|
49
|
-
runtime: PluginRuntime;
|
|
50
|
-
config: OpenClawConfig;
|
|
51
|
-
pluginConfig: Record<string, unknown>;
|
|
52
|
-
logger: PluginLogger;
|
|
53
|
-
registerChannel(registration: {
|
|
54
|
-
plugin: ChannelPlugin;
|
|
55
|
-
}): void;
|
|
56
|
-
registerHttpRoute(params: {
|
|
57
|
-
path: string;
|
|
58
|
-
handler: (req: IncomingMessage, res: ServerResponse) => Promise<void> | void;
|
|
59
|
-
}): void;
|
|
60
|
-
registerTool(tool: AnyAgentTool | OpenClawPluginToolFactory, opts?: OpenClawPluginToolOptions): void;
|
|
61
|
-
registerHook(events: string | string[], handler: (event: Record<string, unknown>) => Promise<unknown> | unknown, opts?: {
|
|
62
|
-
priority?: number;
|
|
63
|
-
}): void;
|
|
64
|
-
on<K extends PluginHookName>(hookName: K, handler: PluginHookHandlerMap[K], opts?: {
|
|
65
|
-
priority?: number;
|
|
66
|
-
}): void;
|
|
67
|
-
}
|
|
68
|
-
type PluginHookName = 'before_agent_start' | 'llm_input' | 'llm_output' | 'agent_end' | 'before_compaction' | 'after_compaction' | 'before_reset' | 'message_received' | 'message_sending' | 'message_sent' | 'before_tool_call' | 'after_tool_call' | 'tool_result_persist' | 'session_start' | 'session_end' | 'gateway_start' | 'gateway_stop';
|
|
69
|
-
interface PluginHookAgentContext {
|
|
70
|
-
agentId?: string;
|
|
71
|
-
sessionKey?: string;
|
|
23
|
+
interface OrchestratorQueryOptions {
|
|
24
|
+
prompt: string;
|
|
25
|
+
orchestratorServer: McpSdkServerConfigWithInstance;
|
|
26
|
+
model: string;
|
|
27
|
+
/** Agent SDK session ID to resume (for multi-turn conversations). */
|
|
72
28
|
sessionId?: string;
|
|
73
|
-
workspaceDir?: string;
|
|
74
|
-
messageProvider?: string;
|
|
75
29
|
}
|
|
76
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Run the orchestrator agent. Returns an async iterable of SDKMessage events.
|
|
32
|
+
*
|
|
33
|
+
* The orchestrator:
|
|
34
|
+
* - Uses DeskFree orchestrator tools via MCP
|
|
35
|
+
* - Dispatches workers via the deskfree_dispatch_worker MCP tool
|
|
36
|
+
* - Persists sessions for multi-turn conversations
|
|
37
|
+
*/
|
|
38
|
+
declare function runOrchestrator(opts: OrchestratorQueryOptions): AsyncGenerator<SDKMessage, void>;
|
|
39
|
+
interface HeartbeatOptions {
|
|
77
40
|
prompt: string;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
interface PluginHookBeforeAgentStartResult {
|
|
81
|
-
systemPrompt?: string;
|
|
82
|
-
prependContext?: string;
|
|
83
|
-
}
|
|
84
|
-
type PluginHookHandlerMap = {
|
|
85
|
-
before_agent_start: (event: PluginHookBeforeAgentStartEvent, ctx: PluginHookAgentContext) => Promise<PluginHookBeforeAgentStartResult | void> | PluginHookBeforeAgentStartResult | void;
|
|
86
|
-
llm_input: (event: Record<string, unknown>, ctx: PluginHookAgentContext) => Promise<void> | void;
|
|
87
|
-
llm_output: (event: Record<string, unknown>, ctx: PluginHookAgentContext) => Promise<void> | void;
|
|
88
|
-
agent_end: (event: Record<string, unknown>, ctx: PluginHookAgentContext) => Promise<void> | void;
|
|
89
|
-
before_compaction: (event: Record<string, unknown>, ctx: PluginHookAgentContext) => Promise<void> | void;
|
|
90
|
-
after_compaction: (event: Record<string, unknown>, ctx: PluginHookAgentContext) => Promise<void> | void;
|
|
91
|
-
before_reset: (event: Record<string, unknown>, ctx: PluginHookAgentContext) => Promise<void> | void;
|
|
92
|
-
message_received: (event: Record<string, unknown>, ctx: Record<string, unknown>) => Promise<void> | void;
|
|
93
|
-
message_sending: (event: Record<string, unknown>, ctx: Record<string, unknown>) => Promise<Record<string, unknown> | void> | Record<string, unknown> | void;
|
|
94
|
-
message_sent: (event: Record<string, unknown>, ctx: Record<string, unknown>) => Promise<void> | void;
|
|
95
|
-
before_tool_call: (event: Record<string, unknown>, ctx: Record<string, unknown>) => Promise<Record<string, unknown> | void> | Record<string, unknown> | void;
|
|
96
|
-
after_tool_call: (event: Record<string, unknown>, ctx: Record<string, unknown>) => Promise<void> | void;
|
|
97
|
-
tool_result_persist: (event: Record<string, unknown>, ctx: Record<string, unknown>) => Record<string, unknown> | void;
|
|
98
|
-
session_start: (event: Record<string, unknown>, ctx: Record<string, unknown>) => Promise<void> | void;
|
|
99
|
-
session_end: (event: Record<string, unknown>, ctx: Record<string, unknown>) => Promise<void> | void;
|
|
100
|
-
gateway_start: (event: Record<string, unknown>, ctx: Record<string, unknown>) => Promise<void> | void;
|
|
101
|
-
gateway_stop: (event: Record<string, unknown>, ctx: Record<string, unknown>) => Promise<void> | void;
|
|
102
|
-
};
|
|
103
|
-
interface PluginRuntime {
|
|
104
|
-
version: string;
|
|
105
|
-
config: {
|
|
106
|
-
loadConfig(): OpenClawConfig;
|
|
107
|
-
writeConfigFile(cfg: OpenClawConfig): Promise<void>;
|
|
108
|
-
};
|
|
109
|
-
channel: {
|
|
110
|
-
reply: {
|
|
111
|
-
finalizeInboundContext<T extends Record<string, unknown>>(ctx: T): T & FinalizedMsgContext;
|
|
112
|
-
dispatchReplyFromConfig(params: {
|
|
113
|
-
ctx: FinalizedMsgContext;
|
|
114
|
-
cfg: OpenClawConfig;
|
|
115
|
-
dispatcher: ReplyDispatcher;
|
|
116
|
-
replyOptions?: Record<string, unknown>;
|
|
117
|
-
}): Promise<{
|
|
118
|
-
queuedFinal: boolean;
|
|
119
|
-
}>;
|
|
120
|
-
createReplyDispatcherWithTyping(params: {
|
|
121
|
-
channel: string;
|
|
122
|
-
accountId: string;
|
|
123
|
-
deliver: (payload: {
|
|
124
|
-
text?: string;
|
|
125
|
-
body?: string;
|
|
126
|
-
}) => Promise<void>;
|
|
127
|
-
[key: string]: unknown;
|
|
128
|
-
}): {
|
|
129
|
-
dispatcher: ReplyDispatcher;
|
|
130
|
-
replyOptions: Record<string, unknown>;
|
|
131
|
-
markDispatchIdle: () => void;
|
|
132
|
-
};
|
|
133
|
-
};
|
|
134
|
-
text: {
|
|
135
|
-
chunkMarkdownText(text: string, limit: number): string[];
|
|
136
|
-
};
|
|
137
|
-
};
|
|
138
|
-
logging: {
|
|
139
|
-
createLogger(name: string): PluginLogger;
|
|
140
|
-
};
|
|
141
|
-
state: {
|
|
142
|
-
resolveStateDir(): string;
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
interface FinalizedMsgContext {
|
|
146
|
-
Body: string;
|
|
147
|
-
RawBody?: string;
|
|
148
|
-
ChatType: string;
|
|
149
|
-
Provider: string;
|
|
150
|
-
Surface: string;
|
|
151
|
-
From: string;
|
|
152
|
-
To: string;
|
|
153
|
-
MessageSid: string;
|
|
154
|
-
Timestamp?: string;
|
|
155
|
-
BodyForAgent?: string;
|
|
156
|
-
[key: string]: unknown;
|
|
157
|
-
}
|
|
158
|
-
interface ReplyDispatcher {
|
|
159
|
-
send(reply: unknown): Promise<void>;
|
|
160
|
-
getQueuedCounts(): unknown;
|
|
161
|
-
}
|
|
162
|
-
interface PluginLogger {
|
|
163
|
-
info(msg: string): void;
|
|
164
|
-
warn(msg: string): void;
|
|
165
|
-
error(msg: string): void;
|
|
166
|
-
debug(msg: string): void;
|
|
167
|
-
}
|
|
168
|
-
interface ChannelMessagingTargetResolver {
|
|
169
|
-
hint?: string;
|
|
170
|
-
looksLikeId?(raw: string, normalized?: string): boolean;
|
|
171
|
-
}
|
|
172
|
-
interface ChannelMessagingAdapter {
|
|
173
|
-
normalizeTarget?(raw: string): string | undefined;
|
|
174
|
-
targetResolver?: ChannelMessagingTargetResolver;
|
|
175
|
-
}
|
|
176
|
-
interface ChannelPlugin {
|
|
177
|
-
id: string;
|
|
178
|
-
meta: ChannelMeta;
|
|
179
|
-
capabilities: ChannelCapabilities;
|
|
180
|
-
config: ChannelConfigAdapter;
|
|
181
|
-
outbound?: ChannelOutboundAdapter;
|
|
182
|
-
gateway?: ChannelGatewayAdapter;
|
|
183
|
-
setup?: ChannelSetupAdapter;
|
|
184
|
-
security?: ChannelSecurityAdapter;
|
|
185
|
-
messaging?: ChannelMessagingAdapter;
|
|
186
|
-
onboarding?: ChannelOnboardingAdapter;
|
|
187
|
-
status?: ChannelStatusAdapter;
|
|
188
|
-
}
|
|
189
|
-
interface ChannelMeta {
|
|
190
|
-
name: string;
|
|
191
|
-
icon?: string;
|
|
192
|
-
description?: string;
|
|
193
|
-
}
|
|
194
|
-
interface ChannelCapabilities {
|
|
195
|
-
text: boolean;
|
|
196
|
-
media: boolean;
|
|
197
|
-
reactions: boolean;
|
|
198
|
-
threads: boolean;
|
|
199
|
-
editing: boolean;
|
|
200
|
-
}
|
|
201
|
-
interface ChannelConfigAdapter {
|
|
202
|
-
listAccountIds(cfg: OpenClawConfig): string[];
|
|
203
|
-
resolveAccount(cfg: OpenClawConfig, accountId?: string | null): ResolvedDeskFreeAccount;
|
|
204
|
-
isConfigured?(account: ResolvedDeskFreeAccount, cfg?: OpenClawConfig): boolean;
|
|
205
|
-
isEnabled?(account: ResolvedDeskFreeAccount, cfg?: OpenClawConfig): boolean;
|
|
206
|
-
describeAccount?(account: ResolvedDeskFreeAccount, cfg?: OpenClawConfig): ChannelAccountSnapshot;
|
|
207
|
-
}
|
|
208
|
-
interface ChannelOutboundAdapter {
|
|
209
|
-
deliveryMode: 'direct' | 'gateway' | 'hybrid';
|
|
210
|
-
resolveTarget?(target: string, ctx: {
|
|
211
|
-
cfg: OpenClawConfig;
|
|
212
|
-
accountId?: string | null;
|
|
213
|
-
}): {
|
|
214
|
-
to: string;
|
|
215
|
-
} | null;
|
|
216
|
-
sendText?(ctx: ChannelOutboundContext): Promise<OutboundDeliveryResult>;
|
|
217
|
-
textChunkLimit?: number;
|
|
218
|
-
chunkerMode?: 'text' | 'markdown';
|
|
219
|
-
}
|
|
220
|
-
interface ChannelGatewayAdapter {
|
|
221
|
-
startAccount?(ctx: ChannelGatewayContext): Promise<unknown>;
|
|
222
|
-
stopAccount?(ctx: ChannelGatewayContext): Promise<void>;
|
|
223
|
-
logoutAccount?(ctx: ChannelLogoutContext): Promise<ChannelLogoutResult>;
|
|
224
|
-
}
|
|
225
|
-
interface ChannelGatewayContext {
|
|
226
|
-
cfg: OpenClawConfig;
|
|
227
|
-
accountId: string;
|
|
228
|
-
account: ResolvedDeskFreeAccount;
|
|
229
|
-
runtime: PluginRuntime;
|
|
230
|
-
abortSignal: AbortSignal;
|
|
231
|
-
log?: PluginLogger;
|
|
232
|
-
getStatus(): ChannelAccountSnapshot;
|
|
233
|
-
setStatus(next: Partial<ChannelAccountSnapshot>): void;
|
|
234
|
-
}
|
|
235
|
-
interface ChannelSetupAdapter {
|
|
236
|
-
applyAccountConfig(params: {
|
|
237
|
-
cfg: OpenClawConfig;
|
|
238
|
-
accountId: string;
|
|
239
|
-
input: Record<string, string>;
|
|
240
|
-
}): OpenClawConfig;
|
|
241
|
-
validateInput?(params: {
|
|
242
|
-
cfg: OpenClawConfig;
|
|
243
|
-
accountId: string;
|
|
244
|
-
input: Record<string, string>;
|
|
245
|
-
}): string | null;
|
|
246
|
-
}
|
|
247
|
-
interface ChannelSecurityDmPolicy {
|
|
248
|
-
policy: string;
|
|
249
|
-
allowFrom?: Array<string | number> | null;
|
|
250
|
-
policyPath?: string;
|
|
251
|
-
allowFromPath: string;
|
|
252
|
-
approveHint: string;
|
|
253
|
-
normalizeEntry?: (raw: string) => string;
|
|
254
|
-
}
|
|
255
|
-
interface ChannelSecurityAdapter {
|
|
256
|
-
resolveDmPolicy?(ctx: {
|
|
257
|
-
cfg: OpenClawConfig;
|
|
258
|
-
accountId?: string | null;
|
|
259
|
-
account: ResolvedDeskFreeAccount;
|
|
260
|
-
}): ChannelSecurityDmPolicy | null;
|
|
261
|
-
collectWarnings?(ctx: {
|
|
262
|
-
cfg: OpenClawConfig;
|
|
263
|
-
accountId?: string | null;
|
|
264
|
-
account: ResolvedDeskFreeAccount;
|
|
265
|
-
}): Promise<string[]> | string[];
|
|
266
|
-
}
|
|
267
|
-
interface ChannelOutboundContext {
|
|
268
|
-
cfg: OpenClawConfig;
|
|
269
|
-
to: string;
|
|
270
|
-
text: string;
|
|
271
|
-
threadId?: string | number | null;
|
|
272
|
-
replyToId?: string | null;
|
|
273
|
-
accountId?: string | null;
|
|
274
|
-
}
|
|
275
|
-
interface OutboundDeliveryResult {
|
|
276
|
-
channel: string;
|
|
277
|
-
success: boolean;
|
|
278
|
-
threadId?: string;
|
|
279
|
-
}
|
|
280
|
-
interface ChannelAccountSnapshot {
|
|
281
|
-
accountId?: string;
|
|
282
|
-
enabled?: boolean;
|
|
283
|
-
configured?: boolean;
|
|
284
|
-
running?: boolean;
|
|
285
|
-
lastStartAt?: number;
|
|
286
|
-
lastStopAt?: number;
|
|
287
|
-
lastError?: string;
|
|
288
|
-
probe?: ChannelProbeResult;
|
|
289
|
-
}
|
|
290
|
-
interface ResolvedDeskFreeAccount {
|
|
291
|
-
accountId: string;
|
|
292
|
-
botToken: string;
|
|
293
|
-
apiUrl: string;
|
|
294
|
-
wsUrl: string;
|
|
295
|
-
userId: string;
|
|
296
|
-
enabled: boolean;
|
|
297
|
-
botName?: string;
|
|
298
|
-
humanName?: string;
|
|
299
|
-
}
|
|
300
|
-
interface DeskFreeChannelConfig {
|
|
301
|
-
enabled?: boolean;
|
|
302
|
-
botToken: string;
|
|
303
|
-
apiUrl: string;
|
|
304
|
-
wsUrl: string;
|
|
305
|
-
userId: string;
|
|
306
|
-
botName?: string;
|
|
307
|
-
humanName?: string;
|
|
308
|
-
accounts?: Record<string, Omit<DeskFreeChannelConfig, 'accounts'>>;
|
|
309
|
-
}
|
|
310
|
-
interface ChatMessageAttachment {
|
|
311
|
-
name: string;
|
|
312
|
-
contentType: string;
|
|
313
|
-
size: number;
|
|
314
|
-
url: string;
|
|
315
|
-
}
|
|
316
|
-
interface ChatMessage {
|
|
317
|
-
messageId: string;
|
|
318
|
-
botId: string;
|
|
319
|
-
humanId: string;
|
|
320
|
-
authorType: 'bot' | 'user';
|
|
321
|
-
content: string;
|
|
322
|
-
attachments?: ChatMessageAttachment[];
|
|
323
|
-
taskId?: string | null;
|
|
324
|
-
createdAt: string;
|
|
325
|
-
userName?: string | null;
|
|
326
|
-
botName?: string | null;
|
|
327
|
-
}
|
|
328
|
-
interface MessagesResponse {
|
|
329
|
-
items: ChatMessage[];
|
|
330
|
-
cursor: string | null;
|
|
331
|
-
hasMore: boolean;
|
|
332
|
-
}
|
|
333
|
-
interface WsTicketResponse {
|
|
334
|
-
ticket: string;
|
|
335
|
-
wsUrl: string;
|
|
336
|
-
expiresAt: string;
|
|
337
|
-
}
|
|
338
|
-
interface WizardPrompter {
|
|
339
|
-
text(params: {
|
|
340
|
-
message: string;
|
|
341
|
-
initialValue?: string;
|
|
342
|
-
placeholder?: string;
|
|
343
|
-
validate?: (value: string) => string | undefined;
|
|
344
|
-
}): Promise<string>;
|
|
345
|
-
confirm(params: {
|
|
346
|
-
message: string;
|
|
347
|
-
initialValue?: boolean;
|
|
348
|
-
}): Promise<boolean>;
|
|
349
|
-
note(message: string, title?: string): Promise<void>;
|
|
350
|
-
}
|
|
351
|
-
interface ChannelOnboardingStatus {
|
|
352
|
-
channel: string;
|
|
353
|
-
configured: boolean;
|
|
354
|
-
statusLines: string[];
|
|
355
|
-
selectionHint?: string;
|
|
356
|
-
quickstartScore?: number;
|
|
357
|
-
}
|
|
358
|
-
interface ChannelOnboardingResult {
|
|
359
|
-
cfg: OpenClawConfig;
|
|
360
|
-
accountId?: string;
|
|
361
|
-
}
|
|
362
|
-
interface ChannelOnboardingAdapter {
|
|
363
|
-
channel: string;
|
|
364
|
-
getStatus(ctx: {
|
|
365
|
-
cfg: OpenClawConfig;
|
|
366
|
-
}): Promise<ChannelOnboardingStatus>;
|
|
367
|
-
configure(ctx: {
|
|
368
|
-
cfg: OpenClawConfig;
|
|
369
|
-
runtime: PluginRuntime;
|
|
370
|
-
prompter: WizardPrompter;
|
|
371
|
-
accountOverrides: Record<string, string>;
|
|
372
|
-
shouldPromptAccountIds: boolean;
|
|
373
|
-
forceAllowFrom: boolean;
|
|
374
|
-
}): Promise<ChannelOnboardingResult>;
|
|
375
|
-
disable?(cfg: OpenClawConfig): OpenClawConfig;
|
|
376
|
-
}
|
|
377
|
-
interface ChannelProbeResult {
|
|
378
|
-
ok: boolean;
|
|
379
|
-
error?: string;
|
|
380
|
-
}
|
|
381
|
-
interface ChannelStatusIssue {
|
|
382
|
-
channel: string;
|
|
383
|
-
accountId: string;
|
|
384
|
-
kind: 'config' | 'auth' | 'runtime';
|
|
385
|
-
message: string;
|
|
386
|
-
fix?: string;
|
|
387
|
-
}
|
|
388
|
-
interface ChannelStatusAdapter {
|
|
389
|
-
probeAccount?(params: {
|
|
390
|
-
account: ResolvedDeskFreeAccount;
|
|
391
|
-
timeoutMs: number;
|
|
392
|
-
cfg: OpenClawConfig;
|
|
393
|
-
}): Promise<ChannelProbeResult>;
|
|
394
|
-
buildAccountSnapshot?(params: {
|
|
395
|
-
account: ResolvedDeskFreeAccount;
|
|
396
|
-
cfg: OpenClawConfig;
|
|
397
|
-
runtime?: ChannelAccountSnapshot;
|
|
398
|
-
probe?: ChannelProbeResult;
|
|
399
|
-
}): ChannelAccountSnapshot;
|
|
400
|
-
collectStatusIssues?(accounts: ChannelAccountSnapshot[]): ChannelStatusIssue[];
|
|
401
|
-
}
|
|
402
|
-
interface ChannelLogoutContext {
|
|
403
|
-
cfg: OpenClawConfig;
|
|
404
|
-
accountId: string;
|
|
405
|
-
account: ResolvedDeskFreeAccount;
|
|
406
|
-
runtime: PluginRuntime;
|
|
407
|
-
log?: PluginLogger;
|
|
408
|
-
}
|
|
409
|
-
interface ChannelLogoutResult {
|
|
410
|
-
cleared: boolean;
|
|
411
|
-
loggedOut?: boolean;
|
|
412
|
-
[key: string]: unknown;
|
|
413
|
-
}
|
|
414
|
-
interface WsNotification {
|
|
415
|
-
action: 'notify';
|
|
416
|
-
hint: string;
|
|
41
|
+
orchestratorServer: McpSdkServerConfigWithInstance;
|
|
42
|
+
model: string;
|
|
417
43
|
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
taskId: string;
|
|
430
|
-
title: string;
|
|
431
|
-
status: 'ready_for_bot' | 'working_on_it' | 'waiting_for_human' | 'done';
|
|
432
|
-
instructions?: string;
|
|
433
|
-
createdAt: string;
|
|
434
|
-
updatedAt: string;
|
|
435
|
-
botId?: string | null;
|
|
436
|
-
createdById: string;
|
|
437
|
-
reason?: string | null;
|
|
438
|
-
deliverable?: string | null;
|
|
439
|
-
}
|
|
440
|
-
interface TaskMessage {
|
|
441
|
-
messageId: string;
|
|
442
|
-
authorType: 'bot' | 'user';
|
|
443
|
-
content: string;
|
|
444
|
-
attachments: ChatMessageAttachment[];
|
|
445
|
-
createdAt: string;
|
|
446
|
-
userName?: string | null;
|
|
447
|
-
}
|
|
448
|
-
interface TaskWithContext extends Task {
|
|
449
|
-
instructions: string;
|
|
450
|
-
deliverable: string;
|
|
451
|
-
messages: TaskMessage[];
|
|
44
|
+
/**
|
|
45
|
+
* Run a one-shot heartbeat query (no session persistence).
|
|
46
|
+
*/
|
|
47
|
+
declare function runHeartbeat(opts: HeartbeatOptions): AsyncGenerator<SDKMessage, void>;
|
|
48
|
+
|
|
49
|
+
interface WorkerQueryOptions {
|
|
50
|
+
prompt: string | AsyncIterable<SDKUserMessage>;
|
|
51
|
+
workerServer: McpSdkServerConfigWithInstance;
|
|
52
|
+
model: string;
|
|
53
|
+
/** Agent SDK session ID to resume (for multi-turn task conversations). */
|
|
54
|
+
sessionId?: string;
|
|
452
55
|
}
|
|
453
56
|
/**
|
|
454
|
-
*
|
|
57
|
+
* Run the worker agent directly. Returns a Query (async iterable of
|
|
58
|
+
* SDKMessage events with a .close() method for teardown).
|
|
455
59
|
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
*
|
|
60
|
+
* Used for task thread messages where the router routes to 'runner'.
|
|
61
|
+
* The worker:
|
|
62
|
+
* - Claims a task and loads its context
|
|
63
|
+
* - Executes work (update files, steps, send messages)
|
|
64
|
+
* - Completes the task
|
|
459
65
|
*/
|
|
460
|
-
|
|
461
|
-
interface CompleteTaskInput {
|
|
462
|
-
taskId: string;
|
|
463
|
-
outcome: 'done' | 'blocked';
|
|
464
|
-
}
|
|
465
|
-
interface WorkspaceStateTask {
|
|
466
|
-
taskId: string;
|
|
467
|
-
title: string;
|
|
468
|
-
status: 'ready_for_bot' | 'working_on_it' | 'waiting_for_human' | 'done';
|
|
469
|
-
instructions?: string | null;
|
|
470
|
-
deliverable?: string | null;
|
|
471
|
-
createdAt: string;
|
|
472
|
-
updatedAt: string;
|
|
473
|
-
}
|
|
474
|
-
interface WorkspaceStateGoal {
|
|
475
|
-
goalId: string;
|
|
476
|
-
title: string;
|
|
477
|
-
description?: string | null;
|
|
478
|
-
status: 'active' | 'paused' | 'completed' | 'archived';
|
|
479
|
-
tasks: WorkspaceStateTask[];
|
|
480
|
-
}
|
|
481
|
-
interface WorkspaceState {
|
|
482
|
-
goals: WorkspaceStateGoal[];
|
|
483
|
-
unlinkedTasks: WorkspaceStateTask[];
|
|
484
|
-
recentlyDone: WorkspaceStateTask[];
|
|
485
|
-
}
|
|
66
|
+
declare function runWorker(opts: WorkerQueryOptions): Query;
|
|
486
67
|
|
|
487
|
-
/**
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
private request;
|
|
507
|
-
/**
|
|
508
|
-
* Validates that a string parameter is non-empty.
|
|
509
|
-
* Catches invalid inputs before they hit the network.
|
|
510
|
-
*/
|
|
511
|
-
private requireNonEmpty;
|
|
68
|
+
/**
|
|
69
|
+
* Manages daily log files for memory observations.
|
|
70
|
+
*
|
|
71
|
+
* Logs are stored at `{stateDir}/memory/{botId}/daily/YYYY-MM-DD.md`.
|
|
72
|
+
* Each entry is a single line: `- [ISO timestamp] (task: {taskId}) {content}`
|
|
73
|
+
*
|
|
74
|
+
* Appends are atomic via O_APPEND flag (safe for writes <4KB on Linux).
|
|
75
|
+
*/
|
|
76
|
+
declare class DailyLogManager {
|
|
77
|
+
private readonly dailyDir;
|
|
78
|
+
constructor(stateDir: string, botId: string);
|
|
79
|
+
/** Ensure the daily log directory exists. */
|
|
80
|
+
init(): void;
|
|
81
|
+
/** Append a learning entry to today's log file. */
|
|
82
|
+
appendLearning(content: string, taskId?: string): Promise<void>;
|
|
83
|
+
/** Read today's daily log, or null if it doesn't exist. */
|
|
84
|
+
readToday(): Promise<string | null>;
|
|
85
|
+
/** Read all daily logs, concatenated with date headers. */
|
|
86
|
+
readAllLogs(): Promise<string | null>;
|
|
512
87
|
/**
|
|
513
|
-
*
|
|
514
|
-
*
|
|
515
|
-
* @param input - Optional parameters including taskId to scope the indicator
|
|
88
|
+
* Read recent daily logs up to a character budget (newest first).
|
|
89
|
+
* Returns as many days as fit. Quiet week → 14 days. Busy day → just today.
|
|
516
90
|
*/
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
91
|
+
readRecentWithBudget(maxChars: number): Promise<string | null>;
|
|
92
|
+
/** Delete daily log files older than the given number of days. */
|
|
93
|
+
pruneOlderThan(days: number): void;
|
|
94
|
+
private todayPath;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
interface WorkerManagerDeps {
|
|
98
|
+
client: DeskFreeClient;
|
|
99
|
+
createWorkerServer: () => McpSdkServerConfigWithInstance;
|
|
100
|
+
model: string;
|
|
101
|
+
log: PluginLogger;
|
|
102
|
+
/** Max concurrent workers. Defaults to 5. */
|
|
103
|
+
maxConcurrentWorkers?: number;
|
|
104
|
+
/** DailyLogManager for injecting recent observations into worker context. */
|
|
105
|
+
dailyLog?: DailyLogManager;
|
|
106
|
+
/** Character budget for daily log injection (~4 chars/token). Defaults to 16000. */
|
|
107
|
+
dailyLogCharBudget?: number;
|
|
108
|
+
/** Path to persist session history JSON (taskId → sessionId). */
|
|
109
|
+
sessionHistoryPath?: string;
|
|
110
|
+
}
|
|
111
|
+
declare class WorkerManager {
|
|
112
|
+
private workers;
|
|
113
|
+
/** Persists taskId → sessionId across worker restarts for session resume. */
|
|
114
|
+
private sessionHistory;
|
|
115
|
+
private pendingQueue;
|
|
116
|
+
private deps;
|
|
117
|
+
private maxConcurrent;
|
|
118
|
+
constructor(deps: WorkerManagerDeps);
|
|
119
|
+
/** Check if a worker is currently active for a task. */
|
|
120
|
+
has(taskId: string): boolean;
|
|
521
121
|
/**
|
|
522
|
-
*
|
|
122
|
+
* Dispatch a new long-lived worker for a task.
|
|
123
|
+
* Claims the task and loads workspace state server-side, then builds
|
|
124
|
+
* an enriched first message so the worker can start immediately.
|
|
523
125
|
*
|
|
524
|
-
*
|
|
126
|
+
* If at capacity, queues the dispatch and notifies the user.
|
|
127
|
+
* If a worker already exists for this taskId, returns 'already_running'.
|
|
525
128
|
*/
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
}>;
|
|
129
|
+
dispatch(taskId: string, userMessage?: string): Promise<'started' | 'already_running' | 'queued'>;
|
|
130
|
+
/** Number of active workers. */
|
|
131
|
+
get activeCount(): number;
|
|
132
|
+
/** Number of queued dispatches waiting for a slot. */
|
|
133
|
+
get queuedCount(): number;
|
|
134
|
+
/** Maximum number of concurrent workers allowed. */
|
|
135
|
+
get maxConcurrentWorkers(): number;
|
|
534
136
|
/**
|
|
535
|
-
*
|
|
536
|
-
*
|
|
537
|
-
* @param input - Message content, optional userId, taskId, and attachments
|
|
137
|
+
* Push a message into an active worker's channel.
|
|
138
|
+
* Resets the idle timer.
|
|
538
139
|
*/
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
}): Promise<{
|
|
550
|
-
messageId: string;
|
|
551
|
-
content: string;
|
|
552
|
-
}>;
|
|
553
|
-
/** Fetch paginated message history for a conversation. */
|
|
554
|
-
listMessages(input: {
|
|
555
|
-
userId?: string;
|
|
556
|
-
cursor?: string | null;
|
|
557
|
-
limit?: number;
|
|
558
|
-
}): Promise<MessagesResponse>;
|
|
559
|
-
/** Obtain a one-time WebSocket authentication ticket for real-time notifications. */
|
|
560
|
-
getWsTicket(): Promise<WsTicketResponse>;
|
|
561
|
-
/** Create a new goal. */
|
|
562
|
-
createGoal(input: {
|
|
563
|
-
title: string;
|
|
564
|
-
description?: string;
|
|
565
|
-
}): Promise<{
|
|
566
|
-
goal: Goal;
|
|
567
|
-
}>;
|
|
568
|
-
/** Update a goal's status, title, or description. */
|
|
569
|
-
updateGoal(input: {
|
|
570
|
-
goalId: string;
|
|
571
|
-
title?: string;
|
|
572
|
-
description?: string;
|
|
573
|
-
status?: string;
|
|
574
|
-
}): Promise<Goal>;
|
|
575
|
-
/** Create a new task, optionally with a recurring schedule. */
|
|
576
|
-
createTask(input: {
|
|
577
|
-
title: string;
|
|
578
|
-
instructions?: string;
|
|
579
|
-
goalId?: string;
|
|
580
|
-
isRecurring?: boolean;
|
|
581
|
-
recurringSchedule?: {
|
|
582
|
-
frequency: 'daily' | 'weekly' | 'biweekly' | 'monthly';
|
|
583
|
-
dayOfWeek?: number;
|
|
584
|
-
dayOfMonth?: number;
|
|
585
|
-
time: string;
|
|
586
|
-
timezone?: string;
|
|
587
|
-
};
|
|
588
|
-
}): Promise<CreateTaskResponse>;
|
|
589
|
-
/** Claim a task so the bot can begin working on it. Returns enriched context. */
|
|
590
|
-
claimTask(input: {
|
|
591
|
-
taskId: string;
|
|
592
|
-
}): Promise<TaskWithContext>;
|
|
593
|
-
/** Update the deliverable (markdown content) for a task. */
|
|
594
|
-
updateDeliverable(input: {
|
|
595
|
-
taskId: string;
|
|
596
|
-
deliverable: string;
|
|
597
|
-
}): Promise<void>;
|
|
598
|
-
/** Send an agent status update to DeskFree. */
|
|
599
|
-
statusUpdate(input: {
|
|
600
|
-
status: 'idle' | 'working' | 'responding';
|
|
601
|
-
activeSubAgents: Array<{
|
|
602
|
-
label: string;
|
|
603
|
-
status: 'running' | 'completed' | 'failed';
|
|
604
|
-
startedAt: string;
|
|
605
|
-
completedAt?: string;
|
|
606
|
-
tokenUsage?: number;
|
|
607
|
-
task?: string;
|
|
608
|
-
}>;
|
|
609
|
-
model?: string;
|
|
610
|
-
lastActivity?: string;
|
|
611
|
-
pluginVersion?: string;
|
|
612
|
-
openclawVersion?: string;
|
|
613
|
-
}): Promise<{
|
|
614
|
-
success: boolean;
|
|
615
|
-
}>;
|
|
616
|
-
/** Report error log entries to the backend for CloudWatch/Slack visibility. */
|
|
617
|
-
reportError(input: {
|
|
618
|
-
errors: Array<{
|
|
619
|
-
message: string;
|
|
620
|
-
level: 'warn' | 'error' | 'fatal';
|
|
621
|
-
timestamp: string;
|
|
622
|
-
metadata?: Record<string, unknown>;
|
|
623
|
-
}>;
|
|
624
|
-
}): Promise<{
|
|
625
|
-
accepted: number;
|
|
626
|
-
}>;
|
|
627
|
-
/** Get short-lived AWS credentials for S3 workspace access. */
|
|
628
|
-
workspaceCredentials(): Promise<{
|
|
629
|
-
accessKeyId: string;
|
|
630
|
-
secretAccessKey: string;
|
|
631
|
-
sessionToken: string;
|
|
632
|
-
expiration: Date;
|
|
633
|
-
s3Uri: string;
|
|
634
|
-
region: string;
|
|
635
|
-
}>;
|
|
636
|
-
/** Notify DeskFree that workspace files have changed locally. */
|
|
637
|
-
workspaceRead(input: {
|
|
638
|
-
path: string;
|
|
639
|
-
}): Promise<{
|
|
640
|
-
path: string;
|
|
641
|
-
content: string;
|
|
642
|
-
lastModified: string;
|
|
643
|
-
}>;
|
|
644
|
-
/** Get full workspace snapshot — goals with tasks, unlinked tasks, recently done. */
|
|
645
|
-
getState(): Promise<WorkspaceState>;
|
|
646
|
-
/** Report token usage for a task. Atomically increments rollup columns. */
|
|
647
|
-
reportUsage(input: {
|
|
648
|
-
taskId: string;
|
|
649
|
-
inputTokens: number;
|
|
650
|
-
outputTokens: number;
|
|
651
|
-
thinkingTokens: number;
|
|
652
|
-
model: string;
|
|
653
|
-
estimatedCost: number;
|
|
654
|
-
}): Promise<{
|
|
655
|
-
success: boolean;
|
|
656
|
-
}>;
|
|
657
|
-
/** Complete a task with an outcome. Moves task to waiting_for_human. */
|
|
658
|
-
completeTask(input: CompleteTaskInput): Promise<Task & {
|
|
659
|
-
outcome: 'done' | 'blocked';
|
|
660
|
-
}>;
|
|
140
|
+
pushMessage(taskId: string, content: string): void;
|
|
141
|
+
/** Tear down a specific worker. */
|
|
142
|
+
teardown(taskId: string): void;
|
|
143
|
+
/** Tear down all active workers and clear the queue (shutdown hook). */
|
|
144
|
+
teardownAll(): void;
|
|
145
|
+
/** Core worker startup logic (no capacity check — callers must check first). */
|
|
146
|
+
private startWorker;
|
|
147
|
+
/** Drain the pending queue — called when a worker finishes. */
|
|
148
|
+
private drainQueue;
|
|
149
|
+
private startIdleTimer;
|
|
661
150
|
/**
|
|
662
|
-
*
|
|
663
|
-
*
|
|
664
|
-
* @param timeoutMs - Maximum time to wait for the probe response
|
|
665
|
-
* @returns Probe result indicating success or a descriptive error
|
|
151
|
+
* Background drain loop — processes query output and streams it back
|
|
152
|
+
* to DeskFree via DeskFreeStreamingSession.
|
|
666
153
|
*/
|
|
667
|
-
|
|
154
|
+
private drainLoop;
|
|
155
|
+
/** Load session history from disk (best-effort). */
|
|
156
|
+
private loadSessionHistory;
|
|
157
|
+
/** Persist session history to disk (best-effort). */
|
|
158
|
+
private saveSessionHistory;
|
|
159
|
+
/** Build an SDKUserMessage from plain text content. */
|
|
160
|
+
private buildUserMessage;
|
|
668
161
|
}
|
|
669
162
|
|
|
670
163
|
/**
|
|
671
|
-
*
|
|
672
|
-
*
|
|
164
|
+
* Create an in-process MCP server with orchestrator tools.
|
|
165
|
+
*
|
|
166
|
+
* When a WorkerManager is provided, adds the deskfree_dispatch_worker
|
|
167
|
+
* tool that lets the orchestrator dispatch long-lived workers for tasks.
|
|
673
168
|
*/
|
|
674
|
-
declare function
|
|
169
|
+
declare function createOrchestratorMcpServer(client: DeskFreeClient, customTools?: DeskFreeTool[], workerManager?: WorkerManager): _anthropic_ai_claude_agent_sdk.McpSdkServerConfigWithInstance;
|
|
675
170
|
|
|
171
|
+
interface ContentScanner {
|
|
172
|
+
scan(content: string): Promise<ScanResult>;
|
|
173
|
+
}
|
|
174
|
+
interface ScanResult {
|
|
175
|
+
safe: boolean;
|
|
176
|
+
reason?: string;
|
|
177
|
+
}
|
|
676
178
|
/**
|
|
677
|
-
*
|
|
179
|
+
* Default content scanner — applies heuristic injection pattern detection.
|
|
180
|
+
* In production the backend may provide a more sophisticated scanner.
|
|
181
|
+
*/
|
|
182
|
+
declare class DefaultContentScanner implements ContentScanner {
|
|
183
|
+
private readonly log?;
|
|
184
|
+
constructor(log?: PluginLogger | undefined);
|
|
185
|
+
scan(content: string): Promise<ScanResult>;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Wrap a tool's execute function with content scan verification.
|
|
189
|
+
* Used to gate file write operations.
|
|
678
190
|
*
|
|
679
|
-
*
|
|
680
|
-
*
|
|
681
|
-
*
|
|
191
|
+
* @param execute - The original tool execute function
|
|
192
|
+
* @param extractContent - Function to extract the text content to scan from args
|
|
193
|
+
* @param scanner - ContentScanner implementation
|
|
194
|
+
*/
|
|
195
|
+
declare function withContentScan<TArgs extends Record<string, unknown>>(execute: (args: TArgs) => Promise<unknown>, extractContent: (args: TArgs) => string | null | undefined, scanner: ContentScanner): (args: TArgs) => Promise<unknown>;
|
|
196
|
+
/**
|
|
197
|
+
* Validate a URL is safe to fetch (HTTPS only, no private IPs).
|
|
198
|
+
* Throws an error with a descriptive message if validation fails.
|
|
199
|
+
*/
|
|
200
|
+
declare function validateDownloadUrl(url: string): void;
|
|
201
|
+
/**
|
|
202
|
+
* Check whether a content type is allowed for attachment downloads.
|
|
682
203
|
*/
|
|
204
|
+
declare function isContentTypeAllowed(contentType: string): boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Sanitize a filename to prevent directory traversal and injection.
|
|
207
|
+
*/
|
|
208
|
+
declare function sanitizeFileName(fileName: string): string;
|
|
683
209
|
|
|
684
|
-
/**
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
210
|
+
/**
|
|
211
|
+
* Create an in-process MCP server with worker tools.
|
|
212
|
+
*
|
|
213
|
+
* If a ContentScanner is provided, the deskfree_update_file tool's execute
|
|
214
|
+
* function is wrapped to scan file content for prompt injection before
|
|
215
|
+
* allowing the write.
|
|
216
|
+
*/
|
|
217
|
+
declare function createWorkerMcpServer(client: DeskFreeClient, customTools?: DeskFreeTool[], contentScanner?: ContentScanner, dailyLog?: DailyLogManager): _anthropic_ai_claude_agent_sdk.McpSdkServerConfigWithInstance;
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* MCP Tool Adapter
|
|
221
|
+
*
|
|
222
|
+
* Converts DeskFreeTool[] into Agent SDK tool() definitions.
|
|
223
|
+
* JSON Schema parameters are converted to Zod schemas for the SDK's
|
|
224
|
+
* type-safe tool() function.
|
|
225
|
+
*/
|
|
226
|
+
|
|
227
|
+
type AgentSdkTool = ReturnType<typeof tool>;
|
|
228
|
+
/**
|
|
229
|
+
* Adapt a single DeskFreeTool into an Agent SDK tool() definition.
|
|
230
|
+
*
|
|
231
|
+
* The handler delegates to `tool.execute()` which returns a `ToolResult`
|
|
232
|
+
* — this is already compatible with the MCP `CallToolResult` shape:
|
|
233
|
+
* `{ content: Array<{ type: 'text', text: string }>, isError?: boolean }`
|
|
234
|
+
*/
|
|
235
|
+
declare function adaptTool(deskfreeTool: DeskFreeTool): AgentSdkTool;
|
|
236
|
+
/**
|
|
237
|
+
* Adapt an array of DeskFree tools into Agent SDK tool() definitions.
|
|
238
|
+
*/
|
|
239
|
+
declare function adaptTools(tools: DeskFreeTool[]): AgentSdkTool[];
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Session Store — maps DeskFree session keys to Agent SDK session IDs.
|
|
243
|
+
*
|
|
244
|
+
* Session keys:
|
|
245
|
+
* dm:<peerId> — DM messages routed to orchestrator
|
|
246
|
+
* task:<taskId> — Task thread messages routed to worker
|
|
247
|
+
*
|
|
248
|
+
* The Agent SDK handles conversation history internally via session
|
|
249
|
+
* persistence. We only need to track the mapping from our session keys
|
|
250
|
+
* to the Agent SDK session IDs.
|
|
251
|
+
*
|
|
252
|
+
* Why in-memory is fine:
|
|
253
|
+
* - Container restarts are clean — agents re-claim context from backend
|
|
254
|
+
* - Session ID mapping is a performance optimization, not state of record
|
|
255
|
+
* - Backend stores all messages persistently
|
|
256
|
+
*/
|
|
257
|
+
interface SessionEntry {
|
|
258
|
+
/** Agent SDK session ID for resuming conversations. */
|
|
259
|
+
agentSessionId: string;
|
|
260
|
+
/** Timestamp of last activity (for TTL eviction). */
|
|
261
|
+
lastActivityAt: number;
|
|
262
|
+
}
|
|
263
|
+
declare class SessionStore {
|
|
264
|
+
private readonly staleTtlMs;
|
|
265
|
+
private readonly maxSessions;
|
|
266
|
+
private readonly sessions;
|
|
267
|
+
private cleanupTimer;
|
|
268
|
+
constructor(staleTtlMs?: number, // 30 min TTL
|
|
269
|
+
maxSessions?: number);
|
|
704
270
|
/**
|
|
705
|
-
*
|
|
706
|
-
* Returns
|
|
271
|
+
* Get the Agent SDK session ID for a given key.
|
|
272
|
+
* Returns undefined if no session exists or it has expired.
|
|
707
273
|
*/
|
|
708
|
-
|
|
274
|
+
getSessionId(key: string): string | undefined;
|
|
709
275
|
/**
|
|
710
|
-
*
|
|
711
|
-
* Called when connectivity is restored (e.g., WebSocket reconnect).
|
|
276
|
+
* Store an Agent SDK session ID for a given key.
|
|
712
277
|
*/
|
|
713
|
-
|
|
714
|
-
/**
|
|
715
|
-
|
|
716
|
-
/**
|
|
717
|
-
|
|
718
|
-
|
|
278
|
+
setSessionId(key: string, agentSessionId: string): void;
|
|
279
|
+
/** Delete a specific session. */
|
|
280
|
+
delete(key: string): void;
|
|
281
|
+
/** Number of active sessions. */
|
|
282
|
+
get size(): number;
|
|
283
|
+
/** Remove sessions that haven't been active within the TTL. */
|
|
284
|
+
private cleanup;
|
|
285
|
+
/** Evict the session with the oldest lastActivityAt. */
|
|
286
|
+
private evictOldest;
|
|
287
|
+
/** Dispose — clear the cleanup timer. */
|
|
288
|
+
dispose(): void;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
interface WorkerStatus {
|
|
292
|
+
activeWorkers: number;
|
|
293
|
+
queuedTasks: number;
|
|
294
|
+
maxConcurrency: number;
|
|
295
|
+
}
|
|
296
|
+
interface GatewayConfig {
|
|
297
|
+
client: DeskFreeClient;
|
|
298
|
+
wsUrl: string;
|
|
299
|
+
accountId: string;
|
|
300
|
+
stateDir: string;
|
|
301
|
+
log: PluginLogger;
|
|
302
|
+
abortSignal: AbortSignal;
|
|
303
|
+
onMessage: (message: ChatMessage) => Promise<void>;
|
|
304
|
+
getWorkerStatus?: () => WorkerStatus;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Start the WS gateway — reconnection loop with backoff.
|
|
308
|
+
*
|
|
309
|
+
* Loop: getWsTicket() → connect → listen for notify → poll messages → deliver
|
|
310
|
+
* On disconnect: backoff → reconnect
|
|
311
|
+
* Fallback: interval-based polling when WS is unavailable
|
|
312
|
+
*/
|
|
313
|
+
declare function startGateway(config: GatewayConfig): Promise<void>;
|
|
314
|
+
|
|
315
|
+
interface ToolPackageConfig {
|
|
316
|
+
package: string;
|
|
317
|
+
version: string;
|
|
719
318
|
}
|
|
319
|
+
/**
|
|
320
|
+
* Install tool packages into an isolated directory.
|
|
321
|
+
* Creates a minimal package.json and runs `bun install`.
|
|
322
|
+
*
|
|
323
|
+
* Tool packages are pre-bundled single files with zero deps —
|
|
324
|
+
* install is fast (~2-5s for a handful of tools).
|
|
325
|
+
*
|
|
326
|
+
* Security: only @deskfree/tool-* packages are allowed.
|
|
327
|
+
*/
|
|
328
|
+
declare function installTools(tools: ToolPackageConfig[], toolsDir: string, log?: PluginLogger): Promise<void>;
|
|
329
|
+
/**
|
|
330
|
+
* Load installed tool packages and extract DeskFreeTool definitions.
|
|
331
|
+
*
|
|
332
|
+
* Each @deskfree/tool-* package must export one of:
|
|
333
|
+
* export const tools: DeskFreeTool[]
|
|
334
|
+
* export function createTools(): DeskFreeTool[]
|
|
335
|
+
*/
|
|
336
|
+
declare function loadToolModules(tools: ToolPackageConfig[], toolsDir: string, log?: PluginLogger): Promise<DeskFreeTool[]>;
|
|
720
337
|
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
338
|
+
/**
|
|
339
|
+
* Local config: values known before connecting to the API.
|
|
340
|
+
* Only botToken + apiUrl are required. Everything else has sensible defaults.
|
|
341
|
+
*/
|
|
342
|
+
interface LocalConfig {
|
|
343
|
+
/** Bot authentication token (required) */
|
|
344
|
+
botToken: string;
|
|
345
|
+
/** DeskFree backend API URL (required) */
|
|
346
|
+
apiUrl: string;
|
|
347
|
+
/** Directory for cursor + media storage */
|
|
348
|
+
stateDir: string;
|
|
349
|
+
/** Directory for dynamic tool installs */
|
|
350
|
+
toolsDir: string;
|
|
351
|
+
/** Log level */
|
|
352
|
+
logLevel: 'debug' | 'info' | 'warn' | 'error';
|
|
353
|
+
/** HTTP port for health check endpoint */
|
|
354
|
+
healthPort: number;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Full runtime config: local config + API-bootstrapped values.
|
|
358
|
+
* Built by merging LocalConfig with the config.get response.
|
|
359
|
+
* Env var overrides take precedence over API values.
|
|
360
|
+
*/
|
|
361
|
+
interface RuntimeConfig extends LocalConfig {
|
|
362
|
+
/** DeskFree WebSocket URL */
|
|
363
|
+
wsUrl: string;
|
|
364
|
+
/** Model ID (Bedrock or Anthropic format) */
|
|
365
|
+
model: string;
|
|
366
|
+
/** AWS region for Bedrock */
|
|
367
|
+
awsRegion: string;
|
|
368
|
+
/** Heartbeat interval in ms (0 = disabled) */
|
|
369
|
+
heartbeatIntervalMs: number;
|
|
370
|
+
/** Tool packages to install */
|
|
371
|
+
tools: Array<{
|
|
372
|
+
package: string;
|
|
373
|
+
version: string;
|
|
374
|
+
}>;
|
|
375
|
+
/** Account ID (set after first API call) */
|
|
376
|
+
accountId: string;
|
|
377
|
+
/** LLM provider: bedrock (default), anthropic, ollama, or claude-code */
|
|
378
|
+
provider: 'bedrock' | 'anthropic' | 'ollama' | 'claude-code';
|
|
379
|
+
/** Anthropic API key (only set when provider is 'anthropic') */
|
|
380
|
+
anthropicApiKey?: string;
|
|
381
|
+
/** Base URL for Ollama-compatible API (only set when provider is 'ollama') */
|
|
382
|
+
baseUrl?: string;
|
|
383
|
+
/** Bot ID for this runtime instance */
|
|
384
|
+
botId: string;
|
|
385
|
+
/** File ID for the bot's Memory file (null if not created yet) */
|
|
386
|
+
memoryFileId: string | null;
|
|
387
|
+
/** Hour of day (0-23) in local time for the nightly sleep cycle (null = disabled) */
|
|
388
|
+
sleepHour: number | null;
|
|
389
|
+
/** Hour of day (0-23) in local time for the evening dusk planning cycle (null = disabled) */
|
|
390
|
+
duskHour: number | null;
|
|
391
|
+
/** IANA timezone string (e.g. 'America/New_York') for sleep scheduling */
|
|
392
|
+
timezone: string | null;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Load local config from environment variables.
|
|
396
|
+
*
|
|
397
|
+
* Checks DESKFREE_LAUNCH first — a base64-encoded JSON with { botToken, apiUrl }.
|
|
398
|
+
* Falls back to individual env vars DESKFREE_BOT_TOKEN and DESKFREE_API_URL.
|
|
399
|
+
*/
|
|
400
|
+
declare function loadConfig(): LocalConfig;
|
|
401
|
+
/**
|
|
402
|
+
* Merge local config with API-bootstrapped config.
|
|
403
|
+
* Env var overrides take precedence over API values for debugging/testing.
|
|
404
|
+
*/
|
|
405
|
+
declare function mergeWithRemoteConfig(local: LocalConfig, remote: RuntimeBootstrapConfig): RuntimeConfig;
|
|
406
|
+
|
|
407
|
+
type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
408
|
+
/**
|
|
409
|
+
* Structured JSON logger that satisfies the PluginLogger interface.
|
|
410
|
+
* Writes newline-delimited JSON to stdout/stderr.
|
|
411
|
+
*
|
|
412
|
+
* Supports optional structured fields that are merged into the JSON entry:
|
|
413
|
+
* log.info('message routed', { sessionKey: 'dm:abc', target: 'orchestrator' })
|
|
414
|
+
*/
|
|
415
|
+
declare function createLogger(component: string, minLevel?: LogLevel): PluginLogger;
|
|
416
|
+
/** Default logger for the root process. */
|
|
417
|
+
declare const logger: PluginLogger;
|
|
726
418
|
|
|
727
|
-
export { type
|
|
419
|
+
export { type ContentScanner, DefaultContentScanner, type DisposeAgent, type GatewayConfig, type HeartbeatOptions, type LocalConfig, type LogLevel, type OrchestratorQueryOptions, type RuntimeConfig, type ScanResult, type SessionEntry, SessionStore, type StartAgentOptions, type ToolPackageConfig, type WorkerQueryOptions, adaptTool, adaptTools, createLogger, createOrchestratorMcpServer, createWorkerMcpServer, installTools, isContentTypeAllowed, loadConfig, loadToolModules, logger, mergeWithRemoteConfig, runHeartbeat, runOrchestrator, runWorker, sanitizeFileName, startAgent, startGateway, validateDownloadUrl, withContentScan };
|