@jerryliang122/openclaw-qqbot 1.0.8 → 2.0.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 +15 -28
- package/README.zh.md +15 -28
- package/dist/index.cjs +264 -247
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -7
- package/package.json +1 -1
- package/src/middleware/attachment.ts +30 -19
- package/src/openclaw-plugin-sdk.d.ts +38 -2
- package/src/tools/platform.ts +86 -72
- package/src/tools/remind.ts +53 -42
- package/src/tools/secret-input.ts +112 -80
- package/src/tools/tool-session.ts +74 -0
- package/src/types.ts +21 -7
- package/src/utils/stt.ts +49 -92
package/dist/index.cjs
CHANGED
|
@@ -8259,7 +8259,7 @@ var init_outbound_service = __esm({
|
|
|
8259
8259
|
|
|
8260
8260
|
// src/utils/pkg-version.ts
|
|
8261
8261
|
function getPackageVersion() {
|
|
8262
|
-
return true ? "
|
|
8262
|
+
return true ? "2.0.0" : "unknown";
|
|
8263
8263
|
}
|
|
8264
8264
|
function getOpenclawVersion(runtimeVersion) {
|
|
8265
8265
|
return runtimeVersion && runtimeVersion !== "unknown" ? runtimeVersion : "unknown";
|
|
@@ -12904,70 +12904,42 @@ init_webhook_server_node();
|
|
|
12904
12904
|
init_webhook_verify();
|
|
12905
12905
|
|
|
12906
12906
|
// src/utils/stt.ts
|
|
12907
|
-
var fs18 = __toESM(require("fs"), 1);
|
|
12908
12907
|
var path16 = __toESM(require("path"), 1);
|
|
12908
|
+
var import_media_understanding_runtime = require("openclaw/plugin-sdk/media-understanding-runtime");
|
|
12909
12909
|
function shouldUsePlatformAsr(cfg) {
|
|
12910
12910
|
const channels = asRecord(cfg.channels);
|
|
12911
12911
|
const qqbot = asRecord(channels?.qqbot);
|
|
12912
|
-
return asRecord(qqbot?.stt)?.asrFallback
|
|
12912
|
+
return asRecord(qqbot?.stt)?.asrFallback !== false;
|
|
12913
12913
|
}
|
|
12914
|
-
function
|
|
12914
|
+
function isFrameworkSttConfigured(cfg) {
|
|
12915
12915
|
const channels = asRecord(cfg.channels);
|
|
12916
12916
|
const qqbot = asRecord(channels?.qqbot);
|
|
12917
|
-
|
|
12918
|
-
|
|
12919
|
-
return null;
|
|
12920
|
-
}
|
|
12921
|
-
const models = asRecord(cfg.models);
|
|
12922
|
-
const providers = asRecord(models?.providers);
|
|
12923
|
-
if (sttCfg) {
|
|
12924
|
-
const providerId = readString(sttCfg, "provider") ?? "openai";
|
|
12925
|
-
const providerCfg = asRecord(providers?.[providerId]);
|
|
12926
|
-
const baseUrl = readString(sttCfg, "baseUrl") ?? readString(providerCfg, "baseUrl");
|
|
12927
|
-
const apiKey = readString(sttCfg, "apiKey") ?? readString(providerCfg, "apiKey");
|
|
12928
|
-
const model = readString(sttCfg, "model") ?? "whisper-1";
|
|
12929
|
-
if (baseUrl && apiKey) {
|
|
12930
|
-
return { enabled: true, baseUrl: baseUrl.replace(/\/+$/, ""), apiKey, model };
|
|
12931
|
-
}
|
|
12917
|
+
if (asRecord(qqbot?.stt)?.enabled === false) {
|
|
12918
|
+
return false;
|
|
12932
12919
|
}
|
|
12933
12920
|
const tools = asRecord(cfg.tools);
|
|
12934
12921
|
const media = asRecord(tools?.media);
|
|
12935
12922
|
const audio = asRecord(media?.audio);
|
|
12936
|
-
|
|
12937
|
-
|
|
12938
|
-
if (audioModelEntry) {
|
|
12939
|
-
const providerId = readString(audioModelEntry, "provider") ?? "openai";
|
|
12940
|
-
const providerCfg = asRecord(providers?.[providerId]);
|
|
12941
|
-
const baseUrl = readString(audioModelEntry, "baseUrl") ?? readString(providerCfg, "baseUrl");
|
|
12942
|
-
const apiKey = readString(audioModelEntry, "apiKey") ?? readString(providerCfg, "apiKey");
|
|
12943
|
-
const model = readString(audioModelEntry, "model") ?? "whisper-1";
|
|
12944
|
-
if (baseUrl && apiKey) {
|
|
12945
|
-
return { enabled: true, baseUrl: baseUrl.replace(/\/+$/, ""), apiKey, model };
|
|
12946
|
-
}
|
|
12923
|
+
if (!audio || audio.enabled === false) {
|
|
12924
|
+
return false;
|
|
12947
12925
|
}
|
|
12948
|
-
return
|
|
12926
|
+
return Array.isArray(audio.models) && audio.models.length > 0;
|
|
12949
12927
|
}
|
|
12950
|
-
|
|
12951
|
-
const
|
|
12952
|
-
|
|
12953
|
-
|
|
12954
|
-
|
|
12955
|
-
|
|
12956
|
-
|
|
12957
|
-
|
|
12958
|
-
|
|
12959
|
-
|
|
12960
|
-
|
|
12961
|
-
|
|
12962
|
-
|
|
12963
|
-
|
|
12964
|
-
body: form
|
|
12928
|
+
function hasLegacySttCredentials(cfg) {
|
|
12929
|
+
const channels = asRecord(cfg.channels);
|
|
12930
|
+
const qqbot = asRecord(channels?.qqbot);
|
|
12931
|
+
const stt = asRecord(qqbot?.stt);
|
|
12932
|
+
if (!stt) return false;
|
|
12933
|
+
return ["provider", "baseUrl", "apiKey", "model"].some(
|
|
12934
|
+
(key2) => typeof stt[key2] === "string" && stt[key2].trim().length > 0
|
|
12935
|
+
);
|
|
12936
|
+
}
|
|
12937
|
+
async function transcribeAudioViaFramework(audioPath, cfg) {
|
|
12938
|
+
const result = await (0, import_media_understanding_runtime.transcribeAudioFile)({
|
|
12939
|
+
filePath: audioPath,
|
|
12940
|
+
cfg,
|
|
12941
|
+
mime: guessMimeType(audioPath)
|
|
12965
12942
|
});
|
|
12966
|
-
if (!resp.ok) {
|
|
12967
|
-
const detail = await resp.text().catch(() => "");
|
|
12968
|
-
throw new Error(`STT failed (HTTP ${resp.status}): ${detail.slice(0, 300)}`);
|
|
12969
|
-
}
|
|
12970
|
-
const result = await resp.json();
|
|
12971
12943
|
return result.text?.trim() || null;
|
|
12972
12944
|
}
|
|
12973
12945
|
function asRecord(value) {
|
|
@@ -12976,16 +12948,6 @@ function asRecord(value) {
|
|
|
12976
12948
|
}
|
|
12977
12949
|
return void 0;
|
|
12978
12950
|
}
|
|
12979
|
-
function readString(obj, key2) {
|
|
12980
|
-
const val = obj?.[key2];
|
|
12981
|
-
if (typeof val === "string" && val.trim()) {
|
|
12982
|
-
return val.trim();
|
|
12983
|
-
}
|
|
12984
|
-
return void 0;
|
|
12985
|
-
}
|
|
12986
|
-
function sanitizeFileName2(name) {
|
|
12987
|
-
return name.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
12988
|
-
}
|
|
12989
12951
|
function guessMimeType(fileName) {
|
|
12990
12952
|
const ext = path16.extname(fileName).toLowerCase();
|
|
12991
12953
|
const mimeMap = {
|
|
@@ -13061,8 +13023,9 @@ function attachmentProcessor(opts) {
|
|
|
13061
13023
|
};
|
|
13062
13024
|
}
|
|
13063
13025
|
async function processAttachments(attachments, cfg, log5) {
|
|
13064
|
-
const sttCfg = resolveSTTConfig(cfg);
|
|
13065
13026
|
const usePlatformAsr = shouldUsePlatformAsr(cfg);
|
|
13027
|
+
const sttConfigured = isFrameworkSttConfigured(cfg);
|
|
13028
|
+
warnLegacySttCredentials(cfg, log5);
|
|
13066
13029
|
const audioPolicy = resolveAudioPolicy(cfg);
|
|
13067
13030
|
const imageUrls = [];
|
|
13068
13031
|
const otherParts = [];
|
|
@@ -13080,7 +13043,7 @@ async function processAttachments(attachments, cfg, log5) {
|
|
|
13080
13043
|
return { type: "image", localPath, url, contentType: att.content_type ?? "image/png", filename: att.filename };
|
|
13081
13044
|
}
|
|
13082
13045
|
if (isVoice) {
|
|
13083
|
-
const transcript = await processVoiceAttachment(att,
|
|
13046
|
+
const transcript = await processVoiceAttachment(att, cfg, usePlatformAsr, sttConfigured, audioPolicy, log5);
|
|
13084
13047
|
return { type: "voice", transcript };
|
|
13085
13048
|
}
|
|
13086
13049
|
if (url) {
|
|
@@ -13153,16 +13116,25 @@ function kindFromContentType(contentType) {
|
|
|
13153
13116
|
if (contentType?.startsWith("audio/")) return "audio";
|
|
13154
13117
|
return "document";
|
|
13155
13118
|
}
|
|
13156
|
-
|
|
13119
|
+
var legacySttWarned = false;
|
|
13120
|
+
function warnLegacySttCredentials(cfg, log5) {
|
|
13121
|
+
if (!legacySttWarned && hasLegacySttCredentials(cfg)) {
|
|
13122
|
+
legacySttWarned = true;
|
|
13123
|
+
log5?.info(
|
|
13124
|
+
"Voice: channels.qqbot.stt credentials (provider/baseUrl/apiKey/model) are deprecated and ignored; configure tools.media.audio.models instead \u2014 platform asr_refer_text is used when framework STT is absent"
|
|
13125
|
+
);
|
|
13126
|
+
}
|
|
13127
|
+
}
|
|
13128
|
+
async function processVoiceAttachment(att, cfg, usePlatformAsr, sttConfigured, audioPolicy, log5) {
|
|
13157
13129
|
const rawAsrText = att.asr_refer_text?.trim() || void 0;
|
|
13158
13130
|
const asrReferText = usePlatformAsr ? rawAsrText : void 0;
|
|
13159
13131
|
const remoteUrl = normalizeUrl(att.voice_wav_url) || normalizeUrl(att.url) || void 0;
|
|
13160
|
-
if (!
|
|
13132
|
+
if (!sttConfigured) {
|
|
13161
13133
|
if (!usePlatformAsr && rawAsrText) {
|
|
13162
|
-
log5?.info(`Voice: STT not configured; platform asr_refer_text discarded (asrFallback
|
|
13134
|
+
log5?.info(`Voice: framework STT not configured; platform asr_refer_text discarded (asrFallback: false)`);
|
|
13163
13135
|
}
|
|
13164
13136
|
if (asrReferText) {
|
|
13165
|
-
log5?.debug?.(`Voice: using asr_refer_text (STT not configured
|
|
13137
|
+
log5?.debug?.(`Voice: using platform asr_refer_text (framework STT not configured)`);
|
|
13166
13138
|
return { text: asrReferText, source: "asr", asrReferText, remoteUrl };
|
|
13167
13139
|
}
|
|
13168
13140
|
return {
|
|
@@ -13209,16 +13181,17 @@ async function processVoiceAttachment(att, sttCfg, usePlatformAsr, audioPolicy,
|
|
|
13209
13181
|
}
|
|
13210
13182
|
if (localPath) {
|
|
13211
13183
|
try {
|
|
13212
|
-
const transcript = await
|
|
13184
|
+
const transcript = await transcribeAudioViaFramework(localPath, cfg);
|
|
13213
13185
|
if (transcript) {
|
|
13214
|
-
log5?.debug?.(`Voice STT: ${transcript.slice(0, 80)}...`);
|
|
13186
|
+
log5?.debug?.(`Voice STT (framework): ${transcript.slice(0, 80)}...`);
|
|
13215
13187
|
return { text: transcript, source: "stt", duration, localPath, remoteUrl, asrReferText };
|
|
13216
13188
|
}
|
|
13217
13189
|
} catch (err) {
|
|
13218
|
-
log5?.error(`Voice STT failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
13190
|
+
log5?.error(`Voice STT (framework) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
13219
13191
|
}
|
|
13220
13192
|
}
|
|
13221
13193
|
if (asrReferText) {
|
|
13194
|
+
log5?.debug?.(`Voice: falling back to platform asr_refer_text after framework STT failure`);
|
|
13222
13195
|
return { text: asrReferText, source: "asr", duration, localPath, remoteUrl, asrReferText };
|
|
13223
13196
|
}
|
|
13224
13197
|
return {
|
|
@@ -13248,9 +13221,6 @@ function normalizeFormats(formats) {
|
|
|
13248
13221
|
return lower.startsWith(".") ? lower : `.${lower}`;
|
|
13249
13222
|
});
|
|
13250
13223
|
}
|
|
13251
|
-
function cfg2stt(sttCfg) {
|
|
13252
|
-
return { channels: { qqbot: { stt: sttCfg } } };
|
|
13253
|
-
}
|
|
13254
13224
|
function normalizeUrl(url) {
|
|
13255
13225
|
if (!url) return "";
|
|
13256
13226
|
return url.startsWith("//") ? `https:${url}` : url;
|
|
@@ -15891,7 +15861,7 @@ function getQQBotApprovalCapability() {
|
|
|
15891
15861
|
|
|
15892
15862
|
// src/features/proactive.ts
|
|
15893
15863
|
init_plugin_logger();
|
|
15894
|
-
var
|
|
15864
|
+
var fs18 = __toESM(require("fs"), 1);
|
|
15895
15865
|
var path20 = __toESM(require("path"), 1);
|
|
15896
15866
|
init_bot_instance();
|
|
15897
15867
|
init_config();
|
|
@@ -15902,8 +15872,8 @@ var KNOWN_USERS_FILE = path20.join(STORAGE_DIR, "known-users.json");
|
|
|
15902
15872
|
var knownUsersCache = null;
|
|
15903
15873
|
var cacheLastModified = 0;
|
|
15904
15874
|
function ensureStorageDir() {
|
|
15905
|
-
if (!
|
|
15906
|
-
|
|
15875
|
+
if (!fs18.existsSync(STORAGE_DIR)) {
|
|
15876
|
+
fs18.mkdirSync(STORAGE_DIR, { recursive: true });
|
|
15907
15877
|
}
|
|
15908
15878
|
}
|
|
15909
15879
|
function getUserKey(type, openid, accountId) {
|
|
@@ -15912,7 +15882,7 @@ function getUserKey(type, openid, accountId) {
|
|
|
15912
15882
|
function loadKnownUsers() {
|
|
15913
15883
|
if (knownUsersCache !== null) {
|
|
15914
15884
|
try {
|
|
15915
|
-
const stat =
|
|
15885
|
+
const stat = fs18.statSync(KNOWN_USERS_FILE);
|
|
15916
15886
|
if (stat.mtimeMs <= cacheLastModified) {
|
|
15917
15887
|
return knownUsersCache;
|
|
15918
15888
|
}
|
|
@@ -15922,14 +15892,14 @@ function loadKnownUsers() {
|
|
|
15922
15892
|
}
|
|
15923
15893
|
const users = /* @__PURE__ */ new Map();
|
|
15924
15894
|
try {
|
|
15925
|
-
if (
|
|
15926
|
-
const data =
|
|
15895
|
+
if (fs18.existsSync(KNOWN_USERS_FILE)) {
|
|
15896
|
+
const data = fs18.readFileSync(KNOWN_USERS_FILE, "utf-8");
|
|
15927
15897
|
const parsed = JSON.parse(data);
|
|
15928
15898
|
for (const user of parsed) {
|
|
15929
15899
|
const key2 = getUserKey(user.type, user.openid, user.accountId);
|
|
15930
15900
|
users.set(key2, user);
|
|
15931
15901
|
}
|
|
15932
|
-
cacheLastModified =
|
|
15902
|
+
cacheLastModified = fs18.statSync(KNOWN_USERS_FILE).mtimeMs;
|
|
15933
15903
|
}
|
|
15934
15904
|
} catch (err) {
|
|
15935
15905
|
log3.error(`Failed to load known users: ${err}`);
|
|
@@ -15941,7 +15911,7 @@ function saveKnownUsers(users) {
|
|
|
15941
15911
|
try {
|
|
15942
15912
|
ensureStorageDir();
|
|
15943
15913
|
const data = Array.from(users.values());
|
|
15944
|
-
|
|
15914
|
+
fs18.writeFileSync(KNOWN_USERS_FILE, JSON.stringify(data, null, 2), "utf-8");
|
|
15945
15915
|
cacheLastModified = Date.now();
|
|
15946
15916
|
knownUsersCache = users;
|
|
15947
15917
|
} catch (err) {
|
|
@@ -17478,9 +17448,33 @@ init_runtime();
|
|
|
17478
17448
|
|
|
17479
17449
|
// src/tools/platform.ts
|
|
17480
17450
|
init_config();
|
|
17481
|
-
|
|
17482
|
-
init_request_context();
|
|
17451
|
+
init_outbound_service();
|
|
17483
17452
|
init_plugin_logger();
|
|
17453
|
+
|
|
17454
|
+
// src/tools/tool-session.ts
|
|
17455
|
+
init_request_context();
|
|
17456
|
+
function resolveToolSessionRoute(delivery) {
|
|
17457
|
+
const alsTarget = getRequestTarget();
|
|
17458
|
+
if (alsTarget) {
|
|
17459
|
+
return {
|
|
17460
|
+
target: alsTarget,
|
|
17461
|
+
accountId: getRequestAccountId(),
|
|
17462
|
+
source: "request-context"
|
|
17463
|
+
};
|
|
17464
|
+
}
|
|
17465
|
+
const to = typeof delivery?.to === "string" ? delivery.to.trim() : "";
|
|
17466
|
+
if (!to) return void 0;
|
|
17467
|
+
const channel = typeof delivery?.channel === "string" ? delivery.channel.trim() : "";
|
|
17468
|
+
if (channel && channel !== "qqbot") return void 0;
|
|
17469
|
+
if (!/^qqbot:(c2c|group|channel):/i.test(to)) return void 0;
|
|
17470
|
+
return {
|
|
17471
|
+
target: to,
|
|
17472
|
+
accountId: delivery?.accountId,
|
|
17473
|
+
source: "delivery-context"
|
|
17474
|
+
};
|
|
17475
|
+
}
|
|
17476
|
+
|
|
17477
|
+
// src/tools/platform.ts
|
|
17484
17478
|
var toolLog = createPluginLogger({ prefix: "[tool:platform]" });
|
|
17485
17479
|
var PlatformApiSchema = {
|
|
17486
17480
|
type: "object",
|
|
@@ -17526,68 +17520,76 @@ function registerPlatformTool(api) {
|
|
|
17526
17520
|
const accountIds = listQQBotAccountIds(cfg);
|
|
17527
17521
|
if (accountIds.length === 0) return;
|
|
17528
17522
|
api.registerTool(
|
|
17529
|
-
{
|
|
17530
|
-
|
|
17531
|
-
|
|
17532
|
-
|
|
17533
|
-
|
|
17534
|
-
|
|
17535
|
-
|
|
17536
|
-
|
|
17537
|
-
|
|
17538
|
-
|
|
17539
|
-
|
|
17540
|
-
|
|
17541
|
-
|
|
17542
|
-
|
|
17543
|
-
|
|
17544
|
-
|
|
17545
|
-
|
|
17546
|
-
|
|
17547
|
-
|
|
17548
|
-
|
|
17549
|
-
|
|
17550
|
-
|
|
17551
|
-
|
|
17552
|
-
|
|
17553
|
-
|
|
17554
|
-
|
|
17555
|
-
|
|
17556
|
-
|
|
17557
|
-
|
|
17558
|
-
|
|
17559
|
-
|
|
17560
|
-
|
|
17561
|
-
|
|
17562
|
-
|
|
17563
|
-
|
|
17564
|
-
|
|
17565
|
-
|
|
17566
|
-
|
|
17567
|
-
|
|
17568
|
-
|
|
17523
|
+
(factoryCtx) => {
|
|
17524
|
+
const delivery = factoryCtx.deliveryContext;
|
|
17525
|
+
return {
|
|
17526
|
+
name: "qqbot_platform_api",
|
|
17527
|
+
label: "QQBot Platform API Gateway",
|
|
17528
|
+
description: "QQ \u5F00\u653E\u5E73\u53F0\u7EDF\u4E00 HTTP API \u7F51\u5173\uFF0C\u81EA\u52A8\u586B\u5145\u9274\u6743 Token\u3002\u5E38\u7528\u63A5\u53E3\u901F\u67E5\uFF1A\u3010\u9891\u9053\u3011GET /users/@me/guilds | /guilds/{guild_id}/channels | /channels/{channel_id} | \u3010\u7FA4\u3011GET /v2/groups/{group_id}/bot_state | /v2/groups/{group_id}/members/{member_id} | /v2/groups/{group_id}/info\u3002\u66F4\u591A\u63A5\u53E3\u548C\u53C2\u6570\u8BE6\u60C5\u8BF7\u9605\u8BFB qqbot-channel \u548C qqbot-group skill\u3002",
|
|
17529
|
+
parameters: PlatformApiSchema,
|
|
17530
|
+
async execute(_toolCallId, params) {
|
|
17531
|
+
const p2 = params;
|
|
17532
|
+
if (!p2.method) return json({ error: "method \u4E3A\u5FC5\u586B\u53C2\u6570" });
|
|
17533
|
+
if (!p2.path) return json({ error: "path \u4E3A\u5FC5\u586B\u53C2\u6570" });
|
|
17534
|
+
const method = p2.method.toUpperCase();
|
|
17535
|
+
if (!["GET", "POST", "PUT", "PATCH", "DELETE"].includes(method)) {
|
|
17536
|
+
return json({ error: `\u4E0D\u652F\u6301\u7684 HTTP \u65B9\u6CD5: ${method}` });
|
|
17537
|
+
}
|
|
17538
|
+
const pathError = validatePath(p2.path);
|
|
17539
|
+
if (pathError) return json({ error: pathError });
|
|
17540
|
+
const route = resolveToolSessionRoute(delivery);
|
|
17541
|
+
if (!route) {
|
|
17542
|
+
return json({
|
|
17543
|
+
error: "\u5F53\u524D\u8FD0\u884C\u6CA1\u6709 QQ \u4F1A\u8BDD\u6765\u6E90\uFF08\u53EF\u80FD\u7531\u5B9A\u65F6\u4EFB\u52A1\u6216\u6846\u67B6\u5185\u90E8\u89E6\u53D1\u7684 run\uFF09\uFF0C\u65E0\u6CD5\u786E\u5B9A\u8C03\u7528\u54EA\u4E2A QQ Bot \u8D26\u6237\u3002\u8BF7\u5728 QQ \u6D88\u606F\u4F1A\u8BDD\u4E2D\u4F7F\u7528\u672C\u5DE5\u5177\u3002"
|
|
17544
|
+
});
|
|
17545
|
+
}
|
|
17546
|
+
try {
|
|
17547
|
+
const resolvedGateway = resolveGatewayForSend(route.accountId ?? "default");
|
|
17548
|
+
if (!resolvedGateway) {
|
|
17549
|
+
return json({ error: `\u8D26\u6237 ${route.accountId ?? "default"} \u7684 gateway \u5C1A\u672A\u542F\u52A8` });
|
|
17550
|
+
}
|
|
17551
|
+
const bot = resolvedGateway.gw.bot;
|
|
17552
|
+
const apiGateway = bot.api;
|
|
17553
|
+
const startedAt = Date.now();
|
|
17554
|
+
let data;
|
|
17555
|
+
switch (method) {
|
|
17556
|
+
case "GET":
|
|
17557
|
+
data = await apiGateway.get(p2.path, p2.query);
|
|
17558
|
+
break;
|
|
17559
|
+
case "POST":
|
|
17560
|
+
data = await apiGateway.post(p2.path, p2.body);
|
|
17561
|
+
break;
|
|
17562
|
+
case "PUT":
|
|
17563
|
+
data = await apiGateway.put(p2.path, p2.body);
|
|
17564
|
+
break;
|
|
17565
|
+
case "PATCH":
|
|
17566
|
+
data = await apiGateway.patch(p2.path, p2.body);
|
|
17567
|
+
break;
|
|
17568
|
+
case "DELETE":
|
|
17569
|
+
data = await apiGateway.delete(p2.path);
|
|
17570
|
+
break;
|
|
17571
|
+
}
|
|
17572
|
+
toolLog.info(`${method} ${p2.path} ok (${Date.now() - startedAt}ms)`, { accountId: resolvedGateway.accountId });
|
|
17573
|
+
return json(data);
|
|
17574
|
+
} catch (err) {
|
|
17575
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
17576
|
+
const apiErr = err;
|
|
17577
|
+
toolLog.warn(`${method} ${p2.path} failed status=${apiErr.httpStatus ?? "?"} code=${apiErr.bizCode ?? "?"}: ${errMsg}`, { accountId: route.accountId ?? "default" });
|
|
17578
|
+
return json({
|
|
17579
|
+
error: errMsg,
|
|
17580
|
+
status: apiErr.httpStatus,
|
|
17581
|
+
code: apiErr.bizCode,
|
|
17582
|
+
path: p2.path
|
|
17583
|
+
});
|
|
17569
17584
|
}
|
|
17570
|
-
toolLog.info(`${method} ${p2.path} ok (${Date.now() - startedAt}ms)`, { accountId });
|
|
17571
|
-
return json(data);
|
|
17572
|
-
} catch (err) {
|
|
17573
|
-
const errMsg = err instanceof Error ? err.message : String(err);
|
|
17574
|
-
const apiErr = err;
|
|
17575
|
-
toolLog.warn(`${method} ${p2.path} failed status=${apiErr.httpStatus ?? "?"} code=${apiErr.bizCode ?? "?"}: ${errMsg}`, { accountId });
|
|
17576
|
-
return json({
|
|
17577
|
-
error: errMsg,
|
|
17578
|
-
status: apiErr.httpStatus,
|
|
17579
|
-
code: apiErr.bizCode,
|
|
17580
|
-
path: p2.path
|
|
17581
|
-
});
|
|
17582
17585
|
}
|
|
17583
|
-
}
|
|
17586
|
+
};
|
|
17584
17587
|
},
|
|
17585
17588
|
{ name: "qqbot_platform_api" }
|
|
17586
17589
|
);
|
|
17587
17590
|
}
|
|
17588
17591
|
|
|
17589
17592
|
// src/tools/remind.ts
|
|
17590
|
-
init_request_context();
|
|
17591
17593
|
var RemindSchema = {
|
|
17592
17594
|
type: "object",
|
|
17593
17595
|
properties: {
|
|
@@ -17732,71 +17734,76 @@ function formatDelay(ms) {
|
|
|
17732
17734
|
}
|
|
17733
17735
|
function registerRemindTool(api) {
|
|
17734
17736
|
api.registerTool(
|
|
17735
|
-
{
|
|
17736
|
-
|
|
17737
|
-
|
|
17738
|
-
|
|
17739
|
-
|
|
17740
|
-
|
|
17741
|
-
|
|
17742
|
-
|
|
17743
|
-
|
|
17744
|
-
|
|
17745
|
-
|
|
17746
|
-
|
|
17747
|
-
|
|
17748
|
-
|
|
17749
|
-
if (!p2.jobId) {
|
|
17750
|
-
return json2({ error: "action=remove \u65F6 jobId \u4E3A\u5FC5\u586B\u53C2\u6570\u3002\u8BF7\u5148\u7528 action=list \u83B7\u53D6 jobId\u3002" });
|
|
17737
|
+
(factoryCtx) => {
|
|
17738
|
+
const delivery = factoryCtx.deliveryContext;
|
|
17739
|
+
return {
|
|
17740
|
+
name: "qqbot_remind",
|
|
17741
|
+
label: "QQBot \u5B9A\u65F6\u63D0\u9192",
|
|
17742
|
+
description: '\u521B\u5EFA\u3001\u67E5\u8BE2\u3001\u5220\u9664 QQ \u5B9A\u65F6\u63D0\u9192\u3002\u4F7F\u7528\u7B80\u5355\u53C2\u6570\u5373\u53EF\uFF0C\u65E0\u9700\u624B\u52A8\u6784\u9020 cron JSON\u3002\n\u521B\u5EFA\u63D0\u9192\uFF1Aaction=add, content=\u63D0\u9192\u5185\u5BB9, to=\u76EE\u6807\u5730\u5740, time=\u65F6\u95F4\n\u67E5\u770B\u63D0\u9192\uFF1Aaction=list\n\u5220\u9664\u63D0\u9192\uFF1Aaction=remove, jobId=\u4EFB\u52A1ID\uFF08\u5148 list \u83B7\u53D6\uFF09\n\u65F6\u95F4\u683C\u5F0F\u793A\u4F8B\uFF1A"5m"(5\u5206\u949F\u540E) "1h"(1\u5C0F\u65F6\u540E) "0 8 * * *"(\u6BCF\u59298\u70B9)',
|
|
17743
|
+
parameters: RemindSchema,
|
|
17744
|
+
async execute(_toolCallId, params) {
|
|
17745
|
+
const p2 = params;
|
|
17746
|
+
if (p2.action === "list") {
|
|
17747
|
+
return json2({
|
|
17748
|
+
_instruction: "\u8BF7\u7ACB\u5373\u4F7F\u7528 cron \u5DE5\u5177\u6267\u884C\u4EE5\u4E0B\u53C2\u6570",
|
|
17749
|
+
cronParams: { action: "list" }
|
|
17750
|
+
});
|
|
17751
17751
|
}
|
|
17752
|
-
|
|
17753
|
-
|
|
17754
|
-
|
|
17755
|
-
|
|
17756
|
-
|
|
17757
|
-
|
|
17758
|
-
|
|
17759
|
-
|
|
17760
|
-
|
|
17761
|
-
|
|
17762
|
-
|
|
17763
|
-
|
|
17764
|
-
|
|
17765
|
-
|
|
17766
|
-
|
|
17767
|
-
|
|
17768
|
-
|
|
17769
|
-
|
|
17752
|
+
if (p2.action === "remove") {
|
|
17753
|
+
if (!p2.jobId) {
|
|
17754
|
+
return json2({ error: "action=remove \u65F6 jobId \u4E3A\u5FC5\u586B\u53C2\u6570\u3002\u8BF7\u5148\u7528 action=list \u83B7\u53D6 jobId\u3002" });
|
|
17755
|
+
}
|
|
17756
|
+
return json2({
|
|
17757
|
+
_instruction: "\u8BF7\u7ACB\u5373\u4F7F\u7528 cron \u5DE5\u5177\u6267\u884C\u4EE5\u4E0B\u53C2\u6570",
|
|
17758
|
+
cronParams: { action: "remove", jobId: p2.jobId }
|
|
17759
|
+
});
|
|
17760
|
+
}
|
|
17761
|
+
if (!p2.content) {
|
|
17762
|
+
return json2({ error: "action=add \u65F6 content\uFF08\u63D0\u9192\u5185\u5BB9\uFF09\u4E3A\u5FC5\u586B\u53C2\u6570" });
|
|
17763
|
+
}
|
|
17764
|
+
const route = resolveToolSessionRoute(delivery);
|
|
17765
|
+
const resolvedTo = p2.to || route?.target;
|
|
17766
|
+
if (!resolvedTo) {
|
|
17767
|
+
return json2({
|
|
17768
|
+
error: "action=add \u65F6\u65E0\u6CD5\u786E\u5B9A\u6295\u9012\u76EE\u6807\u5730\u5740\uFF08\u5F53\u524D run \u65E0 QQ \u4F1A\u8BDD\u6765\u6E90\uFF09\u3002\u8BF7\u663E\u5F0F\u4F20\u5165 to\uFF08\u683C\u5F0F\uFF1Aqqbot:c2c:user_openid \u6216 qqbot:group:group_openid\uFF09\u540E\u91CD\u8BD5\u3002"
|
|
17769
|
+
});
|
|
17770
|
+
}
|
|
17771
|
+
const resolvedAccountId = route?.accountId || "default";
|
|
17772
|
+
if (!p2.time) {
|
|
17773
|
+
return json2({ error: 'action=add \u65F6 time\uFF08\u65F6\u95F4\uFF09\u4E3A\u5FC5\u586B\u53C2\u6570\u3002\u793A\u4F8B\uFF1A"5m"\u3001"1h30m"\u3001"0 8 * * *"' });
|
|
17774
|
+
}
|
|
17775
|
+
if (isCronExpression(p2.time)) {
|
|
17776
|
+
const cronJob = buildCronJob(p2, resolvedTo, resolvedAccountId);
|
|
17777
|
+
return json2({
|
|
17778
|
+
_instruction: "\u8BF7\u7ACB\u5373\u4F7F\u7528 cron \u5DE5\u5177\uFF0C\u5C06 cronParams \u7684\u503C\u539F\u6837\u4F5C\u4E3A\u53C2\u6570\u4F20\u5165\uFF08\u4E0D\u8981\u4FEE\u6539\u6216\u7701\u7565\u4EFB\u4F55\u5B57\u6BB5\uFF0C\u7279\u522B\u662F delivery.accountId\uFF09\uFF0C\u7136\u540E\u56DE\u590D\u7528\u6237\u63D0\u9192\u5DF2\u8BBE\u7F6E",
|
|
17779
|
+
cronParams: cronJob,
|
|
17780
|
+
summary: `\u23F0 \u5468\u671F\u63D0\u9192: "${p2.content}" (${p2.time}, tz=${p2.timezone || "Asia/Shanghai"})`
|
|
17781
|
+
});
|
|
17782
|
+
}
|
|
17783
|
+
const delayMs = parseRelativeTime(p2.time);
|
|
17784
|
+
if (!delayMs || delayMs <= 0) {
|
|
17785
|
+
return json2({
|
|
17786
|
+
error: `\u65E0\u6CD5\u89E3\u6790\u65F6\u95F4 "${p2.time}"\u3002\u652F\u6301\u683C\u5F0F\uFF1A\u76F8\u5BF9\u65F6\u95F4\u5982 "5m"\u3001"1h"\u3001"1h30m"\u3001"2d"\uFF1Bcron \u8868\u8FBE\u5F0F\u5982 "0 8 * * *"\uFF08\u6BCF\u59298\u70B9\uFF09`
|
|
17787
|
+
});
|
|
17788
|
+
}
|
|
17789
|
+
if (delayMs < 3e4) {
|
|
17790
|
+
return json2({ error: "\u63D0\u9192\u65F6\u95F4\u4E0D\u80FD\u5C11\u4E8E 30 \u79D2" });
|
|
17791
|
+
}
|
|
17792
|
+
const onceJob = buildOnceJob(p2, delayMs, resolvedTo, resolvedAccountId);
|
|
17770
17793
|
return json2({
|
|
17771
17794
|
_instruction: "\u8BF7\u7ACB\u5373\u4F7F\u7528 cron \u5DE5\u5177\uFF0C\u5C06 cronParams \u7684\u503C\u539F\u6837\u4F5C\u4E3A\u53C2\u6570\u4F20\u5165\uFF08\u4E0D\u8981\u4FEE\u6539\u6216\u7701\u7565\u4EFB\u4F55\u5B57\u6BB5\uFF0C\u7279\u522B\u662F delivery.accountId\uFF09\uFF0C\u7136\u540E\u56DE\u590D\u7528\u6237\u63D0\u9192\u5DF2\u8BBE\u7F6E",
|
|
17772
|
-
cronParams:
|
|
17773
|
-
summary: `\u23F0 \
|
|
17774
|
-
});
|
|
17775
|
-
}
|
|
17776
|
-
const delayMs = parseRelativeTime(p2.time);
|
|
17777
|
-
if (!delayMs || delayMs <= 0) {
|
|
17778
|
-
return json2({
|
|
17779
|
-
error: `\u65E0\u6CD5\u89E3\u6790\u65F6\u95F4 "${p2.time}"\u3002\u652F\u6301\u683C\u5F0F\uFF1A\u76F8\u5BF9\u65F6\u95F4\u5982 "5m"\u3001"1h"\u3001"1h30m"\u3001"2d"\uFF1Bcron \u8868\u8FBE\u5F0F\u5982 "0 8 * * *"\uFF08\u6BCF\u59298\u70B9\uFF09`
|
|
17795
|
+
cronParams: onceJob,
|
|
17796
|
+
summary: `\u23F0 ${formatDelay(delayMs)}\u540E\u63D0\u9192: "${p2.content}"`
|
|
17780
17797
|
});
|
|
17781
17798
|
}
|
|
17782
|
-
|
|
17783
|
-
return json2({ error: "\u63D0\u9192\u65F6\u95F4\u4E0D\u80FD\u5C11\u4E8E 30 \u79D2" });
|
|
17784
|
-
}
|
|
17785
|
-
const onceJob = buildOnceJob(p2, delayMs, resolvedTo, resolvedAccountId);
|
|
17786
|
-
return json2({
|
|
17787
|
-
_instruction: "\u8BF7\u7ACB\u5373\u4F7F\u7528 cron \u5DE5\u5177\uFF0C\u5C06 cronParams \u7684\u503C\u539F\u6837\u4F5C\u4E3A\u53C2\u6570\u4F20\u5165\uFF08\u4E0D\u8981\u4FEE\u6539\u6216\u7701\u7565\u4EFB\u4F55\u5B57\u6BB5\uFF0C\u7279\u522B\u662F delivery.accountId\uFF09\uFF0C\u7136\u540E\u56DE\u590D\u7528\u6237\u63D0\u9192\u5DF2\u8BBE\u7F6E",
|
|
17788
|
-
cronParams: onceJob,
|
|
17789
|
-
summary: `\u23F0 ${formatDelay(delayMs)}\u540E\u63D0\u9192: "${p2.content}"`
|
|
17790
|
-
});
|
|
17791
|
-
}
|
|
17799
|
+
};
|
|
17792
17800
|
},
|
|
17793
17801
|
{ name: "qqbot_remind" }
|
|
17794
17802
|
);
|
|
17795
17803
|
}
|
|
17796
17804
|
|
|
17797
17805
|
// src/tools/secret-input.ts
|
|
17798
|
-
|
|
17799
|
-
init_request_context();
|
|
17806
|
+
init_outbound_service();
|
|
17800
17807
|
init_target();
|
|
17801
17808
|
init_plugin_logger();
|
|
17802
17809
|
var toolLog2 = createPluginLogger({ prefix: "[tool:secret-input]" });
|
|
@@ -17856,67 +17863,77 @@ function json3(data) {
|
|
|
17856
17863
|
}
|
|
17857
17864
|
function registerSecretInputTool(api) {
|
|
17858
17865
|
api.registerTool(
|
|
17859
|
-
{
|
|
17860
|
-
|
|
17861
|
-
|
|
17862
|
-
|
|
17863
|
-
|
|
17864
|
-
|
|
17865
|
-
|
|
17866
|
-
|
|
17867
|
-
|
|
17868
|
-
|
|
17869
|
-
return json3({
|
|
17870
|
-
|
|
17871
|
-
|
|
17872
|
-
|
|
17873
|
-
|
|
17874
|
-
|
|
17875
|
-
|
|
17876
|
-
|
|
17877
|
-
|
|
17878
|
-
|
|
17879
|
-
|
|
17880
|
-
|
|
17881
|
-
|
|
17882
|
-
|
|
17866
|
+
(factoryCtx) => {
|
|
17867
|
+
const delivery = factoryCtx.deliveryContext;
|
|
17868
|
+
return {
|
|
17869
|
+
name: "qqbot_secret_input",
|
|
17870
|
+
label: "QQBot Secret Input Card",
|
|
17871
|
+
description: "\u5F53\u7528\u6237\u8981\u4EA4\u4ED8\u4E00\u4E2A\u65B0\u5BC6\u94A5/\u51ED\u636E\uFF08API Key\u3001Token \u7B49\uFF09\u7ED9\u7CFB\u7EDF\u4FDD\u5B58\u65F6\u8C03\u7528\uFF1A\u5411\u7528\u6237\u79C1\u804A\u53D1\u9001\u4E00\u5F20\u5BC6\u94A5\u8F93\u5165\u5361\u7247\uFF0C\u7528\u6237\u628A\u5BC6\u94A5\u7C98\u8D34\u5728\u8F93\u5165\u6846\u53D1\u9001\u540E\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u62E6\u622A\u8BE5\u6D88\u606F\u5E76\u6267\u884C openclaw secrets store set \u5B8C\u6210\u4FDD\u5B58\uFF0C\u7ED3\u679C\u7531\u63D2\u4EF6\u76F4\u63A5\u56DE\u590D\u7528\u6237\u3002\u5BC6\u94A5\u5185\u5BB9\u4E0D\u4F1A\u8FDB\u5165\u5BF9\u8BDD\u3002\u5FC5\u987B\u7531\u7528\u6237\u63D0\u4F9B name \u53C2\u6570\uFF08\u73AF\u5883\u53D8\u91CF\u540D\uFF09\u3002",
|
|
17872
|
+
parameters: SecretInputSchema,
|
|
17873
|
+
async execute(_toolCallId, params) {
|
|
17874
|
+
const p2 = params;
|
|
17875
|
+
const name = (p2.name ?? "").trim();
|
|
17876
|
+
if (!name) return json3({ error: "name \u4E3A\u5FC5\u586B\u53C2\u6570\uFF08\u73AF\u5883\u53D8\u91CF\u540D\uFF09" });
|
|
17877
|
+
if (!isValidSecretName(name)) {
|
|
17878
|
+
return json3({
|
|
17879
|
+
error: `\u73AF\u5883\u53D8\u91CF\u540D\u4E0D\u5408\u6CD5\uFF1A\u5FC5\u987B\u4EE5\u5927\u5199\u5B57\u6BCD\u5F00\u5934\uFF0C\u4EC5\u542B\u5927\u5199\u5B57\u6BCD/\u6570\u5B57/\u4E0B\u5212\u7EBF\uFF0C\u6700\u957F 128 \u5B57\u7B26\uFF08\u6536\u5230 "${name}"\uFF09\u3002\u793A\u4F8B\uFF1AOPENWEATHER_API_KEY\u3002\u8BF7\u4FEE\u6B63\u540E\u91CD\u8BD5\u3002`
|
|
17880
|
+
});
|
|
17881
|
+
}
|
|
17882
|
+
const kind = "env";
|
|
17883
|
+
const route = resolveToolSessionRoute(delivery);
|
|
17884
|
+
if (!route) {
|
|
17885
|
+
return json3({
|
|
17886
|
+
error: "\u5F53\u524D\u8FD0\u884C\u6CA1\u6709 QQ \u4F1A\u8BDD\u6765\u6E90\uFF08\u53EF\u80FD\u7531\u5B9A\u65F6\u4EFB\u52A1\u6216\u6846\u67B6\u5185\u90E8\u89E6\u53D1\u7684 run\uFF09\uFF0C\u65E0\u6CD5\u5B9A\u4F4D\u8981\u53D1\u5361\u7684\u7528\u6237\u3002\u8BF7\u5F15\u5BFC\u7528\u6237\u5728 QQ \u79C1\u804A\u4E2D\u76F4\u63A5\u53D1\u8D77\u5BC6\u94A5\u8F93\u5165\uFF0C\u4E0D\u8981\u5728\u65E0\u4F1A\u8BDD\u4E0A\u4E0B\u6587\u7684\u4EFB\u52A1\u91CC\u8C03\u7528\u672C\u5DE5\u5177\u3002"
|
|
17887
|
+
});
|
|
17888
|
+
}
|
|
17889
|
+
const scope = QQBOT_PREFIX_RE.exec(route.target)?.[1]?.toLowerCase();
|
|
17890
|
+
const parsed = parseTarget(route.target);
|
|
17891
|
+
if (scope !== "c2c" || !parsed.targetId) {
|
|
17892
|
+
return json3({
|
|
17893
|
+
error: `\u5BC6\u94A5\u8F93\u5165\u5361\u7247\u4EC5\u652F\u6301\u79C1\u804A\uFF08c2c\uFF09\u4F1A\u8BDD\uFF0C\u5F53\u524D\u76EE\u6807 ${route.target} \u4E0D\u9002\u7528\u2014\u2014\u5BC6\u94A5\u4E0D\u5E94\u51FA\u73B0\u5728\u7FA4\u804A\u6216\u9891\u9053\u4E2D\u3002\u8BF7\u5F15\u5BFC\u7528\u6237\u5728\u79C1\u804A\u4E2D\u53D1\u8D77\u3002`
|
|
17894
|
+
});
|
|
17895
|
+
}
|
|
17896
|
+
const requestedAccountId = route.accountId ?? "default";
|
|
17897
|
+
const resolvedGateway = resolveGatewayForSend(requestedAccountId);
|
|
17898
|
+
if (!resolvedGateway) {
|
|
17899
|
+
return json3({ error: `\u8D26\u6237 ${requestedAccountId} \u7684 gateway \u5C1A\u672A\u542F\u52A8\uFF0C\u65E0\u6CD5\u53D1\u9001\u5BC6\u94A5\u8F93\u5165\u5361\u7247` });
|
|
17900
|
+
}
|
|
17901
|
+
const accountId = resolvedGateway.accountId;
|
|
17902
|
+
const bot = resolvedGateway.gw.bot;
|
|
17903
|
+
const description = p2.description?.trim() || void 0;
|
|
17904
|
+
registerPendingSecretInput({
|
|
17905
|
+
accountId,
|
|
17906
|
+
senderOpenid: parsed.targetId,
|
|
17907
|
+
name,
|
|
17908
|
+
kind,
|
|
17909
|
+
description,
|
|
17910
|
+
createdAt: Date.now()
|
|
17883
17911
|
});
|
|
17884
|
-
|
|
17885
|
-
|
|
17886
|
-
|
|
17887
|
-
|
|
17888
|
-
|
|
17889
|
-
|
|
17890
|
-
|
|
17891
|
-
|
|
17892
|
-
|
|
17893
|
-
|
|
17894
|
-
|
|
17895
|
-
|
|
17896
|
-
|
|
17897
|
-
|
|
17898
|
-
|
|
17899
|
-
await bot.sendTextWithKeyboard(
|
|
17900
|
-
{ scope: "c2c", targetId: parsed.targetId },
|
|
17901
|
-
buildSecretInputCard(name, description, DEFAULT_SECRET_INPUT_TTL_MS / 6e4),
|
|
17902
|
-
buildSecretInputKeyboard()
|
|
17912
|
+
try {
|
|
17913
|
+
await bot.sendTextWithKeyboard(
|
|
17914
|
+
{ scope: "c2c", targetId: parsed.targetId },
|
|
17915
|
+
buildSecretInputCard(name, description, DEFAULT_SECRET_INPUT_TTL_MS / 6e4),
|
|
17916
|
+
buildSecretInputKeyboard()
|
|
17917
|
+
);
|
|
17918
|
+
} catch (err) {
|
|
17919
|
+
cancelPendingSecretInput(accountId, parsed.targetId);
|
|
17920
|
+
toolLog2.error(`card send failed: ${err instanceof Error ? err.message : String(err)}`, { name, accountId });
|
|
17921
|
+
return json3({
|
|
17922
|
+
error: `\u5BC6\u94A5\u8F93\u5165\u5361\u7247\u53D1\u9001\u5931\u8D25\uFF1A${err instanceof Error ? err.message : String(err)}`
|
|
17923
|
+
});
|
|
17924
|
+
}
|
|
17925
|
+
toolLog2.info(
|
|
17926
|
+
`card sent, pending registered name=${name} accountId=${accountId} route=${route.source} ttlMinutes=${DEFAULT_SECRET_INPUT_TTL_MS / 6e4}`
|
|
17903
17927
|
);
|
|
17904
|
-
} catch (err) {
|
|
17905
|
-
cancelPendingSecretInput(accountId, parsed.targetId);
|
|
17906
|
-
toolLog2.error(`card send failed: ${err instanceof Error ? err.message : String(err)}`, { name, accountId });
|
|
17907
17928
|
return json3({
|
|
17908
|
-
|
|
17929
|
+
ok: true,
|
|
17930
|
+
name,
|
|
17931
|
+
kind,
|
|
17932
|
+
command: `openclaw secrets store set ${name} --kind env --value <\u7528\u6237\u8F93\u5165>`,
|
|
17933
|
+
instruction: `\u5361\u7247\u5DF2\u53D1\u9001\u7ED9\u7528\u6237\u3002\u7528\u6237\u4E0B\u4E00\u6761\u79C1\u804A\u6D88\u606F\u5C06\u88AB\u63D2\u4EF6\u81EA\u52A8\u62E6\u622A\uFF08\u4E0D\u4F1A\u8FDB\u5165\u5BF9\u8BDD\uFF09\uFF0C\u6267\u884C\u4E0A\u8FF0\u547D\u4EE4\u4FDD\u5B58\u5BC6\u94A5\uFF0C\u6210\u529F/\u5931\u8D25\u7531\u63D2\u4EF6\u76F4\u63A5\u56DE\u590D\u7528\u6237\u3002\u8BF7\u76F4\u63A5\u7ED3\u675F\u672C\u8F6E\uFF08\u53EF\u544A\u77E5\u7528\u6237\u6309\u5361\u7247\u63D0\u793A\u53D1\u9001\u5BC6\u94A5\uFF09\uFF0C\u4E0D\u8981\u7B49\u5F85\u7528\u6237\u8F93\u5165\uFF0C\u4E5F\u4E0D\u8981\u8BA9\u7528\u6237\u628A\u5BC6\u94A5\u5185\u5BB9\u53D1\u5230\u5BF9\u8BDD\u91CC\u3002`
|
|
17909
17934
|
});
|
|
17910
17935
|
}
|
|
17911
|
-
|
|
17912
|
-
return json3({
|
|
17913
|
-
ok: true,
|
|
17914
|
-
name,
|
|
17915
|
-
kind,
|
|
17916
|
-
command: `openclaw secrets store set ${name} --kind env --value <\u7528\u6237\u8F93\u5165>`,
|
|
17917
|
-
instruction: `\u5361\u7247\u5DF2\u53D1\u9001\u7ED9\u7528\u6237\u3002\u7528\u6237\u4E0B\u4E00\u6761\u79C1\u804A\u6D88\u606F\u5C06\u88AB\u63D2\u4EF6\u81EA\u52A8\u62E6\u622A\uFF08\u4E0D\u4F1A\u8FDB\u5165\u5BF9\u8BDD\uFF09\uFF0C\u6267\u884C\u4E0A\u8FF0\u547D\u4EE4\u4FDD\u5B58\u5BC6\u94A5\uFF0C\u6210\u529F/\u5931\u8D25\u7531\u63D2\u4EF6\u76F4\u63A5\u56DE\u590D\u7528\u6237\u3002\u8BF7\u76F4\u63A5\u7ED3\u675F\u672C\u8F6E\uFF08\u53EF\u544A\u77E5\u7528\u6237\u6309\u5361\u7247\u63D0\u793A\u53D1\u9001\u5BC6\u94A5\uFF09\uFF0C\u4E0D\u8981\u7B49\u5F85\u7528\u6237\u8F93\u5165\uFF0C\u4E5F\u4E0D\u8981\u8BA9\u7528\u6237\u628A\u5BC6\u94A5\u5185\u5BB9\u53D1\u5230\u5BF9\u8BDD\u91CC\u3002`
|
|
17918
|
-
});
|
|
17919
|
-
}
|
|
17936
|
+
};
|
|
17920
17937
|
},
|
|
17921
17938
|
{ name: "qqbot_secret_input" }
|
|
17922
17939
|
);
|