@dhfpub/clawpool-admin 0.2.0 → 0.2.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/README.md CHANGED
@@ -14,7 +14,7 @@ If you are reading the channel plugin documentation first, also read:
14
14
  ## Which Package Do I Need?
15
15
 
16
16
  - Install only `@dhfpub/clawpool` when you only need ClawPool channel transport, website onboarding, and the bundled onboarding skill
17
- - Install both `@dhfpub/clawpool` and `@dhfpub/clawpool-admin` when you want typed group governance or typed API-agent admin actions inside OpenClaw
17
+ - Install both `@dhfpub/clawpool` and `@dhfpub/clawpool-admin` when you want typed query, group governance, or typed API-agent admin actions inside OpenClaw
18
18
  - Do not install only `@dhfpub/clawpool-admin` and expect it to work alone, because it depends on the `channels.clawpool` credentials managed by `@dhfpub/clawpool`
19
19
 
20
20
  ## Install
@@ -48,7 +48,7 @@ For the channel-side setup flow, see:
48
48
  3. Enable the required tools in OpenClaw config
49
49
  4. Restart the OpenClaw gateway
50
50
 
51
- If the `tools` block is missing, the plugin may be installed and loaded, but the agent still cannot use `clawpool_group` or `clawpool_agent_admin`.
51
+ If the `tools` block is missing, the plugin may be installed and loaded, but the agent still cannot use `clawpool_query`, `clawpool_group`, or `clawpool_agent_admin`.
52
52
 
53
53
  ## Configure `channels.clawpool` First
54
54
 
@@ -79,6 +79,7 @@ To make the admin capabilities available to the OpenClaw agent, configure `tools
79
79
  "profile": "coding",
80
80
  "alsoAllow": [
81
81
  "message",
82
+ "clawpool_query",
82
83
  "clawpool_group",
83
84
  "clawpool_agent_admin"
84
85
  ],
@@ -92,6 +93,7 @@ To make the admin capabilities available to the OpenClaw agent, configure `tools
92
93
  These fields are required for the intended ClawPool group-governance workflow:
93
94
 
94
95
  - `message`: lets the agent send and coordinate messages in the group workflow
96
+ - `clawpool_query`: enables typed contact search, session search, and session message-history lookup
95
97
  - `clawpool_group`: enables typed group governance actions
96
98
  - `clawpool_agent_admin`: enables typed API-agent admin actions
97
99
  - `sessions.visibility = agent`: ensures the tool session context is visible to the agent runtime
@@ -112,6 +114,7 @@ These fields are required for the intended ClawPool group-governance workflow:
112
114
  "profile": "coding",
113
115
  "alsoAllow": [
114
116
  "message",
117
+ "clawpool_query",
115
118
  "clawpool_group",
116
119
  "clawpool_agent_admin"
117
120
  ],
@@ -134,11 +137,19 @@ openclaw clawpool-admin doctor
134
137
  Expected result:
135
138
 
136
139
  - `plugins info clawpool-admin` shows `enabled=true`, `status=loaded`
137
- - the plugin exposes `clawpool_group` and `clawpool_agent_admin`
140
+ - the plugin exposes `clawpool_query`, `clawpool_group`, and `clawpool_agent_admin`
138
141
  - `clawpool-admin doctor` can see the configured `channels.clawpool` account
139
142
 
140
143
  ## Agent Tools
141
144
 
145
+ ### `clawpool_query`
146
+
147
+ Typed query tool with these actions:
148
+
149
+ - `contact_search`
150
+ - `session_search`
151
+ - `message_history`
152
+
142
153
  ### `clawpool_group`
143
154
 
144
155
  Typed group governance tool with these actions:
package/dist/index.js CHANGED
@@ -294,6 +294,66 @@ function buildGroupDetailReadRequest(params) {
294
294
  }
295
295
  };
296
296
  }
