@xfxstudio/claworld 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -0
- package/bin/claworld.mjs +9 -0
- package/index.js +51 -0
- package/openclaw.plugin.json +470 -0
- package/package.json +76 -0
- package/setup-entry.js +6 -0
- package/src/lib/accepted-chat-kickoff.js +192 -0
- package/src/lib/agent-address.js +46 -0
- package/src/lib/agent-profile.js +69 -0
- package/src/lib/http-auth.js +151 -0
- package/src/lib/policy.js +118 -0
- package/src/lib/runtime-errors.js +149 -0
- package/src/lib/runtime-guidance.js +458 -0
- package/src/openclaw/index.js +53 -0
- package/src/openclaw/installer/cli.js +349 -0
- package/src/openclaw/installer/constants.js +6 -0
- package/src/openclaw/installer/core.js +1548 -0
- package/src/openclaw/installer/doctor.js +690 -0
- package/src/openclaw/installer/workspace-contract.js +403 -0
- package/src/openclaw/plugin/account-identity.js +66 -0
- package/src/openclaw/plugin/claworld-channel-plugin.js +3118 -0
- package/src/openclaw/plugin/config-schema.js +464 -0
- package/src/openclaw/plugin/lifecycle.js +114 -0
- package/src/openclaw/plugin/managed-config.js +648 -0
- package/src/openclaw/plugin/onboarding.js +291 -0
- package/src/openclaw/plugin/register.js +961 -0
- package/src/openclaw/plugin/relay-client.js +783 -0
- package/src/openclaw/plugin/runtime.js +12 -0
- package/src/openclaw/protocol/relay-event-protocol.js +31 -0
- package/src/openclaw/runtime/canonical-result-builder.js +116 -0
- package/src/openclaw/runtime/demo-session-bootstrap.js +37 -0
- package/src/openclaw/runtime/feedback-helper.js +145 -0
- package/src/openclaw/runtime/inbound-session-router.js +36 -0
- package/src/openclaw/runtime/outbound-session-bridge.js +17 -0
- package/src/openclaw/runtime/product-shell-helper.js +1712 -0
- package/src/openclaw/runtime/runtime-path.js +19 -0
- package/src/openclaw/runtime/system-message-orchestrator.js +1 -0
- package/src/openclaw/runtime/tool-contracts.js +714 -0
- package/src/openclaw/runtime/tool-inventory.js +92 -0
- package/src/openclaw/runtime/world-moderation-helper.js +415 -0
- package/src/openclaw/runtime/world-session-startup.js +1 -0
- package/src/product-shell/catalog/default-world-catalog.js +296 -0
- package/src/product-shell/contracts/candidate-feed.js +330 -0
- package/src/product-shell/contracts/chat-request-approval-policy.js +98 -0
- package/src/product-shell/contracts/world-manifest.js +435 -0
- package/src/product-shell/contracts/world-orchestration.js +1024 -0
- package/src/product-shell/feedback/feedback-contract.js +13 -0
- package/src/product-shell/feedback/feedback-routes.js +98 -0
- package/src/product-shell/feedback/feedback-service.js +254 -0
- package/src/product-shell/index.js +163 -0
- package/src/product-shell/matching/matchmaking-service.js +340 -0
- package/src/product-shell/membership/membership-service.js +277 -0
- package/src/product-shell/onboarding/onboarding-routes.js +37 -0
- package/src/product-shell/onboarding/onboarding-service.js +230 -0
- package/src/product-shell/orchestration/session-orchestrator.js +38 -0
- package/src/product-shell/results/result-service.js +15 -0
- package/src/product-shell/search/search-service.js +359 -0
- package/src/product-shell/social/chat-request-approval-policy.js +332 -0
- package/src/product-shell/social/chat-request-routes.js +108 -0
- package/src/product-shell/social/chat-request-service.js +632 -0
- package/src/product-shell/social/friend-routes.js +82 -0
- package/src/product-shell/social/friend-service.js +560 -0
- package/src/product-shell/social/social-routes.js +21 -0
- package/src/product-shell/social/social-service.js +140 -0
- package/src/product-shell/worlds/world-admin-service.js +705 -0
- package/src/product-shell/worlds/world-authorization.js +135 -0
- package/src/product-shell/worlds/world-broadcast-service.js +299 -0
- package/src/product-shell/worlds/world-routes.js +410 -0
- package/src/product-shell/worlds/world-service.js +89 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { resolveAuthenticatedAgentId } from '../../lib/http-auth.js';
|
|
2
|
+
|
|
3
|
+
function sendFeedbackError(res, error) {
|
|
4
|
+
const status = Number.isInteger(error?.status) ? error.status : 500;
|
|
5
|
+
if (error?.responseBody && typeof error.responseBody === 'object') {
|
|
6
|
+
return res.status(status).json(error.responseBody);
|
|
7
|
+
}
|
|
8
|
+
const code = typeof error?.code === 'string' ? error.code : 'internal_error';
|
|
9
|
+
return res.status(status).json({ error: code, message: error?.message || code });
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function registerFeedbackRoutes(app, { store, feedbackService }) {
|
|
13
|
+
function resolveAgentIdentity(req, res, { providedAgentId = null, fieldName = 'agentId', required = true } = {}) {
|
|
14
|
+
const result = resolveAuthenticatedAgentId({
|
|
15
|
+
store,
|
|
16
|
+
req,
|
|
17
|
+
providedAgentId,
|
|
18
|
+
fieldName,
|
|
19
|
+
});
|
|
20
|
+
if (!result.ok) {
|
|
21
|
+
res.status(result.status).json(result.body);
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
if (!result.agentId) {
|
|
25
|
+
if (!required) return null;
|
|
26
|
+
res.status(400).json({
|
|
27
|
+
error: 'invalid_agent',
|
|
28
|
+
field: fieldName,
|
|
29
|
+
message: `${fieldName} is required`,
|
|
30
|
+
});
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return result.agentId;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
app.post('/v1/feedback', async (req, res) => {
|
|
37
|
+
const reporterAgentId = resolveAgentIdentity(req, res, {
|
|
38
|
+
providedAgentId: req.body?.agentId || null,
|
|
39
|
+
fieldName: 'agentId',
|
|
40
|
+
});
|
|
41
|
+
if (!reporterAgentId) return;
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const result = await feedbackService.submitFeedback({
|
|
45
|
+
reporterAgentId,
|
|
46
|
+
accountId: req.body?.accountId,
|
|
47
|
+
category: req.body?.category,
|
|
48
|
+
title: req.body?.title,
|
|
49
|
+
goal: req.body?.goal,
|
|
50
|
+
actualBehavior: req.body?.actualBehavior,
|
|
51
|
+
expectedBehavior: req.body?.expectedBehavior,
|
|
52
|
+
impact: req.body?.impact,
|
|
53
|
+
details: req.body?.details,
|
|
54
|
+
reproductionSteps: req.body?.reproductionSteps,
|
|
55
|
+
worldId: req.body?.worldId,
|
|
56
|
+
sessionId: req.body?.sessionId,
|
|
57
|
+
roundId: req.body?.roundId,
|
|
58
|
+
targetAgentId: req.body?.targetAgentId,
|
|
59
|
+
targetAgentCode: req.body?.targetAgentCode,
|
|
60
|
+
tags: req.body?.tags,
|
|
61
|
+
metadata: req.body?.metadata,
|
|
62
|
+
context: req.body?.context,
|
|
63
|
+
source: req.body?.source,
|
|
64
|
+
runtimeContext: req.body?.runtimeContext,
|
|
65
|
+
});
|
|
66
|
+
res.status(201).json(result);
|
|
67
|
+
} catch (error) {
|
|
68
|
+
sendFeedbackError(res, error);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
app.get('/v1/moderation/feedback', (req, res) => {
|
|
73
|
+
try {
|
|
74
|
+
const result = feedbackService.listFeedback({
|
|
75
|
+
category: req.query.category,
|
|
76
|
+
impact: req.query.impact,
|
|
77
|
+
accountId: req.query.accountId,
|
|
78
|
+
reporterAgentId: req.query.reporterAgentId,
|
|
79
|
+
worldId: req.query.worldId,
|
|
80
|
+
sessionId: req.query.sessionId,
|
|
81
|
+
source: req.query.source,
|
|
82
|
+
page: req.query.page,
|
|
83
|
+
limit: req.query.limit,
|
|
84
|
+
});
|
|
85
|
+
res.json(result);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
sendFeedbackError(res, error);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
app.get('/v1/moderation/feedback/:feedbackId', (req, res) => {
|
|
92
|
+
try {
|
|
93
|
+
res.json(feedbackService.getFeedback(req.params.feedbackId));
|
|
94
|
+
} catch (error) {
|
|
95
|
+
sendFeedbackError(res, error);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FEEDBACK_CATEGORY_VALUES,
|
|
3
|
+
FEEDBACK_IMPACT_VALUES,
|
|
4
|
+
} from './feedback-contract.js';
|
|
5
|
+
|
|
6
|
+
function normalizeText(value, fallback = null) {
|
|
7
|
+
if (value == null) return fallback;
|
|
8
|
+
const normalized = String(value).trim();
|
|
9
|
+
return normalized || fallback;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function normalizePlainObject(value) {
|
|
13
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return {};
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function normalizeStringList(value = []) {
|
|
18
|
+
if (!Array.isArray(value)) return [];
|
|
19
|
+
return [...new Set(value.map((entry) => normalizeText(entry, null)).filter(Boolean))];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function normalizePaginationInteger(value, fallback) {
|
|
23
|
+
const normalized = Number(value);
|
|
24
|
+
if (!Number.isFinite(normalized) || normalized <= 0) return fallback;
|
|
25
|
+
return Math.max(1, Math.floor(normalized));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function createConfigurationError() {
|
|
29
|
+
const error = new Error('feedback_store_unavailable');
|
|
30
|
+
error.code = 'feedback_store_unavailable';
|
|
31
|
+
error.status = 500;
|
|
32
|
+
return error;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function createFeedbackRequestError(fieldId, message) {
|
|
36
|
+
const error = new Error(`invalid_feedback_request:${fieldId}`);
|
|
37
|
+
error.code = 'invalid_feedback_request';
|
|
38
|
+
error.status = 400;
|
|
39
|
+
error.responseBody = {
|
|
40
|
+
error: error.code,
|
|
41
|
+
message: 'feedback request is invalid',
|
|
42
|
+
fieldErrors: [
|
|
43
|
+
{
|
|
44
|
+
fieldId,
|
|
45
|
+
message,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
return error;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function createReporterNotFoundError(agentId) {
|
|
53
|
+
const error = new Error(`agent_not_found:${agentId}`);
|
|
54
|
+
error.code = 'agent_not_found';
|
|
55
|
+
error.status = 404;
|
|
56
|
+
error.responseBody = {
|
|
57
|
+
error: error.code,
|
|
58
|
+
message: 'reporter agent was not found',
|
|
59
|
+
agentId,
|
|
60
|
+
};
|
|
61
|
+
return error;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function normalizeCategory(category) {
|
|
65
|
+
const normalized = normalizeText(category, null);
|
|
66
|
+
if (!normalized) {
|
|
67
|
+
throw createFeedbackRequestError('category', 'category is required');
|
|
68
|
+
}
|
|
69
|
+
if (!FEEDBACK_CATEGORY_VALUES.includes(normalized)) {
|
|
70
|
+
throw createFeedbackRequestError(
|
|
71
|
+
'category',
|
|
72
|
+
`category must be one of: ${FEEDBACK_CATEGORY_VALUES.join(', ')}`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
return normalized;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function normalizeImpact(impact) {
|
|
79
|
+
const normalized = normalizeText(impact, 'medium');
|
|
80
|
+
if (!FEEDBACK_IMPACT_VALUES.includes(normalized)) {
|
|
81
|
+
throw createFeedbackRequestError(
|
|
82
|
+
'impact',
|
|
83
|
+
`impact must be one of: ${FEEDBACK_IMPACT_VALUES.join(', ')}`,
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
return normalized;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function requireTextField(fieldId, value, message = `${fieldId} is required`) {
|
|
90
|
+
const normalized = normalizeText(value, null);
|
|
91
|
+
if (!normalized) {
|
|
92
|
+
throw createFeedbackRequestError(fieldId, message);
|
|
93
|
+
}
|
|
94
|
+
return normalized;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function projectFeedback(feedback = {}) {
|
|
98
|
+
return {
|
|
99
|
+
feedbackId: feedback.feedbackId,
|
|
100
|
+
category: feedback.category,
|
|
101
|
+
title: feedback.title,
|
|
102
|
+
goal: feedback.goal,
|
|
103
|
+
actualBehavior: feedback.actualBehavior,
|
|
104
|
+
expectedBehavior: feedback.expectedBehavior,
|
|
105
|
+
impact: feedback.impact,
|
|
106
|
+
details: feedback.details || null,
|
|
107
|
+
reproductionSteps: Array.isArray(feedback.reproductionSteps) ? feedback.reproductionSteps : [],
|
|
108
|
+
source: feedback.source || 'openclaw_tool',
|
|
109
|
+
status: feedback.status || 'open',
|
|
110
|
+
accountId: feedback.accountId || null,
|
|
111
|
+
reporter: feedback.reporter && typeof feedback.reporter === 'object'
|
|
112
|
+
? {
|
|
113
|
+
agentId: feedback.reporter.agentId || null,
|
|
114
|
+
agentCode: feedback.reporter.agentCode || null,
|
|
115
|
+
address: feedback.reporter.address || null,
|
|
116
|
+
}
|
|
117
|
+
: {
|
|
118
|
+
agentId: null,
|
|
119
|
+
agentCode: null,
|
|
120
|
+
address: null,
|
|
121
|
+
},
|
|
122
|
+
context: feedback.context && typeof feedback.context === 'object'
|
|
123
|
+
? {
|
|
124
|
+
worldId: feedback.context.worldId || null,
|
|
125
|
+
sessionId: feedback.context.sessionId || null,
|
|
126
|
+
roundId: feedback.context.roundId || null,
|
|
127
|
+
targetAgentId: feedback.context.targetAgentId || null,
|
|
128
|
+
targetAgentCode: feedback.context.targetAgentCode || null,
|
|
129
|
+
tags: Array.isArray(feedback.context.tags) ? feedback.context.tags : [],
|
|
130
|
+
metadata: feedback.context.metadata && typeof feedback.context.metadata === 'object'
|
|
131
|
+
? feedback.context.metadata
|
|
132
|
+
: {},
|
|
133
|
+
}
|
|
134
|
+
: {
|
|
135
|
+
worldId: null,
|
|
136
|
+
sessionId: null,
|
|
137
|
+
roundId: null,
|
|
138
|
+
targetAgentId: null,
|
|
139
|
+
targetAgentCode: null,
|
|
140
|
+
tags: [],
|
|
141
|
+
metadata: {},
|
|
142
|
+
},
|
|
143
|
+
runtimeContext: feedback.runtimeContext && typeof feedback.runtimeContext === 'object'
|
|
144
|
+
? feedback.runtimeContext
|
|
145
|
+
: {},
|
|
146
|
+
createdAt: feedback.createdAt || null,
|
|
147
|
+
updatedAt: feedback.updatedAt || feedback.createdAt || null,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function createFeedbackService({ store } = {}) {
|
|
152
|
+
if (!store || typeof store.createFeedbackReport !== 'function' || typeof store.listFeedbackReports !== 'function') {
|
|
153
|
+
throw createConfigurationError();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
async submitFeedback(input = {}) {
|
|
158
|
+
const reporterAgentId = requireTextField('agentId', input.reporterAgentId || input.agentId);
|
|
159
|
+
const reporter = store.getAgent?.(reporterAgentId);
|
|
160
|
+
if (!reporter) {
|
|
161
|
+
throw createReporterNotFoundError(reporterAgentId);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const context = normalizePlainObject(input.context);
|
|
165
|
+
const runtimeContext = normalizePlainObject(input.runtimeContext);
|
|
166
|
+
const feedback = await store.createFeedbackReport({
|
|
167
|
+
category: normalizeCategory(input.category),
|
|
168
|
+
title: requireTextField('title', input.title),
|
|
169
|
+
goal: requireTextField('goal', input.goal),
|
|
170
|
+
actualBehavior: requireTextField('actualBehavior', input.actualBehavior),
|
|
171
|
+
expectedBehavior: requireTextField('expectedBehavior', input.expectedBehavior),
|
|
172
|
+
impact: normalizeImpact(input.impact),
|
|
173
|
+
details: normalizeText(input.details, null),
|
|
174
|
+
reproductionSteps: normalizeStringList(input.reproductionSteps),
|
|
175
|
+
source: normalizeText(input.source, 'openclaw_tool'),
|
|
176
|
+
accountId: normalizeText(input.accountId, null),
|
|
177
|
+
reporter: {
|
|
178
|
+
agentId: reporter.agentId,
|
|
179
|
+
agentCode: reporter.agentCode,
|
|
180
|
+
address: reporter.address,
|
|
181
|
+
},
|
|
182
|
+
context: {
|
|
183
|
+
worldId: normalizeText(input.worldId, normalizeText(context.worldId, null)),
|
|
184
|
+
sessionId: normalizeText(input.sessionId, normalizeText(context.sessionId, null)),
|
|
185
|
+
roundId: normalizeText(input.roundId, normalizeText(context.roundId, null)),
|
|
186
|
+
targetAgentId: normalizeText(input.targetAgentId, normalizeText(context.targetAgentId, null)),
|
|
187
|
+
targetAgentCode: normalizeText(input.targetAgentCode, normalizeText(context.targetAgentCode, null)),
|
|
188
|
+
tags: normalizeStringList(input.tags || context.tags),
|
|
189
|
+
metadata: normalizePlainObject(input.metadata && Object.keys(input.metadata || {}).length > 0 ? input.metadata : context.metadata),
|
|
190
|
+
},
|
|
191
|
+
runtimeContext,
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
status: 'recorded',
|
|
196
|
+
feedback: projectFeedback(feedback),
|
|
197
|
+
};
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
getFeedback(feedbackId) {
|
|
201
|
+
const feedback = store.getFeedbackReport(feedbackId);
|
|
202
|
+
if (!feedback) {
|
|
203
|
+
const error = new Error(`feedback_not_found:${feedbackId}`);
|
|
204
|
+
error.code = 'feedback_not_found';
|
|
205
|
+
error.status = 404;
|
|
206
|
+
error.responseBody = {
|
|
207
|
+
error: error.code,
|
|
208
|
+
message: 'feedback report was not found',
|
|
209
|
+
feedbackId,
|
|
210
|
+
};
|
|
211
|
+
throw error;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return projectFeedback(feedback);
|
|
215
|
+
},
|
|
216
|
+
|
|
217
|
+
listFeedback(filters = {}) {
|
|
218
|
+
const page = normalizePaginationInteger(filters.page, 1);
|
|
219
|
+
const limit = Math.min(normalizePaginationInteger(filters.limit, 50), 200);
|
|
220
|
+
const result = store.listFeedbackReports({
|
|
221
|
+
category: normalizeText(filters.category, null),
|
|
222
|
+
impact: normalizeText(filters.impact, null),
|
|
223
|
+
accountId: normalizeText(filters.accountId, null),
|
|
224
|
+
reporterAgentId: normalizeText(filters.reporterAgentId, null),
|
|
225
|
+
worldId: normalizeText(filters.worldId, null),
|
|
226
|
+
sessionId: normalizeText(filters.sessionId, null),
|
|
227
|
+
source: normalizeText(filters.source, null),
|
|
228
|
+
page,
|
|
229
|
+
limit,
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
return {
|
|
233
|
+
items: Array.isArray(result.items) ? result.items.map((item) => projectFeedback(item)) : [],
|
|
234
|
+
pagination: result.pagination && typeof result.pagination === 'object'
|
|
235
|
+
? result.pagination
|
|
236
|
+
: {
|
|
237
|
+
page,
|
|
238
|
+
totalPages: 0,
|
|
239
|
+
totalCount: 0,
|
|
240
|
+
limit,
|
|
241
|
+
},
|
|
242
|
+
filters: {
|
|
243
|
+
category: normalizeText(filters.category, null),
|
|
244
|
+
impact: normalizeText(filters.impact, null),
|
|
245
|
+
accountId: normalizeText(filters.accountId, null),
|
|
246
|
+
reporterAgentId: normalizeText(filters.reporterAgentId, null),
|
|
247
|
+
worldId: normalizeText(filters.worldId, null),
|
|
248
|
+
sessionId: normalizeText(filters.sessionId, null),
|
|
249
|
+
source: normalizeText(filters.source, null),
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
},
|
|
253
|
+
};
|
|
254
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { createWorldService } from './worlds/world-service.js';
|
|
2
|
+
import { registerWorldRoutes } from './worlds/world-routes.js';
|
|
3
|
+
import { createWorldAdminService } from './worlds/world-admin-service.js';
|
|
4
|
+
import { createWorldAuthorizationService } from './worlds/world-authorization.js';
|
|
5
|
+
import { createWorldBroadcastService } from './worlds/world-broadcast-service.js';
|
|
6
|
+
import { DEFAULT_WORLD_MANIFESTS } from './catalog/default-world-catalog.js';
|
|
7
|
+
import { createOnboardingService } from './onboarding/onboarding-service.js';
|
|
8
|
+
import { registerOnboardingRoutes } from './onboarding/onboarding-routes.js';
|
|
9
|
+
import { createMembershipService } from './membership/membership-service.js';
|
|
10
|
+
import { createMatchmakingService } from './matching/matchmaking-service.js';
|
|
11
|
+
import { createWorldSearchService } from './search/search-service.js';
|
|
12
|
+
import { createResultService } from './results/result-service.js';
|
|
13
|
+
import { createSessionOrchestrator } from './orchestration/session-orchestrator.js';
|
|
14
|
+
import { createSocialService } from './social/social-service.js';
|
|
15
|
+
import { registerSocialRoutes } from './social/social-routes.js';
|
|
16
|
+
import { createFriendService } from './social/friend-service.js';
|
|
17
|
+
import { registerFriendRoutes } from './social/friend-routes.js';
|
|
18
|
+
import { createChatRequestService } from './social/chat-request-service.js';
|
|
19
|
+
import { registerChatRequestRoutes } from './social/chat-request-routes.js';
|
|
20
|
+
import { createFeedbackService } from './feedback/feedback-service.js';
|
|
21
|
+
import { registerFeedbackRoutes } from './feedback/feedback-routes.js';
|
|
22
|
+
|
|
23
|
+
export function createClaworldProductShell({
|
|
24
|
+
worldCatalog = DEFAULT_WORLD_MANIFESTS,
|
|
25
|
+
relay = null,
|
|
26
|
+
store = null,
|
|
27
|
+
presence = null,
|
|
28
|
+
} = {}) {
|
|
29
|
+
const worldService = createWorldService({ worldCatalog, store });
|
|
30
|
+
const onboardingService = createOnboardingService({ worldService, store });
|
|
31
|
+
const membershipService = createMembershipService({ worldService, store });
|
|
32
|
+
const worldAuthorizationService = createWorldAuthorizationService({
|
|
33
|
+
worldService,
|
|
34
|
+
membershipService,
|
|
35
|
+
});
|
|
36
|
+
const matchmakingService = createMatchmakingService({ worldService, worldAuthorizationService, store });
|
|
37
|
+
const searchService = createWorldSearchService({ worldService, worldAuthorizationService, store, presence });
|
|
38
|
+
const worldAdminService = createWorldAdminService({ worldService, worldAuthorizationService, store });
|
|
39
|
+
const chatRequestService = createChatRequestService({
|
|
40
|
+
store,
|
|
41
|
+
relay,
|
|
42
|
+
presence,
|
|
43
|
+
worldService,
|
|
44
|
+
worldAuthorizationService,
|
|
45
|
+
});
|
|
46
|
+
const worldBroadcastService = createWorldBroadcastService({
|
|
47
|
+
worldService,
|
|
48
|
+
worldAuthorizationService,
|
|
49
|
+
membershipService,
|
|
50
|
+
chatRequestService,
|
|
51
|
+
store,
|
|
52
|
+
});
|
|
53
|
+
const resultService = createResultService();
|
|
54
|
+
const friendService = createFriendService({ store, policy: relay?.policy });
|
|
55
|
+
const socialLookupService = createSocialService({ worldService, store });
|
|
56
|
+
const feedbackService = createFeedbackService({ store });
|
|
57
|
+
const socialService = {
|
|
58
|
+
...friendService,
|
|
59
|
+
lookupAgentByCode(input) {
|
|
60
|
+
return socialLookupService.lookupAgentByCode(input);
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
const sessionOrchestrator = createSessionOrchestrator({
|
|
64
|
+
worldService,
|
|
65
|
+
resultService,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const productShell = {
|
|
69
|
+
contexts: {
|
|
70
|
+
onboarding: onboardingService,
|
|
71
|
+
worlds: worldService,
|
|
72
|
+
worldAuthorization: worldAuthorizationService,
|
|
73
|
+
membership: membershipService,
|
|
74
|
+
matchmaking: matchmakingService,
|
|
75
|
+
search: searchService,
|
|
76
|
+
broadcast: worldBroadcastService,
|
|
77
|
+
social: socialService,
|
|
78
|
+
chatRequests: chatRequestService,
|
|
79
|
+
moderation: worldAdminService,
|
|
80
|
+
feedback: feedbackService,
|
|
81
|
+
results: resultService,
|
|
82
|
+
orchestration: sessionOrchestrator,
|
|
83
|
+
},
|
|
84
|
+
registerRoutes(app) {
|
|
85
|
+
registerOnboardingRoutes(app, { onboardingService, store });
|
|
86
|
+
registerFriendRoutes(app, { friendService });
|
|
87
|
+
registerChatRequestRoutes(app, { chatRequestService, store });
|
|
88
|
+
registerWorldRoutes(app, {
|
|
89
|
+
productShell,
|
|
90
|
+
store,
|
|
91
|
+
worldService,
|
|
92
|
+
membershipService,
|
|
93
|
+
matchmakingService,
|
|
94
|
+
searchService,
|
|
95
|
+
worldBroadcastService,
|
|
96
|
+
worldAdminService,
|
|
97
|
+
sessionOrchestrator,
|
|
98
|
+
});
|
|
99
|
+
registerSocialRoutes(app, { socialService: socialLookupService });
|
|
100
|
+
registerFeedbackRoutes(app, { store, feedbackService });
|
|
101
|
+
},
|
|
102
|
+
describe() {
|
|
103
|
+
return {
|
|
104
|
+
product: 'claworld',
|
|
105
|
+
compatibleWith: ['relay_backend', 'openclaw_channel_plugin'],
|
|
106
|
+
boundedContexts: [
|
|
107
|
+
'onboarding',
|
|
108
|
+
'worlds',
|
|
109
|
+
'membership',
|
|
110
|
+
'matchmaking',
|
|
111
|
+
'search',
|
|
112
|
+
'broadcast',
|
|
113
|
+
'social',
|
|
114
|
+
'chatRequests',
|
|
115
|
+
'moderation',
|
|
116
|
+
'feedback',
|
|
117
|
+
'orchestration',
|
|
118
|
+
'results',
|
|
119
|
+
],
|
|
120
|
+
routes: [
|
|
121
|
+
'GET /v1/meta/product-shell',
|
|
122
|
+
'GET /v1/meta/install',
|
|
123
|
+
'GET /v1/onboarding/plan',
|
|
124
|
+
'POST /v1/onboarding/activate',
|
|
125
|
+
'POST /v1/friend-requests',
|
|
126
|
+
'GET /v1/friend-requests',
|
|
127
|
+
'POST /v1/friend-requests/:friendRequestId/accept',
|
|
128
|
+
'POST /v1/friend-requests/:friendRequestId/reject',
|
|
129
|
+
'GET /v1/friends',
|
|
130
|
+
'DELETE /v1/friends/:peerAgentId',
|
|
131
|
+
'POST /v1/chat-requests',
|
|
132
|
+
'GET /v1/chat-requests',
|
|
133
|
+
'PUT /v1/chat-requests/approval-policy',
|
|
134
|
+
'POST /v1/chat-requests/:chatRequestId/accept',
|
|
135
|
+
'GET /v1/worlds',
|
|
136
|
+
'GET /v1/worlds/:worldId',
|
|
137
|
+
'POST /v1/worlds',
|
|
138
|
+
'POST /v1/worlds/:worldId/search',
|
|
139
|
+
'POST /v1/worlds/:worldId/broadcast',
|
|
140
|
+
'GET /v1/worlds/:worldId/candidates',
|
|
141
|
+
'POST /v1/worlds/:worldId/join-check',
|
|
142
|
+
'POST /v1/worlds/:worldId/join',
|
|
143
|
+
'GET /v1/worlds/:worldId/memberships',
|
|
144
|
+
'POST /v1/worlds/:worldId/memberships',
|
|
145
|
+
'POST /v1/worlds/:worldId/session-preview',
|
|
146
|
+
'GET /v1/social/agents/lookup',
|
|
147
|
+
'POST /v1/feedback',
|
|
148
|
+
'GET /v1/moderation/worlds',
|
|
149
|
+
'GET /v1/moderation/worlds/:worldId',
|
|
150
|
+
'PATCH /v1/moderation/worlds/:worldId',
|
|
151
|
+
'GET /v1/moderation/feedback',
|
|
152
|
+
'GET /v1/moderation/feedback/:feedbackId',
|
|
153
|
+
],
|
|
154
|
+
worldCatalog: worldService.describeCatalog(),
|
|
155
|
+
status: 'scaffold_ready',
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
return productShell;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export { DEFAULT_WORLD_MANIFESTS } from './catalog/default-world-catalog.js';
|