hyperclaw 4.0.2 → 5.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 +246 -60
- package/dist/a2ui-protocol-CfBI44-Q.js +75 -0
- package/dist/agents-routing-ChHiZp36.js +327 -0
- package/dist/agents-routing-ChqZ6l2S.js +4 -0
- package/dist/api-keys-guide-BCcOl0Q7.js +149 -0
- package/dist/api-keys-guide-CGn5BSF7.js +149 -0
- package/dist/audit-BJohI_vC.js +441 -0
- package/dist/audit-BaIiyWFu.js +441 -0
- package/dist/bounty-tools-CY_i91DU.js +211 -0
- package/dist/bounty-tools-DWudyZie.js +211 -0
- package/dist/browser-tools-BsTeGMnX.js +5 -0
- package/dist/browser-tools-D8_rLe2p.js +179 -0
- package/dist/claw-tasks-CgTsiNE8.js +80 -0
- package/dist/claw-tasks-Cyzdbhz_.js +80 -0
- package/dist/connector-5N0-X_xs.js +194 -0
- package/dist/connector-B3v0qcXg.js +425 -0
- package/dist/connector-B8R3iBY1.js +280 -0
- package/dist/connector-BAM-08NN.js +189 -0
- package/dist/connector-BC8FIVu4.js +181 -0
- package/dist/connector-BDmwwaVc.js +213 -0
- package/dist/connector-BGjbBy69.js +225 -0
- package/dist/connector-BO2SRzfG.js +218 -0
- package/dist/connector-BfXky0L3.js +167 -0
- package/dist/connector-BiiSJpx3.js +192 -0
- package/dist/connector-BnDmIhIu.js +85 -0
- package/dist/connector-C1HSoUyk.js +189 -0
- package/dist/connector-CKQHZOXg.js +568 -0
- package/dist/connector-CRl-iidy.js +239 -0
- package/dist/connector-Ci9glMD-.js +340 -0
- package/dist/connector-CjtZIEDj.js +181 -0
- package/dist/connector-Ck6JtOsX.js +531 -0
- package/dist/connector-D8Kelee0.js +286 -0
- package/dist/connector-DAnRJ0oP.js +162 -0
- package/dist/connector-DXTp5PE8.js +508 -0
- package/dist/connector-Dih6dUPP.js +173 -0
- package/dist/connector-DqTH_tPX.js +182 -0
- package/dist/connector-DrnEiiyP.js +419 -0
- package/dist/connector-DtR5GGTX.js +167 -0
- package/dist/connector-Tky_qS_K.js +350 -0
- package/dist/connector-ZSc3oTTy.js +305 -0
- package/dist/connector-sW5yhU1m.js +498 -0
- package/dist/connector-u3ICd3Ic.js +552 -0
- package/dist/cost-tracker-Ca1UPZ33.js +103 -0
- package/dist/cost-tracker-DD9wtWsr.js +103 -0
- package/dist/credentials-store-C6ir0Dae.js +4 -0
- package/dist/credentials-store-CA8UtK0T.js +77 -0
- package/dist/credentials-store-Cm7DH-kh.js +4 -0
- package/dist/credentials-store-H13LqOwJ.js +77 -0
- package/dist/cron-tasks-Bli7Kzd2.js +82 -0
- package/dist/cron-tasks-_pqQCmxc.js +82 -0
- package/dist/daemon-7ViroziB.js +5 -0
- package/dist/daemon-BfyKmZhr.js +318 -0
- package/dist/daemon-Bg4GtCmc.js +318 -0
- package/dist/daemon-DhmwY8k4.js +5 -0
- package/dist/delivery-BmIYy9VQ.js +4 -0
- package/dist/delivery-DVHmv1IR.js +4 -0
- package/dist/delivery-DpMX0Yyc.js +95 -0
- package/dist/delivery-pWUPBp1F.js +95 -0
- package/dist/destructive-gate-D6vWOdEl.js +101 -0
- package/dist/destructive-gate-DZt71UZR.js +101 -0
- package/dist/developer-keys-CPWT7Q6S.js +8 -0
- package/dist/developer-keys-DrrcUqFa.js +127 -0
- package/dist/doctor-BvCe8BBk.js +230 -0
- package/dist/doctor-CxyPLYsJ.js +6 -0
- package/dist/engine-B0kLfRL0.js +256 -0
- package/dist/engine-BJUpRUOv.js +7 -0
- package/dist/engine-CEDSqXfw.js +256 -0
- package/dist/engine-Da4JMNpI.js +7 -0
- package/dist/env-resolve-17ekEU6p.js +10 -0
- package/dist/env-resolve-CiXbWYwe.js +10 -0
- package/dist/env-resolve-CmGWhWXJ.js +115 -0
- package/dist/env-resolve-Z2XF6leB.js +115 -0
- package/dist/extraction-tools-HOZstZ0y.js +91 -0
- package/dist/extraction-tools-m4lmAv7l.js +5 -0
- package/dist/form_data-Cz040rio.js +8657 -0
- package/dist/gmail-watch-setup-Du7DVV7S.js +40 -0
- package/dist/health-B-asI__D.js +6 -0
- package/dist/health-Ds2YlpTB.js +152 -0
- package/dist/heartbeat-engine-BYT5ayQH.js +83 -0
- package/dist/heartbeat-engine-Ut6pXBD6.js +83 -0
- package/dist/hub-9LaKnLjY.js +6 -0
- package/dist/hub-CfwUz9YW.js +515 -0
- package/dist/hub-D0XwdjM-.js +515 -0
- package/dist/hub-LiD5Iztb.js +6 -0
- package/dist/hyperclawbot-CBiDSKsa.js +505 -0
- package/dist/hyperclawbot-zvczQgKx.js +505 -0
- package/dist/inference-0mlFQqIm.js +922 -0
- package/dist/inference-BKVkBREb.js +6 -0
- package/dist/inference-DCXH4Q3x.js +922 -0
- package/dist/inference-SzqFe_nk.js +6 -0
- package/dist/knowledge-graph-DE5lSF02.js +131 -0
- package/dist/knowledge-graph-iBG76fvm.js +131 -0
- package/dist/loader-BkDi8MD9.js +400 -0
- package/dist/loader-CC45xGpC.js +4 -0
- package/dist/loader-CnEdOyjT.js +400 -0
- package/dist/loader-DI2qDRPC.js +4 -0
- package/dist/logger-Cp8wC7F8.js +83 -0
- package/dist/logger-ybOp7VOC.js +83 -0
- package/dist/manager-03ipO9R0.js +105 -0
- package/dist/manager-B2Gls5RG.js +218 -0
- package/dist/manager-BpDfbDjg.js +117 -0
- package/dist/manager-Bxl0sqlh.js +4 -0
- package/dist/manager-CWNSML5D.js +117 -0
- package/dist/manager-CrVDn6eN.js +6 -0
- package/dist/manager-FCgF1plu.js +218 -0
- package/dist/manager-SJe9gt-q.js +4 -0
- package/dist/manager-rgCsaWT1.js +40 -0
- package/dist/mcp-CfoSU4Uz.js +139 -0
- package/dist/mcp-loader-CvxRDtPC.js +94 -0
- package/dist/mcp-loader-DkRBsLpk.js +94 -0
- package/dist/memory-BlHL7JCO.js +4 -0
- package/dist/memory-DsS_eFvJ.js +270 -0
- package/dist/memory-auto-BkvtSFUw.js +5 -0
- package/dist/memory-auto-Bnz_-1wP.js +306 -0
- package/dist/memory-auto-CpQHZlEJ.js +306 -0
- package/dist/memory-auto-Z6LCf-iK.js +5 -0
- package/dist/memory-integration-cSYkZyEo.js +91 -0
- package/dist/memory-integration-g2vxwgoE.js +91 -0
- package/dist/moltbook-BtLDZTfM.js +81 -0
- package/dist/moltbook-Cl8cQfxJ.js +81 -0
- package/dist/node-Dw2Gi-cP.js +222 -0
- package/dist/nodes-registry-B8dmrlLv.js +52 -0
- package/dist/nodes-registry-C9dCFwjh.js +52 -0
- package/dist/oauth-flow-CeaaGAz0.js +150 -0
- package/dist/oauth-flow-DQPvMHRH.js +150 -0
- package/dist/oauth-provider-B4dzn56l.js +110 -0
- package/dist/oauth-provider-Uo4Nib_c.js +110 -0
- package/dist/observability-BV-Yx0V9.js +89 -0
- package/dist/observability-nZ3CBIxG.js +89 -0
- package/dist/onboard-0WoDxbv_.js +10 -0
- package/dist/onboard-BBBWcfhp.js +10 -0
- package/dist/onboard-BXNXCQp4.js +4070 -0
- package/dist/onboard-Bw28IRQ3.js +4070 -0
- package/dist/orchestrator-BovkM63z.js +6 -0
- package/dist/orchestrator-DSbpkP1X.js +189 -0
- package/dist/orchestrator-DmnEvMaL.js +189 -0
- package/dist/orchestrator-RI3bpqqc.js +6 -0
- package/dist/osint-B4_m3VHQ.js +277 -0
- package/dist/pairing-6iM27aD8.js +196 -0
- package/dist/pairing-dGoiGepK.js +4 -0
- package/dist/pc-access-CgCsYrpt.js +8 -0
- package/dist/pc-access-_iH2aorG.js +819 -0
- package/dist/pending-approval-BgNjjuI2.js +22 -0
- package/dist/pending-approval-CUXjysAo.js +22 -0
- package/dist/reminders-store-Drjed_-h.js +58 -0
- package/dist/renderer-BVQrd0_g.js +225 -0
- package/dist/rules-BE4GV6cV.js +103 -0
- package/dist/run-main.js +1639 -460
- package/dist/runner-CJFJUtPm.js +1271 -0
- package/dist/runner-DatMMYYE.js +1271 -0
- package/dist/sdk/index.js +2 -2
- package/dist/sdk/index.mjs +2 -2
- package/dist/security-BqNyT4ID.js +4 -0
- package/dist/security-tpgqPWWH.js +73 -0
- package/dist/server-Brl_HQUB.js +1255 -0
- package/dist/server-D4wVHiX9.js +4 -0
- package/dist/server-Dh3JlBFB.js +1255 -0
- package/dist/server-DhfipkwN.js +4 -0
- package/dist/session-store-BUiPz0Vv.js +5 -0
- package/dist/session-store-is4B6qmD.js +113 -0
- package/dist/sessions-tools-CbUTFe4i.js +5 -0
- package/dist/sessions-tools-CeqD7iil.js +95 -0
- package/dist/skill-loader-BaNLVmJy.js +7 -0
- package/dist/skill-loader-HgpF6Vqs.js +159 -0
- package/dist/skill-runtime-BXWd-Ktf.js +102 -0
- package/dist/skill-runtime-CJN24QPW.js +102 -0
- package/dist/skill-runtime-jgklm02e.js +5 -0
- package/dist/skill-runtime-w1ig_lcw.js +5 -0
- package/dist/src-Bhybpk1J.js +63 -0
- package/dist/src-BxPHKO5x.js +63 -0
- package/dist/src-DIc-L2IG.js +20 -0
- package/dist/src-DMJ4-uqk.js +458 -0
- package/dist/src-g_rNx5rh.js +458 -0
- package/dist/sub-agent-tools-CHQoHz9c.js +39 -0
- package/dist/sub-agent-tools-DHY-4WWM.js +39 -0
- package/dist/theme-DcxwcUgZ.js +180 -0
- package/dist/theme-cx0fkgWC.js +8 -0
- package/dist/tool-policy-CNT-mF2Z.js +189 -0
- package/dist/tool-policy-DZvF8xlQ.js +189 -0
- package/dist/tts-elevenlabs-BRosZv-f.js +61 -0
- package/dist/tts-elevenlabs-C06nUxMK.js +61 -0
- package/dist/update-check-C2Dz85wJ.js +81 -0
- package/dist/update-check-w4XuxVl7.js +81 -0
- package/dist/vision-BMmiIKy7.js +121 -0
- package/dist/vision-JOtOS1Br.js +121 -0
- package/dist/vision-tools-CB28ZCO_.js +5 -0
- package/dist/vision-tools-DVuYc17I.js +51 -0
- package/dist/vision-tools-U3YC4L-g.js +5 -0
- package/dist/vision-tools-vPPwQ-0N.js +51 -0
- package/dist/voice-transcription-B555DbWR.js +138 -0
- package/dist/voice-transcription-DBo5hXmu.js +138 -0
- package/dist/website-watch-tools-DFMrJU-R.js +139 -0
- package/dist/website-watch-tools-Du3W5sN7.js +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-jS-bbMI5.js');
|
|
2
|
+
const chalk = require_chunk.__toESM(require("chalk"));
|
|
3
|
+
const inquirer = require_chunk.__toESM(require("inquirer"));
|
|
4
|
+
const fs_extra = require_chunk.__toESM(require("fs-extra"));
|
|
5
|
+
const path = require_chunk.__toESM(require("path"));
|
|
6
|
+
const os = require_chunk.__toESM(require("os"));
|
|
7
|
+
|
|
8
|
+
//#region src/routing/session-key.ts
|
|
9
|
+
/**
|
|
10
|
+
|
|
11
|
+
* Compute the canonical session key for an inbound message context.
|
|
12
|
+
|
|
13
|
+
*/
|
|
14
|
+
function computeSessionKey(ctx) {
|
|
15
|
+
const { agentId, channel, peerKind, peerId, threadId, topicId, dmScope } = ctx;
|
|
16
|
+
if (peerKind === "dm") {
|
|
17
|
+
if (dmScope === "main" || dmScope === void 0) return `agent:${agentId}:main`;
|
|
18
|
+
return `agent:${agentId}:${channel}:dm:${peerId}`;
|
|
19
|
+
}
|
|
20
|
+
if (peerKind === "group") {
|
|
21
|
+
let key$1 = `agent:${agentId}:${channel}:group:${peerId}`;
|
|
22
|
+
if (topicId) key$1 += `:topic:${topicId}`;
|
|
23
|
+
if (threadId) key$1 += `:thread:${threadId}`;
|
|
24
|
+
return key$1;
|
|
25
|
+
}
|
|
26
|
+
let key = `agent:${agentId}:${channel}:channel:${peerId}`;
|
|
27
|
+
if (threadId) key += `:thread:${threadId}`;
|
|
28
|
+
return key;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/routing/agents-routing.ts
|
|
33
|
+
const STATE_FILE = path.default.join(os.default.homedir(), ".hyperclaw", "routing.json");
|
|
34
|
+
const DEFAULT_AGENT = {
|
|
35
|
+
id: "main",
|
|
36
|
+
name: "main",
|
|
37
|
+
workspace: path.default.join(os.default.homedir(), ".hyperclaw", "workspace"),
|
|
38
|
+
default: true
|
|
39
|
+
};
|
|
40
|
+
var AgentRouter = class {
|
|
41
|
+
config;
|
|
42
|
+
constructor(config) {
|
|
43
|
+
this.config = config ?? this._loadConfig();
|
|
44
|
+
}
|
|
45
|
+
_loadConfig() {
|
|
46
|
+
try {
|
|
47
|
+
return fs_extra.default.readJsonSync(STATE_FILE);
|
|
48
|
+
} catch {
|
|
49
|
+
return {
|
|
50
|
+
agents: { list: [DEFAULT_AGENT] },
|
|
51
|
+
bindings: [],
|
|
52
|
+
session: { dmScope: "main" }
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
_saveConfig() {
|
|
57
|
+
fs_extra.default.ensureDirSync(path.default.dirname(STATE_FILE));
|
|
58
|
+
fs_extra.default.writeJsonSync(STATE_FILE, this.config, { spaces: 2 });
|
|
59
|
+
}
|
|
60
|
+
route(msg) {
|
|
61
|
+
const agents = this.config.agents?.list ?? [DEFAULT_AGENT];
|
|
62
|
+
const bindings = this.config.bindings ?? [];
|
|
63
|
+
const broadcastAgents = this._resolveBroadcast(msg);
|
|
64
|
+
const matched = this._matchBinding(msg, bindings, agents);
|
|
65
|
+
const agentDef = matched.agentDef;
|
|
66
|
+
const sessionKey = this._computeKey(msg, agentDef.id);
|
|
67
|
+
const skipLastRoute = msg.isDM ? this._shouldSkipLastRoute(msg) : false;
|
|
68
|
+
return {
|
|
69
|
+
agentId: agentDef.id,
|
|
70
|
+
agentDef,
|
|
71
|
+
sessionKey,
|
|
72
|
+
matchedBy: matched.matchedBy,
|
|
73
|
+
...broadcastAgents.length > 1 ? { broadcast: broadcastAgents } : {},
|
|
74
|
+
...skipLastRoute ? { skipLastRoute: true } : {}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
_matchBinding(msg, bindings, agents) {
|
|
78
|
+
const find = (id) => agents.find((a) => a.id === id) ?? DEFAULT_AGENT;
|
|
79
|
+
for (const b of bindings) {
|
|
80
|
+
if (!this._matchesFilter(msg, b.match)) continue;
|
|
81
|
+
return {
|
|
82
|
+
agentDef: find(b.agentId),
|
|
83
|
+
matchedBy: this._describeMatch(b.match)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const defaultAgent = agents.find((a) => a.default) ?? agents[0] ?? DEFAULT_AGENT;
|
|
87
|
+
return {
|
|
88
|
+
agentDef: defaultAgent,
|
|
89
|
+
matchedBy: "default"
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
_matchesFilter(msg, match) {
|
|
93
|
+
if (match.channel && match.channel !== msg.channel) return false;
|
|
94
|
+
if (match.accountId && match.accountId !== "*" && match.accountId !== msg.accountId) return false;
|
|
95
|
+
if (match.peer) {
|
|
96
|
+
if (match.peer.kind !== msg.peer.kind) return false;
|
|
97
|
+
if (match.peer.id !== msg.peer.id) return false;
|
|
98
|
+
}
|
|
99
|
+
if (match.guildId && match.guildId !== msg.guildId) return false;
|
|
100
|
+
if (match.roles?.length) {
|
|
101
|
+
const senderRoles = msg.roles ?? [];
|
|
102
|
+
if (!match.roles.every((r) => senderRoles.includes(r))) return false;
|
|
103
|
+
}
|
|
104
|
+
if (match.teamId && match.teamId !== msg.teamId) return false;
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
_describeMatch(m) {
|
|
108
|
+
const parts = [];
|
|
109
|
+
if (m.channel) parts.push(`channel=${m.channel}`);
|
|
110
|
+
if (m.peer) parts.push(`peer=${m.peer.kind}:${m.peer.id}`);
|
|
111
|
+
if (m.guildId) parts.push(`guild=${m.guildId}`);
|
|
112
|
+
if (m.teamId) parts.push(`team=${m.teamId}`);
|
|
113
|
+
if (m.accountId) parts.push(`account=${m.accountId}`);
|
|
114
|
+
return parts.join(" ") || "channel-match";
|
|
115
|
+
}
|
|
116
|
+
_computeKey(msg, agentId) {
|
|
117
|
+
const dmScope = this.config.session?.dmScope ?? "main";
|
|
118
|
+
const ctx = {
|
|
119
|
+
agentId,
|
|
120
|
+
channel: msg.channel,
|
|
121
|
+
peerKind: msg.isDM ? "dm" : msg.peer.kind,
|
|
122
|
+
peerId: msg.peer.id,
|
|
123
|
+
threadId: msg.threadId,
|
|
124
|
+
topicId: msg.topicId,
|
|
125
|
+
dmScope: msg.isDM ? dmScope : void 0
|
|
126
|
+
};
|
|
127
|
+
return computeSessionKey(ctx);
|
|
128
|
+
}
|
|
129
|
+
_resolveBroadcast(msg) {
|
|
130
|
+
const bc = this.config.broadcast;
|
|
131
|
+
if (!bc) return [];
|
|
132
|
+
const agentIds = bc[msg.peer.id] ?? bc[msg.senderId];
|
|
133
|
+
if (Array.isArray(agentIds)) return agentIds;
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Returns true when the inbound DM sender is not the pinned owner.
|
|
138
|
+
* Pinned owner = the single non-wildcard allowFrom entry for this channel.
|
|
139
|
+
*/
|
|
140
|
+
_shouldSkipLastRoute(msg) {
|
|
141
|
+
const chanCfg = this.config.channels?.[msg.channel];
|
|
142
|
+
if (!chanCfg?.allowFrom) return false;
|
|
143
|
+
const nonWild = chanCfg.allowFrom.filter((id) => id !== "*" && id !== "**");
|
|
144
|
+
if (nonWild.length !== 1) return false;
|
|
145
|
+
const pinnedOwner = nonWild[0];
|
|
146
|
+
return msg.senderId !== pinnedOwner;
|
|
147
|
+
}
|
|
148
|
+
resolveDefaultAccount(channelId) {
|
|
149
|
+
return this.config.channels?.[channelId]?.defaultAccount;
|
|
150
|
+
}
|
|
151
|
+
listBindings() {
|
|
152
|
+
const agents = this.config.agents?.list ?? [];
|
|
153
|
+
const bindings = this.config.bindings ?? [];
|
|
154
|
+
console.log(chalk.default.bold.cyan("\n 🦅 AGENT BINDINGS\n"));
|
|
155
|
+
if (agents.length === 0) {
|
|
156
|
+
console.log(chalk.default.gray(" No agents configured.\n"));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
for (const a of agents) {
|
|
160
|
+
const def = a.default ? chalk.default.green(" [default]") : "";
|
|
161
|
+
const model = a.model ? chalk.default.gray(` model:${a.model}`) : "";
|
|
162
|
+
console.log(` ${chalk.default.bold(a.id)}${def} ${chalk.default.gray(a.workspace)}${model}`);
|
|
163
|
+
}
|
|
164
|
+
console.log();
|
|
165
|
+
if (bindings.length === 0) {
|
|
166
|
+
console.log(chalk.default.gray(" No explicit bindings — all traffic → default agent.\n"));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
console.log(chalk.default.bold(" Bindings:\n"));
|
|
170
|
+
for (const b of bindings) {
|
|
171
|
+
const m = b.match;
|
|
172
|
+
const parts = [];
|
|
173
|
+
if (m.channel) parts.push(chalk.default.cyan(m.channel));
|
|
174
|
+
if (m.peer) parts.push(`peer:${m.peer.kind}/${chalk.default.white(m.peer.id)}`);
|
|
175
|
+
if (m.guildId) parts.push(`guild:${chalk.default.white(m.guildId)}`);
|
|
176
|
+
if (m.teamId) parts.push(`team:${chalk.default.white(m.teamId)}`);
|
|
177
|
+
if (m.roles?.length) parts.push(`roles:[${m.roles.join(",")}]`);
|
|
178
|
+
if (m.accountId) parts.push(`account:${m.accountId}`);
|
|
179
|
+
console.log(` ${parts.join(" ")} ${chalk.default.gray("→")} ${chalk.default.bold(b.agentId)}`);
|
|
180
|
+
}
|
|
181
|
+
const bc = this.config.broadcast;
|
|
182
|
+
if (bc) {
|
|
183
|
+
console.log(chalk.default.bold("\n Broadcast groups:\n"));
|
|
184
|
+
const strat = bc.strategy ?? "parallel";
|
|
185
|
+
for (const [peerId, agents$1] of Object.entries(bc)) {
|
|
186
|
+
if (peerId === "strategy") continue;
|
|
187
|
+
if (Array.isArray(agents$1)) console.log(` ${chalk.default.white(peerId)} ${chalk.default.gray(`→ [${agents$1.join(", ")}]`)} ${chalk.default.gray(`(${strat})`)}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
console.log();
|
|
191
|
+
}
|
|
192
|
+
async bind() {
|
|
193
|
+
console.log(chalk.default.cyan("\n Bind a channel/peer to an agent\n"));
|
|
194
|
+
const { channel, matchType } = await inquirer.default.prompt([{
|
|
195
|
+
type: "input",
|
|
196
|
+
name: "channel",
|
|
197
|
+
message: "Channel ID (e.g. telegram, discord, slack, whatsapp):",
|
|
198
|
+
validate: (v) => v.trim().length > 0 || "Required"
|
|
199
|
+
}, {
|
|
200
|
+
type: "list",
|
|
201
|
+
name: "matchType",
|
|
202
|
+
message: "Match by:",
|
|
203
|
+
choices: [
|
|
204
|
+
{
|
|
205
|
+
name: "Any message on this channel",
|
|
206
|
+
value: "channel"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
name: "Specific peer (group ID, user ID, channel ID)",
|
|
210
|
+
value: "peer"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
name: "Discord guild",
|
|
214
|
+
value: "guild"
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
name: "Slack team",
|
|
218
|
+
value: "team"
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
name: "Account ID",
|
|
222
|
+
value: "account"
|
|
223
|
+
}
|
|
224
|
+
]
|
|
225
|
+
}]);
|
|
226
|
+
const match = { channel };
|
|
227
|
+
if (matchType === "peer") {
|
|
228
|
+
const { kind, peerId } = await inquirer.default.prompt([{
|
|
229
|
+
type: "list",
|
|
230
|
+
name: "kind",
|
|
231
|
+
message: "Peer type:",
|
|
232
|
+
choices: [
|
|
233
|
+
"group",
|
|
234
|
+
"channel",
|
|
235
|
+
"dm",
|
|
236
|
+
"room"
|
|
237
|
+
]
|
|
238
|
+
}, {
|
|
239
|
+
type: "input",
|
|
240
|
+
name: "peerId",
|
|
241
|
+
message: "Peer ID:",
|
|
242
|
+
validate: (v) => v.trim().length > 0 || "Required"
|
|
243
|
+
}]);
|
|
244
|
+
match.peer = {
|
|
245
|
+
kind,
|
|
246
|
+
id: peerId
|
|
247
|
+
};
|
|
248
|
+
} else if (matchType === "guild") {
|
|
249
|
+
const { guildId } = await inquirer.default.prompt([{
|
|
250
|
+
type: "input",
|
|
251
|
+
name: "guildId",
|
|
252
|
+
message: "Discord guild ID:",
|
|
253
|
+
validate: (v) => v.trim().length > 0 || "Required"
|
|
254
|
+
}]);
|
|
255
|
+
match.guildId = guildId;
|
|
256
|
+
} else if (matchType === "team") {
|
|
257
|
+
const { teamId } = await inquirer.default.prompt([{
|
|
258
|
+
type: "input",
|
|
259
|
+
name: "teamId",
|
|
260
|
+
message: "Slack team ID:",
|
|
261
|
+
validate: (v) => v.trim().length > 0 || "Required"
|
|
262
|
+
}]);
|
|
263
|
+
match.teamId = teamId;
|
|
264
|
+
} else if (matchType === "account") {
|
|
265
|
+
const { accountId } = await inquirer.default.prompt([{
|
|
266
|
+
type: "input",
|
|
267
|
+
name: "accountId",
|
|
268
|
+
message: "Account ID:",
|
|
269
|
+
validate: (v) => v.trim().length > 0 || "Required"
|
|
270
|
+
}]);
|
|
271
|
+
match.accountId = accountId;
|
|
272
|
+
}
|
|
273
|
+
const agentIds = (this.config.agents?.list ?? []).map((a) => a.id);
|
|
274
|
+
const { agentId } = await inquirer.default.prompt([{
|
|
275
|
+
type: agentIds.length > 1 ? "list" : "input",
|
|
276
|
+
name: "agentId",
|
|
277
|
+
message: "Route to agent ID:",
|
|
278
|
+
choices: agentIds.length > 1 ? agentIds : void 0,
|
|
279
|
+
default: agentIds[0] ?? "main"
|
|
280
|
+
}]);
|
|
281
|
+
if (!this.config.bindings) this.config.bindings = [];
|
|
282
|
+
this.config.bindings.unshift({
|
|
283
|
+
match,
|
|
284
|
+
agentId,
|
|
285
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
286
|
+
});
|
|
287
|
+
this._saveConfig();
|
|
288
|
+
console.log(chalk.default.green(`\n ✔ Binding added: ${channel}/${matchType} → ${agentId}\n`));
|
|
289
|
+
}
|
|
290
|
+
async unbind() {
|
|
291
|
+
const bindings = this.config.bindings ?? [];
|
|
292
|
+
if (bindings.length === 0) {
|
|
293
|
+
console.log(chalk.default.gray("\n No bindings to remove.\n"));
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
const { toRemove } = await inquirer.default.prompt([{
|
|
297
|
+
type: "checkbox",
|
|
298
|
+
name: "toRemove",
|
|
299
|
+
message: "Select bindings to remove:",
|
|
300
|
+
choices: bindings.map((b, i) => ({
|
|
301
|
+
name: `${this._describeMatch(b.match)} → ${b.agentId}`,
|
|
302
|
+
value: i
|
|
303
|
+
}))
|
|
304
|
+
}]);
|
|
305
|
+
for (const idx of toRemove.sort((a, b) => b - a)) bindings.splice(idx, 1);
|
|
306
|
+
this.config.bindings = bindings;
|
|
307
|
+
this._saveConfig();
|
|
308
|
+
console.log(chalk.default.green(`\n ✔ Removed ${toRemove.length} binding(s)\n`));
|
|
309
|
+
}
|
|
310
|
+
getConfig() {
|
|
311
|
+
return this.config;
|
|
312
|
+
}
|
|
313
|
+
getAgents() {
|
|
314
|
+
return this.config.agents?.list ?? [DEFAULT_AGENT];
|
|
315
|
+
}
|
|
316
|
+
getBindings() {
|
|
317
|
+
return this.config.bindings ?? [];
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
//#endregion
|
|
322
|
+
Object.defineProperty(exports, 'AgentRouter', {
|
|
323
|
+
enumerable: true,
|
|
324
|
+
get: function () {
|
|
325
|
+
return AgentRouter;
|
|
326
|
+
}
|
|
327
|
+
});
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-jS-bbMI5.js');
|
|
2
|
+
|
|
3
|
+
//#region src/infra/api-keys-guide.ts
|
|
4
|
+
const API_KEYS_GUIDE = [
|
|
5
|
+
{
|
|
6
|
+
serviceId: "anthropic",
|
|
7
|
+
name: "Anthropic (Claude)",
|
|
8
|
+
envVar: "ANTHROPIC_API_KEY",
|
|
9
|
+
url: "platform.anthropic.com",
|
|
10
|
+
setupSteps: [
|
|
11
|
+
"1. Go to platform.anthropic.com → API Keys.",
|
|
12
|
+
"2. Sign up / sign in with an Anthropic account.",
|
|
13
|
+
"3. Create Key — copy it (starts with sk-ant-). Not shown again!",
|
|
14
|
+
"",
|
|
15
|
+
" 🔗 platform.anthropic.com/settings/keys"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
serviceId: "openai",
|
|
20
|
+
name: "OpenAI (GPT)",
|
|
21
|
+
envVar: "OPENAI_API_KEY",
|
|
22
|
+
url: "platform.openai.com",
|
|
23
|
+
setupSteps: [
|
|
24
|
+
"1. Go to platform.openai.com → API keys.",
|
|
25
|
+
"2. Create new secret key — copy it (starts with sk-). Not shown again!",
|
|
26
|
+
"3. You need billing enabled for production use.",
|
|
27
|
+
"",
|
|
28
|
+
" 🔗 platform.openai.com/api-keys"
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
serviceId: "openrouter",
|
|
33
|
+
name: "OpenRouter",
|
|
34
|
+
envVar: "OPENROUTER_API_KEY",
|
|
35
|
+
url: "openrouter.ai",
|
|
36
|
+
setupSteps: [
|
|
37
|
+
"1. Go to openrouter.ai → Keys.",
|
|
38
|
+
"2. Sign in (Google/GitHub).",
|
|
39
|
+
"3. Create Key — copy it. OpenRouter provides access to many models (Claude, GPT etc.).",
|
|
40
|
+
"",
|
|
41
|
+
" 🔗 openrouter.ai/keys"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
serviceId: "tavily",
|
|
46
|
+
name: "Tavily (Web Search)",
|
|
47
|
+
envVar: "TAVILY_API_KEY",
|
|
48
|
+
url: "tavily.com",
|
|
49
|
+
setupSteps: [
|
|
50
|
+
"1. Go to tavily.com → Sign up.",
|
|
51
|
+
"2. Dashboard → API Keys → Create API Key.",
|
|
52
|
+
"3. Copy the key. Used for the web-search skill.",
|
|
53
|
+
"",
|
|
54
|
+
" 🔗 app.tavily.com"
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
serviceId: "elevenlabs",
|
|
59
|
+
name: "ElevenLabs (TTS)",
|
|
60
|
+
envVar: "ELEVENLABS_API_KEY",
|
|
61
|
+
url: "elevenlabs.io",
|
|
62
|
+
setupSteps: [
|
|
63
|
+
"1. Go to elevenlabs.io → Profile → API Key.",
|
|
64
|
+
"2. Copy the API key (or create a new one).",
|
|
65
|
+
"3. Used for talk mode (voice responses).",
|
|
66
|
+
"",
|
|
67
|
+
" 🔗 elevenlabs.io/app/settings/api-keys"
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
serviceId: "deepl",
|
|
72
|
+
name: "DeepL (Translation)",
|
|
73
|
+
envVar: "DEEPL_API_KEY",
|
|
74
|
+
url: "deepl.com",
|
|
75
|
+
setupSteps: [
|
|
76
|
+
"1. Go to deepl.com/pro-api → Get API key.",
|
|
77
|
+
"2. Sign up (free tier available).",
|
|
78
|
+
"3. Account → API keys — copy the Authentication Key.",
|
|
79
|
+
"",
|
|
80
|
+
" 🔗 deepl.com/pro-api"
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
serviceId: "github",
|
|
85
|
+
name: "GitHub (PAT)",
|
|
86
|
+
envVar: "GITHUB_TOKEN",
|
|
87
|
+
url: "github.com",
|
|
88
|
+
setupSteps: [
|
|
89
|
+
"1. GitHub → Settings → Developer settings → Personal access tokens.",
|
|
90
|
+
"2. Generate new token (classic or fine-grained).",
|
|
91
|
+
"3. Select scopes: repo, read:user etc. depending on use case.",
|
|
92
|
+
"",
|
|
93
|
+
" 🔗 github.com/settings/tokens"
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
serviceId: "xai",
|
|
98
|
+
name: "xAI (Grok)",
|
|
99
|
+
envVar: "XAI_API_KEY",
|
|
100
|
+
url: "x.ai",
|
|
101
|
+
setupSteps: [
|
|
102
|
+
"1. Go to console.x.ai → API keys.",
|
|
103
|
+
"2. Sign in and create a new key.",
|
|
104
|
+
"3. Copy the key.",
|
|
105
|
+
"",
|
|
106
|
+
" 🔗 console.x.ai"
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
serviceId: "google",
|
|
111
|
+
name: "Google AI (Gemini)",
|
|
112
|
+
envVar: "GOOGLE_AI_API_KEY",
|
|
113
|
+
url: "ai.google.dev",
|
|
114
|
+
setupSteps: [
|
|
115
|
+
"1. Go to aistudio.google.com/apikey.",
|
|
116
|
+
"2. Get API key or Create API key.",
|
|
117
|
+
"3. Copy the key.",
|
|
118
|
+
"",
|
|
119
|
+
" 🔗 aistudio.google.com/apikey"
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
];
|
|
123
|
+
const SERVICE_ID_MAP = new Map(API_KEYS_GUIDE.map((g) => [g.serviceId.toLowerCase(), g]));
|
|
124
|
+
/** Known name aliases (e.g. anthropic, claude -> anthropic) */
|
|
125
|
+
const ALIASES = {
|
|
126
|
+
claude: "anthropic",
|
|
127
|
+
gpt: "openai",
|
|
128
|
+
xai: "xai",
|
|
129
|
+
google: "google"
|
|
130
|
+
};
|
|
131
|
+
function getApiKeyGuide(serviceId) {
|
|
132
|
+
const id = serviceId.toLowerCase().replace(/[^a-z0-9-]/g, "");
|
|
133
|
+
return SERVICE_ID_MAP.get(id) ?? SERVICE_ID_MAP.get(ALIASES[id] ?? "") ?? null;
|
|
134
|
+
}
|
|
135
|
+
/** For unknown services — generic API key instructions */
|
|
136
|
+
const GENERIC_API_KEY_STEPS = [
|
|
137
|
+
"For an unknown service:",
|
|
138
|
+
"1. Go to the official service website (e.g. developers.xxx.com).",
|
|
139
|
+
"2. Sign up / sign in. An account is usually required.",
|
|
140
|
+
"3. Look for \"API Keys\", \"Credentials\", \"Developer\" or \"Integrations\" section.",
|
|
141
|
+
"4. Create a new API key or token. Copy it immediately — many services do not show it again.",
|
|
142
|
+
"5. Keep it secret — do not share it or commit it to a repo.",
|
|
143
|
+
"",
|
|
144
|
+
" 💡 Known services: anthropic, openai, openrouter, tavily, elevenlabs, deepl, github, xai, google"
|
|
145
|
+
];
|
|
146
|
+
|
|
147
|
+
//#endregion
|
|
148
|
+
exports.GENERIC_API_KEY_STEPS = GENERIC_API_KEY_STEPS;
|
|
149
|
+
exports.getApiKeyGuide = getApiKeyGuide;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-jS-bbMI5.js');
|
|
2
|
+
|
|
3
|
+
//#region src/infra/api-keys-guide.ts
|
|
4
|
+
const API_KEYS_GUIDE = [
|
|
5
|
+
{
|
|
6
|
+
serviceId: "anthropic",
|
|
7
|
+
name: "Anthropic (Claude)",
|
|
8
|
+
envVar: "ANTHROPIC_API_KEY",
|
|
9
|
+
url: "platform.anthropic.com",
|
|
10
|
+
setupSteps: [
|
|
11
|
+
"1. Go to platform.anthropic.com → API Keys.",
|
|
12
|
+
"2. Sign up / sign in with an Anthropic account.",
|
|
13
|
+
"3. Create Key — copy it (starts with sk-ant-). Not shown again!",
|
|
14
|
+
"",
|
|
15
|
+
" 🔗 platform.anthropic.com/settings/keys"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
serviceId: "openai",
|
|
20
|
+
name: "OpenAI (GPT)",
|
|
21
|
+
envVar: "OPENAI_API_KEY",
|
|
22
|
+
url: "platform.openai.com",
|
|
23
|
+
setupSteps: [
|
|
24
|
+
"1. Go to platform.openai.com → API keys.",
|
|
25
|
+
"2. Create new secret key — copy it (starts with sk-). Not shown again!",
|
|
26
|
+
"3. You need billing enabled for production use.",
|
|
27
|
+
"",
|
|
28
|
+
" 🔗 platform.openai.com/api-keys"
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
serviceId: "openrouter",
|
|
33
|
+
name: "OpenRouter",
|
|
34
|
+
envVar: "OPENROUTER_API_KEY",
|
|
35
|
+
url: "openrouter.ai",
|
|
36
|
+
setupSteps: [
|
|
37
|
+
"1. Go to openrouter.ai → Keys.",
|
|
38
|
+
"2. Sign in (Google/GitHub).",
|
|
39
|
+
"3. Create Key — copy it. OpenRouter provides access to many models (Claude, GPT etc.).",
|
|
40
|
+
"",
|
|
41
|
+
" 🔗 openrouter.ai/keys"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
serviceId: "tavily",
|
|
46
|
+
name: "Tavily (Web Search)",
|
|
47
|
+
envVar: "TAVILY_API_KEY",
|
|
48
|
+
url: "tavily.com",
|
|
49
|
+
setupSteps: [
|
|
50
|
+
"1. Go to tavily.com → Sign up.",
|
|
51
|
+
"2. Dashboard → API Keys → Create API Key.",
|
|
52
|
+
"3. Copy the key. Used for the web-search skill.",
|
|
53
|
+
"",
|
|
54
|
+
" 🔗 app.tavily.com"
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
serviceId: "elevenlabs",
|
|
59
|
+
name: "ElevenLabs (TTS)",
|
|
60
|
+
envVar: "ELEVENLABS_API_KEY",
|
|
61
|
+
url: "elevenlabs.io",
|
|
62
|
+
setupSteps: [
|
|
63
|
+
"1. Go to elevenlabs.io → Profile → API Key.",
|
|
64
|
+
"2. Copy the API key (or create a new one).",
|
|
65
|
+
"3. Used for talk mode (voice responses).",
|
|
66
|
+
"",
|
|
67
|
+
" 🔗 elevenlabs.io/app/settings/api-keys"
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
serviceId: "deepl",
|
|
72
|
+
name: "DeepL (Translation)",
|
|
73
|
+
envVar: "DEEPL_API_KEY",
|
|
74
|
+
url: "deepl.com",
|
|
75
|
+
setupSteps: [
|
|
76
|
+
"1. Go to deepl.com/pro-api → Get API key.",
|
|
77
|
+
"2. Sign up (free tier available).",
|
|
78
|
+
"3. Account → API keys — copy the Authentication Key.",
|
|
79
|
+
"",
|
|
80
|
+
" 🔗 deepl.com/pro-api"
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
serviceId: "github",
|
|
85
|
+
name: "GitHub (PAT)",
|
|
86
|
+
envVar: "GITHUB_TOKEN",
|
|
87
|
+
url: "github.com",
|
|
88
|
+
setupSteps: [
|
|
89
|
+
"1. GitHub → Settings → Developer settings → Personal access tokens.",
|
|
90
|
+
"2. Generate new token (classic or fine-grained).",
|
|
91
|
+
"3. Select scopes: repo, read:user etc. depending on use case.",
|
|
92
|
+
"",
|
|
93
|
+
" 🔗 github.com/settings/tokens"
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
serviceId: "xai",
|
|
98
|
+
name: "xAI (Grok)",
|
|
99
|
+
envVar: "XAI_API_KEY",
|
|
100
|
+
url: "x.ai",
|
|
101
|
+
setupSteps: [
|
|
102
|
+
"1. Go to console.x.ai → API keys.",
|
|
103
|
+
"2. Sign in and create a new key.",
|
|
104
|
+
"3. Copy the key.",
|
|
105
|
+
"",
|
|
106
|
+
" 🔗 console.x.ai"
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
serviceId: "google",
|
|
111
|
+
name: "Google AI (Gemini)",
|
|
112
|
+
envVar: "GOOGLE_AI_API_KEY",
|
|
113
|
+
url: "ai.google.dev",
|
|
114
|
+
setupSteps: [
|
|
115
|
+
"1. Go to aistudio.google.com/apikey.",
|
|
116
|
+
"2. Get API key or Create API key.",
|
|
117
|
+
"3. Copy the key.",
|
|
118
|
+
"",
|
|
119
|
+
" 🔗 aistudio.google.com/apikey"
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
];
|
|
123
|
+
const SERVICE_ID_MAP = new Map(API_KEYS_GUIDE.map((g) => [g.serviceId.toLowerCase(), g]));
|
|
124
|
+
/** Known name aliases (e.g. anthropic, claude -> anthropic) */
|
|
125
|
+
const ALIASES = {
|
|
126
|
+
claude: "anthropic",
|
|
127
|
+
gpt: "openai",
|
|
128
|
+
xai: "xai",
|
|
129
|
+
google: "google"
|
|
130
|
+
};
|
|
131
|
+
function getApiKeyGuide(serviceId) {
|
|
132
|
+
const id = serviceId.toLowerCase().replace(/[^a-z0-9-]/g, "");
|
|
133
|
+
return SERVICE_ID_MAP.get(id) ?? SERVICE_ID_MAP.get(ALIASES[id] ?? "") ?? null;
|
|
134
|
+
}
|
|
135
|
+
/** For unknown services — generic API key instructions */
|
|
136
|
+
const GENERIC_API_KEY_STEPS = [
|
|
137
|
+
"For an unknown service:",
|
|
138
|
+
"1. Go to the official service website (e.g. developers.xxx.com).",
|
|
139
|
+
"2. Sign up / sign in. An account is usually required.",
|
|
140
|
+
"3. Look for \"API Keys\", \"Credentials\", \"Developer\" or \"Integrations\" section.",
|
|
141
|
+
"4. Create a new API key or token. Copy it immediately — many services do not show it again.",
|
|
142
|
+
"5. Keep it secret — do not share it or commit it to a repo.",
|
|
143
|
+
"",
|
|
144
|
+
" 💡 Known services: anthropic, openai, openrouter, tavily, elevenlabs, deepl, github, xai, google"
|
|
145
|
+
];
|
|
146
|
+
|
|
147
|
+
//#endregion
|
|
148
|
+
exports.GENERIC_API_KEY_STEPS = GENERIC_API_KEY_STEPS;
|
|
149
|
+
exports.getApiKeyGuide = getApiKeyGuide;
|