@byte5ai/palaia 2.3.6 → 2.5.1
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/README.md +1 -1
- package/index.ts +42 -17
- package/package.json +2 -2
- package/skill/SKILL.md +358 -8
- package/src/config.ts +17 -0
- package/src/context-engine.ts +440 -297
- package/src/hooks/capture.ts +22 -5
- package/src/hooks/index.ts +101 -33
- package/src/hooks/recall.ts +65 -2
- package/src/hooks/session.ts +464 -0
- package/src/hooks/state.ts +102 -0
- package/src/priorities.ts +12 -0
- package/src/tools.ts +31 -7
- package/src/types.ts +409 -22
package/src/types.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* They are maintained locally to avoid a build-time dependency on the
|
|
6
6
|
* openclaw package (which is a peerDependency loaded at runtime).
|
|
7
7
|
*
|
|
8
|
-
* Based on OpenClaw v2026.3.
|
|
8
|
+
* Based on OpenClaw v2026.3.28 plugin-sdk.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type { TObject } from "@sinclair/typebox";
|
|
@@ -28,23 +28,230 @@ export interface ToolOptions {
|
|
|
28
28
|
optional?: boolean;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export type ToolFactory = ToolDefinition;
|
|
31
|
+
export type ToolFactory = ToolDefinition | ((ctx: Record<string, unknown>) => ToolDefinition | ToolDefinition[] | null);
|
|
32
32
|
|
|
33
|
-
// ── Hook Types
|
|
33
|
+
// ── Hook Types ─────────────��────────────────────────────────────────────
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* All hook names supported by OpenClaw v2026.3.28.
|
|
37
|
+
* palaia registers handlers for a subset of these.
|
|
38
|
+
*/
|
|
35
39
|
export type HookName =
|
|
40
|
+
// Session lifecycle
|
|
41
|
+
| "session_start"
|
|
42
|
+
| "session_end"
|
|
43
|
+
// Agent & LLM
|
|
44
|
+
| "before_model_resolve"
|
|
36
45
|
| "before_prompt_build"
|
|
46
|
+
| "before_agent_start"
|
|
47
|
+
| "llm_input"
|
|
48
|
+
| "llm_output"
|
|
37
49
|
| "agent_end"
|
|
50
|
+
// Context management
|
|
51
|
+
| "before_compaction"
|
|
52
|
+
| "after_compaction"
|
|
53
|
+
| "before_reset"
|
|
54
|
+
// Messages
|
|
55
|
+
| "inbound_claim"
|
|
56
|
+
| "before_dispatch"
|
|
38
57
|
| "message_received"
|
|
39
|
-
| "message_sending"
|
|
58
|
+
| "message_sending"
|
|
59
|
+
| "message_sent"
|
|
60
|
+
// Tool execution
|
|
61
|
+
| "before_tool_call"
|
|
62
|
+
| "after_tool_call"
|
|
63
|
+
| "tool_result_persist"
|
|
64
|
+
| "before_message_write"
|
|
65
|
+
// Subagents
|
|
66
|
+
| "subagent_spawning"
|
|
67
|
+
| "subagent_delivery_target"
|
|
68
|
+
| "subagent_spawned"
|
|
69
|
+
| "subagent_ended"
|
|
70
|
+
// Gateway
|
|
71
|
+
| "gateway_start"
|
|
72
|
+
| "gateway_stop";
|
|
40
73
|
|
|
41
|
-
export type HookHandler = (event: unknown, ctx: unknown) =>
|
|
74
|
+
export type HookHandler = (event: unknown, ctx: unknown) => unknown | Promise<unknown>;
|
|
42
75
|
|
|
43
76
|
export interface HookOptions {
|
|
44
77
|
priority?: number;
|
|
45
78
|
}
|
|
46
79
|
|
|
47
|
-
// ──
|
|
80
|
+
// ── Hook Event Types ────────────────────────────────────────────────────
|
|
81
|
+
|
|
82
|
+
/** session_start event. */
|
|
83
|
+
export type SessionStartEvent = {
|
|
84
|
+
sessionId: string;
|
|
85
|
+
sessionKey?: string;
|
|
86
|
+
resumedFrom?: string;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/** session_end event. */
|
|
90
|
+
export type SessionEndEvent = {
|
|
91
|
+
sessionId: string;
|
|
92
|
+
sessionKey?: string;
|
|
93
|
+
messageCount: number;
|
|
94
|
+
durationMs?: number;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/** before_prompt_build event. */
|
|
98
|
+
export type BeforePromptBuildEvent = {
|
|
99
|
+
prompt: string;
|
|
100
|
+
messages: unknown[];
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
/** before_prompt_build result. */
|
|
104
|
+
export type BeforePromptBuildResult = {
|
|
105
|
+
systemPrompt?: string;
|
|
106
|
+
prependContext?: string;
|
|
107
|
+
prependSystemContext?: string;
|
|
108
|
+
appendSystemContext?: string;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/** before_reset event. */
|
|
112
|
+
export type BeforeResetEvent = {
|
|
113
|
+
sessionFile?: string;
|
|
114
|
+
messages?: unknown[];
|
|
115
|
+
reason?: string;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/** agent_end event. */
|
|
119
|
+
export type AgentEndEvent = {
|
|
120
|
+
messages: unknown[];
|
|
121
|
+
success: boolean;
|
|
122
|
+
error?: string;
|
|
123
|
+
durationMs?: number;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/** llm_input event — fired before each LLM call. */
|
|
127
|
+
export type LlmInputEvent = {
|
|
128
|
+
runId: string;
|
|
129
|
+
sessionId: string;
|
|
130
|
+
provider: string;
|
|
131
|
+
model: string;
|
|
132
|
+
systemPrompt?: string;
|
|
133
|
+
prompt: string;
|
|
134
|
+
historyMessages: unknown[];
|
|
135
|
+
imagesCount: number;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/** llm_output event — fired after each LLM response. */
|
|
139
|
+
export type LlmOutputEvent = {
|
|
140
|
+
runId: string;
|
|
141
|
+
sessionId: string;
|
|
142
|
+
provider: string;
|
|
143
|
+
model: string;
|
|
144
|
+
assistantTexts: string[];
|
|
145
|
+
lastAssistant?: unknown;
|
|
146
|
+
usage?: {
|
|
147
|
+
input?: number;
|
|
148
|
+
output?: number;
|
|
149
|
+
cacheRead?: number;
|
|
150
|
+
cacheWrite?: number;
|
|
151
|
+
total?: number;
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
/** after_tool_call event. */
|
|
156
|
+
export type AfterToolCallEvent = {
|
|
157
|
+
toolName: string;
|
|
158
|
+
params: Record<string, unknown>;
|
|
159
|
+
runId?: string;
|
|
160
|
+
toolCallId?: string;
|
|
161
|
+
result?: unknown;
|
|
162
|
+
error?: string;
|
|
163
|
+
durationMs?: number;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
/** message_received event. */
|
|
167
|
+
export type MessageReceivedEvent = {
|
|
168
|
+
from: string;
|
|
169
|
+
content: string;
|
|
170
|
+
timestamp?: number;
|
|
171
|
+
metadata?: Record<string, unknown>;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/** message_sending event. */
|
|
175
|
+
export type MessageSendingEvent = {
|
|
176
|
+
to: string;
|
|
177
|
+
content: string;
|
|
178
|
+
metadata?: Record<string, unknown>;
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
/** message_sending result. */
|
|
182
|
+
export type MessageSendingResult = {
|
|
183
|
+
content?: string;
|
|
184
|
+
cancel?: boolean;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
/** subagent_spawning event. */
|
|
188
|
+
export type SubagentSpawningEvent = {
|
|
189
|
+
childSessionKey: string;
|
|
190
|
+
agentId: string;
|
|
191
|
+
label?: string;
|
|
192
|
+
mode: "run" | "session";
|
|
193
|
+
requester?: {
|
|
194
|
+
channel?: string;
|
|
195
|
+
accountId?: string;
|
|
196
|
+
to?: string;
|
|
197
|
+
threadId?: string | number;
|
|
198
|
+
};
|
|
199
|
+
threadRequested: boolean;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
/** subagent_ended event. */
|
|
203
|
+
export type SubagentEndedEvent = {
|
|
204
|
+
targetSessionKey: string;
|
|
205
|
+
targetKind: "subagent" | "acp";
|
|
206
|
+
reason: string;
|
|
207
|
+
sendFarewell?: boolean;
|
|
208
|
+
accountId?: string;
|
|
209
|
+
runId?: string;
|
|
210
|
+
endedAt?: number;
|
|
211
|
+
outcome?: "ok" | "error" | "timeout" | "killed" | "reset" | "deleted";
|
|
212
|
+
error?: string;
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
// ── Hook Context Types ──────────────��───────────────────────────────────
|
|
216
|
+
|
|
217
|
+
export type AgentContext = {
|
|
218
|
+
agentId?: string;
|
|
219
|
+
sessionKey?: string;
|
|
220
|
+
sessionId?: string;
|
|
221
|
+
workspaceDir?: string;
|
|
222
|
+
messageProvider?: string;
|
|
223
|
+
trigger?: string;
|
|
224
|
+
channelId?: string;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
export type MessageContext = {
|
|
228
|
+
channelId: string;
|
|
229
|
+
accountId?: string;
|
|
230
|
+
conversationId?: string;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
export type SessionContext = {
|
|
234
|
+
agentId?: string;
|
|
235
|
+
sessionId: string;
|
|
236
|
+
sessionKey?: string;
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
export type ToolContext = {
|
|
240
|
+
agentId?: string;
|
|
241
|
+
sessionKey?: string;
|
|
242
|
+
sessionId?: string;
|
|
243
|
+
runId?: string;
|
|
244
|
+
toolName: string;
|
|
245
|
+
toolCallId?: string;
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
export type SubagentContext = {
|
|
249
|
+
runId?: string;
|
|
250
|
+
childSessionKey?: string;
|
|
251
|
+
requesterSessionKey?: string;
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// ── Command Types ───���───────────────────────────────────────────────────
|
|
48
255
|
|
|
49
256
|
export interface CommandDefinition {
|
|
50
257
|
name: string;
|
|
@@ -52,17 +259,156 @@ export interface CommandDefinition {
|
|
|
52
259
|
handler(args: string): Promise<{ text: string }> | { text: string };
|
|
53
260
|
}
|
|
54
261
|
|
|
55
|
-
// ── Service Types
|
|
262
|
+
// ── Service Types ─────────────────────────────────────���─────────────────
|
|
263
|
+
|
|
264
|
+
export interface ServiceContext {
|
|
265
|
+
config: Record<string, unknown>;
|
|
266
|
+
workspaceDir?: string;
|
|
267
|
+
stateDir: string;
|
|
268
|
+
logger: PluginLogger;
|
|
269
|
+
}
|
|
56
270
|
|
|
57
271
|
export interface ServiceDefinition {
|
|
58
272
|
id: string;
|
|
59
|
-
start(): Promise<void>;
|
|
60
|
-
stop?(): Promise<void>;
|
|
273
|
+
start(ctx: ServiceContext): Promise<void>;
|
|
274
|
+
stop?(ctx: ServiceContext): Promise<void>;
|
|
61
275
|
}
|
|
62
276
|
|
|
63
|
-
//
|
|
277
|
+
// ���─ Context Engine Types ────────────���───────────────────────────────────
|
|
278
|
+
|
|
279
|
+
/** Opaque message type from OpenClaw's agent runtime. */
|
|
280
|
+
export type AgentMessage = unknown;
|
|
281
|
+
|
|
282
|
+
export interface ContextEngineInfo {
|
|
283
|
+
id: string;
|
|
284
|
+
name: string;
|
|
285
|
+
version?: string;
|
|
286
|
+
ownsCompaction?: boolean;
|
|
287
|
+
}
|
|
64
288
|
|
|
289
|
+
export type BootstrapResult = {
|
|
290
|
+
bootstrapped: boolean;
|
|
291
|
+
importedMessages?: number;
|
|
292
|
+
reason?: string;
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
export type IngestResult = {
|
|
296
|
+
ingested: boolean;
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
export type AssembleResult = {
|
|
300
|
+
messages: AgentMessage[];
|
|
301
|
+
estimatedTokens: number;
|
|
302
|
+
systemPromptAddition?: string;
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
export type CompactResult = {
|
|
306
|
+
ok: boolean;
|
|
307
|
+
compacted: boolean;
|
|
308
|
+
reason?: string;
|
|
309
|
+
result?: {
|
|
310
|
+
summary?: string;
|
|
311
|
+
firstKeptEntryId?: string;
|
|
312
|
+
tokensBefore: number;
|
|
313
|
+
tokensAfter?: number;
|
|
314
|
+
details?: unknown;
|
|
315
|
+
};
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
export type SubagentSpawnPreparation = {
|
|
319
|
+
rollback: () => void | Promise<void>;
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
export type SubagentEndReason = "deleted" | "completed" | "swept" | "released";
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* ContextEngine interface — matches OpenClaw v2026.3.28.
|
|
326
|
+
*
|
|
327
|
+
* This is the full interface. Palaia implements a subset;
|
|
328
|
+
* optional methods are marked with `?`.
|
|
329
|
+
*/
|
|
65
330
|
export interface ContextEngine {
|
|
331
|
+
readonly info: ContextEngineInfo;
|
|
332
|
+
|
|
333
|
+
bootstrap?(params: {
|
|
334
|
+
sessionId: string;
|
|
335
|
+
sessionKey?: string;
|
|
336
|
+
sessionFile: string;
|
|
337
|
+
}): Promise<BootstrapResult>;
|
|
338
|
+
|
|
339
|
+
maintain?(params: {
|
|
340
|
+
sessionId: string;
|
|
341
|
+
sessionKey?: string;
|
|
342
|
+
sessionFile: string;
|
|
343
|
+
runtimeContext?: Record<string, unknown>;
|
|
344
|
+
}): Promise<unknown>;
|
|
345
|
+
|
|
346
|
+
ingest(params: {
|
|
347
|
+
sessionId: string;
|
|
348
|
+
sessionKey?: string;
|
|
349
|
+
message: AgentMessage;
|
|
350
|
+
isHeartbeat?: boolean;
|
|
351
|
+
}): Promise<IngestResult>;
|
|
352
|
+
|
|
353
|
+
ingestBatch?(params: {
|
|
354
|
+
sessionId: string;
|
|
355
|
+
sessionKey?: string;
|
|
356
|
+
messages: AgentMessage[];
|
|
357
|
+
isHeartbeat?: boolean;
|
|
358
|
+
}): Promise<{ ingestedCount: number }>;
|
|
359
|
+
|
|
360
|
+
afterTurn?(params: {
|
|
361
|
+
sessionId: string;
|
|
362
|
+
sessionKey?: string;
|
|
363
|
+
sessionFile: string;
|
|
364
|
+
messages: AgentMessage[];
|
|
365
|
+
prePromptMessageCount: number;
|
|
366
|
+
autoCompactionSummary?: string;
|
|
367
|
+
isHeartbeat?: boolean;
|
|
368
|
+
tokenBudget?: number;
|
|
369
|
+
runtimeContext?: Record<string, unknown>;
|
|
370
|
+
}): Promise<void>;
|
|
371
|
+
|
|
372
|
+
assemble(params: {
|
|
373
|
+
sessionId: string;
|
|
374
|
+
sessionKey?: string;
|
|
375
|
+
messages: AgentMessage[];
|
|
376
|
+
tokenBudget?: number;
|
|
377
|
+
model?: string;
|
|
378
|
+
prompt?: string;
|
|
379
|
+
}): Promise<AssembleResult>;
|
|
380
|
+
|
|
381
|
+
compact(params: {
|
|
382
|
+
sessionId: string;
|
|
383
|
+
sessionKey?: string;
|
|
384
|
+
sessionFile: string;
|
|
385
|
+
tokenBudget?: number;
|
|
386
|
+
force?: boolean;
|
|
387
|
+
currentTokenCount?: number;
|
|
388
|
+
compactionTarget?: "budget" | "threshold";
|
|
389
|
+
customInstructions?: string;
|
|
390
|
+
runtimeContext?: Record<string, unknown>;
|
|
391
|
+
}): Promise<CompactResult>;
|
|
392
|
+
|
|
393
|
+
prepareSubagentSpawn?(params: {
|
|
394
|
+
parentSessionKey: string;
|
|
395
|
+
childSessionKey: string;
|
|
396
|
+
ttlMs?: number;
|
|
397
|
+
}): Promise<SubagentSpawnPreparation | undefined>;
|
|
398
|
+
|
|
399
|
+
onSubagentEnded?(params: {
|
|
400
|
+
childSessionKey: string;
|
|
401
|
+
reason: SubagentEndReason;
|
|
402
|
+
}): Promise<void>;
|
|
403
|
+
|
|
404
|
+
dispose?(): Promise<void>;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Legacy ContextEngine interface for backward compatibility.
|
|
409
|
+
* Used when OpenClaw < 2026.3.24 registers via the old signature.
|
|
410
|
+
*/
|
|
411
|
+
export interface LegacyContextEngine {
|
|
66
412
|
bootstrap?(): Promise<void>;
|
|
67
413
|
ingest?(messages: unknown[]): Promise<void>;
|
|
68
414
|
assemble(budget: { maxTokens: number }): Promise<{ content: string; tokenEstimate: number }>;
|
|
@@ -72,45 +418,86 @@ export interface ContextEngine {
|
|
|
72
418
|
onSubagentEnded?(result: unknown): Promise<void>;
|
|
73
419
|
}
|
|
74
420
|
|
|
75
|
-
|
|
421
|
+
export type ContextEngineFactory = () => ContextEngine | Promise<ContextEngine>;
|
|
422
|
+
|
|
423
|
+
// ── Memory Prompt Section ───────────────────────────────────────────────
|
|
424
|
+
|
|
425
|
+
export type MemoryPromptSectionBuilder = (params: {
|
|
426
|
+
availableTools: Set<string>;
|
|
427
|
+
citationsMode?: string;
|
|
428
|
+
}) => string[];
|
|
429
|
+
|
|
430
|
+
// ── Logger ──────────────���───────────────────────────────────────────────
|
|
76
431
|
|
|
77
432
|
export interface PluginLogger {
|
|
78
|
-
info(
|
|
79
|
-
warn(
|
|
80
|
-
error
|
|
81
|
-
debug?(
|
|
433
|
+
info(message: string): void;
|
|
434
|
+
warn(message: string): void;
|
|
435
|
+
error(message: string): void;
|
|
436
|
+
debug?(message: string): void;
|
|
82
437
|
}
|
|
83
438
|
|
|
84
|
-
//
|
|
439
|
+
// ���─ Runtime ───────────────��─────────────────────────────���───────────────
|
|
85
440
|
|
|
86
441
|
export interface PluginRuntime {
|
|
442
|
+
version?: string;
|
|
87
443
|
agent?: {
|
|
88
444
|
runEmbeddedPiAgent?(params: Record<string, unknown>): Promise<unknown>;
|
|
445
|
+
session?: {
|
|
446
|
+
resolveStorePath?(...args: unknown[]): string;
|
|
447
|
+
loadSessionStore?(...args: unknown[]): Promise<unknown>;
|
|
448
|
+
};
|
|
449
|
+
};
|
|
450
|
+
subagent?: {
|
|
451
|
+
run?(params: {
|
|
452
|
+
sessionKey: string;
|
|
453
|
+
message: string;
|
|
454
|
+
provider?: string;
|
|
455
|
+
model?: string;
|
|
456
|
+
extraSystemPrompt?: string;
|
|
457
|
+
}): Promise<{ runId: string }>;
|
|
458
|
+
getSessionMessages?(params: {
|
|
459
|
+
sessionKey: string;
|
|
460
|
+
limit?: number;
|
|
461
|
+
}): Promise<{ messages: unknown[] }>;
|
|
89
462
|
};
|
|
90
463
|
modelAuth?: {
|
|
91
464
|
resolveApiKeyForProvider(params: {
|
|
92
465
|
provider: string;
|
|
93
|
-
cfg
|
|
466
|
+
cfg?: Record<string, unknown>;
|
|
94
467
|
}): Promise<string | null>;
|
|
95
468
|
};
|
|
469
|
+
system?: {
|
|
470
|
+
requestHeartbeatNow?(): void;
|
|
471
|
+
};
|
|
472
|
+
events?: {
|
|
473
|
+
onSessionTranscriptUpdate?(handler: (event: unknown) => void): void;
|
|
474
|
+
};
|
|
96
475
|
}
|
|
97
476
|
|
|
98
477
|
// ── Main Plugin API ─────────────────────────────────────────────────────
|
|
99
478
|
|
|
100
479
|
export interface OpenClawPluginApi {
|
|
101
|
-
|
|
480
|
+
id: string;
|
|
481
|
+
name: string;
|
|
482
|
+
version?: string;
|
|
483
|
+
source?: string;
|
|
484
|
+
registrationMode?: string;
|
|
485
|
+
|
|
486
|
+
registerTool(definition: ToolDefinition | ToolFactory, options?: ToolOptions): void;
|
|
102
487
|
registerCommand(command: CommandDefinition): void;
|
|
103
488
|
registerService(service: ServiceDefinition): void;
|
|
104
|
-
registerContextEngine?(id: string,
|
|
105
|
-
|
|
106
|
-
|
|
489
|
+
registerContextEngine?(id: string, factory: ContextEngineFactory): void;
|
|
490
|
+
registerMemoryPromptSection?(builder: MemoryPromptSectionBuilder): void;
|
|
491
|
+
registerHook?(events: string | string[], handler: HookHandler, opts?: HookOptions): void;
|
|
492
|
+
on(hook: HookName | string, handler: HookHandler, opts?: HookOptions): void;
|
|
107
493
|
logger: PluginLogger;
|
|
108
494
|
runtime: PluginRuntime;
|
|
109
495
|
config: Record<string, unknown>;
|
|
496
|
+
pluginConfig?: Record<string, unknown>;
|
|
110
497
|
workspace?: { dir: string; agentId?: string } | string;
|
|
111
498
|
}
|
|
112
499
|
|
|
113
|
-
// ── Plugin Entry
|
|
500
|
+
// ── Plugin Entry ────────���───────────────────────────────────────────────
|
|
114
501
|
|
|
115
502
|
export interface OpenClawPluginEntry {
|
|
116
503
|
id: string;
|