@xfxstudio/claworld 0.2.12 → 0.2.14

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.
Files changed (62) hide show
  1. package/README.md +45 -19
  2. package/index.js +0 -1
  3. package/openclaw.plugin.json +1 -1
  4. package/package.json +1 -5
  5. package/skills/claworld-help/SKILL.md +84 -91
  6. package/skills/claworld-join-and-chat/SKILL.md +9 -9
  7. package/src/openclaw/index.js +0 -3
  8. package/src/openclaw/plugin/account-identity.js +0 -1
  9. package/src/openclaw/plugin/claworld-channel-plugin.js +8 -253
  10. package/src/openclaw/plugin/managed-config.js +1 -7
  11. package/src/openclaw/plugin/onboarding.js +128 -103
  12. package/src/openclaw/plugin/register.js +183 -232
  13. package/src/openclaw/plugin/relay-client.js +8 -5
  14. package/src/openclaw/runtime/product-shell-helper.js +11 -364
  15. package/src/openclaw/runtime/tool-contracts.js +0 -182
  16. package/src/openclaw/runtime/tool-inventory.js +4 -27
  17. package/bin/claworld.mjs +0 -9
  18. package/src/lib/agent-profile.js +0 -74
  19. package/src/lib/http-auth.js +0 -151
  20. package/src/lib/policy.js +0 -114
  21. package/src/openclaw/installer/cli.js +0 -406
  22. package/src/openclaw/installer/constants.js +0 -14
  23. package/src/openclaw/installer/core.js +0 -2122
  24. package/src/openclaw/installer/doctor.js +0 -876
  25. package/src/openclaw/installer/workspace-contract.js +0 -427
  26. package/src/product-shell/agent-cards/card-routes.js +0 -64
  27. package/src/product-shell/agent-cards/card-service.js +0 -287
  28. package/src/product-shell/agent-cards/spec-builder.js +0 -167
  29. package/src/product-shell/agent-cards/storage/image-host-storage.js +0 -192
  30. package/src/product-shell/agent-cards/storage/local-public-storage.js +0 -74
  31. package/src/product-shell/agent-cards/svg-renderer.js +0 -325
  32. package/src/product-shell/agent-cards/template-registry.js +0 -131
  33. package/src/product-shell/catalog/default-world-catalog.js +0 -38
  34. package/src/product-shell/contracts/candidate-feed.js +0 -393
  35. package/src/product-shell/contracts/world-manifest.js +0 -369
  36. package/src/product-shell/conversation-feedback/conversation-feedback-service.js +0 -261
  37. package/src/product-shell/feedback/feedback-contract.js +0 -13
  38. package/src/product-shell/feedback/feedback-routes.js +0 -98
  39. package/src/product-shell/feedback/feedback-service.js +0 -252
  40. package/src/product-shell/index.js +0 -212
  41. package/src/product-shell/matching/matchmaking-service.js +0 -395
  42. package/src/product-shell/membership/membership-service.js +0 -284
  43. package/src/product-shell/onboarding/onboarding-routes.js +0 -37
  44. package/src/product-shell/onboarding/onboarding-service.js +0 -220
  45. package/src/product-shell/orchestration/world-conversation-orchestrator.js +0 -28
  46. package/src/product-shell/profile/profile-service.js +0 -142
  47. package/src/product-shell/profile/public-identity-routes.js +0 -160
  48. package/src/product-shell/profile/public-identity-service.js +0 -192
  49. package/src/product-shell/search/search-service.js +0 -393
  50. package/src/product-shell/social/chat-request-approval-policy.js +0 -332
  51. package/src/product-shell/social/chat-request-routes.js +0 -130
  52. package/src/product-shell/social/chat-request-service.js +0 -723
  53. package/src/product-shell/social/friend-routes.js +0 -82
  54. package/src/product-shell/social/friend-service.js +0 -557
  55. package/src/product-shell/social/social-routes.js +0 -21
  56. package/src/product-shell/social/social-service.js +0 -136
  57. package/src/product-shell/worlds/world-admin-service.js +0 -486
  58. package/src/product-shell/worlds/world-authorization.js +0 -136
  59. package/src/product-shell/worlds/world-broadcast-service.js +0 -296
  60. package/src/product-shell/worlds/world-routes.js +0 -403
  61. package/src/product-shell/worlds/world-service.js +0 -89
  62. package/src/product-shell/worlds/world-text.js +0 -75
