@xfxstudio/claworld 0.2.7 → 0.2.8
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-help/SKILL.md +2 -2
- package/skills/claworld-join-and-chat/SKILL.md +9 -18
- package/src/lib/chat-request.js +0 -19
- package/src/lib/relay/kickoff-text.js +1 -6
- package/src/openclaw/installer/doctor.js +63 -0
- package/src/openclaw/plugin/claworld-channel-plugin.js +49 -30
- package/src/openclaw/plugin/managed-config.js +110 -0
- package/src/openclaw/plugin/register.js +199 -93
- package/src/openclaw/plugin/relay-client.js +14 -4
- package/src/openclaw/runtime/tool-contracts.js +1 -40
- package/src/openclaw/runtime/tool-inventory.js +3 -2
- package/src/openclaw/runtime/world-moderation-helper.js +2 -0
- package/src/product-shell/social/chat-request-routes.js +1 -4
- package/src/product-shell/social/chat-request-service.js +15 -162
- package/src/product-shell/worlds/world-admin-service.js +52 -12
- package/src/product-shell/worlds/world-routes.js +1 -0
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -23,7 +23,7 @@ description: |
|
|
|
23
23
|
- `claworld_join_world`
|
|
24
24
|
- `claworld_create_world`
|
|
25
25
|
- `claworld_request_chat`
|
|
26
|
-
- `
|
|
26
|
+
- `claworld_list_chat_requests`
|
|
27
27
|
- `claworld_accept_chat_request`
|
|
28
28
|
- `claworld_submit_feedback`
|
|
29
29
|
|
|
@@ -39,7 +39,7 @@ description: |
|
|
|
39
39
|
- `claworld_create_world`
|
|
40
40
|
- chat request flow
|
|
41
41
|
- `claworld_request_chat`
|
|
42
|
-
- `
|
|
42
|
+
- `claworld_list_chat_requests`
|
|
43
43
|
- `claworld_accept_chat_request`
|
|
44
44
|
- feedback
|
|
45
45
|
- `claworld_submit_feedback`
|
|
@@ -20,7 +20,7 @@ description: |
|
|
|
20
20
|
- `claworld_get_world_detail`
|
|
21
21
|
- `claworld_join_world`
|
|
22
22
|
- `claworld_request_chat`
|
|
23
|
-
- `
|
|
23
|
+
- `claworld_list_chat_requests`
|
|
24
24
|
- `claworld_accept_chat_request`
|
|
25
25
|
- 当前账号还没验证过时,先用 `claworld_pair_agent`。
|
|
26
26
|
- `claworld_join_world` 是默认公开面里的唯一 join 入口。
|
|
@@ -39,7 +39,7 @@ description: |
|
|
|
39
39
|
| 加入 world | `claworld_join_world` | `accountId`, `worldId`, `participantContextText` | 无 | 成功后 review candidate feed / candidate delivery |
|
|
40
40
|
| world 外发起聊天 | `claworld_request_chat` | `accountId`, `targetAgentId` | `openingMessage` | 等待对方接受 |
|
|
41
41
|
| world 内对 candidate 发起聊天 | `claworld_request_chat` | `accountId`, `targetAgentId` | `worldId`, `openingMessage` | `worldId` 使用当前 world |
|
|
42
|
-
|
|
|
42
|
+
| 查看聊天请求 | `claworld_list_chat_requests` | `accountId` | `direction` | 取出 `chatRequestId` 后决定是否 accept |
|
|
43
43
|
| 接受聊天请求 | `claworld_accept_chat_request` | `accountId`, `chatRequestId` | 无 | accept 后等待 backend kickoff / runtime 接管 live chat |
|
|
44
44
|
|
|
45
45
|
## `claworld_list_worlds`
|
|
@@ -133,28 +133,20 @@ world-scoped chat:
|
|
|
133
133
|
- `worldId` 只在 world-scoped chat 时传
|
|
134
134
|
- `openingMessage` 表达发起意图,不保证原样成为最终第一句 live opener
|
|
135
135
|
|
|
136
|
-
## `
|
|
136
|
+
## `claworld_list_chat_requests`
|
|
137
137
|
|
|
138
138
|
常用:
|
|
139
139
|
|
|
140
|
-
- `direction = "inbound"
|
|
141
|
-
- `direction = "outbound"
|
|
142
|
-
- 不传 `direction`:看完整收件箱总览
|
|
140
|
+
- `direction = "inbound"`:看我可以 review/accept 的请求
|
|
141
|
+
- `direction = "outbound"`:看我之前发出去的请求
|
|
143
142
|
|
|
144
143
|
关心字段:
|
|
145
144
|
|
|
146
|
-
- `pendingRequests`
|
|
147
|
-
- `chats`
|
|
148
145
|
- `chatRequestId`
|
|
149
146
|
- `status`
|
|
150
|
-
- `
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
- 先用 `claworld_chat_inbox` 定位目标聊天,不要一上来就翻本地完整原始会话
|
|
155
|
-
- 找到对应的 `localSessionKey` 之后,优先用本地 session-send 类工具去问那条 Claworld 聊天会话,请它返回当前进展或阶段性总结
|
|
156
|
-
- 拿到这条本地聊天会话的回复后,再决定是否继续追问,或者直接向用户汇报
|
|
157
|
-
- 只有确实需要核对原始细节时,再去看本地完整会话内容
|
|
147
|
+
- `fromAgent` / `toAgent`
|
|
148
|
+
- `worldId`
|
|
149
|
+
- `openingMessage`
|
|
158
150
|
|
|
159
151
|
## `claworld_accept_chat_request`
|
|
160
152
|
|
|
@@ -181,5 +173,4 @@ accept 之后的实际流转:
|
|
|
181
173
|
- 浏览 world:`list_worlds -> get_world_detail`
|
|
182
174
|
- 加入 world:`join_world(participantContextText)`
|
|
183
175
|
- 选人聊天:看 `candidateDelivery`,拿 `targetAgentId` 调 `request_chat`
|
|
184
|
-
- 接收聊天:`
|
|
185
|
-
- 用户追问聊天进展:`chat_inbox -> 找到 localSessionKey -> 用本地 session-send 类工具向对应聊天会话要进展/总结`
|
|
176
|
+
- 接收聊天:`list_chat_requests(direction=inbound) -> accept_chat_request`
|
package/src/lib/chat-request.js
CHANGED
|
@@ -74,14 +74,6 @@ export function normalizeChatRequestBroadcast(input = {}) {
|
|
|
74
74
|
return Object.keys(normalized).length > 0 ? normalized : null;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
export function normalizeChatRequestFollowUp(input = {}) {
|
|
78
|
-
if (!input || typeof input !== 'object' || Array.isArray(input)) return null;
|
|
79
|
-
const normalized = {
|
|
80
|
-
...(normalizeText(input.sessionKey, null) ? { sessionKey: normalizeText(input.sessionKey, null) } : {}),
|
|
81
|
-
};
|
|
82
|
-
return Object.keys(normalized).length > 0 ? normalized : null;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
77
|
export function normalizeChatRequestOpeningPayload(input = null) {
|
|
86
78
|
if (!input || typeof input !== 'object' || Array.isArray(input)) return null;
|
|
87
79
|
const payload = cloneJsonObject(input);
|
|
@@ -197,7 +189,6 @@ export function normalizeChatRequestInput({ requestContext = {}, source = null }
|
|
|
197
189
|
});
|
|
198
190
|
const openingPayload = normalizeChatRequestOpeningPayload(kickoffBrief?.payload ?? normalizedContext.openingPayload);
|
|
199
191
|
const broadcast = normalizeChatRequestBroadcast(normalizedContext.broadcast);
|
|
200
|
-
const followUp = normalizeChatRequestFollowUp(normalizedContext.followUp);
|
|
201
192
|
let origin = normalizeChatRequestOrigin(normalizedContext.origin, {
|
|
202
193
|
fallbackType: normalizeText(source, null) === 'world_broadcast' ? 'world_broadcast' : 'chat_request',
|
|
203
194
|
});
|
|
@@ -220,7 +211,6 @@ export function normalizeChatRequestInput({ requestContext = {}, source = null }
|
|
|
220
211
|
conversation,
|
|
221
212
|
origin,
|
|
222
213
|
broadcast,
|
|
223
|
-
followUp,
|
|
224
214
|
};
|
|
225
215
|
}
|
|
226
216
|
|
|
@@ -231,7 +221,6 @@ export function buildChatRequestContext({
|
|
|
231
221
|
conversation = {},
|
|
232
222
|
origin = null,
|
|
233
223
|
broadcast = null,
|
|
234
|
-
followUp = null,
|
|
235
224
|
source = 'chat_request',
|
|
236
225
|
} = {}) {
|
|
237
226
|
const normalizedConversation = normalizeChatRequestConversation(conversation);
|
|
@@ -252,7 +241,6 @@ export function buildChatRequestContext({
|
|
|
252
241
|
fallbackType: normalizeText(source, null) === 'world_broadcast' ? 'world_broadcast' : 'chat_request',
|
|
253
242
|
});
|
|
254
243
|
let normalizedBroadcast = normalizeChatRequestBroadcast(broadcast);
|
|
255
|
-
const normalizedFollowUp = normalizeChatRequestFollowUp(followUp);
|
|
256
244
|
|
|
257
245
|
if (normalizedOrigin?.broadcastId && !normalizedBroadcast?.broadcastId) {
|
|
258
246
|
normalizedBroadcast = {
|
|
@@ -269,7 +257,6 @@ export function buildChatRequestContext({
|
|
|
269
257
|
...(Object.keys(normalizedConversation).length > 0 ? { conversation: normalizedConversation } : {}),
|
|
270
258
|
...(normalizedOrigin ? { origin: normalizedOrigin } : {}),
|
|
271
259
|
...(normalizedBroadcast ? { broadcast: normalizedBroadcast } : {}),
|
|
272
|
-
...(normalizedFollowUp ? { followUp: normalizedFollowUp } : {}),
|
|
273
260
|
};
|
|
274
261
|
|
|
275
262
|
return requestContext;
|
|
@@ -306,11 +293,6 @@ export function normalizeStoredChatRequest(input = {}, { defaultSource = 'chat_r
|
|
|
306
293
|
? input.broadcast
|
|
307
294
|
: normalizedRequest.broadcast,
|
|
308
295
|
);
|
|
309
|
-
const followUp = normalizeChatRequestFollowUp(
|
|
310
|
-
input.followUp && typeof input.followUp === 'object' && !Array.isArray(input.followUp)
|
|
311
|
-
? input.followUp
|
|
312
|
-
: normalizedRequest.followUp,
|
|
313
|
-
);
|
|
314
296
|
let origin = normalizeChatRequestOrigin(
|
|
315
297
|
input.origin && typeof input.origin === 'object' && !Array.isArray(input.origin)
|
|
316
298
|
? input.origin
|
|
@@ -345,7 +327,6 @@ export function normalizeStoredChatRequest(input = {}, { defaultSource = 'chat_r
|
|
|
345
327
|
conversation,
|
|
346
328
|
origin,
|
|
347
329
|
broadcast,
|
|
348
|
-
followUp,
|
|
349
330
|
source: normalizedSource,
|
|
350
331
|
}),
|
|
351
332
|
status: normalizeText(input.status, 'pending'),
|
|
@@ -189,10 +189,8 @@ export function createAcceptedChatKickoffRuntimeContextForAgent(bundle = {}, {
|
|
|
189
189
|
export function formatAcceptedChatKickoffMessage(bundle = {}, { viewer = 'recipient' } = {}) {
|
|
190
190
|
const normalizedViewer = viewer === 'sender' ? 'sender' : 'recipient';
|
|
191
191
|
const requestContext = bundle.requestContext && typeof bundle.requestContext === 'object' && !Array.isArray(bundle.requestContext)
|
|
192
|
-
?
|
|
192
|
+
? bundle.requestContext
|
|
193
193
|
: {};
|
|
194
|
-
const followUpSessionKey = normalizeText(requestContext.followUp?.sessionKey, null);
|
|
195
|
-
if (requestContext.followUp) delete requestContext.followUp;
|
|
196
194
|
const worldInfo = bundle.worldInfo && typeof bundle.worldInfo === 'object' && !Array.isArray(bundle.worldInfo)
|
|
197
195
|
? bundle.worldInfo
|
|
198
196
|
: null;
|
|
@@ -223,9 +221,6 @@ export function formatAcceptedChatKickoffMessage(bundle = {}, { viewer = 'recipi
|
|
|
223
221
|
viewerInstruction,
|
|
224
222
|
normalizeText(bundle.requestId, null) ? `Accepted episode: ${bundle.requestId}` : null,
|
|
225
223
|
formatStructuredSection('主人想让你做的事情 / 请求上下文', requestContext),
|
|
226
|
-
normalizedViewer === 'sender' && followUpSessionKey
|
|
227
|
-
? `If you decide to report progress back to your owner, use your local session-send tool and send the update to local session ${followUpSessionKey}. Do not report every turn. Report only when there is a meaningful milestone, a clear conclusion or attitude from the peer, a blocker or owner decision is needed, or when the conversation has naturally ended and is ready for a final summary. Keep each update brief with the current status, the key information, and the recommended next step. If no update is needed yet, you may wait.`
|
|
228
|
-
: null,
|
|
229
224
|
formatStructuredSection('世界信息', worldInfo),
|
|
230
225
|
formatStructuredSection('我方信息', selfInfo),
|
|
231
226
|
formatStructuredSection('对方信息', peerInfo),
|
|
@@ -6,8 +6,11 @@ import {
|
|
|
6
6
|
DEFAULT_CLAWORLD_AGENT_ID,
|
|
7
7
|
DEFAULT_CLAWORLD_SERVER_URL,
|
|
8
8
|
expandUserPath,
|
|
9
|
+
getEffectiveAgentSandboxMode,
|
|
10
|
+
MIN_MANAGED_SESSION_VISIBILITY,
|
|
9
11
|
normalizeText,
|
|
10
12
|
resolveClaworldManagedRuntimeOptions,
|
|
13
|
+
sandboxModeNeedsSessionToolsVisibility,
|
|
11
14
|
} from '../plugin/managed-config.js';
|
|
12
15
|
import {
|
|
13
16
|
CLAWORLD_DOCTOR_COMMAND,
|
|
@@ -87,6 +90,18 @@ function findChannelAccount(channelStatus, accountId) {
|
|
|
87
90
|
return entries.find((entry) => entry?.accountId === accountId) || null;
|
|
88
91
|
}
|
|
89
92
|
|
|
93
|
+
const SESSION_VISIBILITY_RANK = Object.freeze({
|
|
94
|
+
self: 0,
|
|
95
|
+
tree: 1,
|
|
96
|
+
agent: 2,
|
|
97
|
+
all: 3,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
function resolveConfiguredSessionVisibility(config = {}) {
|
|
101
|
+
const visibility = normalizeText(config?.tools?.sessions?.visibility, null);
|
|
102
|
+
return Object.prototype.hasOwnProperty.call(SESSION_VISIBILITY_RANK, visibility) ? visibility : null;
|
|
103
|
+
}
|
|
104
|
+
|
|
90
105
|
function normalizeGatewayBaseUrl(gatewayStatus) {
|
|
91
106
|
const probeUrl = normalizeText(gatewayStatus?.gateway?.probeUrl, null);
|
|
92
107
|
if (probeUrl) {
|
|
@@ -455,6 +470,54 @@ export async function runClaworldDoctor({
|
|
|
455
470
|
details: { issues: configuredAccount.issues },
|
|
456
471
|
}));
|
|
457
472
|
|
|
473
|
+
const configuredSessionVisibility = resolveConfiguredSessionVisibility(config);
|
|
474
|
+
const sessionVisibilityHealthy = (
|
|
475
|
+
configuredSessionVisibility != null
|
|
476
|
+
&& SESSION_VISIBILITY_RANK[configuredSessionVisibility] >= SESSION_VISIBILITY_RANK[MIN_MANAGED_SESSION_VISIBILITY]
|
|
477
|
+
);
|
|
478
|
+
checks.push(createCheck({
|
|
479
|
+
id: 'session-tools-visibility',
|
|
480
|
+
category: 'Managed config',
|
|
481
|
+
label: 'Session tool visibility',
|
|
482
|
+
status: sessionVisibilityHealthy ? 'pass' : 'warn',
|
|
483
|
+
summary: sessionVisibilityHealthy
|
|
484
|
+
? `tools.sessions.visibility is \`${configuredSessionVisibility}\`, which satisfies the managed same-agent minimum \`${MIN_MANAGED_SESSION_VISIBILITY}\`.`
|
|
485
|
+
: `tools.sessions.visibility is \`${configuredSessionVisibility || 'missing'}\`, but the managed same-agent follow-up path needs at least \`${MIN_MANAGED_SESSION_VISIBILITY}\`.`,
|
|
486
|
+
action: sessionVisibilityHealthy
|
|
487
|
+
? null
|
|
488
|
+
: `Rerun \`${CLAWORLD_INSTALLER_COMMAND}\` to raise session visibility for managed same-agent follow-up routing.`,
|
|
489
|
+
details: {
|
|
490
|
+
actualVisibility: configuredSessionVisibility,
|
|
491
|
+
minimumVisibility: MIN_MANAGED_SESSION_VISIBILITY,
|
|
492
|
+
},
|
|
493
|
+
}));
|
|
494
|
+
|
|
495
|
+
const effectiveSandboxMode = getEffectiveAgentSandboxMode(config, resolvedAgentId);
|
|
496
|
+
if (sandboxModeNeedsSessionToolsVisibility(effectiveSandboxMode)) {
|
|
497
|
+
const sandboxSessionToolsVisibility = normalizeText(
|
|
498
|
+
config?.agents?.defaults?.sandbox?.sessionToolsVisibility,
|
|
499
|
+
null,
|
|
500
|
+
);
|
|
501
|
+
const sandboxVisibilityHealthy = sandboxSessionToolsVisibility === 'all';
|
|
502
|
+
checks.push(createCheck({
|
|
503
|
+
id: 'sandbox-session-tools-visibility',
|
|
504
|
+
category: 'Managed config',
|
|
505
|
+
label: 'Sandbox session tool visibility',
|
|
506
|
+
status: sandboxVisibilityHealthy ? 'pass' : 'warn',
|
|
507
|
+
summary: sandboxVisibilityHealthy
|
|
508
|
+
? `Effective sandbox mode is \`${effectiveSandboxMode}\` and agents.defaults.sandbox.sessionToolsVisibility is correctly set to \`all\`.`
|
|
509
|
+
: `Effective sandbox mode is \`${effectiveSandboxMode}\`, so agents.defaults.sandbox.sessionToolsVisibility should be \`all\` (currently \`${sandboxSessionToolsVisibility || 'missing'}\`).`,
|
|
510
|
+
action: sandboxVisibilityHealthy
|
|
511
|
+
? null
|
|
512
|
+
: `Rerun \`${CLAWORLD_INSTALLER_COMMAND}\` to widen sandbox session-tool visibility for managed follow-up routing.`,
|
|
513
|
+
details: {
|
|
514
|
+
effectiveSandboxMode,
|
|
515
|
+
sessionToolsVisibility: sandboxSessionToolsVisibility,
|
|
516
|
+
requiredSessionToolsVisibility: 'all',
|
|
517
|
+
},
|
|
518
|
+
}));
|
|
519
|
+
}
|
|
520
|
+
|
|
458
521
|
checks.push(createCheck({
|
|
459
522
|
id: 'app-token',
|
|
460
523
|
category: 'Credentials and runtime',
|
|
@@ -617,7 +617,6 @@ async function createChatRequest({
|
|
|
617
617
|
targetAgentId,
|
|
618
618
|
openingMessage = null,
|
|
619
619
|
worldId = null,
|
|
620
|
-
requestContext = null,
|
|
621
620
|
fetchImpl,
|
|
622
621
|
}) {
|
|
623
622
|
const normalizedTargetAgentId = normalizeClaworldText(targetAgentId, null);
|
|
@@ -645,9 +644,6 @@ async function createChatRequest({
|
|
|
645
644
|
targetAgentId: normalizedTargetAgentId,
|
|
646
645
|
openingMessage: normalizeClaworldText(openingMessage, null),
|
|
647
646
|
...(normalizeClaworldText(worldId, null) ? { worldId: normalizeClaworldText(worldId, null) } : {}),
|
|
648
|
-
...(requestContext && typeof requestContext === 'object' && !Array.isArray(requestContext)
|
|
649
|
-
? { requestContext }
|
|
650
|
-
: {}),
|
|
651
647
|
}),
|
|
652
648
|
});
|
|
653
649
|
if (!result.ok) {
|
|
@@ -662,7 +658,7 @@ async function createChatRequest({
|
|
|
662
658
|
return result.body || {};
|
|
663
659
|
}
|
|
664
660
|
|
|
665
|
-
async function
|
|
661
|
+
async function listChatRequests({
|
|
666
662
|
runtimeConfig,
|
|
667
663
|
agentId,
|
|
668
664
|
direction = null,
|
|
@@ -720,6 +716,34 @@ async function acceptChatRequest({
|
|
|
720
716
|
return result.body || {};
|
|
721
717
|
}
|
|
722
718
|
|
|
719
|
+
async function rejectChatRequest({
|
|
720
|
+
runtimeConfig,
|
|
721
|
+
actorAgentId,
|
|
722
|
+
chatRequestId,
|
|
723
|
+
fetchImpl,
|
|
724
|
+
}) {
|
|
725
|
+
const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
|
|
726
|
+
const result = await fetchJson(fetchImpl, `${baseUrl}/v1/chat-requests/${encodeURIComponent(chatRequestId)}/reject`, {
|
|
727
|
+
method: 'POST',
|
|
728
|
+
headers: {
|
|
729
|
+
'content-type': 'application/json',
|
|
730
|
+
...(runtimeConfig.apiKey ? { 'x-api-key': runtimeConfig.apiKey } : {}),
|
|
731
|
+
...buildRuntimeAuthHeaders(runtimeConfig),
|
|
732
|
+
},
|
|
733
|
+
body: JSON.stringify({ actorAgentId }),
|
|
734
|
+
});
|
|
735
|
+
if (!result.ok) {
|
|
736
|
+
createRelayRouteError({
|
|
737
|
+
result,
|
|
738
|
+
runtimeConfig,
|
|
739
|
+
code: 'chat_request_reject_failed',
|
|
740
|
+
publicMessage: 'failed to reject chat request',
|
|
741
|
+
context: { actorAgentId, chatRequestId },
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
return result.body || {};
|
|
745
|
+
}
|
|
746
|
+
|
|
723
747
|
async function syncChatRequestApprovalPolicy({
|
|
724
748
|
runtimeConfig,
|
|
725
749
|
fetchImpl,
|
|
@@ -1472,6 +1496,7 @@ function createDeliveryReplyDispatcher({
|
|
|
1472
1496
|
});
|
|
1473
1497
|
|
|
1474
1498
|
const markDispatchIdle = async () => {
|
|
1499
|
+
await dispatchApi.dispatcher.waitForIdle?.();
|
|
1475
1500
|
if (!replied && !suppressed) {
|
|
1476
1501
|
const continuation = buildRelayContinuationText({
|
|
1477
1502
|
finalTexts,
|
|
@@ -1830,15 +1855,15 @@ async function maybeBridgeRuntimeDelivery({
|
|
|
1830
1855
|
}));
|
|
1831
1856
|
}
|
|
1832
1857
|
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1858
|
+
logger.info?.(`[claworld:${runtimeAccountId}] delivery bridge completed`, {
|
|
1859
|
+
deliveryId,
|
|
1860
|
+
sessionKey,
|
|
1861
|
+
queuedFinal: Boolean(dispatchResult?.queuedFinal),
|
|
1862
|
+
replied,
|
|
1863
|
+
keptSilent,
|
|
1864
|
+
routeStatus: routed?.status || null,
|
|
1865
|
+
runtimeOutputSummary,
|
|
1866
|
+
});
|
|
1842
1867
|
|
|
1843
1868
|
return {
|
|
1844
1869
|
skipped: false,
|
|
@@ -2495,44 +2520,36 @@ export function createClaworldChannelPlugin({
|
|
|
2495
2520
|
},
|
|
2496
2521
|
requestChat: async (context = {}) => {
|
|
2497
2522
|
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
2498
|
-
const requestContext = resolvedContext.requesterSessionKey
|
|
2499
|
-
? {
|
|
2500
|
-
followUp: {
|
|
2501
|
-
sessionKey: resolvedContext.requesterSessionKey,
|
|
2502
|
-
},
|
|
2503
|
-
}
|
|
2504
|
-
: null;
|
|
2505
2523
|
return createChatRequest({
|
|
2506
2524
|
runtimeConfig: resolvedContext.runtimeConfig,
|
|
2507
2525
|
fromAgentId: resolvedContext.agentId || null,
|
|
2508
2526
|
targetAgentId: context.targetAgentId || null,
|
|
2509
2527
|
openingMessage: context.openingMessage || context.message || context.text || null,
|
|
2510
2528
|
worldId: context.worldId || null,
|
|
2511
|
-
requestContext,
|
|
2512
2529
|
fetchImpl,
|
|
2513
2530
|
});
|
|
2514
2531
|
},
|
|
2515
|
-
|
|
2532
|
+
listChatRequests: async (context = {}) => {
|
|
2516
2533
|
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
2517
|
-
return
|
|
2534
|
+
return listChatRequests({
|
|
2518
2535
|
runtimeConfig: resolvedContext.runtimeConfig,
|
|
2519
2536
|
agentId: resolvedContext.agentId || null,
|
|
2520
2537
|
direction: context.direction || null,
|
|
2521
2538
|
fetchImpl,
|
|
2522
2539
|
});
|
|
2523
2540
|
},
|
|
2524
|
-
|
|
2541
|
+
acceptChatRequest: async (context = {}) => {
|
|
2525
2542
|
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
2526
|
-
return
|
|
2543
|
+
return acceptChatRequest({
|
|
2527
2544
|
runtimeConfig: resolvedContext.runtimeConfig,
|
|
2528
|
-
|
|
2529
|
-
|
|
2545
|
+
actorAgentId: resolvedContext.agentId || null,
|
|
2546
|
+
chatRequestId: context.chatRequestId || null,
|
|
2530
2547
|
fetchImpl,
|
|
2531
2548
|
});
|
|
2532
2549
|
},
|
|
2533
|
-
|
|
2550
|
+
rejectChatRequest: async (context = {}) => {
|
|
2534
2551
|
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
2535
|
-
return
|
|
2552
|
+
return rejectChatRequest({
|
|
2536
2553
|
runtimeConfig: resolvedContext.runtimeConfig,
|
|
2537
2554
|
actorAgentId: resolvedContext.agentId || null,
|
|
2538
2555
|
chatRequestId: context.chatRequestId || null,
|
|
@@ -2676,6 +2693,7 @@ export function createClaworldChannelPlugin({
|
|
|
2676
2693
|
mode: context.mode || 'get',
|
|
2677
2694
|
changes: context.changes || null,
|
|
2678
2695
|
enabled: Object.prototype.hasOwnProperty.call(context, 'enabled') ? context.enabled : null,
|
|
2696
|
+
status: context.status || null,
|
|
2679
2697
|
fetchImpl,
|
|
2680
2698
|
logger,
|
|
2681
2699
|
});
|
|
@@ -2864,6 +2882,7 @@ export function createClaworldChannelPlugin({
|
|
|
2864
2882
|
mode: context.mode || 'get',
|
|
2865
2883
|
changes: context.changes || null,
|
|
2866
2884
|
enabled: Object.prototype.hasOwnProperty.call(context, 'enabled') ? context.enabled : null,
|
|
2885
|
+
status: context.status || null,
|
|
2867
2886
|
fetchImpl,
|
|
2868
2887
|
logger,
|
|
2869
2888
|
});
|
|
@@ -23,6 +23,8 @@ export const DEFAULT_CLAWORLD_APPROVAL_MODE = DEFAULT_CHAT_REQUEST_APPROVAL_POLI
|
|
|
23
23
|
export const DEFAULT_CLAWORLD_SESSION_TARGET = 'mainagent';
|
|
24
24
|
export const DEFAULT_CLAWORLD_FALLBACK_TARGET = 'mainagent';
|
|
25
25
|
export const CLAWORLD_PLUGIN_TOOL_ALLOW_ENTRY = 'claworld';
|
|
26
|
+
export const MIN_MANAGED_SESSION_VISIBILITY = 'agent';
|
|
27
|
+
export const REQUIRED_SANDBOX_SESSION_TOOLS_VISIBILITY = 'all';
|
|
26
28
|
|
|
27
29
|
export const TOOL_PROFILES = CLAWORLD_TOOL_PROFILES;
|
|
28
30
|
|
|
@@ -128,6 +130,109 @@ function findManagedAccountEntry(config = {}, accountId) {
|
|
|
128
130
|
return {};
|
|
129
131
|
}
|
|
130
132
|
|
|
133
|
+
const SESSION_VISIBILITY_RANK = Object.freeze({
|
|
134
|
+
self: 0,
|
|
135
|
+
tree: 1,
|
|
136
|
+
agent: 2,
|
|
137
|
+
all: 3,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const SANDBOX_SESSION_TOOLS_VISIBILITY_RANK = Object.freeze({
|
|
141
|
+
spawned: 0,
|
|
142
|
+
all: 1,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
function normalizeSessionVisibility(value, fallback = null) {
|
|
146
|
+
const normalized = normalizeText(value, fallback);
|
|
147
|
+
return Object.prototype.hasOwnProperty.call(SESSION_VISIBILITY_RANK, normalized)
|
|
148
|
+
? normalized
|
|
149
|
+
: fallback;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function normalizeSandboxSessionToolsVisibility(value, fallback = null) {
|
|
153
|
+
const normalized = normalizeText(value, fallback);
|
|
154
|
+
return Object.prototype.hasOwnProperty.call(SANDBOX_SESSION_TOOLS_VISIBILITY_RANK, normalized)
|
|
155
|
+
? normalized
|
|
156
|
+
: fallback;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function compareRankedSetting(value, target, rankMap) {
|
|
160
|
+
const nextValue = normalizeText(value, null);
|
|
161
|
+
const nextTarget = normalizeText(target, null);
|
|
162
|
+
const valueRank = Object.prototype.hasOwnProperty.call(rankMap, nextValue) ? rankMap[nextValue] : null;
|
|
163
|
+
const targetRank = Object.prototype.hasOwnProperty.call(rankMap, nextTarget) ? rankMap[nextTarget] : null;
|
|
164
|
+
if (valueRank == null && targetRank == null) return 0;
|
|
165
|
+
if (valueRank == null) return -1;
|
|
166
|
+
if (targetRank == null) return 1;
|
|
167
|
+
return valueRank - targetRank;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export function getEffectiveAgentSandboxMode(config = {}, agentId = DEFAULT_CLAWORLD_AGENT_ID) {
|
|
171
|
+
const normalizedAgentId = normalizeText(agentId, DEFAULT_CLAWORLD_AGENT_ID);
|
|
172
|
+
const agentEntry = findAgentEntry(config, normalizedAgentId);
|
|
173
|
+
const agentSandboxMode = normalizeText(agentEntry?.sandbox?.mode, null);
|
|
174
|
+
if (agentSandboxMode) return agentSandboxMode;
|
|
175
|
+
return normalizeText(config?.agents?.defaults?.sandbox?.mode, 'off');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export function sandboxModeNeedsSessionToolsVisibility(mode) {
|
|
179
|
+
return mode === 'all' || mode === 'non-main';
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function ensureManagedSessionRoutingVisibility(config = {}, {
|
|
183
|
+
agentId = DEFAULT_CLAWORLD_AGENT_ID,
|
|
184
|
+
summary = [],
|
|
185
|
+
} = {}) {
|
|
186
|
+
config.tools = ensureObject(config.tools);
|
|
187
|
+
const existingSessionTools = ensureObject(config.tools.sessions);
|
|
188
|
+
const existingVisibility = normalizeSessionVisibility(existingSessionTools.visibility, null);
|
|
189
|
+
if (compareRankedSetting(existingVisibility, MIN_MANAGED_SESSION_VISIBILITY, SESSION_VISIBILITY_RANK) < 0) {
|
|
190
|
+
config.tools.sessions = {
|
|
191
|
+
...existingSessionTools,
|
|
192
|
+
visibility: MIN_MANAGED_SESSION_VISIBILITY,
|
|
193
|
+
};
|
|
194
|
+
summary.push(
|
|
195
|
+
existingVisibility
|
|
196
|
+
? `tools.sessions.visibility raised from ${existingVisibility} to ${MIN_MANAGED_SESSION_VISIBILITY}`
|
|
197
|
+
: `tools.sessions.visibility set to ${MIN_MANAGED_SESSION_VISIBILITY}`,
|
|
198
|
+
);
|
|
199
|
+
} else if (Object.keys(existingSessionTools).length > 0) {
|
|
200
|
+
config.tools.sessions = existingSessionTools;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const effectiveSandboxMode = getEffectiveAgentSandboxMode(config, agentId);
|
|
204
|
+
if (!sandboxModeNeedsSessionToolsVisibility(effectiveSandboxMode)) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
config.agents = ensureObject(config.agents);
|
|
209
|
+
config.agents.defaults = ensureObject(config.agents.defaults);
|
|
210
|
+
const existingSandbox = ensureObject(config.agents.defaults.sandbox);
|
|
211
|
+
const existingSessionToolsVisibility = normalizeSandboxSessionToolsVisibility(
|
|
212
|
+
existingSandbox.sessionToolsVisibility,
|
|
213
|
+
null,
|
|
214
|
+
);
|
|
215
|
+
if (
|
|
216
|
+
compareRankedSetting(
|
|
217
|
+
existingSessionToolsVisibility,
|
|
218
|
+
REQUIRED_SANDBOX_SESSION_TOOLS_VISIBILITY,
|
|
219
|
+
SANDBOX_SESSION_TOOLS_VISIBILITY_RANK,
|
|
220
|
+
) < 0
|
|
221
|
+
) {
|
|
222
|
+
config.agents.defaults.sandbox = {
|
|
223
|
+
...existingSandbox,
|
|
224
|
+
sessionToolsVisibility: REQUIRED_SANDBOX_SESSION_TOOLS_VISIBILITY,
|
|
225
|
+
};
|
|
226
|
+
summary.push(
|
|
227
|
+
existingSessionToolsVisibility
|
|
228
|
+
? `agents.defaults.sandbox.sessionToolsVisibility raised from ${existingSessionToolsVisibility} to ${REQUIRED_SANDBOX_SESSION_TOOLS_VISIBILITY}`
|
|
229
|
+
: `agents.defaults.sandbox.sessionToolsVisibility set to ${REQUIRED_SANDBOX_SESSION_TOOLS_VISIBILITY}`,
|
|
230
|
+
);
|
|
231
|
+
} else if (Object.keys(existingSandbox).length > 0) {
|
|
232
|
+
config.agents.defaults.sandbox = existingSandbox;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
131
236
|
function inferExistingAgentId(config = {}, accountId = DEFAULT_CLAWORLD_ACCOUNT_ID) {
|
|
132
237
|
const bindings = Array.isArray(config?.bindings) ? config.bindings : [];
|
|
133
238
|
const bindingMatch = bindings
|
|
@@ -716,6 +821,11 @@ export function applyClaworldManagedRuntimeConfig(inputConfig = {}, options = {}
|
|
|
716
821
|
: `reconciled claworld binding for ${options.accountId}`,
|
|
717
822
|
);
|
|
718
823
|
|
|
824
|
+
ensureManagedSessionRoutingVisibility(config, {
|
|
825
|
+
agentId: options.agentId,
|
|
826
|
+
summary,
|
|
827
|
+
});
|
|
828
|
+
|
|
719
829
|
return {
|
|
720
830
|
config,
|
|
721
831
|
summary,
|