@xfxstudio/claworld 0.1.4 → 0.2.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 +12 -29
- package/openclaw.plugin.json +9 -33
- package/package.json +2 -10
- package/skills/claworld-help/SKILL.md +86 -160
- package/skills/claworld-join-and-chat/SKILL.md +107 -203
- package/skills/claworld-manage-worlds/SKILL.md +75 -392
- package/src/lib/chat-request.js +347 -0
- package/src/lib/{accepted-chat-kickoff.js → relay/kickoff-text.js} +67 -26
- package/src/openclaw/index.js +0 -5
- package/src/openclaw/installer/cli.js +14 -16
- package/src/openclaw/installer/core.js +13 -14
- package/src/openclaw/installer/doctor.js +69 -31
- package/src/openclaw/installer/workspace-contract.js +33 -9
- package/src/openclaw/plugin/claworld-channel-plugin.js +156 -625
- package/src/openclaw/plugin/config-schema.js +4 -16
- package/src/openclaw/plugin/managed-config.js +127 -75
- package/src/openclaw/plugin/onboarding.js +7 -3
- package/src/openclaw/plugin/register.js +40 -339
- package/src/openclaw/plugin/relay-client.js +112 -102
- package/src/openclaw/protocol/relay-event-protocol.js +34 -22
- package/src/openclaw/runtime/canonical-result-builder.js +15 -5
- package/src/openclaw/runtime/demo-session-bootstrap.js +0 -4
- package/src/openclaw/runtime/feedback-helper.js +3 -2
- package/src/openclaw/runtime/inbound-session-router.js +28 -20
- package/src/openclaw/runtime/outbound-session-bridge.js +21 -9
- package/src/openclaw/runtime/product-shell-helper.js +45 -637
- package/src/openclaw/runtime/runtime-path.js +2 -2
- package/src/openclaw/runtime/system-message-orchestrator.js +1 -1
- package/src/openclaw/runtime/tool-contracts.js +36 -258
- package/src/openclaw/runtime/world-moderation-helper.js +11 -65
- package/src/product-shell/catalog/default-world-catalog.js +15 -33
- package/src/product-shell/contracts/candidate-feed.js +40 -5
- package/src/product-shell/contracts/chat-request-approval-policy.js +3 -3
- package/src/product-shell/contracts/world-manifest.js +134 -161
- package/src/product-shell/contracts/world-orchestration.js +55 -326
- package/src/product-shell/feedback/feedback-routes.js +4 -3
- package/src/product-shell/feedback/feedback-service.js +11 -8
- package/src/product-shell/index.js +6 -7
- package/src/product-shell/matching/matchmaking-service.js +39 -5
- package/src/product-shell/membership/membership-service.js +125 -147
- package/src/product-shell/onboarding/onboarding-service.js +2 -2
- package/src/product-shell/orchestration/world-conversation-orchestrator.js +30 -0
- package/src/product-shell/orchestration/world-conversation-text.js +231 -0
- package/src/product-shell/results/result-service.js +9 -3
- package/src/product-shell/search/search-service.js +28 -1
- package/src/product-shell/social/chat-request-routes.js +0 -1
- package/src/product-shell/social/chat-request-service.js +1 -102
- package/src/product-shell/worlds/world-admin-service.js +86 -277
- package/src/product-shell/worlds/world-authorization.js +3 -5
- package/src/product-shell/worlds/world-routes.js +8 -38
- package/src/product-shell/worlds/world-service.js +3 -3
- package/src/product-shell/worlds/world-text.js +77 -0
- package/src/lib/runtime-guidance.js +0 -457
- package/src/openclaw/runtime/world-session-startup.js +0 -1
- package/src/product-shell/orchestration/session-orchestrator.js +0 -38
|
@@ -7,6 +7,7 @@ export const CANDIDATE_OBJECT_FIELDS = Object.freeze([
|
|
|
7
7
|
'worldId',
|
|
8
8
|
'targetAgentId',
|
|
9
9
|
'sourceMembershipId',
|
|
10
|
+
'online',
|
|
10
11
|
'requestChat',
|
|
11
12
|
'profileSummary',
|
|
12
13
|
'compatibilitySignals',
|
|
@@ -100,6 +101,16 @@ function normalizeComparableText(value) {
|
|
|
100
101
|
return normalizeText(value, null)?.toLowerCase() || null;
|
|
101
102
|
}
|
|
102
103
|
|
|
104
|
+
function tokenizeText(value) {
|
|
105
|
+
return [...new Set(
|
|
106
|
+
String(value || '')
|
|
107
|
+
.toLowerCase()
|
|
108
|
+
.split(/[^a-z0-9\u4e00-\u9fff]+/i)
|
|
109
|
+
.map((entry) => entry.trim())
|
|
110
|
+
.filter((entry) => entry.length >= 2),
|
|
111
|
+
)];
|
|
112
|
+
}
|
|
113
|
+
|
|
103
114
|
function projectSummaryField(field = {}, profile = {}) {
|
|
104
115
|
const normalizedValue = normalizeValue(profile[field.fieldId], field);
|
|
105
116
|
if (normalizedValue == null) return null;
|
|
@@ -115,7 +126,7 @@ function projectSummaryField(field = {}, profile = {}) {
|
|
|
115
126
|
function projectProfileSummary(world, profile = {}, agent = null) {
|
|
116
127
|
return {
|
|
117
128
|
displayName: normalizeText(agent?.displayName, null),
|
|
118
|
-
headline: normalizeText(profile.headline, null),
|
|
129
|
+
headline: normalizeText(profile.participantContextText, normalizeText(profile.headline, null)),
|
|
119
130
|
requiredFields: world.joinSchema.requiredFields
|
|
120
131
|
.map((field) => projectSummaryField(field, profile))
|
|
121
132
|
.filter(Boolean),
|
|
@@ -136,6 +147,21 @@ function createCompatibilitySignal({ sourceMembershipId, type, fieldIds, score,
|
|
|
136
147
|
}
|
|
137
148
|
|
|
138
149
|
function compareFieldValues(field, viewerValue, candidateValue, sourceMembershipId) {
|
|
150
|
+
if (field.fieldId === 'participantContextText') {
|
|
151
|
+
const viewerTokens = tokenizeText(viewerValue);
|
|
152
|
+
const candidateTokens = tokenizeText(candidateValue);
|
|
153
|
+
const sharedItems = viewerTokens.filter((item) => candidateTokens.includes(item));
|
|
154
|
+
if (sharedItems.length === 0) return null;
|
|
155
|
+
|
|
156
|
+
return createCompatibilitySignal({
|
|
157
|
+
sourceMembershipId,
|
|
158
|
+
type: 'field_overlap',
|
|
159
|
+
fieldIds: [field.fieldId],
|
|
160
|
+
score: Math.min(sharedItems.length * 0.08, 0.48),
|
|
161
|
+
summary: `Shared context: ${sharedItems.slice(0, 6).join(', ')}.`,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
139
165
|
if (field.type === 'string[]') {
|
|
140
166
|
const viewerItems = normalizeComparableArray(viewerValue);
|
|
141
167
|
const candidateItems = normalizeComparableArray(candidateValue);
|
|
@@ -180,7 +206,7 @@ function buildCompatibilitySignals(world, viewerProfile = {}, candidateProfile =
|
|
|
180
206
|
type: 'world_ready',
|
|
181
207
|
fieldIds: [],
|
|
182
208
|
score: 0.05,
|
|
183
|
-
summary: 'Candidate
|
|
209
|
+
summary: 'Candidate is online with an active world membership and is ready for agent review before live session handoff.',
|
|
184
210
|
}),
|
|
185
211
|
];
|
|
186
212
|
}
|
|
@@ -192,7 +218,7 @@ function buildDeliveryReason(signals = []) {
|
|
|
192
218
|
return {
|
|
193
219
|
code: 'world_membership_ready',
|
|
194
220
|
matchedFieldIds: [],
|
|
195
|
-
summary: 'Delivered for manual review because the candidate is active in this world, even though no direct profile overlap signal was detected yet.',
|
|
221
|
+
summary: 'Delivered for manual review because the candidate is online and active in this world, even though no direct profile overlap signal was detected yet.',
|
|
196
222
|
};
|
|
197
223
|
}
|
|
198
224
|
|
|
@@ -264,7 +290,7 @@ export function projectCandidateFeedModel(world) {
|
|
|
264
290
|
},
|
|
265
291
|
liveDeliveryEvent: projectLiveDeliveryEvent(world, candidateFields),
|
|
266
292
|
summary:
|
|
267
|
-
'Active members can review candidate opportunities first, then call request_chat with the selected targetAgentId when they want to start a world-scoped conversation request.',
|
|
293
|
+
'Active online members can review candidate opportunities first, then call request_chat with the selected targetAgentId when they want to start a world-scoped conversation request.',
|
|
268
294
|
status: 'phase1_candidate_feed',
|
|
269
295
|
};
|
|
270
296
|
}
|
|
@@ -274,6 +300,7 @@ function projectCandidateOpportunity({
|
|
|
274
300
|
viewerProfile,
|
|
275
301
|
candidateMembership,
|
|
276
302
|
candidateAgent,
|
|
303
|
+
candidatePresence,
|
|
277
304
|
expiresAt,
|
|
278
305
|
}) {
|
|
279
306
|
const profileSnapshot = candidateMembership.profileSnapshot || {};
|
|
@@ -290,6 +317,7 @@ function projectCandidateOpportunity({
|
|
|
290
317
|
worldId: world.worldId,
|
|
291
318
|
sourceMembershipId: candidateMembership.membershipId,
|
|
292
319
|
targetAgentId: requestChat?.targetAgentId || null,
|
|
320
|
+
online: candidatePresence?.online === true,
|
|
293
321
|
requestChat,
|
|
294
322
|
profileSummary: projectProfileSummary(world, profileSnapshot, candidateAgent),
|
|
295
323
|
compatibilitySignals,
|
|
@@ -304,6 +332,7 @@ export function buildCandidateFeed({
|
|
|
304
332
|
viewerAgent = null,
|
|
305
333
|
candidateMemberships = [],
|
|
306
334
|
getAgent = () => null,
|
|
335
|
+
getPresence = () => ({ online: true }),
|
|
307
336
|
nowMs = Date.now(),
|
|
308
337
|
limit = DEFAULT_CANDIDATE_FEED_LIMIT,
|
|
309
338
|
}) {
|
|
@@ -315,12 +344,18 @@ export function buildCandidateFeed({
|
|
|
315
344
|
|
|
316
345
|
const candidates = candidateMemberships
|
|
317
346
|
.filter((membership) => membership?.status === 'active' && membership.membershipId !== viewerMembership.membershipId)
|
|
318
|
-
.map((membership) => {
|
|
347
|
+
.map((membership) => ({
|
|
348
|
+
membership,
|
|
349
|
+
candidatePresence: getPresence(membership.agentId),
|
|
350
|
+
}))
|
|
351
|
+
.filter(({ candidatePresence }) => candidatePresence?.online === true)
|
|
352
|
+
.map(({ membership, candidatePresence }) => {
|
|
319
353
|
const opportunity = projectCandidateOpportunity({
|
|
320
354
|
world,
|
|
321
355
|
viewerProfile,
|
|
322
356
|
candidateMembership: membership,
|
|
323
357
|
candidateAgent: getAgent(membership.agentId),
|
|
358
|
+
candidatePresence,
|
|
324
359
|
expiresAt,
|
|
325
360
|
});
|
|
326
361
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const DEFAULT_MODE = '
|
|
1
|
+
const DEFAULT_MODE = 'open';
|
|
2
2
|
const SUPPORTED_MODES = Object.freeze([
|
|
3
3
|
DEFAULT_MODE,
|
|
4
4
|
'world_only',
|
|
@@ -45,7 +45,7 @@ export function normalizeChatRequestApprovalMode(value, fallback = DEFAULT_MODE)
|
|
|
45
45
|
case 'manual':
|
|
46
46
|
case 'manual_review':
|
|
47
47
|
case 'review':
|
|
48
|
-
return
|
|
48
|
+
return 'manual_review';
|
|
49
49
|
case 'world':
|
|
50
50
|
case 'world_only':
|
|
51
51
|
return 'world_only';
|
|
@@ -88,7 +88,7 @@ export function normalizeChatRequestApprovalPolicy(
|
|
|
88
88
|
: normalizedLegacyAutoAccept === true
|
|
89
89
|
? 'open'
|
|
90
90
|
: normalizedLegacyAutoAccept === false
|
|
91
|
-
?
|
|
91
|
+
? 'manual_review'
|
|
92
92
|
: normalizeChatRequestApprovalMode(fallbackMode, DEFAULT_MODE);
|
|
93
93
|
|
|
94
94
|
return {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { projectCandidateFeedModel } from './candidate-feed.js';
|
|
2
2
|
import { buildWorldSessionStartupText } from './world-orchestration.js';
|
|
3
|
+
import { buildWorldContextText } from '../worlds/world-text.js';
|
|
3
4
|
|
|
4
5
|
function normalizeText(value, fallback = null) {
|
|
5
6
|
if (value == null) return fallback;
|
|
@@ -12,6 +13,24 @@ function normalizeStringList(values = []) {
|
|
|
12
13
|
return [...new Set(values.map((value) => normalizeText(value, null)).filter(Boolean))];
|
|
13
14
|
}
|
|
14
15
|
|
|
16
|
+
function normalizeCandidateSource(value) {
|
|
17
|
+
const normalized = normalizeText(value, null);
|
|
18
|
+
if (!normalized) return null;
|
|
19
|
+
if (
|
|
20
|
+
normalized === 'active_memberships'
|
|
21
|
+
|| normalized === 'world_members'
|
|
22
|
+
|| normalized === 'search_results'
|
|
23
|
+
) {
|
|
24
|
+
return 'active_memberships_online';
|
|
25
|
+
}
|
|
26
|
+
return normalized;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function normalizeCandidateSources(values = []) {
|
|
30
|
+
if (!Array.isArray(values)) return [];
|
|
31
|
+
return [...new Set(values.map((value) => normalizeCandidateSource(value)).filter(Boolean))];
|
|
32
|
+
}
|
|
33
|
+
|
|
15
34
|
function normalizeWorldEligibility(value, fallback = 'active') {
|
|
16
35
|
const normalized = normalizeText(value, fallback);
|
|
17
36
|
if (normalized === 'joined') return 'joined';
|
|
@@ -78,17 +97,21 @@ function normalizeExampleSignals(exampleSignals = {}) {
|
|
|
78
97
|
}
|
|
79
98
|
|
|
80
99
|
function normalizeJoinSchema(joinSchema = {}) {
|
|
81
|
-
const requiredFields = Array.isArray(joinSchema.requiredFields)
|
|
82
|
-
? joinSchema.requiredFields.map((field, index) => normalizeField(field, index, { required: true }))
|
|
83
|
-
: [];
|
|
84
|
-
const optionalFields = Array.isArray(joinSchema.optionalFields)
|
|
85
|
-
? joinSchema.optionalFields.map((field, index) => normalizeField(field, index, { required: false }))
|
|
86
|
-
: [];
|
|
87
|
-
|
|
88
100
|
return {
|
|
89
|
-
requiredFields
|
|
90
|
-
|
|
91
|
-
|
|
101
|
+
requiredFields: [
|
|
102
|
+
{
|
|
103
|
+
fieldId: 'participantContextText',
|
|
104
|
+
label: 'Entry Profile',
|
|
105
|
+
type: 'string',
|
|
106
|
+
source: 'membership',
|
|
107
|
+
required: true,
|
|
108
|
+
description: 'Free-form participant profile/context text used for world join, search, and candidate review.',
|
|
109
|
+
examples: [],
|
|
110
|
+
constraints: {},
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
optionalFields: [],
|
|
114
|
+
hints: [],
|
|
92
115
|
};
|
|
93
116
|
}
|
|
94
117
|
|
|
@@ -139,12 +162,25 @@ function normalizeSearchSchema(searchSchema = {}, joinSchema = {}) {
|
|
|
139
162
|
};
|
|
140
163
|
}
|
|
141
164
|
|
|
165
|
+
function resolveConversationTemplateInput(manifest = {}) {
|
|
166
|
+
if (manifest.conversationTemplate && typeof manifest.conversationTemplate === 'object' && !Array.isArray(manifest.conversationTemplate)) {
|
|
167
|
+
return manifest.conversationTemplate;
|
|
168
|
+
}
|
|
169
|
+
return {};
|
|
170
|
+
}
|
|
171
|
+
|
|
142
172
|
export function normalizeWorldManifest(manifest = {}, index = 0) {
|
|
143
173
|
const worldId = normalizeText(manifest.worldId || manifest.id, `world_${index + 1}`);
|
|
144
174
|
const joinSchema = normalizeJoinSchema(manifest.joinSchema);
|
|
145
175
|
const searchSchema = normalizeSearchSchema(manifest.searchSchema, joinSchema);
|
|
146
|
-
const
|
|
147
|
-
const
|
|
176
|
+
const conversationTemplate = resolveConversationTemplateInput(manifest);
|
|
177
|
+
const defaultInteractionRules = normalizeText(conversationTemplate?.worldRules?.openingText, null);
|
|
178
|
+
const normalizedInteractionRules = normalizeText(manifest.interactionRules, defaultInteractionRules);
|
|
179
|
+
const normalizedProhibitedRules = normalizeText(manifest.prohibitedRules, null);
|
|
180
|
+
const normalizedRatingRules = normalizeText(
|
|
181
|
+
manifest.ratingRules,
|
|
182
|
+
'After the interaction ends, each agent should rate the other participant from 1 to 10 based on fit, clarity, and rule compliance.',
|
|
183
|
+
);
|
|
148
184
|
|
|
149
185
|
return {
|
|
150
186
|
worldId,
|
|
@@ -155,12 +191,21 @@ export function normalizeWorldManifest(manifest = {}, index = 0) {
|
|
|
155
191
|
category: normalizeText(manifest.category, 'general'),
|
|
156
192
|
lifecycle: normalizeText(manifest.lifecycle, 'scaffold'),
|
|
157
193
|
tags: normalizeStringList(manifest.tags),
|
|
158
|
-
interactionRules:
|
|
159
|
-
prohibitedRules:
|
|
160
|
-
ratingRules:
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
194
|
+
interactionRules: normalizedInteractionRules,
|
|
195
|
+
prohibitedRules: normalizedProhibitedRules,
|
|
196
|
+
ratingRules: normalizedRatingRules,
|
|
197
|
+
worldContextText: buildWorldContextText({
|
|
198
|
+
worldId,
|
|
199
|
+
displayName: normalizeText(manifest.displayName, worldId),
|
|
200
|
+
summary: normalizeText(manifest.summary, null),
|
|
201
|
+
worldContextText: normalizeText(
|
|
202
|
+
manifest.worldContextText,
|
|
203
|
+
normalizeText(manifest.runtimeWorldContext?.text, null),
|
|
204
|
+
),
|
|
205
|
+
interactionRules: normalizedInteractionRules,
|
|
206
|
+
prohibitedRules: normalizedProhibitedRules,
|
|
207
|
+
ratingRules: normalizedRatingRules,
|
|
208
|
+
}),
|
|
164
209
|
creatorAgentId: normalizeText(manifest.creatorAgentId, null),
|
|
165
210
|
adminAgentIds: normalizeStringList(manifest.adminAgentIds),
|
|
166
211
|
eligibility: normalizeWorldEligibility(manifest.eligibility, 'active'),
|
|
@@ -188,27 +233,17 @@ export function normalizeWorldManifest(manifest = {}, index = 0) {
|
|
|
188
233
|
mode: normalizeText(manifest.matching?.mode, 'manual_review'),
|
|
189
234
|
cadence: normalizeText(manifest.matching?.cadence, 'on_demand'),
|
|
190
235
|
strategySummary: normalizeText(manifest.matching?.strategySummary, null),
|
|
191
|
-
candidateSources:
|
|
236
|
+
candidateSources: normalizeCandidateSources(manifest.matching?.candidateSources),
|
|
192
237
|
},
|
|
193
|
-
|
|
194
|
-
mode: normalizeText(
|
|
195
|
-
maxTurns: Number.isFinite(Number(manifest.sessionTemplate?.maxTurns))
|
|
196
|
-
? Math.max(1, Number(manifest.sessionTemplate.maxTurns))
|
|
197
|
-
: 6,
|
|
198
|
-
turnTimeoutMs: Number.isFinite(Number(manifest.sessionTemplate?.turnTimeoutMs))
|
|
199
|
-
? Math.max(1000, Number(manifest.sessionTemplate.turnTimeoutMs))
|
|
200
|
-
: 60_000,
|
|
201
|
-
raiseHandPolicy: {
|
|
202
|
-
mode: normalizeText(manifest.sessionTemplate?.raiseHandPolicy?.mode, 'dual_raise_hand'),
|
|
203
|
-
summary: normalizeText(manifest.sessionTemplate?.raiseHandPolicy?.summary, null),
|
|
204
|
-
},
|
|
238
|
+
conversationTemplate: {
|
|
239
|
+
mode: normalizeText(conversationTemplate?.mode, 'a2a'),
|
|
205
240
|
worldRules: {
|
|
206
|
-
openingText: normalizeText(
|
|
207
|
-
turnMessageRules: Array.isArray(
|
|
208
|
-
?
|
|
241
|
+
openingText: normalizeText(conversationTemplate?.worldRules?.openingText, null),
|
|
242
|
+
turnMessageRules: Array.isArray(conversationTemplate?.worldRules?.turnMessageRules)
|
|
243
|
+
? conversationTemplate.worldRules.turnMessageRules
|
|
209
244
|
: [],
|
|
210
|
-
convergence:
|
|
211
|
-
stateChangeMessages:
|
|
245
|
+
convergence: conversationTemplate?.worldRules?.convergence || {},
|
|
246
|
+
stateChangeMessages: conversationTemplate?.worldRules?.stateChangeMessages || {},
|
|
212
247
|
},
|
|
213
248
|
},
|
|
214
249
|
resultContract: {
|
|
@@ -225,40 +260,26 @@ export function normalizeWorldManifest(manifest = {}, index = 0) {
|
|
|
225
260
|
}
|
|
226
261
|
|
|
227
262
|
export function projectWorldCard(world) {
|
|
228
|
-
const agentSummary = {
|
|
229
|
-
displayName: world.displayName,
|
|
230
|
-
summary: world.summary,
|
|
231
|
-
category: world.category,
|
|
232
|
-
requiredFieldCount: world.joinSchema.requiredFields.length,
|
|
233
|
-
matchingMode: world.matching.mode,
|
|
234
|
-
sessionMode: world.sessionTemplate.mode,
|
|
235
|
-
};
|
|
236
|
-
|
|
237
263
|
return {
|
|
238
264
|
worldId: world.worldId,
|
|
239
265
|
slug: world.slug,
|
|
240
|
-
displayName:
|
|
241
|
-
|
|
242
|
-
category: agentSummary.category,
|
|
243
|
-
lifecycle: world.lifecycle,
|
|
244
|
-
tags: world.tags,
|
|
245
|
-
requiredFieldCount: agentSummary.requiredFieldCount,
|
|
246
|
-
roleCount: world.roles.length,
|
|
247
|
-
matchingMode: agentSummary.matchingMode,
|
|
248
|
-
sessionMode: agentSummary.sessionMode,
|
|
266
|
+
displayName: world.displayName,
|
|
267
|
+
worldContextText: world.worldContextText,
|
|
249
268
|
createdAt: world.createdAt || null,
|
|
250
269
|
updatedAt: world.updatedAt || null,
|
|
251
|
-
status: world.meta.status,
|
|
252
|
-
|
|
270
|
+
status: world.status || world.meta.status,
|
|
271
|
+
enabled: world.enabled === true,
|
|
253
272
|
};
|
|
254
273
|
}
|
|
255
274
|
|
|
256
275
|
export function projectJoinPlan(world) {
|
|
257
276
|
return {
|
|
258
277
|
worldId: world.worldId,
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
278
|
+
participantContextField: {
|
|
279
|
+
fieldId: 'participantContextText',
|
|
280
|
+
label: 'Entry Profile',
|
|
281
|
+
description: 'A short text describing who you are in this world and what context you bring into it.',
|
|
282
|
+
},
|
|
262
283
|
nextAction: 'call_join_world',
|
|
263
284
|
};
|
|
264
285
|
}
|
|
@@ -296,140 +317,92 @@ export function projectSearchModel(world) {
|
|
|
296
317
|
|
|
297
318
|
export function projectWorldDetail(world) {
|
|
298
319
|
const joinPlan = projectJoinPlan(world);
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
const candidateFeedOverview = projectCandidateFeedModel(world);
|
|
303
|
-
const searchSchema = projectSearchModel(world);
|
|
304
|
-
const runtimeStartupContext = {
|
|
305
|
-
worldId: world.worldId,
|
|
306
|
-
status: 'ready',
|
|
307
|
-
source: 'product_shell_session_startup',
|
|
308
|
-
text: buildWorldSessionStartupText({
|
|
320
|
+
const worldContextText = normalizeText(
|
|
321
|
+
world.worldContextText,
|
|
322
|
+
buildWorldSessionStartupText({
|
|
309
323
|
worldId: world.worldId,
|
|
310
324
|
displayName: world.displayName,
|
|
311
325
|
summary: world.summary,
|
|
312
326
|
interactionRules: world.interactionRules,
|
|
313
327
|
prohibitedRules: world.prohibitedRules,
|
|
314
328
|
ratingRules: world.ratingRules,
|
|
315
|
-
|
|
316
|
-
|
|
329
|
+
conversationMode: world.conversationTemplate.mode,
|
|
330
|
+
conversationOverview: {
|
|
317
331
|
worldId: world.worldId,
|
|
318
|
-
mode: world.
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
raiseHandPolicy: world.sessionTemplate.raiseHandPolicy,
|
|
322
|
-
openingText: world.sessionTemplate.worldRules.openingText,
|
|
323
|
-
convergence: world.sessionTemplate.worldRules.convergence,
|
|
332
|
+
mode: world.conversationTemplate.mode,
|
|
333
|
+
openingText: world.conversationTemplate.worldRules.openingText,
|
|
334
|
+
convergence: world.conversationTemplate.worldRules.convergence,
|
|
324
335
|
},
|
|
325
336
|
}),
|
|
326
|
-
|
|
337
|
+
);
|
|
327
338
|
|
|
328
339
|
return {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
displayName: world.displayName,
|
|
332
|
-
summary: world.summary,
|
|
333
|
-
category: world.category,
|
|
334
|
-
requiredFieldCount: world.joinSchema.requiredFields.length,
|
|
335
|
-
optionalFieldCount: world.joinSchema.optionalFields.length,
|
|
336
|
-
matchingMode: world.matching.mode,
|
|
337
|
-
sessionMode: world.sessionTemplate.mode,
|
|
338
|
-
},
|
|
339
|
-
joinSchema: {
|
|
340
|
-
worldId: world.worldId,
|
|
341
|
-
requiredFields: world.joinSchema.requiredFields,
|
|
342
|
-
optionalFields: world.joinSchema.optionalFields,
|
|
343
|
-
requiredFieldIds: requiredFieldGuide.map((field) => field.fieldId),
|
|
344
|
-
optionalFieldIds: optionalFieldGuide.map((field) => field.fieldId),
|
|
345
|
-
requiredFieldCount: requiredFieldGuide.length,
|
|
346
|
-
optionalFieldCount: optionalFieldGuide.length,
|
|
347
|
-
hints: world.joinSchema.hints,
|
|
348
|
-
nextAction: joinPlan.nextAction,
|
|
349
|
-
},
|
|
350
|
-
fieldGuide: {
|
|
351
|
-
required: requiredFieldGuide,
|
|
352
|
-
optional: optionalFieldGuide,
|
|
353
|
-
allFields: allFieldGuide,
|
|
354
|
-
},
|
|
355
|
-
sessionOverview: {
|
|
340
|
+
worldId: world.worldId,
|
|
341
|
+
world: {
|
|
356
342
|
worldId: world.worldId,
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
turnTimeoutMs: world.sessionTemplate.turnTimeoutMs,
|
|
360
|
-
raiseHandPolicy: world.sessionTemplate.raiseHandPolicy,
|
|
361
|
-
openingText: world.sessionTemplate.worldRules.openingText,
|
|
362
|
-
convergence: world.sessionTemplate.worldRules.convergence,
|
|
363
|
-
turnMessageRules: world.sessionTemplate.worldRules.turnMessageRules,
|
|
364
|
-
expectationSummary:
|
|
365
|
-
`Expect a ${world.sessionTemplate.mode} session with up to ${world.sessionTemplate.maxTurns} turns and ` +
|
|
366
|
-
`a ${world.sessionTemplate.turnTimeoutMs}ms turn timeout before the world asks both agents to converge.`,
|
|
367
|
-
status: 'scaffold_ready',
|
|
343
|
+
displayName: world.displayName,
|
|
344
|
+
worldContextText,
|
|
368
345
|
},
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
status: 'scaffold_ready',
|
|
346
|
+
management: {
|
|
347
|
+
ownerAgentId: world.creatorAgentId || null,
|
|
348
|
+
enabled: world.enabled === true,
|
|
349
|
+
status: world.status || world.meta.status,
|
|
350
|
+
createdAt: world.createdAt || null,
|
|
351
|
+
updatedAt: world.updatedAt || null,
|
|
352
|
+
memberCount: world.metrics?.memberCount || null,
|
|
353
|
+
totalConversationCount: Number.isFinite(Number(world.metrics?.totalConversationCount))
|
|
354
|
+
? Math.max(0, Math.trunc(Number(world.metrics.totalConversationCount)))
|
|
355
|
+
: 0,
|
|
380
356
|
},
|
|
381
|
-
|
|
382
|
-
candidateFeedOverview,
|
|
357
|
+
participantContextField: joinPlan.participantContextField,
|
|
383
358
|
joinPlan,
|
|
384
|
-
|
|
359
|
+
worldContextText,
|
|
385
360
|
};
|
|
386
361
|
}
|
|
387
362
|
|
|
388
|
-
export function
|
|
389
|
-
const
|
|
363
|
+
export function projectConversationWorldContext(world) {
|
|
364
|
+
const runtimeWorldContext = {
|
|
390
365
|
worldId: world.worldId,
|
|
391
366
|
status: 'ready',
|
|
392
|
-
source: '
|
|
393
|
-
text:
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
summary: world.summary,
|
|
397
|
-
interactionRules: world.interactionRules,
|
|
398
|
-
prohibitedRules: world.prohibitedRules,
|
|
399
|
-
ratingRules: world.ratingRules,
|
|
400
|
-
sessionMode: world.sessionTemplate.mode,
|
|
401
|
-
sessionOverview: {
|
|
367
|
+
source: 'product_shell_conversation_world_context',
|
|
368
|
+
text: normalizeText(
|
|
369
|
+
world.worldContextText,
|
|
370
|
+
buildWorldSessionStartupText({
|
|
402
371
|
worldId: world.worldId,
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
372
|
+
displayName: world.displayName,
|
|
373
|
+
summary: world.summary,
|
|
374
|
+
interactionRules: world.interactionRules,
|
|
375
|
+
prohibitedRules: world.prohibitedRules,
|
|
376
|
+
ratingRules: world.ratingRules,
|
|
377
|
+
conversationMode: world.conversationTemplate.mode,
|
|
378
|
+
conversationOverview: {
|
|
379
|
+
worldId: world.worldId,
|
|
380
|
+
mode: world.conversationTemplate.mode,
|
|
381
|
+
openingText: world.conversationTemplate.worldRules.openingText,
|
|
382
|
+
convergence: world.conversationTemplate.worldRules.convergence,
|
|
383
|
+
},
|
|
384
|
+
}),
|
|
385
|
+
),
|
|
411
386
|
};
|
|
412
387
|
|
|
413
388
|
return {
|
|
414
389
|
worldId: world.worldId,
|
|
415
390
|
displayName: world.displayName,
|
|
416
391
|
summary: world.summary,
|
|
392
|
+
worldContextText: runtimeWorldContext.text,
|
|
417
393
|
interactionRules: world.interactionRules,
|
|
418
394
|
prohibitedRules: world.prohibitedRules,
|
|
419
395
|
ratingRules: world.ratingRules,
|
|
420
|
-
|
|
421
|
-
|
|
396
|
+
conversationMode: world.conversationTemplate.mode,
|
|
397
|
+
conversationOverview: {
|
|
422
398
|
worldId: world.worldId,
|
|
423
|
-
mode: world.
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
openingText: world.sessionTemplate.worldRules.openingText,
|
|
428
|
-
convergence: world.sessionTemplate.worldRules.convergence,
|
|
429
|
-
turnMessageRules: world.sessionTemplate.worldRules.turnMessageRules,
|
|
399
|
+
mode: world.conversationTemplate.mode,
|
|
400
|
+
openingText: world.conversationTemplate.worldRules.openingText,
|
|
401
|
+
convergence: world.conversationTemplate.worldRules.convergence,
|
|
402
|
+
turnMessageRules: world.conversationTemplate.worldRules.turnMessageRules,
|
|
430
403
|
},
|
|
431
404
|
status: 'ready',
|
|
432
|
-
source: '
|
|
433
|
-
|
|
405
|
+
source: 'product_shell_conversation_world_context',
|
|
406
|
+
runtimeWorldContext,
|
|
434
407
|
};
|
|
435
408
|
}
|