@melaya/runner 1.0.72 → 1.0.74
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/dist/cli.js +2 -2
- package/dist/detect.d.ts +1 -4
- package/dist/detect.js +49 -1
- package/dist/pythonEnv.js +8 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -63,8 +63,8 @@ async function main() {
|
|
|
63
63
|
// Detect local models
|
|
64
64
|
const models = await detectModels();
|
|
65
65
|
if (models.length === 0) {
|
|
66
|
-
console.log(chalk.yellow(" ⚠ No local models detected (LM Studio / Ollama not running)"));
|
|
67
|
-
console.log(chalk.gray(" Start LM Studio or Ollama, then restart the runner"));
|
|
66
|
+
console.log(chalk.yellow(" ⚠ No local models detected (LM Studio / Ollama not running, Claude Code not logged in)"));
|
|
67
|
+
console.log(chalk.gray(" Start LM Studio or Ollama (or log in to Claude Code), then restart the runner"));
|
|
68
68
|
}
|
|
69
69
|
else {
|
|
70
70
|
for (const m of models) {
|
package/dist/detect.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auto-detect local LLM providers (LM Studio, Ollama) and list models.
|
|
3
|
-
*/
|
|
4
1
|
export interface DetectedModel {
|
|
5
|
-
provider: "lmstudio" | "ollama";
|
|
2
|
+
provider: "lmstudio" | "ollama" | "claude_code";
|
|
6
3
|
name: string;
|
|
7
4
|
}
|
|
8
5
|
export declare function detectModels(): Promise<DetectedModel[]>;
|
package/dist/detect.js
CHANGED
|
@@ -1,6 +1,52 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Auto-detect local LLM providers (LM Studio, Ollama
|
|
2
|
+
* Auto-detect local LLM providers (LM Studio, Ollama, Claude Code CLI)
|
|
3
|
+
* and list models.
|
|
3
4
|
*/
|
|
5
|
+
import { execFile } from "child_process";
|
|
6
|
+
import { promisify } from "util";
|
|
7
|
+
import { readFile } from "fs/promises";
|
|
8
|
+
import { homedir } from "os";
|
|
9
|
+
import { join } from "path";
|
|
10
|
+
const execFileAsync = promisify(execFile);
|
|
11
|
+
/** Claude Code is a subscription CLI — when it's logged in on this machine,
|
|
12
|
+
* report its model aliases so the platform's model picker shows TRUE
|
|
13
|
+
* availability for local runs (claude_code pipelines execute HERE).
|
|
14
|
+
*
|
|
15
|
+
* We read the CLI's OAuth credentials FILE directly rather than spawning
|
|
16
|
+
* `claude auth status`. That subprocess flashed a console window on Windows
|
|
17
|
+
* every time the runner started (`windowsHide` is unreliable through the
|
|
18
|
+
* `.cmd` shell wrapper, which spawns its own conhost). The file is the source
|
|
19
|
+
* of truth on Windows/Linux; macOS keeps the grant in the Keychain, where
|
|
20
|
+
* `security` is a subprocess but pops NO window. Zero windows, faster, and
|
|
21
|
+
* it mirrors exactly what the runtime (model.py `_read_claude_oauth`) reads. */
|
|
22
|
+
async function detectClaudeCode() {
|
|
23
|
+
let raw = null;
|
|
24
|
+
try {
|
|
25
|
+
raw = await readFile(join(homedir(), ".claude", ".credentials.json"), "utf8");
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
raw = null;
|
|
29
|
+
}
|
|
30
|
+
if (!raw && process.platform === "darwin") {
|
|
31
|
+
try {
|
|
32
|
+
const { stdout } = await execFileAsync("security", ["find-generic-password", "-s", "Claude Code-credentials", "-w"], { timeout: 8000 });
|
|
33
|
+
if (stdout && stdout.trim())
|
|
34
|
+
raw = stdout.trim();
|
|
35
|
+
}
|
|
36
|
+
catch { /* not in keychain */ }
|
|
37
|
+
}
|
|
38
|
+
if (!raw)
|
|
39
|
+
return [];
|
|
40
|
+
try {
|
|
41
|
+
const oauth = (JSON.parse(raw)?.claudeAiOauth ?? {});
|
|
42
|
+
const expiresAt = Number(oauth.expiresAt ?? 0);
|
|
43
|
+
if (oauth.accessToken && (!expiresAt || Date.now() < expiresAt)) {
|
|
44
|
+
return ["sonnet", "opus", "haiku"].map((name) => ({ provider: "claude_code", name }));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch { /* malformed creds → treat as logged out */ }
|
|
48
|
+
return []; // not logged in / expired → don't advertise models
|
|
49
|
+
}
|
|
4
50
|
export async function detectModels() {
|
|
5
51
|
const models = [];
|
|
6
52
|
// LM Studio — OpenAI-compatible at :1234
|
|
@@ -25,5 +71,7 @@ export async function detectModels() {
|
|
|
25
71
|
}
|
|
26
72
|
}
|
|
27
73
|
catch { /* not running */ }
|
|
74
|
+
// Claude Code CLI — subscription auth on THIS machine
|
|
75
|
+
models.push(...await detectClaudeCode());
|
|
28
76
|
return models;
|
|
29
77
|
}
|
package/dist/pythonEnv.js
CHANGED
|
@@ -109,6 +109,14 @@ const PIP_DEPS = [
|
|
|
109
109
|
// shared.tools.telegram_user_tools. The bot-API path in
|
|
110
110
|
// shared.tools.messaging.py uses plain HTTP and needs no extra dep.
|
|
111
111
|
"telethon",
|
|
112
|
+
// yfinance — TradFi/macro price history + live FX spot for the financial
|
|
113
|
+
// tools (shared.tools.alphavantage_tools yf_* + shared.tools.fx_tools live
|
|
114
|
+
// spot). BOTH modules guard the import (try/except at load + a
|
|
115
|
+
// _require_yfinance() that raises a clear "pip install yfinance" only when a
|
|
116
|
+
// yf_ tool is actually CALLED), so a runner without it still imports every
|
|
117
|
+
// tool module cleanly — this just makes the dep present so the yf_ tools work
|
|
118
|
+
// when attached. Pulls pandas transitively.
|
|
119
|
+
"yfinance",
|
|
112
120
|
// ── Vector RAG (retrieval mode) ────────────────────────────────────────
|
|
113
121
|
// ollama — Python client used by agentscope.embedding.OllamaTextEmbedding.
|
|
114
122
|
// Talks to localhost:11434 (the user's local Ollama daemon) to embed
|