@xfxstudio/claworld 0.1.5 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -29
- package/openclaw.plugin.json +5 -29
- package/package.json +4 -12
- package/skills/claworld-help/SKILL.md +50 -182
- package/skills/claworld-join-and-chat/SKILL.md +78 -288
- package/skills/claworld-manage-worlds/SKILL.md +71 -288
- 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 +18 -9
- package/src/openclaw/installer/core.js +12 -6
- 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 +118 -623
- package/src/openclaw/plugin/config-schema.js +3 -15
- package/src/openclaw/plugin/managed-config.js +98 -47
- package/src/openclaw/plugin/onboarding.js +7 -3
- package/src/openclaw/plugin/register.js +37 -336
- package/src/openclaw/plugin/relay-client.js +111 -101
- 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 +43 -636
- 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 +33 -258
- package/src/openclaw/runtime/world-moderation-helper.js +11 -65
- package/src/product-shell/catalog/default-world-catalog.js +9 -27
- package/src/product-shell/contracts/candidate-feed.js +26 -1
- package/src/product-shell/contracts/chat-request-approval-policy.js +4 -4
- package/src/product-shell/contracts/world-manifest.js +115 -160
- package/src/product-shell/contracts/world-orchestration.js +47 -322
- 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 +5 -6
- 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 +85 -276
- 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';
|
|
@@ -35,9 +35,10 @@ Install options:
|
|
|
35
35
|
--server-url <url> Override the Claworld backend URL
|
|
36
36
|
--api-key <value> Override the Claworld backend API key
|
|
37
37
|
--account-id <id> Managed Claworld account id (default: claworld)
|
|
38
|
-
--agent-id <id>
|
|
39
|
-
--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
|
|
40
40
|
--display-name <name> Managed display name override
|
|
41
|
+
--tool-profile <profile> minimal | default | full | world
|
|
41
42
|
--repo-root <path> Local repo root when using --plugin-install-mode link|copy
|
|
42
43
|
--plugin-install-mode <m> npm | link | copy | skip (default: npm)
|
|
43
44
|
--plugin-source <value> npm package or local path (default: ${CLAWORLD_INSTALLER_PACKAGE_NAME})
|
|
@@ -48,17 +49,18 @@ Update options:
|
|
|
48
49
|
--server-url <url> Override the Claworld backend URL
|
|
49
50
|
--api-key <value> Override the Claworld backend API key
|
|
50
51
|
--account-id <id> Managed Claworld account id (default: claworld)
|
|
51
|
-
--agent-id <id>
|
|
52
|
-
--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
|
|
53
54
|
--display-name <name> Managed display name override
|
|
55
|
+
--tool-profile <profile> minimal | default | full | world
|
|
54
56
|
Doctor options:
|
|
55
57
|
--config <path> OpenClaw config path (default: ${DEFAULT_OPENCLAW_CONFIG_PATH})
|
|
56
58
|
--state-dir <path> Optional OPENCLAW_STATE_DIR for OpenClaw commands
|
|
57
59
|
--openclaw-bin <path> OpenClaw CLI binary (default: ${DEFAULT_OPENCLAW_BIN})
|
|
58
60
|
--server-url <url> Override the Claworld backend URL
|
|
59
61
|
--account-id <id> Managed Claworld account id (default: claworld)
|
|
60
|
-
--agent-id <id>
|
|
61
|
-
--workspace <path>
|
|
62
|
+
--agent-id <id> Local OpenClaw agent id bound to claworld (default: main)
|
|
63
|
+
--workspace <path> Optional dedicated workspace path override
|
|
62
64
|
--json Print machine-readable result
|
|
63
65
|
--help, -h Show this help
|
|
64
66
|
|
|
@@ -88,12 +90,13 @@ export function parseInstallerCliArgs(argv = process.argv.slice(2), env = proces
|
|
|
88
90
|
serverUrl: null,
|
|
89
91
|
apiKey: null,
|
|
90
92
|
accountId: 'claworld',
|
|
91
|
-
agentId: '
|
|
93
|
+
agentId: 'main',
|
|
92
94
|
workspace: null,
|
|
93
95
|
displayName: null,
|
|
94
96
|
repoRoot: null,
|
|
95
97
|
pluginInstallMode: 'npm',
|
|
96
98
|
pluginInstallSource: CLAWORLD_INSTALLER_PACKAGE_NAME,
|
|
99
|
+
toolProfile: null,
|
|
97
100
|
},
|
|
98
101
|
update: {
|
|
99
102
|
openclawBin: env.OPENCLAW_BIN || DEFAULT_OPENCLAW_BIN,
|
|
@@ -102,9 +105,10 @@ export function parseInstallerCliArgs(argv = process.argv.slice(2), env = proces
|
|
|
102
105
|
serverUrl: null,
|
|
103
106
|
apiKey: null,
|
|
104
107
|
accountId: 'claworld',
|
|
105
|
-
agentId: '
|
|
108
|
+
agentId: 'main',
|
|
106
109
|
workspace: null,
|
|
107
110
|
displayName: null,
|
|
111
|
+
toolProfile: null,
|
|
108
112
|
},
|
|
109
113
|
doctor: {
|
|
110
114
|
openclawBin: env.OPENCLAW_BIN || DEFAULT_OPENCLAW_BIN,
|
|
@@ -112,7 +116,7 @@ export function parseInstallerCliArgs(argv = process.argv.slice(2), env = proces
|
|
|
112
116
|
stateDir: env.OPENCLAW_STATE_DIR ? expandUserPath(env.OPENCLAW_STATE_DIR, homeDir) : null,
|
|
113
117
|
serverUrl: null,
|
|
114
118
|
accountId: 'claworld',
|
|
115
|
-
agentId: '
|
|
119
|
+
agentId: 'main',
|
|
116
120
|
workspace: null,
|
|
117
121
|
},
|
|
118
122
|
};
|
|
@@ -180,6 +184,11 @@ export function parseInstallerCliArgs(argv = process.argv.slice(2), env = proces
|
|
|
180
184
|
options.update.displayName = options.install.displayName;
|
|
181
185
|
index += 1;
|
|
182
186
|
break;
|
|
187
|
+
case '--tool-profile':
|
|
188
|
+
options.install.toolProfile = nextValue(remaining, index);
|
|
189
|
+
options.update.toolProfile = options.install.toolProfile;
|
|
190
|
+
index += 1;
|
|
191
|
+
break;
|
|
183
192
|
case '--repo-root':
|
|
184
193
|
options.install.repoRoot = path.resolve(expandUserPath(nextValue(remaining, index), homeDir));
|
|
185
194
|
index += 1;
|
|
@@ -6,6 +6,7 @@ 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,
|
|
@@ -467,9 +468,12 @@ function defaultCommandRunner({
|
|
|
467
468
|
};
|
|
468
469
|
}
|
|
469
470
|
|
|
471
|
+
const useShell = process.platform === 'win32' && /\.(cmd|bat)$/i.test(effectiveBin);
|
|
470
472
|
const result = spawnSync(effectiveBin, args, {
|
|
471
473
|
cwd,
|
|
472
474
|
env,
|
|
475
|
+
shell: useShell,
|
|
476
|
+
windowsHide: true,
|
|
473
477
|
stdio: capture ? 'pipe' : 'inherit',
|
|
474
478
|
encoding: 'utf8',
|
|
475
479
|
});
|
|
@@ -615,9 +619,9 @@ export function inspectManagedClaworldInstall({
|
|
|
615
619
|
const managedReady = Boolean(
|
|
616
620
|
managedAccountPresent
|
|
617
621
|
&& managedRuntimeReady
|
|
618
|
-
&& managedAgentPresent
|
|
619
622
|
&& managedBindingPresent
|
|
620
623
|
&& toolsReady
|
|
624
|
+
&& (managedOptions.manageAgentEntry !== true || managedAgentPresent)
|
|
621
625
|
);
|
|
622
626
|
|
|
623
627
|
let statusLabel = 'needs setup';
|
|
@@ -1146,7 +1150,7 @@ export async function verifyClaworldInstall({
|
|
|
1146
1150
|
configPath = null,
|
|
1147
1151
|
stateDir = DEFAULT_OPENCLAW_STATE_DIR,
|
|
1148
1152
|
accountId = DEFAULT_CLAWORLD_ACCOUNT_ID,
|
|
1149
|
-
agentId =
|
|
1153
|
+
agentId = DEFAULT_CLAWORLD_AGENT_ID,
|
|
1150
1154
|
commandRunner = defaultCommandRunner,
|
|
1151
1155
|
cwd = process.cwd(),
|
|
1152
1156
|
env = process.env,
|
|
@@ -1248,7 +1252,7 @@ async function reconcileManagedClaworldRuntime({
|
|
|
1248
1252
|
serverUrl = null,
|
|
1249
1253
|
apiKey = null,
|
|
1250
1254
|
accountId = DEFAULT_CLAWORLD_ACCOUNT_ID,
|
|
1251
|
-
agentId =
|
|
1255
|
+
agentId = DEFAULT_CLAWORLD_AGENT_ID,
|
|
1252
1256
|
workspace = null,
|
|
1253
1257
|
displayName = null,
|
|
1254
1258
|
toolProfile = null,
|
|
@@ -1389,7 +1393,9 @@ async function reconcileManagedClaworldRuntime({
|
|
|
1389
1393
|
await writeConfig(configPath, transformed.config, dryRun);
|
|
1390
1394
|
}
|
|
1391
1395
|
|
|
1392
|
-
const workspaceActions =
|
|
1396
|
+
const workspaceActions = managedOptions.manageWorkspace
|
|
1397
|
+
? await seedManagedWorkspace(managedOptions, dryRun)
|
|
1398
|
+
: [];
|
|
1393
1399
|
await validateOpenclawConfig({
|
|
1394
1400
|
openclawBin,
|
|
1395
1401
|
configPath,
|
|
@@ -1452,7 +1458,7 @@ export async function runClaworldInstallerInstall({
|
|
|
1452
1458
|
serverUrl = null,
|
|
1453
1459
|
apiKey = null,
|
|
1454
1460
|
accountId = DEFAULT_CLAWORLD_ACCOUNT_ID,
|
|
1455
|
-
agentId =
|
|
1461
|
+
agentId = DEFAULT_CLAWORLD_AGENT_ID,
|
|
1456
1462
|
workspace = null,
|
|
1457
1463
|
displayName = null,
|
|
1458
1464
|
toolProfile = null,
|
|
@@ -1552,7 +1558,7 @@ export async function runClaworldInstallerUpdate({
|
|
|
1552
1558
|
serverUrl = null,
|
|
1553
1559
|
apiKey = null,
|
|
1554
1560
|
accountId = DEFAULT_CLAWORLD_ACCOUNT_ID,
|
|
1555
|
-
agentId =
|
|
1561
|
+
agentId = DEFAULT_CLAWORLD_AGENT_ID,
|
|
1556
1562
|
workspace = null,
|
|
1557
1563
|
displayName = null,
|
|
1558
1564
|
toolProfile = null,
|