@xfxstudio/claworld 0.1.4 → 0.2.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/README.md +12 -29
- package/openclaw.plugin.json +9 -33
- package/package.json +2 -10
- package/skills/claworld-help/SKILL.md +86 -160
- package/skills/claworld-join-and-chat/SKILL.md +107 -203
- package/skills/claworld-manage-worlds/SKILL.md +75 -392
- package/src/lib/chat-request.js +347 -0
- package/src/lib/{accepted-chat-kickoff.js → relay/kickoff-text.js} +67 -26
- package/src/openclaw/index.js +0 -5
- package/src/openclaw/installer/cli.js +14 -16
- package/src/openclaw/installer/core.js +13 -14
- package/src/openclaw/installer/doctor.js +69 -31
- package/src/openclaw/installer/workspace-contract.js +33 -9
- package/src/openclaw/plugin/claworld-channel-plugin.js +156 -625
- package/src/openclaw/plugin/config-schema.js +4 -16
- package/src/openclaw/plugin/managed-config.js +127 -75
- package/src/openclaw/plugin/onboarding.js +7 -3
- package/src/openclaw/plugin/register.js +40 -339
- package/src/openclaw/plugin/relay-client.js +112 -102
- package/src/openclaw/protocol/relay-event-protocol.js +34 -22
- package/src/openclaw/runtime/canonical-result-builder.js +15 -5
- package/src/openclaw/runtime/demo-session-bootstrap.js +0 -4
- package/src/openclaw/runtime/feedback-helper.js +3 -2
- package/src/openclaw/runtime/inbound-session-router.js +28 -20
- package/src/openclaw/runtime/outbound-session-bridge.js +21 -9
- package/src/openclaw/runtime/product-shell-helper.js +45 -637
- package/src/openclaw/runtime/runtime-path.js +2 -2
- package/src/openclaw/runtime/system-message-orchestrator.js +1 -1
- package/src/openclaw/runtime/tool-contracts.js +36 -258
- package/src/openclaw/runtime/world-moderation-helper.js +11 -65
- package/src/product-shell/catalog/default-world-catalog.js +15 -33
- package/src/product-shell/contracts/candidate-feed.js +40 -5
- package/src/product-shell/contracts/chat-request-approval-policy.js +3 -3
- package/src/product-shell/contracts/world-manifest.js +134 -161
- package/src/product-shell/contracts/world-orchestration.js +55 -326
- package/src/product-shell/feedback/feedback-routes.js +4 -3
- package/src/product-shell/feedback/feedback-service.js +11 -8
- package/src/product-shell/index.js +6 -7
- package/src/product-shell/matching/matchmaking-service.js +39 -5
- package/src/product-shell/membership/membership-service.js +125 -147
- package/src/product-shell/onboarding/onboarding-service.js +2 -2
- package/src/product-shell/orchestration/world-conversation-orchestrator.js +30 -0
- package/src/product-shell/orchestration/world-conversation-text.js +231 -0
- package/src/product-shell/results/result-service.js +9 -3
- package/src/product-shell/search/search-service.js +28 -1
- package/src/product-shell/social/chat-request-routes.js +0 -1
- package/src/product-shell/social/chat-request-service.js +1 -102
- package/src/product-shell/worlds/world-admin-service.js +86 -277
- package/src/product-shell/worlds/world-authorization.js +3 -5
- package/src/product-shell/worlds/world-routes.js +8 -38
- package/src/product-shell/worlds/world-service.js +3 -3
- package/src/product-shell/worlds/world-text.js +77 -0
- package/src/lib/runtime-guidance.js +0 -457
- package/src/openclaw/runtime/world-session-startup.js +0 -1
- package/src/product-shell/orchestration/session-orchestrator.js +0 -38
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import { createKickoffBrief } from './relay/kickoff-text.js';
|
|
2
|
+
|
|
3
|
+
function normalizeText(value, fallback = null) {
|
|
4
|
+
if (value == null) return fallback;
|
|
5
|
+
const normalized = String(value).trim();
|
|
6
|
+
return normalized || fallback;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function cloneJsonObject(value) {
|
|
10
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return null;
|
|
11
|
+
try {
|
|
12
|
+
const cloned = JSON.parse(JSON.stringify(value));
|
|
13
|
+
if (!cloned || typeof cloned !== 'object' || Array.isArray(cloned)) return null;
|
|
14
|
+
return cloned;
|
|
15
|
+
} catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function normalizeChatRequestConversation(input = {}) {
|
|
21
|
+
if (!input || typeof input !== 'object' || Array.isArray(input)) return {};
|
|
22
|
+
const conversation = {
|
|
23
|
+
...(normalizeText(input.worldId, null) ? { worldId: normalizeText(input.worldId, null) } : {}),
|
|
24
|
+
...(normalizeText(input.scope, null)
|
|
25
|
+
? { scope: normalizeText(input.scope, null) }
|
|
26
|
+
: {}),
|
|
27
|
+
...(normalizeText(input.conversationId, null) ? { conversationId: normalizeText(input.conversationId, null) } : {}),
|
|
28
|
+
...(normalizeText(input.threadId, null) ? { threadId: normalizeText(input.threadId, null) } : {}),
|
|
29
|
+
...(normalizeText(input.conversationKey, null) ? { conversationKey: normalizeText(input.conversationKey, null) } : {}),
|
|
30
|
+
...(normalizeText(input.sessionKey, null) ? { sessionKey: normalizeText(input.sessionKey, null) } : {}),
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const episode = cloneJsonObject(input.episode);
|
|
34
|
+
if (episode) {
|
|
35
|
+
conversation.episode = episode;
|
|
36
|
+
}
|
|
37
|
+
const worldContextText = normalizeText(
|
|
38
|
+
input.worldContextText,
|
|
39
|
+
normalizeText(input.worldContext?.worldContextText, normalizeText(input.worldContext?.text, null)),
|
|
40
|
+
);
|
|
41
|
+
if (worldContextText) {
|
|
42
|
+
conversation.worldContextText = worldContextText;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return conversation;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function normalizeChatRequestOrigin(origin = {}, { fallbackType = null } = {}) {
|
|
49
|
+
if (!origin || typeof origin !== 'object' || Array.isArray(origin)) {
|
|
50
|
+
const type = normalizeText(fallbackType, null);
|
|
51
|
+
return type ? { type } : null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const normalized = {
|
|
55
|
+
...(normalizeText(origin.type, normalizeText(fallbackType, null))
|
|
56
|
+
? { type: normalizeText(origin.type, normalizeText(fallbackType, null)) }
|
|
57
|
+
: {}),
|
|
58
|
+
...(normalizeText(origin.broadcastId, null) ? { broadcastId: normalizeText(origin.broadcastId, null) } : {}),
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
return Object.keys(normalized).length > 0 ? normalized : null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function normalizeChatRequestBroadcast(input = {}) {
|
|
65
|
+
if (!input || typeof input !== 'object' || Array.isArray(input)) return null;
|
|
66
|
+
const normalized = {
|
|
67
|
+
...(normalizeText(input.broadcastId, null) ? { broadcastId: normalizeText(input.broadcastId, null) } : {}),
|
|
68
|
+
...(normalizeText(input.worldId, null) ? { worldId: normalizeText(input.worldId, null) } : {}),
|
|
69
|
+
...(normalizeText(input.audience, null) ? { audience: normalizeText(input.audience, null) } : {}),
|
|
70
|
+
...(normalizeText(input.senderRole, null) ? { senderRole: normalizeText(input.senderRole, null) } : {}),
|
|
71
|
+
...(normalizeText(input.eligibility, null) ? { eligibility: normalizeText(input.eligibility, null) } : {}),
|
|
72
|
+
...(typeof input.excludeSelf === 'boolean' ? { excludeSelf: input.excludeSelf } : {}),
|
|
73
|
+
};
|
|
74
|
+
return Object.keys(normalized).length > 0 ? normalized : null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function normalizeChatRequestOpeningPayload(input = null) {
|
|
78
|
+
if (!input || typeof input !== 'object' || Array.isArray(input)) return null;
|
|
79
|
+
const payload = cloneJsonObject(input);
|
|
80
|
+
if (!payload) return null;
|
|
81
|
+
if (typeof payload.text === 'string') {
|
|
82
|
+
payload.text = payload.text.trim();
|
|
83
|
+
if (!payload.text) delete payload.text;
|
|
84
|
+
}
|
|
85
|
+
if (typeof payload.source === 'string') {
|
|
86
|
+
payload.source = payload.source.trim() || undefined;
|
|
87
|
+
}
|
|
88
|
+
return Object.keys(payload).length > 0 ? payload : null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function resolveChatRequestOpeningMessage({
|
|
92
|
+
openingMessage = null,
|
|
93
|
+
openingPayload = null,
|
|
94
|
+
requestContext = null,
|
|
95
|
+
} = {}) {
|
|
96
|
+
return normalizeText(
|
|
97
|
+
openingMessage,
|
|
98
|
+
normalizeText(openingPayload?.text, normalizeText(requestContext?.message, null)),
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function resolveKickoffBriefSource({
|
|
103
|
+
kickoffBrief = null,
|
|
104
|
+
openingPayload = null,
|
|
105
|
+
requestContext = null,
|
|
106
|
+
source = null,
|
|
107
|
+
} = {}) {
|
|
108
|
+
const normalizedContext = requestContext && typeof requestContext === 'object' && !Array.isArray(requestContext)
|
|
109
|
+
? requestContext
|
|
110
|
+
: {};
|
|
111
|
+
const explicitKickoffBrief = kickoffBrief && typeof kickoffBrief === 'object' && !Array.isArray(kickoffBrief)
|
|
112
|
+
? kickoffBrief
|
|
113
|
+
: null;
|
|
114
|
+
const contextKickoffBrief = normalizedContext.kickoffBrief && typeof normalizedContext.kickoffBrief === 'object' && !Array.isArray(normalizedContext.kickoffBrief)
|
|
115
|
+
? normalizedContext.kickoffBrief
|
|
116
|
+
: null;
|
|
117
|
+
const fallbackSource = normalizeText(source, null) === 'world_broadcast'
|
|
118
|
+
? 'world_broadcast_brief'
|
|
119
|
+
: 'chat_request_brief';
|
|
120
|
+
return normalizeText(
|
|
121
|
+
explicitKickoffBrief?.source,
|
|
122
|
+
normalizeText(
|
|
123
|
+
contextKickoffBrief?.source,
|
|
124
|
+
normalizeText(
|
|
125
|
+
openingPayload?.source,
|
|
126
|
+
normalizeText(normalizedContext.openingPayload?.source, fallbackSource),
|
|
127
|
+
),
|
|
128
|
+
),
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function resolveChatRequestKickoffBrief({
|
|
133
|
+
kickoffBrief = null,
|
|
134
|
+
openingMessage = null,
|
|
135
|
+
openingPayload = null,
|
|
136
|
+
requestContext = null,
|
|
137
|
+
source = null,
|
|
138
|
+
} = {}) {
|
|
139
|
+
const normalizedContext = requestContext && typeof requestContext === 'object' && !Array.isArray(requestContext)
|
|
140
|
+
? requestContext
|
|
141
|
+
: {};
|
|
142
|
+
const explicitKickoffBrief = kickoffBrief && typeof kickoffBrief === 'object' && !Array.isArray(kickoffBrief)
|
|
143
|
+
? kickoffBrief
|
|
144
|
+
: null;
|
|
145
|
+
const contextKickoffBrief = normalizedContext.kickoffBrief && typeof normalizedContext.kickoffBrief === 'object' && !Array.isArray(normalizedContext.kickoffBrief)
|
|
146
|
+
? normalizedContext.kickoffBrief
|
|
147
|
+
: null;
|
|
148
|
+
const normalizedOpeningPayload = normalizeChatRequestOpeningPayload(
|
|
149
|
+
explicitKickoffBrief?.payload
|
|
150
|
+
?? contextKickoffBrief?.payload
|
|
151
|
+
?? openingPayload
|
|
152
|
+
?? normalizedContext.openingPayload,
|
|
153
|
+
);
|
|
154
|
+
const normalizedOpeningMessage = resolveChatRequestOpeningMessage({
|
|
155
|
+
openingMessage:
|
|
156
|
+
explicitKickoffBrief?.text
|
|
157
|
+
?? contextKickoffBrief?.text
|
|
158
|
+
?? openingMessage,
|
|
159
|
+
openingPayload: normalizedOpeningPayload,
|
|
160
|
+
requestContext: normalizedContext,
|
|
161
|
+
});
|
|
162
|
+
return createKickoffBrief({
|
|
163
|
+
text: normalizedOpeningMessage,
|
|
164
|
+
payload: explicitKickoffBrief?.payload ?? contextKickoffBrief?.payload ?? normalizedOpeningPayload,
|
|
165
|
+
source: resolveKickoffBriefSource({
|
|
166
|
+
kickoffBrief: explicitKickoffBrief ?? contextKickoffBrief,
|
|
167
|
+
openingPayload: normalizedOpeningPayload,
|
|
168
|
+
requestContext: normalizedContext,
|
|
169
|
+
source,
|
|
170
|
+
}),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export function normalizeChatRequestInput({ requestContext = {}, source = null } = {}) {
|
|
175
|
+
const normalizedContext = requestContext && typeof requestContext === 'object' && !Array.isArray(requestContext)
|
|
176
|
+
? requestContext
|
|
177
|
+
: {};
|
|
178
|
+
const conversationSource = normalizedContext.conversation && typeof normalizedContext.conversation === 'object' && !Array.isArray(normalizedContext.conversation)
|
|
179
|
+
? normalizedContext.conversation
|
|
180
|
+
: {};
|
|
181
|
+
const conversation = normalizeChatRequestConversation({
|
|
182
|
+
...conversationSource,
|
|
183
|
+
conversationKey: normalizedContext.conversationKey ?? conversationSource.conversationKey,
|
|
184
|
+
sessionKey: normalizedContext.sessionKey ?? conversationSource.sessionKey,
|
|
185
|
+
});
|
|
186
|
+
const kickoffBrief = resolveChatRequestKickoffBrief({
|
|
187
|
+
requestContext: normalizedContext,
|
|
188
|
+
source,
|
|
189
|
+
});
|
|
190
|
+
const openingPayload = normalizeChatRequestOpeningPayload(kickoffBrief?.payload ?? normalizedContext.openingPayload);
|
|
191
|
+
const broadcast = normalizeChatRequestBroadcast(normalizedContext.broadcast);
|
|
192
|
+
let origin = normalizeChatRequestOrigin(normalizedContext.origin, {
|
|
193
|
+
fallbackType: normalizeText(source, null) === 'world_broadcast' ? 'world_broadcast' : 'chat_request',
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
if (broadcast?.broadcastId && !origin?.broadcastId) {
|
|
197
|
+
origin = {
|
|
198
|
+
...(origin || { type: normalizeText(source, null) === 'world_broadcast' ? 'world_broadcast' : 'chat_request' }),
|
|
199
|
+
broadcastId: broadcast.broadcastId,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
kickoffBrief,
|
|
205
|
+
openingMessage: resolveChatRequestOpeningMessage({
|
|
206
|
+
openingMessage: kickoffBrief?.text ?? null,
|
|
207
|
+
openingPayload: kickoffBrief?.payload ?? openingPayload,
|
|
208
|
+
requestContext: normalizedContext,
|
|
209
|
+
}),
|
|
210
|
+
openingPayload: kickoffBrief?.payload ?? openingPayload,
|
|
211
|
+
conversation,
|
|
212
|
+
origin,
|
|
213
|
+
broadcast,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export function buildChatRequestContext({
|
|
218
|
+
kickoffBrief = null,
|
|
219
|
+
openingMessage = null,
|
|
220
|
+
openingPayload = null,
|
|
221
|
+
conversation = {},
|
|
222
|
+
origin = null,
|
|
223
|
+
broadcast = null,
|
|
224
|
+
source = 'chat_request',
|
|
225
|
+
} = {}) {
|
|
226
|
+
const normalizedConversation = normalizeChatRequestConversation(conversation);
|
|
227
|
+
const normalizedKickoffBrief = resolveChatRequestKickoffBrief({
|
|
228
|
+
kickoffBrief,
|
|
229
|
+
openingMessage,
|
|
230
|
+
openingPayload,
|
|
231
|
+
source,
|
|
232
|
+
});
|
|
233
|
+
const normalizedOpeningPayload = normalizeChatRequestOpeningPayload(
|
|
234
|
+
normalizedKickoffBrief?.payload ?? openingPayload,
|
|
235
|
+
);
|
|
236
|
+
const normalizedMessage = resolveChatRequestOpeningMessage({
|
|
237
|
+
openingMessage: normalizedKickoffBrief?.text ?? openingMessage,
|
|
238
|
+
openingPayload: normalizedOpeningPayload,
|
|
239
|
+
});
|
|
240
|
+
let normalizedOrigin = normalizeChatRequestOrigin(origin, {
|
|
241
|
+
fallbackType: normalizeText(source, null) === 'world_broadcast' ? 'world_broadcast' : 'chat_request',
|
|
242
|
+
});
|
|
243
|
+
let normalizedBroadcast = normalizeChatRequestBroadcast(broadcast);
|
|
244
|
+
|
|
245
|
+
if (normalizedOrigin?.broadcastId && !normalizedBroadcast?.broadcastId) {
|
|
246
|
+
normalizedBroadcast = {
|
|
247
|
+
...(normalizedBroadcast || {}),
|
|
248
|
+
broadcastId: normalizedOrigin.broadcastId,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const requestContext = {
|
|
253
|
+
type: 'chat_request',
|
|
254
|
+
...(normalizedKickoffBrief ? { kickoffBrief: normalizedKickoffBrief } : {}),
|
|
255
|
+
...(normalizedMessage ? { message: normalizedMessage } : {}),
|
|
256
|
+
...(normalizedOpeningPayload ? { openingPayload: normalizedOpeningPayload } : {}),
|
|
257
|
+
...(Object.keys(normalizedConversation).length > 0 ? { conversation: normalizedConversation } : {}),
|
|
258
|
+
...(normalizedOrigin ? { origin: normalizedOrigin } : {}),
|
|
259
|
+
...(normalizedBroadcast ? { broadcast: normalizedBroadcast } : {}),
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
return requestContext;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export function normalizeStoredChatRequest(input = {}, { defaultSource = 'chat_request' } = {}) {
|
|
266
|
+
const normalizedSource = normalizeText(input.source, defaultSource);
|
|
267
|
+
const normalizedRequest = normalizeChatRequestInput({
|
|
268
|
+
requestContext: input.requestContext,
|
|
269
|
+
source: normalizedSource,
|
|
270
|
+
});
|
|
271
|
+
const kickoffBrief = resolveChatRequestKickoffBrief({
|
|
272
|
+
kickoffBrief: input.kickoffBrief,
|
|
273
|
+
openingMessage: input.openingMessage,
|
|
274
|
+
openingPayload: input.openingPayload ?? normalizedRequest.openingPayload,
|
|
275
|
+
requestContext: input.requestContext,
|
|
276
|
+
source: normalizedSource,
|
|
277
|
+
});
|
|
278
|
+
const openingPayload = normalizeChatRequestOpeningPayload(
|
|
279
|
+
input.openingPayload ?? kickoffBrief?.payload ?? normalizedRequest.openingPayload,
|
|
280
|
+
);
|
|
281
|
+
const openingMessage = resolveChatRequestOpeningMessage({
|
|
282
|
+
openingMessage: kickoffBrief?.text ?? input.openingMessage,
|
|
283
|
+
openingPayload,
|
|
284
|
+
requestContext: input.requestContext,
|
|
285
|
+
});
|
|
286
|
+
const conversation = normalizeChatRequestConversation(
|
|
287
|
+
input.conversation && typeof input.conversation === 'object' && !Array.isArray(input.conversation)
|
|
288
|
+
? input.conversation
|
|
289
|
+
: normalizedRequest.conversation,
|
|
290
|
+
);
|
|
291
|
+
const broadcast = normalizeChatRequestBroadcast(
|
|
292
|
+
input.broadcast && typeof input.broadcast === 'object' && !Array.isArray(input.broadcast)
|
|
293
|
+
? input.broadcast
|
|
294
|
+
: normalizedRequest.broadcast,
|
|
295
|
+
);
|
|
296
|
+
let origin = normalizeChatRequestOrigin(
|
|
297
|
+
input.origin && typeof input.origin === 'object' && !Array.isArray(input.origin)
|
|
298
|
+
? input.origin
|
|
299
|
+
: normalizedRequest.origin,
|
|
300
|
+
{ fallbackType: normalizedSource === 'world_broadcast' ? 'world_broadcast' : 'chat_request' },
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
if (broadcast?.broadcastId && !origin?.broadcastId) {
|
|
304
|
+
origin = {
|
|
305
|
+
...(origin || { type: normalizedSource === 'world_broadcast' ? 'world_broadcast' : 'chat_request' }),
|
|
306
|
+
broadcastId: broadcast.broadcastId,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const chatRequestId = normalizeText(input.chatRequestId, normalizeText(input.requestId, null));
|
|
311
|
+
const normalized = {
|
|
312
|
+
chatRequestId,
|
|
313
|
+
requestId: chatRequestId,
|
|
314
|
+
fromAgentId: normalizeText(input.fromAgentId, null),
|
|
315
|
+
toAgentId: normalizeText(input.toAgentId, null),
|
|
316
|
+
toAddress: normalizeText(input.toAddress, null),
|
|
317
|
+
openingMessage,
|
|
318
|
+
...(kickoffBrief ? { kickoffBrief } : {}),
|
|
319
|
+
...(openingPayload ? { openingPayload } : {}),
|
|
320
|
+
conversation,
|
|
321
|
+
...(origin ? { origin } : {}),
|
|
322
|
+
...(broadcast ? { broadcast } : {}),
|
|
323
|
+
requestContext: buildChatRequestContext({
|
|
324
|
+
kickoffBrief,
|
|
325
|
+
openingMessage,
|
|
326
|
+
openingPayload,
|
|
327
|
+
conversation,
|
|
328
|
+
origin,
|
|
329
|
+
broadcast,
|
|
330
|
+
source: normalizedSource,
|
|
331
|
+
}),
|
|
332
|
+
status: normalizeText(input.status, 'pending'),
|
|
333
|
+
createdAt: normalizeText(input.createdAt, null),
|
|
334
|
+
respondedAt: normalizeText(input.respondedAt, null),
|
|
335
|
+
expiresAt: normalizeText(input.expiresAt, null),
|
|
336
|
+
source: normalizedSource,
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
const acceptedByAgentId = normalizeText(input.acceptedByAgentId, null);
|
|
340
|
+
if (acceptedByAgentId) normalized.acceptedByAgentId = acceptedByAgentId;
|
|
341
|
+
const approvalGrantId = normalizeText(input.approvalGrantId, null);
|
|
342
|
+
if (approvalGrantId) normalized.approvalGrantId = approvalGrantId;
|
|
343
|
+
const kickoff = cloneJsonObject(input.kickoff);
|
|
344
|
+
if (kickoff) normalized.kickoff = kickoff;
|
|
345
|
+
|
|
346
|
+
return normalized;
|
|
347
|
+
}
|
|
@@ -21,6 +21,43 @@ function normalizeKickoffPayload(input) {
|
|
|
21
21
|
return cloneJsonObject(input);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
function formatScalar(value) {
|
|
25
|
+
if (value == null) return null;
|
|
26
|
+
if (typeof value === 'string') return normalizeText(value, null);
|
|
27
|
+
if (typeof value === 'number' || typeof value === 'boolean') return String(value);
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function formatStructuredValue(value, indent = '') {
|
|
32
|
+
const scalar = formatScalar(value);
|
|
33
|
+
if (scalar != null) return scalar;
|
|
34
|
+
if (Array.isArray(value)) {
|
|
35
|
+
const items = value
|
|
36
|
+
.map((item) => formatStructuredValue(item, `${indent} `))
|
|
37
|
+
.filter(Boolean);
|
|
38
|
+
if (items.length === 0) return null;
|
|
39
|
+
return items.map((item) => `${indent}- ${String(item).replace(/\n/g, `\n${indent} `)}`).join('\n');
|
|
40
|
+
}
|
|
41
|
+
if (!value || typeof value !== 'object') return null;
|
|
42
|
+
const entries = Object.entries(value)
|
|
43
|
+
.map(([key, entryValue]) => {
|
|
44
|
+
const formatted = formatStructuredValue(entryValue, `${indent} `);
|
|
45
|
+
if (!formatted) return null;
|
|
46
|
+
if (formatted.includes('\n')) {
|
|
47
|
+
return `${indent}${key}:\n${formatted}`;
|
|
48
|
+
}
|
|
49
|
+
return `${indent}${key}: ${formatted}`;
|
|
50
|
+
})
|
|
51
|
+
.filter(Boolean);
|
|
52
|
+
return entries.length > 0 ? entries.join('\n') : null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function formatStructuredSection(title, value) {
|
|
56
|
+
const formatted = formatStructuredValue(value);
|
|
57
|
+
if (!formatted) return null;
|
|
58
|
+
return `${title}:\n${formatted}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
24
61
|
function normalizeKickoffSource(value, fallback = 'chat_request_brief') {
|
|
25
62
|
return normalizeText(value, fallback);
|
|
26
63
|
}
|
|
@@ -63,7 +100,7 @@ export function resolveStoredKickoffBrief(requestContext = {}) {
|
|
|
63
100
|
return createKickoffBrief({
|
|
64
101
|
text: normalizeText(requestContext.openingPayload?.text, normalizeText(requestContext.message, null)),
|
|
65
102
|
payload: requestContext.openingPayload,
|
|
66
|
-
source: requestContext.openingPayload?.source || '
|
|
103
|
+
source: requestContext.openingPayload?.source || 'chat_request_opening',
|
|
67
104
|
});
|
|
68
105
|
}
|
|
69
106
|
|
|
@@ -151,16 +188,28 @@ export function createAcceptedChatKickoffRuntimeContextForAgent(bundle = {}, {
|
|
|
151
188
|
|
|
152
189
|
export function formatAcceptedChatKickoffMessage(bundle = {}, { viewer = 'recipient' } = {}) {
|
|
153
190
|
const normalizedViewer = viewer === 'sender' ? 'sender' : 'recipient';
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
191
|
+
const requestContext = bundle.requestContext && typeof bundle.requestContext === 'object' && !Array.isArray(bundle.requestContext)
|
|
192
|
+
? bundle.requestContext
|
|
193
|
+
: {};
|
|
194
|
+
const worldInfo = bundle.worldInfo && typeof bundle.worldInfo === 'object' && !Array.isArray(bundle.worldInfo)
|
|
195
|
+
? bundle.worldInfo
|
|
196
|
+
: null;
|
|
197
|
+
const senderInfo = bundle.senderInfo && typeof bundle.senderInfo === 'object' && !Array.isArray(bundle.senderInfo)
|
|
198
|
+
? bundle.senderInfo
|
|
199
|
+
: (
|
|
200
|
+
bundle.selfInfo && typeof bundle.selfInfo === 'object' && !Array.isArray(bundle.selfInfo)
|
|
201
|
+
? bundle.selfInfo
|
|
202
|
+
: null
|
|
203
|
+
);
|
|
204
|
+
const recipientInfo = bundle.recipientInfo && typeof bundle.recipientInfo === 'object' && !Array.isArray(bundle.recipientInfo)
|
|
205
|
+
? bundle.recipientInfo
|
|
206
|
+
: (
|
|
207
|
+
bundle.peerInfo && typeof bundle.peerInfo === 'object' && !Array.isArray(bundle.peerInfo)
|
|
208
|
+
? bundle.peerInfo
|
|
209
|
+
: null
|
|
210
|
+
);
|
|
211
|
+
const selfInfo = normalizedViewer === 'sender' ? senderInfo : recipientInfo;
|
|
212
|
+
const peerInfo = normalizedViewer === 'sender' ? recipientInfo : senderInfo;
|
|
164
213
|
const viewerInstruction = normalizedViewer === 'recipient'
|
|
165
214
|
? 'Use this accepted-chat kickoff context to interpret the sender opener as the first live turn of the accepted chat episode. Decide whether and how to reply. Do not echo the bundle verbatim to the peer.'
|
|
166
215
|
: 'Use this accepted-chat kickoff bundle to craft the first live opener to the recipient. Do not echo the bundle verbatim to the peer.';
|
|
@@ -171,21 +220,13 @@ export function formatAcceptedChatKickoffMessage(bundle = {}, { viewer = 'recipi
|
|
|
171
220
|
: 'Internal Claworld accepted-chat kickoff bundle for the sender runtime.',
|
|
172
221
|
viewerInstruction,
|
|
173
222
|
normalizeText(bundle.requestId, null) ? `Accepted episode: ${bundle.requestId}` : null,
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
? `Recipient: ${normalizeText(recipient.displayName, recipient.agentId)}${recipient.agentId ? ` [${recipient.agentId}]` : ''}`
|
|
182
|
-
: null,
|
|
183
|
-
world?.summary ? `World summary: ${world.summary}` : null,
|
|
184
|
-
world?.sessionContext ? `World session context:\n${JSON.stringify(world.sessionContext, null, 2)}` : null,
|
|
185
|
-
participants.sender?.worldProfile ? `Sender world profile:\n${JSON.stringify(participants.sender.worldProfile, null, 2)}` : null,
|
|
186
|
-
participants.recipient?.worldProfile ? `Recipient world profile:\n${JSON.stringify(participants.recipient.worldProfile, null, 2)}` : null,
|
|
187
|
-
Object.keys(policy).length > 0 ? `Accepted episode policy:\n${JSON.stringify(policy, null, 2)}` : null,
|
|
188
|
-
brief.payload ? `Structured brief payload:\n${JSON.stringify(brief.payload, null, 2)}` : null,
|
|
223
|
+
formatStructuredSection('主人想让你做的事情 / 请求上下文', requestContext),
|
|
224
|
+
formatStructuredSection('世界信息', worldInfo),
|
|
225
|
+
formatStructuredSection('我方信息', selfInfo),
|
|
226
|
+
formatStructuredSection('对方信息', peerInfo),
|
|
227
|
+
normalizedViewer === 'sender'
|
|
228
|
+
? '请你现在直接输出一条自然的开场白。不要解释规则,不要复述这些说明。'
|
|
229
|
+
: '请把对方刚发来的 opener 视为这段对话的第一条 live turn,并决定是否以及如何直接回复。不要解释规则,不要复述这些说明。',
|
|
189
230
|
].filter(Boolean);
|
|
190
231
|
|
|
191
232
|
return blocks.join('\n\n');
|
package/src/openclaw/index.js
CHANGED
|
@@ -37,17 +37,12 @@ export {
|
|
|
37
37
|
buildWorldSelectionPrompt,
|
|
38
38
|
resolveWorldSelection,
|
|
39
39
|
fetchWorldDetail,
|
|
40
|
-
fetchWorldJoinCheck,
|
|
41
40
|
joinWorld,
|
|
42
|
-
submitWorldJoin,
|
|
43
41
|
fetchWorldSearch,
|
|
44
42
|
submitWorldSearch,
|
|
45
43
|
broadcastWorld,
|
|
46
44
|
fetchWorldCandidateFeed,
|
|
47
45
|
buildCandidateDeliverySummary,
|
|
48
|
-
buildRequiredFieldExplanation,
|
|
49
|
-
resolveWorldProfileCollectionFlow,
|
|
50
46
|
resolveWorldSelectionFlow,
|
|
51
|
-
resolveWorldJoinFlow,
|
|
52
47
|
} from './runtime/product-shell-helper.js';
|
|
53
48
|
export { submitFeedbackReport } from './runtime/feedback-helper.js';
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import os from 'os';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import {
|
|
4
|
-
DEFAULT_CLAWORLD_TOOL_PROFILE,
|
|
5
4
|
expandUserPath,
|
|
6
|
-
normalizeClaworldToolProfile,
|
|
7
5
|
} from '../plugin/managed-config.js';
|
|
8
6
|
import {
|
|
9
7
|
CLAWORLD_DOCTOR_COMMAND,
|
|
@@ -37,10 +35,10 @@ Install options:
|
|
|
37
35
|
--server-url <url> Override the Claworld backend URL
|
|
38
36
|
--api-key <value> Override the Claworld backend API key
|
|
39
37
|
--account-id <id> Managed Claworld account id (default: claworld)
|
|
40
|
-
--agent-id <id>
|
|
41
|
-
--workspace <path>
|
|
38
|
+
--agent-id <id> Local OpenClaw agent id to bind claworld onto (default: main)
|
|
39
|
+
--workspace <path> Optional dedicated workspace path for claworld-specific bootstrap files
|
|
42
40
|
--display-name <name> Managed display name override
|
|
43
|
-
--tool-profile <
|
|
41
|
+
--tool-profile <profile> minimal | default | full | world
|
|
44
42
|
--repo-root <path> Local repo root when using --plugin-install-mode link|copy
|
|
45
43
|
--plugin-install-mode <m> npm | link | copy | skip (default: npm)
|
|
46
44
|
--plugin-source <value> npm package or local path (default: ${CLAWORLD_INSTALLER_PACKAGE_NAME})
|
|
@@ -51,18 +49,18 @@ Update options:
|
|
|
51
49
|
--server-url <url> Override the Claworld backend URL
|
|
52
50
|
--api-key <value> Override the Claworld backend API key
|
|
53
51
|
--account-id <id> Managed Claworld account id (default: claworld)
|
|
54
|
-
--agent-id <id>
|
|
55
|
-
--workspace <path>
|
|
52
|
+
--agent-id <id> Local OpenClaw agent id bound to claworld (default: main)
|
|
53
|
+
--workspace <path> Optional dedicated workspace path for claworld-specific bootstrap files
|
|
56
54
|
--display-name <name> Managed display name override
|
|
57
|
-
--tool-profile <
|
|
55
|
+
--tool-profile <profile> minimal | default | full | world
|
|
58
56
|
Doctor options:
|
|
59
57
|
--config <path> OpenClaw config path (default: ${DEFAULT_OPENCLAW_CONFIG_PATH})
|
|
60
58
|
--state-dir <path> Optional OPENCLAW_STATE_DIR for OpenClaw commands
|
|
61
59
|
--openclaw-bin <path> OpenClaw CLI binary (default: ${DEFAULT_OPENCLAW_BIN})
|
|
62
60
|
--server-url <url> Override the Claworld backend URL
|
|
63
61
|
--account-id <id> Managed Claworld account id (default: claworld)
|
|
64
|
-
--agent-id <id>
|
|
65
|
-
--workspace <path>
|
|
62
|
+
--agent-id <id> Local OpenClaw agent id bound to claworld (default: main)
|
|
63
|
+
--workspace <path> Optional dedicated workspace path override
|
|
66
64
|
--json Print machine-readable result
|
|
67
65
|
--help, -h Show this help
|
|
68
66
|
|
|
@@ -92,13 +90,13 @@ export function parseInstallerCliArgs(argv = process.argv.slice(2), env = proces
|
|
|
92
90
|
serverUrl: null,
|
|
93
91
|
apiKey: null,
|
|
94
92
|
accountId: 'claworld',
|
|
95
|
-
agentId: '
|
|
93
|
+
agentId: 'main',
|
|
96
94
|
workspace: null,
|
|
97
95
|
displayName: null,
|
|
98
|
-
toolProfile: DEFAULT_CLAWORLD_TOOL_PROFILE,
|
|
99
96
|
repoRoot: null,
|
|
100
97
|
pluginInstallMode: 'npm',
|
|
101
98
|
pluginInstallSource: CLAWORLD_INSTALLER_PACKAGE_NAME,
|
|
99
|
+
toolProfile: null,
|
|
102
100
|
},
|
|
103
101
|
update: {
|
|
104
102
|
openclawBin: env.OPENCLAW_BIN || DEFAULT_OPENCLAW_BIN,
|
|
@@ -107,10 +105,10 @@ export function parseInstallerCliArgs(argv = process.argv.slice(2), env = proces
|
|
|
107
105
|
serverUrl: null,
|
|
108
106
|
apiKey: null,
|
|
109
107
|
accountId: 'claworld',
|
|
110
|
-
agentId: '
|
|
108
|
+
agentId: 'main',
|
|
111
109
|
workspace: null,
|
|
112
110
|
displayName: null,
|
|
113
|
-
toolProfile:
|
|
111
|
+
toolProfile: null,
|
|
114
112
|
},
|
|
115
113
|
doctor: {
|
|
116
114
|
openclawBin: env.OPENCLAW_BIN || DEFAULT_OPENCLAW_BIN,
|
|
@@ -118,7 +116,7 @@ export function parseInstallerCliArgs(argv = process.argv.slice(2), env = proces
|
|
|
118
116
|
stateDir: env.OPENCLAW_STATE_DIR ? expandUserPath(env.OPENCLAW_STATE_DIR, homeDir) : null,
|
|
119
117
|
serverUrl: null,
|
|
120
118
|
accountId: 'claworld',
|
|
121
|
-
agentId: '
|
|
119
|
+
agentId: 'main',
|
|
122
120
|
workspace: null,
|
|
123
121
|
},
|
|
124
122
|
};
|
|
@@ -187,7 +185,7 @@ export function parseInstallerCliArgs(argv = process.argv.slice(2), env = proces
|
|
|
187
185
|
index += 1;
|
|
188
186
|
break;
|
|
189
187
|
case '--tool-profile':
|
|
190
|
-
options.install.toolProfile =
|
|
188
|
+
options.install.toolProfile = nextValue(remaining, index);
|
|
191
189
|
options.update.toolProfile = options.install.toolProfile;
|
|
192
190
|
index += 1;
|
|
193
191
|
break;
|
|
@@ -6,13 +6,13 @@ import { spawnSync } from 'child_process';
|
|
|
6
6
|
import vm from 'vm';
|
|
7
7
|
import {
|
|
8
8
|
DEFAULT_CLAWORLD_ACCOUNT_ID,
|
|
9
|
+
DEFAULT_CLAWORLD_AGENT_ID,
|
|
9
10
|
DEFAULT_CLAWORLD_SERVER_URL,
|
|
10
11
|
applyClaworldManagedRuntimeConfig,
|
|
11
12
|
ensureObject,
|
|
12
13
|
expandUserPath,
|
|
13
14
|
normalizeText,
|
|
14
15
|
resolveClaworldManagedRuntimeOptions,
|
|
15
|
-
resolveToolNames,
|
|
16
16
|
} from '../plugin/managed-config.js';
|
|
17
17
|
import {
|
|
18
18
|
defaultClaworldAccountId,
|
|
@@ -58,13 +58,7 @@ export function hasManagedBinding(config = {}, { agentId, accountId } = {}) {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export function isManagedToolAllowlistReady(config = {}, options = {}) {
|
|
61
|
-
|
|
62
|
-
(Array.isArray(config?.tools?.allow) ? config.tools.allow : [])
|
|
63
|
-
.map((item) => normalizeText(item, null))
|
|
64
|
-
.filter(Boolean),
|
|
65
|
-
);
|
|
66
|
-
if (allow.has('*')) return true;
|
|
67
|
-
return resolveToolNames(options).every((toolName) => allow.has(toolName));
|
|
61
|
+
return true;
|
|
68
62
|
}
|
|
69
63
|
|
|
70
64
|
export function isRelayBootstrapReady(account = {}) {
|
|
@@ -474,9 +468,12 @@ function defaultCommandRunner({
|
|
|
474
468
|
};
|
|
475
469
|
}
|
|
476
470
|
|
|
471
|
+
const useShell = process.platform === 'win32' && /\.(cmd|bat)$/i.test(effectiveBin);
|
|
477
472
|
const result = spawnSync(effectiveBin, args, {
|
|
478
473
|
cwd,
|
|
479
474
|
env,
|
|
475
|
+
shell: useShell,
|
|
476
|
+
windowsHide: true,
|
|
480
477
|
stdio: capture ? 'pipe' : 'inherit',
|
|
481
478
|
encoding: 'utf8',
|
|
482
479
|
});
|
|
@@ -622,9 +619,9 @@ export function inspectManagedClaworldInstall({
|
|
|
622
619
|
const managedReady = Boolean(
|
|
623
620
|
managedAccountPresent
|
|
624
621
|
&& managedRuntimeReady
|
|
625
|
-
&& managedAgentPresent
|
|
626
622
|
&& managedBindingPresent
|
|
627
623
|
&& toolsReady
|
|
624
|
+
&& (managedOptions.manageAgentEntry !== true || managedAgentPresent)
|
|
628
625
|
);
|
|
629
626
|
|
|
630
627
|
let statusLabel = 'needs setup';
|
|
@@ -1153,7 +1150,7 @@ export async function verifyClaworldInstall({
|
|
|
1153
1150
|
configPath = null,
|
|
1154
1151
|
stateDir = DEFAULT_OPENCLAW_STATE_DIR,
|
|
1155
1152
|
accountId = DEFAULT_CLAWORLD_ACCOUNT_ID,
|
|
1156
|
-
agentId =
|
|
1153
|
+
agentId = DEFAULT_CLAWORLD_AGENT_ID,
|
|
1157
1154
|
commandRunner = defaultCommandRunner,
|
|
1158
1155
|
cwd = process.cwd(),
|
|
1159
1156
|
env = process.env,
|
|
@@ -1255,7 +1252,7 @@ async function reconcileManagedClaworldRuntime({
|
|
|
1255
1252
|
serverUrl = null,
|
|
1256
1253
|
apiKey = null,
|
|
1257
1254
|
accountId = DEFAULT_CLAWORLD_ACCOUNT_ID,
|
|
1258
|
-
agentId =
|
|
1255
|
+
agentId = DEFAULT_CLAWORLD_AGENT_ID,
|
|
1259
1256
|
workspace = null,
|
|
1260
1257
|
displayName = null,
|
|
1261
1258
|
toolProfile = null,
|
|
@@ -1396,7 +1393,9 @@ async function reconcileManagedClaworldRuntime({
|
|
|
1396
1393
|
await writeConfig(configPath, transformed.config, dryRun);
|
|
1397
1394
|
}
|
|
1398
1395
|
|
|
1399
|
-
const workspaceActions =
|
|
1396
|
+
const workspaceActions = managedOptions.manageWorkspace
|
|
1397
|
+
? await seedManagedWorkspace(managedOptions, dryRun)
|
|
1398
|
+
: [];
|
|
1400
1399
|
await validateOpenclawConfig({
|
|
1401
1400
|
openclawBin,
|
|
1402
1401
|
configPath,
|
|
@@ -1459,7 +1458,7 @@ export async function runClaworldInstallerInstall({
|
|
|
1459
1458
|
serverUrl = null,
|
|
1460
1459
|
apiKey = null,
|
|
1461
1460
|
accountId = DEFAULT_CLAWORLD_ACCOUNT_ID,
|
|
1462
|
-
agentId =
|
|
1461
|
+
agentId = DEFAULT_CLAWORLD_AGENT_ID,
|
|
1463
1462
|
workspace = null,
|
|
1464
1463
|
displayName = null,
|
|
1465
1464
|
toolProfile = null,
|
|
@@ -1559,7 +1558,7 @@ export async function runClaworldInstallerUpdate({
|
|
|
1559
1558
|
serverUrl = null,
|
|
1560
1559
|
apiKey = null,
|
|
1561
1560
|
accountId = DEFAULT_CLAWORLD_ACCOUNT_ID,
|
|
1562
|
-
agentId =
|
|
1561
|
+
agentId = DEFAULT_CLAWORLD_AGENT_ID,
|
|
1563
1562
|
workspace = null,
|
|
1564
1563
|
displayName = null,
|
|
1565
1564
|
toolProfile = null,
|