@xfxstudio/claworld 2026.4.30-testing.1 → 2026.4.30-testing.2

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.
@@ -18,6 +18,7 @@ import {
18
18
  buildClaworldToolMaintenanceEvent,
19
19
  ensureClaworldWorkingMemory,
20
20
  resolveClaworldBootstrapTarget,
21
+ updateClaworldSessionDirectory,
21
22
  } from '../runtime/working-memory.js';
22
23
  import { resolveOpenClawWorkspaceRoot } from '../runtime/workspace-resolver.js';
23
24
  import { setClaworldRuntime } from './runtime.js';
@@ -1968,16 +1969,7 @@ function buildRegisteredTools(api, plugin) {
1968
1969
  expiresInSeconds: params.expiresInSeconds ?? null,
1969
1970
  });
1970
1971
  const pairedAgentId = identityPayload?.agentId || runtimeConfig.relay?.agentId || null;
1971
- const pairedRuntimeConfig = pairedAgentId
1972
- ? {
1973
- ...runtimeConfig,
1974
- relay: {
1975
- ...(runtimeConfig.relay && typeof runtimeConfig.relay === 'object' ? runtimeConfig.relay : {}),
1976
- agentId: pairedAgentId,
1977
- },
1978
- }
1979
- : runtimeConfig;
1980
- const relayAgentFallback = pairedAgentId
1972
+ const relayAgent = pairedAgentId
1981
1973
  ? {
1982
1974
  agentId: pairedAgentId,
1983
1975
  displayName: normalizeText(
@@ -1998,39 +1990,23 @@ function buildRegisteredTools(api, plugin) {
1998
1990
  || runtimeConfig.relay?.appToken
1999
1991
  || runtimeConfig.relay?.credentialToken,
2000
1992
  );
2001
- const activationReady = hasConfiguredAppToken;
2002
- const bindingReady = activationReady && Boolean(pairedAgentId);
2003
- const bindingStatus = activationReady
2004
- ? (bindingReady ? 'bound' : 'identity_unresolved')
2005
- : 'unactivated';
2006
- let relayAgent = relayAgentFallback;
2007
- if (hasConfiguredAppToken && pairedAgentId && typeof plugin.helpers?.pairing?.resolveAgentIdentity === 'function') {
2008
- const resolvedRelayAgent = await plugin.helpers.pairing.resolveAgentIdentity({
2009
- cfg,
2010
- accountId,
2011
- runtimeConfig: pairedRuntimeConfig,
2012
- agentId: pairedAgentId,
2013
- });
2014
- if (resolvedRelayAgent && typeof resolvedRelayAgent === 'object') {
2015
- relayAgent = {
2016
- ...relayAgentFallback,
2017
- ...resolvedRelayAgent,
2018
- agentId: normalizeText(resolvedRelayAgent.agentId, pairedAgentId),
2019
- displayName: normalizeText(resolvedRelayAgent.displayName, relayAgentFallback?.displayName ?? null),
2020
- };
2021
- }
2022
- }
2023
1993
  const pairingPayload = {
2024
- status: activationReady ? 'paired' : 'unpaired',
2025
- bindingReady,
2026
- bindingStatus,
2027
- reason: activationReady
1994
+ status: hasConfiguredAppToken ? 'paired' : 'unpaired',
1995
+ reason: hasConfiguredAppToken
2028
1996
  ? (pairedAgentId ? null : 'missing_agent_id')
2029
1997
  : 'missing_app_token',
2030
- bindingSource: activationReady
1998
+ bindingSource: hasConfiguredAppToken
2031
1999
  ? 'configured_app_token'
2032
2000
  : (runtimeConfig.registration?.enabled === true ? 'registration_pending' : 'unbound'),
2033
- runtimeConfig: pairedRuntimeConfig,
2001
+ runtimeConfig: pairedAgentId
2002
+ ? {
2003
+ ...runtimeConfig,
2004
+ relay: {
2005
+ ...(runtimeConfig.relay && typeof runtimeConfig.relay === 'object' ? runtimeConfig.relay : {}),
2006
+ agentId: pairedAgentId,
2007
+ },
2008
+ }
2009
+ : runtimeConfig,
2034
2010
  relayAgent,
2035
2011
  };
2036
2012
  return buildToolResult(projectToolAccountViewResponse({
@@ -2095,13 +2071,45 @@ export function registerClaworldPluginFull(api, plugin) {
2095
2071
  });
2096
2072
 
2097
2073
  api.on('before_tool_call', async (event, ctx) => {
2098
- if (event?.toolName !== 'claworld_manage_conversations') return;
2074
+ const toolName = normalizeText(event?.toolName, null);
2075
+ if (!toolName || !toolName.startsWith('claworld_')) return;
2099
2076
  const params = event?.params && typeof event.params === 'object' && !Array.isArray(event.params)
2100
2077
  ? event.params
2101
2078
  : {};
2102
- if (normalizeTerminalConversationAction(params.action, null) !== 'request') return;
2103
2079
  const requesterSessionKey = normalizeText(ctx?.sessionKey, null);
2104
- if (!requesterSessionKey) return;
2080
+ if (requesterSessionKey) {
2081
+ const logger = getHookLogger(api);
2082
+ try {
2083
+ const workspaceRoot = await resolveHookWorkspaceRoot(api, event, ctx);
2084
+ if (workspaceRoot) {
2085
+ await updateClaworldSessionDirectory(
2086
+ workspaceRoot,
2087
+ {
2088
+ timestamp: event?.timestamp || ctx?.timestamp || null,
2089
+ source: 'claworld_hook',
2090
+ eventType: 'before_tool_call',
2091
+ kind: toolName,
2092
+ toolName,
2093
+ relations: {
2094
+ localSessionKey: requesterSessionKey,
2095
+ sessionKey: requesterSessionKey,
2096
+ localAgentId: normalizeText(ctx?.agentId ?? ctx?.AgentId, null),
2097
+ },
2098
+ context: ctx || {},
2099
+ },
2100
+ );
2101
+ }
2102
+ } catch (error) {
2103
+ logger?.warn?.('[claworld:working-memory] unable to update session directory before tool call', error);
2104
+ }
2105
+ }
2106
+ if (
2107
+ toolName !== 'claworld_manage_conversations'
2108
+ || normalizeTerminalConversationAction(params.action, null) !== 'request'
2109
+ || !requesterSessionKey
2110
+ ) {
2111
+ return;
2112
+ }
2105
2113
  return {
2106
2114
  params: {
2107
2115
  ...params,
@@ -2123,6 +2131,7 @@ export function registerClaworldPluginFull(api, plugin) {
2123
2131
  params: event?.params || {},
2124
2132
  result: hookToolResult(event),
2125
2133
  timestamp: event?.timestamp || ctx?.timestamp || null,
2134
+ context: ctx || {},
2126
2135
  });
2127
2136
  if (!maintenanceEvent) return;
2128
2137
  await appendClaworldJournalEvent(workspaceRoot, maintenanceEvent);
@@ -23,10 +23,52 @@ export function normalizeRelayWebSocketUrl(serverUrl) {
23
23
 
24
24
  export function buildInboundEnvelope(message = {}) {
25
25
  const data = message.data || {};
26
- if (message.event !== 'delivery') return null;
27
26
  const metadata = data.metadata && typeof data.metadata === 'object' && !Array.isArray(data.metadata)
28
27
  ? { ...data.metadata }
29
28
  : {};
29
+ if (message.event !== 'delivery') {
30
+ const eventType = normalizeOptionalText(data.eventType) || normalizeOptionalText(message.event);
31
+ const notification = data.notification && typeof data.notification === 'object' && !Array.isArray(data.notification)
32
+ ? data.notification
33
+ : {};
34
+ const targetAgentId = normalizeOptionalText(
35
+ data.targetAgentId
36
+ || notification.targetAgentId
37
+ || metadata.targetAgentId,
38
+ );
39
+ const sessionKey = normalizeOptionalText(
40
+ data.sessionKey
41
+ || notification.targetSessionKey
42
+ || metadata.sessionKey,
43
+ ) || (targetAgentId ? `management:${targetAgentId}` : null);
44
+ if (!eventType || !sessionKey) return null;
45
+ return {
46
+ eventType,
47
+ eventName: normalizeOptionalText(data.eventName) || normalizeOptionalText(message.event),
48
+ eventId: normalizeOptionalText(data.eventId)
49
+ || normalizeOptionalText(data.inboxItemId)
50
+ || normalizeOptionalText(notification.notificationId)
51
+ || null,
52
+ sessionKey,
53
+ targetAgentId,
54
+ conversationKey: normalizeOptionalText(data.conversationKey)
55
+ || normalizeOptionalText(notification.relatedObjects?.conversationKey)
56
+ || null,
57
+ worldId: normalizeOptionalText(data.worldId)
58
+ || normalizeOptionalText(notification.relatedObjects?.worldId)
59
+ || null,
60
+ createdAt: data.createdAt || notification.createdAt || null,
61
+ updatedAt: data.updatedAt || notification.updatedAt || null,
62
+ payload: data && typeof data === 'object' && !Array.isArray(data)
63
+ ? { ...data }
64
+ : {},
65
+ metadata: {
66
+ ...metadata,
67
+ relayEvent: normalizeOptionalText(message.event),
68
+ inboxItemId: normalizeOptionalText(data.inboxItemId) || null,
69
+ },
70
+ };
71
+ }
30
72
  return {
31
73
  eventType: data.eventType || 'delivery',
32
74
  deliveryId: data.deliveryId || null,
@@ -1,6 +1,15 @@
1
1
  export const CLAWORLD_PLUGIN_BRIDGE_PROTOCOL = 'claworld.delivery_reply.v1';
2
2
 
3
3
  const DELIVERY_EVENT_TYPE = 'delivery';
4
+ const MANAGEMENT_EVENT_TYPES = new Set([
5
+ 'notification',
6
+ 'domain_notification',
7
+ 'management_wake',
8
+ 'management_tick',
9
+ 'conversation_lifecycle',
10
+ 'platform_recommendation',
11
+ 'ops_recommendation',
12
+ ]);
4
13
 
5
14
  function normalizeText(value, fallback = null) {
6
15
  if (value == null) return fallback;
@@ -16,27 +25,28 @@ function normalizePayload(payload = null) {
16
25
  export function createRelayEventProtocol() {
17
26
  return {
18
27
  version: CLAWORLD_PLUGIN_BRIDGE_PROTOCOL,
19
- eventTypes: [DELIVERY_EVENT_TYPE],
20
- requiredEnvelopeFields: ['eventType', 'deliveryId', 'sessionKey', 'payload'],
28
+ eventTypes: [DELIVERY_EVENT_TYPE, ...MANAGEMENT_EVENT_TYPES],
29
+ requiredEnvelopeFields: ['eventType', 'sessionKey', 'payload'],
21
30
  describeEvent(event = {}) {
22
31
  const payload = normalizePayload(event.payload);
23
32
  const missing = [];
24
- if (normalizeText(event.eventType, null) !== DELIVERY_EVENT_TYPE) {
33
+ const eventType = normalizeText(event.eventType, null);
34
+ if (eventType !== DELIVERY_EVENT_TYPE && !MANAGEMENT_EVENT_TYPES.has(eventType)) {
25
35
  missing.push('eventType');
26
36
  }
27
- if (!normalizeText(event.deliveryId, null)) {
37
+ if (eventType === DELIVERY_EVENT_TYPE && !normalizeText(event.deliveryId, null)) {
28
38
  missing.push('deliveryId');
29
39
  }
30
40
  if (!normalizeText(event.sessionKey, null)) {
31
41
  missing.push('sessionKey');
32
42
  }
33
- if (!normalizeText(payload.text, null)) {
43
+ if (eventType === DELIVERY_EVENT_TYPE && !normalizeText(payload.text, null)) {
34
44
  missing.push('payload.text');
35
45
  }
36
46
  return {
37
47
  ok: missing.length === 0,
38
48
  missing,
39
- role: 'delivery',
49
+ role: eventType === DELIVERY_EVENT_TYPE ? 'delivery' : 'management',
40
50
  };
41
51
  },
42
52
  };