hyperclaw 5.2.4 โ 5.2.5
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 +17 -111
- package/dist/chat-CbntPqAD.js +324 -0
- package/dist/daemon-BVz136O4.js +7 -0
- package/dist/daemon-rXG1-sEx.js +404 -0
- package/dist/engine-8auuZb7x.js +7 -0
- package/dist/engine-fLaefti6.js +323 -0
- package/dist/hyperclawbot-CFz_TKkS.js +508 -0
- package/dist/mcp-loader-CMtuM3oJ.js +93 -0
- package/dist/onboard-CO0j5jJ1.js +13 -0
- package/dist/onboard-cY-Emhr7.js +3865 -0
- package/dist/orchestrator-BJ08fjSq.js +6 -0
- package/dist/orchestrator-DrFHEhaP.js +189 -0
- package/dist/run-main.js +25 -25
- package/dist/server-CRqwlLX9.js +1294 -0
- package/dist/server-DqXe03-t.js +4 -0
- package/dist/skill-runtime-C-3EKfkr.js +102 -0
- package/dist/skill-runtime-CpPJV2Ga.js +5 -0
- package/dist/src-B3eBN96E.js +458 -0
- package/dist/src-sWcDdkdR.js +63 -0
- package/dist/sub-agent-tools-BI8UISC4.js +39 -0
- package/package.json +1 -1
- package/static/dashboard.html +1 -1
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
| | |
|
|
41
41
|
|---|---|
|
|
42
42
|
| [Why HyperClaw?](#why-hyperclaw) | [Use cases](#use-cases) |
|
|
43
|
-
| [Screenshots](#screenshots) | [๐ Get started in 60 seconds](#-get-started-in-60-seconds) |
|
|
43
|
+
| [Screenshots](#screenshots) ยท [๐ธ Full Gallery](SCREENSHOTS.md) | [๐ Get started in 60 seconds](#-get-started-in-60-seconds) |
|
|
44
44
|
| [โถ๏ธ Running your bot](#๏ธ-running-your-bot) | [Channels](#channels) |
|
|
45
45
|
| [Architecture](#architecture) | [AI Models](#ai-models) |
|
|
46
46
|
| [Channels](#channels) | [Configuration](#configuration) |
|
|
@@ -96,132 +96,38 @@
|
|
|
96
96
|
|
|
97
97
|
## Screenshots
|
|
98
98
|
|
|
99
|
-
### Main banner
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
</div>
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
### Daemon mode (`hyperclaw daemon start`)
|
|
108
|
-
|
|
109
|
-
<div align="center">
|
|
110
|
-
<img src="assets/screenshot-daemon-mode.png" width="700" alt="HyperClaw daemon mode โ ALWAYS WATCHING">
|
|
111
|
-
</div>
|
|
112
|
-
|
|
113
|
-
> Red `๐ฉธ DAEMON MODE - ALWAYS WATCHING ๐ฉธ` banner activates when running with full PC access.
|
|
114
|
-
> After starting, open `http://127.0.0.1:18789/chat` in your browser to chat with the agent.
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
### Setup wizard โ start (`hyperclaw onboard`)
|
|
119
|
-
|
|
120
|
-
<div align="center">
|
|
121
|
-
<img src="assets/screenshot-onboard-start.png" width="700" alt="HyperClaw onboard wizard start">
|
|
122
|
-
</div>
|
|
123
|
-
|
|
124
|
-
---
|
|
125
|
-
|
|
126
|
-
### Setup wizard โ AI providers
|
|
127
|
-
|
|
128
|
-
<div align="center">
|
|
129
|
-
<img src="assets/screenshot-onboard-providers.png" width="700" alt="HyperClaw onboard AI provider selection">
|
|
130
|
-
</div>
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
### Setup wizard โ API key step
|
|
135
|
-
|
|
136
|
-
<div align="center">
|
|
137
|
-
<img src="assets/screenshot-onboard-apikey.png" width="700" alt="HyperClaw onboard API key entry">
|
|
138
|
-
</div>
|
|
139
|
-
|
|
140
|
-
---
|
|
141
|
-
|
|
142
|
-
### Daemon install mode (`hyperclaw onboard --install-daemon`)
|
|
143
|
-
|
|
144
|
-
<div align="center">
|
|
145
|
-
<img src="assets/screenshot-onboard-daemon.png" width="700" alt="HyperClaw daemon install mode">
|
|
146
|
-
</div>
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
### Security notice
|
|
151
|
-
|
|
152
|
-
<div align="center">
|
|
153
|
-
<img src="assets/screenshot-security-notice.png" width="700" alt="HyperClaw security notice screen">
|
|
154
|
-
</div>
|
|
155
|
-
|
|
156
|
-
---
|
|
157
|
-
|
|
158
|
-
### Theme selection
|
|
159
|
-
|
|
160
|
-
<div align="center">
|
|
161
|
-
<img src="assets/screenshot-theme-select.png" width="700" alt="HyperClaw color theme selector">
|
|
162
|
-
</div>
|
|
163
|
-
|
|
164
|
-
---
|
|
165
|
-
|
|
166
|
-
### Gateway Dashboard (`hyperclaw dashboard`)
|
|
167
|
-
|
|
168
|
-
<div align="center">
|
|
169
|
-
<img src="assets/screenshot-dashboard.png" width="700" alt="HyperClaw Gateway Dashboard TUI">
|
|
170
|
-
</div>
|
|
171
|
-
|
|
172
|
-
> Live status, active channels, installed skills, and logs. Press `[d]` daemon ยท `[h]` hub ยท `[g]` gateway ยท `[m]` memory ยท `[q]` quit.
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
### Terminal chat (`hyperclaw chat`)
|
|
177
|
-
|
|
178
|
-
<div align="center">
|
|
179
|
-
<img src="assets/screenshot-chat.png" width="700" alt="HyperClaw terminal chat interface">
|
|
180
|
-
</div>
|
|
181
|
-
|
|
182
|
-
---
|
|
183
|
-
|
|
184
|
-
### All commands (`hyperclaw --help`)
|
|
185
|
-
|
|
99
|
+
### Main banner
|
|
100
|
+
```bash
|
|
101
|
+
hyperclaw
|
|
102
|
+
```
|
|
186
103
|
<div align="center">
|
|
187
|
-
<img src="assets/screenshot-
|
|
104
|
+
<img src="assets/screenshot-banner.png" width="720" alt="HyperClaw main banner with quick actions">
|
|
188
105
|
</div>
|
|
189
106
|
|
|
190
107
|
---
|
|
191
108
|
|
|
192
|
-
###
|
|
193
|
-
|
|
109
|
+
### ๐ต๏ธ OSINT / Ethical Hacking mode
|
|
110
|
+
```bash
|
|
111
|
+
hyperclaw osint
|
|
112
|
+
hyperclaw osint setup # interactive session setup
|
|
113
|
+
hyperclaw osint --show # show current profile
|
|
114
|
+
```
|
|
194
115
|
<div align="center">
|
|
195
|
-
<img src="assets/screenshot-
|
|
116
|
+
<img src="assets/screenshot-osint.png" width="720" alt="HyperClaw OSINT mode โ recon, bugbounty, pentest workflows">
|
|
196
117
|
</div>
|
|
197
118
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
### Health check (`hyperclaw health`)
|
|
201
|
-
|
|
202
|
-
<div align="center">
|
|
203
|
-
<img src="assets/screenshot-health.png" width="700" alt="HyperClaw health check output">
|
|
204
|
-
</div>
|
|
119
|
+
> Passive recon ยท Bug bounty ยท Pentest ยท Digital footprint โ all from your terminal.
|
|
120
|
+
> For authorized security research only. Always have written permission.
|
|
205
121
|
|
|
206
122
|
---
|
|
207
123
|
|
|
208
|
-
### Security tools (`hyperclaw security`)
|
|
209
|
-
|
|
210
124
|
<div align="center">
|
|
211
|
-
<img src="assets/screenshot-security.png" width="700" alt="HyperClaw security tools">
|
|
212
|
-
</div>
|
|
213
125
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
### OSINT / Ethical Hacking mode (`hyperclaw osint`)
|
|
126
|
+
**๐ See all screenshots โ wizard, dashboard, web UI, chat, themes, security and more:**
|
|
127
|
+
**[๐ธ Full Screenshots Gallery โ](SCREENSHOTS.md)**
|
|
217
128
|
|
|
218
|
-
<div align="center">
|
|
219
|
-
<img src="assets/screenshot-osint.png" width="700" alt="HyperClaw OSINT mode with recon, bugbounty, pentest workflows">
|
|
220
129
|
</div>
|
|
221
130
|
|
|
222
|
-
> Passive recon, bug bounty, pentest, digital footprint โ all from your terminal.
|
|
223
|
-
> For authorized security research only.
|
|
224
|
-
|
|
225
131
|
<div align="right"><a href="#top">โฒ Back to top</a></div>
|
|
226
132
|
|
|
227
133
|
---
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-jS-bbMI5.js');
|
|
2
|
+
const require_paths = require('./paths-AIyBxIzm.js');
|
|
3
|
+
require('./browser-tools-Btu_vB2d.js');
|
|
4
|
+
require('./src-CbTAVbeI.js');
|
|
5
|
+
const require_engine = require('./engine-fLaefti6.js');
|
|
6
|
+
require('./extraction-tools-BX5HGgko.js');
|
|
7
|
+
const require_inference = require('./inference-C2HOfRf8.js');
|
|
8
|
+
require('./memory-auto-CSUt3aas.js');
|
|
9
|
+
require('./orchestrator-DrFHEhaP.js');
|
|
10
|
+
require('./pc-access-D5k6dAfU.js');
|
|
11
|
+
require('./session-store-Bx7lBD_a.js');
|
|
12
|
+
require('./sessions-tools-DVSejkNU.js');
|
|
13
|
+
require('./skill-loader-99egKAGN.js');
|
|
14
|
+
require('./skill-runtime-C-3EKfkr.js');
|
|
15
|
+
require('./vision-tools-DnUjpQhI.js');
|
|
16
|
+
require('./website-watch-tools-Oxf8Mv4j.js');
|
|
17
|
+
const require_src$1 = require('./src-B3eBN96E.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 [id] /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("/model <id>")} โ switch model (e.g. /model claude-sonnet-4-5)`);
|
|
44
|
+
console.log(` ${chalk.default.cyan("/skills")} โ list installed skills + how to add more`);
|
|
45
|
+
console.log(` ${chalk.default.cyan("/help")} โ show this help`);
|
|
46
|
+
console.log();
|
|
47
|
+
console.log(chalk.default.gray(" Tip: you can also tell the agent to install a skill:"));
|
|
48
|
+
console.log(chalk.default.gray(" \"Install the web-search skill\" or paste a clawhub.ai link"));
|
|
49
|
+
console.log();
|
|
50
|
+
}
|
|
51
|
+
async function printSkills() {
|
|
52
|
+
console.log();
|
|
53
|
+
try {
|
|
54
|
+
const { loadSkills } = await Promise.resolve().then(() => require("./skill-loader-DwbmjEDa.js"));
|
|
55
|
+
const skills = await loadSkills();
|
|
56
|
+
if (skills.length === 0) console.log(chalk.default.gray(" No skills installed yet."));
|
|
57
|
+
else {
|
|
58
|
+
console.log(chalk.default.bold(" Installed skills:"));
|
|
59
|
+
for (const s of skills) {
|
|
60
|
+
console.log(` ${chalk.default.cyan("โข")} ${chalk.default.bold(s.title || s.id)} ${chalk.default.gray(`(${s.id})`)}`);
|
|
61
|
+
if (s.capabilities) console.log(chalk.default.gray(` ${s.capabilities}`));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
} catch (e) {
|
|
65
|
+
console.log(chalk.default.gray(" Could not load skills list."));
|
|
66
|
+
console.log(chalk.default.gray(` ${(e?.message || String(e)).slice(0, 80)}`));
|
|
67
|
+
console.log(chalk.default.gray(" Run: hyperclaw doctor or hyperclaw hub to check setup."));
|
|
68
|
+
}
|
|
69
|
+
console.log();
|
|
70
|
+
console.log(chalk.default.bold(" How to add a skill:"));
|
|
71
|
+
console.log(` ${chalk.default.gray("1.")} Tell the agent: ${chalk.default.cyan("\"Install the web-search skill\"")}`);
|
|
72
|
+
console.log(` ${chalk.default.gray("2.")} Paste a link: ${chalk.default.cyan("\"Install this: https://clawhub.ai/user/skill-name\"")}`);
|
|
73
|
+
console.log(` ${chalk.default.gray("3.")} CLI (outside chat): ${chalk.default.cyan("hyperclaw skill install <name>")}`);
|
|
74
|
+
console.log(` ${chalk.default.gray("4.")} Re-run wizard: ${chalk.default.cyan("hyperclaw onboard")}`);
|
|
75
|
+
console.log();
|
|
76
|
+
}
|
|
77
|
+
function makeSessionId() {
|
|
78
|
+
return Math.random().toString(36).slice(2, 9);
|
|
79
|
+
}
|
|
80
|
+
async function runChat(opts) {
|
|
81
|
+
const cfg = await fs_extra.default.readJson(require_paths.getConfigPath()).catch(() => null);
|
|
82
|
+
if (!cfg) {
|
|
83
|
+
console.log(chalk.default.red("\n No configuration found.\n"));
|
|
84
|
+
console.log(chalk.default.gray(" Chat works without the gateway. Run: hyperclaw onboard\n"));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const { getProviderCredentialAsync } = await Promise.resolve().then(() => require("./env-resolve-CC_po9t5.js"));
|
|
88
|
+
const apiKey = await getProviderCredentialAsync(cfg).catch(() => null);
|
|
89
|
+
const isLocal = [
|
|
90
|
+
"local",
|
|
91
|
+
"ollama",
|
|
92
|
+
"lmstudio"
|
|
93
|
+
].includes(cfg?.provider?.providerId ?? "");
|
|
94
|
+
if (!apiKey && !isLocal) {
|
|
95
|
+
console.log(chalk.default.red("\n No API key configured.\n"));
|
|
96
|
+
console.log(chalk.default.gray(" Chat uses your AI provider directly (no gateway needed). Run: hyperclaw config set-key\n"));
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const { getProvider } = await Promise.resolve().then(() => require("./providers-CFQC39vg.js"));
|
|
100
|
+
const providerMeta = getProvider(cfg?.provider?.providerId ?? "");
|
|
101
|
+
const CUSTOM_IDS = new Set([
|
|
102
|
+
"groq",
|
|
103
|
+
"mistral",
|
|
104
|
+
"deepseek",
|
|
105
|
+
"perplexity",
|
|
106
|
+
"huggingface",
|
|
107
|
+
"ollama",
|
|
108
|
+
"lmstudio",
|
|
109
|
+
"local",
|
|
110
|
+
"xai",
|
|
111
|
+
"openai",
|
|
112
|
+
"google",
|
|
113
|
+
"minimax",
|
|
114
|
+
"moonshot",
|
|
115
|
+
"qwen",
|
|
116
|
+
"zai",
|
|
117
|
+
"litellm",
|
|
118
|
+
"cloudflare",
|
|
119
|
+
"copilot",
|
|
120
|
+
"vercel-ai",
|
|
121
|
+
"opencode-zen"
|
|
122
|
+
]);
|
|
123
|
+
const isAnthropicVariant = [
|
|
124
|
+
"anthropic",
|
|
125
|
+
"anthropic-oauth",
|
|
126
|
+
"anthropic-setup-token"
|
|
127
|
+
].includes(cfg?.provider?.providerId ?? "");
|
|
128
|
+
const provider = isAnthropicVariant ? "anthropic" : cfg?.provider?.providerId === "custom" || isLocal || CUSTOM_IDS.has(cfg?.provider?.providerId ?? "") ? "custom" : "openrouter";
|
|
129
|
+
let rawModel = opts.model || cfg?.provider?.modelId || "claude-sonnet-4-5";
|
|
130
|
+
const model = rawModel.startsWith("ollama/") ? rawModel.slice(7) : rawModel;
|
|
131
|
+
const resolvedBaseUrl = cfg?.provider?.baseUrl || providerMeta?.baseUrl || (isLocal ? "http://localhost:11434/v1" : void 0);
|
|
132
|
+
const THINKING_BUDGET = {
|
|
133
|
+
high: 1e4,
|
|
134
|
+
medium: 4e3,
|
|
135
|
+
low: 1e3,
|
|
136
|
+
none: 0
|
|
137
|
+
};
|
|
138
|
+
const thinkingBudget = THINKING_BUDGET[opts.thinking ?? "none"] ?? 0;
|
|
139
|
+
const maxTokens = thinkingBudget > 0 ? thinkingBudget + 4096 : 4096;
|
|
140
|
+
const context = await require_engine.loadWorkspaceContext(opts.workspace) + await require_engine.loadSkillsContext();
|
|
141
|
+
const tools = await require_engine.resolveTools({
|
|
142
|
+
config: cfg,
|
|
143
|
+
source: "cli",
|
|
144
|
+
elevated: true,
|
|
145
|
+
daemonMode: false
|
|
146
|
+
});
|
|
147
|
+
const engineOpts = {
|
|
148
|
+
model,
|
|
149
|
+
apiKey,
|
|
150
|
+
provider,
|
|
151
|
+
system: context || void 0,
|
|
152
|
+
tools,
|
|
153
|
+
maxTokens,
|
|
154
|
+
onToken: () => {},
|
|
155
|
+
...provider === "custom" ? { baseUrl: resolvedBaseUrl || "" } : {},
|
|
156
|
+
...thinkingBudget > 0 && model.includes("claude") ? { thinking: { budget_tokens: thinkingBudget } } : {}
|
|
157
|
+
};
|
|
158
|
+
const sessionId = opts.sessionId ?? makeSessionId();
|
|
159
|
+
const messages = [];
|
|
160
|
+
let autoMem = null;
|
|
161
|
+
try {
|
|
162
|
+
const { AutoMemory } = await Promise.resolve().then(() => require("./memory-auto-D_mPVYqI.js"));
|
|
163
|
+
autoMem = new AutoMemory({ extractEveryNTurns: 3 });
|
|
164
|
+
} catch {}
|
|
165
|
+
printHeader(rawModel, sessionId);
|
|
166
|
+
try {
|
|
167
|
+
const { maybeShowUpdateNotice } = await Promise.resolve().then(() => require("./update-check-CaHNCDqe.js"));
|
|
168
|
+
maybeShowUpdateNotice();
|
|
169
|
+
} catch {}
|
|
170
|
+
const rl = readline.default.createInterface({
|
|
171
|
+
input: process.stdin,
|
|
172
|
+
output: process.stdout,
|
|
173
|
+
terminal: true
|
|
174
|
+
});
|
|
175
|
+
rl.on("SIGINT", () => {
|
|
176
|
+
console.log(chalk.default.gray("\n\n Bye!\n"));
|
|
177
|
+
rl.close();
|
|
178
|
+
process.exit(0);
|
|
179
|
+
});
|
|
180
|
+
await new Promise((resolve) => {
|
|
181
|
+
rl.on("close", resolve);
|
|
182
|
+
const prompt = () => {
|
|
183
|
+
rl.question(chalk.default.bold.green(" You โบ "), async (input) => {
|
|
184
|
+
const text = input.trim();
|
|
185
|
+
if (!text) {
|
|
186
|
+
prompt();
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
if ([
|
|
190
|
+
"/exit",
|
|
191
|
+
"/quit",
|
|
192
|
+
"/bye",
|
|
193
|
+
"exit",
|
|
194
|
+
"quit",
|
|
195
|
+
"bye"
|
|
196
|
+
].includes(text.toLowerCase())) {
|
|
197
|
+
console.log(chalk.default.gray("\n Bye!\n"));
|
|
198
|
+
rl.close();
|
|
199
|
+
process.exit(0);
|
|
200
|
+
}
|
|
201
|
+
if (text === "/help") {
|
|
202
|
+
printHelp();
|
|
203
|
+
prompt();
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (text === "/skills") {
|
|
207
|
+
await printSkills();
|
|
208
|
+
prompt();
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
if (text === "/model" || text.startsWith("/model ")) {
|
|
212
|
+
const newModelArg = text.slice(7).trim().replace(/^<|>$/g, "");
|
|
213
|
+
if (newModelArg) {
|
|
214
|
+
rawModel = newModelArg;
|
|
215
|
+
engineOpts.model = rawModel.startsWith("ollama/") ? rawModel.slice(7) : rawModel;
|
|
216
|
+
console.log(chalk.default.green(`\n โ Model switched to: ${chalk.default.bold(rawModel)}\n`));
|
|
217
|
+
} else if (providerMeta?.models?.length) {
|
|
218
|
+
rl.pause();
|
|
219
|
+
try {
|
|
220
|
+
const inquirer = (await import("inquirer")).default;
|
|
221
|
+
const defaultIdx = Math.max(0, providerMeta.models.findIndex((m) => m.id === rawModel));
|
|
222
|
+
const { selected } = await inquirer.prompt([{
|
|
223
|
+
type: "list",
|
|
224
|
+
name: "selected",
|
|
225
|
+
message: chalk.default.cyan("Select model") + chalk.default.gray(" (โโ arrows, Enter to confirm):"),
|
|
226
|
+
choices: providerMeta.models.map((m) => ({
|
|
227
|
+
name: `${m.id} ${chalk.default.gray(m.name)}`,
|
|
228
|
+
value: m.id,
|
|
229
|
+
short: m.id
|
|
230
|
+
})),
|
|
231
|
+
default: defaultIdx,
|
|
232
|
+
prefix: " "
|
|
233
|
+
}]);
|
|
234
|
+
rawModel = selected;
|
|
235
|
+
engineOpts.model = rawModel.startsWith("ollama/") ? rawModel.slice(7) : rawModel;
|
|
236
|
+
console.log(chalk.default.green(`\n โ Model switched to: ${chalk.default.bold(rawModel)}\n`));
|
|
237
|
+
} catch {
|
|
238
|
+
console.log(chalk.default.gray("\n Selection failed. Use: /model <model-id> (e.g. claude-sonnet-4-5)\n"));
|
|
239
|
+
} finally {
|
|
240
|
+
rl.resume();
|
|
241
|
+
}
|
|
242
|
+
} else {
|
|
243
|
+
console.log(chalk.default.gray(`\n Current model: ${chalk.default.bold(rawModel)}`));
|
|
244
|
+
console.log(chalk.default.gray(" Use: /model <model-id>\n"));
|
|
245
|
+
}
|
|
246
|
+
prompt();
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
if (text === "/clear") {
|
|
250
|
+
messages.length = 0;
|
|
251
|
+
console.log(chalk.default.gray("\n Conversation cleared.\n"));
|
|
252
|
+
prompt();
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
messages.push({
|
|
256
|
+
role: "user",
|
|
257
|
+
content: text
|
|
258
|
+
});
|
|
259
|
+
const spinner = (0, ora.default)({
|
|
260
|
+
text: chalk.default.gray("Thinking..."),
|
|
261
|
+
color: "cyan",
|
|
262
|
+
prefixText: " "
|
|
263
|
+
}).start();
|
|
264
|
+
let responseText = "";
|
|
265
|
+
try {
|
|
266
|
+
let prefixPrinted = false;
|
|
267
|
+
const engine = new require_inference.InferenceEngine({
|
|
268
|
+
...engineOpts,
|
|
269
|
+
onToken: (token) => {
|
|
270
|
+
if (spinner.isSpinning) spinner.stop();
|
|
271
|
+
if (!prefixPrinted) {
|
|
272
|
+
process.stdout.write(chalk.default.bold.blue("\n Agent โบ "));
|
|
273
|
+
prefixPrinted = true;
|
|
274
|
+
}
|
|
275
|
+
process.stdout.write(token);
|
|
276
|
+
},
|
|
277
|
+
onToolCall: (name) => {
|
|
278
|
+
if (spinner.isSpinning) spinner.stop();
|
|
279
|
+
console.log(chalk.default.gray(`\n [tool: ${name}]`));
|
|
280
|
+
prefixPrinted = false;
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
const result = await engine.run(messages);
|
|
284
|
+
responseText = result.text || "";
|
|
285
|
+
spinner.stop();
|
|
286
|
+
if (!prefixPrinted) {
|
|
287
|
+
process.stdout.write(chalk.default.bold.blue("\n Agent โบ "));
|
|
288
|
+
process.stdout.write(responseText || chalk.default.gray("(empty โ try rephrasing or check model/tools)"));
|
|
289
|
+
} else if (!responseText) process.stdout.write(chalk.default.gray("(empty โ try rephrasing or check model/tools)"));
|
|
290
|
+
console.log("\n");
|
|
291
|
+
if (result.usage) console.log(chalk.default.gray(` Tokens โ in: ${result.usage.input} out: ${result.usage.output}\n`));
|
|
292
|
+
} catch (e) {
|
|
293
|
+
spinner.stop();
|
|
294
|
+
const msg = e?.message || String(e);
|
|
295
|
+
responseText = `Error: ${msg}`;
|
|
296
|
+
console.log(chalk.default.red(`\n Error: ${msg}\n`));
|
|
297
|
+
const hint = (() => {
|
|
298
|
+
if (/401|unauthorized|invalid.*key|authentication/i.test(msg)) return "Check API key: hyperclaw config set-key";
|
|
299
|
+
if (/429|rate.?limit|quota/i.test(msg)) return "Rate limited. Wait a moment and retry.";
|
|
300
|
+
if (/500|503|service.?unavailable/i.test(msg)) return "Provider temporarily down. Try again later.";
|
|
301
|
+
if (/network|ECONNREFUSED|ETIMEDOUT|fetch failed/i.test(msg)) return "Network error. Check connection and base URL.";
|
|
302
|
+
if (/model|not found|invalid model/i.test(msg)) return "Try: /model <id> to switch model.";
|
|
303
|
+
return "Run: hyperclaw doctor for setup checks.";
|
|
304
|
+
})();
|
|
305
|
+
console.log(chalk.default.gray(` ${hint}\n`));
|
|
306
|
+
}
|
|
307
|
+
if (responseText) messages.push({
|
|
308
|
+
role: "assistant",
|
|
309
|
+
content: responseText
|
|
310
|
+
});
|
|
311
|
+
if (autoMem) {
|
|
312
|
+
autoMem.addTurn("user", text);
|
|
313
|
+
if (responseText) autoMem.addTurn("assistant", responseText);
|
|
314
|
+
autoMem.extract().catch(() => {});
|
|
315
|
+
}
|
|
316
|
+
prompt();
|
|
317
|
+
});
|
|
318
|
+
};
|
|
319
|
+
prompt();
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
//#endregion
|
|
324
|
+
exports.runChat = runChat;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-jS-bbMI5.js');
|
|
2
|
+
require('./paths-AIyBxIzm.js');
|
|
3
|
+
require('./paths-DPovhojT.js');
|
|
4
|
+
require('./server-CRqwlLX9.js');
|
|
5
|
+
const require_daemon = require('./daemon-rXG1-sEx.js');
|
|
6
|
+
|
|
7
|
+
exports.DaemonManager = require_daemon.DaemonManager;
|