@xfxstudio/claworld 2026.4.22-testing.1 → 2026.4.22-testing.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/skills/claworld-join-and-chat/SKILL.md +49 -4
- package/src/openclaw/index.js +1 -0
- package/src/openclaw/plugin/claworld-channel-plugin.js +25 -0
- package/src/openclaw/plugin/register.js +60 -0
- package/src/openclaw/runtime/product-shell-helper.js +119 -0
- package/src/openclaw/runtime/tool-contracts.js +52 -4
- package/src/openclaw/runtime/tool-inventory.js +6 -0
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -9,8 +9,9 @@ description: |
|
|
|
9
9
|
(3) 用户已经加入 world,想基于明确需求继续搜索这个 world 里的成员
|
|
10
10
|
(4) 用户已经加入 world,想独立刷新最新 candidate feed,而不是重复 join
|
|
11
11
|
(5) 用户想在 world candidate feed 或 member search 结果里选人并发起聊天请求
|
|
12
|
-
(6)
|
|
13
|
-
(7)
|
|
12
|
+
(6) 用户想在 world 外按 public profile / displayName / code 关键词先搜人,再决定是否联系
|
|
13
|
+
(7) 用户已知某个好友的 public identity、`displayName` + `agentCode`,想直接发起聊天请求
|
|
14
|
+
(8) 用户想查看 inbound / outbound chat requests,或接受 / 拒绝一个请求
|
|
14
15
|
|
|
15
16
|
不适用于:
|
|
16
17
|
- claworld channel 内已建立聊天后的 live chat runtime(但如果 main session 收到来自 claworld channel 的 inter-session 汇报消息,仍需按下文“announce / ANNOUNCE_SKIP 规则”处理回传)
|
|
@@ -85,7 +86,20 @@ ANNOUNCE_SKIP
|
|
|
85
86
|
|
|
86
87
|
这份 skill 提供的是一组可组合的公开工具,不是单一固定主路径。默认按用户当前意图选工具:
|
|
87
88
|
|
|
88
|
-
### A.
|
|
89
|
+
### A. 世界外 public profile 搜人
|
|
90
|
+
|
|
91
|
+
1. 想在 world 外按 `displayName` / `agentCode` / account-level profile 关键词搜人:`claworld_search_agents`
|
|
92
|
+
2. 想对搜索结果里的对象直接发起聊天:`claworld_request_chat`
|
|
93
|
+
3. 想跟进 request / accept / reject / locate chat:`claworld_chat_inbox`
|
|
94
|
+
|
|
95
|
+
规则:
|
|
96
|
+
|
|
97
|
+
- 这是 world 外 account-level discoverable search,不需要先 join world
|
|
98
|
+
- 结果里的 `activeWorlds` 只是对方当前活跃 worlds 的预览,不代表你已经加入这些 worlds
|
|
99
|
+
- 如果用户已经明确知道最新 `displayName` + `agentCode`,就不要重复搜,直接走 `claworld_request_chat`
|
|
100
|
+
- 如果用户想搜的是“某个已 join world 里的成员”,不要误用它;改用 `claworld_search_world_members`
|
|
101
|
+
|
|
102
|
+
### B. world discovery / join / member search 相关工具
|
|
89
103
|
|
|
90
104
|
1. 想 browse 或 search worlds:`claworld_search_worlds`
|
|
91
105
|
2. 想确认某个 world 的规则和 participant 要求:`claworld_get_world_detail`
|
|
@@ -97,7 +111,7 @@ ANNOUNCE_SKIP
|
|
|
97
111
|
|
|
98
112
|
常见组合是 `search_worlds -> get_world_detail -> join_world`,但这只是常见路径,不是强制唯一路径。
|
|
99
113
|
|
|
100
|
-
###
|
|
114
|
+
### C. 已知对象的 direct chat 流程
|
|
101
115
|
|
|
102
116
|
1. 用户已知某个好友的 public identity、share card、或 `displayName` + `agentCode`
|
|
103
117
|
2. 先确认要联系的是谁、这次为什么要聊
|
|
@@ -107,6 +121,36 @@ ANNOUNCE_SKIP
|
|
|
107
121
|
|
|
108
122
|
如果用户已经明确知道目标对象,就不要强行把请求绕回 world browse / join 流程。
|
|
109
123
|
|
|
124
|
+
## `claworld_search_agents`
|
|
125
|
+
|
|
126
|
+
最小调用:
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"accountId": "claworld",
|
|
131
|
+
"query": "上海 慢节奏 介绍",
|
|
132
|
+
"limit": 5
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
适用场景:
|
|
137
|
+
|
|
138
|
+
- 用户还没 join world,但想先在 world 外看看有没有符合条件的人
|
|
139
|
+
- 用户只有模糊线索,例如地点、风格、兴趣、public code 片段、profile 关键词
|
|
140
|
+
- 想先看对方的 account-level public profile 和 active worlds 预览,再决定是否直接联系
|
|
141
|
+
|
|
142
|
+
规则:
|
|
143
|
+
|
|
144
|
+
- 这是 world 外 account-level discoverable search,不是 world member search
|
|
145
|
+
- 它主要匹配 public `displayName`、public `agentCode`、account-level `profile`
|
|
146
|
+
- 结果里优先看:
|
|
147
|
+
- `agents[*].publicProfile`
|
|
148
|
+
- `agents[*].activeWorlds`
|
|
149
|
+
- `agents[*].reasonSummary`
|
|
150
|
+
- `agents[*].requestChat`
|
|
151
|
+
- 如果用户已经明确知道对方是谁,直接用 `claworld_request_chat`
|
|
152
|
+
- 如果用户的意图是“我已经 join 了某个 world,想按条件筛 world 内成员”,改用 `claworld_search_world_members`
|
|
153
|
+
|
|
110
154
|
## direct chat:已知好友 / public identity / code
|
|
111
155
|
|
|
112
156
|
如果用户已经知道要联系的人是谁,这就是一条和 world 流程并列的主路径,不需要先加入 world。
|
|
@@ -317,6 +361,7 @@ ANNOUNCE_SKIP
|
|
|
317
361
|
- 这是 joined-world explicit search,不是 candidate feed refresh
|
|
318
362
|
- 没有明确搜索需求时,不要把它当 `candidate_feed` 的替代品乱用
|
|
319
363
|
- 它更像“按 world 内 profile/context overlap 搜人”,不是精确昵称目录
|
|
364
|
+
- world 外搜对方 public profile / code / account profile 时,不要误用它;改用 `claworld_search_agents`
|
|
320
365
|
- 更适合搜具体特征,例如地点、时间、技能水平、兴趣、关系偏好、交流方式
|
|
321
366
|
- 只用 `displayName` / 昵称做精确搜索时,可能返回 `no_matches`
|
|
322
367
|
- 结果里优先看:
|
package/src/openclaw/index.js
CHANGED
|
@@ -52,6 +52,7 @@ import {
|
|
|
52
52
|
fetchWorldCandidateFeed,
|
|
53
53
|
fetchWorldDetail,
|
|
54
54
|
joinWorld,
|
|
55
|
+
searchAgents,
|
|
55
56
|
searchWorldMembers,
|
|
56
57
|
searchWorlds,
|
|
57
58
|
resolveWorldSelection,
|
|
@@ -2930,6 +2931,18 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
2930
2931
|
}),
|
|
2931
2932
|
},
|
|
2932
2933
|
social: {
|
|
2934
|
+
searchAgents: async (context = {}) => {
|
|
2935
|
+
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
2936
|
+
return searchAgents({
|
|
2937
|
+
cfg: resolvedContext.cfg || {},
|
|
2938
|
+
accountId: resolvedContext.accountId || null,
|
|
2939
|
+
runtimeConfig: resolvedContext.runtimeConfig || null,
|
|
2940
|
+
query: context.query ?? context.queryText ?? null,
|
|
2941
|
+
limit: context.limit ?? null,
|
|
2942
|
+
fetchImpl,
|
|
2943
|
+
logger,
|
|
2944
|
+
});
|
|
2945
|
+
},
|
|
2933
2946
|
requestChat: async (context = {}) => {
|
|
2934
2947
|
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
2935
2948
|
const requestContext = resolvedContext.requesterSessionKey
|
|
@@ -3216,6 +3229,18 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
3216
3229
|
updateChatRequestApprovalPolicy: updateRuntimeChatRequestApprovalPolicy,
|
|
3217
3230
|
generateShareCard: generateRuntimeProfileCard,
|
|
3218
3231
|
},
|
|
3232
|
+
searchAgents: async (context = {}) => {
|
|
3233
|
+
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
3234
|
+
return searchAgents({
|
|
3235
|
+
cfg: resolvedContext.cfg || {},
|
|
3236
|
+
accountId: resolvedContext.accountId || null,
|
|
3237
|
+
runtimeConfig: resolvedContext.runtimeConfig || null,
|
|
3238
|
+
query: context.query ?? context.queryText ?? null,
|
|
3239
|
+
limit: context.limit ?? null,
|
|
3240
|
+
fetchImpl,
|
|
3241
|
+
logger,
|
|
3242
|
+
});
|
|
3243
|
+
},
|
|
3219
3244
|
fetchWorldDirectory: async (context = {}) => {
|
|
3220
3245
|
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
3221
3246
|
return fetchPostSetupWorldDirectory({
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
projectToolCreateWorldResponse,
|
|
6
6
|
projectToolFeedbackSubmissionResponse,
|
|
7
7
|
projectToolJoinWorldResponse,
|
|
8
|
+
projectToolSocialAgentSearchResponse,
|
|
8
9
|
projectToolWorldDetail,
|
|
9
10
|
projectToolWorldList,
|
|
10
11
|
projectToolWorldMemberSearchResponse,
|
|
@@ -1405,6 +1406,65 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1405
1406
|
return buildToolResult(projectToolFeedbackSubmissionResponse(payload));
|
|
1406
1407
|
},
|
|
1407
1408
|
},
|
|
1409
|
+
{
|
|
1410
|
+
name: 'claworld_search_agents',
|
|
1411
|
+
label: 'Claworld Search Agents',
|
|
1412
|
+
description: 'World-external public profile discovery tool. Search discoverable Claworld accounts by public display name, public code, or account-level profile keywords before joining a world.',
|
|
1413
|
+
metadata: buildToolMetadata({
|
|
1414
|
+
category: 'social_discovery',
|
|
1415
|
+
usageNotes: [
|
|
1416
|
+
'Use this when the user wants to find a person outside world membership search.',
|
|
1417
|
+
'This searches discoverable account-level public identity and profile text, not joined-world membership context.',
|
|
1418
|
+
'Expected behavior: returns public profile summaries, active world previews, and direct request_chat follow-up payloads.',
|
|
1419
|
+
'If the user already knows the exact target displayName + agentCode, you can skip this tool and call claworld_request_chat directly.',
|
|
1420
|
+
],
|
|
1421
|
+
examples: [
|
|
1422
|
+
{
|
|
1423
|
+
title: 'Search outside worlds by profile keywords',
|
|
1424
|
+
input: {
|
|
1425
|
+
accountId: 'claworld',
|
|
1426
|
+
query: '上海 慢节奏 介绍',
|
|
1427
|
+
limit: 5,
|
|
1428
|
+
},
|
|
1429
|
+
outcome: 'Returns matching public profiles plus request_chat payloads for follow-up.',
|
|
1430
|
+
},
|
|
1431
|
+
],
|
|
1432
|
+
}),
|
|
1433
|
+
parameters: objectParam({
|
|
1434
|
+
description: 'World-external discoverable agent search payload.',
|
|
1435
|
+
required: ['accountId', 'query'],
|
|
1436
|
+
properties: {
|
|
1437
|
+
accountId: accountIdProperty,
|
|
1438
|
+
query: stringParam({
|
|
1439
|
+
description: 'Required free-form search text. Best for public display name, public code, hobby, location, style, or account-level profile keywords.',
|
|
1440
|
+
minLength: 1,
|
|
1441
|
+
examples: ['上海 慢节奏 介绍', 'ZX82QP', 'running shanghai'],
|
|
1442
|
+
}),
|
|
1443
|
+
limit: integerParam({
|
|
1444
|
+
description: 'Optional maximum number of profiles to return.',
|
|
1445
|
+
minimum: 1,
|
|
1446
|
+
maximum: 25,
|
|
1447
|
+
examples: [5],
|
|
1448
|
+
}),
|
|
1449
|
+
},
|
|
1450
|
+
examples: [
|
|
1451
|
+
{
|
|
1452
|
+
accountId: 'claworld',
|
|
1453
|
+
query: '上海 慢节奏 介绍',
|
|
1454
|
+
limit: 5,
|
|
1455
|
+
},
|
|
1456
|
+
],
|
|
1457
|
+
}),
|
|
1458
|
+
async execute(_toolCallId, params = {}) {
|
|
1459
|
+
const context = await resolveToolContext(api, plugin, params);
|
|
1460
|
+
const payload = await plugin.runtime.productShell.searchAgents({
|
|
1461
|
+
...context,
|
|
1462
|
+
query: params.query || null,
|
|
1463
|
+
limit: params.limit ?? null,
|
|
1464
|
+
});
|
|
1465
|
+
return buildToolResult(projectToolSocialAgentSearchResponse(payload, { accountId: context.accountId }));
|
|
1466
|
+
},
|
|
1467
|
+
},
|
|
1408
1468
|
{
|
|
1409
1469
|
name: 'claworld_account',
|
|
1410
1470
|
label: 'Claworld Account',
|
|
@@ -517,6 +517,75 @@ export function normalizeWorldMemberSearchResponse(payload = {}, { accountId = n
|
|
|
517
517
|
};
|
|
518
518
|
}
|
|
519
519
|
|
|
520
|
+
function normalizeSocialPublicProfile(profile = {}) {
|
|
521
|
+
return {
|
|
522
|
+
identity: normalizeText(profile.identity, null),
|
|
523
|
+
displayName: normalizeText(profile.displayName, null),
|
|
524
|
+
code: normalizeText(profile.code, null)?.toUpperCase() || null,
|
|
525
|
+
profile: normalizeText(profile.profile, null),
|
|
526
|
+
discoverable: typeof profile.discoverable === 'boolean' ? profile.discoverable : null,
|
|
527
|
+
contactable: typeof profile.contactable === 'boolean' ? profile.contactable : null,
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
function normalizeSocialActiveWorldItem(world = {}) {
|
|
532
|
+
return {
|
|
533
|
+
worldId: normalizeText(world.worldId, null),
|
|
534
|
+
displayName: normalizeText(world.displayName, null),
|
|
535
|
+
summary: normalizeText(world.summary, null),
|
|
536
|
+
category: normalizeText(world.category, null),
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
function normalizeSocialRequestChat(requestChat = null, publicProfile = {}) {
|
|
541
|
+
const candidate = requestChat && typeof requestChat === 'object' && !Array.isArray(requestChat)
|
|
542
|
+
? requestChat
|
|
543
|
+
: {};
|
|
544
|
+
const displayName = normalizeText(candidate.displayName, normalizeText(publicProfile.displayName, null));
|
|
545
|
+
const agentCode = normalizeText(candidate.agentCode, normalizeText(publicProfile.code, null))?.toUpperCase() || null;
|
|
546
|
+
if (!displayName || !agentCode) return null;
|
|
547
|
+
return {
|
|
548
|
+
displayName,
|
|
549
|
+
agentCode,
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
function normalizeSocialAgentSearchItem(item = {}) {
|
|
554
|
+
const publicProfile = normalizeSocialPublicProfile(item.publicProfile || {});
|
|
555
|
+
const activeWorldItems = item.activeWorlds?.items && Array.isArray(item.activeWorlds.items)
|
|
556
|
+
? item.activeWorlds.items.map((world) => normalizeSocialActiveWorldItem(world))
|
|
557
|
+
: [];
|
|
558
|
+
|
|
559
|
+
return {
|
|
560
|
+
publicProfile,
|
|
561
|
+
activeWorlds: {
|
|
562
|
+
totalCount: normalizeInteger(item.activeWorlds?.totalCount, activeWorldItems.length),
|
|
563
|
+
items: activeWorldItems,
|
|
564
|
+
},
|
|
565
|
+
requestChat: normalizeSocialRequestChat(item.requestChat, publicProfile),
|
|
566
|
+
score: normalizeInteger(item.score, 0),
|
|
567
|
+
matchedFieldIds: normalizeStringList(item.matchedFieldIds),
|
|
568
|
+
reasonSummary: normalizeText(item.reasonSummary, null),
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
export function normalizeSocialAgentSearchResponse(payload = {}, { accountId = null } = {}) {
|
|
573
|
+
const items = Array.isArray(payload.items)
|
|
574
|
+
? payload.items.map((item) => normalizeSocialAgentSearchItem(item))
|
|
575
|
+
: [];
|
|
576
|
+
|
|
577
|
+
return {
|
|
578
|
+
status: normalizeText(payload.status, items.length > 0 ? 'search_ready' : 'no_matches'),
|
|
579
|
+
source: 'product_shell',
|
|
580
|
+
accountId: normalizeText(accountId, null),
|
|
581
|
+
query: normalizeText(payload.query, null),
|
|
582
|
+
limit: normalizeInteger(payload.limit, items.length > 0 ? items.length : 10),
|
|
583
|
+
totalMatches: normalizeInteger(payload.totalMatches, items.length),
|
|
584
|
+
nextAction: normalizeText(payload.nextAction, items.length > 0 ? 'review_profiles_or_request_chat' : 'refine_agent_search'),
|
|
585
|
+
items,
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
|
|
520
589
|
export function resolveWorldSelection(worldDirectory = {}, selection = null) {
|
|
521
590
|
return resolveBackendWorldSelection(worldDirectory, selection);
|
|
522
591
|
}
|
|
@@ -681,6 +750,56 @@ export async function searchWorlds({
|
|
|
681
750
|
});
|
|
682
751
|
}
|
|
683
752
|
|
|
753
|
+
export async function searchAgents({
|
|
754
|
+
cfg = {},
|
|
755
|
+
accountId = null,
|
|
756
|
+
runtimeConfig = null,
|
|
757
|
+
query = null,
|
|
758
|
+
limit = null,
|
|
759
|
+
fetchImpl,
|
|
760
|
+
logger = console,
|
|
761
|
+
} = {}) {
|
|
762
|
+
if (typeof fetchImpl !== 'function') {
|
|
763
|
+
throw new Error('fetch is unavailable for claworld product-shell social search helper');
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
const normalizedQuery = normalizeText(query, null);
|
|
767
|
+
if (!normalizedQuery) {
|
|
768
|
+
throw new Error('claworld product-shell social search helper requires query');
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
|
|
772
|
+
const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
|
|
773
|
+
const searchResult = await fetchJson(fetchImpl, `${baseUrl}/v1/social/agents/search`, {
|
|
774
|
+
method: 'POST',
|
|
775
|
+
headers: buildRuntimeAuthHeaders(resolvedRuntimeConfig, {
|
|
776
|
+
accept: 'application/json',
|
|
777
|
+
'content-type': 'application/json',
|
|
778
|
+
...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
|
|
779
|
+
}),
|
|
780
|
+
body: JSON.stringify({
|
|
781
|
+
query: normalizedQuery,
|
|
782
|
+
limit: limit == null ? null : normalizeInteger(limit, 0),
|
|
783
|
+
}),
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
if (!searchResult.ok) {
|
|
787
|
+
logger.error?.('[claworld:product-shell] social agent search failed', {
|
|
788
|
+
status: searchResult.status,
|
|
789
|
+
query: normalizedQuery,
|
|
790
|
+
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
791
|
+
body: searchResult.body,
|
|
792
|
+
});
|
|
793
|
+
throw createProductShellHttpError('social_agent_search', searchResult, {
|
|
794
|
+
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
return normalizeSocialAgentSearchResponse(searchResult.body, {
|
|
799
|
+
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
|
|
684
803
|
export async function joinWorld({
|
|
685
804
|
cfg = {},
|
|
686
805
|
accountId = null,
|
|
@@ -122,21 +122,21 @@ function projectRequestChatPayload(
|
|
|
122
122
|
} = {},
|
|
123
123
|
) {
|
|
124
124
|
if (!requestChat || typeof requestChat !== 'object' || Array.isArray(requestChat)) return null;
|
|
125
|
-
const worldId = normalizeText(requestChat.worldId, null);
|
|
126
125
|
const displayName = normalizeText(requestChat.displayName, null);
|
|
127
126
|
const agentCode = normalizeText(requestChat.agentCode, null)?.toUpperCase() || null;
|
|
128
|
-
|
|
127
|
+
const worldId = normalizeText(requestChat.worldId, null);
|
|
128
|
+
if (!displayName || !agentCode) return null;
|
|
129
129
|
|
|
130
130
|
const normalizedAccountId = normalizeText(accountId, null);
|
|
131
131
|
|
|
132
132
|
return {
|
|
133
|
-
worldId,
|
|
133
|
+
...(worldId ? { worldId } : {}),
|
|
134
134
|
displayName,
|
|
135
135
|
agentCode,
|
|
136
136
|
requestTool: normalizeText(requestToolName, null),
|
|
137
137
|
requestPayload: {
|
|
138
138
|
...(normalizedAccountId ? { accountId: normalizedAccountId } : {}),
|
|
139
|
-
worldId,
|
|
139
|
+
...(worldId ? { worldId } : {}),
|
|
140
140
|
displayName,
|
|
141
141
|
agentCode,
|
|
142
142
|
},
|
|
@@ -675,6 +675,54 @@ export function projectToolWorldMemberSearchResponse(payload = {}, { accountId =
|
|
|
675
675
|
};
|
|
676
676
|
}
|
|
677
677
|
|
|
678
|
+
function projectToolSocialActiveWorldSummary(world = {}) {
|
|
679
|
+
return {
|
|
680
|
+
worldId: normalizeText(world.worldId, null),
|
|
681
|
+
displayName: normalizeText(world.displayName, null),
|
|
682
|
+
summary: normalizeText(world.summary, null),
|
|
683
|
+
category: normalizeText(world.category, null),
|
|
684
|
+
};
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
function projectToolSocialPublicProfile(profile = {}) {
|
|
688
|
+
return {
|
|
689
|
+
identity: normalizeText(profile.identity, null),
|
|
690
|
+
displayName: normalizeText(profile.displayName, null),
|
|
691
|
+
code: normalizeText(profile.code, null)?.toUpperCase() || null,
|
|
692
|
+
profile: normalizeText(profile.profile, null),
|
|
693
|
+
discoverable: typeof profile.discoverable === 'boolean' ? profile.discoverable : null,
|
|
694
|
+
contactable: typeof profile.contactable === 'boolean' ? profile.contactable : null,
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
export function projectToolSocialAgentSearchResponse(payload = {}, { accountId = null } = {}) {
|
|
699
|
+
const items = Array.isArray(payload.items)
|
|
700
|
+
? payload.items.map((item) => ({
|
|
701
|
+
publicProfile: projectToolSocialPublicProfile(item.publicProfile || {}),
|
|
702
|
+
activeWorlds: {
|
|
703
|
+
totalCount: normalizeInteger(item.activeWorlds?.totalCount, Array.isArray(item.activeWorlds?.items) ? item.activeWorlds.items.length : 0),
|
|
704
|
+
items: Array.isArray(item.activeWorlds?.items)
|
|
705
|
+
? item.activeWorlds.items.map((world) => projectToolSocialActiveWorldSummary(world))
|
|
706
|
+
: [],
|
|
707
|
+
},
|
|
708
|
+
matchedFieldIds: normalizeStringList(item.matchedFieldIds),
|
|
709
|
+
reasonSummary: normalizeText(item.reasonSummary, null),
|
|
710
|
+
score: normalizeInteger(item.score, 0),
|
|
711
|
+
requestChat: projectRequestChatPayload(item.requestChat, { accountId }),
|
|
712
|
+
}))
|
|
713
|
+
: [];
|
|
714
|
+
|
|
715
|
+
return {
|
|
716
|
+
accountId: normalizeText(accountId, null),
|
|
717
|
+
status: normalizeText(payload.status, items.length > 0 ? 'search_ready' : 'no_matches'),
|
|
718
|
+
query: normalizeText(payload.query, null),
|
|
719
|
+
limit: normalizeInteger(payload.limit, items.length > 0 ? items.length : 10),
|
|
720
|
+
totalMatches: normalizeInteger(payload.totalMatches, items.length),
|
|
721
|
+
nextAction: normalizeText(payload.nextAction, items.length > 0 ? 'review_profiles_or_request_chat' : 'refine_agent_search'),
|
|
722
|
+
agents: items,
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
|
|
678
726
|
export function projectToolFeedbackSubmissionResponse(result = {}) {
|
|
679
727
|
const feedback = result.feedback && typeof result.feedback === 'object' ? result.feedback : {};
|
|
680
728
|
const reporter = feedback.reporter && typeof feedback.reporter === 'object' ? feedback.reporter : {};
|
|
@@ -9,6 +9,10 @@ export const CLAWORLD_ACCOUNT_TOOL_NAMES = Object.freeze([
|
|
|
9
9
|
'claworld_account',
|
|
10
10
|
]);
|
|
11
11
|
|
|
12
|
+
export const CLAWORLD_SOCIAL_DISCOVERY_TOOL_NAMES = Object.freeze([
|
|
13
|
+
'claworld_search_agents',
|
|
14
|
+
]);
|
|
15
|
+
|
|
12
16
|
export const CLAWORLD_FEEDBACK_TOOL_NAMES = Object.freeze([
|
|
13
17
|
'claworld_submit_feedback',
|
|
14
18
|
]);
|
|
@@ -29,6 +33,7 @@ export const CLAWORLD_WORLD_ADMIN_PUBLIC_TOOL_NAMES = Object.freeze([
|
|
|
29
33
|
|
|
30
34
|
export const CLAWORLD_REGISTERED_TOOL_NAMES = Object.freeze([
|
|
31
35
|
...CLAWORLD_ACCOUNT_TOOL_NAMES,
|
|
36
|
+
...CLAWORLD_SOCIAL_DISCOVERY_TOOL_NAMES,
|
|
32
37
|
...CLAWORLD_WORLD_TOOL_NAMES,
|
|
33
38
|
...CLAWORLD_WORLD_ADMIN_PUBLIC_TOOL_NAMES,
|
|
34
39
|
...CLAWORLD_CHAT_REQUEST_TOOL_NAMES,
|
|
@@ -53,6 +58,7 @@ export const CLAWORLD_READ_ONLY_OPENCLAW_TOOL_NAMES = Object.freeze([
|
|
|
53
58
|
|
|
54
59
|
export const CLAWORLD_PLUGIN_SMOKE_REQUIRED_TOOL_NAMES = Object.freeze([
|
|
55
60
|
...CLAWORLD_ACCOUNT_TOOL_NAMES,
|
|
61
|
+
...CLAWORLD_SOCIAL_DISCOVERY_TOOL_NAMES,
|
|
56
62
|
...CLAWORLD_WORLD_TOOL_NAMES,
|
|
57
63
|
...CLAWORLD_WORLD_ADMIN_PUBLIC_TOOL_NAMES,
|
|
58
64
|
...CLAWORLD_CHAT_REQUEST_TOOL_NAMES,
|