297
+ function buildContactSearchRequest(params) {
298
+ const keyword = readRequiredStringParam(params, "keyword");
299
+ const limit = readOptionalInt(params, "limit");
300
+ const offset = readOptionalInt(params, "offset");
301
+ const query = {
302
+ keyword
303
+ };
304
+ if (limit != null) {
305
+ query.limit = String(limit);
306
+ }
307
+ if (offset != null) {
308
+ query.offset = String(offset);
309
+ }
310
+ return {
311
+ actionName: "contact_search",
312
+ method: "GET",
313
+ path: "/contacts/search",
314
+ query
315
+ };
316
+ }
317
+ function buildSessionSearchRequest(params) {
318
+ const keyword = readRequiredStringParam(params, "keyword");
319
+ const limit = readOptionalInt(params, "limit");
320
+ const offset = readOptionalInt(params, "offset");
321
+ const query = {
322
+ keyword
323
+ };
324
+ if (limit != null) {
325
+ query.limit = String(limit);
326
+ }
327
+ if (offset != null) {
328
+ query.offset = String(offset);
329
+ }
330
+ return {
331
+ actionName: "session_search",
332
+ method: "GET",
333
+ path: "/sessions/search",
334
+ query
335
+ };
336
+ }
337
+ function buildMessageHistoryRequest(params) {
338
+ const sessionID = readRequiredStringParam(params, "sessionId");
339
+ const beforeID = readStringParam(params, "beforeId");
340
+ const limit = readOptionalInt(params, "limit");
341
+ const query = {
342
+ session_id: sessionID
343
+ };
344
+ if (beforeID) {
345
+ query.before_id = beforeID;
346
+ }
347
+ if (limit != null) {
348
+ query.limit = String(limit);
349
+ }
350
+ return {
351
+ actionName: "message_history",
352
+ method: "GET",
353
+ path: "/messages/history",
354
+ query
355
+ };
356
+ }
297
357
  function buildAgentAPICreateRequest(params) {
298
358
  const agentName = readRequiredStringParam(params, "agentName");
299
359
  if (!AGENT_NAME_RE.test(agentName)) {
@@ -315,6 +375,12 @@ function buildAgentAPICreateRequest(params) {
315
375
  }
316
376
  function buildAgentHTTPRequest(action, params) {
317
377
  switch (action) {
378
+ case "contact_search":
379
+ return buildContactSearchRequest(params);
380
+ case "session_search":
381
+ return buildSessionSearchRequest(params);
382
+ case "message_history":
383
+ return buildMessageHistoryRequest(params);
318
384
  case "group_create":
319
385
  return buildGroupCreateRequest(params);
320
386
  case "group_member_add":
@@ -919,6 +985,113 @@ function createClawpoolGroupTool(api) {
919
985
  };
920
986
  }
921
987
 
988
+ // src/query-service.ts
989
+ function mapQueryActionToRequestAction(action) {
990
+ switch (action) {
991
+ case "contact_search":
992
+ return "contact_search";
993
+ case "session_search":
994
+ return "session_search";
995
+ case "message_history":
996
+ return "message_history";
997
+ default:
998
+ action;
999
+ throw new Error(`Unsupported Clawpool query action: ${String(action)}`);
1000
+ }
1001
+ }
1002
+ async function runClawpoolQueryAction(params) {
1003
+ const account = resolveClawpoolAccount({
1004
+ cfg: params.cfg,
1005
+ accountId: params.toolParams.accountId
1006
+ });
1007
+ if (!account.enabled) {
1008
+ throw new Error(`Clawpool account "${account.accountId}" is disabled.`);
1009
+ }
1010
+ if (!account.configured) {
1011
+ throw new Error(`Clawpool account "${account.accountId}" is not configured.`);
1012
+ }
1013
+ const requestAction = mapQueryActionToRequestAction(params.toolParams.action);
1014
+ const request = buildAgentHTTPRequest(requestAction, params.toolParams);
1015
+ const data = await callAgentAPI({
1016
+ account,
1017
+ actionName: request.actionName,
1018
+ method: request.method,
1019
+ path: request.path,
1020
+ query: request.query,
1021
+ body: request.body
1022
+ });
1023
+ return {
1024
+ ok: true,
1025
+ accountId: account.accountId,
1026
+ action: params.toolParams.action,
1027
+ data
1028
+ };
1029
+ }
1030
+
1031
+ // src/query-tool.ts
1032
+ var ClawpoolQueryToolSchema = {
1033
+ oneOf: [
1034
+ {
1035
+ type: "object",
1036
+ additionalProperties: false,
1037
+ properties: {
1038
+ action: { const: "contact_search" },
1039
+ accountId: { type: "string", minLength: 1 },
1040
+ keyword: { type: "string", minLength: 1 },
1041
+ limit: { type: "integer", minimum: 1 },
1042
+ offset: { type: "integer", minimum: 0 }
1043
+ },
1044
+ required: ["action", "keyword"]
1045
+ },
1046
+ {
1047
+ type: "object",
1048
+ additionalProperties: false,
1049
+ properties: {
1050
+ action: { const: "session_search" },
1051
+ accountId: { type: "string", minLength: 1 },
1052
+ keyword: { type: "string", minLength: 1 },
1053
+ limit: { type: "integer", minimum: 1 },
1054
+ offset: { type: "integer", minimum: 0 }
1055
+ },
1056
+ required: ["action", "keyword"]
1057
+ },
1058
+ {
1059
+ type: "object",
1060
+ additionalProperties: false,
1061
+ properties: {
1062
+ action: { const: "message_history" },
1063
+ accountId: { type: "string", minLength: 1 },
1064
+ sessionId: { type: "string", minLength: 1 },
1065
+ beforeId: { type: "string", pattern: "^[0-9]+$" },
1066
+ limit: { type: "integer", minimum: 1 }
1067
+ },
1068
+ required: ["action", "sessionId"]
1069
+ }
1070
+ ]
1071
+ };
1072
+ function createClawpoolQueryTool(api) {
1073
+ return {
1074
+ name: "clawpool_query",
1075
+ label: "Clawpool Query",
1076
+ description: "Search Clawpool contacts and sessions, or read session message history through typed query operations.",
1077
+ parameters: ClawpoolQueryToolSchema,
1078
+ async execute(_toolCallId, params) {
1079
+ try {
1080
+ return jsonToolResult(
1081
+ await runClawpoolQueryAction({
1082
+ cfg: api.config,
1083
+ toolParams: params
1084
+ })
1085
+ );
1086
+ } catch (err) {
1087
+ return jsonToolResult({
1088
+ error: err instanceof Error ? err.message : String(err)
1089
+ });
1090
+ }
1091
+ }
1092
+ };
1093
+ }
1094
+
922
1095
  // index.ts
923
1096
  var plugin = {
924
1097
  id: "clawpool-admin",
@@ -926,6 +1099,7 @@ var plugin = {
926
1099
  description: "Typed optional admin tools and operator CLI for Clawpool",
927
1100
  configSchema: emptyPluginConfigSchema(),
928
1101
  register(api) {
1102
+ api.registerTool(createClawpoolQueryTool(api), { optional: true });
929
1103
  api.registerTool(createClawpoolGroupTool(api), { optional: true });
930
1104
  api.registerTool(createClawpoolAgentAdminTool(api), { optional: true });
931
1105
  api.registerCli(({ program }) => registerClawpoolAdminCli({ api, program }), {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhfpub/clawpool-admin",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "OpenClaw admin tools plugin for ClawPool",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -11,7 +11,7 @@ This skill is about tool selection and guardrails, not protocol bridging.
11
11
  ## Workflow
12
12
 
13
13
  1. Parse the user request into one action:
14
- `create`, `detail`, `add_members`, `remove_members`, `update_member_role`, or `dissolve`.
14
+ `create`, `detail`, `add_members`, `remove_members`, `update_member_role`, `update_all_members_muted`, `update_member_speaking`, or `dissolve`.
15
15
  2. Validate required fields before any call.
16
16
  3. Call `clawpool_group` exactly once per business action.
17
17
  4. Classify failures by HTTP/BizCode and return exact remediation.
@@ -23,13 +23,13 @@ This skill is about tool selection and guardrails, not protocol bridging.
23
23
  For Clawpool group governance, always call:
24
24
 
25
25
  1. Tool: `clawpool_group`
26
- 2. `action`: one of `create`, `detail`, `add_members`, `remove_members`, `update_member_role`, `dissolve`
26
+ 2. `action`: one of `create`, `detail`, `add_members`, `remove_members`, `update_member_role`, `update_all_members_muted`, `update_member_speaking`, `dissolve`
27
27
  3. `accountId`: optional; include it when the configured account is ambiguous
28
28
 
29
29
  Rules:
30
30
 
31
31
  1. Pass business parameters with their exact typed field names.
32
- 2. Use `sessionId`, `memberIds`, `memberTypes`, `memberId`, `memberType`, and `role` explicitly.
32
+ 2. Use `sessionId`, `memberIds`, `memberTypes`, `memberId`, `memberType`, `role`, `allMembersMuted`, `isSpeakMuted`, and `canSpeakWhenAllMuted` explicitly.
33
33
  3. Do not invent aliases or fallback fields.
34
34
  4. Keep one tool call per action for audit clarity.
35
35
 
@@ -87,6 +87,32 @@ Guardrails:
87
87
  1. Only use `memberType=1` for role updates.
88
88
  2. Never guess a role value; confirm when unclear.
89
89
 
90
+ ### update_all_members_muted
91
+
92
+ Required input:
93
+
94
+ 1. `sessionId`
95
+ 2. `allMembersMuted`
96
+
97
+ Guardrails:
98
+
99
+ 1. Only use this for group-wide mute state changes.
100
+ 2. Never guess the desired mute state from vague wording; confirm whether the user wants to enable or disable all-member mute.
101
+
102
+ ### update_member_speaking
103
+
104
+ Required input:
105
+
106
+ 1. `sessionId`
107
+ 2. `memberId`
108
+ 3. At least one of `isSpeakMuted` or `canSpeakWhenAllMuted`
109
+
110
+ Guardrails:
111
+
112
+ 1. Only use `memberType=1` or `memberType=2`.
113
+ 2. Do not send an empty speaking update; at least one speaking field must be explicit.
114
+ 3. If the target member is ambiguous, ask the user to confirm the exact member first.
115
+
90
116
  ### detail / dissolve
91
117
 
92
118
  Required input:
@@ -109,7 +135,7 @@ Required input:
109
135
  ## Response Style
110
136
 
111
137
  1. State action result first.
112
- 2. Include key identifiers (`session_id`, member count) when successful.
138
+ 2. Include key identifiers (`session_id`, member count, mute state) when successful.
113
139
  3. Include exact remediation when failed.
114
140
  4. Never hide scope or auth errors behind generic wording.
115
141
 
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: clawpool-query
3
+ description: Use the typed `clawpool_query` tool for Clawpool contact search, session search, and session message history lookup. Trigger when users ask to find contacts, locate a conversation, or inspect recent messages in a known session.
4
+ ---
5
+
6
+ # Clawpool Query
7
+
8
+ Use the `clawpool_query` tool for read-only Clawpool lookup actions.
9
+ This skill is only for querying existing contacts, sessions, and message history.
10
+
11
+ ## Workflow
12
+
13
+ 1. Parse the user request into one action:
14
+ `contact_search`, `session_search`, or `message_history`.
15
+ 2. Validate required fields before any tool call.
16
+ 3. Call `clawpool_query` exactly once per business action.
17
+ 4. If the user wants message history but no `sessionId` is known, locate the target session first through `session_search` or ask the user for a precise target.
18
+ 5. Return exact remediation for scope, auth, and parameter failures.
19
+
20
+ ## Tool Contract
21
+
22
+ For Clawpool query actions, always call:
23
+
24
+ 1. Tool: `clawpool_query`
25
+ 2. `action`: one of `contact_search`, `session_search`, or `message_history`
26
+ 3. `accountId`: optional; include it when the configured account is ambiguous
27
+
28
+ Rules:
29
+
30
+ 1. Pass query parameters with their exact typed field names.
31
+ 2. Use `keyword` for search actions.
32
+ 3. Use `sessionId`, `beforeId`, and `limit` explicitly for message history.
33
+ 4. Never invent a `sessionId`. Resolve it from context, from a previous tool result, or ask the user.
34
+ 5. Keep one tool call per action for audit clarity.
35
+
36
+ ## Action Contracts
37
+
38
+ ### contact_search
39
+
40
+ Purpose: search the owner's Clawpool contact directory.
41
+
42
+ Required input:
43
+
44
+ 1. `keyword` (non-empty string)
45
+
46
+ Optional input:
47
+
48
+ 1. `limit`
49
+ 2. `offset`
50
+
51
+ Guardrails:
52
+
53
+ 1. Use this when the user is trying to find a person or active agent by display name, remark, nickname, username, or agent name.
54
+ 2. Do not jump directly to session history from a vague contact hint; resolve the contact or session first.
55
+
56
+ ### session_search
57
+
58
+ Purpose: search the owner's visible sessions by final display title.
59
+
60
+ Required input:
61
+
62
+ 1. `keyword` (non-empty string)
63
+
64
+ Optional input:
65
+
66
+ 1. `limit`
67
+ 2. `offset`
68
+
69
+ Guardrails:
70
+
71
+ 1. Use this when the user describes a conversation by session title, group name, or known list title.
72
+ 2. If multiple sessions match, present the candidates and let the user choose before reading history.
73
+
74
+ ### message_history
75
+
76
+ Purpose: read recent message history from a known session.
77
+
78
+ Required input:
79
+
80
+ 1. `sessionId`
81
+
82
+ Optional input:
83
+
84
+ 1. `beforeId`
85
+ 2. `limit`
86
+
87
+ Guardrails:
88
+
89
+ 1. Only call this after the target session is unambiguous.
90
+ 2. Use `beforeId` only for older-page pagination.
91
+ 3. Do not claim to have full history if only one page was fetched.
92
+
93
+ ## Error Handling Rules
94
+
95
+ 1. `403/20011`:
96
+ report missing scope and ask the owner to grant the required scope in the Aibot Agent permission page.
97
+ 2. `401/10001`:
98
+ report invalid key/auth and suggest checking agent config or rotating the API key.
99
+ 3. `403/10002`:
100
+ report the agent is not active or has an invalid provider type.
101
+ 4. `400/10003`:
102
+ report invalid or missing parameters and ask the user for corrected values.
103
+ 5. `404/4004`:
104
+ report the target session does not exist or is not visible.
105
+ 6. Other errors:
106
+ return the backend `msg` and stop automatic retries.
107
+
108
+ ## Response Style
109
+
110
+ 1. State the query result first.
111
+ 2. Include key identifiers from successful lookups:
112
+ `peer_id` / `peer_type` for contacts, `session_id` for sessions, and message identifiers for history.
113
+ 3. If history results may be partial, state that clearly.
114
+ 4. Never hide scope or auth errors behind generic wording.
@@ -0,0 +1,4 @@
1
+ version: 1
2
+ agent:
3
+ name: clawpool-query
4
+ default_prompt: "Use this skill when users ask to find Clawpool contacts, locate sessions, or inspect a known session's message history. Validate required parameters, call clawpool_query exactly once per action, and do not fabricate a sessionId."