@xfxstudio/claworld 2026.5.6-testing.1 → 2026.5.11-testing.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/openclaw.plugin.json +1 -10
- package/package.json +1 -1
- package/src/openclaw/plugin/claworld-channel-plugin.js +373 -49
- package/src/openclaw/plugin/register-tooling.js +8 -106
- package/src/openclaw/plugin/register.js +35 -3
- package/src/openclaw/plugin/relay-client-shared.js +38 -6
- package/src/openclaw/protocol/relay-event-protocol.js +4 -3
- package/src/openclaw/runtime/inbound-session-router.js +0 -1
- package/src/openclaw/runtime/session-routing.js +19 -11
- package/src/openclaw/runtime/working-memory.js +1037 -56
package/openclaw.plugin.json
CHANGED
|
@@ -6,18 +6,9 @@
|
|
|
6
6
|
"skills": [
|
|
7
7
|
"./skills"
|
|
8
8
|
],
|
|
9
|
-
"contracts": {
|
|
10
|
-
"tools": [
|
|
11
|
-
"claworld_manage_account",
|
|
12
|
-
"claworld_search",
|
|
13
|
-
"claworld_get_public_profile",
|
|
14
|
-
"claworld_manage_worlds",
|
|
15
|
-
"claworld_manage_conversations"
|
|
16
|
-
]
|
|
17
|
-
},
|
|
18
9
|
"name": "Claworld Persona Relay",
|
|
19
10
|
"description": "Claworld relay world channel plugin for OpenClaw.",
|
|
20
|
-
"version": "2026.5.
|
|
11
|
+
"version": "2026.5.11-testing.1",
|
|
21
12
|
"configSchema": {
|
|
22
13
|
"type": "object",
|
|
23
14
|
"additionalProperties": false,
|
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import path from 'node:path';
|
|
2
3
|
|
|
3
4
|
import {
|
|
4
5
|
applyRuntimeIdentity,
|
|
@@ -32,6 +33,10 @@ import { createInboundSessionRouter } from '../runtime/inbound-session-router.js
|
|
|
32
33
|
import { createOutboundSessionBridge } from '../runtime/outbound-session-bridge.js';
|
|
33
34
|
import { createCanonicalResultBuilder } from '../runtime/canonical-result-builder.js';
|
|
34
35
|
import { createDemoSessionBootstrap } from '../runtime/demo-session-bootstrap.js';
|
|
36
|
+
import {
|
|
37
|
+
appendClaworldJournalEvent,
|
|
38
|
+
buildClaworldRuntimeMaintenanceEvent,
|
|
39
|
+
} from '../runtime/working-memory.js';
|
|
35
40
|
import {
|
|
36
41
|
broadcastModeratedWorld,
|
|
37
42
|
createModeratedWorld,
|
|
@@ -62,6 +67,7 @@ import {
|
|
|
62
67
|
resolveWorldSelectionFlow,
|
|
63
68
|
} from '../runtime/product-shell-helper.js';
|
|
64
69
|
import { extractBackendErrorContext } from '../runtime/backend-error-context.js';
|
|
70
|
+
import { resolveOpenClawWorkspaceRoot } from '../runtime/workspace-resolver.js';
|
|
65
71
|
import { getClaworldRuntime } from './runtime.js';
|
|
66
72
|
import {
|
|
67
73
|
CLAWORLD_PLUGIN_CURRENT_VERSION,
|
|
@@ -582,17 +588,19 @@ async function deliverRelayMessage({ runtimeConfig, to, text, fetchImpl, logger,
|
|
|
582
588
|
|
|
583
589
|
if (!result.ok) {
|
|
584
590
|
logger.error?.('[claworld:outbound] message delivery failed', { status: result.status, body: result.body });
|
|
585
|
-
|
|
586
|
-
result,
|
|
587
|
-
runtimeConfig,
|
|
591
|
+
throw createRuntimeBoundaryError({
|
|
588
592
|
code: 'relay_message_delivery_failed',
|
|
589
|
-
|
|
593
|
+
category: 'transport',
|
|
594
|
+
status: result.status >= 500 ? 502 : result.status,
|
|
590
595
|
message: `claworld outbound failed: ${result.status}`,
|
|
596
|
+
publicMessage: 'claworld outbound message delivery failed',
|
|
597
|
+
recoverable: true,
|
|
591
598
|
context: {
|
|
599
|
+
accountId: runtimeConfig.accountId || null,
|
|
592
600
|
fromAgentId,
|
|
593
601
|
targetAgentId,
|
|
602
|
+
status: result.status,
|
|
594
603
|
},
|
|
595
|
-
passThroughBackendConflict: true,
|
|
596
604
|
});
|
|
597
605
|
}
|
|
598
606
|
|
|
@@ -628,23 +636,13 @@ function createRelayRouteError({
|
|
|
628
636
|
publicMessage,
|
|
629
637
|
message,
|
|
630
638
|
context = {},
|
|
631
|
-
passThroughBackendConflict = false,
|
|
632
639
|
}) {
|
|
633
|
-
const backendCode = resolveNormalizedText(result?.body?.error, null);
|
|
634
|
-
const backendMessage = resolveNormalizedText(result?.body?.message, null);
|
|
635
|
-
const shouldPassThroughConflict = passThroughBackendConflict === true
|
|
636
|
-
&& Number(result?.status) === 409
|
|
637
|
-
&& backendCode;
|
|
638
640
|
throw createRuntimeBoundaryError({
|
|
639
|
-
code
|
|
640
|
-
category:
|
|
641
|
+
code,
|
|
642
|
+
category: 'transport',
|
|
641
643
|
status: result?.status >= 500 ? 502 : result?.status || 502,
|
|
642
|
-
message:
|
|
643
|
-
|
|
644
|
-
: (message || publicMessage),
|
|
645
|
-
publicMessage: shouldPassThroughConflict
|
|
646
|
-
? (backendMessage || publicMessage)
|
|
647
|
-
: publicMessage,
|
|
644
|
+
message: message || publicMessage,
|
|
645
|
+
publicMessage,
|
|
648
646
|
recoverable: true,
|
|
649
647
|
context: {
|
|
650
648
|
accountId: runtimeConfig.accountId || null,
|
|
@@ -735,7 +733,6 @@ async function createChatRequest({
|
|
|
735
733
|
displayName: normalizedDisplayName,
|
|
736
734
|
agentCode: normalizedAgentCode,
|
|
737
735
|
},
|
|
738
|
-
passThroughBackendConflict: true,
|
|
739
736
|
});
|
|
740
737
|
}
|
|
741
738
|
return result.body || {};
|
|
@@ -818,7 +815,6 @@ async function acceptChatRequest({
|
|
|
818
815
|
code: 'chat_request_accept_failed',
|
|
819
816
|
publicMessage: 'failed to accept chat request',
|
|
820
817
|
context: { actorAgentId, chatRequestId },
|
|
821
|
-
passThroughBackendConflict: true,
|
|
822
818
|
});
|
|
823
819
|
}
|
|
824
820
|
return normalizeChatInboxPayloadSessionKeys(result.body || {}, { localAgentId });
|
|
@@ -847,7 +843,6 @@ async function rejectChatRequest({
|
|
|
847
843
|
code: 'chat_request_reject_failed',
|
|
848
844
|
publicMessage: 'failed to reject chat request',
|
|
849
845
|
context: { actorAgentId, chatRequestId },
|
|
850
|
-
passThroughBackendConflict: true,
|
|
851
846
|
});
|
|
852
847
|
}
|
|
853
848
|
return result.body || {};
|
|
@@ -1852,6 +1847,297 @@ function buildDeliveryInboundEnvelope({
|
|
|
1852
1847
|
};
|
|
1853
1848
|
}
|
|
1854
1849
|
|
|
1850
|
+
function normalizeSessionStoreKey(value) {
|
|
1851
|
+
return resolveNormalizedText(value, '').toLowerCase();
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
function resolveSessionStoreEntry(store = null, sessionKey = null) {
|
|
1855
|
+
if (!store || typeof store !== 'object' || Array.isArray(store)) return null;
|
|
1856
|
+
const normalizedSessionKey = resolveNormalizedText(sessionKey, null);
|
|
1857
|
+
if (!normalizedSessionKey) return null;
|
|
1858
|
+
if (store[normalizedSessionKey] && typeof store[normalizedSessionKey] === 'object') {
|
|
1859
|
+
return store[normalizedSessionKey];
|
|
1860
|
+
}
|
|
1861
|
+
const lowerSessionKey = normalizeSessionStoreKey(normalizedSessionKey);
|
|
1862
|
+
if (store[lowerSessionKey] && typeof store[lowerSessionKey] === 'object') {
|
|
1863
|
+
return store[lowerSessionKey];
|
|
1864
|
+
}
|
|
1865
|
+
const match = Object.entries(store).find(([key, value]) => (
|
|
1866
|
+
normalizeSessionStoreKey(key) === lowerSessionKey
|
|
1867
|
+
&& value
|
|
1868
|
+
&& typeof value === 'object'
|
|
1869
|
+
&& !Array.isArray(value)
|
|
1870
|
+
));
|
|
1871
|
+
return match ? match[1] : null;
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
function readRuntimeSessionStoreEntry({ runtime = null, sessionStorePath = null, sessionKey = null } = {}) {
|
|
1875
|
+
if (!runtime?.agent?.session?.loadSessionStore || !sessionStorePath || !sessionKey) return null;
|
|
1876
|
+
try {
|
|
1877
|
+
return resolveSessionStoreEntry(
|
|
1878
|
+
runtime.agent.session.loadSessionStore(sessionStorePath),
|
|
1879
|
+
sessionKey,
|
|
1880
|
+
);
|
|
1881
|
+
} catch {
|
|
1882
|
+
return null;
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1886
|
+
function resolveSessionFilePathFromRuntime({
|
|
1887
|
+
runtime = null,
|
|
1888
|
+
sessionId = null,
|
|
1889
|
+
record = {},
|
|
1890
|
+
sessionStorePath = null,
|
|
1891
|
+
localAgentId = null,
|
|
1892
|
+
} = {}) {
|
|
1893
|
+
const normalizedSessionId = resolveNormalizedText(sessionId, null);
|
|
1894
|
+
if (!normalizedSessionId) return null;
|
|
1895
|
+
|
|
1896
|
+
const sessionsDir = sessionStorePath
|
|
1897
|
+
? path.dirname(path.resolve(sessionStorePath))
|
|
1898
|
+
: null;
|
|
1899
|
+
if (typeof runtime?.agent?.session?.resolveSessionFilePath === 'function') {
|
|
1900
|
+
try {
|
|
1901
|
+
const resolved = runtime.agent.session.resolveSessionFilePath(
|
|
1902
|
+
normalizedSessionId,
|
|
1903
|
+
record,
|
|
1904
|
+
{
|
|
1905
|
+
...(sessionsDir ? { sessionsDir } : {}),
|
|
1906
|
+
...(localAgentId ? { agentId: localAgentId } : {}),
|
|
1907
|
+
},
|
|
1908
|
+
);
|
|
1909
|
+
const normalized = resolveNormalizedText(resolved, null);
|
|
1910
|
+
if (normalized) return normalized;
|
|
1911
|
+
} catch {
|
|
1912
|
+
// Fall through to the local derivation below.
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1916
|
+
const candidate = resolveNormalizedText(record?.sessionFile, null);
|
|
1917
|
+
if (candidate) {
|
|
1918
|
+
if (path.isAbsolute(candidate) || !sessionsDir) return candidate;
|
|
1919
|
+
return path.resolve(sessionsDir, candidate);
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1922
|
+
if (sessionsDir) {
|
|
1923
|
+
return path.join(sessionsDir, `${normalizedSessionId}.jsonl`);
|
|
1924
|
+
}
|
|
1925
|
+
return null;
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1928
|
+
function resolveSessionRecordArtifacts(record = null, fallbackStorePath = null, options = {}) {
|
|
1929
|
+
const normalizedRecord = record && typeof record === 'object' && !Array.isArray(record) ? record : {};
|
|
1930
|
+
const nestedSession = normalizedRecord.session && typeof normalizedRecord.session === 'object' && !Array.isArray(normalizedRecord.session)
|
|
1931
|
+
? normalizedRecord.session
|
|
1932
|
+
: {};
|
|
1933
|
+
const sessionId = resolveNormalizedText(
|
|
1934
|
+
normalizedRecord.sessionId,
|
|
1935
|
+
resolveNormalizedText(nestedSession.sessionId, resolveNormalizedText(normalizedRecord.id, null)),
|
|
1936
|
+
);
|
|
1937
|
+
const sessionStorePath = resolveNormalizedText(
|
|
1938
|
+
normalizedRecord.storePath,
|
|
1939
|
+
resolveNormalizedText(normalizedRecord.sessionStorePath, fallbackStorePath),
|
|
1940
|
+
);
|
|
1941
|
+
const directSessionFile = resolveNormalizedText(
|
|
1942
|
+
normalizedRecord.sessionFile,
|
|
1943
|
+
resolveNormalizedText(
|
|
1944
|
+
normalizedRecord.sessionPath,
|
|
1945
|
+
resolveNormalizedText(
|
|
1946
|
+
normalizedRecord.filePath,
|
|
1947
|
+
resolveNormalizedText(normalizedRecord.path, resolveNormalizedText(nestedSession.filePath, null)),
|
|
1948
|
+
),
|
|
1949
|
+
),
|
|
1950
|
+
);
|
|
1951
|
+
const sessionFile = directSessionFile || resolveSessionFilePathFromRuntime({
|
|
1952
|
+
runtime: options.runtime,
|
|
1953
|
+
sessionId,
|
|
1954
|
+
record: normalizedRecord,
|
|
1955
|
+
sessionStorePath,
|
|
1956
|
+
localAgentId: options.localAgentId,
|
|
1957
|
+
});
|
|
1958
|
+
const transcriptPath = resolveNormalizedText(
|
|
1959
|
+
normalizedRecord.transcriptPath,
|
|
1960
|
+
resolveNormalizedText(nestedSession.transcriptPath, sessionFile),
|
|
1961
|
+
);
|
|
1962
|
+
return {
|
|
1963
|
+
sessionId,
|
|
1964
|
+
sessionFile,
|
|
1965
|
+
sessionStorePath,
|
|
1966
|
+
transcriptPath,
|
|
1967
|
+
};
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1970
|
+
async function recordRuntimeInboundSessionArtifacts({
|
|
1971
|
+
runtime = null,
|
|
1972
|
+
currentCfg = {},
|
|
1973
|
+
localAgentId = null,
|
|
1974
|
+
sessionKey = null,
|
|
1975
|
+
ctx = {},
|
|
1976
|
+
logger = console,
|
|
1977
|
+
runtimeAccountId = null,
|
|
1978
|
+
logLabel = 'inbound',
|
|
1979
|
+
logContext = {},
|
|
1980
|
+
} = {}) {
|
|
1981
|
+
let sessionStorePath = null;
|
|
1982
|
+
let sessionRecord = null;
|
|
1983
|
+
const sessionApi = runtime?.channel?.session || {};
|
|
1984
|
+
const localSessionKey = resolveNormalizedText(ctx?.SessionKey, sessionKey);
|
|
1985
|
+
|
|
1986
|
+
if (sessionApi.resolveStorePath && localAgentId) {
|
|
1987
|
+
sessionStorePath = sessionApi.resolveStorePath(currentCfg.session?.store, {
|
|
1988
|
+
agentId: localAgentId,
|
|
1989
|
+
});
|
|
1990
|
+
const onRecordError = (error) => {
|
|
1991
|
+
logger.error?.(`[claworld:${runtimeAccountId}] failed to record ${logLabel} inbound session`, {
|
|
1992
|
+
...logContext,
|
|
1993
|
+
sessionKey,
|
|
1994
|
+
localSessionKey,
|
|
1995
|
+
localAgentId,
|
|
1996
|
+
error: error?.message || String(error),
|
|
1997
|
+
});
|
|
1998
|
+
};
|
|
1999
|
+
try {
|
|
2000
|
+
if (typeof sessionApi.recordSessionMetaFromInbound === 'function') {
|
|
2001
|
+
sessionRecord = await sessionApi.recordSessionMetaFromInbound({
|
|
2002
|
+
storePath: sessionStorePath,
|
|
2003
|
+
sessionKey: localSessionKey,
|
|
2004
|
+
ctx,
|
|
2005
|
+
});
|
|
2006
|
+
} else if (typeof sessionApi.recordInboundSession === 'function') {
|
|
2007
|
+
sessionRecord = await sessionApi.recordInboundSession({
|
|
2008
|
+
storePath: sessionStorePath,
|
|
2009
|
+
sessionKey: localSessionKey,
|
|
2010
|
+
ctx,
|
|
2011
|
+
onRecordError,
|
|
2012
|
+
});
|
|
2013
|
+
}
|
|
2014
|
+
} catch (error) {
|
|
2015
|
+
onRecordError(error);
|
|
2016
|
+
}
|
|
2017
|
+
if (!sessionRecord) {
|
|
2018
|
+
sessionRecord = readRuntimeSessionStoreEntry({
|
|
2019
|
+
runtime,
|
|
2020
|
+
sessionStorePath,
|
|
2021
|
+
sessionKey: localSessionKey,
|
|
2022
|
+
});
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
return {
|
|
2027
|
+
sessionStorePath,
|
|
2028
|
+
sessionRecord,
|
|
2029
|
+
sessionArtifacts: resolveSessionRecordArtifacts(sessionRecord, sessionStorePath, {
|
|
2030
|
+
runtime,
|
|
2031
|
+
localAgentId,
|
|
2032
|
+
}),
|
|
2033
|
+
};
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
function buildInboundRuntimeMaintenanceEvent({
|
|
2037
|
+
delivery = {},
|
|
2038
|
+
metadata = {},
|
|
2039
|
+
payload = {},
|
|
2040
|
+
messageId = null,
|
|
2041
|
+
eventType = 'delivery',
|
|
2042
|
+
sessionKind = null,
|
|
2043
|
+
localSessionKey = null,
|
|
2044
|
+
localAgentId = null,
|
|
2045
|
+
sessionArtifacts = {},
|
|
2046
|
+
workspaceRoot = null,
|
|
2047
|
+
} = {}) {
|
|
2048
|
+
const normalizedEventType = resolveNormalizedText(eventType, 'delivery');
|
|
2049
|
+
const isRelayDelivery = normalizedEventType === 'delivery';
|
|
2050
|
+
const sessionKey = resolveNormalizedText(delivery.sessionKey, null);
|
|
2051
|
+
const requestId = resolveNormalizedText(
|
|
2052
|
+
metadata.kickoffRequestId,
|
|
2053
|
+
resolveNormalizedText(metadata.requestId, resolveNormalizedText(metadata.chatRequestId, null)),
|
|
2054
|
+
);
|
|
2055
|
+
const worldId = resolveNormalizedText(
|
|
2056
|
+
metadata.worldId,
|
|
2057
|
+
resolveNormalizedText(delivery.worldId, resolveNormalizedText(payload.worldId, null)),
|
|
2058
|
+
);
|
|
2059
|
+
const conversationKey = resolveNormalizedText(
|
|
2060
|
+
metadata.conversationKey,
|
|
2061
|
+
resolveNormalizedText(delivery.conversationKey, resolveNormalizedText(payload.conversationKey, null)),
|
|
2062
|
+
);
|
|
2063
|
+
const fromAgentId = resolveNormalizedText(metadata.fromAgentId, null);
|
|
2064
|
+
const targetAgentId = resolveNormalizedText(
|
|
2065
|
+
delivery.targetAgentId,
|
|
2066
|
+
resolveNormalizedText(payload.targetAgentId, resolveNormalizedText(metadata.targetAgentId, null)),
|
|
2067
|
+
);
|
|
2068
|
+
const notificationId = resolveNormalizedText(
|
|
2069
|
+
metadata.notificationId,
|
|
2070
|
+
resolveNormalizedText(payload.notificationId, null),
|
|
2071
|
+
);
|
|
2072
|
+
const inboxItemId = resolveNormalizedText(
|
|
2073
|
+
metadata.inboxItemId,
|
|
2074
|
+
resolveNormalizedText(payload.inboxItemId, null),
|
|
2075
|
+
);
|
|
2076
|
+
const scope = sessionKind === 'management' ? 'management' : 'conversation';
|
|
2077
|
+
const summary = [
|
|
2078
|
+
isRelayDelivery
|
|
2079
|
+
? 'Inbound Claworld delivery joined local session'
|
|
2080
|
+
: 'Inbound Claworld runtime input joined local session',
|
|
2081
|
+
requestId ? `for request ${requestId}` : null,
|
|
2082
|
+
fromAgentId ? `from ${fromAgentId}` : null,
|
|
2083
|
+
].filter(Boolean).join(' ');
|
|
2084
|
+
return buildClaworldRuntimeMaintenanceEvent({
|
|
2085
|
+
id: messageId ? `runtime:${normalizedEventType}:${messageId}` : null,
|
|
2086
|
+
timestamp: delivery.createdAt || metadata.createdAt || payload.createdAt || null,
|
|
2087
|
+
kind: isRelayDelivery
|
|
2088
|
+
? (metadata.deliveryType ? `delivery.${metadata.deliveryType}` : 'delivery')
|
|
2089
|
+
: 'runtime_event',
|
|
2090
|
+
eventType: normalizedEventType,
|
|
2091
|
+
scope,
|
|
2092
|
+
summary,
|
|
2093
|
+
excerpt: isRelayDelivery
|
|
2094
|
+
? (
|
|
2095
|
+
payload.contextText
|
|
2096
|
+
? 'Inbound delivery included contextText; raw dialogue is kept in the OpenClaw session transcript.'
|
|
2097
|
+
: 'Inbound delivery routed into an OpenClaw session after backend session resolution.'
|
|
2098
|
+
)
|
|
2099
|
+
: 'Inbound runtime input routed into an OpenClaw session after backend session resolution.',
|
|
2100
|
+
refs: {
|
|
2101
|
+
deliveryId: isRelayDelivery ? messageId : null,
|
|
2102
|
+
eventId: messageId,
|
|
2103
|
+
requestId,
|
|
2104
|
+
chatRequestId: requestId,
|
|
2105
|
+
worldId,
|
|
2106
|
+
conversationKey,
|
|
2107
|
+
fromAgentId,
|
|
2108
|
+
targetAgentId,
|
|
2109
|
+
notificationId,
|
|
2110
|
+
inboxItemId,
|
|
2111
|
+
sessionKey: localSessionKey || sessionKey,
|
|
2112
|
+
relaySessionKey: sessionKey,
|
|
2113
|
+
},
|
|
2114
|
+
relations: {
|
|
2115
|
+
deliveryId: isRelayDelivery ? messageId : null,
|
|
2116
|
+
eventId: messageId,
|
|
2117
|
+
requestId,
|
|
2118
|
+
chatRequestId: requestId,
|
|
2119
|
+
worldId,
|
|
2120
|
+
conversationKey,
|
|
2121
|
+
fromAgentId,
|
|
2122
|
+
targetAgentId,
|
|
2123
|
+
notificationId,
|
|
2124
|
+
inboxItemId,
|
|
2125
|
+
localAgentId,
|
|
2126
|
+
localSessionKey,
|
|
2127
|
+
relaySessionKey: sessionKey,
|
|
2128
|
+
sessionKey: localSessionKey || sessionKey,
|
|
2129
|
+
sessionId: sessionArtifacts.sessionId,
|
|
2130
|
+
sessionFile: sessionArtifacts.sessionFile,
|
|
2131
|
+
sessionStorePath: sessionArtifacts.sessionStorePath,
|
|
2132
|
+
transcriptPath: sessionArtifacts.transcriptPath,
|
|
2133
|
+
},
|
|
2134
|
+
artifacts: {
|
|
2135
|
+
workspaceRoot,
|
|
2136
|
+
...sessionArtifacts,
|
|
2137
|
+
},
|
|
2138
|
+
});
|
|
2139
|
+
}
|
|
2140
|
+
|
|
1855
2141
|
function createDeliveryReplyDispatcher({
|
|
1856
2142
|
runtime,
|
|
1857
2143
|
currentCfg,
|
|
@@ -2243,18 +2529,14 @@ async function maybeBridgeRuntimeInboundEvent({
|
|
|
2243
2529
|
const contextText = resolveNormalizedText(payload.contextText, null);
|
|
2244
2530
|
const incomingText = resolveNormalizedText(
|
|
2245
2531
|
payload.commandText,
|
|
2246
|
-
contextText
|
|
2532
|
+
contextText
|
|
2533
|
+
? null
|
|
2534
|
+
: resolveNormalizedText(payload.text, resolveNormalizedText(payload.body, null)),
|
|
2247
2535
|
);
|
|
2248
2536
|
const commandText = resolveNormalizedText(payload.commandText, incomingText);
|
|
2249
2537
|
const fromAgentId = resolveNormalizedText(metadata.fromAgentId, null);
|
|
2250
|
-
const routeSessionKind = resolveNormalizedText(
|
|
2251
|
-
event?.route?.sessionKind,
|
|
2252
|
-
resolveNormalizedText(delivery.sessionKind, resolveNormalizedText(payload.sessionKind, null)),
|
|
2253
|
-
);
|
|
2254
2538
|
const isRelayDelivery = eventType === 'delivery';
|
|
2255
2539
|
const allowReply = metadata.allowReply === true || (isRelayDelivery && metadata.allowReply !== false);
|
|
2256
|
-
const remoteIdentity = fromAgentId
|
|
2257
|
-
|| resolveNormalizedText(metadata.source, routeSessionKind === 'management' ? 'claworld-management' : 'unknown-peer');
|
|
2258
2540
|
|
|
2259
2541
|
if (
|
|
2260
2542
|
!runtime?.channel?.reply?.finalizeInboundContext
|
|
@@ -2301,6 +2583,12 @@ async function maybeBridgeRuntimeInboundEvent({
|
|
|
2301
2583
|
sessionTarget: runtimeConfig.routing?.sessionTarget,
|
|
2302
2584
|
fallbackTarget: runtimeConfig.routing?.fallbackTarget,
|
|
2303
2585
|
}) || null;
|
|
2586
|
+
const routeSessionKind = resolveNormalizedText(
|
|
2587
|
+
event?.route?.sessionKind,
|
|
2588
|
+
resolveNormalizedText(routed?.sessionKind, null),
|
|
2589
|
+
);
|
|
2590
|
+
const remoteIdentity = fromAgentId
|
|
2591
|
+
|| resolveNormalizedText(metadata.source, routeSessionKind === 'management' ? 'claworld-management' : 'unknown-peer');
|
|
2304
2592
|
const worldId = resolveDeliveryWorldId(delivery);
|
|
2305
2593
|
const commandAuthorized = isRelayDelivery && shouldAuthorizeBridgedCommand({
|
|
2306
2594
|
runtimeConfig,
|
|
@@ -2342,6 +2630,9 @@ async function maybeBridgeRuntimeInboundEvent({
|
|
|
2342
2630
|
OriginatingFrom: remoteIdentity,
|
|
2343
2631
|
OriginatingTo: remoteIdentity,
|
|
2344
2632
|
ChatType: isManagementSession ? 'management' : 'direct',
|
|
2633
|
+
SessionType: isManagementSession ? 'management' : 'direct',
|
|
2634
|
+
sessionType: isManagementSession ? 'management' : 'direct',
|
|
2635
|
+
sessionKind: isManagementSession ? 'management' : 'conversation',
|
|
2345
2636
|
SenderName: senderName,
|
|
2346
2637
|
SenderId: remoteIdentity,
|
|
2347
2638
|
MessageId: deliveryId,
|
|
@@ -2357,26 +2648,21 @@ async function maybeBridgeRuntimeInboundEvent({
|
|
|
2357
2648
|
UntrustedContext,
|
|
2358
2649
|
});
|
|
2359
2650
|
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
error: error?.message || String(error),
|
|
2376
|
-
});
|
|
2377
|
-
},
|
|
2378
|
-
});
|
|
2379
|
-
}
|
|
2651
|
+
const {
|
|
2652
|
+
sessionArtifacts,
|
|
2653
|
+
} = await recordRuntimeInboundSessionArtifacts({
|
|
2654
|
+
runtime,
|
|
2655
|
+
currentCfg,
|
|
2656
|
+
localAgentId,
|
|
2657
|
+
sessionKey,
|
|
2658
|
+
ctx: inboundCtx,
|
|
2659
|
+
logger,
|
|
2660
|
+
runtimeAccountId,
|
|
2661
|
+
logContext: {
|
|
2662
|
+
eventType,
|
|
2663
|
+
deliveryId,
|
|
2664
|
+
},
|
|
2665
|
+
});
|
|
2380
2666
|
|
|
2381
2667
|
logger.info?.(`[claworld:${runtimeAccountId}] ${isRelayDelivery ? 'routing delivery into runtime session' : 'routing inbound event into runtime session'}`, {
|
|
2382
2668
|
eventType,
|
|
@@ -2478,16 +2764,54 @@ async function maybeBridgeRuntimeInboundEvent({
|
|
|
2478
2764
|
}));
|
|
2479
2765
|
}
|
|
2480
2766
|
|
|
2767
|
+
let journalResult = null;
|
|
2768
|
+
const workspaceRoot = resolveOpenClawWorkspaceRoot({
|
|
2769
|
+
sources: [
|
|
2770
|
+
{ agentId: localAgentId, localAgentId },
|
|
2771
|
+
currentCfg,
|
|
2772
|
+
runtimeConfig,
|
|
2773
|
+
],
|
|
2774
|
+
config: currentCfg,
|
|
2775
|
+
agentId: localAgentId,
|
|
2776
|
+
});
|
|
2777
|
+
if (workspaceRoot) {
|
|
2778
|
+
try {
|
|
2779
|
+
const maintenanceEvent = buildInboundRuntimeMaintenanceEvent({
|
|
2780
|
+
delivery,
|
|
2781
|
+
metadata,
|
|
2782
|
+
payload,
|
|
2783
|
+
messageId: deliveryId,
|
|
2784
|
+
eventType,
|
|
2785
|
+
sessionKind: routeSessionKind,
|
|
2786
|
+
localSessionKey,
|
|
2787
|
+
localAgentId,
|
|
2788
|
+
sessionArtifacts,
|
|
2789
|
+
workspaceRoot,
|
|
2790
|
+
});
|
|
2791
|
+
journalResult = await appendClaworldJournalEvent(workspaceRoot, maintenanceEvent);
|
|
2792
|
+
} catch (error) {
|
|
2793
|
+
logger.warn?.(`[claworld:${runtimeAccountId}] inbound journal append failed`, {
|
|
2794
|
+
eventType,
|
|
2795
|
+
deliveryId,
|
|
2796
|
+
sessionKey,
|
|
2797
|
+
error: error?.message || String(error),
|
|
2798
|
+
});
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2801
|
+
|
|
2481
2802
|
logger.info?.(`[claworld:${runtimeAccountId}] ${isRelayDelivery ? 'delivery bridge completed' : 'inbound bridge completed'}`, {
|
|
2482
2803
|
eventType,
|
|
2483
2804
|
deliveryId,
|
|
2484
2805
|
sessionKey,
|
|
2485
2806
|
localSessionKey,
|
|
2807
|
+
sessionId: sessionArtifacts.sessionId || null,
|
|
2808
|
+
sessionFile: sessionArtifacts.sessionFile || null,
|
|
2486
2809
|
queuedFinal: Boolean(dispatchResult?.queuedFinal),
|
|
2487
2810
|
replied,
|
|
2488
2811
|
keptSilent,
|
|
2489
2812
|
routeStatus: routed?.status || null,
|
|
2490
2813
|
runtimeOutputSummary,
|
|
2814
|
+
journal: journalResult?.ok === true,
|
|
2491
2815
|
});
|
|
2492
2816
|
|
|
2493
2817
|
return {
|