@agentvault/agentvault 0.13.12 → 0.14.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.
@@ -0,0 +1,33 @@
1
+ /**
2
+ * OpenClaw SDK compatibility layer — dynamic import wrappers with caching.
3
+ *
4
+ * Each wrapper attempts to import a deep SDK module at runtime. If the import
5
+ * fails (older gateway, missing SDK), the function returns a no-op result.
6
+ * Results are cached after the first attempt.
7
+ *
8
+ * IMPORTANT: All imports are guarded by try/catch — the plugin degrades
9
+ * gracefully on older OpenClaw versions.
10
+ */
11
+ import type { AgentEventPayload, TranscriptUpdatePayload } from "./openclaw-types.js";
12
+ /**
13
+ * Request an immediate heartbeat wake from the OpenClaw gateway.
14
+ * Returns true if the heartbeat API was available and called, false otherwise.
15
+ * Never throws.
16
+ */
17
+ export declare function requestHeartbeatNow(opts?: {
18
+ reason?: string;
19
+ }): Promise<boolean>;
20
+ type AgentEventCallback = (event: AgentEventPayload) => void;
21
+ /**
22
+ * Subscribe to agent-level events (tool_use, reasoning_complete, error, etc.).
23
+ * Returns an unsubscribe function, or a no-op if the API is unavailable.
24
+ */
25
+ export declare function onAgentEvent(callback: AgentEventCallback): Promise<() => void>;
26
+ type TranscriptCallback = (update: TranscriptUpdatePayload) => void;
27
+ /**
28
+ * Subscribe to session transcript updates for behavioral analysis.
29
+ * Returns an unsubscribe function, or a no-op if the API is unavailable.
30
+ */
31
+ export declare function onSessionTranscriptUpdate(callback: TranscriptCallback): Promise<() => void>;
32
+ export {};
33
+ //# sourceMappingURL=openclaw-compat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openclaw-compat.d.ts","sourceRoot":"","sources":["../src/openclaw-compat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAQtF;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAmBtF;AAMD,KAAK,kBAAkB,GAAG,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;AAG7D;;;GAGG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAkBpF;AAMD,KAAK,kBAAkB,GAAG,CAAC,MAAM,EAAE,uBAAuB,KAAK,IAAI,CAAC;AAGpE;;;GAGG;AACH,wBAAsB,yBAAyB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAkBjG"}
@@ -7,6 +7,9 @@
7
7
  *
8
8
  * Loaded by OpenClaw via the `openclaw.extensions` field in package.json.
9
9
  */
10
+ import type { OpenClawPluginApi } from "./openclaw-types.js";
11
+ /** Whether OpenClaw managed HTTP routes are active (vs self-managed server). */
12
+ export declare let isUsingManagedRoutes: boolean;
10
13
  /** Extract @mention names from plaintext. Returns lowercased names. */
11
14
  declare function _parseMentions(text: string): string[];
12
15
  /** Determine whether this agent should process a room message based on @mentions. */
@@ -18,7 +21,7 @@ declare const _default: {
18
21
  id: string;
19
22
  name: string;
20
23
  description: string;
21
- register(api: any): void;
24
+ register(api: OpenClawPluginApi): void;
22
25
  };
23
26
  export default _default;
24
27
  //# sourceMappingURL=openclaw-entry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"openclaw-entry.d.ts","sourceRoot":"","sources":["../src/openclaw-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAyBH,uEAAuE;AACvE,iBAAS,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAS9C;AAED,qFAAqF;AACrF,iBAAS,yBAAyB,CAChC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAcT;AAED,sFAAsF;AACtF,iBAAS,cAAc,CACrB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,CAiBR;AA2oBD,OAAO,EAAE,cAAc,EAAE,yBAAyB,EAAE,cAAc,EAAE,CAAC;;;;;kBAQrD,GAAG;;AAJnB,wBAgHE"}
