@newbase-clawchat/openclaw-clawchat 2026.4.29 → 2026.5.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/README.md +37 -11
- package/dist/index.js +27 -0
- package/dist/src/api-client.js +156 -0
- package/dist/src/api-types.js +17 -0
- package/dist/src/buffered-stream.js +177 -0
- package/dist/src/channel.js +200 -0
- package/dist/src/client.js +176 -0
- package/dist/src/commands.js +35 -0
- package/dist/src/config.js +226 -0
- package/dist/src/inbound.js +133 -0
- package/dist/src/login.runtime.js +132 -0
- package/dist/src/media-runtime.js +85 -0
- package/dist/src/message-mapper.js +82 -0
- package/dist/src/outbound.js +181 -0
- package/dist/src/protocol.js +38 -0
- package/dist/src/reply-dispatcher.js +440 -0
- package/dist/src/runtime.js +288 -0
- package/dist/src/streaming.js +65 -0
- package/dist/src/tools-schema.js +38 -0
- package/dist/src/tools.js +287 -0
- package/openclaw.plugin.json +21 -0
- package/package.json +27 -5
- package/skills/clawchat-activate/SKILL.md +18 -9
- package/src/buffered-stream.test.ts +10 -0
- package/src/buffered-stream.ts +6 -6
- package/src/channel.outbound.test.ts +3 -3
- package/src/channel.test.ts +7 -1
- package/src/channel.ts +27 -8
- package/src/client.test.ts +8 -1
- package/src/client.ts +11 -10
- package/src/commands.test.ts +6 -0
- package/src/commands.ts +5 -1
- package/src/config.test.ts +47 -0
- package/src/config.ts +28 -5
- package/src/inbound.test.ts +4 -1
- package/src/inbound.ts +11 -10
- package/src/login.runtime.test.ts +36 -0
- package/src/login.runtime.ts +57 -27
- package/src/manifest.test.ts +156 -30
- package/src/outbound.test.ts +6 -5
- package/src/outbound.ts +8 -7
- package/src/plugin-entry.test.ts +7 -1
- package/src/reply-dispatcher.test.ts +418 -3
- package/src/reply-dispatcher.ts +137 -12
- package/src/runtime.ts +1 -0
- package/src/streaming.test.ts +12 -9
- package/src/streaming.ts +6 -6
- package/src/tools.test.ts +81 -18
- package/src/tools.ts +65 -74
package/src/tools.ts
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import type { OpenClawAgentToolResult } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
4
|
-
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/
|
|
4
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
|
|
5
|
+
import type { OpenclawClawchatMutateConfigFile } from "./login.runtime.ts";
|
|
5
6
|
import { createOpenclawClawlingApiClient } from "./api-client.ts";
|
|
6
7
|
import { ClawlingApiError, type Profile } from "./api-types.ts";
|
|
7
8
|
import { resolveOpenclawClawlingAccount } from "./config.ts";
|
|
8
9
|
import {
|
|
9
|
-
|
|
10
|
+
ClawchatActivateSchema,
|
|
10
11
|
ClawchatGetAccountProfileSchema,
|
|
11
12
|
ClawchatGetUserProfileSchema,
|
|
12
13
|
ClawchatListAccountFriendsSchema,
|
|
13
14
|
ClawchatUpdateAccountProfileSchema,
|
|
14
15
|
ClawchatUploadAvatarImageSchema,
|
|
15
16
|
ClawchatUploadMediaFileSchema,
|
|
16
|
-
|
|
17
|
+
type ClawchatActivateParams,
|
|
17
18
|
type ClawchatGetUserProfileParams,
|
|
18
19
|
type ClawchatListAccountFriendsParams,
|
|
19
20
|
type ClawchatUpdateAccountProfileParams,
|
|
@@ -46,12 +47,12 @@ function validationError(message: string) {
|
|
|
46
47
|
return jsonResponse({ error: "validation", message });
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
function resolveActivateCode(params: ClawchatActivateParams & { command?: unknown }): string {
|
|
51
|
+
const explicit = typeof params.code === "string" ? params.code.trim() : "";
|
|
52
|
+
if (explicit) return explicit;
|
|
53
|
+
const command = typeof params.command === "string" ? params.command.trim() : "";
|
|
54
|
+
return command.match(/\b[A-Z0-9]{6}\b/u)?.[0] ?? "";
|
|
55
|
+
}
|
|
55
56
|
|
|
56
57
|
function genericError(err: unknown) {
|
|
57
58
|
return jsonResponse({
|
|
@@ -94,64 +95,53 @@ export function registerOpenclawClawlingTools(api: OpenClawPluginApi): void {
|
|
|
94
95
|
return;
|
|
95
96
|
}
|
|
96
97
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
// { name: "clawchat_activate" },
|
|
145
|
-
// );
|
|
146
|
-
|
|
147
|
-
const account = resolveOpenclawClawlingAccount(api.config);
|
|
148
|
-
if (!account.configured) {
|
|
149
|
-
api.logger.debug?.(
|
|
150
|
-
"openclaw-clawchat: account not yet configured; account tools will register " +
|
|
151
|
-
"on the next config reload after channel login.",
|
|
152
|
-
);
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
98
|
+
api.registerTool(
|
|
99
|
+
{
|
|
100
|
+
name: "clawchat_activate",
|
|
101
|
+
label: "Clawling: Activate (Login with Invite Code)",
|
|
102
|
+
description:
|
|
103
|
+
"Activate this OpenClaw plugin on ClawChat by exchanging an invite code for a token. " +
|
|
104
|
+
"Invite codes use six uppercase letters/digits, e.g. A1B2C3. " +
|
|
105
|
+
"TRIGGER — invoke this tool whenever the user's message matches ANY of: " +
|
|
106
|
+
"(1) activation intent with an embedded invite code, such as 'activate ClawChat with invite code A1B2C3', " +
|
|
107
|
+
"'login to ClawChat with invite code A1B2C3', 'connect ClawChat using invite code A1B2C3', " +
|
|
108
|
+
"or '绑定 ClawChat,邀请码 A1B2C3' — call this tool with `code = \"A1B2C3\"`; " +
|
|
109
|
+
"(2) generic activation intent without an embedded code, such as 'activate ClawChat' or " +
|
|
110
|
+
"'login to ClawChat' — ask for invite code before calling the tool; " +
|
|
111
|
+
"(3) activation intent with an embedded code, such as 'use invite code A1B2C3', " +
|
|
112
|
+
"or the user pasting an invite code in the context of ClawChat activation. " +
|
|
113
|
+
"Extract the code verbatim — do NOT normalize / lowercase / add prefixes. " +
|
|
114
|
+
"On success the tool persists the resulting token + userId to the config, so " +
|
|
115
|
+
"subsequent `clawchat_*` calls work without another plugin registration pass.",
|
|
116
|
+
parameters: ClawchatActivateSchema,
|
|
117
|
+
async execute(_callId, params) {
|
|
118
|
+
const code = resolveActivateCode(params as ClawchatActivateParams & { command?: unknown });
|
|
119
|
+
if (!code) {
|
|
120
|
+
return validationError("openclaw-clawchat: code is required");
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
const { runOpenclawClawlingLogin } = await import("./login.runtime.ts");
|
|
124
|
+
await runOpenclawClawlingLogin({
|
|
125
|
+
cfg: api.config!,
|
|
126
|
+
accountId: null,
|
|
127
|
+
runtime: { log: (message: string) => api.logger.info?.(message) },
|
|
128
|
+
readInviteCode: async () => code,
|
|
129
|
+
mutateConfigFile: (api.runtime.config as unknown as {
|
|
130
|
+
mutateConfigFile: OpenclawClawchatMutateConfigFile;
|
|
131
|
+
}).mutateConfigFile,
|
|
132
|
+
});
|
|
133
|
+
return jsonResponse({
|
|
134
|
+
ok: true,
|
|
135
|
+
message: "ClawChat activated successfully.",
|
|
136
|
+
});
|
|
137
|
+
} catch (err) {
|
|
138
|
+
if (err instanceof ClawlingApiError) return apiError(err);
|
|
139
|
+
return genericError(err);
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
{ name: "clawchat_activate" },
|
|
144
|
+
);
|
|
155
145
|
|
|
156
146
|
// Re-resolve at call time so config reloads pick up new tokens / baseUrl.
|
|
157
147
|
function resolveCurrent() {
|
|
@@ -159,18 +149,19 @@ export function registerOpenclawClawlingTools(api: OpenClawPluginApi): void {
|
|
|
159
149
|
}
|
|
160
150
|
|
|
161
151
|
type ClientResult =
|
|
162
|
-
| { error: OpenClawAgentToolResult<unknown
|
|
163
|
-
| { client: ReturnType<typeof createOpenclawClawlingApiClient
|
|
152
|
+
| { ok: false; error: OpenClawAgentToolResult<unknown> }
|
|
153
|
+
| { ok: true; client: ReturnType<typeof createOpenclawClawlingApiClient> };
|
|
164
154
|
|
|
165
155
|
function buildClient(): ClientResult {
|
|
166
156
|
const acct = resolveCurrent();
|
|
167
157
|
// `baseUrl` always resolves via the built-in default in config.ts, so we
|
|
168
|
-
// only need to gate on `token` here (which is populated by
|
|
169
|
-
//
|
|
158
|
+
// only need to gate on `token` here (which is populated by ClawChat
|
|
159
|
+
// activation/login).
|
|
170
160
|
if (!acct.token) {
|
|
171
|
-
return { error: configError("openclaw-clawchat: token is required") };
|
|
161
|
+
return { ok: false, error: configError("openclaw-clawchat: token is required") };
|
|
172
162
|
}
|
|
173
163
|
return {
|
|
164
|
+
ok: true,
|
|
174
165
|
client: createOpenclawClawlingApiClient({
|
|
175
166
|
baseUrl: acct.baseUrl,
|
|
176
167
|
token: acct.token,
|
|
@@ -184,7 +175,7 @@ export function registerOpenclawClawlingTools(api: OpenClawPluginApi): void {
|
|
|
184
175
|
): Promise<OpenClawAgentToolResult<unknown>> {
|
|
185
176
|
return (async (): Promise<OpenClawAgentToolResult<unknown>> => {
|
|
186
177
|
const built = buildClient();
|
|
187
|
-
if (built.
|
|
178
|
+
if (!built.ok) return built.error;
|
|
188
179
|
try {
|
|
189
180
|
const data = await fn(built.client);
|
|
190
181
|
return jsonResponse(data);
|
|
@@ -368,6 +359,6 @@ export function registerOpenclawClawlingTools(api: OpenClawPluginApi): void {
|
|
|
368
359
|
);
|
|
369
360
|
|
|
370
361
|
api.logger.debug?.(
|
|
371
|
-
"openclaw-clawchat: registered
|
|
362
|
+
"openclaw-clawchat: registered 7 clawchat_* tools (activate, get_account_profile, get_user_profile, list_account_friends, update_account_profile, upload_avatar_image, upload_media_file)",
|
|
372
363
|
);
|
|
373
364
|
}
|