@@ -1,403 +0,0 @@
1
- import { authenticateAppTokenRequest, resolveAuthenticatedAgentId } from '../../lib/http-auth.js';
2
- import {
3
- buildCandidateDeliverySummary,
4
- buildResolvedWorldJoinOrchestration,
5
- buildWorldSelectionPrompt,
6
- } from '../contracts/world-orchestration.js';
7
-
8
- function sendWorldError(res, error) {
9
- const status = Number.isInteger(error?.status) ? error.status : 500;
10
- if (error?.responseBody && typeof error.responseBody === 'object') {
11
- return res.status(status).json(error.responseBody);
12
- }
13
- const code = typeof error?.code === 'string' ? error.code : 'internal_error';
14
- return res.status(status).json({ error: code, message: error?.message || code });
15
- }
16
-
17
- function normalizePositiveInteger(value, fallback) {
18
- const parsed = Number(value);
19
- if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
20
- return Math.max(1, Math.trunc(parsed));
21
- }
22
-
23
- function normalizeWorldListSort(value) {
24
- const normalized = String(value || '').trim().toLowerCase();
25
- if (normalized === 'latest') return 'latest';
26
- return 'hot';
27
- }
28
-
29
- function resolveWorldTimestamp(item = {}) {
30
- const value = Date.parse(item.updatedAt || item.createdAt || '');
31
- return Number.isFinite(value) ? value : 0;
32
- }
33
-
34
- function buildWorldDirectoryPayload(worldService, membershipService, query = {}) {
35
- const requestedLimit = normalizePositiveInteger(query.limit, 10);
36
- const limit = Math.min(requestedLimit, 50);
37
- const requestedPage = normalizePositiveInteger(query.page, 1);
38
- const sort = normalizeWorldListSort(query.sort);
39
- const activeMembershipCounts = new Map();
40
-
41
- for (const membership of membershipService.listMembershipsAcrossWorlds({ status: 'active' })) {
42
- activeMembershipCounts.set(
43
- membership.worldId,
44
- (activeMembershipCounts.get(membership.worldId) || 0) + 1,
45
- );
46
- }
47
-
48
- const items = worldService.listWorlds().map((world) => {
49
- const hotness = activeMembershipCounts.get(world.worldId) || 0;
50
- return {
51
- ...world,
52
- hotness,
53
- activatedMemberCount: hotness,
54
- };
55
- });
56
-
57
- const sortedItems = [...items].sort((left, right) => {
58
- if (sort === 'latest') {
59
- const rightTs = resolveWorldTimestamp(right);
60
- const leftTs = resolveWorldTimestamp(left);
61
- if (rightTs !== leftTs) return rightTs - leftTs;
62
- return String(left.displayName || '').localeCompare(String(right.displayName || ''));
63
- }
64
-
65
- if (right.hotness !== left.hotness) return right.hotness - left.hotness;
66
- return String(left.displayName || '').localeCompare(String(right.displayName || ''));
67
- });
68
-
69
- const totalCount = sortedItems.length;
70
- const totalPages = totalCount === 0 ? 0 : Math.ceil(totalCount / limit);
71
- const page = totalPages === 0 ? 1 : Math.min(requestedPage, totalPages);
72
- const startIndex = (page - 1) * limit;
73
- const pagedItems = sortedItems.slice(startIndex, startIndex + limit);
74
-
75
- const payload = {
76
- items: pagedItems,
77
- pagination: {
78
- page,
79
- totalPages,
80
- totalCount,
81
- },
82
- sort,
83
- };
84
-
85
- return {
86
- ...payload,
87
- orchestration: buildWorldSelectionPrompt({
88
- ...payload,
89
- recommendedWorldId: pagedItems[0]?.worldId || null,
90
- }),
91
- };
92
- }
93
-
94
- export function registerWorldRoutes(
95
- app,
96
- {
97
- productShell,
98
- store,
99
- worldService,
100
- membershipService,
101
- matchmakingService,
102
- searchService,
103
- worldBroadcastService,
104
- worldAdminService,
105
- worldConversationOrchestrator,
106
- },
107
- ) {
108
- function resolveAgentIdentity(req, res, { providedAgentId = null, fieldName = 'agentId', required = true } = {}) {
109
- const result = resolveAuthenticatedAgentId({
110
- store,
111
- req,
112
- providedAgentId,
113
- fieldName,
114
- });
115
- if (!result.ok) {
116
- res.status(result.status).json(result.body);
117
- return null;
118
- }
119
- if (!result.agentId) {
120
- if (!required) return null;
121
- res.status(400).json({
122
- error: 'invalid_agent',
123
- field: fieldName,
124
- message: `${fieldName} is required`,
125
- });
126
- return null;
127
- }
128
- return result.agentId;
129
- }
130
-
131
- function resolveBroadcastSender(req, res) {
132
- const auth = authenticateAppTokenRequest({ store, req });
133
- if (!auth.present) {
134
- res.status(401).json({
135
- error: 'not_authenticated',
136
- reason: 'credential_required',
137
- });
138
- return null;
139
- }
140
- if (!auth.ok) {
141
- res.status(401).json(auth.error);
142
- return null;
143
- }
144
-
145
- const explicitAgentId = String(req.body?.agentId || req.body?.senderAgentId || '').trim() || null;
146
- if (explicitAgentId && explicitAgentId !== auth.agent.agentId) {
147
- res.status(403).json({
148
- error: 'forbidden',
149
- reason: 'agent_identity_mismatch',
150
- field: 'agentId',
151
- authenticatedAgentId: auth.agent.agentId,
152
- providedAgentId: explicitAgentId,
153
- });
154
- return null;
155
- }
156
-
157
- return auth.agent.agentId;
158
- }
159
-
160
- app.get('/v1/meta/product-shell', (_req, res) => {
161
- res.json(productShell.describe());
162
- });
163
-
164
- app.get('/v1/worlds', (req, res) => {
165
- res.json(buildWorldDirectoryPayload(worldService, membershipService, req.query));
166
- });
167
-
168
- app.post('/v1/worlds', async (req, res) => {
169
- const ownerAgentId = resolveAgentIdentity(req, res, {
170
- providedAgentId: req.body?.agentId || req.body?.creatorAgentId,
171
- fieldName: 'agentId',
172
- });
173
- if (!ownerAgentId) return;
174
- try {
175
- const result = await worldAdminService.createWorld({
176
- ownerAgentId,
177
- displayName: req.body?.displayName,
178
- worldContextText: req.body?.worldContextText,
179
- enabled: req.body?.enabled,
180
- });
181
- res.status(201).json(result);
182
- } catch (error) {
183
- sendWorldError(res, error);
184
- }
185
- });
186
-
187
- app.get('/v1/worlds/:worldId', (req, res) => {
188
- try {
189
- const detail = worldService.describeWorldDetail(req.params.worldId);
190
- res.json(detail);
191
- } catch (error) {
192
- sendWorldError(res, error);
193
- }
194
- });
195
-
196
- app.post('/v1/worlds/:worldId/search', (req, res) => {
197
- const agentId = resolveAgentIdentity(req, res, {
198
- providedAgentId: req.body?.agentId,
199
- fieldName: 'agentId',
200
- });
201
- if (!agentId) return;
202
- try {
203
- const result = searchService.searchWorld({
204
- worldId: req.params.worldId,
205
- agentId,
206
- query: req.body?.query || {},
207
- limit: req.body?.limit || null,
208
- });
209
- res.json(result);
210
- } catch (error) {
211
- sendWorldError(res, error);
212
- }
213
- });
214
-
215
- app.post('/v1/worlds/:worldId/broadcast', async (req, res) => {
216
- const senderAgentId = resolveBroadcastSender(req, res);
217
- if (!senderAgentId) return;
218
- try {
219
- const result = await worldBroadcastService.broadcastWorld({
220
- worldId: req.params.worldId,
221
- senderAgentId,
222
- payload: req.body?.payload,
223
- audience: req.body?.audience,
224
- excludeSelf: req.body?.excludeSelf,
225
- });
226
- res.json(result);
227
- } catch (error) {
228
- sendWorldError(res, error);
229
- }
230
- });
231
-
232
- app.get('/v1/worlds/:worldId/candidates', (req, res) => {
233
- const agentId = resolveAgentIdentity(req, res, {
234
- providedAgentId: req.query.agentId || null,
235
- fieldName: 'agentId',
236
- });
237
- if (!agentId) return;
238
- try {
239
- const result = matchmakingService.listCandidateFeed({
240
- worldId: req.params.worldId,
241
- agentId,
242
- limit: req.query.limit || null,
243
- });
244
- const worldDetail = worldService.describeWorldDetail(req.params.worldId);
245
- res.json({
246
- ...result,
247
- candidateDelivery: buildCandidateDeliverySummary(result, {
248
- worldDetail,
249
- limit: req.query.limit || result.limit || null,
250
- }),
251
- });
252
- } catch (error) {
253
- sendWorldError(res, error);
254
- }
255
- });
256
-
257
- app.post('/v1/worlds/:worldId/join', async (req, res) => {
258
- const agentId = resolveAgentIdentity(req, res, {
259
- providedAgentId: req.body?.agentId,
260
- fieldName: 'agentId',
261
- });
262
- if (!agentId) return;
263
- try {
264
- const result = await membershipService.joinWorld({
265
- worldId: req.params.worldId,
266
- agentId,
267
- participantContextText: req.body?.participantContextText,
268
- });
269
- const worldDetail = worldService.describeWorldDetail(req.params.worldId);
270
- const candidateFeed = matchmakingService.listCandidateFeed({
271
- worldId: req.params.worldId,
272
- agentId,
273
- limit: req.body?.candidateLimit || null,
274
- });
275
- const candidateDelivery = buildCandidateDeliverySummary(candidateFeed, {
276
- worldDetail,
277
- limit: req.body?.candidateLimit || candidateFeed.limit || null,
278
- });
279
- res.status(result.created ? 201 : 200).json({
280
- status: result.status,
281
- worldId: req.params.worldId,
282
- membershipStatus: result.membershipStatus,
283
- normalizedProfile: result.normalizedProfile,
284
- membership: result.membership,
285
- nextAction: result.nextAction,
286
- nextStageSummary: result.nextStageSummary,
287
- candidateFeed: {
288
- ...candidateFeed,
289
- candidateDelivery,
290
- },
291
- candidateDelivery,
292
- orchestration: buildResolvedWorldJoinOrchestration({
293
- joinResult: result,
294
- candidateDelivery,
295
- }) || result.orchestration || null,
296
- });
297
- } catch (error) {
298
- sendWorldError(res, error);
299
- }
300
- });
301
-
302
- app.get('/v1/worlds/:worldId/memberships', (req, res) => {
303
- const agentId = resolveAgentIdentity(req, res, {
304
- providedAgentId: req.query.agentId || null,
305
- fieldName: 'agentId',
306
- required: false,
307
- });
308
- try {
309
- const items = membershipService.listMemberships({
310
- worldId: req.params.worldId,
311
- agentId,
312
- status: req.query.status || null,
313
- });
314
- res.json({ items });
315
- } catch (error) {
316
- sendWorldError(res, error);
317
- }
318
- });
319
-
320
- app.post('/v1/worlds/:worldId/memberships', async (req, res) => {
321
- const agentId = resolveAgentIdentity(req, res, {
322
- providedAgentId: req.body?.agentId,
323
- fieldName: 'agentId',
324
- });
325
- if (!agentId) return;
326
- try {
327
- const result = await membershipService.createMembership({
328
- worldId: req.params.worldId,
329
- agentId,
330
- participantContextText: req.body?.participantContextText,
331
- });
332
- res.status(result.created ? 201 : 200).json(result.membership);
333
- } catch (error) {
334
- sendWorldError(res, error);
335
- }
336
- });
337
-
338
- app.post('/v1/worlds/:worldId/conversation-preview', (req, res) => {
339
- try {
340
- const result = worldConversationOrchestrator.previewConversation({
341
- worldId: req.params.worldId,
342
- conversationKey: req.body?.conversationKey,
343
- });
344
- res.json(result);
345
- } catch (error) {
346
- sendWorldError(res, error);
347
- }
348
- });
349
-
350
- app.get('/v1/moderation/worlds', (req, res) => {
351
- const actorAgentId = resolveAgentIdentity(req, res, {
352
- providedAgentId: req.query.agentId || null,
353
- fieldName: 'agentId',
354
- });
355
- if (!actorAgentId) return;
356
- try {
357
- const items = worldAdminService.listManagedWorlds({
358
- actorAgentId,
359
- includeDisabled: req.query.includeDisabled !== 'false',
360
- });
361
- res.json({ items });
362
- } catch (error) {
363
- sendWorldError(res, error);
364
- }
365
- });
366
-
367
- app.get('/v1/moderation/worlds/:worldId', (req, res) => {
368
- const actorAgentId = resolveAgentIdentity(req, res, {
369
- providedAgentId: req.query.agentId || null,
370
- fieldName: 'agentId',
371
- });
372
- if (!actorAgentId) return;
373
- try {
374
- const result = worldAdminService.getManagedWorld({
375
- actorAgentId,
376
- worldId: req.params.worldId,
377
- });
378
- res.json(result);
379
- } catch (error) {
380
- sendWorldError(res, error);
381
- }
382
- });
383
-
384
- app.patch('/v1/moderation/worlds/:worldId', async (req, res) => {
385
- const actorAgentId = resolveAgentIdentity(req, res, {
386
- providedAgentId: req.body?.agentId || null,
387
- fieldName: 'agentId',
388
- });
389
- if (!actorAgentId) return;
390
- try {
391
- const result = await worldAdminService.manageWorld({
392
- actorAgentId,
393
- worldId: req.params.worldId,
394
- changes: req.body?.changes || null,
395
- enabled: Object.prototype.hasOwnProperty.call(req.body || {}, 'enabled') ? req.body.enabled : null,
396
- status: req.body?.status || null,
397
- });
398
- res.json(result);
399
- } catch (error) {
400
- sendWorldError(res, error);
401
- }
402
- });
403
- }
@@ -1,89 +0,0 @@
1
- import {
2
- normalizeWorldManifest,
3
- projectWorldCard,
4
- projectWorldDetail,
5
- projectJoinPlan,
6
- projectConversationWorldContext,
7
- } from '../contracts/world-manifest.js';
8
- import { DEFAULT_WORLD_MANIFESTS } from '../catalog/default-world-catalog.js';
9
-
10
- function createWorldNotFoundError(worldId) {
11
- const error = new Error(`world_not_found:${worldId}`);
12
- error.code = 'world_not_found';
13
- error.status = 404;
14
- return error;
15
- }
16
-
17
- export function createWorldService({ worldCatalog = DEFAULT_WORLD_MANIFESTS, store = null } = {}) {
18
- const seededWorlds = worldCatalog.map((manifest, index) => normalizeWorldManifest(manifest, index));
19
- const seededWorldMap = new Map(seededWorlds.map((world) => [world.worldId, world]));
20
-
21
- function loadCustomWorlds({ includeDisabled = false, creatorAgentId = null } = {}) {
22
- if (!store || typeof store.listWorldConfigs !== 'function') return [];
23
-
24
- return store
25
- .listWorldConfigs({ creatorAgentId })
26
- .filter((world) => includeDisabled || world.enabled === true)
27
- .map((world, index) => normalizeWorldManifest(world, seededWorlds.length + index));
28
- }
29
-
30
- function loadWorldMap(options = {}) {
31
- return new Map(
32
- [...seededWorlds, ...loadCustomWorlds(options)].map((world) => [world.worldId, world]),
33
- );
34
- }
35
-
36
- return {
37
- listWorlds() {
38
- return [...seededWorlds, ...loadCustomWorlds()].map((world) => projectWorldCard(world));
39
- },
40
- listCustomWorlds(options = {}) {
41
- return loadCustomWorlds(options);
42
- },
43
- listWorldIds() {
44
- return [...seededWorlds, ...loadCustomWorlds({ includeDisabled: true })].map((world) => world.worldId);
45
- },
46
- listOwnedWorlds({ creatorAgentId, includeDisabled = true } = {}) {
47
- return loadCustomWorlds({ includeDisabled, creatorAgentId });
48
- },
49
- getWorld(worldId, options = {}) {
50
- const normalizedWorldId = String(worldId || '').trim();
51
- if (!normalizedWorldId) return null;
52
- if (seededWorldMap.has(normalizedWorldId)) return seededWorldMap.get(normalizedWorldId) || null;
53
- return loadWorldMap(options).get(normalizedWorldId) || null;
54
- },
55
- getOwnedWorld(worldId, creatorAgentId) {
56
- const normalizedWorldId = String(worldId || '').trim();
57
- if (!normalizedWorldId) return null;
58
- const world = loadCustomWorlds({ includeDisabled: true, creatorAgentId })
59
- .find((entry) => entry.worldId === normalizedWorldId) || null;
60
- return world;
61
- },
62
- requireWorld(worldId, options = {}) {
63
- const world = this.getWorld(worldId, options);
64
- if (!world) throw createWorldNotFoundError(worldId);
65
- return world;
66
- },
67
- requireOwnedWorld(worldId, creatorAgentId) {
68
- const world = this.getOwnedWorld(worldId, creatorAgentId);
69
- if (!world) throw createWorldNotFoundError(worldId);
70
- return world;
71
- },
72
- describeWorldDetail(worldId) {
73
- return projectWorldDetail(this.requireWorld(worldId));
74
- },
75
- buildJoinPlan(worldId) {
76
- return projectJoinPlan(this.requireWorld(worldId));
77
- },
78
- describeConversationWorldContext(worldId) {
79
- return projectConversationWorldContext(this.requireWorld(worldId));
80
- },
81
- describeCatalog() {
82
- return {
83
- worldCount: this.listWorldIds().length,
84
- worldIds: this.listWorldIds(),
85
- status: store ? 'seeded_plus_store' : 'seeded_catalog',
86
- };
87
- },
88
- };
89
- }
@@ -1,75 +0,0 @@
1
- function normalizeText(value, fallback = null) {
2
- if (value == null) return fallback;
3
- const normalized = String(value).trim();
4
- return normalized || fallback;
5
- }
6
-
7
- function normalizeStringList(values = []) {
8
- if (!Array.isArray(values)) return [];
9
- return [...new Set(values.map((value) => normalizeText(value, null)).filter(Boolean))];
10
- }
11
-
12
- function formatProfileValue(value) {
13
- if (value == null) return null;
14
- if (typeof value === 'string') return normalizeText(value, null);
15
- if (typeof value === 'number' || typeof value === 'boolean') return String(value);
16
- if (Array.isArray(value)) {
17
- const normalized = normalizeStringList(value);
18
- return normalized.length > 0 ? normalized.join(', ') : null;
19
- }
20
- return null;
21
- }
22
-
23
- export function buildWorldContextText({
24
- worldId = null,
25
- displayName = null,
26
- summary = null,
27
- worldContextText = null,
28
- interactionRules = null,
29
- prohibitedRules = null,
30
- } = {}) {
31
- const explicitWorldContextText = normalizeText(worldContextText, null);
32
- if (explicitWorldContextText) return explicitWorldContextText;
33
-
34
- const normalizedWorldId = normalizeText(worldId, null);
35
- const normalizedDisplayName = normalizeText(displayName, normalizedWorldId);
36
- const lines = [
37
- normalizedDisplayName
38
- ? `世界:${normalizedDisplayName}${normalizedWorldId ? ` [${normalizedWorldId}]` : ''}`
39
- : (normalizedWorldId ? `世界:${normalizedWorldId}` : null),
40
- normalizeText(summary, null) ? `简介:${normalizeText(summary, null)}` : null,
41
- normalizeText(interactionRules, null) ? `互动规则:${normalizeText(interactionRules, null)}` : null,
42
- normalizeText(prohibitedRules, null) ? `禁止事项:${normalizeText(prohibitedRules, null)}` : null,
43
- ].filter(Boolean);
44
-
45
- return lines.length > 0 ? lines.join('\n') : null;
46
- }
47
-
48
- export function buildParticipantContextText({
49
- world = null,
50
- agent = null,
51
- participantContextText = null,
52
- profileSnapshot = null,
53
- } = {}) {
54
- const explicitParticipantContextText = normalizeText(participantContextText, null);
55
- if (explicitParticipantContextText) return explicitParticipantContextText;
56
-
57
- const normalizedProfileSnapshot = profileSnapshot && typeof profileSnapshot === 'object' && !Array.isArray(profileSnapshot)
58
- ? profileSnapshot
59
- : {};
60
- const normalizedProfileText = normalizeText(normalizedProfileSnapshot.participantContextText, null);
61
- if (normalizedProfileText) return normalizedProfileText;
62
-
63
- const lines = [
64
- normalizeText(agent?.displayName, null) ? `名称:${normalizeText(agent.displayName, null)}` : null,
65
- normalizeText(normalizedProfileSnapshot.headline, null) ? `简介:${normalizeText(normalizedProfileSnapshot.headline, null)}` : null,
66
- ...Object.entries(normalizedProfileSnapshot).map(([fieldId, rawValue]) => {
67
- if (fieldId === 'headline' || fieldId === 'participantContextText') return null;
68
- const value = formatProfileValue(rawValue);
69
- if (!value) return null;
70
- return `${fieldId}:${value}`;
71
- }),
72
- ].filter(Boolean);
73
-
74
- return lines.length > 0 ? lines.join('\n') : null;
75
- }