hyperclaw 5.0.5 → 5.0.7
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 +113 -5
- package/dist/chat-C7Jwz6dG.js +261 -0
- package/dist/chat-CjZKt5Sa.js +261 -0
- package/dist/chat-jnikU_sY.js +258 -0
- package/dist/clawhub-DRzu1zgW.js +1 -1
- package/dist/daemon-CRtwyRPM.js +5 -0
- package/dist/daemon-CckW3svB.js +318 -0
- package/dist/daemon-Dhd1g5G3.js +318 -0
- package/dist/daemon-pjlxpq7e.js +5 -0
- package/dist/developer-keys-B9VmWyj7.js +1 -1
- package/dist/developer-keys-BHt_R-yo.js +1 -1
- package/dist/developer-keys-BNo6wlFV.js +1 -1
- package/dist/developer-keys-Cnd1kswV.js +1 -1
- package/dist/developer-keys-DrrcUqFa.js +1 -1
- package/dist/developer-keys-JaJK3T27.js +1 -1
- package/dist/doctor-BvCe8BBk.js +1 -1
- package/dist/doctor-Dgjoc3DG.js +1 -1
- package/dist/engine-CdINNSpU.js +7 -0
- package/dist/engine-DwMKOfwf.js +305 -0
- package/dist/engine-hWJ1H1iP.js +305 -0
- package/dist/engine-wq9XrYn_.js +7 -0
- package/dist/health-DVfkpUQW.js +1 -1
- package/dist/health-Ds2YlpTB.js +1 -1
- package/dist/hub-BO6bj8Yj.js +2 -2
- package/dist/hub-CfwUz9YW.js +2 -2
- package/dist/hub-D0XwdjM-.js +2 -2
- package/dist/hub-FrPTA33j.js +2 -2
- package/dist/hyperclawbot-_lByyYQP.js +505 -0
- package/dist/hyperclawbot-m7N4LcRP.js +505 -0
- package/dist/logger-BFZSSq02.js +84 -0
- package/dist/manager-B2Gls5RG.js +1 -1
- package/dist/manager-BGLjW-ua.js +1 -1
- package/dist/manager-Bc4MAD-u.js +1 -1
- package/dist/manager-Biz9ixWJ.js +1 -1
- package/dist/manager-BnEDrLmB.js +1 -1
- package/dist/manager-CGFXv_Wl.js +1 -1
- package/dist/manager-CHROwzvH.js +1 -1
- package/dist/manager-CVLLaKmq.js +1 -1
- package/dist/manager-ClSlbh9E.js +1 -1
- package/dist/manager-DOWs9lLX.js +1 -1
- package/dist/manager-DWQSp1oL.js +1 -1
- package/dist/manager-DgyF52mg.js +1 -1
- package/dist/manager-Dm8nrMFx.js +1 -1
- package/dist/manager-DmpD4AaH.js +1 -1
- package/dist/manager-FCgF1plu.js +1 -1
- package/dist/manager-rgCsaWT1.js +1 -1
- package/dist/mcp-loader-BnxhSR9g.js +94 -0
- package/dist/mcp-loader-C7wVxPeQ.js +94 -0
- package/dist/memory-integration-B8RSN4pr.js +1 -1
- package/dist/memory-integration-BvgKnc-3.js +1 -1
- package/dist/memory-integration-CBPtFFjO.js +1 -1
- package/dist/memory-integration-DZExqWr4.js +1 -1
- package/dist/memory-integration-HTZzDjPr.js +1 -1
- package/dist/memory-integration-PZuznyp9.js +1 -1
- package/dist/memory-integration-cSYkZyEo.js +1 -1
- package/dist/memory-integration-g2vxwgoE.js +1 -1
- package/dist/memory-integration-lAXNUc7y.js +1 -1
- package/dist/onboard-B963fZXV.js +1 -1
- package/dist/onboard-BI5-egZB.js +11 -0
- package/dist/onboard-BKfMt31e.js +1 -1
- package/dist/onboard-BUmfBWVq.js +4123 -0
- package/dist/onboard-BVG2PEum.js +1 -1
- package/dist/onboard-BVOtKQdh.js +1 -1
- package/dist/onboard-BXNXCQp4.js +1 -1
- package/dist/onboard-Bd_wsYdi.js +1 -1
- package/dist/onboard-Bw28IRQ3.js +1 -1
- package/dist/onboard-CAN7x3me.js +1 -1
- package/dist/onboard-CLABoNKG.js +4099 -0
- package/dist/onboard-CVI5lUsf.js +1 -1
- package/dist/onboard-CdJCHc1l.js +1 -1
- package/dist/onboard-ChdCrzG4.js +3959 -0
- package/dist/onboard-CrxmSiy9.js +1 -1
- package/dist/onboard-DAqvQwwu.js +11 -0
- package/dist/onboard-DE6HRM9h.js +11 -0
- package/dist/onboard-DTFz_Whz.js +1 -1
- package/dist/onboard-DVgH7paw.js +11 -0
- package/dist/onboard-DgMPC9Qt.js +4123 -0
- package/dist/onboard-DnegOHMh.js +1 -1
- package/dist/onboard-DzXbFS1o.js +1 -1
- package/dist/orchestrator-79HXXDdP.js +6 -0
- package/dist/orchestrator-BC-7wA2Q.js +6 -0
- package/dist/orchestrator-Dr-Kx8Sj.js +189 -0
- package/dist/orchestrator-TGesUBGZ.js +189 -0
- package/dist/paths-BAyP6TbW.js +1 -1
- package/dist/paths-D-QecARF.js +1 -1
- package/dist/paths-DPovhojT.js +1 -1
- package/dist/pc-access-560pyOsu.js +1 -1
- package/dist/run-main.js +36 -29
- package/dist/runner-BHRSOPEU.js +1 -1
- package/dist/runner-Bu--_RXw.js +1 -1
- package/dist/runner-C-mmfhY7.js +1 -1
- package/dist/runner-CJFJUtPm.js +1 -1
- package/dist/runner-CuO6TMFT.js +1 -1
- package/dist/runner-D0ca-Lzi.js +1 -1
- package/dist/runner-D1rjuMTJ.js +1 -1
- package/dist/runner-D2Q8YvHW.js +1 -1
- package/dist/runner-DIefAdtj.js +1 -1
- package/dist/runner-DatMMYYE.js +1 -1
- package/dist/runner-Dh65wta9.js +1 -1
- package/dist/runner-FhyE2VNa.js +1 -1
- package/dist/server-5BJD83CF.js +4 -0
- package/dist/server-BoGCZCf2.js +4 -0
- package/dist/server-Cv6kgXvX.js +1255 -0
- package/dist/server-DB6PQzNR.js +1 -1
- package/dist/server-DaBgrB4W.js +1255 -0
- package/dist/skill-runtime-BxRuz-SL.js +102 -0
- package/dist/skill-runtime-CYtCaHxf.js +5 -0
- package/dist/skill-runtime-ChEoWYiG.js +5 -0
- package/dist/skill-runtime-Z8OhW4eX.js +102 -0
- package/dist/src-0nY9IATM.js +63 -0
- package/dist/src-3S81Pvdb.js +458 -0
- package/dist/src-BJtvfghE.js +63 -0
- package/dist/src-BeacbqsZ.js +1 -1
- package/dist/src-C3_9DBLN.js +1 -1
- package/dist/src-CDnzzbzf.js +1 -1
- package/dist/src-CGQjRI4N.js +1 -1
- package/dist/src-CVxp9DM-.js +1 -1
- package/dist/src-CcX1rZa1.js +458 -0
- package/dist/src-DIc-L2IG.js +1 -1
- package/dist/src-DWCUhnD4.js +1 -1
- package/dist/sub-agent-tools-BN_8yWye.js +39 -0
- package/dist/sub-agent-tools-DpGd5o7N.js +39 -0
- package/package.json +2 -1
- package/scripts/fix-init-paths.mjs +44 -0
- package/scripts/postinstall.js +1 -1
package/README.md
CHANGED
|
@@ -84,24 +84,72 @@ hyperclaw onboard --install-daemon
|
|
|
84
84
|
|
|
85
85
|
The wizard walks you through: AI provider → model → channels → skills. Done.
|
|
86
86
|
|
|
87
|
+
## ▶️ Running your bot
|
|
88
|
+
|
|
87
89
|
```bash
|
|
88
|
-
#
|
|
90
|
+
# Step 1 — Start the daemon (runs in the background, bot becomes active on Telegram/Discord/etc.)
|
|
89
91
|
hyperclaw daemon start
|
|
90
92
|
|
|
91
|
-
#
|
|
93
|
+
# Step 2 — Open the TUI dashboard to see live status, channels, logs
|
|
94
|
+
hyperclaw dashboard
|
|
95
|
+
|
|
96
|
+
# Step 3 — Or chat directly from your terminal (no Telegram needed)
|
|
92
97
|
hyperclaw chat
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### How it works
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
hyperclaw daemon start
|
|
104
|
+
↓
|
|
105
|
+
Gateway (background process)
|
|
106
|
+
↓
|
|
107
|
+
┌─────────────┬──────────────┐
|
|
108
|
+
│ Telegram │ Dashboard │
|
|
109
|
+
│ Discord │ hyperclaw │
|
|
110
|
+
│ WhatsApp │ dashboard │
|
|
111
|
+
└─────────────┴──────────────┘
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
> **The daemon must be running** for the Telegram/Discord/WhatsApp bot to answer messages and for the TUI dashboard to show "ONLINE".
|
|
115
|
+
> On **Windows** the daemon runs via Task Scheduler (no WSL, no admin).
|
|
116
|
+
> On **Linux/macOS** with `--install-daemon` it uses systemd / launchd.
|
|
117
|
+
|
|
118
|
+
### Without the daemon (foreground mode)
|
|
119
|
+
|
|
120
|
+
If you haven't installed the daemon, run the bot in the foreground — the terminal stays open:
|
|
93
121
|
|
|
122
|
+
```bash
|
|
123
|
+
# Run bot in foreground (Ctrl+C to stop)
|
|
124
|
+
hyperclaw start
|
|
125
|
+
|
|
126
|
+
# In a second terminal, open the dashboard
|
|
127
|
+
hyperclaw dashboard
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Quick reference
|
|
131
|
+
|
|
132
|
+
| I want to… | Command |
|
|
133
|
+
|-----------------------------------------|----------------------------|
|
|
134
|
+
| Start Telegram/Discord bot (background) | `hyperclaw daemon start` |
|
|
135
|
+
| Stop the bot | `hyperclaw daemon stop` |
|
|
136
|
+
| Check if running | `hyperclaw daemon status` |
|
|
137
|
+
| Open TUI dashboard | `hyperclaw dashboard` |
|
|
138
|
+
| Chat from terminal (no Telegram needed) | `hyperclaw chat` |
|
|
139
|
+
| Run in foreground (no daemon) | `hyperclaw start` |
|
|
140
|
+
| Health check | `hyperclaw doctor` |
|
|
141
|
+
|
|
142
|
+
```bash
|
|
94
143
|
# Send a single message (non-interactive)
|
|
95
144
|
hyperclaw agent --message "What can you do?"
|
|
96
|
-
|
|
97
|
-
# Health check
|
|
98
|
-
hyperclaw doctor
|
|
99
145
|
```
|
|
100
146
|
|
|
101
147
|
> **Windows**: No WSL2, no admin rights needed. The daemon uses Task Scheduler and runs as your account.
|
|
102
148
|
|
|
103
149
|
> **Linux**: If you get an `EACCES: permission denied` error during `npm install -g`, see the [Linux install fix](#-linux-permission-fix) below.
|
|
104
150
|
|
|
151
|
+
> **Emojis not showing?** See the [Terminal emoji fix](#-emojis-not-showing-in-terminal) below.
|
|
152
|
+
|
|
105
153
|
<details>
|
|
106
154
|
<summary>More install options</summary>
|
|
107
155
|
|
|
@@ -198,6 +246,65 @@ sudo npm install -g hyperclaw@latest
|
|
|
198
246
|
|
|
199
247
|
</details>
|
|
200
248
|
|
|
249
|
+
<details>
|
|
250
|
+
<summary id="-emojis-not-showing-in-terminal">🎨 Emojis not showing in terminal (showing as ?? or □)</summary>
|
|
251
|
+
|
|
252
|
+
HyperClaw uses emojis in its banner and wizard. If you see `??` or empty boxes, your terminal or font doesn't support emoji rendering.
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
### 🪟 Windows — CMD / PowerShell
|
|
257
|
+
|
|
258
|
+
The old `cmd.exe` and classic PowerShell window do **not** support emoji.
|
|
259
|
+
|
|
260
|
+
**Fix: Use Windows Terminal** (free, from Microsoft Store):
|
|
261
|
+
|
|
262
|
+
1. Open **Microsoft Store** → search **"Windows Terminal"** → Install
|
|
263
|
+
2. Open Windows Terminal → Settings → Profiles → Defaults → Appearance
|
|
264
|
+
3. Set font to **Cascadia Code** (already included) or install [JetBrains Mono Nerd Font](https://www.nerdfonts.com/font-downloads)
|
|
265
|
+
4. Run `hyperclaw onboard` from Windows Terminal — emojis will show correctly
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
### 🐧 Linux — XFCE / Konsole / other terminals
|
|
270
|
+
|
|
271
|
+
Install the Google Noto emoji font:
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
# Debian / Ubuntu / Kali
|
|
275
|
+
sudo apt install fonts-noto-color-emoji
|
|
276
|
+
|
|
277
|
+
# Arch / Manjaro
|
|
278
|
+
sudo pacman -S noto-fonts-emoji
|
|
279
|
+
|
|
280
|
+
# Fedora / RHEL
|
|
281
|
+
sudo dnf install google-noto-emoji-fonts
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Then **restart your terminal** — emojis will appear.
|
|
285
|
+
|
|
286
|
+
> If you use **XFCE Terminal**: go to Edit → Preferences → Appearance and set a font like **JetBrains Mono** or **DejaVu Sans Mono**.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
### 🍎 macOS — Terminal.app
|
|
291
|
+
|
|
292
|
+
macOS Terminal.app supports emoji out of the box on recent versions. If you still see `?`:
|
|
293
|
+
|
|
294
|
+
1. Terminal → Settings → Profiles → Text → Change Font
|
|
295
|
+
2. Set to **Menlo**, **SF Mono**, or any font from [Nerd Fonts](https://www.nerdfonts.com/)
|
|
296
|
+
3. Alternatively, use **iTerm2** (free) which has full emoji support by default
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
brew install --cask iterm2
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
> **Note**: If you prefer to keep using your current terminal without emoji, HyperClaw works perfectly — only the visual display is affected, not the functionality.
|
|
305
|
+
|
|
306
|
+
</details>
|
|
307
|
+
|
|
201
308
|
---
|
|
202
309
|
|
|
203
310
|
## Channels
|
|
@@ -519,6 +626,7 @@ Example — ask the agent:
|
|
|
519
626
|
"Create a note in Obsidian: Meeting notes..."
|
|
520
627
|
"Add a card to my Trello board"
|
|
521
628
|
"Set my 8Sleep to temperature 20 on the left side"
|
|
629
|
+
|
|
522
630
|
"Get my GitHub password from 1Password"
|
|
523
631
|
"Send an iMessage to +1234567890: I'll be late"
|
|
524
632
|
"What's playing on my Sonos?"
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-jS-bbMI5.js');
|
|
2
|
+
const require_paths = require('./paths-AIyBxIzm.js');
|
|
3
|
+
require('./browser-tools-JZ9ji6AW.js');
|
|
4
|
+
require('./src-CGQjRI4N.js');
|
|
5
|
+
const require_engine = require('./engine-hWJ1H1iP.js');
|
|
6
|
+
require('./extraction-tools-Dg7AHS35.js');
|
|
7
|
+
const require_inference = require('./inference-DhA8jpfH.js');
|
|
8
|
+
require('./memory-auto-D-L2q21G.js');
|
|
9
|
+
require('./orchestrator-TGesUBGZ.js');
|
|
10
|
+
require('./pc-access-B0KocJNe.js');
|
|
11
|
+
require('./session-store-DCTQIVur.js');
|
|
12
|
+
require('./sessions-tools-BdlN6Pb6.js');
|
|
13
|
+
require('./skill-loader-Wf3brNOj.js');
|
|
14
|
+
require('./skill-runtime-Z8OhW4eX.js');
|
|
15
|
+
require('./vision-tools-dwn9p4el.js');
|
|
16
|
+
require('./website-watch-tools-B-jRAeTe.js');
|
|
17
|
+
const require_src$1 = require('./src-3S81Pvdb.js');
|
|
18
|
+
const chalk = require_chunk.__toESM(require("chalk"));
|
|
19
|
+
const ora = require_chunk.__toESM(require("ora"));
|
|
20
|
+
const fs_extra = require_chunk.__toESM(require("fs-extra"));
|
|
21
|
+
const readline = require_chunk.__toESM(require("readline"));
|
|
22
|
+
|
|
23
|
+
//#region src/cli/chat.ts
|
|
24
|
+
require_src$1.init_src();
|
|
25
|
+
const DIVIDER = chalk.default.gray(" " + "─".repeat(56));
|
|
26
|
+
function printHeader(model, sessionId) {
|
|
27
|
+
console.log();
|
|
28
|
+
console.log(DIVIDER);
|
|
29
|
+
console.log(chalk.default.bold.cyan(" 🦅 HYPERCLAW CHAT"));
|
|
30
|
+
console.log(chalk.default.gray(` Model: ${model} · Session: ${sessionId}`));
|
|
31
|
+
console.log(DIVIDER);
|
|
32
|
+
console.log(chalk.default.gray(" Type your message and press Enter."));
|
|
33
|
+
console.log(chalk.default.gray(" Commands: /exit /clear /model /skills /help"));
|
|
34
|
+
console.log(DIVIDER);
|
|
35
|
+
console.log();
|
|
36
|
+
}
|
|
37
|
+
function printHelp() {
|
|
38
|
+
console.log();
|
|
39
|
+
console.log(chalk.default.bold(" Commands:"));
|
|
40
|
+
console.log(` ${chalk.default.cyan("/exit")} — quit the chat`);
|
|
41
|
+
console.log(` ${chalk.default.cyan("/clear")} — clear conversation history`);
|
|
42
|
+
console.log(` ${chalk.default.cyan("/model")} — show current model`);
|
|
43
|
+
console.log(` ${chalk.default.cyan("/skills")} — list installed skills + how to add more`);
|
|
44
|
+
console.log(` ${chalk.default.cyan("/help")} — show this help`);
|
|
45
|
+
console.log();
|
|
46
|
+
console.log(chalk.default.gray(" Tip: you can also tell the agent to install a skill:"));
|
|
47
|
+
console.log(chalk.default.gray(" \"Install the web-search skill\" or paste a clawhub.ai link"));
|
|
48
|
+
console.log();
|
|
49
|
+
}
|
|
50
|
+
async function printSkills() {
|
|
51
|
+
console.log();
|
|
52
|
+
try {
|
|
53
|
+
const { loadSkills } = await Promise.resolve().then(() => require("./skill-loader-B5oeliGu.js"));
|
|
54
|
+
const skills = await loadSkills();
|
|
55
|
+
if (skills.length === 0) console.log(chalk.default.gray(" No skills installed yet."));
|
|
56
|
+
else {
|
|
57
|
+
console.log(chalk.default.bold(" Installed skills:"));
|
|
58
|
+
for (const s of skills) {
|
|
59
|
+
console.log(` ${chalk.default.cyan("•")} ${chalk.default.bold(s.title || s.id)} ${chalk.default.gray(`(${s.id})`)}`);
|
|
60
|
+
if (s.capabilities) console.log(chalk.default.gray(` ${s.capabilities}`));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
} catch {
|
|
64
|
+
console.log(chalk.default.gray(" Could not load skills list."));
|
|
65
|
+
}
|
|
66
|
+
console.log();
|
|
67
|
+
console.log(chalk.default.bold(" How to add a skill:"));
|
|
68
|
+
console.log(` ${chalk.default.gray("1.")} Tell the agent: ${chalk.default.cyan("\"Install the web-search skill\"")}`);
|
|
69
|
+
console.log(` ${chalk.default.gray("2.")} Paste a link: ${chalk.default.cyan("\"Install this: https://clawhub.ai/user/skill-name\"")}`);
|
|
70
|
+
console.log(` ${chalk.default.gray("3.")} CLI (outside chat): ${chalk.default.cyan("hyperclaw skill install <name>")}`);
|
|
71
|
+
console.log(` ${chalk.default.gray("4.")} Re-run wizard: ${chalk.default.cyan("hyperclaw onboard")}`);
|
|
72
|
+
console.log();
|
|
73
|
+
}
|
|
74
|
+
function makeSessionId() {
|
|
75
|
+
return Math.random().toString(36).slice(2, 9);
|
|
76
|
+
}
|
|
77
|
+
async function runChat(opts) {
|
|
78
|
+
const cfg = await fs_extra.default.readJson(require_paths.getConfigPath()).catch(() => null);
|
|
79
|
+
if (!cfg) {
|
|
80
|
+
console.log(chalk.default.red("\n No configuration found. Run: hyperclaw onboard\n"));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const { getProviderCredentialAsync } = await Promise.resolve().then(() => require("./env-resolve-bDYssfih.js"));
|
|
84
|
+
const apiKey = await getProviderCredentialAsync(cfg).catch(() => null);
|
|
85
|
+
const isLocal = [
|
|
86
|
+
"local",
|
|
87
|
+
"ollama",
|
|
88
|
+
"lmstudio"
|
|
89
|
+
].includes(cfg?.provider?.providerId ?? "");
|
|
90
|
+
if (!apiKey && !isLocal) {
|
|
91
|
+
console.log(chalk.default.red("\n No API key configured. Run: hyperclaw config set-key\n"));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const { getProvider } = await Promise.resolve().then(() => require("./providers-DxiamZSL.js"));
|
|
95
|
+
const providerMeta = getProvider(cfg?.provider?.providerId ?? "");
|
|
96
|
+
const CUSTOM_IDS = new Set([
|
|
97
|
+
"groq",
|
|
98
|
+
"mistral",
|
|
99
|
+
"deepseek",
|
|
100
|
+
"perplexity",
|
|
101
|
+
"huggingface",
|
|
102
|
+
"ollama",
|
|
103
|
+
"lmstudio",
|
|
104
|
+
"local",
|
|
105
|
+
"xai",
|
|
106
|
+
"openai",
|
|
107
|
+
"google",
|
|
108
|
+
"minimax",
|
|
109
|
+
"moonshot",
|
|
110
|
+
"qwen",
|
|
111
|
+
"zai",
|
|
112
|
+
"litellm",
|
|
113
|
+
"cloudflare",
|
|
114
|
+
"copilot",
|
|
115
|
+
"vercel-ai",
|
|
116
|
+
"opencode-zen"
|
|
117
|
+
]);
|
|
118
|
+
const isAnthropicVariant = [
|
|
119
|
+
"anthropic",
|
|
120
|
+
"anthropic-oauth",
|
|
121
|
+
"anthropic-setup-token"
|
|
122
|
+
].includes(cfg?.provider?.providerId ?? "");
|
|
123
|
+
const provider = isAnthropicVariant ? "anthropic" : cfg?.provider?.providerId === "custom" || isLocal || CUSTOM_IDS.has(cfg?.provider?.providerId ?? "") ? "custom" : "openrouter";
|
|
124
|
+
const rawModel = opts.model || cfg?.provider?.modelId || "claude-sonnet-4-5";
|
|
125
|
+
const model = rawModel.startsWith("ollama/") ? rawModel.slice(7) : rawModel;
|
|
126
|
+
const resolvedBaseUrl = cfg?.provider?.baseUrl || providerMeta?.baseUrl || (isLocal ? "http://localhost:11434/v1" : void 0);
|
|
127
|
+
const THINKING_BUDGET = {
|
|
128
|
+
high: 1e4,
|
|
129
|
+
medium: 4e3,
|
|
130
|
+
low: 1e3,
|
|
131
|
+
none: 0
|
|
132
|
+
};
|
|
133
|
+
const thinkingBudget = THINKING_BUDGET[opts.thinking ?? "none"] ?? 0;
|
|
134
|
+
const maxTokens = thinkingBudget > 0 ? thinkingBudget + 4096 : 4096;
|
|
135
|
+
const context = await require_engine.loadWorkspaceContext(opts.workspace) + await require_engine.loadSkillsContext();
|
|
136
|
+
const tools = await require_engine.resolveTools({
|
|
137
|
+
config: cfg,
|
|
138
|
+
source: "cli",
|
|
139
|
+
elevated: true,
|
|
140
|
+
daemonMode: false
|
|
141
|
+
});
|
|
142
|
+
const engineOpts = {
|
|
143
|
+
model,
|
|
144
|
+
apiKey,
|
|
145
|
+
provider,
|
|
146
|
+
system: context || void 0,
|
|
147
|
+
tools,
|
|
148
|
+
maxTokens,
|
|
149
|
+
onToken: () => {},
|
|
150
|
+
...provider === "custom" ? { baseUrl: resolvedBaseUrl || "" } : {},
|
|
151
|
+
...thinkingBudget > 0 && model.includes("claude") ? { thinking: { budget_tokens: thinkingBudget } } : {}
|
|
152
|
+
};
|
|
153
|
+
const sessionId = opts.sessionId ?? makeSessionId();
|
|
154
|
+
const messages = [];
|
|
155
|
+
printHeader(rawModel, sessionId);
|
|
156
|
+
const rl = readline.default.createInterface({
|
|
157
|
+
input: process.stdin,
|
|
158
|
+
output: process.stdout,
|
|
159
|
+
terminal: true
|
|
160
|
+
});
|
|
161
|
+
rl.on("SIGINT", () => {
|
|
162
|
+
console.log(chalk.default.gray("\n\n Bye!\n"));
|
|
163
|
+
rl.close();
|
|
164
|
+
process.exit(0);
|
|
165
|
+
});
|
|
166
|
+
await new Promise((resolve) => {
|
|
167
|
+
rl.on("close", resolve);
|
|
168
|
+
const prompt = () => {
|
|
169
|
+
rl.question(chalk.default.bold.green(" You › "), async (input) => {
|
|
170
|
+
const text = input.trim();
|
|
171
|
+
if (!text) {
|
|
172
|
+
prompt();
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if ([
|
|
176
|
+
"/exit",
|
|
177
|
+
"/quit",
|
|
178
|
+
"/bye",
|
|
179
|
+
"exit",
|
|
180
|
+
"quit",
|
|
181
|
+
"bye"
|
|
182
|
+
].includes(text.toLowerCase())) {
|
|
183
|
+
console.log(chalk.default.gray("\n Bye!\n"));
|
|
184
|
+
rl.close();
|
|
185
|
+
process.exit(0);
|
|
186
|
+
}
|
|
187
|
+
if (text === "/help") {
|
|
188
|
+
printHelp();
|
|
189
|
+
prompt();
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (text === "/skills") {
|
|
193
|
+
await printSkills();
|
|
194
|
+
prompt();
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (text === "/model") {
|
|
198
|
+
console.log(chalk.default.gray(`\n Model: ${rawModel}\n`));
|
|
199
|
+
prompt();
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (text === "/clear") {
|
|
203
|
+
messages.length = 0;
|
|
204
|
+
console.log(chalk.default.gray("\n Conversation cleared.\n"));
|
|
205
|
+
prompt();
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
messages.push({
|
|
209
|
+
role: "user",
|
|
210
|
+
content: text
|
|
211
|
+
});
|
|
212
|
+
const spinner = (0, ora.default)({
|
|
213
|
+
text: chalk.default.gray("Thinking..."),
|
|
214
|
+
color: "cyan",
|
|
215
|
+
prefixText: " "
|
|
216
|
+
}).start();
|
|
217
|
+
let responseText = "";
|
|
218
|
+
try {
|
|
219
|
+
const engine = new require_inference.InferenceEngine({
|
|
220
|
+
...engineOpts,
|
|
221
|
+
onToken: (token) => {
|
|
222
|
+
if (spinner.isSpinning) spinner.stop();
|
|
223
|
+
process.stdout.write(token);
|
|
224
|
+
},
|
|
225
|
+
onToolCall: (name) => {
|
|
226
|
+
if (spinner.isSpinning) spinner.stop();
|
|
227
|
+
console.log(chalk.default.gray(`\n [tool: ${name}]`));
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
spinner.stop();
|
|
231
|
+
process.stdout.write(chalk.default.bold.blue("\n Agent › "));
|
|
232
|
+
const result = await engine.run(messages);
|
|
233
|
+
responseText = result.text || "";
|
|
234
|
+
if (!responseText && !result.text) process.stdout.write(chalk.default.gray("(empty)"));
|
|
235
|
+
console.log("\n");
|
|
236
|
+
if (result.usage) console.log(chalk.default.gray(` Tokens — in: ${result.usage.input} out: ${result.usage.output}\n`));
|
|
237
|
+
} catch (e) {
|
|
238
|
+
spinner.stop();
|
|
239
|
+
responseText = `Error: ${e.message}`;
|
|
240
|
+
console.log(chalk.default.red(`\n Error: ${e.message}\n`));
|
|
241
|
+
}
|
|
242
|
+
if (responseText) messages.push({
|
|
243
|
+
role: "assistant",
|
|
244
|
+
content: responseText
|
|
245
|
+
});
|
|
246
|
+
try {
|
|
247
|
+
const { AutoMemory } = await Promise.resolve().then(() => require("./memory-auto-DTcy5VBy.js"));
|
|
248
|
+
const mem = new AutoMemory({ extractEveryNTurns: 3 });
|
|
249
|
+
mem.addTurn("user", text);
|
|
250
|
+
if (responseText) mem.addTurn("assistant", responseText);
|
|
251
|
+
mem.extract().catch(() => {});
|
|
252
|
+
} catch {}
|
|
253
|
+
prompt();
|
|
254
|
+
});
|
|
255
|
+
};
|
|
256
|
+
prompt();
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
//#endregion
|
|
261
|
+
exports.runChat = runChat;
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-jS-bbMI5.js');
|
|
2
|
+
const require_paths = require('./paths-AIyBxIzm.js');
|
|
3
|
+
require('./browser-tools-JZ9ji6AW.js');
|
|
4
|
+
require('./src-CGQjRI4N.js');
|
|
5
|
+
const require_engine = require('./engine-DwMKOfwf.js');
|
|
6
|
+
require('./extraction-tools-Dg7AHS35.js');
|
|
7
|
+
const require_inference = require('./inference-DhA8jpfH.js');
|
|
8
|
+
require('./memory-auto-D-L2q21G.js');
|
|
9
|
+
require('./orchestrator-Dr-Kx8Sj.js');
|
|
10
|
+
require('./pc-access-B0KocJNe.js');
|
|
11
|
+
require('./session-store-DCTQIVur.js');
|
|
12
|
+
require('./sessions-tools-BdlN6Pb6.js');
|
|
13
|
+
require('./skill-loader-Wf3brNOj.js');
|
|
14
|
+
require('./skill-runtime-BxRuz-SL.js');
|
|
15
|
+
require('./vision-tools-dwn9p4el.js');
|
|
16
|
+
require('./website-watch-tools-B-jRAeTe.js');
|
|
17
|
+
const require_src$1 = require('./src-CcX1rZa1.js');
|
|
18
|
+
const chalk = require_chunk.__toESM(require("chalk"));
|
|
19
|
+
const ora = require_chunk.__toESM(require("ora"));
|
|
20
|
+
const fs_extra = require_chunk.__toESM(require("fs-extra"));
|
|
21
|
+
const readline = require_chunk.__toESM(require("readline"));
|
|
22
|
+
|
|
23
|
+
//#region src/cli/chat.ts
|
|
24
|
+
require_src$1.init_src();
|
|
25
|
+
const DIVIDER = chalk.default.gray(" " + "─".repeat(56));
|
|
26
|
+
function printHeader(model, sessionId) {
|
|
27
|
+
console.log();
|
|
28
|
+
console.log(DIVIDER);
|
|
29
|
+
console.log(chalk.default.bold.cyan(" 🦅 HYPERCLAW CHAT"));
|
|
30
|
+
console.log(chalk.default.gray(` Model: ${model} · Session: ${sessionId}`));
|
|
31
|
+
console.log(DIVIDER);
|
|
32
|
+
console.log(chalk.default.gray(" Type your message and press Enter."));
|
|
33
|
+
console.log(chalk.default.gray(" Commands: /exit /clear /model /skills /help"));
|
|
34
|
+
console.log(DIVIDER);
|
|
35
|
+
console.log();
|
|
36
|
+
}
|
|
37
|
+
function printHelp() {
|
|
38
|
+
console.log();
|
|
39
|
+
console.log(chalk.default.bold(" Commands:"));
|
|
40
|
+
console.log(` ${chalk.default.cyan("/exit")} — quit the chat`);
|
|
41
|
+
console.log(` ${chalk.default.cyan("/clear")} — clear conversation history`);
|
|
42
|
+
console.log(` ${chalk.default.cyan("/model")} — show current model`);
|
|
43
|
+
console.log(` ${chalk.default.cyan("/skills")} — list installed skills + how to add more`);
|
|
44
|
+
console.log(` ${chalk.default.cyan("/help")} — show this help`);
|
|
45
|
+
console.log();
|
|
46
|
+
console.log(chalk.default.gray(" Tip: you can also tell the agent to install a skill:"));
|
|
47
|
+
console.log(chalk.default.gray(" \"Install the web-search skill\" or paste a clawhub.ai link"));
|
|
48
|
+
console.log();
|
|
49
|
+
}
|
|
50
|
+
async function printSkills() {
|
|
51
|
+
console.log();
|
|
52
|
+
try {
|
|
53
|
+
const { loadSkills } = await Promise.resolve().then(() => require("./skill-loader-B5oeliGu.js"));
|
|
54
|
+
const skills = await loadSkills();
|
|
55
|
+
if (skills.length === 0) console.log(chalk.default.gray(" No skills installed yet."));
|
|
56
|
+
else {
|
|
57
|
+
console.log(chalk.default.bold(" Installed skills:"));
|
|
58
|
+
for (const s of skills) {
|
|
59
|
+
console.log(` ${chalk.default.cyan("•")} ${chalk.default.bold(s.title || s.id)} ${chalk.default.gray(`(${s.id})`)}`);
|
|
60
|
+
if (s.capabilities) console.log(chalk.default.gray(` ${s.capabilities}`));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
} catch {
|
|
64
|
+
console.log(chalk.default.gray(" Could not load skills list."));
|
|
65
|
+
}
|
|
66
|
+
console.log();
|
|
67
|
+
console.log(chalk.default.bold(" How to add a skill:"));
|
|
68
|
+
console.log(` ${chalk.default.gray("1.")} Tell the agent: ${chalk.default.cyan("\"Install the web-search skill\"")}`);
|
|
69
|
+
console.log(` ${chalk.default.gray("2.")} Paste a link: ${chalk.default.cyan("\"Install this: https://clawhub.ai/user/skill-name\"")}`);
|
|
70
|
+
console.log(` ${chalk.default.gray("3.")} CLI (outside chat): ${chalk.default.cyan("hyperclaw skill install <name>")}`);
|
|
71
|
+
console.log(` ${chalk.default.gray("4.")} Re-run wizard: ${chalk.default.cyan("hyperclaw onboard")}`);
|
|
72
|
+
console.log();
|
|
73
|
+
}
|
|
74
|
+
function makeSessionId() {
|
|
75
|
+
return Math.random().toString(36).slice(2, 9);
|
|
76
|
+
}
|
|
77
|
+
async function runChat(opts) {
|
|
78
|
+
const cfg = await fs_extra.default.readJson(require_paths.getConfigPath()).catch(() => null);
|
|
79
|
+
if (!cfg) {
|
|
80
|
+
console.log(chalk.default.red("\n No configuration found. Run: hyperclaw onboard\n"));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const { getProviderCredentialAsync } = await Promise.resolve().then(() => require("./env-resolve-bDYssfih.js"));
|
|
84
|
+
const apiKey = await getProviderCredentialAsync(cfg).catch(() => null);
|
|
85
|
+
const isLocal = [
|
|
86
|
+
"local",
|
|
87
|
+
"ollama",
|
|
88
|
+
"lmstudio"
|
|
89
|
+
].includes(cfg?.provider?.providerId ?? "");
|
|
90
|
+
if (!apiKey && !isLocal) {
|
|
91
|
+
console.log(chalk.default.red("\n No API key configured. Run: hyperclaw config set-key\n"));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const { getProvider } = await Promise.resolve().then(() => require("./providers-DxiamZSL.js"));
|
|
95
|
+
const providerMeta = getProvider(cfg?.provider?.providerId ?? "");
|
|
96
|
+
const CUSTOM_IDS = new Set([
|
|
97
|
+
"groq",
|
|
98
|
+
"mistral",
|
|
99
|
+
"deepseek",
|
|
100
|
+
"perplexity",
|
|
101
|
+
"huggingface",
|
|
102
|
+
"ollama",
|
|
103
|
+
"lmstudio",
|
|
104
|
+
"local",
|
|
105
|
+
"xai",
|
|
106
|
+
"openai",
|
|
107
|
+
"google",
|
|
108
|
+
"minimax",
|
|
109
|
+
"moonshot",
|
|
110
|
+
"qwen",
|
|
111
|
+
"zai",
|
|
112
|
+
"litellm",
|
|
113
|
+
"cloudflare",
|
|
114
|
+
"copilot",
|
|
115
|
+
"vercel-ai",
|
|
116
|
+
"opencode-zen"
|
|
117
|
+
]);
|
|
118
|
+
const isAnthropicVariant = [
|
|
119
|
+
"anthropic",
|
|
120
|
+
"anthropic-oauth",
|
|
121
|
+
"anthropic-setup-token"
|
|
122
|
+
].includes(cfg?.provider?.providerId ?? "");
|
|
123
|
+
const provider = isAnthropicVariant ? "anthropic" : cfg?.provider?.providerId === "custom" || isLocal || CUSTOM_IDS.has(cfg?.provider?.providerId ?? "") ? "custom" : "openrouter";
|
|
124
|
+
const rawModel = opts.model || cfg?.provider?.modelId || "claude-sonnet-4-5";
|
|
125
|
+
const model = rawModel.startsWith("ollama/") ? rawModel.slice(7) : rawModel;
|
|
126
|
+
const resolvedBaseUrl = cfg?.provider?.baseUrl || providerMeta?.baseUrl || (isLocal ? "http://localhost:11434/v1" : void 0);
|
|
127
|
+
const THINKING_BUDGET = {
|
|
128
|
+
high: 1e4,
|
|
129
|
+
medium: 4e3,
|
|
130
|
+
low: 1e3,
|
|
131
|
+
none: 0
|
|
132
|
+
};
|
|
133
|
+
const thinkingBudget = THINKING_BUDGET[opts.thinking ?? "none"] ?? 0;
|
|
134
|
+
const maxTokens = thinkingBudget > 0 ? thinkingBudget + 4096 : 4096;
|
|
135
|
+
const context = await require_engine.loadWorkspaceContext(opts.workspace) + await require_engine.loadSkillsContext();
|
|
136
|
+
const tools = await require_engine.resolveTools({
|
|
137
|
+
config: cfg,
|
|
138
|
+
source: "cli",
|
|
139
|
+
elevated: true,
|
|
140
|
+
daemonMode: false
|
|
141
|
+
});
|
|
142
|
+
const engineOpts = {
|
|
143
|
+
model,
|
|
144
|
+
apiKey,
|
|
145
|
+
provider,
|
|
146
|
+
system: context || void 0,
|
|
147
|
+
tools,
|
|
148
|
+
maxTokens,
|
|
149
|
+
onToken: () => {},
|
|
150
|
+
...provider === "custom" ? { baseUrl: resolvedBaseUrl || "" } : {},
|
|
151
|
+
...thinkingBudget > 0 && model.includes("claude") ? { thinking: { budget_tokens: thinkingBudget } } : {}
|
|
152
|
+
};
|
|
153
|
+
const sessionId = opts.sessionId ?? makeSessionId();
|
|
154
|
+
const messages = [];
|
|
155
|
+
printHeader(rawModel, sessionId);
|
|
156
|
+
const rl = readline.default.createInterface({
|
|
157
|
+
input: process.stdin,
|
|
158
|
+
output: process.stdout,
|
|
159
|
+
terminal: true
|
|
160
|
+
});
|
|
161
|
+
rl.on("SIGINT", () => {
|
|
162
|
+
console.log(chalk.default.gray("\n\n Bye!\n"));
|
|
163
|
+
rl.close();
|
|
164
|
+
process.exit(0);
|
|
165
|
+
});
|
|
166
|
+
await new Promise((resolve) => {
|
|
167
|
+
rl.on("close", resolve);
|
|
168
|
+
const prompt = () => {
|
|
169
|
+
rl.question(chalk.default.bold.green(" You › "), async (input) => {
|
|
170
|
+
const text = input.trim();
|
|
171
|
+
if (!text) {
|
|
172
|
+
prompt();
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if ([
|
|
176
|
+
"/exit",
|
|
177
|
+
"/quit",
|
|
178
|
+
"/bye",
|
|
179
|
+
"exit",
|
|
180
|
+
"quit",
|
|
181
|
+
"bye"
|
|
182
|
+
].includes(text.toLowerCase())) {
|
|
183
|
+
console.log(chalk.default.gray("\n Bye!\n"));
|
|
184
|
+
rl.close();
|
|
185
|
+
process.exit(0);
|
|
186
|
+
}
|
|
187
|
+
if (text === "/help") {
|
|
188
|
+
printHelp();
|
|
189
|
+
prompt();
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (text === "/skills") {
|
|
193
|
+
await printSkills();
|
|
194
|
+
prompt();
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (text === "/model") {
|
|
198
|
+
console.log(chalk.default.gray(`\n Model: ${rawModel}\n`));
|
|
199
|
+
prompt();
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (text === "/clear") {
|
|
203
|
+
messages.length = 0;
|
|
204
|
+
console.log(chalk.default.gray("\n Conversation cleared.\n"));
|
|
205
|
+
prompt();
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
messages.push({
|
|
209
|
+
role: "user",
|
|
210
|
+
content: text
|
|
211
|
+
});
|
|
212
|
+
const spinner = (0, ora.default)({
|
|
213
|
+
text: chalk.default.gray("Thinking..."),
|
|
214
|
+
color: "cyan",
|
|
215
|
+
prefixText: " "
|
|
216
|
+
}).start();
|
|
217
|
+
let responseText = "";
|
|
218
|
+
try {
|
|
219
|
+
const engine = new require_inference.InferenceEngine({
|
|
220
|
+
...engineOpts,
|
|
221
|
+
onToken: (token) => {
|
|
222
|
+
if (spinner.isSpinning) spinner.stop();
|
|
223
|
+
process.stdout.write(token);
|
|
224
|
+
},
|
|
225
|
+
onToolCall: (name) => {
|
|
226
|
+
if (spinner.isSpinning) spinner.stop();
|
|
227
|
+
console.log(chalk.default.gray(`\n [tool: ${name}]`));
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
spinner.stop();
|
|
231
|
+
process.stdout.write(chalk.default.bold.blue("\n Agent › "));
|
|
232
|
+
const result = await engine.run(messages);
|
|
233
|
+
responseText = result.text || "";
|
|
234
|
+
if (!responseText && !result.text) process.stdout.write(chalk.default.gray("(empty)"));
|
|
235
|
+
console.log("\n");
|
|
236
|
+
if (result.usage) console.log(chalk.default.gray(` Tokens — in: ${result.usage.input} out: ${result.usage.output}\n`));
|
|
237
|
+
} catch (e) {
|
|
238
|
+
spinner.stop();
|
|
239
|
+
responseText = `Error: ${e.message}`;
|
|
240
|
+
console.log(chalk.default.red(`\n Error: ${e.message}\n`));
|
|
241
|
+
}
|
|
242
|
+
if (responseText) messages.push({
|
|
243
|
+
role: "assistant",
|
|
244
|
+
content: responseText
|
|
245
|
+
});
|
|
246
|
+
try {
|
|
247
|
+
const { AutoMemory } = await Promise.resolve().then(() => require("./memory-auto-DTcy5VBy.js"));
|
|
248
|
+
const mem = new AutoMemory({ extractEveryNTurns: 3 });
|
|
249
|
+
mem.addTurn("user", text);
|
|
250
|
+
if (responseText) mem.addTurn("assistant", responseText);
|
|
251
|
+
mem.extract().catch(() => {});
|
|
252
|
+
} catch {}
|
|
253
|
+
prompt();
|
|
254
|
+
});
|
|
255
|
+
};
|
|
256
|
+
prompt();
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
//#endregion
|
|
261
|
+
exports.runChat = runChat;
|