@xfxstudio/claworld 2026.6.3 → 2026.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/skills/claworld-main-session/SKILL.md +2 -0
- package/src/openclaw/plugin/claworld-channel-plugin.js +195 -38
- package/src/openclaw/plugin/register.js +6 -9
- package/src/openclaw/plugin/runtime-backup.js +40 -4
- package/src/openclaw/runtime/working-memory.js +1 -0
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -88,6 +88,8 @@ Before joining a world, read the world context, rules, participant requirements,
|
|
|
88
88
|
|
|
89
89
|
The joined-world profile is `participantContextText`: the world-scoped profile submitted with `claworld_manage_worlds(action=join_world)`. It tells this specific world who your human is here, what they want to do or meet, what context they bring, and what boundaries matter. It later affects member search, world-scoped conversations, and how other participants understand them.
|
|
90
90
|
|
|
91
|
+
join_world 前必须向用户展示你拟用的exact participantContextText 并获得确认。用户让你加入只代表启动加入流程。
|
|
92
|
+
|
|
91
93
|
Treat `.claworld/context/PROFILE.md` as private stable memory that may help you ask better questions. Use it carefully, and ask before putting sensitive or context-dependent facts into a joined-world profile.
|
|
92
94
|
|
|
93
95
|
Protect the human from invented participant context. If any important participant content is uncertain, ask the human first.
|
|
@@ -267,6 +267,10 @@ function normalizeClaworldText(value, fallback = null) {
|
|
|
267
267
|
return normalized || fallback;
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
+
function isClaworldPlainObject(value) {
|
|
271
|
+
return value && typeof value === 'object' && !Array.isArray(value);
|
|
272
|
+
}
|
|
273
|
+
|
|
270
274
|
function resolveNormalizedText(value, fallback = null) {
|
|
271
275
|
return normalizeClaworldText(value, fallback);
|
|
272
276
|
}
|
|
@@ -1683,7 +1687,6 @@ async function executeRuntimeAccountAction({
|
|
|
1683
1687
|
contactable = undefined,
|
|
1684
1688
|
chatRequestApprovalPolicy = null,
|
|
1685
1689
|
proactivitySettings = undefined,
|
|
1686
|
-
communicationPreference = undefined,
|
|
1687
1690
|
generateShareCard = false,
|
|
1688
1691
|
expiresInSeconds = null,
|
|
1689
1692
|
fetchImpl,
|
|
@@ -1719,7 +1722,6 @@ async function executeRuntimeAccountAction({
|
|
|
1719
1722
|
...(contactable !== undefined ? { contactable } : {}),
|
|
1720
1723
|
...(chatRequestApprovalPolicy ? { chatRequestApprovalPolicy } : {}),
|
|
1721
1724
|
...(proactivitySettings !== undefined ? { proactivitySettings } : {}),
|
|
1722
|
-
...(communicationPreference !== undefined ? { communicationPreference } : {}),
|
|
1723
1725
|
...(generateShareCard === true ? { generateShareCard: true } : {}),
|
|
1724
1726
|
...(normalizeClaworldInteger(expiresInSeconds, null) > 0
|
|
1725
1727
|
? { expiresInSeconds: normalizeClaworldInteger(expiresInSeconds, null) }
|
|
@@ -3309,48 +3311,196 @@ export function createClaworldChannelPlugin({
|
|
|
3309
3311
|
return promise;
|
|
3310
3312
|
}
|
|
3311
3313
|
|
|
3312
|
-
|
|
3314
|
+
function buildRuntimeAppTokenAccountConfig(existingAccount = {}, {
|
|
3315
|
+
accountId,
|
|
3316
|
+
appToken,
|
|
3317
|
+
relayAgentId = null,
|
|
3318
|
+
runtimeConfig = null,
|
|
3319
|
+
} = {}) {
|
|
3320
|
+
const account = isClaworldPlainObject(existingAccount) ? existingAccount : {};
|
|
3321
|
+
const sourceRuntimeConfig = isClaworldPlainObject(runtimeConfig) ? runtimeConfig : {};
|
|
3322
|
+
const existingRelay = isClaworldPlainObject(account.relay) ? account.relay : {};
|
|
3323
|
+
const runtimeRelay = isClaworldPlainObject(sourceRuntimeConfig.relay) ? sourceRuntimeConfig.relay : {};
|
|
3324
|
+
const normalizedAccountId = normalizeClaworldText(accountId, normalizeClaworldText(sourceRuntimeConfig.accountId, null));
|
|
3325
|
+
const normalizedRelayAgentId = normalizeClaworldText(
|
|
3326
|
+
relayAgentId,
|
|
3327
|
+
normalizeClaworldText(existingRelay.agentId, normalizeClaworldText(runtimeRelay.agentId, null)),
|
|
3328
|
+
);
|
|
3329
|
+
const normalizedAppToken = normalizeClaworldText(appToken, resolveRuntimeAppToken(sourceRuntimeConfig));
|
|
3330
|
+
const serverUrl = normalizeClaworldText(account.serverUrl, normalizeClaworldText(sourceRuntimeConfig.serverUrl, null));
|
|
3331
|
+
const apiKey = normalizeClaworldText(account.apiKey, normalizeClaworldText(sourceRuntimeConfig.apiKey, null));
|
|
3332
|
+
const name = normalizeClaworldText(account.name, normalizeClaworldText(sourceRuntimeConfig.name, null));
|
|
3333
|
+
const toolProfile = normalizeClaworldText(account.toolProfile, normalizeClaworldText(sourceRuntimeConfig.toolProfile, null));
|
|
3334
|
+
const heartbeatSeconds = Number.isInteger(account.heartbeatSeconds)
|
|
3335
|
+
? account.heartbeatSeconds
|
|
3336
|
+
: (Number.isInteger(sourceRuntimeConfig.heartbeatSeconds) ? sourceRuntimeConfig.heartbeatSeconds : null);
|
|
3337
|
+
const reconnect = typeof account.reconnect === 'boolean'
|
|
3338
|
+
? account.reconnect
|
|
3339
|
+
: (typeof sourceRuntimeConfig.reconnect === 'boolean' ? sourceRuntimeConfig.reconnect : null);
|
|
3340
|
+
const routing = isClaworldPlainObject(account.routing)
|
|
3341
|
+
? account.routing
|
|
3342
|
+
: (isClaworldPlainObject(sourceRuntimeConfig.routing) ? sourceRuntimeConfig.routing : null);
|
|
3343
|
+
const testing = isClaworldPlainObject(account.testing)
|
|
3344
|
+
? account.testing
|
|
3345
|
+
: (isClaworldPlainObject(sourceRuntimeConfig.testing) ? sourceRuntimeConfig.testing : null);
|
|
3346
|
+
|
|
3347
|
+
const nextAccount = {
|
|
3348
|
+
...account,
|
|
3349
|
+
enabled: typeof account.enabled === 'boolean'
|
|
3350
|
+
? account.enabled
|
|
3351
|
+
: (typeof sourceRuntimeConfig.enabled === 'boolean' ? sourceRuntimeConfig.enabled : true),
|
|
3352
|
+
...(serverUrl ? { serverUrl } : {}),
|
|
3353
|
+
...(apiKey ? { apiKey } : {}),
|
|
3354
|
+
...(normalizedAccountId ? { accountId: normalizedAccountId } : {}),
|
|
3355
|
+
...(normalizedAppToken ? { appToken: normalizedAppToken } : {}),
|
|
3356
|
+
...(name ? { name } : {}),
|
|
3357
|
+
...(toolProfile ? { toolProfile } : {}),
|
|
3358
|
+
...(heartbeatSeconds ? { heartbeatSeconds } : {}),
|
|
3359
|
+
...(typeof reconnect === 'boolean' ? { reconnect } : {}),
|
|
3360
|
+
...(routing ? { routing } : {}),
|
|
3361
|
+
...(testing ? { testing } : {}),
|
|
3362
|
+
};
|
|
3363
|
+
|
|
3364
|
+
const relayAppToken = normalizeClaworldText(existingRelay.appToken, normalizeClaworldText(runtimeRelay.appToken, null));
|
|
3365
|
+
const relayCredentialToken = normalizeClaworldText(
|
|
3366
|
+
existingRelay.credentialToken,
|
|
3367
|
+
normalizeClaworldText(runtimeRelay.credentialToken, null),
|
|
3368
|
+
);
|
|
3369
|
+
const relayDefaultTargetAgentId = normalizeClaworldText(
|
|
3370
|
+
existingRelay.defaultTargetAgentId,
|
|
3371
|
+
normalizeClaworldText(runtimeRelay.defaultTargetAgentId, null),
|
|
3372
|
+
);
|
|
3373
|
+
const relay = {
|
|
3374
|
+
...(relayAppToken ? { appToken: relayAppToken } : {}),
|
|
3375
|
+
...(relayCredentialToken ? { credentialToken: relayCredentialToken } : {}),
|
|
3376
|
+
...(relayDefaultTargetAgentId ? { defaultTargetAgentId: relayDefaultTargetAgentId } : {}),
|
|
3377
|
+
...(normalizedRelayAgentId ? { agentId: normalizedRelayAgentId } : {}),
|
|
3378
|
+
};
|
|
3379
|
+
if (Object.keys(relay).length > 0) nextAccount.relay = relay;
|
|
3380
|
+
else delete nextAccount.relay;
|
|
3381
|
+
delete nextAccount.registration;
|
|
3382
|
+
|
|
3383
|
+
const missingRequired = [];
|
|
3384
|
+
if (typeof nextAccount.enabled !== 'boolean') missingRequired.push('enabled');
|
|
3385
|
+
if (!normalizeClaworldText(nextAccount.serverUrl, null)) missingRequired.push('serverUrl');
|
|
3386
|
+
if (!normalizeClaworldText(nextAccount.apiKey, null)) missingRequired.push('apiKey');
|
|
3387
|
+
if (!normalizeClaworldText(nextAccount.accountId, null)) missingRequired.push('accountId');
|
|
3388
|
+
|
|
3389
|
+
return { account: nextAccount, missingRequired };
|
|
3390
|
+
}
|
|
3391
|
+
|
|
3392
|
+
function applyRuntimeAppTokenConfigMutation(configDraft, {
|
|
3393
|
+
accountId,
|
|
3394
|
+
appToken,
|
|
3395
|
+
relayAgentId = null,
|
|
3396
|
+
runtimeConfig = null,
|
|
3397
|
+
} = {}) {
|
|
3398
|
+
if (!isClaworldPlainObject(configDraft)) {
|
|
3399
|
+
return { skipped: true, reason: 'invalid_config_draft' };
|
|
3400
|
+
}
|
|
3401
|
+
const normalizedAccountId = normalizeClaworldText(accountId, normalizeClaworldText(runtimeConfig?.accountId, null));
|
|
3402
|
+
if (!normalizedAccountId || !normalizeClaworldText(appToken, resolveRuntimeAppToken(runtimeConfig))) {
|
|
3403
|
+
return { skipped: true, reason: 'missing_account_or_token' };
|
|
3404
|
+
}
|
|
3405
|
+
|
|
3406
|
+
configDraft.channels = isClaworldPlainObject(configDraft.channels) ? configDraft.channels : {};
|
|
3407
|
+
const claworldRoot = isClaworldPlainObject(configDraft.channels.claworld)
|
|
3408
|
+
? configDraft.channels.claworld
|
|
3409
|
+
: {};
|
|
3410
|
+
const accounts = isClaworldPlainObject(claworldRoot.accounts) ? claworldRoot.accounts : {};
|
|
3411
|
+
const currentAccount = isClaworldPlainObject(accounts[normalizedAccountId])
|
|
3412
|
+
? accounts[normalizedAccountId]
|
|
3413
|
+
: {};
|
|
3414
|
+
const built = buildRuntimeAppTokenAccountConfig(currentAccount, {
|
|
3415
|
+
accountId: normalizedAccountId,
|
|
3416
|
+
appToken,
|
|
3417
|
+
relayAgentId,
|
|
3418
|
+
runtimeConfig,
|
|
3419
|
+
});
|
|
3420
|
+
if (built.missingRequired.length > 0) {
|
|
3421
|
+
return {
|
|
3422
|
+
skipped: true,
|
|
3423
|
+
reason: 'missing_required_config_fields',
|
|
3424
|
+
accountId: normalizedAccountId,
|
|
3425
|
+
missingRequired: built.missingRequired,
|
|
3426
|
+
};
|
|
3427
|
+
}
|
|
3428
|
+
|
|
3429
|
+
if (JSON.stringify(currentAccount) === JSON.stringify(built.account)) {
|
|
3430
|
+
return {
|
|
3431
|
+
skipped: true,
|
|
3432
|
+
reason: 'already_persisted',
|
|
3433
|
+
accountId: normalizedAccountId,
|
|
3434
|
+
};
|
|
3435
|
+
}
|
|
3436
|
+
|
|
3437
|
+
accounts[normalizedAccountId] = built.account;
|
|
3438
|
+
claworldRoot.accounts = accounts;
|
|
3439
|
+
if (!normalizeClaworldText(claworldRoot.defaultAccount, null)) {
|
|
3440
|
+
claworldRoot.defaultAccount = normalizedAccountId;
|
|
3441
|
+
}
|
|
3442
|
+
configDraft.channels.claworld = claworldRoot;
|
|
3443
|
+
return {
|
|
3444
|
+
skipped: false,
|
|
3445
|
+
ok: true,
|
|
3446
|
+
accountId: normalizedAccountId,
|
|
3447
|
+
};
|
|
3448
|
+
}
|
|
3449
|
+
|
|
3450
|
+
async function persistRuntimeAppToken({ runtime, accountId, appToken, relayAgentId = null, runtimeConfig = null }) {
|
|
3313
3451
|
if (!accountId || !appToken) {
|
|
3314
3452
|
return { skipped: true, reason: 'missing_account_or_token' };
|
|
3315
3453
|
}
|
|
3316
3454
|
|
|
3317
3455
|
let configPersistResult = { skipped: true, reason: 'missing_runtime_config_io' };
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
: {};
|
|
3333
|
-
|
|
3334
|
-
const normalizedRelayAgentId = normalizeClaworldText(relayAgentId, normalizeClaworldText(account?.relay?.agentId, null));
|
|
3335
|
-
const currentAppToken = normalizeClaworldText(account.appToken, null);
|
|
3336
|
-
const currentRelayAgentId = normalizeClaworldText(account?.relay?.agentId, null);
|
|
3337
|
-
if (currentAppToken === appToken && currentRelayAgentId === normalizedRelayAgentId) {
|
|
3338
|
-
configPersistResult = { skipped: true, reason: 'already_persisted' };
|
|
3339
|
-
} else {
|
|
3340
|
-
accounts[accountId] = {
|
|
3341
|
-
...account,
|
|
3342
|
-
appToken,
|
|
3343
|
-
relay: {
|
|
3344
|
-
...(account?.relay && typeof account.relay === 'object' && !Array.isArray(account.relay) ? account.relay : {}),
|
|
3345
|
-
...(normalizedRelayAgentId ? { agentId: normalizedRelayAgentId } : {}),
|
|
3456
|
+
try {
|
|
3457
|
+
if (typeof runtime?.config?.mutateConfigFile === 'function') {
|
|
3458
|
+
let mutationOutcome = null;
|
|
3459
|
+
const mutationParams = {
|
|
3460
|
+
base: 'source',
|
|
3461
|
+
afterWrite: { mode: 'auto' },
|
|
3462
|
+
mutate: (draft) => {
|
|
3463
|
+
mutationOutcome = applyRuntimeAppTokenConfigMutation(draft, {
|
|
3464
|
+
accountId,
|
|
3465
|
+
appToken,
|
|
3466
|
+
relayAgentId,
|
|
3467
|
+
runtimeConfig,
|
|
3468
|
+
});
|
|
3469
|
+
return mutationOutcome;
|
|
3346
3470
|
},
|
|
3347
3471
|
};
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3472
|
+
const mutationResult = await runtime.config.mutateConfigFile(mutationParams);
|
|
3473
|
+
configPersistResult = {
|
|
3474
|
+
...(mutationResult?.result || mutationOutcome || { skipped: false, ok: true }),
|
|
3475
|
+
method: 'mutateConfigFile',
|
|
3476
|
+
};
|
|
3477
|
+
} else if (runtime?.config?.loadConfig && runtime?.config?.writeConfigFile) {
|
|
3478
|
+
const currentCfg = await runtime.config.loadConfig();
|
|
3479
|
+
const nextCfg = JSON.parse(JSON.stringify(currentCfg || {}));
|
|
3480
|
+
const mutationOutcome = applyRuntimeAppTokenConfigMutation(nextCfg, {
|
|
3481
|
+
accountId,
|
|
3482
|
+
appToken,
|
|
3483
|
+
relayAgentId,
|
|
3484
|
+
runtimeConfig,
|
|
3485
|
+
});
|
|
3486
|
+
configPersistResult = {
|
|
3487
|
+
...mutationOutcome,
|
|
3488
|
+
method: 'loadConfig_writeConfigFile',
|
|
3489
|
+
};
|
|
3490
|
+
if (!mutationOutcome.skipped) {
|
|
3491
|
+
await runtime.config.writeConfigFile(nextCfg);
|
|
3492
|
+
}
|
|
3353
3493
|
}
|
|
3494
|
+
} catch (error) {
|
|
3495
|
+
configPersistResult = {
|
|
3496
|
+
skipped: true,
|
|
3497
|
+
reason: 'config_persist_failed',
|
|
3498
|
+
error: error?.message || String(error),
|
|
3499
|
+
};
|
|
3500
|
+
logger.warn?.(`[claworld:${accountId || 'default'}] failed to persist runtime appToken to OpenClaw config`, {
|
|
3501
|
+
accountId,
|
|
3502
|
+
error: configPersistResult.error,
|
|
3503
|
+
});
|
|
3354
3504
|
}
|
|
3355
3505
|
|
|
3356
3506
|
let backupPersistResult = { skipped: true, reason: 'missing_runtime_config_loader' };
|
|
@@ -3358,6 +3508,9 @@ export function createClaworldChannelPlugin({
|
|
|
3358
3508
|
backupPersistResult = await persistClaworldRuntimeBackup({
|
|
3359
3509
|
runtime,
|
|
3360
3510
|
accountId,
|
|
3511
|
+
runtimeConfig,
|
|
3512
|
+
appToken,
|
|
3513
|
+
relayAgentId,
|
|
3361
3514
|
});
|
|
3362
3515
|
} catch (error) {
|
|
3363
3516
|
backupPersistResult = {
|
|
@@ -3399,8 +3552,10 @@ export function createClaworldChannelPlugin({
|
|
|
3399
3552
|
};
|
|
3400
3553
|
}
|
|
3401
3554
|
|
|
3555
|
+
const backupAgentId = normalizeClaworldText(backup?.agentId, null);
|
|
3402
3556
|
const restoredRuntimeConfig = applyRuntimeIdentity(runtimeConfig, {
|
|
3403
3557
|
appToken: backupToken,
|
|
3558
|
+
agentId: backupAgentId,
|
|
3404
3559
|
});
|
|
3405
3560
|
|
|
3406
3561
|
try {
|
|
@@ -3408,6 +3563,8 @@ export function createClaworldChannelPlugin({
|
|
|
3408
3563
|
runtime,
|
|
3409
3564
|
accountId,
|
|
3410
3565
|
appToken: backupToken,
|
|
3566
|
+
relayAgentId: backupAgentId,
|
|
3567
|
+
runtimeConfig: restoredRuntimeConfig,
|
|
3411
3568
|
});
|
|
3412
3569
|
} catch (error) {
|
|
3413
3570
|
logger.warn?.(`[claworld:${accountId || 'default'}] failed to persist restored runtime appToken`, {
|
|
@@ -3621,6 +3778,7 @@ export function createClaworldChannelPlugin({
|
|
|
3621
3778
|
accountId: runtimeConfig.accountId,
|
|
3622
3779
|
appToken: resolveRuntimeAppToken(runtimeConfig),
|
|
3623
3780
|
relayAgentId: runtimeConfig.relay?.agentId || null,
|
|
3781
|
+
runtimeConfig,
|
|
3624
3782
|
});
|
|
3625
3783
|
if (!persisted.skipped || persisted.backup?.skipped === false) {
|
|
3626
3784
|
logger.info?.(`[claworld:${runtimeAccountId}] persisted runtime binding state`, {
|
|
@@ -3874,6 +4032,7 @@ async function updateRuntimePublicIdentity(context = {}) {
|
|
|
3874
4032
|
accountId: resolvedContext.accountId || boundRuntimeConfig.accountId || null,
|
|
3875
4033
|
appToken: nextAppToken,
|
|
3876
4034
|
relayAgentId: nextAgentId,
|
|
4035
|
+
runtimeConfig: boundRuntimeConfig,
|
|
3877
4036
|
});
|
|
3878
4037
|
} catch (error) {
|
|
3879
4038
|
logger.warn?.('[claworld:profile] failed to persist activated runtime binding', {
|
|
@@ -4208,7 +4367,6 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
4208
4367
|
contactable: Object.prototype.hasOwnProperty.call(context, 'contactable') ? context.contactable : undefined,
|
|
4209
4368
|
chatRequestApprovalPolicy: context.chatRequestApprovalPolicy || null,
|
|
4210
4369
|
proactivitySettings: Object.prototype.hasOwnProperty.call(context, 'proactivitySettings') ? context.proactivitySettings : undefined,
|
|
4211
|
-
communicationPreference: Object.prototype.hasOwnProperty.call(context, 'communicationPreference') ? context.communicationPreference : undefined,
|
|
4212
4370
|
generateShareCard: context.generateShareCard === true,
|
|
4213
4371
|
expiresInSeconds: context.expiresInSeconds ?? null,
|
|
4214
4372
|
fetchImpl,
|
|
@@ -4592,7 +4750,6 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
4592
4750
|
contactable: Object.prototype.hasOwnProperty.call(context, 'contactable') ? context.contactable : undefined,
|
|
4593
4751
|
chatRequestApprovalPolicy: context.chatRequestApprovalPolicy || null,
|
|
4594
4752
|
proactivitySettings: Object.prototype.hasOwnProperty.call(context, 'proactivitySettings') ? context.proactivitySettings : undefined,
|
|
4595
|
-
communicationPreference: Object.prototype.hasOwnProperty.call(context, 'communicationPreference') ? context.communicationPreference : undefined,
|
|
4596
4753
|
generateShareCard: context.generateShareCard === true,
|
|
4597
4754
|
expiresInSeconds: context.expiresInSeconds ?? null,
|
|
4598
4755
|
fetchImpl,
|
|
@@ -490,10 +490,6 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
490
490
|
description: 'Account-level proactive-management settings.',
|
|
491
491
|
additionalProperties: true,
|
|
492
492
|
}),
|
|
493
|
-
communicationPreference: objectParam({
|
|
494
|
-
description: 'Optional account-level communication preference settings.',
|
|
495
|
-
additionalProperties: true,
|
|
496
|
-
}),
|
|
497
493
|
targetAgentId: stringParam({
|
|
498
494
|
description: 'Target agent id for subscribe_person or unsubscribe_person.',
|
|
499
495
|
minLength: 1,
|
|
@@ -583,7 +579,6 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
583
579
|
contactable: params.contactable,
|
|
584
580
|
chatRequestApprovalPolicy: params.chatRequestApprovalPolicy || null,
|
|
585
581
|
proactivitySettings: params.proactivitySettings,
|
|
586
|
-
communicationPreference: params.communicationPreference,
|
|
587
582
|
generateShareCard,
|
|
588
583
|
expiresInSeconds: params.expiresInSeconds ?? null,
|
|
589
584
|
});
|
|
@@ -2061,14 +2056,16 @@ function buildRegisteredTools(api, plugin) {
|
|
|
2061
2056
|
}));
|
|
2062
2057
|
}
|
|
2063
2058
|
|
|
2064
|
-
const
|
|
2065
|
-
const
|
|
2066
|
-
const
|
|
2059
|
+
const context = await resolveToolContext(api, plugin, params);
|
|
2060
|
+
const cfg = context.cfg || await loadCurrentConfig(api);
|
|
2061
|
+
const accountId = context.accountId;
|
|
2062
|
+
const runtimeConfig = context.runtimeConfig || plugin.config.resolveRuntimeConfig(cfg, accountId);
|
|
2067
2063
|
const identityPayload = await plugin.runtime.productShell.profile.getPublicIdentity({
|
|
2064
|
+
...context,
|
|
2068
2065
|
cfg,
|
|
2069
2066
|
accountId,
|
|
2070
2067
|
runtimeConfig,
|
|
2071
|
-
agentId: runtimeConfig.relay?.agentId || null,
|
|
2068
|
+
agentId: context.agentId || runtimeConfig.relay?.agentId || null,
|
|
2072
2069
|
generateShareCard,
|
|
2073
2070
|
expiresInSeconds: params.expiresInSeconds ?? null,
|
|
2074
2071
|
});
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
setClaworldManagedRuntimeBackupState,
|
|
9
9
|
stripClaworldManagedRuntimeConfig,
|
|
10
10
|
} from './managed-config.js';
|
|
11
|
+
import { resolveRuntimeAppToken } from './account-identity.js';
|
|
11
12
|
|
|
12
13
|
function normalizeText(value, fallback = null) {
|
|
13
14
|
if (value == null) return fallback;
|
|
@@ -67,18 +68,53 @@ export async function persistClaworldRuntimeBackup({
|
|
|
67
68
|
runtime = null,
|
|
68
69
|
accountId = DEFAULT_CLAWORLD_ACCOUNT_ID,
|
|
69
70
|
configPath = resolveDefaultOpenClawConfigPath(),
|
|
71
|
+
runtimeConfig = null,
|
|
72
|
+
appToken = null,
|
|
73
|
+
relayAgentId = null,
|
|
70
74
|
} = {}) {
|
|
71
|
-
if (!runtime?.config?.loadConfig) {
|
|
75
|
+
if (!runtime?.config?.loadConfig && !runtimeConfig && !appToken) {
|
|
72
76
|
return { skipped: true, reason: 'missing_runtime_config_loader' };
|
|
73
77
|
}
|
|
74
78
|
|
|
75
|
-
|
|
76
|
-
|
|
79
|
+
let currentConfig = {};
|
|
80
|
+
if (runtime?.config?.loadConfig) {
|
|
81
|
+
try {
|
|
82
|
+
currentConfig = await runtime.config.loadConfig();
|
|
83
|
+
} catch (error) {
|
|
84
|
+
if (!runtimeConfig && !appToken) throw error;
|
|
85
|
+
currentConfig = {};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const { backup: configBackup } = stripClaworldManagedRuntimeConfig(currentConfig, {
|
|
77
89
|
accountId,
|
|
78
90
|
preserveBackup: true,
|
|
79
91
|
});
|
|
92
|
+
const explicitRuntimeConfig = runtimeConfig && typeof runtimeConfig === 'object' && !Array.isArray(runtimeConfig)
|
|
93
|
+
? runtimeConfig
|
|
94
|
+
: {};
|
|
95
|
+
const backup = {
|
|
96
|
+
...configBackup,
|
|
97
|
+
version: configBackup?.version || 1,
|
|
98
|
+
accountId: normalizeText(configBackup?.accountId, normalizeText(explicitRuntimeConfig.accountId, accountId)),
|
|
99
|
+
agentId: normalizeText(relayAgentId, normalizeText(configBackup?.agentId, normalizeText(explicitRuntimeConfig?.relay?.agentId, null))),
|
|
100
|
+
serverUrl: normalizeText(configBackup?.serverUrl, normalizeText(explicitRuntimeConfig.serverUrl, null)),
|
|
101
|
+
apiKey: normalizeText(configBackup?.apiKey, normalizeText(explicitRuntimeConfig.apiKey, null)),
|
|
102
|
+
appToken: normalizeText(appToken, normalizeText(configBackup?.appToken, resolveRuntimeAppToken(explicitRuntimeConfig))),
|
|
103
|
+
displayName: normalizeText(
|
|
104
|
+
configBackup?.displayName,
|
|
105
|
+
normalizeText(explicitRuntimeConfig.name, normalizeText(explicitRuntimeConfig.registration?.displayName, null)),
|
|
106
|
+
),
|
|
107
|
+
name: normalizeText(configBackup?.name, normalizeText(explicitRuntimeConfig.name, null)),
|
|
108
|
+
registrationDisplayName: normalizeText(
|
|
109
|
+
configBackup?.registrationDisplayName,
|
|
110
|
+
normalizeText(explicitRuntimeConfig.registration?.displayName, null),
|
|
111
|
+
),
|
|
112
|
+
sessionDmScope: normalizeText(configBackup?.sessionDmScope, null),
|
|
113
|
+
toolProfile: normalizeText(configBackup?.toolProfile, null),
|
|
114
|
+
preservedAt: new Date().toISOString(),
|
|
115
|
+
};
|
|
80
116
|
|
|
81
|
-
if (!backup
|
|
117
|
+
if (!backup.appToken) {
|
|
82
118
|
return { skipped: true, reason: 'missing_app_token', backup: null };
|
|
83
119
|
}
|
|
84
120
|
|
|
@@ -193,6 +193,7 @@ function buildClaworldManagementStartupPrompt(options = {}) {
|
|
|
193
193
|
'',
|
|
194
194
|
'## First Rule',
|
|
195
195
|
'When you receive a Claworld notification, management wake, lifecycle event, or recurring Claworld management task, read the `claworld-management-session` skill before deciding what to do.',
|
|
196
|
+
'A pre-compaction memory flush is a maintenance turn only. It does not satisfy, replace, or change any Claworld notification. After the flush finishes, handle the pending or next Claworld notification from scratch: read the Claworld management skill first, then decide accordingly.',
|
|
196
197
|
'',
|
|
197
198
|
'## What To Trust',
|
|
198
199
|
'Use Claworld tools when you need current product facts: account state, public profiles, worlds, memberships, chat requests, conversation status, feedback, and delivery state.',
|