1
+ {"version":3,"file":"openclaw-entry.d.ts","sourceRoot":"","sources":["../src/openclaw-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,OAAO,KAAK,EACV,iBAAiB,EASlB,MAAM,qBAAqB,CAAC;AAO7B,gFAAgF;AAChF,eAAO,IAAI,oBAAoB,SAAQ,CAAC;AAexC,uEAAuE;AACvE,iBAAS,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAS9C;AAED,qFAAqF;AACrF,iBAAS,yBAAyB,CAChC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAcT;AAED,sFAAsF;AACtF,iBAAS,cAAc,CACrB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,CAiBR;AAitBD,OAAO,EAAE,cAAc,EAAE,yBAAyB,EAAE,cAAc,EAAE,CAAC;;;;;kBAQrD,iBAAiB;;AAJjC,wBAyQE"}
@@ -1,3 +1,89 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __esm = (fn, res) => function __init() {
4
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
+ };
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+
11
+ // src/openclaw-compat.ts
12
+ var openclaw_compat_exports = {};
13
+ __export(openclaw_compat_exports, {
14
+ onAgentEvent: () => onAgentEvent,
15
+ onSessionTranscriptUpdate: () => onSessionTranscriptUpdate,
16
+ requestHeartbeatNow: () => requestHeartbeatNow
17
+ });
18
+ async function requestHeartbeatNow(opts) {
19
+ if (_heartbeatFn === null) {
20
+ try {
21
+ const mod = await import("openclaw/dist/plugin-sdk/infra/heartbeat-wake.js");
22
+ _heartbeatFn = mod.requestHeartbeatNow ?? mod.default?.requestHeartbeatNow ?? false;
23
+ } catch {
24
+ _heartbeatFn = false;
25
+ }
26
+ }
27
+ if (typeof _heartbeatFn === "function") {
28
+ try {
29
+ await _heartbeatFn(opts);
30
+ return true;
31
+ } catch {
32
+ return false;
33
+ }
34
+ }
35
+ return false;
36
+ }
37
+ async function onAgentEvent(callback) {
38
+ if (_agentEventFn === null) {
39
+ try {
40
+ const mod = await import("openclaw/dist/plugin-sdk/infra/agent-events.js");
41
+ _agentEventFn = mod.onAgentEvent ?? mod.default?.onAgentEvent ?? false;
42
+ } catch {
43
+ _agentEventFn = false;
44
+ }
45
+ }
46
+ if (typeof _agentEventFn === "function") {
47
+ try {
48
+ return _agentEventFn(callback);
49
+ } catch {
50
+ return () => {
51
+ };
52
+ }
53
+ }
54
+ return () => {
55
+ };
56
+ }
57
+ async function onSessionTranscriptUpdate(callback) {
58
+ if (_transcriptFn === null) {
59
+ try {
60
+ const mod = await import("openclaw/dist/plugin-sdk/sessions/transcript-events.js");
61
+ _transcriptFn = mod.onSessionTranscriptUpdate ?? mod.default?.onSessionTranscriptUpdate ?? false;
62
+ } catch {
63
+ _transcriptFn = false;
64
+ }
65
+ }
66
+ if (typeof _transcriptFn === "function") {
67
+ try {
68
+ return _transcriptFn(callback);
69
+ } catch {
70
+ return () => {
71
+ };
72
+ }
73
+ }
74
+ return () => {
75
+ };
76
+ }
77
+ var _heartbeatFn, _agentEventFn, _transcriptFn;
78
+ var init_openclaw_compat = __esm({
79
+ "src/openclaw-compat.ts"() {
80
+ "use strict";
81
+ _heartbeatFn = null;
82
+ _agentEventFn = null;
83
+ _transcriptFn = null;
84
+ }
85
+ });
86
+
1
87
  // src/openclaw-entry.ts
2
88
  import { resolve } from "node:path";
3
89
  import { randomBytes } from "node:crypto";
@@ -197,10 +283,75 @@ function runWithTraceContext(ctx, fn) {
197
283
  return traceStore.run(ctx, fn);
198
284
  }
199
285
 
286
+ // src/http-handlers.ts
287
+ async function handleSendRequest(parsed, channel) {
288
+ const text = parsed.text;
289
+ if (!text || typeof text !== "string") {
290
+ return { status: 400, body: { ok: false, error: "Missing 'text' field" } };
291
+ }
292
+ try {
293
+ if (parsed.room_id && typeof parsed.room_id === "string") {
294
+ await channel.sendToRoom(parsed.room_id, text, {
295
+ messageType: parsed.message_type,
296
+ priority: parsed.priority,
297
+ metadata: parsed.metadata
298
+ });
299
+ } else if (parsed.file_path && typeof parsed.file_path === "string") {
300
+ await channel.sendWithAttachment(text, parsed.file_path, {
301
+ topicId: parsed.topicId
302
+ });
303
+ } else {
304
+ await channel.send(text, {
305
+ topicId: parsed.topicId,
306
+ messageType: parsed.message_type,
307
+ metadata: parsed.metadata
308
+ });
309
+ }
310
+ return { status: 200, body: { ok: true } };
311
+ } catch (err) {
312
+ return { status: 500, body: { ok: false, error: String(err) } };
313
+ }
314
+ }
315
+ async function handleActionRequest(parsed, channel) {
316
+ if (!parsed.action || typeof parsed.action !== "string") {
317
+ return { status: 400, body: { ok: false, error: "Missing 'action' field" } };
318
+ }
319
+ try {
320
+ const confirmation = {
321
+ action: parsed.action,
322
+ status: parsed.status ?? "completed",
323
+ decisionId: parsed.decision_id,
324
+ detail: parsed.detail,
325
+ estimated_cost: parsed.estimated_cost
326
+ };
327
+ if (parsed.room_id && typeof parsed.room_id === "string") {
328
+ await channel.sendActionConfirmationToRoom(parsed.room_id, confirmation);
329
+ } else {
330
+ await channel.sendActionConfirmation(confirmation);
331
+ }
332
+ return { status: 200, body: { ok: true } };
333
+ } catch (err) {
334
+ return { status: 500, body: { ok: false, error: String(err) } };
335
+ }
336
+ }
337
+ function handleStatusRequest(channel) {
338
+ return {
339
+ status: 200,
340
+ body: {
341
+ ok: true,
342
+ state: channel.state,
343
+ deviceId: channel.deviceId ?? void 0,
344
+ sessions: channel.sessionCount
345
+ }
346
+ };
347
+ }
348
+
200
349
  // src/openclaw-entry.ts
350
+ init_openclaw_compat();
201
351
  var _ocRuntime = null;
202
352
  var _channels = /* @__PURE__ */ new Map();
203
353
  var _messageQueue = [];
354
+ var isUsingManagedRoutes = false;
204
355
  function _setRuntime(rt) {
205
356
  _ocRuntime = rt;
206
357
  if (_messageQueue.length > 0) {
@@ -265,10 +416,14 @@ async function handleInbound(params) {
265
416
  };
266
417
  const _instrument = {
267
418
  reportLlm: (opts) => {
419
+ const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };
420
+ if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;
268
421
  try {
269
- channel.telemetry?.reportLlmCall({ ...opts, traceId, parentSpanId: inferenceSpanId });
422
+ channel.telemetry?.reportLlmCall(enriched);
270
423
  } catch {
271
424
  }
425
+ const activityAttrs = { "ai.agent.llm.model": opts.model ?? "" };
426
+ if (enriched.skillName) activityAttrs["ai.agent.skill.name"] = enriched.skillName;
272
427
  _sendActivity({
273
428
  span_id: randomBytes(8).toString("hex"),
274
429
  span_type: "llm",
@@ -277,16 +432,20 @@ async function handleInbound(params) {
277
432
  start_time: new Date(Date.now() - (opts.latencyMs ?? 0)).toISOString(),
278
433
  end_time: (/* @__PURE__ */ new Date()).toISOString(),
279
434
  duration_ms: opts.latencyMs ?? 0,
280
- attributes: { "ai.agent.llm.model": opts.model ?? "" },
435
+ attributes: activityAttrs,
281
436
  tokens_input: opts.tokensInput,
282
437
  tokens_output: opts.tokensOutput
283
438
  });
284
439
  },
285
440
  reportTool: (opts) => {
441
+ const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };
442
+ if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;
286
443
  try {
287
- channel.telemetry?.reportToolCall({ ...opts, traceId, parentSpanId: inferenceSpanId });
444
+ channel.telemetry?.reportToolCall(enriched);
288
445
  } catch {
289
446
  }
447
+ const activityAttrs = { "ai.agent.tool.name": opts.toolName ?? "" };
448
+ if (enriched.skillName) activityAttrs["ai.agent.skill.name"] = enriched.skillName;
290
449
  _sendActivity({
291
450
  span_id: randomBytes(8).toString("hex"),
292
451
  span_type: "tool",
@@ -295,15 +454,19 @@ async function handleInbound(params) {
295
454
  start_time: new Date(Date.now() - (opts.latencyMs ?? 0)).toISOString(),
296
455
  end_time: (/* @__PURE__ */ new Date()).toISOString(),
297
456
  duration_ms: opts.latencyMs ?? 0,
298
- attributes: { "ai.agent.tool.name": opts.toolName ?? "" },
457
+ attributes: activityAttrs,
299
458
  tool_success: opts.success
300
459
  });
301
460
  },
302
461
  reportError: (opts) => {
462
+ const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };
463
+ if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;
303
464
  try {
304
- channel.telemetry?.reportError({ ...opts, traceId, parentSpanId: inferenceSpanId });
465
+ channel.telemetry?.reportError(enriched);
305
466
  } catch {
306
467
  }
468
+ const activityAttrs = { "ai.agent.error.type": opts.errorType ?? "" };
469
+ if (enriched.skillName) activityAttrs["ai.agent.skill.name"] = enriched.skillName;
307
470
  _sendActivity({
308
471
  span_id: randomBytes(8).toString("hex"),
309
472
  span_type: "error",
@@ -312,16 +475,20 @@ async function handleInbound(params) {
312
475
  start_time: (/* @__PURE__ */ new Date()).toISOString(),
313
476
  end_time: (/* @__PURE__ */ new Date()).toISOString(),
314
477
  duration_ms: 0,
315
- attributes: { "ai.agent.error.type": opts.errorType ?? "" },
478
+ attributes: activityAttrs,
316
479
  error_type: opts.errorType,
317
480
  error_message: opts.errorMessage
318
481
  });
319
482
  },
320
483
  reportHttp: (opts) => {
484
+ const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };
485
+ if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;
321
486
  try {
322
- channel.telemetry?.reportHttpCall({ ...opts, traceId, parentSpanId: inferenceSpanId });
487
+ channel.telemetry?.reportHttpCall(enriched);
323
488
  } catch {
324
489
  }
490
+ const activityAttrs = { "ai.agent.http.method": opts.method ?? "", "ai.agent.http.url": opts.url ?? "" };
491
+ if (enriched.skillName) activityAttrs["ai.agent.skill.name"] = enriched.skillName;
325
492
  _sendActivity({
326
493
  span_id: randomBytes(8).toString("hex"),
327
494
  span_type: "http",
@@ -336,17 +503,21 @@ async function handleInbound(params) {
336
503
  start_time: new Date(Date.now() - (opts.latencyMs ?? 0)).toISOString(),
337
504
  end_time: (/* @__PURE__ */ new Date()).toISOString(),
338
505
  duration_ms: opts.latencyMs ?? 0,
339
- attributes: { "ai.agent.http.method": opts.method ?? "", "ai.agent.http.url": opts.url ?? "" },
506
+ attributes: activityAttrs,
340
507
  http_method: opts.method,
341
508
  http_status_code: opts.statusCode,
342
509
  http_url: opts.url
343
510
  });
344
511
  },
345
512
  reportAction: (opts) => {
513
+ const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };
514
+ if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;
346
515
  try {
347
- channel.telemetry?.reportActionCall({ ...opts, traceId, parentSpanId: inferenceSpanId });
516
+ channel.telemetry?.reportActionCall(enriched);
348
517
  } catch {
349
518
  }
519
+ const activityAttrs = { "ai.agent.action.type": opts.actionType ?? "", "ai.agent.action.target": opts.target ?? "" };
520
+ if (enriched.skillName) activityAttrs["ai.agent.skill.name"] = enriched.skillName;
350
521
  _sendActivity({
351
522
  span_id: randomBytes(8).toString("hex"),
352
523
  span_type: "action",
@@ -355,16 +526,20 @@ async function handleInbound(params) {
355
526
  start_time: new Date(Date.now() - (opts.latencyMs ?? 0)).toISOString(),
356
527
  end_time: (/* @__PURE__ */ new Date()).toISOString(),
357
528
  duration_ms: opts.latencyMs ?? 0,
358
- attributes: { "ai.agent.action.type": opts.actionType ?? "", "ai.agent.action.target": opts.target ?? "" },
529
+ attributes: activityAttrs,
359
530
  action_type: opts.actionType,
360
531
  action_target: opts.target
361
532
  });
362
533
  },
363
534
  reportNav: (opts) => {
535
+ const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };
536
+ if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;
364
537
  try {
365
- channel.telemetry?.reportNavCall({ ...opts, traceId, parentSpanId: inferenceSpanId });
538
+ channel.telemetry?.reportNavCall(enriched);
366
539
  } catch {
367
540
  }
541
+ const activityAttrs = { "ai.agent.nav.to_url": opts.toUrl ?? "" };
542
+ if (enriched.skillName) activityAttrs["ai.agent.skill.name"] = enriched.skillName;
368
543
  _sendActivity({
369
544
  span_id: randomBytes(8).toString("hex"),
370
545
  span_type: "nav",
@@ -373,9 +548,10 @@ async function handleInbound(params) {
373
548
  start_time: new Date(Date.now() - (opts.latencyMs ?? 0)).toISOString(),
374
549
  end_time: (/* @__PURE__ */ new Date()).toISOString(),
375
550
  duration_ms: opts.latencyMs ?? 0,
376
- attributes: { "ai.agent.nav.to_url": opts.toUrl ?? "" }
551
+ attributes: activityAttrs
377
552
  });
378
553
  },
554
+ skillName: void 0,
379
555
  traceId,
380
556
  parentSpanId: inferenceSpanId
381
557
  };
@@ -727,14 +903,14 @@ var agentVaultPlugin = {
727
903
  },
728
904
  startAccount: async (ctx) => {
729
905
  const { account, cfg, log, abortSignal } = ctx;
906
+ const _log = typeof log === "function" ? log : log?.info?.bind(log);
730
907
  if (!account.configured) {
731
908
  throw new Error(
732
909
  "AgentVault channel not configured. Run: npx @agentvault/agentvault setup --token=av_tok_...\nThen restart OpenClaw."
733
910
  );
734
911
  }
735
912
  const dataDir = resolve(account.dataDir.replace(/^~/, process.env.HOME ?? "~"));
736
- log?.info(`[AgentVault] starting (dataDir=${dataDir})`);
737
- const { SecureChannel } = await import("./index.js");
913
+ _log?.(`[AgentVault] starting (dataDir=${dataDir})`);
738
914
  await new Promise((resolve2, reject) => {
739
915
  let channel;
740
916
  const onAbort = async () => {
@@ -743,15 +919,15 @@ var agentVaultPlugin = {
743
919
  resolve2();
744
920
  };
745
921
  abortSignal?.addEventListener("abort", () => void onAbort());
746
- import("./index.js").then(({ SecureChannel: SecureChannel2 }) => {
747
- channel = new SecureChannel2({
922
+ import("./index.js").then(({ SecureChannel }) => {
923
+ channel = new SecureChannel({
748
924
  inviteToken: "",
749
925
  dataDir,
750
926
  apiUrl: account.apiUrl,
751
927
  agentName: account.agentName,
752
928
  onMessage: async (plaintext, metadata) => {
753
929
  if (!_ocRuntime) {
754
- log?.info("[AgentVault] runtime not ready, queuing message");
930
+ _log?.("[AgentVault] runtime not ready, queuing message");
755
931
  _messageQueue.push(async () => {
756
932
  await handleInbound({ plaintext, metadata, channel, account, cfg });
757
933
  });
@@ -760,22 +936,26 @@ var agentVaultPlugin = {
760
936
  try {
761
937
  await handleInbound({ plaintext, metadata, channel, account, cfg });
762
938
  } catch (err) {
763
- log?.info(`[AgentVault] inbound error: ${String(err)}`);
939
+ _log?.(`[AgentVault] inbound error: ${String(err)}`);
764
940
  }
765
941
  },
766
942
  onStateChange: (state) => {
767
- log?.info(`[AgentVault] \u2192 ${state}`);
943
+ _log?.(`[AgentVault] \u2192 ${state}`);
768
944
  if (state === "error") reject(new Error("AgentVault channel permanent error"));
769
945
  }
770
946
  });
771
947
  _channels.set(account.accountId, channel);
772
948
  channel.on("error", (err) => {
773
- log?.info(`[AgentVault] channel error (non-fatal): ${String(err)}`);
949
+ _log?.(`[AgentVault] channel error (non-fatal): ${String(err)}`);
774
950
  });
775
951
  const httpPort = account.httpPort ?? 18790;
776
952
  channel.on("ready", () => {
777
- channel.startHttpServer(httpPort);
778
- log?.info(`[AgentVault] HTTP send server listening on http://127.0.0.1:${httpPort}`);
953
+ if (!isUsingManagedRoutes) {
954
+ channel.startHttpServer(httpPort);
955
+ _log?.(`[AgentVault] HTTP send server listening on http://127.0.0.1:${httpPort}`);
956
+ } else {
957
+ _log?.(`[AgentVault] using OpenClaw managed HTTP routes (skipping self-managed server)`);
958
+ }
779
959
  });
780
960
  channel.start().catch(reject);
781
961
  }).catch(reject);
@@ -825,6 +1005,36 @@ ${mediaUrl}` : mediaUrl;
825
1005
  } catch (err) {
826
1006
  return { ok: false, error: String(err) };
827
1007
  }
1008
+ },
1009
+ /** Rich payload delivery — OpenClaw v2026.3.2+ calls this for structured messages. */
1010
+ sendPayload: async (ctx) => {
1011
+ const { payload, accountId } = ctx;
1012
+ const resolvedId = accountId ?? "default";
1013
+ const ch = _channels.get(resolvedId);
1014
+ if (!ch) return { ok: false, error: "AgentVault channel not connected" };
1015
+ try {
1016
+ if (payload.isReasoning) return { ok: true };
1017
+ requestHeartbeatNow({ reason: "outbound-payload" }).catch(() => {
1018
+ });
1019
+ const text = (payload.text ?? "").trim();
1020
+ if (!text && !payload.mediaUrls?.length) return { ok: true };
1021
+ if (text) {
1022
+ await ch.send(text);
1023
+ }
1024
+ if (payload.mediaUrls?.length) {
1025
+ for (const url of payload.mediaUrls) {
1026
+ await ch.send(url);
1027
+ }
1028
+ }
1029
+ if (payload.suggestedActions?.length) {
1030
+ const actionsText = payload.suggestedActions.map((a) => `- ${a.label}: ${a.action}`).join("\n");
1031
+ await ch.send(`Suggested actions:
1032
+ ${actionsText}`);
1033
+ }
1034
+ return { ok: true };
1035
+ } catch (err) {
1036
+ return { ok: false, error: String(err) };
1037
+ }
828
1038
  }
829
1039
  }
830
1040
  };
@@ -882,6 +1092,157 @@ var openclaw_entry_default = {
882
1092
  }
883
1093
  });
884
1094
  api.registerChannel({ plugin: agentVaultPlugin });
1095
+ if (typeof api.registerHttpRoute === "function") {
1096
+ try {
1097
+ api.registerHttpRoute({
1098
+ path: "/agentvault/send",
1099
+ method: "POST",
1100
+ handler: async (req) => {
1101
+ const ch = _channels.values().next().value;
1102
+ if (!ch) return { status: 503, body: { ok: false, error: "Channel not started" } };
1103
+ const parsed = typeof req.body === "string" ? JSON.parse(req.body) : req.body;
1104
+ const result = await handleSendRequest(parsed, ch);
1105
+ return { status: result.status, body: result.body };
1106
+ }
1107
+ });
1108
+ api.registerHttpRoute({
1109
+ path: "/agentvault/action",
1110
+ method: "POST",
1111
+ handler: async (req) => {
1112
+ const ch = _channels.values().next().value;
1113
+ if (!ch) return { status: 503, body: { ok: false, error: "Channel not started" } };
1114
+ const parsed = typeof req.body === "string" ? JSON.parse(req.body) : req.body;
1115
+ const result = await handleActionRequest(parsed, ch);
1116
+ return { status: result.status, body: result.body };
1117
+ }
1118
+ });
1119
+ api.registerHttpRoute({
1120
+ path: "/agentvault/status",
1121
+ method: "GET",
1122
+ handler: async () => {
1123
+ const ch = _channels.values().next().value;
1124
+ if (!ch) return { status: 503, body: { ok: false, error: "Channel not started" } };
1125
+ const result = handleStatusRequest(ch);
1126
+ return { status: result.status, body: result.body };
1127
+ }
1128
+ });
1129
+ isUsingManagedRoutes = true;
1130
+ } catch {
1131
+ }
1132
+ }
1133
+ if (typeof api.on === "function") {
1134
+ api.on("message_sent", async (event) => {
1135
+ try {
1136
+ const ch = _channels.values().next().value;
1137
+ if (!ch?.telemetry) return;
1138
+ ch.telemetry.reportCustomSpan({
1139
+ traceId: randomBytes(16).toString("hex"),
1140
+ spanId: randomBytes(8).toString("hex"),
1141
+ name: "agentvault.message.delivered",
1142
+ kind: "internal",
1143
+ startTime: event.timestamp,
1144
+ endTime: event.timestamp + 1,
1145
+ attributes: {
1146
+ "agentvault.message.id": event.messageId,
1147
+ "agentvault.delivery.status": event.deliveryStatus,
1148
+ "agentvault.channel.id": event.channelId
1149
+ },
1150
+ status: { code: event.deliveryStatus === "failed" ? 2 : 1 }
1151
+ });
1152
+ } catch {
1153
+ }
1154
+ });
1155
+ api.on("session_start", async (event) => {
1156
+ try {
1157
+ const ch = _channels.values().next().value;
1158
+ if (!ch?.telemetry) return;
1159
+ ch.telemetry.reportCustomSpan({
1160
+ traceId: randomBytes(16).toString("hex"),
1161
+ spanId: randomBytes(8).toString("hex"),
1162
+ name: "agentvault.session.start",
1163
+ kind: "internal",
1164
+ startTime: event.timestamp,
1165
+ endTime: event.timestamp + 1,
1166
+ attributes: {
1167
+ "agentvault.session.key": event.sessionKey,
1168
+ "agentvault.agent.id": event.agentId
1169
+ },
1170
+ status: { code: 1 }
1171
+ });
1172
+ } catch {
1173
+ }
1174
+ });
1175
+ api.on("session_end", async (event) => {
1176
+ try {
1177
+ const ch = _channels.values().next().value;
1178
+ if (!ch?.telemetry) return;
1179
+ ch.telemetry.reportCustomSpan({
1180
+ traceId: randomBytes(16).toString("hex"),
1181
+ spanId: randomBytes(8).toString("hex"),
1182
+ name: "agentvault.session.end",
1183
+ kind: "internal",
1184
+ startTime: event.timestamp,
1185
+ endTime: event.timestamp + 1,
1186
+ attributes: {
1187
+ "agentvault.session.key": event.sessionKey,
1188
+ "agentvault.agent.id": event.agentId,
1189
+ ...event.reason ? { "agentvault.session.end_reason": event.reason } : {}
1190
+ },
1191
+ status: { code: 1 }
1192
+ });
1193
+ } catch {
1194
+ }
1195
+ });
1196
+ }
1197
+ Promise.resolve().then(() => (init_openclaw_compat(), openclaw_compat_exports)).then(async ({ onAgentEvent: onAgentEvent2, onSessionTranscriptUpdate: onSessionTranscriptUpdate2 }) => {
1198
+ onAgentEvent2((event) => {
1199
+ try {
1200
+ const ch = _channels.values().next().value;
1201
+ if (!ch?.telemetry) return;
1202
+ ch.telemetry.reportCustomSpan({
1203
+ traceId: randomBytes(16).toString("hex"),
1204
+ spanId: randomBytes(8).toString("hex"),
1205
+ name: `ai.agent.event.${event.type}`,
1206
+ kind: "internal",
1207
+ startTime: event.timestamp,
1208
+ endTime: event.timestamp + 1,
1209
+ attributes: {
1210
+ "ai.agent.event.type": event.type,
1211
+ "ai.agent.id": event.agentId,
1212
+ ...event.data ? Object.fromEntries(
1213
+ Object.entries(event.data).map(([k, v]) => [`ai.agent.event.${k}`, String(v)])
1214
+ ) : {}
1215
+ },
1216
+ status: { code: 1 }
1217
+ });
1218
+ } catch {
1219
+ }
1220
+ }).catch(() => {
1221
+ });
1222
+ onSessionTranscriptUpdate2((update) => {
1223
+ try {
1224
+ const ch = _channels.values().next().value;
1225
+ if (!ch?.telemetry) return;
1226
+ ch.telemetry.reportCustomSpan({
1227
+ traceId: randomBytes(16).toString("hex"),
1228
+ spanId: randomBytes(8).toString("hex"),
1229
+ name: "ai.agent.transcript.update",
1230
+ kind: "internal",
1231
+ startTime: update.timestamp,
1232
+ endTime: update.timestamp + 1,
1233
+ attributes: {
1234
+ "agentvault.session.key": update.sessionKey,
1235
+ "ai.agent.transcript.role": update.role ?? "unknown",
1236
+ "ai.agent.transcript.delta_chars": update.delta.length
1237
+ },
1238
+ status: { code: 1 }
1239
+ });
1240
+ } catch {
1241
+ }
1242
+ }).catch(() => {
1243
+ });
1244
+ }).catch(() => {
1245
+ });
885
1246
  try {
886
1247
  api.registerTool?.({
887
1248
  name: "agentvault_status",
@@ -941,6 +1302,7 @@ export {
941
1302
  _parseMentions,
942
1303
  _shouldProcessRoomMessage,
943
1304
  _stripMentions,
944
- openclaw_entry_default as default
1305
+ openclaw_entry_default as default,
1306
+ isUsingManagedRoutes
945
1307
  };
946
1308
  //# sourceMappingURL=openclaw-entry.js.map