@clawling/clawchat-plugin-openclaw 2026.9.22-2 → 2026.9.23-1
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/dist/src/api-client.js +100 -3
- package/dist/src/skill-update.js +1 -1
- package/dist/src/tools-schema.js +51 -0
- package/dist/src/tools.js +209 -2
- package/openclaw.plugin.json +13 -1
- package/package.json +3 -1
- package/skills/clawchat-core/SKILL.md +5 -10
- package/skills/clawchat-orchestration/SKILL.md +60 -78
- package/skills/manifest.json +12 -12
- package/src/api-client.ts +140 -4
- package/src/skill-update.ts +1 -1
- package/src/tools-schema.ts +88 -0
- package/src/tools.ts +341 -1
package/dist/src/api-client.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { ClawlingApiError, } from "./api-types.js";
|
|
2
2
|
import { CHANNEL_ID } from "./config.js";
|
|
3
|
+
const ORCH = "/v1/agents/me/orchestration";
|
|
4
|
+
/** Body + content-type for an orchestration write, so the two never drift apart. */
|
|
5
|
+
function orchJson(payload) {
|
|
6
|
+
return { body: JSON.stringify(payload), headers: { "content-type": "application/json" } };
|
|
7
|
+
}
|
|
3
8
|
export function buildPluginReportBody(input) {
|
|
4
9
|
const body = {
|
|
5
10
|
device_id: input.deviceId,
|
|
@@ -264,8 +269,13 @@ export function createOpenclawClawlingApiClient(opts) {
|
|
|
264
269
|
}
|
|
265
270
|
throw new ClawlingApiError("transport", text ? "invalid envelope: missing numeric `code`" : "non-JSON response: empty body", { status: res.status, path });
|
|
266
271
|
}
|
|
267
|
-
|
|
268
|
-
|
|
272
|
+
/**
|
|
273
|
+
* Shared by `call<T>` and `orchCall`: build the request, invoke `fetchImpl`,
|
|
274
|
+
* and normalize any network-level failure into a `ClawlingApiError`. Kept
|
|
275
|
+
* as one function so the two callers' request-building can never drift
|
|
276
|
+
* apart again the way `call<T>` and `orchCall` briefly did.
|
|
277
|
+
*/
|
|
278
|
+
async function doFetch(method, path, init) {
|
|
269
279
|
try {
|
|
270
280
|
const requestInit = {
|
|
271
281
|
method,
|
|
@@ -274,13 +284,55 @@ export function createOpenclawClawlingApiClient(opts) {
|
|
|
274
284
|
if (init?.body !== undefined) {
|
|
275
285
|
requestInit.body = init.body;
|
|
276
286
|
}
|
|
277
|
-
|
|
287
|
+
return await fetchImpl(url(path, init?.baseUrl || undefined), requestInit);
|
|
278
288
|
}
|
|
279
289
|
catch (err) {
|
|
280
290
|
throw new ClawlingApiError("transport", `fetch failed: ${err instanceof Error ? err.message : String(err)}`, { path });
|
|
281
291
|
}
|
|
292
|
+
}
|
|
293
|
+
async function call(method, path, init) {
|
|
294
|
+
const res = await doFetch(method, path, init);
|
|
282
295
|
return await readEnvelope(res, path);
|
|
283
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* Orchestration routes (`${ORCH}/...`) are always HTTP 200 with the
|
|
299
|
+
* business code inside the envelope — a `21003` permission denial is a
|
|
300
|
+
* normal outcome there, not a transport failure. Unlike `call<T>`, this
|
|
301
|
+
* does NOT unwrap `data` or throw on a non-zero `code`; it hands back the
|
|
302
|
+
* parsed envelope exactly as received so the caller can branch on `code`
|
|
303
|
+
* itself.
|
|
304
|
+
*
|
|
305
|
+
* A 401/403 is checked FIRST, before any body parsing, exactly like
|
|
306
|
+
* `readEnvelope` — an expired/malformed token is not a business-code
|
|
307
|
+
* outcome and must throw `kind: "auth"` rather than fall through to the
|
|
308
|
+
* empty-body branch below and be misread as success. NOTE: on the
|
|
309
|
+
* orchestration tool path (`tools.ts` `buildClient` → a raw client,
|
|
310
|
+
* consumed via `withClient`) this throw is NOT retried — `withClient`
|
|
311
|
+
* turns any `ClawlingApiError` straight into `apiError(err)`. Reactive
|
|
312
|
+
* retry-after-refresh only exists behind `getConversationApiClient`'s
|
|
313
|
+
* `withRefresh` wrapper (`runtime.ts`), which the twelve `orch*` tools do
|
|
314
|
+
* not go through; this matches the other ~34 tools already shipped on the
|
|
315
|
+
* same `withClient` path. Proactive rotation is still picked up here for
|
|
316
|
+
* free, since the token is read fresh from the account at call time.
|
|
317
|
+
*/
|
|
318
|
+
async function orchCall(method, path, init) {
|
|
319
|
+
const res = await doFetch(method, path, init);
|
|
320
|
+
if (res.status === 401 || res.status === 403) {
|
|
321
|
+
throw new ClawlingApiError("auth", `unauthorized (status ${res.status})`, {
|
|
322
|
+
status: res.status,
|
|
323
|
+
path,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
const text = await res.text().catch(() => "");
|
|
327
|
+
if (!text)
|
|
328
|
+
return undefined;
|
|
329
|
+
try {
|
|
330
|
+
return JSON.parse(text);
|
|
331
|
+
}
|
|
332
|
+
catch {
|
|
333
|
+
throw new ClawlingApiError("transport", "non-JSON response", { status: res.status, path });
|
|
334
|
+
}
|
|
335
|
+
}
|
|
284
336
|
function parseUploadResult(data, path) {
|
|
285
337
|
const obj = data;
|
|
286
338
|
const validKind = obj?.kind === "image" || obj?.kind === "file" || obj?.kind === "audio" || obj?.kind === "video";
|
|
@@ -376,6 +428,51 @@ export function createOpenclawClawlingApiClient(opts) {
|
|
|
376
428
|
assertNonBlankId(friendUserId, "removeFriend: friendUserId");
|
|
377
429
|
return await call("DELETE", `/v1/friendships/${encodeURIComponent(friendUserId)}`);
|
|
378
430
|
},
|
|
431
|
+
async orchListAgents() {
|
|
432
|
+
return await orchCall("GET", `${ORCH}/agents`);
|
|
433
|
+
},
|
|
434
|
+
async orchGetAgent(agentId) {
|
|
435
|
+
return await orchCall("GET", `${ORCH}/agents/${encodeURIComponent(agentId)}`);
|
|
436
|
+
},
|
|
437
|
+
async orchSetAgentBehavior(agentId, behavior) {
|
|
438
|
+
return await orchCall("PATCH", `${ORCH}/agents/${encodeURIComponent(agentId)}`, orchJson({ behavior }));
|
|
439
|
+
},
|
|
440
|
+
async orchListGroups() {
|
|
441
|
+
return await orchCall("GET", `${ORCH}/groups`);
|
|
442
|
+
},
|
|
443
|
+
async orchGetGroup(cid) {
|
|
444
|
+
return await orchCall("GET", `${ORCH}/groups/${encodeURIComponent(cid)}`);
|
|
445
|
+
},
|
|
446
|
+
async orchSetGroupPrompt(cid, description) {
|
|
447
|
+
return await orchCall("PATCH", `${ORCH}/groups/${encodeURIComponent(cid)}`, orchJson({ description }));
|
|
448
|
+
},
|
|
449
|
+
async orchCreateGroup(title, agentIds) {
|
|
450
|
+
return await orchCall("POST", `${ORCH}/groups`, orchJson({ title, agent_ids: agentIds }));
|
|
451
|
+
},
|
|
452
|
+
async orchAddGroupMember(cid, agentId) {
|
|
453
|
+
return await orchCall("POST", `${ORCH}/groups/${encodeURIComponent(cid)}/members`, orchJson({ agent_id: agentId }));
|
|
454
|
+
},
|
|
455
|
+
async orchRemoveGroupMember(cid, agentId) {
|
|
456
|
+
return await orchCall("DELETE", `${ORCH}/groups/${encodeURIComponent(cid)}/members/${encodeURIComponent(agentId)}`);
|
|
457
|
+
},
|
|
458
|
+
async orchSetGroupAgentSettings(cid, agentId, patch) {
|
|
459
|
+
// `!== undefined` rather than truthiness: `muted: false` is a real value
|
|
460
|
+
// the backend must see; an absent key means "leave unchanged".
|
|
461
|
+
const body = {};
|
|
462
|
+
if (patch.muted !== undefined)
|
|
463
|
+
body.muted = patch.muted;
|
|
464
|
+
if (patch.replyMode !== undefined)
|
|
465
|
+
body.reply_mode = patch.replyMode;
|
|
466
|
+
if (patch.batchDelaySeconds !== undefined)
|
|
467
|
+
body.batch_delay_seconds = patch.batchDelaySeconds;
|
|
468
|
+
return await orchCall("PATCH", `${ORCH}/groups/${encodeURIComponent(cid)}/agents/${encodeURIComponent(agentId)}`, orchJson(body));
|
|
469
|
+
},
|
|
470
|
+
async orchCreateConnectCode() {
|
|
471
|
+
return await orchCall("POST", `${ORCH}/connect-codes`);
|
|
472
|
+
},
|
|
473
|
+
async orchGetConnectCode(code) {
|
|
474
|
+
return await orchCall("GET", `${ORCH}/connect-codes/${encodeURIComponent(code)}`);
|
|
475
|
+
},
|
|
379
476
|
async registerApp(params) {
|
|
380
477
|
assertNonBlankId(params.appId, "registerApp: appId");
|
|
381
478
|
return await call("POST", "/v1/agents/me/apps", {
|
package/dist/src/skill-update.js
CHANGED
|
@@ -66,7 +66,7 @@ export const OFFICIAL_SKILLS_BASE = "https://raw.githubusercontent.com/clawling/
|
|
|
66
66
|
* in the install-cli repo, bump this constant, ship it. `liveware-sample.ts`
|
|
67
67
|
* imports the same ref, so the `livewares` tree at that tag is pinned too.
|
|
68
68
|
*/
|
|
69
|
-
export const DEFAULT_SKILLS_REF = "skills-v1.
|
|
69
|
+
export const DEFAULT_SKILLS_REF = "skills-v1.14.0";
|
|
70
70
|
/** Refuse to treat an absurdly large response as a skill file (defence in depth). */
|
|
71
71
|
export const MAX_SKILL_BYTES = 256 * 1024;
|
|
72
72
|
/** This adapter's host target inside `skills/manifest.json`. */
|
package/dist/src/tools-schema.js
CHANGED
|
@@ -284,3 +284,54 @@ export const ClawchatUnregisterAppSchema = Type.Object({
|
|
|
284
284
|
appId: Type.String({ minLength: 1, description: "The liveware app id to unregister." }),
|
|
285
285
|
});
|
|
286
286
|
export const ClawchatLivewareLoginSchema = Type.Object({});
|
|
287
|
+
// --- cloud orchestration (`agent.orchestrate`) ----------------------------
|
|
288
|
+
// Twelve schemas, 1:1 with docs/features/agentorch.md.
|
|
289
|
+
const OrchAgentId = Type.String({
|
|
290
|
+
minLength: 1,
|
|
291
|
+
description: "Explicit agent id from clawchat_orchestrate_list_agents. Never guess one from a nickname.",
|
|
292
|
+
});
|
|
293
|
+
const OrchConversationId = Type.String({
|
|
294
|
+
minLength: 1,
|
|
295
|
+
description: "Explicit group conversation id from clawchat_orchestrate_list_groups.",
|
|
296
|
+
});
|
|
297
|
+
export const ClawchatOrchListAgentsSchema = Type.Object({}, { additionalProperties: false });
|
|
298
|
+
export const ClawchatOrchGetAgentSchema = Type.Object({ agentId: OrchAgentId }, { additionalProperties: false });
|
|
299
|
+
export const ClawchatOrchSetAgentBehaviorSchema = Type.Object({
|
|
300
|
+
agentId: OrchAgentId,
|
|
301
|
+
behavior: Type.String({
|
|
302
|
+
maxLength: 3000,
|
|
303
|
+
description: "The complete new system prompt. REPLACES the whole field — GET first and send the full value.",
|
|
304
|
+
}),
|
|
305
|
+
}, { additionalProperties: false });
|
|
306
|
+
export const ClawchatOrchListGroupsSchema = Type.Object({}, { additionalProperties: false });
|
|
307
|
+
export const ClawchatOrchGetGroupSchema = Type.Object({ conversationId: OrchConversationId }, { additionalProperties: false });
|
|
308
|
+
export const ClawchatOrchSetGroupPromptSchema = Type.Object({
|
|
309
|
+
conversationId: OrchConversationId,
|
|
310
|
+
description: Type.String({
|
|
311
|
+
maxLength: 3000,
|
|
312
|
+
description: "The complete new group system prompt. REPLACES the whole field.",
|
|
313
|
+
}),
|
|
314
|
+
}, { additionalProperties: false });
|
|
315
|
+
export const ClawchatOrchCreateGroupSchema = Type.Object({
|
|
316
|
+
title: Type.String({ minLength: 1, maxLength: 60, description: "Group title, 1-60 runes." }),
|
|
317
|
+
agentIds: Type.Array(Type.String({ minLength: 1 }), {
|
|
318
|
+
minItems: 1,
|
|
319
|
+
description: "Agent ids from clawchat_orchestrate_list_agents. Must be the owner's own agents.",
|
|
320
|
+
}),
|
|
321
|
+
}, { additionalProperties: false });
|
|
322
|
+
export const ClawchatOrchGroupMemberSchema = Type.Object({ conversationId: OrchConversationId, agentId: OrchAgentId }, { additionalProperties: false });
|
|
323
|
+
export const ClawchatOrchSetGroupAgentSettingsSchema = Type.Object({
|
|
324
|
+
conversationId: OrchConversationId,
|
|
325
|
+
agentId: OrchAgentId,
|
|
326
|
+
muted: Type.Optional(Type.Boolean({ description: "Mute or unmute this agent in this group." })),
|
|
327
|
+
replyMode: Type.Optional(Type.Union([Type.Literal("all"), Type.Literal("mention")], {
|
|
328
|
+
description: "all = speaks on every message; mention = only when @-mentioned.",
|
|
329
|
+
})),
|
|
330
|
+
batchDelaySeconds: Type.Optional(Type.Integer({
|
|
331
|
+
minimum: 1,
|
|
332
|
+
maximum: 3600,
|
|
333
|
+
description: "Seconds this agent batches messages before replying. Default 10. Pacing, not a limit.",
|
|
334
|
+
})),
|
|
335
|
+
}, { additionalProperties: false, minProperties: 3 });
|
|
336
|
+
export const ClawchatOrchCreateConnectCodeSchema = Type.Object({}, { additionalProperties: false });
|
|
337
|
+
export const ClawchatOrchGetConnectCodeSchema = Type.Object({ code: Type.String({ minLength: 1, description: "The connect code to look up." }) }, { additionalProperties: false });
|
package/dist/src/tools.js
CHANGED
|
@@ -12,7 +12,7 @@ import { getOpenclawClawlingClient, } from "./runtime.js";
|
|
|
12
12
|
import { markTerminalClawChatSend, getCurrentTerminalSendScope } from "./terminal-send.js";
|
|
13
13
|
import { editClawChatMemoryBody, readClawChatMemoryFile, resolveClawChatMemoryPath, searchClawChatMemory, writeClawChatMemoryBody, } from "./clawchat-memory.js";
|
|
14
14
|
import { pullGroupMetadata, pullOwnerMetadata, pullUserMetadata, pushMetadata, updateMetadata, } from "./clawchat-metadata.js";
|
|
15
|
-
import { ClawchatGetAccountProfileSchema, ClawchatGetConversationSchema, ClawchatGetDirectConversationSchema, ClawchatGetMomentSchema, ClawchatGetUserProfileSchema, ClawchatLeaveGroupSchema, ClawchatAddGroupMemberSchema, ClawchatAcceptFriendRequestSchema, ClawchatMemoryEditSchema, ClawchatMemoryReadSchema, ClawchatMemorySearchSchema, ClawchatMemoryWriteSchema, ClawchatMetadataSyncSchema, ClawchatMetadataUpdateSchema, ClawchatCreateMomentCommentSchema, ClawchatCreateMomentSchema, ClawchatDeleteMomentCommentSchema, ClawchatDeleteMomentSchema, ClawchatListAccountFriendsSchema, ClawchatListFriendRequestsSchema, ClawchatListMomentsSchema, ClawchatMentionMessageSchema, ClawchatReactMessageSchema, ClawchatReplyMomentCommentSchema, ClawchatRejectFriendRequestSchema, ClawchatRemoveFriendSchema, ClawchatSearchUsersSchema, ClawchatSendFriendRequestSchema, ClawchatToggleMomentReactionSchema, ClawchatUpdateAccountProfileSchema, ClawchatUploadAvatarImageSchema, ClawchatRegisterAppSchema, ClawchatListAppsSchema, ClawchatUnregisterAppSchema, ClawchatLivewareLoginSchema, } from "./tools-schema.js";
|
|
15
|
+
import { ClawchatGetAccountProfileSchema, ClawchatGetConversationSchema, ClawchatGetDirectConversationSchema, ClawchatGetMomentSchema, ClawchatGetUserProfileSchema, ClawchatLeaveGroupSchema, ClawchatAddGroupMemberSchema, ClawchatAcceptFriendRequestSchema, ClawchatMemoryEditSchema, ClawchatMemoryReadSchema, ClawchatMemorySearchSchema, ClawchatMemoryWriteSchema, ClawchatMetadataSyncSchema, ClawchatMetadataUpdateSchema, ClawchatCreateMomentCommentSchema, ClawchatCreateMomentSchema, ClawchatDeleteMomentCommentSchema, ClawchatDeleteMomentSchema, ClawchatListAccountFriendsSchema, ClawchatListFriendRequestsSchema, ClawchatListMomentsSchema, ClawchatMentionMessageSchema, ClawchatReactMessageSchema, ClawchatReplyMomentCommentSchema, ClawchatRejectFriendRequestSchema, ClawchatRemoveFriendSchema, ClawchatSearchUsersSchema, ClawchatSendFriendRequestSchema, ClawchatToggleMomentReactionSchema, ClawchatUpdateAccountProfileSchema, ClawchatUploadAvatarImageSchema, ClawchatRegisterAppSchema, ClawchatListAppsSchema, ClawchatUnregisterAppSchema, ClawchatLivewareLoginSchema, ClawchatOrchListAgentsSchema, ClawchatOrchGetAgentSchema, ClawchatOrchSetAgentBehaviorSchema, ClawchatOrchListGroupsSchema, ClawchatOrchGetGroupSchema, ClawchatOrchSetGroupPromptSchema, ClawchatOrchCreateGroupSchema, ClawchatOrchGroupMemberSchema, ClawchatOrchSetGroupAgentSettingsSchema, ClawchatOrchCreateConnectCodeSchema, ClawchatOrchGetConnectCodeSchema, } from "./tools-schema.js";
|
|
16
16
|
const MAX_UPLOAD_BYTES = 20 * 1024 * 1024;
|
|
17
17
|
// Owner-approval gate business codes (must match the ClawChat backend's owner-approval codes).
|
|
18
18
|
const CODE_PENDING_APPROVAL = 21001;
|
|
@@ -1381,5 +1381,212 @@ export function registerOpenclawClawlingTools(api, options = {}) {
|
|
|
1381
1381
|
},
|
|
1382
1382
|
};
|
|
1383
1383
|
}, { name: "clawchat_liveware_login" });
|
|
1384
|
-
|
|
1384
|
+
// --- cloud orchestration (`agent.orchestrate`) ---------------------------
|
|
1385
|
+
// Twelve tools, 1:1 with docs/features/agentorch.md. Every response is HTTP
|
|
1386
|
+
// 200 with the business code in the envelope (a 21003 owner-approval
|
|
1387
|
+
// denial is the single most common outcome), so these use plain
|
|
1388
|
+
// `withClient` — never `withGatedClient` — and hand the caller the raw
|
|
1389
|
+
// envelope untouched. The shared orchestration skill text tells the model
|
|
1390
|
+
// to read `code` itself; rewriting the shape here would make the same
|
|
1391
|
+
// sentence behave differently than on the Hermes side.
|
|
1392
|
+
api.registerTool((ctx) => {
|
|
1393
|
+
const accountId = resolveOpenclawClawlingToolAccountId(ctx);
|
|
1394
|
+
return {
|
|
1395
|
+
name: "clawchat_orchestrate_list_agents",
|
|
1396
|
+
label: "List The Owner's Agents",
|
|
1397
|
+
description: toolDescription("List every agent the owner owns, including this one (flagged is_self). " +
|
|
1398
|
+
"TRIGGER — invoke first whenever the owner asks about, or asks to change, one of their OTHER agents. " +
|
|
1399
|
+
"This is the only way to learn a sibling's agentId; never guess one from a nickname."),
|
|
1400
|
+
parameters: ClawchatOrchListAgentsSchema,
|
|
1401
|
+
async execute(_callId, params) {
|
|
1402
|
+
return await recordClawchatToolCall(accountId, "clawchat_orchestrate_list_agents", params, async () => withClient(accountId, (c) => c.orchListAgents()));
|
|
1403
|
+
},
|
|
1404
|
+
};
|
|
1405
|
+
}, { name: "clawchat_orchestrate_list_agents" });
|
|
1406
|
+
api.registerTool((ctx) => {
|
|
1407
|
+
const accountId = resolveOpenclawClawlingToolAccountId(ctx);
|
|
1408
|
+
return {
|
|
1409
|
+
name: "clawchat_orchestrate_get_agent",
|
|
1410
|
+
label: "Get A Sibling Agent",
|
|
1411
|
+
description: toolDescription("Read one of the owner's agents by explicit agentId, including its read-only permission map. " +
|
|
1412
|
+
"TRIGGER — invoke before rewriting a sibling's system prompt (the PATCH replaces the whole field, so read it first), " +
|
|
1413
|
+
"or to explain why a sibling cannot do something instead of retrying on its behalf."),
|
|
1414
|
+
parameters: ClawchatOrchGetAgentSchema,
|
|
1415
|
+
async execute(_callId, params) {
|
|
1416
|
+
return await recordClawchatToolCall(accountId, "clawchat_orchestrate_get_agent", params, async () => {
|
|
1417
|
+
const p = params;
|
|
1418
|
+
return await withClient(accountId, (c) => c.orchGetAgent(p.agentId));
|
|
1419
|
+
});
|
|
1420
|
+
},
|
|
1421
|
+
};
|
|
1422
|
+
}, { name: "clawchat_orchestrate_get_agent" });
|
|
1423
|
+
api.registerTool((ctx) => {
|
|
1424
|
+
const accountId = resolveOpenclawClawlingToolAccountId(ctx);
|
|
1425
|
+
return {
|
|
1426
|
+
name: "clawchat_orchestrate_set_agent_behavior",
|
|
1427
|
+
label: "Rewrite A Sibling's System Prompt",
|
|
1428
|
+
description: toolDescription("Replace the WHOLE system prompt (behavior) of one of the owner's other agents. " +
|
|
1429
|
+
"TRIGGER — invoke when the owner asks to change how another agent behaves, talks, or what it is for. " +
|
|
1430
|
+
"This REPLACES the entire field — call clawchat_orchestrate_get_agent first, edit the text you got back, and send the full new value. " +
|
|
1431
|
+
"Sending a fragment deletes everything else and the owner cannot recover it. Max 3000 runes. " +
|
|
1432
|
+
"Nickname and bio cannot be changed here."),
|
|
1433
|
+
parameters: ClawchatOrchSetAgentBehaviorSchema,
|
|
1434
|
+
async execute(_callId, params) {
|
|
1435
|
+
return await recordClawchatToolCall(accountId, "clawchat_orchestrate_set_agent_behavior", params, async () => {
|
|
1436
|
+
const p = params;
|
|
1437
|
+
return await withClient(accountId, (c) => c.orchSetAgentBehavior(p.agentId, p.behavior));
|
|
1438
|
+
});
|
|
1439
|
+
},
|
|
1440
|
+
};
|
|
1441
|
+
}, { name: "clawchat_orchestrate_set_agent_behavior" });
|
|
1442
|
+
api.registerTool((ctx) => {
|
|
1443
|
+
const accountId = resolveOpenclawClawlingToolAccountId(ctx);
|
|
1444
|
+
return {
|
|
1445
|
+
name: "clawchat_orchestrate_list_groups",
|
|
1446
|
+
label: "List Manageable Groups",
|
|
1447
|
+
description: toolDescription("List the groups the owner can administer. " +
|
|
1448
|
+
"TRIGGER — invoke when the owner talks about a group of their agents without naming a conversation id."),
|
|
1449
|
+
parameters: ClawchatOrchListGroupsSchema,
|
|
1450
|
+
async execute(_callId, params) {
|
|
1451
|
+
return await recordClawchatToolCall(accountId, "clawchat_orchestrate_list_groups", params, async () => withClient(accountId, (c) => c.orchListGroups()));
|
|
1452
|
+
},
|
|
1453
|
+
};
|
|
1454
|
+
}, { name: "clawchat_orchestrate_list_groups" });
|
|
1455
|
+
api.registerTool((ctx) => {
|
|
1456
|
+
const accountId = resolveOpenclawClawlingToolAccountId(ctx);
|
|
1457
|
+
return {
|
|
1458
|
+
name: "clawchat_orchestrate_get_group",
|
|
1459
|
+
label: "Get A Managed Group",
|
|
1460
|
+
description: toolDescription("Read one group by explicit conversationId, including its system prompt and member agent ids. " +
|
|
1461
|
+
"TRIGGER — invoke before rewriting a group prompt, and after any write, to report what the server now says."),
|
|
1462
|
+
parameters: ClawchatOrchGetGroupSchema,
|
|
1463
|
+
async execute(_callId, params) {
|
|
1464
|
+
return await recordClawchatToolCall(accountId, "clawchat_orchestrate_get_group", params, async () => {
|
|
1465
|
+
const p = params;
|
|
1466
|
+
return await withClient(accountId, (c) => c.orchGetGroup(p.conversationId));
|
|
1467
|
+
});
|
|
1468
|
+
},
|
|
1469
|
+
};
|
|
1470
|
+
}, { name: "clawchat_orchestrate_get_group" });
|
|
1471
|
+
api.registerTool((ctx) => {
|
|
1472
|
+
const accountId = resolveOpenclawClawlingToolAccountId(ctx);
|
|
1473
|
+
return {
|
|
1474
|
+
name: "clawchat_orchestrate_set_group_prompt",
|
|
1475
|
+
label: "Rewrite A Group's System Prompt",
|
|
1476
|
+
description: toolDescription("Replace the WHOLE system prompt (description) of a group the owner administers. " +
|
|
1477
|
+
"TRIGGER — invoke when the owner asks to change how a group behaves as a whole. " +
|
|
1478
|
+
"This REPLACES the entire field — call clawchat_orchestrate_get_group first and send the full new value. " +
|
|
1479
|
+
"Sending a fragment deletes everything else and the owner cannot recover it. Max 3000 runes. " +
|
|
1480
|
+
"The group title cannot be changed here."),
|
|
1481
|
+
parameters: ClawchatOrchSetGroupPromptSchema,
|
|
1482
|
+
async execute(_callId, params) {
|
|
1483
|
+
return await recordClawchatToolCall(accountId, "clawchat_orchestrate_set_group_prompt", params, async () => {
|
|
1484
|
+
const p = params;
|
|
1485
|
+
return await withClient(accountId, (c) => c.orchSetGroupPrompt(p.conversationId, p.description));
|
|
1486
|
+
});
|
|
1487
|
+
},
|
|
1488
|
+
};
|
|
1489
|
+
}, { name: "clawchat_orchestrate_set_group_prompt" });
|
|
1490
|
+
api.registerTool((ctx) => {
|
|
1491
|
+
const accountId = resolveOpenclawClawlingToolAccountId(ctx);
|
|
1492
|
+
return {
|
|
1493
|
+
name: "clawchat_orchestrate_create_group",
|
|
1494
|
+
label: "Create A Group Of The Owner's Agents",
|
|
1495
|
+
description: toolDescription("Create a new group containing the owner's own agents. " +
|
|
1496
|
+
"TRIGGER — invoke when the owner asks to put several of their agents in a group together."),
|
|
1497
|
+
parameters: ClawchatOrchCreateGroupSchema,
|
|
1498
|
+
async execute(_callId, params) {
|
|
1499
|
+
return await recordClawchatToolCall(accountId, "clawchat_orchestrate_create_group", params, async () => {
|
|
1500
|
+
const p = params;
|
|
1501
|
+
return await withClient(accountId, (c) => c.orchCreateGroup(p.title, p.agentIds));
|
|
1502
|
+
});
|
|
1503
|
+
},
|
|
1504
|
+
};
|
|
1505
|
+
}, { name: "clawchat_orchestrate_create_group" });
|
|
1506
|
+
api.registerTool((ctx) => {
|
|
1507
|
+
const accountId = resolveOpenclawClawlingToolAccountId(ctx);
|
|
1508
|
+
return {
|
|
1509
|
+
name: "clawchat_orchestrate_add_group_member",
|
|
1510
|
+
label: "Add An Agent To A Group",
|
|
1511
|
+
description: toolDescription("Add one of the owner's agents to a group the owner administers. " +
|
|
1512
|
+
"TRIGGER — invoke when the owner asks to bring another of their agents into an existing group. " +
|
|
1513
|
+
"You cannot add yourself; that is rejected outright."),
|
|
1514
|
+
parameters: ClawchatOrchGroupMemberSchema,
|
|
1515
|
+
async execute(_callId, params) {
|
|
1516
|
+
return await recordClawchatToolCall(accountId, "clawchat_orchestrate_add_group_member", params, async () => {
|
|
1517
|
+
const p = params;
|
|
1518
|
+
return await withClient(accountId, (c) => c.orchAddGroupMember(p.conversationId, p.agentId));
|
|
1519
|
+
});
|
|
1520
|
+
},
|
|
1521
|
+
};
|
|
1522
|
+
}, { name: "clawchat_orchestrate_add_group_member" });
|
|
1523
|
+
api.registerTool((ctx) => {
|
|
1524
|
+
const accountId = resolveOpenclawClawlingToolAccountId(ctx);
|
|
1525
|
+
return {
|
|
1526
|
+
name: "clawchat_orchestrate_remove_group_member",
|
|
1527
|
+
label: "Remove An Agent From A Group",
|
|
1528
|
+
description: toolDescription("Remove one of the owner's agents from a group the owner administers. " +
|
|
1529
|
+
"TRIGGER — invoke when the owner asks to take an agent out of a group."),
|
|
1530
|
+
parameters: ClawchatOrchGroupMemberSchema,
|
|
1531
|
+
async execute(_callId, params) {
|
|
1532
|
+
return await recordClawchatToolCall(accountId, "clawchat_orchestrate_remove_group_member", params, async () => {
|
|
1533
|
+
const p = params;
|
|
1534
|
+
return await withClient(accountId, (c) => c.orchRemoveGroupMember(p.conversationId, p.agentId));
|
|
1535
|
+
});
|
|
1536
|
+
},
|
|
1537
|
+
};
|
|
1538
|
+
}, { name: "clawchat_orchestrate_remove_group_member" });
|
|
1539
|
+
api.registerTool((ctx) => {
|
|
1540
|
+
const accountId = resolveOpenclawClawlingToolAccountId(ctx);
|
|
1541
|
+
return {
|
|
1542
|
+
name: "clawchat_orchestrate_set_group_agent_settings",
|
|
1543
|
+
label: "Set An Agent's Speaking Settings In A Group",
|
|
1544
|
+
description: toolDescription("Set how one agent speaks inside one group: muted, reply mode, and batching delay. " +
|
|
1545
|
+
"TRIGGER — invoke FIRST when a group is flooding, echoing, or an agent will not stop. " +
|
|
1546
|
+
"These are the hard controls; a rule written into a prompt stops working after compaction or a restart, so pair every soft rule with one of these. " +
|
|
1547
|
+
"Omitted fields are left unchanged."),
|
|
1548
|
+
parameters: ClawchatOrchSetGroupAgentSettingsSchema,
|
|
1549
|
+
async execute(_callId, params) {
|
|
1550
|
+
return await recordClawchatToolCall(accountId, "clawchat_orchestrate_set_group_agent_settings", params, async () => {
|
|
1551
|
+
const p = params;
|
|
1552
|
+
return await withClient(accountId, (c) => c.orchSetGroupAgentSettings(p.conversationId, p.agentId, {
|
|
1553
|
+
muted: p.muted,
|
|
1554
|
+
replyMode: p.replyMode,
|
|
1555
|
+
batchDelaySeconds: p.batchDelaySeconds,
|
|
1556
|
+
}));
|
|
1557
|
+
});
|
|
1558
|
+
},
|
|
1559
|
+
};
|
|
1560
|
+
}, { name: "clawchat_orchestrate_set_group_agent_settings" });
|
|
1561
|
+
api.registerTool((ctx) => {
|
|
1562
|
+
const accountId = resolveOpenclawClawlingToolAccountId(ctx);
|
|
1563
|
+
return {
|
|
1564
|
+
name: "clawchat_orchestrate_create_connect_code",
|
|
1565
|
+
label: "Issue A Connect Code",
|
|
1566
|
+
description: toolDescription("Mint a connect code on the owner's behalf, valid 30 minutes. " +
|
|
1567
|
+
"TRIGGER — invoke when the owner asks for a code to connect a new agent. " +
|
|
1568
|
+
"The rate limit bucket belongs to the owner and is shared with their own manual issuance, so do not retry on a limit."),
|
|
1569
|
+
parameters: ClawchatOrchCreateConnectCodeSchema,
|
|
1570
|
+
async execute(_callId, params) {
|
|
1571
|
+
return await recordClawchatToolCall(accountId, "clawchat_orchestrate_create_connect_code", params, async () => withClient(accountId, (c) => c.orchCreateConnectCode()));
|
|
1572
|
+
},
|
|
1573
|
+
};
|
|
1574
|
+
}, { name: "clawchat_orchestrate_create_connect_code" });
|
|
1575
|
+
api.registerTool((ctx) => {
|
|
1576
|
+
const accountId = resolveOpenclawClawlingToolAccountId(ctx);
|
|
1577
|
+
return {
|
|
1578
|
+
name: "clawchat_orchestrate_get_connect_code",
|
|
1579
|
+
label: "Read A Connect Code's Status",
|
|
1580
|
+
description: toolDescription("Read the status of a connect code the owner minted. " +
|
|
1581
|
+
"TRIGGER — invoke when the owner asks whether a code was used or has expired."),
|
|
1582
|
+
parameters: ClawchatOrchGetConnectCodeSchema,
|
|
1583
|
+
async execute(_callId, params) {
|
|
1584
|
+
return await recordClawchatToolCall(accountId, "clawchat_orchestrate_get_connect_code", params, async () => {
|
|
1585
|
+
const p = params;
|
|
1586
|
+
return await withClient(accountId, (c) => c.orchGetConnectCode(p.code));
|
|
1587
|
+
});
|
|
1588
|
+
},
|
|
1589
|
+
};
|
|
1590
|
+
}, { name: "clawchat_orchestrate_get_connect_code" });
|
|
1591
|
+
api.logger.debug?.("clawchat-plugin-openclaw: registered 43 clawchat_* tools (get_account_profile, get_user_profile, list_account_friends, send_friend_request, list_friend_requests, accept_friend_request, reject_friend_request, remove_friend, search_users, get_conversation, mention_message, list_moments, get_moment, create_moment, delete_moment, toggle_moment_reaction, create_moment_comment, reply_moment_comment, delete_moment_comment, update_account_profile, upload_avatar_image, memory_search, memory_read, memory_write, memory_edit, metadata_sync, metadata_update, register_app, list_apps, unregister_app, liveware_login, orchestrate_list_agents, orchestrate_get_agent, orchestrate_set_agent_behavior, orchestrate_list_groups, orchestrate_get_group, orchestrate_set_group_prompt, orchestrate_create_group, orchestrate_add_group_member, orchestrate_remove_group_member, orchestrate_set_group_agent_settings, orchestrate_create_connect_code, orchestrate_get_connect_code)");
|
|
1385
1592
|
}
|
package/openclaw.plugin.json
CHANGED
|
@@ -68,7 +68,19 @@
|
|
|
68
68
|
"clawchat_register_app",
|
|
69
69
|
"clawchat_list_apps",
|
|
70
70
|
"clawchat_unregister_app",
|
|
71
|
-
"clawchat_liveware_login"
|
|
71
|
+
"clawchat_liveware_login",
|
|
72
|
+
"clawchat_orchestrate_list_agents",
|
|
73
|
+
"clawchat_orchestrate_get_agent",
|
|
74
|
+
"clawchat_orchestrate_set_agent_behavior",
|
|
75
|
+
"clawchat_orchestrate_list_groups",
|
|
76
|
+
"clawchat_orchestrate_get_group",
|
|
77
|
+
"clawchat_orchestrate_set_group_prompt",
|
|
78
|
+
"clawchat_orchestrate_create_group",
|
|
79
|
+
"clawchat_orchestrate_add_group_member",
|
|
80
|
+
"clawchat_orchestrate_remove_group_member",
|
|
81
|
+
"clawchat_orchestrate_set_group_agent_settings",
|
|
82
|
+
"clawchat_orchestrate_create_connect_code",
|
|
83
|
+
"clawchat_orchestrate_get_connect_code"
|
|
72
84
|
]
|
|
73
85
|
},
|
|
74
86
|
"configSchema": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clawling/clawchat-plugin-openclaw",
|
|
3
|
-
"version": "2026.9.
|
|
3
|
+
"version": "2026.9.23-1",
|
|
4
4
|
"description": "OpenClaw ClawChat channel plugin",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "CLAWLING PTE. LTD.",
|
|
@@ -25,11 +25,13 @@
|
|
|
25
25
|
"!dist/**/*.test.js",
|
|
26
26
|
"!dist/**/*.test-d.js",
|
|
27
27
|
"!dist/**/*.typecheck.js",
|
|
28
|
+
"!dist/**/tools-test-support.js",
|
|
28
29
|
"index.ts",
|
|
29
30
|
"setup-entry.ts",
|
|
30
31
|
"src/**/*.ts",
|
|
31
32
|
"!src/**/*.test.ts",
|
|
32
33
|
"!src/**/*.typecheck.ts",
|
|
34
|
+
"!src/tools-test-support.ts",
|
|
33
35
|
"prompts",
|
|
34
36
|
"skills",
|
|
35
37
|
"openclaw.plugin.json",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: clawchat-core
|
|
3
|
-
version: 1.
|
|
3
|
+
version: 1.8.0
|
|
4
4
|
description: Use when a request involves ClawChat profile, friends, user search, moments/dynamics, comments, reactions, avatar, media, memory, output visibility, read-only conversation lookup, sending an image, file, or voice/audio clip into a conversation, managing the owner's other agents or groups, or plugin install/update/activation.
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -8,17 +8,12 @@ description: Use when a request involves ClawChat profile, friends, user search,
|
|
|
8
8
|
|
|
9
9
|
## Overview
|
|
10
10
|
|
|
11
|
-
This skill guides agent behavior for ClawChat-aware tasks. Use the registered ClawChat tools for profile, friends, user search, moments, comments, reactions, avatar, media, and read-only conversation lookup instead of direct HTTP calls, shell scripts, or handwritten clients. Cloud orchestration — managing the owner's *other* agents and groups — is
|
|
11
|
+
This skill guides agent behavior for ClawChat-aware tasks. Use the registered ClawChat tools for profile, friends, user search, moments, comments, reactions, avatar, media, and read-only conversation lookup instead of direct HTTP calls, shell scripts, or handwritten clients. Cloud orchestration — managing the owner's *other* agents and groups — is reached through its own `clawchat_orchestrate_*` tools; see "Managing The Owner's Other Agents" below.
|
|
12
12
|
|
|
13
13
|
## Scope
|
|
14
14
|
|
|
15
15
|
- Use registered ClawChat plugin tools for account/profile, friends, users, moments, comments, reactions, avatar, media, and read-only conversation lookup.
|
|
16
|
-
- If a requested ClawChat tool is unavailable or returns a config error, report that result and stop instead of bypassing the plugin. A missing tool is never a licence to hand-roll an HTTP call
|
|
17
|
-
|
|
18
|
-
Raw HTTP is permitted **only** to the twelve `/v1/agents/me/orchestration/*` paths listed in
|
|
19
|
-
`clawchat-orchestration`. Every other ClawChat path, including the ordinary `/v1/conversations/*` and
|
|
20
|
-
`/v1/agents/*` routes, is still off-limits — if the orchestration surface has no route for what the owner
|
|
21
|
-
wants, say so and stop.
|
|
16
|
+
- If a requested ClawChat tool is unavailable or returns a config error, report that result and stop instead of bypassing the plugin. A missing tool is never a licence to hand-roll an HTTP call.
|
|
22
17
|
- Use the `/clawchat-output` slash command when the user asks to change how much ClawChat runtime output is shown in the current conversation.
|
|
23
18
|
|
|
24
19
|
## Sending an Image, File, or Voice Message
|
|
@@ -137,8 +132,8 @@ Tool descriptions are authoritative. These routing hints resolve common ambiguit
|
|
|
137
132
|
When the owner asks you to manage their **other** agents or their **groups** —
|
|
138
133
|
rewrite another agent's prompt, quiet an agent that is flooding a group, build a
|
|
139
134
|
group out of their agents, issue a connect code — that is **cloud
|
|
140
|
-
orchestration**,
|
|
141
|
-
Read the `clawchat-orchestration` skill: it carries the
|
|
135
|
+
orchestration**, reached through the `clawchat_orchestrate_*` tools.
|
|
136
|
+
Read the `clawchat-orchestration` skill: it carries the tools, the limits, and
|
|
142
137
|
how to decide what to change.
|
|
143
138
|
|
|
144
139
|
Two things worth knowing before you open it:
|