leadsradar-agent 1.0.0 → 1.0.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 +1 -1
- package/leadsradar-agent.mjs +172 -16
- package/package.json +1 -1
- package/skills/leadsradar-research/SKILL.md +1 -1
package/README.md
CHANGED
package/leadsradar-agent.mjs
CHANGED
|
@@ -3733,7 +3733,7 @@ import {
|
|
|
3733
3733
|
createHash,
|
|
3734
3734
|
createPrivateKey
|
|
3735
3735
|
} from "node:crypto";
|
|
3736
|
-
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
3736
|
+
import { readFileSync, writeFileSync, existsSync, readdirSync, copyFileSync, unlinkSync } from "node:fs";
|
|
3737
3737
|
import { homedir } from "node:os";
|
|
3738
3738
|
import { fileURLToPath } from "node:url";
|
|
3739
3739
|
import { dirname, join } from "node:path";
|
|
@@ -3742,7 +3742,7 @@ import { createServer as createHttpServer } from "node:http";
|
|
|
3742
3742
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
3743
3743
|
var PORT = Number(process.env.LEADSRADAR_AGENT_PORT) || 17373;
|
|
3744
3744
|
var PROTOCOL_VERSION = "3";
|
|
3745
|
-
var ADAPTER_VERSION = "1.2.
|
|
3745
|
+
var ADAPTER_VERSION = "1.2.18";
|
|
3746
3746
|
var HOST_LABELS = {
|
|
3747
3747
|
"doubao-work": "\u8C46\u5305\u5DE5\u4F5C",
|
|
3748
3748
|
// ⭐r85 字节系多客户端实测(用户已验证豆包客户端支持 stdio 连接器,与豆包工作同源):
|
|
@@ -3767,7 +3767,7 @@ var HOST_LABELS = {
|
|
|
3767
3767
|
};
|
|
3768
3768
|
var HOST = (process.env.LEADSRADAR_AGENT_HOST || "doubao-work").toLowerCase();
|
|
3769
3769
|
var HTTP_MODE = process.argv.includes("--http") || process.env.LEADSRADAR_AGENT_HTTP === "1";
|
|
3770
|
-
var HTTP_PORT = Number(process.env.LEADSRADAR_AGENT_HTTP_PORT) ||
|
|
3770
|
+
var HTTP_PORT = Number(process.env.LEADSRADAR_AGENT_HTTP_PORT) || 17375;
|
|
3771
3771
|
var DEVICE_NAME = process.env.LEADSRADAR_AGENT_DEVICE_NAME || `\u63A2\u6817 Agent (${HOST_LABELS[HOST] || "\u672C\u673A"})`;
|
|
3772
3772
|
var DEVICE_ID = `leadsradar-agent-${HOST.replace(/[^a-z0-9-]/g, "") || "local"}`;
|
|
3773
3773
|
var KEY_FILE = join(homedir(), `.leadsradar-agent-key-${HOST}.json`);
|
|
@@ -3775,6 +3775,58 @@ var LEGACY_KEY_FILE = join(__dirname, ".agent-key.json");
|
|
|
3775
3775
|
function log(...args) {
|
|
3776
3776
|
process.stderr.write(args.join(" ") + "\n");
|
|
3777
3777
|
}
|
|
3778
|
+
var __extProfileCache = { at: 0, result: null };
|
|
3779
|
+
function detectExtensionProfiles() {
|
|
3780
|
+
if (Date.now() - __extProfileCache.at < 1e4) return __extProfileCache.result;
|
|
3781
|
+
const found = [];
|
|
3782
|
+
const roots = [
|
|
3783
|
+
{ browser: "chrome", dir: join(homedir(), "AppData/Local/Google/Chrome/User Data") },
|
|
3784
|
+
{ browser: "msedge", dir: join(homedir(), "AppData/Local/Microsoft/Edge/User Data") }
|
|
3785
|
+
];
|
|
3786
|
+
for (const { browser, dir } of roots) {
|
|
3787
|
+
let profiles = [];
|
|
3788
|
+
try {
|
|
3789
|
+
profiles = readdirSync(dir).filter((n) => n === "Default" || /^Profile /.test(n));
|
|
3790
|
+
} catch {
|
|
3791
|
+
continue;
|
|
3792
|
+
}
|
|
3793
|
+
for (const prof of profiles) {
|
|
3794
|
+
if (found.some((f) => f.browser === browser && f.profile === prof)) continue;
|
|
3795
|
+
for (const file of ["Secure Preferences", "Preferences"]) {
|
|
3796
|
+
const p = join(dir, prof, file);
|
|
3797
|
+
let text = null;
|
|
3798
|
+
try {
|
|
3799
|
+
const tmp = `${p}.lf-probe.tmp`;
|
|
3800
|
+
copyFileSync(p, tmp);
|
|
3801
|
+
text = readFileSync(tmp, "utf8");
|
|
3802
|
+
unlinkSync(tmp);
|
|
3803
|
+
} catch {
|
|
3804
|
+
continue;
|
|
3805
|
+
}
|
|
3806
|
+
try {
|
|
3807
|
+
const settings = JSON.parse(text)?.extensions?.settings || {};
|
|
3808
|
+
for (const v of Object.values(settings)) {
|
|
3809
|
+
const extPath = String(v?.path || "");
|
|
3810
|
+
if (extPath && /leads?find|leads?radar/i.test(extPath)) {
|
|
3811
|
+
found.push({ browser, profile: prof });
|
|
3812
|
+
break;
|
|
3813
|
+
}
|
|
3814
|
+
}
|
|
3815
|
+
} catch {
|
|
3816
|
+
}
|
|
3817
|
+
if (found.some((f) => f.browser === browser && f.profile === prof)) break;
|
|
3818
|
+
}
|
|
3819
|
+
}
|
|
3820
|
+
}
|
|
3821
|
+
__extProfileCache = { at: Date.now(), result: found };
|
|
3822
|
+
return found;
|
|
3823
|
+
}
|
|
3824
|
+
function extensionLaunchHint() {
|
|
3825
|
+
const found = detectExtensionProfiles();
|
|
3826
|
+
if (!found.length) return null;
|
|
3827
|
+
const cmd = found.map((f) => `start ${f.browser} '-profile-directory="${f.profile}"'`).join(" \u6216 ");
|
|
3828
|
+
return `\u5DF2\u63A2\u6D4B\u5230\u63D2\u4EF6\u88C5\u5728 ${found.map((f) => `${f.browser === "msedge" ? "Edge" : "Chrome"} \u7684 ${f.profile}`).join(" \u548C ")}\u2014\u2014\u82E5\u4F60\u6709\u7EC8\u7AEF\u6743\u9650\uFF0C\u8FD0\u884C ${cmd} \u6253\u5F00\u5BF9\u5E94\u7A97\u53E3\uFF0C\u63D2\u4EF6\u7EA6 5 \u79D2\u81EA\u52A8\u91CD\u8FDE\u540E\u91CD\u8BD5`;
|
|
3829
|
+
}
|
|
3778
3830
|
function loadOrCreateKeys() {
|
|
3779
3831
|
for (const f of [KEY_FILE, LEGACY_KEY_FILE]) {
|
|
3780
3832
|
if (!existsSync(f)) continue;
|
|
@@ -3829,6 +3881,7 @@ var AgentBroker = class {
|
|
|
3829
3881
|
this.awaitingSince = 0;
|
|
3830
3882
|
this.selfPaired = false;
|
|
3831
3883
|
this.lastDisconnect = "";
|
|
3884
|
+
this.lastClose = null;
|
|
3832
3885
|
this.client = null;
|
|
3833
3886
|
this.downstreams = /* @__PURE__ */ new Map();
|
|
3834
3887
|
this.relay = null;
|
|
@@ -4107,6 +4160,9 @@ var AgentBroker = class {
|
|
|
4107
4160
|
extensionVersion: String(msg.extensionVersion || ""),
|
|
4108
4161
|
sessionId: String(msg.sessionId || ""),
|
|
4109
4162
|
pendingResultCount: Number(msg.pendingResultCount) || 0,
|
|
4163
|
+
// ⭐B7b-P1 未领取结果摘要透传(connection_status 展示 + claim_pending_result 领取引导);
|
|
4164
|
+
// 旧版插件 hello 无此字段=空数组(不保留上次值:摘要必须与插件真源同步,宁缺勿旧)
|
|
4165
|
+
pendingResults: Array.isArray(msg.pendingResults) ? msg.pendingResults.slice(0, 10) : [],
|
|
4110
4166
|
// ⭐r81 P0-3 登录态随握手上报(宿主 connection_status 可见,需登录的动作可动手前预检);
|
|
4111
4167
|
// 旧 hello 无此字段时保留上次值(防重握手瞬间丢登录态)
|
|
4112
4168
|
account: msg.account ? { loggedIn: msg.account.loggedIn === true, nickname: String(msg.account.nickname || "") || null } : this.extension.account || null
|
|
@@ -4115,6 +4171,19 @@ var AgentBroker = class {
|
|
|
4115
4171
|
this.notifyDownstreamsExtension(true);
|
|
4116
4172
|
return;
|
|
4117
4173
|
}
|
|
4174
|
+
case "extension.account.update": {
|
|
4175
|
+
if (msg.account) {
|
|
4176
|
+
this.extension = {
|
|
4177
|
+
...this.extension,
|
|
4178
|
+
account: {
|
|
4179
|
+
loggedIn: msg.account.loggedIn === true,
|
|
4180
|
+
nickname: String(msg.account.nickname || "") || null
|
|
4181
|
+
}
|
|
4182
|
+
};
|
|
4183
|
+
log(`[lf-agent] \u767B\u5F55\u6001\u66F4\u65B0\uFF1A${msg.account.loggedIn === true ? `\u5DF2\u767B\u5F55\uFF08${msg.account.nickname || "?"}\uFF09` : "\u672A\u767B\u5F55"}`);
|
|
4184
|
+
}
|
|
4185
|
+
return;
|
|
4186
|
+
}
|
|
4118
4187
|
case "task.progress": {
|
|
4119
4188
|
const p = msg.progress || {};
|
|
4120
4189
|
const dsProgress = this.downstreams.get(String(msg.deviceId || ""));
|
|
@@ -4215,7 +4284,7 @@ var AgentBroker = class {
|
|
|
4215
4284
|
return;
|
|
4216
4285
|
}
|
|
4217
4286
|
});
|
|
4218
|
-
ws.on("close", () => {
|
|
4287
|
+
ws.on("close", (code, reasonBuf) => {
|
|
4219
4288
|
if (pokeTimer) clearTimeout(pokeTimer);
|
|
4220
4289
|
clearInterval(pingTimer);
|
|
4221
4290
|
if (ws.__lfDownstreamId) {
|
|
@@ -4231,11 +4300,14 @@ var AgentBroker = class {
|
|
|
4231
4300
|
if (this.client === ws) {
|
|
4232
4301
|
this.client = null;
|
|
4233
4302
|
this.clientExtensionId = null;
|
|
4303
|
+
const closeReason = String(reasonBuf?.toString?.("utf8") || "");
|
|
4304
|
+
this.lastClose = { code: Number(code) || 0, reason: closeReason, at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
4234
4305
|
if (this.extension.connected) {
|
|
4235
4306
|
this.extension = { ...this.extension, connected: false };
|
|
4236
4307
|
this.lastDisconnect = (/* @__PURE__ */ new Date()).toISOString();
|
|
4237
|
-
log(
|
|
4238
|
-
this.
|
|
4308
|
+
log(`[lf-agent] \u63D2\u4EF6\u65AD\u5F00\uFF08close code=${code}${closeReason ? ` reason="${closeReason}"` : ""}\uFF1B\u7B49\u63D2\u4EF6\u81EA\u52A8\u91CD\u8FDE\uFF1B\u82E5\u957F\u65F6\u95F4\u672A\u6062\u590D\uFF0C\u68C0\u67E5\u63D2\u4EF6\u5F00\u5173/\u91CD\u8F7D\u63D2\u4EF6\uFF09`);
|
|
4309
|
+
this.abortPendingTasks();
|
|
4310
|
+
this.notifyDownstreamsExtension(false, this.lastClose);
|
|
4239
4311
|
}
|
|
4240
4312
|
if (this.awaitingPairing) {
|
|
4241
4313
|
this.awaitingPairing = false;
|
|
@@ -4251,11 +4323,11 @@ var AgentBroker = class {
|
|
|
4251
4323
|
const devices = [DEVICE, ...[...this.downstreams.values()].map((d) => d.device)];
|
|
4252
4324
|
this.send({ type: "broker.hello", protocolVersion: PROTOCOL_VERSION, serverName: "LeadsRadar Agent Adapter", devices });
|
|
4253
4325
|
}
|
|
4254
|
-
/** 插件在线状态变化时通知所有卫星(卫星据此维护自己的 extension.connected / step
|
|
4255
|
-
notifyDownstreamsExtension(connected) {
|
|
4326
|
+
/** 插件在线状态变化时通知所有卫星(卫星据此维护自己的 extension.connected / step);⭐1.2.17 B3:断开时顺带透传 close frame 诊断 */
|
|
4327
|
+
notifyDownstreamsExtension(connected, lastClose = null) {
|
|
4256
4328
|
for (const entry of this.downstreams.values()) {
|
|
4257
4329
|
try {
|
|
4258
|
-
entry.ws.send(JSON.stringify({ type: "device.extension.state", connected: connected === true }));
|
|
4330
|
+
entry.ws.send(JSON.stringify({ type: "device.extension.state", connected: connected === true, lastClose: lastClose ? { code: lastClose.code, reason: lastClose.reason } : null, pendingResults: (this.extension.pendingResults || []).slice(0, 10) }));
|
|
4259
4331
|
} catch {
|
|
4260
4332
|
}
|
|
4261
4333
|
}
|
|
@@ -4422,13 +4494,20 @@ var AgentBroker = class {
|
|
|
4422
4494
|
switch (msg.type) {
|
|
4423
4495
|
case "device.extension.state":
|
|
4424
4496
|
relay.extensionConnected = msg.connected === true;
|
|
4497
|
+
if (Array.isArray(msg.pendingResults)) {
|
|
4498
|
+
this.extension = { ...this.extension, pendingResults: msg.pendingResults.slice(0, 10), pendingResultCount: msg.pendingResults.length };
|
|
4499
|
+
}
|
|
4425
4500
|
if (msg.connected === true && this.awaitingPairing) {
|
|
4426
4501
|
this.awaitingPairing = false;
|
|
4427
4502
|
log("[lf-agent] \u536B\u661F\u6A21\u5F0F\u5DF2\u590D\u4F4D\u7B49\u5F85\u6279\u51C6\u72B6\u6001");
|
|
4428
4503
|
}
|
|
4429
4504
|
if (this.extension.connected !== relay.extensionConnected) {
|
|
4430
4505
|
this.extension = { ...this.extension, connected: relay.extensionConnected };
|
|
4431
|
-
if (!relay.extensionConnected)
|
|
4506
|
+
if (!relay.extensionConnected) {
|
|
4507
|
+
this.lastDisconnect = (/* @__PURE__ */ new Date()).toISOString();
|
|
4508
|
+
if (relay.lastClose) this.lastClose = { code: relay.lastClose.code || 0, reason: relay.lastClose.reason || "", at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
4509
|
+
this.abortPendingTasks();
|
|
4510
|
+
}
|
|
4432
4511
|
log(`[lf-agent] \u4E2D\u8F6C\u901A\u77E5\uFF1A\u63D2\u4EF6${relay.extensionConnected ? "\u5DF2\u8FDE\u63A5" : "\u5DF2\u65AD\u5F00"}`);
|
|
4433
4512
|
}
|
|
4434
4513
|
return;
|
|
@@ -4526,6 +4605,45 @@ var AgentBroker = class {
|
|
|
4526
4605
|
waiter.response = response;
|
|
4527
4606
|
waiter.resolve(response);
|
|
4528
4607
|
}
|
|
4608
|
+
/** ⭐1.2.17 B3 断开原因诊断:按插件断开的 close frame(code+reason)给精准指引。
|
|
4609
|
+
* 返回非空字符串=有诊断(调用方以此为首选指引,跳过 start chrome 类无效指引);null=无可用诊断(回落旧文案)。
|
|
4610
|
+
* reason 真源在插件 local-agent-connector.ts:stop() 关开关 → "LF Agent disabled";
|
|
4611
|
+
* stopForAvailability() 桥不可用 → "LF Agent bridge is not publicly available";
|
|
4612
|
+
* 浏览器被关/插件被禁用/重载 = SW 直接被杀无告别帧 → ws 层报 1006(1005/1001 同归异常断) */
|
|
4613
|
+
disconnectDiagnosis() {
|
|
4614
|
+
const c = this.lastClose;
|
|
4615
|
+
if (!c) return null;
|
|
4616
|
+
if (Date.now() - new Date(c.at).getTime() > 10 * 60 * 1e3) return null;
|
|
4617
|
+
if (c.reason.includes("disabled")) {
|
|
4618
|
+
return `\u8BCA\u65AD\uFF1A\u63D2\u4EF6\u7684\u300C\u667A\u80FD\u4F53\u8FDE\u63A5\u300D\u5F00\u5173\u88AB\u5173\u95ED\uFF08\u6D4F\u89C8\u5668\u8FD8\u5F00\u7740\uFF0C\u65E0\u9700\u91CD\u542F\uFF09\u2014\u2014\u8BF7\u7528\u6237\u5230\u63D2\u4EF6\u8BBE\u7F6E \u2192 \u667A\u80FD\u4F53\u8FDE\u63A5 \u2192 \u91CD\u65B0\u6253\u5F00\u9876\u90E8\u5F00\u5173\uFF0C\u914D\u5BF9\u5173\u7CFB\u4FDD\u7559\uFF0C\u7EA6 5 \u79D2\u81EA\u52A8\u91CD\u8FDE\u540E\u91CD\u8BD5`;
|
|
4619
|
+
}
|
|
4620
|
+
if (c.reason.includes("not publicly available")) {
|
|
4621
|
+
return `\u8BCA\u65AD\uFF1A\u63D2\u4EF6\u4FA7\u5224\u5B9A\u672C\u5730\u6865\u4E0D\u53EF\u7528\u5DF2\u81EA\u52A8\u65AD\u5F00\u2014\u2014\u8BF7\u7528\u6237\u91CD\u542F\u6D4F\u89C8\u5668\uFF0C\u518D\u5230\u63D2\u4EF6\u8BBE\u7F6E \u2192 \u667A\u80FD\u4F53\u8FDE\u63A5\u91CD\u65B0\u6253\u5F00\u5F00\u5173`;
|
|
4622
|
+
}
|
|
4623
|
+
if (c.code === 1006 || c.code === 1005 || c.code === 1001) {
|
|
4624
|
+
return `\u8BCA\u65AD\uFF1A\u8FDE\u63A5\u88AB\u76F4\u63A5\u5207\u65AD\uFF08\u6D4F\u89C8\u5668\u88AB\u5173\u95ED\uFF0C\u6216\u63D2\u4EF6\u88AB\u7981\u7528/\u91CD\u8F7D\u2014\u2014\u65E0\u544A\u522B\u5E27\uFF09\u2014\u2014\u8BF7\u7528\u6237\u91CD\u5F00\u6D4F\u89C8\u5668\u5E76\u786E\u8BA4\u63A2\u6817\u63D2\u4EF6\u5DF2\u542F\u7528\uFF0C\u63D2\u4EF6\u7EA6 5 \u79D2\u81EA\u52A8\u91CD\u8FDE\u540E\u91CD\u8BD5`;
|
|
4625
|
+
}
|
|
4626
|
+
if (c.code === 1e3 && c.reason) {
|
|
4627
|
+
return `\u8BCA\u65AD\uFF1A\u63D2\u4EF6\u4E3B\u52A8\u65AD\u5F00\uFF08${c.reason}\uFF09\u2014\u2014\u8BF7\u7528\u6237\u68C0\u67E5\u63D2\u4EF6\u8BBE\u7F6E \u2192 \u667A\u80FD\u4F53\u8FDE\u63A5\u7684\u5F00\u5173\u72B6\u6001\u540E\u91CD\u8BD5`;
|
|
4628
|
+
}
|
|
4629
|
+
return null;
|
|
4630
|
+
}
|
|
4631
|
+
/** ⭐1.2.16 B7:插件连接断开时中止所有等待中的任务(浏览器被关/插件掉线不再傻等 TASK_TIMEOUT,秒级返回失败) */
|
|
4632
|
+
abortPendingTasks() {
|
|
4633
|
+
if (!this.taskWaiters.size) return;
|
|
4634
|
+
const ids = [...this.taskWaiters.keys()];
|
|
4635
|
+
log(`[lf-agent] \u63D2\u4EF6\u65AD\u5F00 \u2192 \u79D2\u7EA7\u4E2D\u6B62 ${ids.length} \u4E2A\u7B49\u5F85\u4E2D\u7684\u4EFB\u52A1`);
|
|
4636
|
+
for (const id of ids) {
|
|
4637
|
+
this.finishTask(id, {
|
|
4638
|
+
ok: false,
|
|
4639
|
+
error: {
|
|
4640
|
+
code: "TASK_ABORTED",
|
|
4641
|
+
// ⭐1.2.17 B3:诊断优先(开关关→指开关;被杀→指重开浏览器),无诊断才回落探测命令
|
|
4642
|
+
message: `\u63D2\u4EF6\u8FDE\u63A5\u5DF2\u65AD\u5F00\uFF0C\u4EFB\u52A1\u5DF2\u4E2D\u6B62\u3002${this.disconnectDiagnosis() || extensionLaunchHint() || "\u8BF7\u91CD\u5F00\u6D4F\u89C8\u5668\uFF08\u63D2\u4EF6\u7EA6 5 \u79D2\u81EA\u52A8\u91CD\u8FDE\uFF09\u540E\u91CD\u8BD5\u3002"}`
|
|
4643
|
+
}
|
|
4644
|
+
});
|
|
4645
|
+
}
|
|
4646
|
+
}
|
|
4529
4647
|
/**
|
|
4530
4648
|
* 下发任务并等待结果。
|
|
4531
4649
|
* @returns {Promise<{ok:boolean, error?:object, [k:string]:unknown}>}
|
|
@@ -4533,11 +4651,12 @@ var AgentBroker = class {
|
|
|
4533
4651
|
startTask(task, timeoutMs = LIST_TASK_TIMEOUT_MS) {
|
|
4534
4652
|
if (this.relay) return this.startTaskViaRelay(task, timeoutMs);
|
|
4535
4653
|
if (!this.extension.connected) {
|
|
4654
|
+
const diag = this.disconnectDiagnosis();
|
|
4536
4655
|
return Promise.resolve({
|
|
4537
4656
|
ok: false,
|
|
4538
4657
|
error: {
|
|
4539
4658
|
code: "EXTENSION_NOT_CONNECTED",
|
|
4540
|
-
message: this.awaitingPairing ? "\u63D2\u4EF6\u5DF2\u68C0\u6D4B\u5230\u672C\u8BBE\u5907\uFF0C\u4F46\u5C1A\u672A\u6279\u51C6\u914D\u5BF9\u3002\u8BF7\u8BA9\u7528\u6237\u5728\u63D2\u4EF6\u8BBE\u7F6E\u9875\u300C\u667A\u80FD\u4F53\u8FDE\u63A5\u300D\u4E2D\u6838\u5BF9\u8BBE\u5907\u6307\u7EB9\u5E76\u70B9\u51FB\u6279\u51C6\uFF0C\u7136\u540E\u91CD\u8BD5\u3002" :
|
|
4659
|
+
message: this.awaitingPairing ? "\u63D2\u4EF6\u5DF2\u68C0\u6D4B\u5230\u672C\u8BBE\u5907\uFF0C\u4F46\u5C1A\u672A\u6279\u51C6\u914D\u5BF9\u3002\u8BF7\u8BA9\u7528\u6237\u5728\u63D2\u4EF6\u8BBE\u7F6E\u9875\u300C\u667A\u80FD\u4F53\u8FDE\u63A5\u300D\u4E2D\u6838\u5BF9\u8BBE\u5907\u6307\u7EB9\u5E76\u70B9\u51FB\u6279\u51C6\uFF0C\u7136\u540E\u91CD\u8BD5\u3002" : diag ? `\u672A\u8FDE\u63A5\u5230\u63A2\u6817\uFF08LeadsRadar\uFF09\u6D4F\u89C8\u5668\u63D2\u4EF6\u3002${diag}\u3002` : `\u672A\u8FDE\u63A5\u5230\u63A2\u6817\uFF08LeadsRadar\uFF09\u6D4F\u89C8\u5668\u63D2\u4EF6\u3002${extensionLaunchHint() || "\u82E5\u4F60\u6709\u7EC8\u7AEF\u6743\u9650\uFF0C\u53EF\u76F4\u63A5\u8FD0\u884C start chrome\uFF08\u6216 start msedge\uFF09\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u91CD\u8FDE\uFF08\u7EA6\u7B49 5 \u79D2\u518D\u91CD\u8BD5\uFF09"}\uFF1B\u5426\u5219\u8BF7\u8BA9\u7528\u6237\uFF1A1) \u6253\u5F00\u6D4F\u89C8\u5668\u5E76\u786E\u8BA4\u63A2\u6817\u63D2\u4EF6\u5DF2\u542F\u7528\uFF1B2) \u63D2\u4EF6\u8BBE\u7F6E\u9875 \u2192\u300C\u667A\u80FD\u4F53\u8FDE\u63A5\u300D\u2192 \u5F00\u542F\u9876\u90E8\u5F00\u5173\uFF0C\u7136\u540E\u91CD\u8BD5\u3002`
|
|
4541
4660
|
}
|
|
4542
4661
|
});
|
|
4543
4662
|
}
|
|
@@ -4549,7 +4668,7 @@ var AgentBroker = class {
|
|
|
4549
4668
|
ok: false,
|
|
4550
4669
|
error: {
|
|
4551
4670
|
code: "TASK_TIMEOUT",
|
|
4552
|
-
message: `\u4EFB\u52A1\u8D85\u65F6\uFF08${Math.round(timeoutMs / 1e3)}s\uFF09\u3002\u63D2\u4EF6\u53EF\u80FD\
|
|
4671
|
+
message: `\u4EFB\u52A1\u8D85\u65F6\uFF08${Math.round(timeoutMs / 1e3)}s\uFF09\u3002\u6CE8\u610F\uFF1A\u63D2\u4EF6\u53EF\u80FD\u4ECD\u5728\u6267\u884C\uFF0C\u4E14\u91C7\u96C6\u6570\u636E\u4F1A\u5148\u843D\u63A2\u6817\u672C\u5730\u5E93\u2014\u2014\u8BF7\u5148\u7528 query_local_data \u67E5\u8BE2\u8BE5\u4EFB\u52A1\u7684 keyword/url \u5BF9\u5E94\u7ED3\u679C\uFF0C\u67E5\u5230\u5C31\u76F4\u63A5\u7528\u3001\u4E0D\u8981\u91CD\u53D1\uFF1B\u786E\u5B9E\u6CA1\u6709\u518D\u91CD\u53D1\u4EFB\u52A1\uFF08\u907F\u514D\u91CD\u590D\u6D88\u8017\u91C7\u96C6\u989D\u5EA6\uFF09\u3002`
|
|
4553
4672
|
}
|
|
4554
4673
|
});
|
|
4555
4674
|
}, timeoutMs);
|
|
@@ -4562,11 +4681,12 @@ var AgentBroker = class {
|
|
|
4562
4681
|
startTaskViaRelay(task, timeoutMs) {
|
|
4563
4682
|
const relay = this.relay;
|
|
4564
4683
|
if (!relay || !relay.attached || !relay.extensionConnected) {
|
|
4684
|
+
const diag = this.disconnectDiagnosis();
|
|
4565
4685
|
return Promise.resolve({
|
|
4566
4686
|
ok: false,
|
|
4567
4687
|
error: {
|
|
4568
4688
|
code: "EXTENSION_NOT_CONNECTED",
|
|
4569
|
-
message: this.awaitingPairing ? `\u63D2\u4EF6\u5DF2\u68C0\u6D4B\u5230\u672C\u8BBE\u5907\uFF08\u536B\u661F\u6A21\u5F0F\uFF09\uFF0C\u4F46\u5C1A\u672A\u6279\u51C6\u914D\u5BF9\u3002\u8BF7\u8BA9\u7528\u6237\u5728\u63D2\u4EF6\u8BBE\u7F6E\u9875\u300C\u667A\u80FD\u4F53\u8FDE\u63A5\u300D\u4E2D\u6838\u5BF9\u8BBE\u5907\u6307\u7EB9\u5E76\u70B9\u51FB\u6279\u51C6\uFF0C\u7136\u540E\u91CD\u8BD5\u3002\u6307\u7EB9\uFF1A${fingerprint}` : `\u672A\u8FDE\u63A5\u5230\u63A2\u6817\u63D2\u4EF6\u3002\u5F53\u524D\u4E3A\u591A\u5BBF\u4E3B\u4E2D\u8F6C\u6A21\u5F0F\uFF08\u7AEF\u53E3\u88AB ${relay?.hostLabel || "\u53E6\u4E00\u5BBF\u4E3B"} \u7684\u9002\u914D\u5668\u5360\u7528\uFF0C\u672C\u8BBE\u5907\u7ECF\u5176\u4E2D\u8F6C\uFF09\
|
|
4689
|
+
message: this.awaitingPairing ? `\u63D2\u4EF6\u5DF2\u68C0\u6D4B\u5230\u672C\u8BBE\u5907\uFF08\u536B\u661F\u6A21\u5F0F\uFF09\uFF0C\u4F46\u5C1A\u672A\u6279\u51C6\u914D\u5BF9\u3002\u8BF7\u8BA9\u7528\u6237\u5728\u63D2\u4EF6\u8BBE\u7F6E\u9875\u300C\u667A\u80FD\u4F53\u8FDE\u63A5\u300D\u4E2D\u6838\u5BF9\u8BBE\u5907\u6307\u7EB9\u5E76\u70B9\u51FB\u6279\u51C6\uFF0C\u7136\u540E\u91CD\u8BD5\u3002\u6307\u7EB9\uFF1A${fingerprint}` : diag ? `\u672A\u8FDE\u63A5\u5230\u63A2\u6817\u63D2\u4EF6\uFF08\u591A\u5BBF\u4E3B\u4E2D\u8F6C\u6A21\u5F0F\uFF09\u3002${diag}\u3002` : `\u672A\u8FDE\u63A5\u5230\u63A2\u6817\u63D2\u4EF6\u3002\u5F53\u524D\u4E3A\u591A\u5BBF\u4E3B\u4E2D\u8F6C\u6A21\u5F0F\uFF08\u7AEF\u53E3\u88AB ${relay?.hostLabel || "\u53E6\u4E00\u5BBF\u4E3B"} \u7684\u9002\u914D\u5668\u5360\u7528\uFF0C\u672C\u8BBE\u5907\u7ECF\u5176\u4E2D\u8F6C\uFF09\u3002${extensionLaunchHint() || "\u8BF7\u8BA9\u7528\u6237\uFF1A1) \u786E\u8BA4\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u4E14\u63A2\u6817\u63D2\u4EF6\u5DF2\u542F\u7528\uFF1B2) \u63D2\u4EF6\u8BBE\u7F6E\u9875 \u2192\u300C\u667A\u80FD\u4F53\u8FDE\u63A5\u300D\u2192 \u5F00\u542F\u9876\u90E8\u5F00\u5173"}\uFF0C\u7136\u540E\u6BCF 8 \u79D2\u91CD\u8BD5\u4E00\u6B21\u3002`
|
|
4570
4690
|
}
|
|
4571
4691
|
});
|
|
4572
4692
|
}
|
|
@@ -4578,7 +4698,7 @@ var AgentBroker = class {
|
|
|
4578
4698
|
ok: false,
|
|
4579
4699
|
error: {
|
|
4580
4700
|
code: "TASK_TIMEOUT",
|
|
4581
|
-
message: `\u4EFB\u52A1\u8D85\u65F6\uFF08${Math.round(timeoutMs / 1e3)}s\uFF0C\u7ECF\u4E3B Broker \u4E2D\u8F6C\uFF09\u3002\u63D2\u4EF6\u53EF\u80FD\
|
|
4701
|
+
message: `\u4EFB\u52A1\u8D85\u65F6\uFF08${Math.round(timeoutMs / 1e3)}s\uFF0C\u7ECF\u4E3B Broker \u4E2D\u8F6C\uFF09\u3002\u6CE8\u610F\uFF1A\u63D2\u4EF6\u53EF\u80FD\u4ECD\u5728\u6267\u884C\uFF0C\u4E14\u91C7\u96C6\u6570\u636E\u4F1A\u5148\u843D\u63A2\u6817\u672C\u5730\u5E93\u2014\u2014\u8BF7\u5148\u7528 query_local_data \u67E5\u8BE2\u8BE5\u4EFB\u52A1\u7684 keyword/url \u5BF9\u5E94\u7ED3\u679C\uFF0C\u67E5\u5230\u5C31\u76F4\u63A5\u7528\u3001\u4E0D\u8981\u91CD\u53D1\uFF1B\u786E\u5B9E\u6CA1\u6709\u518D\u91CD\u53D1\u4EFB\u52A1\uFF08\u907F\u514D\u91CD\u590D\u6D88\u8017\u91C7\u96C6\u989D\u5EA6\uFF09\u3002`
|
|
4582
4702
|
}
|
|
4583
4703
|
});
|
|
4584
4704
|
}, timeoutMs);
|
|
@@ -4594,6 +4714,13 @@ var AgentBroker = class {
|
|
|
4594
4714
|
});
|
|
4595
4715
|
}
|
|
4596
4716
|
/** connection_status 快照(驱动宿主 AI 的 onboarding 状态机);⭐403 token 经济版:welcome 全文仅在 step=3 下发,step 1/2 轮询每轮省约 200 tokens */
|
|
4717
|
+
/** ⭐B7b-P1 存货提示(主/卫星 hint 共用):插件侧有已完成未领取结果时,引导 AI 先领取再决定重发 */
|
|
4718
|
+
pendingResultsHint() {
|
|
4719
|
+
const list = this.extension.pendingResults || [];
|
|
4720
|
+
if (!list.length) return "";
|
|
4721
|
+
const brief = list.slice(0, 3).map((p) => `${p.mode || "?"}\xB7${p.keyword || p.url || p.taskId}`).join("\u3001");
|
|
4722
|
+
return `\u6CE8\u610F\uFF1A\u6709 ${list.length} \u6761\u5DF2\u5B8C\u6210\u7684\u4EFB\u52A1\u7ED3\u679C\u672A\u88AB\u9886\u53D6\uFF08${brief}${list.length > 3 ? " \u7B49" : ""}\uFF09\u2014\u2014\u8BF7\u5148\u7528 leadsradar_claim_pending_result \u9886\u53D6\uFF08\u4E0D\u5360\u91C7\u96C6\u9650\u989D\uFF09\uFF0C\u9886\u5230\u76F4\u63A5\u7528\uFF1B\u6CA1\u6709\u9700\u8981\u7684\u518D\u8003\u8651\u65B0\u4EFB\u52A1\uFF0C\u907F\u514D\u91CD\u590D\u6D88\u8017\u989D\u5EA6\u3002`;
|
|
4723
|
+
}
|
|
4597
4724
|
statusSnapshot() {
|
|
4598
4725
|
const connected = this.relay ? this.relay.extensionConnected : this.extension.connected;
|
|
4599
4726
|
const awaitingPairing = this.awaitingPairing;
|
|
@@ -4619,7 +4746,13 @@ var AgentBroker = class {
|
|
|
4619
4746
|
extensionId: this.extension.extensionId || null,
|
|
4620
4747
|
extensionVersion: this.extension.extensionVersion || null,
|
|
4621
4748
|
pendingResultCount: this.extension.pendingResultCount,
|
|
4749
|
+
// ⭐B7b-P1 未领取结果摘要透出:非空=插件侧有已完成结果待 leadsradar_claim_pending_result 领取
|
|
4750
|
+
pendingResults: this.extension.pendingResults || [],
|
|
4622
4751
|
lastDisconnectedAt: this.lastDisconnect || null,
|
|
4752
|
+
// ⭐1.2.17 B3 断开原因透出:close frame 原文(code+reason)+诊断结论,宿主 AI 可直接读
|
|
4753
|
+
lastDisconnectCode: this.lastClose?.code ?? null,
|
|
4754
|
+
lastDisconnectReason: this.lastClose?.reason || null,
|
|
4755
|
+
disconnectDiagnosis: this.extension.connected ? null : this.disconnectDiagnosis(),
|
|
4623
4756
|
// ⭐r81 P0-3 登录态透出:save_topic/云端入库等需登录——宿主动手前用 connection_status
|
|
4624
4757
|
// 预检(wb 实测采完详情才报 CLOUD_ERROR,白消耗采集额度)。注意:握手时点的快照,
|
|
4625
4758
|
// 中途登录/退出会过期,动作层 LOGIN_REQUIRED 报错是第二道防线
|
|
@@ -4634,7 +4767,7 @@ var AgentBroker = class {
|
|
|
4634
4767
|
awaitingPairing,
|
|
4635
4768
|
portBound: false,
|
|
4636
4769
|
relayMode: true,
|
|
4637
|
-
hint: step === 3 ? `\u5DF2\u8FDE\u63A5\uFF08\u591A\u5BBF\u4E3B\u4E2D\u8F6C\u6A21\u5F0F\uFF1A\u7ECF\u300C${this.relay.hostLabel || this.relay.host}\u300D\u7684\u8FDE\u63A5\u5668\u5171\u4EAB\u63D2\u4EF6\u8FDE\u63A5\uFF0C\u8C46\u5305\u5DE5\u4F5C/WorkBuddy \u53EF\u540C\u65F6\u5728\u7EBF\uFF09\uFF0C\u53EF\u4EE5\u5F00\u59CB\u91C7\u96C6\u4EFB\u52A1\u3002` : step === 2 ? `\u7B49\u5F85\u7528\u6237\u6279\u51C6\u914D\u5BF9\uFF08\u536B\u661F\u6A21\u5F0F\uFF0C\u7ECF\u300C${this.relay.hostLabel || this.relay.host}\u300D\u4E2D\u8F6C\uFF09\uFF1A\u628A adapter.fingerprint \u539F\u6837\u8F6C\u544A\u7528\u6237\uFF0C\u8BF7\u5176\u5230\u63D2\u4EF6\u8BBE\u7F6E\u9875\u786E\u8BA4\u662F\u81EA\u5DF1\u7684\u8BBE\u5907\u540E\u70B9\u300C\u6279\u51C6\u300D\uFF0C\u7136\u540E\u6BCF 8 \u79D2\u590D\u67E5\u4E00\u6B21\uFF08\u6CE8\u610F\uFF1A\u6279\u51C6\u524D\u4EFB\u52A1\u4F1A\u88AB\u62D2\u7EDD\uFF0C\u522B\u6025\u7740\u5F00\u5DE5\uFF09\u3002` : `\u4E2D\u8F6C\u6A21\u5F0F\u7B49\u5F85\u63D2\u4EF6\uFF1A\u8BF7\u8BA9\u7528\u6237\u6253\u5F00\u6D4F\u89C8\u5668\u786E\u8BA4\u63A2\u6817\u63D2\u4EF6\u5DF2\u542F\u7528\u3001\u8BBE\u7F6E\u9875\u300C\u667A\u80FD\u4F53\u8FDE\u63A5\u300D\u5F00\u5173\u5DF2\u6253\u5F00\uFF0C\u7136\u540E\u6BCF 8 \u79D2\u590D\u67E5\u4E00\u6B21\u3002`
|
|
4770
|
+
hint: step === 3 ? `\u5DF2\u8FDE\u63A5\uFF08\u591A\u5BBF\u4E3B\u4E2D\u8F6C\u6A21\u5F0F\uFF1A\u7ECF\u300C${this.relay.hostLabel || this.relay.host}\u300D\u7684\u8FDE\u63A5\u5668\u5171\u4EAB\u63D2\u4EF6\u8FDE\u63A5\uFF0C\u8C46\u5305\u5DE5\u4F5C/WorkBuddy \u53EF\u540C\u65F6\u5728\u7EBF\uFF09\uFF0C\u53EF\u4EE5\u5F00\u59CB\u91C7\u96C6\u4EFB\u52A1\u3002${this.pendingResultsHint()}` : step === 2 ? `\u7B49\u5F85\u7528\u6237\u6279\u51C6\u914D\u5BF9\uFF08\u536B\u661F\u6A21\u5F0F\uFF0C\u7ECF\u300C${this.relay.hostLabel || this.relay.host}\u300D\u4E2D\u8F6C\uFF09\uFF1A\u628A adapter.fingerprint \u539F\u6837\u8F6C\u544A\u7528\u6237\uFF0C\u8BF7\u5176\u5230\u63D2\u4EF6\u8BBE\u7F6E\u9875\u786E\u8BA4\u662F\u81EA\u5DF1\u7684\u8BBE\u5907\u540E\u70B9\u300C\u6279\u51C6\u300D\uFF0C\u7136\u540E\u6BCF 8 \u79D2\u590D\u67E5\u4E00\u6B21\uFF08\u6CE8\u610F\uFF1A\u6279\u51C6\u524D\u4EFB\u52A1\u4F1A\u88AB\u62D2\u7EDD\uFF0C\u522B\u6025\u7740\u5F00\u5DE5\uFF09\u3002` : `\u4E2D\u8F6C\u6A21\u5F0F\u7B49\u5F85\u63D2\u4EF6\uFF1A\u8BF7\u8BA9\u7528\u6237\u6253\u5F00\u6D4F\u89C8\u5668\u786E\u8BA4\u63A2\u6817\u63D2\u4EF6\u5DF2\u542F\u7528\u3001\u8BBE\u7F6E\u9875\u300C\u667A\u80FD\u4F53\u8FDE\u63A5\u300D\u5F00\u5173\u5DF2\u6253\u5F00\uFF0C\u7136\u540E\u6BCF 8 \u79D2\u590D\u67E5\u4E00\u6B21\u3002`
|
|
4638
4771
|
},
|
|
4639
4772
|
welcome: step === 3 ? { fixedCopy: WELCOME_FIXED_COPY } : null
|
|
4640
4773
|
};
|
|
@@ -4648,7 +4781,7 @@ var AgentBroker = class {
|
|
|
4648
4781
|
// ⭐r85 portBlocked:EADDRINUSE 且占用者探测无应答 → Windows 动态端口保留段圈走端口。
|
|
4649
4782
|
// 让宿主 AI 直接把根治命令转告用户,而不是一起懵在「连接器连接失败」
|
|
4650
4783
|
portBlocked: this.portBlocked === true,
|
|
4651
|
-
hint: this.portBlocked ? `\u9002\u914D\u5668\u7AEF\u53E3 ${PORT} \u88AB Windows \u52A8\u6001\u7AEF\u53E3\u4FDD\u7559\uFF08Hyper-V/WSL \u6392\u9664\u6BB5\uFF09\u6321\u4F4F\uFF1Abind \u88AB\u62D2\u4F46\u65E0\u8FDB\u7A0B\u5360\u7528\uFF0C\u901A\u5E38\u51E0\u5341\u5206\u949F\u5185\u81EA\u52A8\u6062\u590D\uFF0C\u9002\u914D\u5668\u5728\u6301\u7EED\u91CD\u8BD5\u3002\u8BF7\u628A\u8FD9\u6761\u6839\u6CBB\u547D\u4EE4\u8F6C\u544A\u7528\u6237\uFF08\u7BA1\u7406\u5458 PowerShell \u8FD0\u884C\u4E00\u6B21\u6C38\u4E45\u751F\u6548\uFF09\uFF1Anet stop winnat ; netsh int ipv4 add excludedportrange protocol=tcp startport=${PORT} numberofports=1 ; net start winnat\uFF08\u8FD0\u884C\u5B8C\u91CD\u542F\u672C\u4F1A\u8BDD\u5373\u8FDE\u4E0A\uFF09\u3002\u8F6C\u544A\u540E\u6BCF 30 \u79D2\u590D\u67E5\u4E00\u6B21\u3002` : !this.portBound ? `\u672C\u9002\u914D\u5668\u7684\u672C\u673A\u7AEF\u53E3 ${PORT} \u6B63\u5728\u88AB\u5360\u7528\u4E14\u5C1A\u672A\u5B8C\u6210\u4E2D\u8F6C\u534F\u5546\uFF08\u6B63\u5728\u81EA\u52A8\u5904\u7406\uFF1A\u540C\u5BBF\u4E3B\u5B64\u513F\u4F1A\u88AB\u63A5\u7BA1\uFF0C\u5F02\u5BBF\u4E3B\u4F1A\u81EA\u52A8\u8F6C\u5165\u4E2D\u8F6C\u5171\u5B58\uFF09\u3002\u8BF7\u6BCF 8 \u79D2\u590D\u67E5\u4E00\u6B21\uFF1B\u82E5\u8D85\u8FC7 1 \u5206\u949F\u4ECD\u505C\u7559\u5728\u6B64\u72B6\u6001\uFF0C\u8BF7\u7528\u6237\u5B8C\u5168\u9000\u51FA\u6240\u6709 AI \u52A9\u624B\uFF08\u542B\u6258\u76D8\uFF09\u540E\u91CD\u5F00\u3002` : step === 1 ?
|
|
4784
|
+
hint: this.portBlocked ? `\u9002\u914D\u5668\u7AEF\u53E3 ${PORT} \u88AB Windows \u52A8\u6001\u7AEF\u53E3\u4FDD\u7559\uFF08Hyper-V/WSL \u6392\u9664\u6BB5\uFF09\u6321\u4F4F\uFF1Abind \u88AB\u62D2\u4F46\u65E0\u8FDB\u7A0B\u5360\u7528\uFF0C\u901A\u5E38\u51E0\u5341\u5206\u949F\u5185\u81EA\u52A8\u6062\u590D\uFF0C\u9002\u914D\u5668\u5728\u6301\u7EED\u91CD\u8BD5\u3002\u8BF7\u628A\u8FD9\u6761\u6839\u6CBB\u547D\u4EE4\u8F6C\u544A\u7528\u6237\uFF08\u7BA1\u7406\u5458 PowerShell \u8FD0\u884C\u4E00\u6B21\u6C38\u4E45\u751F\u6548\uFF09\uFF1Anet stop winnat ; netsh int ipv4 add excludedportrange protocol=tcp startport=${PORT} numberofports=1 ; net start winnat\uFF08\u8FD0\u884C\u5B8C\u91CD\u542F\u672C\u4F1A\u8BDD\u5373\u8FDE\u4E0A\uFF09\u3002\u8F6C\u544A\u540E\u6BCF 30 \u79D2\u590D\u67E5\u4E00\u6B21\u3002` : !this.portBound ? `\u672C\u9002\u914D\u5668\u7684\u672C\u673A\u7AEF\u53E3 ${PORT} \u6B63\u5728\u88AB\u5360\u7528\u4E14\u5C1A\u672A\u5B8C\u6210\u4E2D\u8F6C\u534F\u5546\uFF08\u6B63\u5728\u81EA\u52A8\u5904\u7406\uFF1A\u540C\u5BBF\u4E3B\u5B64\u513F\u4F1A\u88AB\u63A5\u7BA1\uFF0C\u5F02\u5BBF\u4E3B\u4F1A\u81EA\u52A8\u8F6C\u5165\u4E2D\u8F6C\u5171\u5B58\uFF09\u3002\u8BF7\u6BCF 8 \u79D2\u590D\u67E5\u4E00\u6B21\uFF1B\u82E5\u8D85\u8FC7 1 \u5206\u949F\u4ECD\u505C\u7559\u5728\u6B64\u72B6\u6001\uFF0C\u8BF7\u7528\u6237\u5B8C\u5168\u9000\u51FA\u6240\u6709 AI \u52A9\u624B\uFF08\u542B\u6258\u76D8\uFF09\u540E\u91CD\u5F00\u3002` : step === 1 ? `\u63D2\u4EF6\u672A\u8FDE\u63A5\uFF1A${this.disconnectDiagnosis() || extensionLaunchHint() || "\u82E5\u4F60\u6709\u7EC8\u7AEF\u6743\u9650\u53EF\u8FD0\u884C start chrome\uFF08\u6216 start msedge\uFF09\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u63D2\u4EF6\u7EA6 5 \u79D2\u5185\u81EA\u52A8\u91CD\u8FDE"}\uFF1B\u5426\u5219\u8BF7\u7528\u6237\u5728\u6D4F\u89C8\u5668\u6253\u5F00\u63A2\u6817\u63D2\u4EF6 \u2192 \u8BBE\u7F6E \u2192 \u667A\u80FD\u4F53\u8FDE\u63A5 \u2192 \u6253\u5F00\u9876\u90E8\u5F00\u5173\uFF0C\u7136\u540E\u6BCF 8 \u79D2\u590D\u67E5\u4E00\u6B21\u3002` : step === 2 ? `\u7B49\u5F85\u7528\u6237\u6279\u51C6\u914D\u5BF9\uFF1A\u628A adapter.fingerprint \u539F\u6837\u8F6C\u544A\u7528\u6237\uFF0C\u8BF7\u5176\u5230\u63D2\u4EF6\u8BBE\u7F6E\u9875\u6838\u5BF9\u6307\u7EB9\u4E00\u81F4\u540E\u70B9\u300C\u6279\u51C6\u300D\uFF0C\u7136\u540E\u6BCF 8 \u79D2\u590D\u67E5\u4E00\u6B21\u3002\u6CE8\u610F\uFF1A\u82E5 extension.connected \u4E3A false\uFF0C\u8BF4\u660E\u8FD9\u662F\u63D2\u4EF6\u65AD\u5F00\u524D\u7684\u65E7\u72B6\u6001\u2014\u2014\u8BF7\u63D0\u9192\u7528\u6237\u68C0\u67E5\u63D2\u4EF6\u5F00\u5173\u662F\u5426\u6253\u5F00\uFF08\u6216\u91CD\u65B0\u52A0\u8F7D\u63D2\u4EF6\u540E\u91CD\u65B0\u6253\u5F00\uFF09\uFF0C\u63D2\u4EF6\u91CD\u8FDE\u4F1A\u81EA\u52A8\u91CD\u65B0\u63E1\u624B\u3002` : `\u5DF2\u8FDE\u63A5\uFF0C\u53EF\u4EE5\u5F00\u59CB\u91C7\u96C6\u4EFB\u52A1\u3002${this.pendingResultsHint()}`
|
|
4652
4785
|
},
|
|
4653
4786
|
// step<3 不下发 welcome(省 token);step=3 由宿主 AI 原样展示给用户
|
|
4654
4787
|
welcome: step === 3 ? { fixedCopy: WELCOME_FIXED_COPY } : null
|
|
@@ -4786,6 +4919,17 @@ var TOOLS = [
|
|
|
4786
4919
|
required: ["source"],
|
|
4787
4920
|
additionalProperties: false
|
|
4788
4921
|
}
|
|
4922
|
+
},
|
|
4923
|
+
{
|
|
4924
|
+
name: "leadsradar_claim_pending_result",
|
|
4925
|
+
description: "\u9886\u53D6\u63A2\u6817\u63D2\u4EF6\u4FA7\u5DF2\u5B8C\u6210\u4F46\u672A\u88AB\u8BA4\u9886\u7684\u4EFB\u52A1\u7ED3\u679C\uFF08\u4E0D\u5360\u91C7\u96C6\u9650\u989D\u3001\u79D2\u56DE\uFF09\u3002\u4F55\u65F6\u7528\uFF1A\u2460\u4EFB\u52A1\u8D85\u65F6\u540E\uFF08\u63D2\u4EF6\u53EF\u80FD\u5DF2\u8DD1\u5B8C\uFF0C\u5148\u9886\u518D\u51B3\u5B9A\u662F\u5426\u91CD\u53D1\uFF0C\u907F\u514D\u53CC\u8017\u91C7\u96C6\u989D\u5EA6\uFF09\uFF1B\u2461\u5BBF\u4E3B/\u4F1A\u8BDD\u91CD\u542F\u540E\u56DE\u6765\uFF1B\u2462connection_status \u7684 extension.pendingResults \u5217\u8868\u975E\u7A7A\u65F6\u3002\u9886\u53D6\u7ED3\u679C\u91CC results \u4E3A\u7ED3\u679C\u672C\u4F53\u53EF\u76F4\u63A5\u4F7F\u7528\uFF0Cpending \u4E3A\u5269\u4F59\u672A\u9886\u53D6\u6458\u8981\u3002\u9886\u4E0D\u5230\u518D\u7528 query_local_data \u67E5\u672C\u5730\u5E93\uFF0C\u90FD\u6CA1\u6709\u624D\u8003\u8651\u91CD\u53D1\u4EFB\u52A1\u3002",
|
|
4926
|
+
inputSchema: {
|
|
4927
|
+
type: "object",
|
|
4928
|
+
properties: {
|
|
4929
|
+
taskId: { type: "string", description: "\u53EF\u9009\uFF1A\u8981\u9886\u53D6\u7684 taskId\uFF08\u6765\u81EA connection_status \u7684 extension.pendingResults\uFF09\uFF1B\u4E0D\u4F20=\u9886\u53D6\u5168\u90E8\u672A\u9886\u53D6\u7ED3\u679C" }
|
|
4930
|
+
},
|
|
4931
|
+
additionalProperties: false
|
|
4932
|
+
}
|
|
4789
4933
|
}
|
|
4790
4934
|
];
|
|
4791
4935
|
async function callTool(name, args) {
|
|
@@ -4886,6 +5030,18 @@ async function callTool(name, args) {
|
|
|
4886
5030
|
3e4
|
|
4887
5031
|
);
|
|
4888
5032
|
}
|
|
5033
|
+
case "leadsradar_claim_pending_result": {
|
|
5034
|
+
const claimTaskId = String(args.taskId || "").trim();
|
|
5035
|
+
return broker.startTask(
|
|
5036
|
+
{
|
|
5037
|
+
mode: "claim_pending_result",
|
|
5038
|
+
...claimTaskId ? { claimTaskId } : { claimAll: true },
|
|
5039
|
+
source: HOST,
|
|
5040
|
+
agentContext: { host: HOST }
|
|
5041
|
+
},
|
|
5042
|
+
3e4
|
|
5043
|
+
);
|
|
5044
|
+
}
|
|
4889
5045
|
default:
|
|
4890
5046
|
return { ok: false, error: { code: "UNKNOWN_TOOL", message: `\u672A\u77E5\u5DE5\u5177 ${name}` } };
|
|
4891
5047
|
}
|
package/package.json
CHANGED
|
@@ -32,7 +32,7 @@ requires:
|
|
|
32
32
|
|
|
33
33
|
1. 调用 `leadsradar_connection_status`
|
|
34
34
|
2. `extension.connected = true` → 直接开工
|
|
35
|
-
3. 未连接 → 按返回的 onboarding
|
|
35
|
+
3. 未连接 → 按返回的 onboarding 指引转述给用户(开插件「智能体连接」开关 / 批准配对),每 8 秒复查一次,最多 12 次;期间不要让用户重复操作
|
|
36
36
|
|
|
37
37
|
## 三、输入分流
|
|
38
38
|
|