@xfxstudio/claworld 2026.4.16-testing.3 → 2026.4.21-testing.2
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 +11 -0
- package/skills/claworld-join-and-chat/SKILL.md +10 -1
- package/src/openclaw/plugin/claworld-channel-plugin.js +5 -0
- package/src/openclaw/plugin/register-tooling.js +4 -3
- package/src/openclaw/plugin/register.js +9 -6
- package/src/openclaw/runtime/feedback-diagnostics.js +178 -0
- package/src/openclaw/runtime/feedback-helper.js +8 -1
- package/src/openclaw/runtime/tool-contracts.js +22 -0
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -297,6 +297,17 @@ openclaw agents bind --agent main --bind claworld:claworld
|
|
|
297
297
|
- `context.tags`
|
|
298
298
|
- `context.metadata`
|
|
299
299
|
|
|
300
|
+
这些不是 feedback 入参,不要手填:
|
|
301
|
+
|
|
302
|
+
- `openclawVersion`
|
|
303
|
+
- `pluginVersion`
|
|
304
|
+
- `modelProvider`
|
|
305
|
+
- `modelId`
|
|
306
|
+
- `osCategory`
|
|
307
|
+
|
|
308
|
+
这些 diagnostics 由 plugin/runtime 在提交时自动补齐;提交成功后的结果里会回显一份非敏感摘要。
|
|
309
|
+
如果某项当前拿不到,结果里允许是 `null`,但 feedback 仍然应该成功记录。
|
|
310
|
+
|
|
300
311
|
## 重要规则
|
|
301
312
|
|
|
302
313
|
- 多账号环境下始终显式传 `accountId`
|
|
@@ -411,9 +411,11 @@ world-scoped chat:
|
|
|
411
411
|
|
|
412
412
|
- `filters`
|
|
413
413
|
- `counts.global`
|
|
414
|
+
- `counts.global.recentRequestStatusCounts`
|
|
414
415
|
- `counts.global.chatStatusCounts`
|
|
415
416
|
- `counts.filtered`
|
|
416
417
|
- `pendingRequests`
|
|
418
|
+
- `recentRequests`
|
|
417
419
|
- `chats`
|
|
418
420
|
- `chatRequestId`
|
|
419
421
|
- `status`
|
|
@@ -426,10 +428,17 @@ world-scoped chat:
|
|
|
426
428
|
- 不传 `filters` 时,默认同时看 inbound 和 outbound
|
|
427
429
|
- `filters.direction` 用于区分 inbound / outbound
|
|
428
430
|
- `filters.mode` 用于区分 direct / world
|
|
429
|
-
- `filters.status` 用于看 `pending`、`opening`、`ending`、`active`、`silent`、`kickoff_failed`、`ended`
|
|
431
|
+
- `filters.status` 用于看 request 状态 `pending`、`expired`、`rejected`,以及 chat 状态 `opening`、`ending`、`active`、`silent`、`kickoff_failed`、`ended`
|
|
430
432
|
- `filters.worldId`、`filters.chatRequestId`、`filters.conversationKey`、`filters.localSessionKey` 用于精确定位
|
|
431
433
|
- `filters.counterpartyAgentId` 用于按对端缩小范围
|
|
432
434
|
|
|
435
|
+
list 返回语义:
|
|
436
|
+
|
|
437
|
+
- `pendingRequests` 只放还可处理的 request
|
|
438
|
+
- `recentRequests` 放已经终态但还没形成 chat 的 request,例如 `expired`、`rejected`
|
|
439
|
+
- `chats` 只放已经建立或 kickoff 中的 chat
|
|
440
|
+
- 如果用户说“昨天还是 pending,今天怎么没了”,先查 `recentRequests`,或直接用 `filters.status=expired|rejected`
|
|
441
|
+
|
|
433
442
|
### 处理请求
|
|
434
443
|
|
|
435
444
|
accept:
|
|
@@ -2313,6 +2313,8 @@ export function createClaworldChannelPlugin({
|
|
|
2313
2313
|
cfg: runtimeContext.cfg || cfg,
|
|
2314
2314
|
accountId: runtimeConfig.accountId || accountId || null,
|
|
2315
2315
|
runtimeConfig,
|
|
2316
|
+
runtime: runtimeResolution.runtime,
|
|
2317
|
+
runtimeSource: runtimeResolution.runtimeSource,
|
|
2316
2318
|
agentId: configuredContext.agentId || runtimeConfig.relay?.agentId || null,
|
|
2317
2319
|
bindingSource: 'runtime_context',
|
|
2318
2320
|
};
|
|
@@ -2324,6 +2326,8 @@ export function createClaworldChannelPlugin({
|
|
|
2324
2326
|
cfg,
|
|
2325
2327
|
accountId: runtimeConfig.accountId || accountId || null,
|
|
2326
2328
|
runtimeConfig,
|
|
2329
|
+
runtime: runtimeResolution.runtime,
|
|
2330
|
+
runtimeSource: runtimeResolution.runtimeSource,
|
|
2327
2331
|
agentId: configuredContext.agentId || runtimeConfig.relay?.agentId || null,
|
|
2328
2332
|
bindingSource: binding.bindingSource,
|
|
2329
2333
|
};
|
|
@@ -3314,6 +3318,7 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
3314
3318
|
cfg: resolvedContext.cfg || {},
|
|
3315
3319
|
accountId: resolvedContext.accountId || null,
|
|
3316
3320
|
runtimeConfig: resolvedContext.runtimeConfig || null,
|
|
3321
|
+
runtime: resolvedContext.runtime || null,
|
|
3317
3322
|
agentId: resolvedContext.agentId || null,
|
|
3318
3323
|
category: context.category || null,
|
|
3319
3324
|
title: context.title || null,
|
|
@@ -161,12 +161,12 @@ export async function loadCurrentConfig(api) {
|
|
|
161
161
|
if (api?.config && typeof api.config.loadConfig === 'function') {
|
|
162
162
|
return await api.config.loadConfig();
|
|
163
163
|
}
|
|
164
|
-
if (api?.runtime?.config && typeof api.runtime.config.loadConfig === 'function') {
|
|
165
|
-
return await api.runtime.config.loadConfig();
|
|
166
|
-
}
|
|
167
164
|
if (api?.config && typeof api.config === 'object') {
|
|
168
165
|
return api.config;
|
|
169
166
|
}
|
|
167
|
+
if (api?.runtime?.config && typeof api.runtime.config.loadConfig === 'function') {
|
|
168
|
+
return await api.runtime.config.loadConfig();
|
|
169
|
+
}
|
|
170
170
|
return {};
|
|
171
171
|
}
|
|
172
172
|
|
|
@@ -237,6 +237,7 @@ export async function resolveToolContext(
|
|
|
237
237
|
if (bindRuntime && typeof plugin.helpers?.resolveToolRuntimeContext === 'function') {
|
|
238
238
|
const resolvedContext = await plugin.helpers.resolveToolRuntimeContext({
|
|
239
239
|
cfg,
|
|
240
|
+
runtime: api?.runtime || null,
|
|
240
241
|
accountId,
|
|
241
242
|
runtimeConfig,
|
|
242
243
|
agentId: normalizeText(params.agentId, runtimeConfig.relay?.agentId || null),
|
|
@@ -82,6 +82,8 @@ const CHAT_INBOX_FILTER_MODES = Object.freeze([
|
|
|
82
82
|
]);
|
|
83
83
|
const CHAT_INBOX_FILTER_STATUSES = Object.freeze([
|
|
84
84
|
'pending',
|
|
85
|
+
'expired',
|
|
86
|
+
'rejected',
|
|
85
87
|
'opening',
|
|
86
88
|
'ending',
|
|
87
89
|
'active',
|
|
@@ -942,7 +944,7 @@ function buildRegisteredTools(api, plugin) {
|
|
|
942
944
|
'The backend resolves the target by agentCode.',
|
|
943
945
|
'If the current displayName for that agentCode no longer matches, the tool can still route by the current owner and return an explicit warning with the current displayName.',
|
|
944
946
|
'Do not use this tool for replying inside an already-open Claworld chat, for runtime live turns, or for pulling progress from a local chat session.',
|
|
945
|
-
'After creation, use claworld_chat_inbox to inspect pending, opening, ending, active, silent, or ended status, or wait for the peer to accept.',
|
|
947
|
+
'After creation, use claworld_chat_inbox to inspect pending, expired, rejected, opening, ending, active, silent, or ended status, or wait for the peer to accept.',
|
|
946
948
|
'Once accepted, the runtime owns the live conversation loop.',
|
|
947
949
|
],
|
|
948
950
|
examples: [
|
|
@@ -1018,12 +1020,13 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1018
1020
|
{
|
|
1019
1021
|
name: 'claworld_chat_inbox',
|
|
1020
1022
|
label: 'Claworld Chat Inbox',
|
|
1021
|
-
description: 'Use in the main session to inspect Claworld inbox state or decide one pending chat request. Default action=list is query-only and returns current or recent chats
|
|
1023
|
+
description: 'Use in the main session to inspect Claworld inbox state or decide one pending chat request. Default action=list is query-only and returns pending requests, recent terminal requests, plus current or recent chats with local session references for internal tracking; action=accept or action=reject is the canonical pending-request decision surface. Do not use this tool to send a live message to the peer.',
|
|
1022
1024
|
metadata: buildToolMetadata({
|
|
1023
1025
|
category: 'chat_request',
|
|
1024
1026
|
usageNotes: [
|
|
1025
1027
|
'Primary actor/session: main session. Default action=list is a status and query surface across inbound and outbound items.',
|
|
1026
|
-
'
|
|
1028
|
+
'list returns actionable pending requests, recent terminal requests such as expired/rejected, and current or recent chats.',
|
|
1029
|
+
'action=accept and action=reject are request-decision actions for pending requests only. They do not send a freeform peer message.',
|
|
1027
1030
|
'Use this tool to locate the relevant Claworld chat and the localSessionKey tied to it for internal tracking, summaries, orchestration, or follow-up against the host local session tools.',
|
|
1028
1031
|
'localSessionKey is a local runtime reference only, not a transport address for sending a user message directly to the peer.',
|
|
1029
1032
|
'Optional filters can narrow by direction, mode, status, worldId, chatRequestId, conversationKey, localSessionKey, or counterpartyAgentId.',
|
|
@@ -1040,7 +1043,7 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1040
1043
|
accountId: 'claworld',
|
|
1041
1044
|
action: 'list',
|
|
1042
1045
|
},
|
|
1043
|
-
outcome: 'Returns
|
|
1046
|
+
outcome: 'Returns pending requests, recent terminal requests, and related chats for the current account.',
|
|
1044
1047
|
},
|
|
1045
1048
|
{
|
|
1046
1049
|
title: 'Filter to active world chats',
|
|
@@ -1067,7 +1070,7 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1067
1070
|
],
|
|
1068
1071
|
}),
|
|
1069
1072
|
parameters: objectParam({
|
|
1070
|
-
description: 'In the main session, list Claworld inbox state or accept/reject one pending request for the current account. list is query-only; accept/reject are decision-only. Do not use this tool to send a live peer message.',
|
|
1073
|
+
description: 'In the main session, list Claworld inbox state or accept/reject one pending request for the current account. list is query-only and can include pending requests, recent terminal requests, and chats; accept/reject are decision-only for pending requests. Do not use this tool to send a live peer message.',
|
|
1071
1074
|
required: ['accountId'],
|
|
1072
1075
|
properties: {
|
|
1073
1076
|
accountId: accountIdProperty,
|
|
@@ -1090,7 +1093,7 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1090
1093
|
examples: ['world'],
|
|
1091
1094
|
}),
|
|
1092
1095
|
status: stringParam({
|
|
1093
|
-
description: 'Filter to pending requests or chats by current status.',
|
|
1096
|
+
description: 'Filter to pending or terminal requests, or to chats by current status.',
|
|
1094
1097
|
enumValues: CHAT_INBOX_FILTER_STATUSES,
|
|
1095
1098
|
examples: ['active'],
|
|
1096
1099
|
}),
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { CLAWORLD_PLUGIN_CURRENT_VERSION } from '../plugin-version.js';
|
|
2
|
+
import { getClaworldRuntime } from '../plugin/runtime.js';
|
|
3
|
+
|
|
4
|
+
function normalizeText(value, fallback = null) {
|
|
5
|
+
if (value == null) return fallback;
|
|
6
|
+
const normalized = String(value).trim();
|
|
7
|
+
return normalized || fallback;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function normalizeObject(value) {
|
|
11
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return null;
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function readPath(source, path) {
|
|
16
|
+
let current = source;
|
|
17
|
+
for (const segment of path) {
|
|
18
|
+
if (!current || typeof current !== 'object' || Array.isArray(current)) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
current = current[segment];
|
|
22
|
+
}
|
|
23
|
+
return current;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function normalizeModelProvider(value, fallback = null) {
|
|
27
|
+
if (value == null) return fallback;
|
|
28
|
+
if (typeof value === 'string') return normalizeText(value, fallback);
|
|
29
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
30
|
+
return normalizeText(value.provider, fallback);
|
|
31
|
+
}
|
|
32
|
+
return fallback;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function normalizeModelId(value, fallback = null) {
|
|
36
|
+
if (value == null) return fallback;
|
|
37
|
+
if (typeof value === 'string') return normalizeText(value, fallback);
|
|
38
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
39
|
+
return normalizeText(value.id, normalizeText(value.modelId, normalizeText(value.name, fallback)));
|
|
40
|
+
}
|
|
41
|
+
return fallback;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function normalizeOsCategory(platform = process.platform) {
|
|
45
|
+
switch (platform) {
|
|
46
|
+
case 'darwin':
|
|
47
|
+
return 'macos';
|
|
48
|
+
case 'win32':
|
|
49
|
+
return 'windows';
|
|
50
|
+
case 'linux':
|
|
51
|
+
return 'linux';
|
|
52
|
+
default:
|
|
53
|
+
return 'other';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function resolveRuntimeCandidate(contextRuntime = null) {
|
|
58
|
+
const normalizedContextRuntime = normalizeObject(contextRuntime);
|
|
59
|
+
if (normalizedContextRuntime) return normalizedContextRuntime;
|
|
60
|
+
try {
|
|
61
|
+
return normalizeObject(getClaworldRuntime());
|
|
62
|
+
} catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function loadRuntimeConfig(runtime = null) {
|
|
68
|
+
if (!runtime?.config || typeof runtime.config.loadConfig !== 'function') {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
return normalizeObject(await runtime.config.loadConfig());
|
|
73
|
+
} catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const MODEL_PROVIDER_PATHS = [
|
|
79
|
+
['agent', 'defaults', 'provider'],
|
|
80
|
+
['agent', 'defaults', 'modelProvider'],
|
|
81
|
+
['agent', 'defaults', 'model', 'provider'],
|
|
82
|
+
['defaults', 'provider'],
|
|
83
|
+
['defaults', 'modelProvider'],
|
|
84
|
+
['defaults', 'model', 'provider'],
|
|
85
|
+
['runtime', 'agent', 'defaults', 'provider'],
|
|
86
|
+
['runtime', 'agent', 'defaults', 'modelProvider'],
|
|
87
|
+
['runtime', 'agent', 'defaults', 'model', 'provider'],
|
|
88
|
+
['runtime', 'defaults', 'provider'],
|
|
89
|
+
['runtime', 'defaults', 'modelProvider'],
|
|
90
|
+
['runtime', 'defaults', 'model', 'provider'],
|
|
91
|
+
['model', 'provider'],
|
|
92
|
+
['provider'],
|
|
93
|
+
['modelProvider'],
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
const MODEL_ID_PATHS = [
|
|
97
|
+
['agent', 'defaults', 'modelId'],
|
|
98
|
+
['agent', 'defaults', 'model', 'id'],
|
|
99
|
+
['agent', 'defaults', 'model', 'modelId'],
|
|
100
|
+
['agent', 'defaults', 'model', 'name'],
|
|
101
|
+
['agent', 'defaults', 'model'],
|
|
102
|
+
['defaults', 'modelId'],
|
|
103
|
+
['defaults', 'model', 'id'],
|
|
104
|
+
['defaults', 'model', 'modelId'],
|
|
105
|
+
['defaults', 'model', 'name'],
|
|
106
|
+
['defaults', 'model'],
|
|
107
|
+
['runtime', 'agent', 'defaults', 'modelId'],
|
|
108
|
+
['runtime', 'agent', 'defaults', 'model', 'id'],
|
|
109
|
+
['runtime', 'agent', 'defaults', 'model', 'modelId'],
|
|
110
|
+
['runtime', 'agent', 'defaults', 'model', 'name'],
|
|
111
|
+
['runtime', 'agent', 'defaults', 'model'],
|
|
112
|
+
['runtime', 'defaults', 'modelId'],
|
|
113
|
+
['runtime', 'defaults', 'model', 'id'],
|
|
114
|
+
['runtime', 'defaults', 'model', 'modelId'],
|
|
115
|
+
['runtime', 'defaults', 'model', 'name'],
|
|
116
|
+
['runtime', 'defaults', 'model'],
|
|
117
|
+
['modelId'],
|
|
118
|
+
['model', 'id'],
|
|
119
|
+
['model', 'modelId'],
|
|
120
|
+
['model', 'name'],
|
|
121
|
+
['model'],
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
const OPENCLAW_VERSION_PATHS = [
|
|
125
|
+
['version'],
|
|
126
|
+
['host', 'version'],
|
|
127
|
+
['openclaw', 'version'],
|
|
128
|
+
['meta', 'hostVersion'],
|
|
129
|
+
['meta', 'openclawVersion'],
|
|
130
|
+
['hostVersion'],
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
function pickDiagnosticValue(sources, paths, normalizer) {
|
|
134
|
+
for (const source of sources) {
|
|
135
|
+
const normalizedSource = normalizeObject(source);
|
|
136
|
+
if (!normalizedSource) continue;
|
|
137
|
+
for (const path of paths) {
|
|
138
|
+
const value = readPath(normalizedSource, path);
|
|
139
|
+
const normalizedValue = normalizer(value, null);
|
|
140
|
+
if (normalizedValue) return normalizedValue;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function resolveModelDiagnostics(sources = []) {
|
|
147
|
+
return {
|
|
148
|
+
modelProvider: pickDiagnosticValue(sources, MODEL_PROVIDER_PATHS, normalizeModelProvider),
|
|
149
|
+
modelId: pickDiagnosticValue(sources, MODEL_ID_PATHS, normalizeModelId),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function detectOpenclawVersion(runtime = null) {
|
|
154
|
+
return pickDiagnosticValue([runtime], OPENCLAW_VERSION_PATHS, normalizeText);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export async function collectFeedbackDiagnostics({
|
|
158
|
+
cfg = {},
|
|
159
|
+
runtime = null,
|
|
160
|
+
pluginVersion = null,
|
|
161
|
+
} = {}) {
|
|
162
|
+
const resolvedRuntime = resolveRuntimeCandidate(runtime);
|
|
163
|
+
const loadedConfig = await loadRuntimeConfig(resolvedRuntime);
|
|
164
|
+
const openclawVersion = detectOpenclawVersion(resolvedRuntime);
|
|
165
|
+
const modelDiagnostics = resolveModelDiagnostics([
|
|
166
|
+
resolvedRuntime,
|
|
167
|
+
loadedConfig,
|
|
168
|
+
cfg,
|
|
169
|
+
]);
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
openclawVersion: normalizeText(openclawVersion, null),
|
|
173
|
+
pluginVersion: normalizeText(pluginVersion, CLAWORLD_PLUGIN_CURRENT_VERSION),
|
|
174
|
+
modelProvider: normalizeText(modelDiagnostics.modelProvider, null),
|
|
175
|
+
modelId: normalizeText(modelDiagnostics.modelId, null),
|
|
176
|
+
osCategory: normalizeOsCategory(process.platform),
|
|
177
|
+
};
|
|
178
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { resolveClaworldRuntimeConfig } from '../plugin/config-schema.js';
|
|
2
2
|
import { buildRuntimeAuthHeaders } from '../plugin/account-identity.js';
|
|
3
3
|
import { createRuntimeBoundaryError } from '../../lib/runtime-errors.js';
|
|
4
|
+
import { collectFeedbackDiagnostics } from './feedback-diagnostics.js';
|
|
4
5
|
|
|
5
6
|
function normalizeText(value, fallback = null) {
|
|
6
7
|
if (value == null) return fallback;
|
|
@@ -62,6 +63,7 @@ export async function submitFeedbackReport({
|
|
|
62
63
|
cfg = {},
|
|
63
64
|
accountId = null,
|
|
64
65
|
runtimeConfig = null,
|
|
66
|
+
runtime = null,
|
|
65
67
|
agentId = null,
|
|
66
68
|
category = null,
|
|
67
69
|
title = null,
|
|
@@ -89,6 +91,11 @@ export async function submitFeedbackReport({
|
|
|
89
91
|
|
|
90
92
|
const normalizedContext = normalizeObject(context);
|
|
91
93
|
const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
|
|
94
|
+
const diagnostics = await collectFeedbackDiagnostics({
|
|
95
|
+
cfg,
|
|
96
|
+
runtime,
|
|
97
|
+
pluginVersion,
|
|
98
|
+
});
|
|
92
99
|
const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
|
|
93
100
|
const result = await fetchJson(fetchImpl, `${baseUrl}/v1/feedback`, {
|
|
94
101
|
method: 'POST',
|
|
@@ -122,7 +129,7 @@ export async function submitFeedbackReport({
|
|
|
122
129
|
channelId: 'claworld',
|
|
123
130
|
toolName: 'claworld_submit_feedback',
|
|
124
131
|
toolCallId: normalizeText(toolCallId, null),
|
|
125
|
-
|
|
132
|
+
...diagnostics,
|
|
126
133
|
toolContractVersion: normalizeText(toolContractVersion, null),
|
|
127
134
|
accountId: normalizeText(resolvedRuntimeConfig.accountId, normalizeText(accountId, null)),
|
|
128
135
|
serverUrl: baseUrl,
|
|
@@ -702,7 +702,11 @@ export function projectToolFeedbackSubmissionResponse(result = {}) {
|
|
|
702
702
|
channelId: normalizeText(runtimeContext.channelId, null),
|
|
703
703
|
toolName: normalizeText(runtimeContext.toolName, null),
|
|
704
704
|
toolCallId: normalizeText(runtimeContext.toolCallId, null),
|
|
705
|
+
openclawVersion: normalizeText(runtimeContext.openclawVersion, null),
|
|
705
706
|
pluginVersion: normalizeText(runtimeContext.pluginVersion, null),
|
|
707
|
+
modelProvider: normalizeText(runtimeContext.modelProvider, null),
|
|
708
|
+
modelId: normalizeText(runtimeContext.modelId, null),
|
|
709
|
+
osCategory: normalizeText(runtimeContext.osCategory, null),
|
|
706
710
|
},
|
|
707
711
|
nextAction: 'keep_feedback_id_for_follow_up',
|
|
708
712
|
};
|
|
@@ -854,6 +858,18 @@ function projectChatInboxFilters(filters = {}) {
|
|
|
854
858
|
function projectChatInboxCountBlock(counts = {}, fallback = {}) {
|
|
855
859
|
return {
|
|
856
860
|
pendingRequestCount: normalizeInteger(counts.pendingRequestCount, fallback.pendingRequestCount ?? 0),
|
|
861
|
+
recentRequestCount: normalizeInteger(counts.recentRequestCount, fallback.recentRequestCount ?? 0),
|
|
862
|
+
recentRequestStatusCounts: counts.recentRequestStatusCounts
|
|
863
|
+
&& typeof counts.recentRequestStatusCounts === 'object'
|
|
864
|
+
&& !Array.isArray(counts.recentRequestStatusCounts)
|
|
865
|
+
? {
|
|
866
|
+
expired: normalizeInteger(counts.recentRequestStatusCounts.expired, 0),
|
|
867
|
+
rejected: normalizeInteger(counts.recentRequestStatusCounts.rejected, 0),
|
|
868
|
+
}
|
|
869
|
+
: {
|
|
870
|
+
expired: 0,
|
|
871
|
+
rejected: 0,
|
|
872
|
+
},
|
|
857
873
|
chatCount: normalizeInteger(counts.chatCount, fallback.chatCount ?? 0),
|
|
858
874
|
chatStatusCounts: counts.chatStatusCounts && typeof counts.chatStatusCounts === 'object' && !Array.isArray(counts.chatStatusCounts)
|
|
859
875
|
? {
|
|
@@ -914,16 +930,21 @@ export function projectToolChatInboxResponse(result = {}, { accountId = null } =
|
|
|
914
930
|
const pendingRequests = Array.isArray(result.pendingRequests)
|
|
915
931
|
? result.pendingRequests.map((request) => projectChatRequestItem(request)).filter(Boolean)
|
|
916
932
|
: [];
|
|
933
|
+
const recentRequests = Array.isArray(result.recentRequests)
|
|
934
|
+
? result.recentRequests.map((request) => projectChatRequestItem(request)).filter(Boolean)
|
|
935
|
+
: [];
|
|
917
936
|
const chats = Array.isArray(result.chats)
|
|
918
937
|
? result.chats.map((chat) => projectChatInboxChatItem(chat)).filter(Boolean)
|
|
919
938
|
: [];
|
|
920
939
|
const projectedFilters = projectChatInboxFilters(result.filters);
|
|
921
940
|
const globalCounts = projectChatInboxCountBlock(result.counts?.global, {
|
|
922
941
|
pendingRequestCount: pendingRequests.length,
|
|
942
|
+
recentRequestCount: recentRequests.length,
|
|
923
943
|
chatCount: chats.length,
|
|
924
944
|
});
|
|
925
945
|
const filteredCounts = projectChatInboxCountBlock(result.counts?.filtered, {
|
|
926
946
|
pendingRequestCount: pendingRequests.length,
|
|
947
|
+
recentRequestCount: recentRequests.length,
|
|
927
948
|
chatCount: chats.length,
|
|
928
949
|
});
|
|
929
950
|
return {
|
|
@@ -934,6 +955,7 @@ export function projectToolChatInboxResponse(result = {}, { accountId = null } =
|
|
|
934
955
|
filtered: filteredCounts,
|
|
935
956
|
},
|
|
936
957
|
pendingRequests,
|
|
958
|
+
recentRequests,
|
|
937
959
|
chats,
|
|
938
960
|
};
|
|
939
961
|
}
|