ollanet 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/argv.d.ts +17 -0
- package/dist/argv.js +73 -0
- package/dist/bench.js +21 -61
- package/dist/chats.js +4 -6
- package/dist/compare.js +13 -63
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/prompt.js +22 -71
- package/dist/ps.js +4 -10
- package/dist/pull.js +7 -12
- package/dist/rm.js +7 -12
- package/dist/show.js +7 -12
- package/dist/target.d.ts +2 -0
- package/dist/target.js +10 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -176,7 +176,7 @@ await scanNetwork({
|
|
|
176
176
|
|
|
177
177
|
`pullModel({ machine, model })` asks that host to download (or update) a library model. The bits never transit ollanet. `showModel`, `removeModel({ yes: true })`, and `listLoaded` are the inspect / delete / VRAM trio.
|
|
178
178
|
|
|
179
|
-
Requires **ollanet ≥ 0.4.0** (library). **Model management (`pull` / `show` / `rm` / `ps`) needs ≥ 0.5.0.** **Compare, `lastScan`, and bench `--hot` need ≥ 0.6.0.** Bundlers (Vite / SvelteKit SSR):
|
|
179
|
+
Requires **ollanet ≥ 0.4.0** (library). **Model management (`pull` / `show` / `rm` / `ps`) needs ≥ 0.5.0.** **Compare, `lastScan`, and bench `--hot` need ≥ 0.6.0.** **`resolveTarget` / `listTargets` need ≥ 0.6.1.** Bundlers (Vite / SvelteKit SSR):
|
|
180
180
|
|
|
181
181
|
```ts
|
|
182
182
|
// vite.config.ts
|
package/dist/argv.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CLI flag helpers. Commands keep their own usage() and unique flags.
|
|
3
|
+
*/
|
|
4
|
+
import type { GenerateSettings } from "./config.js";
|
|
5
|
+
export type UsageFn = () => never;
|
|
6
|
+
export declare function takeValue(args: string[], flag: string, usage: UsageFn): string;
|
|
7
|
+
/** `--name value` or `--name=value`. Returns undefined if `arg` is not this flag. */
|
|
8
|
+
export declare function takeFlag(arg: string, name: string, args: string[], usage: UsageFn): string | undefined;
|
|
9
|
+
export declare function parseNumberFlag(raw: string, flag: string, usage: UsageFn): number;
|
|
10
|
+
export declare function parseKeepAlive(raw: string): string | number;
|
|
11
|
+
export interface SettingsFlagOpts {
|
|
12
|
+
temperature?: boolean;
|
|
13
|
+
numPredict?: boolean;
|
|
14
|
+
system?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** Shared generate-settings flags. Returns true when `arg` was consumed. */
|
|
17
|
+
export declare function consumeSettingsFlag(arg: string, args: string[], settings: GenerateSettings, usage: UsageFn, opts?: SettingsFlagOpts): boolean;
|
package/dist/argv.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export function takeValue(args, flag, usage) {
|
|
2
|
+
const value = args.shift();
|
|
3
|
+
if (!value) {
|
|
4
|
+
console.error(`${flag} requires a value`);
|
|
5
|
+
usage();
|
|
6
|
+
}
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
/** `--name value` or `--name=value`. Returns undefined if `arg` is not this flag. */
|
|
10
|
+
export function takeFlag(arg, name, args, usage) {
|
|
11
|
+
if (arg === name)
|
|
12
|
+
return takeValue(args, name, usage);
|
|
13
|
+
if (arg.startsWith(`${name}=`))
|
|
14
|
+
return arg.slice(name.length + 1);
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
export function parseNumberFlag(raw, flag, usage) {
|
|
18
|
+
const n = Number(raw);
|
|
19
|
+
if (!Number.isFinite(n)) {
|
|
20
|
+
console.error(`${flag} must be a number (got "${raw}")`);
|
|
21
|
+
usage();
|
|
22
|
+
}
|
|
23
|
+
return n;
|
|
24
|
+
}
|
|
25
|
+
export function parseKeepAlive(raw) {
|
|
26
|
+
const asNum = Number(raw);
|
|
27
|
+
return raw.trim() !== "" && Number.isFinite(asNum) && String(asNum) === raw ? asNum : raw;
|
|
28
|
+
}
|
|
29
|
+
/** Shared generate-settings flags. Returns true when `arg` was consumed. */
|
|
30
|
+
export function consumeSettingsFlag(arg, args, settings, usage, opts = {}) {
|
|
31
|
+
if (arg === "--think") {
|
|
32
|
+
settings.think = true;
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
if (arg === "--no-think") {
|
|
36
|
+
settings.think = false;
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
if (opts.system) {
|
|
40
|
+
const system = takeFlag(arg, "--system", args, usage);
|
|
41
|
+
if (system !== undefined) {
|
|
42
|
+
settings.system = system;
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (opts.temperature) {
|
|
47
|
+
if (arg === "-t" || arg === "--temperature" || arg.startsWith("--temperature=")) {
|
|
48
|
+
const raw = arg === "-t" || arg === "--temperature"
|
|
49
|
+
? takeValue(args, "--temperature", usage)
|
|
50
|
+
: arg.slice("--temperature=".length);
|
|
51
|
+
settings.temperature = parseNumberFlag(raw, "--temperature", usage);
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (opts.numPredict) {
|
|
56
|
+
const raw = takeFlag(arg, "--num-predict", args, usage);
|
|
57
|
+
if (raw !== undefined) {
|
|
58
|
+
settings.num_predict = Math.trunc(parseNumberFlag(raw, "--num-predict", usage));
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const numCtx = takeFlag(arg, "--num-ctx", args, usage);
|
|
63
|
+
if (numCtx !== undefined) {
|
|
64
|
+
settings.num_ctx = Math.trunc(parseNumberFlag(numCtx, "--num-ctx", usage));
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
const keepAlive = takeFlag(arg, "--keep-alive", args, usage);
|
|
68
|
+
if (keepAlive !== undefined) {
|
|
69
|
+
settings.keep_alive = parseKeepAlive(keepAlive);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
}
|
package/dist/bench.js
CHANGED
|
@@ -5,7 +5,9 @@ import { defaultModelForHost, loadConfig, machineSettingsForHost, mergeSettings,
|
|
|
5
5
|
import { comparabilityKey, getSuiteCases, median, suiteRevision, } from "./bench-suite.js";
|
|
6
6
|
import { benchmarksDir, newBenchId, saveBenchmark } from "./bench-store.js";
|
|
7
7
|
import { readFile } from "node:fs/promises";
|
|
8
|
-
import {
|
|
8
|
+
import { envInt, ollamaBaseUrl, shortName } from "./hosts.js";
|
|
9
|
+
import { consumeSettingsFlag, parseNumberFlag, takeFlag } from "./argv.js";
|
|
10
|
+
import { resolveTarget } from "./target.js";
|
|
9
11
|
import { projectPath } from "./paths.js";
|
|
10
12
|
import { contextLengthForModel, isCompletionCapable, isVisionCapable, ollamaChat, ollamaShow, ollamaTags, ollamaUnload, ollamaVersion, ollamaPs, psHasModel, shouldWarnNoThinking, vramForModel, waitUntilUnloaded, } from "./ollama-chat.js";
|
|
11
13
|
const MODEL_COL = 34;
|
|
@@ -41,22 +43,6 @@ Options:
|
|
|
41
43
|
See docs/bench-spec.md for measurement rules.`);
|
|
42
44
|
process.exit(1);
|
|
43
45
|
}
|
|
44
|
-
function takeValue(args, flag) {
|
|
45
|
-
const value = args.shift();
|
|
46
|
-
if (!value) {
|
|
47
|
-
console.error(`${flag} requires a value`);
|
|
48
|
-
usage();
|
|
49
|
-
}
|
|
50
|
-
return value;
|
|
51
|
-
}
|
|
52
|
-
function parseNumberFlag(raw, flag) {
|
|
53
|
-
const n = Number(raw);
|
|
54
|
-
if (!Number.isFinite(n)) {
|
|
55
|
-
console.error(`${flag} must be a number (got "${raw}")`);
|
|
56
|
-
usage();
|
|
57
|
-
}
|
|
58
|
-
return n;
|
|
59
|
-
}
|
|
60
46
|
function isLoopback(host) {
|
|
61
47
|
return (host.source === "localhost" ||
|
|
62
48
|
host.ip === "127.0.0.1" ||
|
|
@@ -157,57 +143,35 @@ function parseArgs(argv) {
|
|
|
157
143
|
failOnError = true;
|
|
158
144
|
continue;
|
|
159
145
|
}
|
|
160
|
-
if (arg === "--think") {
|
|
161
|
-
settings.think = true;
|
|
162
|
-
continue;
|
|
163
|
-
}
|
|
164
|
-
if (arg === "--no-think") {
|
|
165
|
-
settings.think = false;
|
|
166
|
-
continue;
|
|
167
|
-
}
|
|
168
146
|
if (arg === "--judge") {
|
|
169
147
|
judge = true;
|
|
170
148
|
continue;
|
|
171
149
|
}
|
|
172
|
-
if (arg
|
|
173
|
-
const raw = arg.includes("=") ? arg.slice("--suite=".length) : takeValue(args, "--suite");
|
|
174
|
-
if (raw !== "quick" && raw !== "full") {
|
|
175
|
-
console.error(`Unknown suite "${raw}" (use quick|full)`);
|
|
176
|
-
usage();
|
|
177
|
-
}
|
|
178
|
-
suite = raw;
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
if (arg === "--runs" || arg.startsWith("--runs=")) {
|
|
182
|
-
const raw = arg.includes("=") ? arg.slice("--runs=".length) : takeValue(args, "--runs");
|
|
183
|
-
runs = Math.max(1, Math.trunc(parseNumberFlag(raw, "--runs")));
|
|
150
|
+
if (consumeSettingsFlag(arg, args, settings, usage)) {
|
|
184
151
|
continue;
|
|
185
152
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
153
|
+
const suiteRaw = takeFlag(arg, "--suite", args, usage);
|
|
154
|
+
if (suiteRaw !== undefined) {
|
|
155
|
+
if (suiteRaw !== "quick" && suiteRaw !== "full") {
|
|
156
|
+
console.error(`Unknown suite "${suiteRaw}" (use quick|full)`);
|
|
157
|
+
usage();
|
|
158
|
+
}
|
|
159
|
+
suite = suiteRaw;
|
|
191
160
|
continue;
|
|
192
161
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
162
|
+
const runsRaw = takeFlag(arg, "--runs", args, usage);
|
|
163
|
+
if (runsRaw !== undefined) {
|
|
164
|
+
runs = Math.max(1, Math.trunc(parseNumberFlag(runsRaw, "--runs", usage)));
|
|
196
165
|
continue;
|
|
197
166
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
: takeValue(args, "--keep-alive");
|
|
202
|
-
const asNum = Number(raw);
|
|
203
|
-
settings.keep_alive =
|
|
204
|
-
raw.trim() !== "" && Number.isFinite(asNum) && String(asNum) === raw ? asNum : raw;
|
|
167
|
+
const predictRaw = takeFlag(arg, "--num-predict", args, usage);
|
|
168
|
+
if (predictRaw !== undefined) {
|
|
169
|
+
throughputNumPredict = Math.trunc(parseNumberFlag(predictRaw, "--num-predict", usage));
|
|
205
170
|
continue;
|
|
206
171
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
: takeValue(args, "--judge-model");
|
|
172
|
+
const judgeRaw = takeFlag(arg, "--judge-model", args, usage);
|
|
173
|
+
if (judgeRaw !== undefined) {
|
|
174
|
+
judgeModel = judgeRaw;
|
|
211
175
|
continue;
|
|
212
176
|
}
|
|
213
177
|
if (arg.startsWith("-")) {
|
|
@@ -527,11 +491,7 @@ function pad(s, n) {
|
|
|
527
491
|
export async function main() {
|
|
528
492
|
const parsed = parseArgs(process.argv.slice(2));
|
|
529
493
|
const config = await loadConfig();
|
|
530
|
-
const
|
|
531
|
-
hosts: config.hosts,
|
|
532
|
-
discovery: config.discovery,
|
|
533
|
-
});
|
|
534
|
-
const host = resolveHost(targets, parsed.machine);
|
|
494
|
+
const host = await resolveTarget(parsed.machine, config);
|
|
535
495
|
const baseUrl = ollamaBaseUrl(host);
|
|
536
496
|
const machineLabel = shortName(host);
|
|
537
497
|
const tags = await ollamaTags(baseUrl, Math.min(BENCH_TIMEOUT_MS, 15_000));
|
package/dist/chats.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* ollanet chats --id a1b2c3d4e5f6
|
|
8
8
|
*/
|
|
9
9
|
import { loadChat, listChats, responsesDir, } from "./chat-store.js";
|
|
10
|
+
import { takeFlag } from "./argv.js";
|
|
10
11
|
function usage() {
|
|
11
12
|
console.error(`Usage: ollanet chats [--json] [--id <hash>]
|
|
12
13
|
|
|
@@ -31,12 +32,9 @@ function parseArgs(argv) {
|
|
|
31
32
|
json = true;
|
|
32
33
|
continue;
|
|
33
34
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
console.error("--id requires a value");
|
|
38
|
-
usage();
|
|
39
|
-
}
|
|
35
|
+
const idFlag = takeFlag(arg, "--id", args, usage);
|
|
36
|
+
if (idFlag !== undefined) {
|
|
37
|
+
id = idFlag;
|
|
40
38
|
continue;
|
|
41
39
|
}
|
|
42
40
|
console.error(`Unknown flag: ${arg}`);
|
package/dist/compare.js
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
* ollanet compare studio m1 m2 --file task.md
|
|
6
6
|
*/
|
|
7
7
|
import { configFromPartial, loadConfig, machineSettingsForHost, mergeSettings, settingsFromEnv, } from "./config.js";
|
|
8
|
-
import {
|
|
8
|
+
import { envInt, ollamaBaseUrl, shortName } from "./hosts.js";
|
|
9
|
+
import { consumeSettingsFlag, takeFlag, takeValue } from "./argv.js";
|
|
10
|
+
import { resolveTarget } from "./target.js";
|
|
9
11
|
import { ollamaChat, ollamaTags, ollamaUnload, waitUntilUnloaded, } from "./ollama-chat.js";
|
|
10
12
|
import { assemblePrompt, readPromptFile } from "./prompt-input.js";
|
|
11
13
|
import { comparesDir, newCompareId, saveCompare } from "./compare-store.js";
|
|
@@ -50,22 +52,6 @@ Options:
|
|
|
50
52
|
--json Emit the full record on stdout`);
|
|
51
53
|
process.exit(1);
|
|
52
54
|
}
|
|
53
|
-
function takeValue(args, flag) {
|
|
54
|
-
const value = args.shift();
|
|
55
|
-
if (!value) {
|
|
56
|
-
console.error(`${flag} requires a value`);
|
|
57
|
-
usage();
|
|
58
|
-
}
|
|
59
|
-
return value;
|
|
60
|
-
}
|
|
61
|
-
function parseNumberFlag(raw, flag) {
|
|
62
|
-
const n = Number(raw);
|
|
63
|
-
if (!Number.isFinite(n)) {
|
|
64
|
-
console.error(`${flag} must be a number (got "${raw}")`);
|
|
65
|
-
usage();
|
|
66
|
-
}
|
|
67
|
-
return n;
|
|
68
|
-
}
|
|
69
55
|
function parseArgs(argv) {
|
|
70
56
|
const args = [...argv];
|
|
71
57
|
let prompt;
|
|
@@ -93,48 +79,19 @@ function parseArgs(argv) {
|
|
|
93
79
|
unload = true;
|
|
94
80
|
continue;
|
|
95
81
|
}
|
|
96
|
-
if (arg
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
settings.think = false;
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
if (arg === "--prompt" || arg === "-p" || arg.startsWith("--prompt=")) {
|
|
105
|
-
prompt = arg.includes("=") ? arg.slice("--prompt=".length) : takeValue(args, "--prompt");
|
|
82
|
+
if (consumeSettingsFlag(arg, args, settings, usage, {
|
|
83
|
+
temperature: true,
|
|
84
|
+
numPredict: true,
|
|
85
|
+
system: true,
|
|
86
|
+
})) {
|
|
106
87
|
continue;
|
|
107
88
|
}
|
|
108
|
-
if (arg === "
|
|
109
|
-
|
|
89
|
+
if (arg === "-p" || arg === "--prompt" || arg.startsWith("--prompt=")) {
|
|
90
|
+
prompt = arg === "-p" ? takeValue(args, "--prompt", usage) : takeFlag(arg, "--prompt", args, usage);
|
|
110
91
|
continue;
|
|
111
92
|
}
|
|
112
|
-
if (arg === "--
|
|
113
|
-
|
|
114
|
-
? arg.slice("--system=".length)
|
|
115
|
-
: takeValue(args, "--system");
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
if (arg === "--temperature" || arg === "-t" || arg.startsWith("--temperature=")) {
|
|
119
|
-
const raw = arg.includes("=") ? arg.slice("--temperature=".length) : takeValue(args, "--temperature");
|
|
120
|
-
settings.temperature = parseNumberFlag(raw, "--temperature");
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
if (arg === "--num-predict" || arg.startsWith("--num-predict=")) {
|
|
124
|
-
const raw = arg.includes("=") ? arg.slice("--num-predict=".length) : takeValue(args, "--num-predict");
|
|
125
|
-
settings.num_predict = Math.trunc(parseNumberFlag(raw, "--num-predict"));
|
|
126
|
-
continue;
|
|
127
|
-
}
|
|
128
|
-
if (arg === "--num-ctx" || arg.startsWith("--num-ctx=")) {
|
|
129
|
-
const raw = arg.includes("=") ? arg.slice("--num-ctx=".length) : takeValue(args, "--num-ctx");
|
|
130
|
-
settings.num_ctx = Math.trunc(parseNumberFlag(raw, "--num-ctx"));
|
|
131
|
-
continue;
|
|
132
|
-
}
|
|
133
|
-
if (arg === "--keep-alive" || arg.startsWith("--keep-alive=")) {
|
|
134
|
-
const raw = arg.includes("=") ? arg.slice("--keep-alive=".length) : takeValue(args, "--keep-alive");
|
|
135
|
-
const asNum = Number(raw);
|
|
136
|
-
settings.keep_alive =
|
|
137
|
-
raw.trim() !== "" && Number.isFinite(asNum) && String(asNum) === raw ? asNum : raw;
|
|
93
|
+
if (arg === "-f" || arg === "--file" || arg.startsWith("--file=")) {
|
|
94
|
+
file = arg === "-f" ? takeValue(args, "--file", usage) : takeFlag(arg, "--file", args, usage);
|
|
138
95
|
continue;
|
|
139
96
|
}
|
|
140
97
|
if (arg.startsWith("-")) {
|
|
@@ -189,14 +146,7 @@ export async function runCompare(opts) {
|
|
|
189
146
|
const defaulted = !assembled;
|
|
190
147
|
const prompt = assembled || DEFAULT_COMPARE_PROMPT;
|
|
191
148
|
const config = opts.config ? configFromPartial(opts.config) : await loadConfig();
|
|
192
|
-
const
|
|
193
|
-
hosts: config.hosts,
|
|
194
|
-
discovery: config.discovery,
|
|
195
|
-
});
|
|
196
|
-
const host = resolveHost(hosts, opts.machine);
|
|
197
|
-
if (!host.online && !host.isSelf && host.source === "tailscale") {
|
|
198
|
-
throw new Error(`Machine "${shortName(host)}" appears offline.`);
|
|
199
|
-
}
|
|
149
|
+
const host = await resolveTarget(opts.machine, config);
|
|
200
150
|
const baseUrl = ollamaBaseUrl(host);
|
|
201
151
|
const timeoutMs = opts.timeoutMs ?? compareTimeoutMs();
|
|
202
152
|
let available = null;
|
package/dist/index.d.ts
CHANGED
|
@@ -29,5 +29,6 @@ export type { RemoveOptions, RemoveResult } from "./rm.js";
|
|
|
29
29
|
export { listLoaded } from "./ps.js";
|
|
30
30
|
export type { PsOptions, PsResult, LoadedHost, LoadedModel } from "./ps.js";
|
|
31
31
|
export { looksTuned } from "./tuned.js";
|
|
32
|
+
export { resolveTarget, listTargets } from "./target.js";
|
|
32
33
|
export { ollamaChat, ollamaTags, ollamaShow, ollamaPs, ollamaPsRequired, ollamaPull, ollamaDelete, } from "./ollama-chat.js";
|
|
33
34
|
export type { PullChunk, OllamaPullOptions, OllamaPullResult, OllamaShowInfo, } from "./ollama-chat.js";
|
package/dist/index.js
CHANGED
|
@@ -19,4 +19,5 @@ export { showModel } from "./show.js";
|
|
|
19
19
|
export { removeModel } from "./rm.js";
|
|
20
20
|
export { listLoaded } from "./ps.js";
|
|
21
21
|
export { looksTuned } from "./tuned.js";
|
|
22
|
+
export { resolveTarget, listTargets } from "./target.js";
|
|
22
23
|
export { ollamaChat, ollamaTags, ollamaShow, ollamaPs, ollamaPsRequired, ollamaPull, ollamaDelete, } from "./ollama-chat.js";
|
package/dist/prompt.js
CHANGED
|
@@ -14,9 +14,11 @@
|
|
|
14
14
|
import { stdin as stdinStream } from "node:process";
|
|
15
15
|
import { appendMessage, cleanTopic, createChat, loadChat, saveChat, toApiMessages, topicFromPrompt, } from "./chat-store.js";
|
|
16
16
|
import { configPath, defaultModelForHost, loadConfig, machineSettingsForHost, mergeSettings, parseFormat, settingsFromEnv, settingsSummary, configFromPartial, } from "./config.js";
|
|
17
|
-
import {
|
|
17
|
+
import { envInt, findDiscoveredHost, ollamaBaseUrl, resolveHost, shortName, } from "./hosts.js";
|
|
18
18
|
import { ollamaChat } from "./ollama-chat.js";
|
|
19
19
|
import { assemblePrompt, readPromptFile } from "./prompt-input.js";
|
|
20
|
+
import { consumeSettingsFlag, takeFlag, takeValue } from "./argv.js";
|
|
21
|
+
import { listTargets, resolveTarget } from "./target.js";
|
|
20
22
|
/** Prompt/chat HTTP timeout (ms). 0 = no timeout. Separate from scan's OLLAMA_TIMEOUT_MS. */
|
|
21
23
|
function promptTimeoutMs() {
|
|
22
24
|
return envInt("OLLAMA_PROMPT_TIMEOUT_MS", 600_000);
|
|
@@ -119,22 +121,6 @@ async function maybePeelModel(host, promptParts, fromStdin) {
|
|
|
119
121
|
}
|
|
120
122
|
return { promptParts };
|
|
121
123
|
}
|
|
122
|
-
function takeValue(args, flag) {
|
|
123
|
-
const value = args.shift();
|
|
124
|
-
if (!value) {
|
|
125
|
-
console.error(`${flag} requires a value`);
|
|
126
|
-
usage();
|
|
127
|
-
}
|
|
128
|
-
return value;
|
|
129
|
-
}
|
|
130
|
-
function parseNumberFlag(raw, flag) {
|
|
131
|
-
const n = Number(raw);
|
|
132
|
-
if (!Number.isFinite(n)) {
|
|
133
|
-
console.error(`${flag} must be a number (got "${raw}")`);
|
|
134
|
-
usage();
|
|
135
|
-
}
|
|
136
|
-
return n;
|
|
137
|
-
}
|
|
138
124
|
function parseArgs(argv) {
|
|
139
125
|
const args = [...argv];
|
|
140
126
|
let machineFlag;
|
|
@@ -165,59 +151,34 @@ function parseArgs(argv) {
|
|
|
165
151
|
save = false;
|
|
166
152
|
continue;
|
|
167
153
|
}
|
|
168
|
-
if (arg
|
|
169
|
-
|
|
154
|
+
if (consumeSettingsFlag(arg, args, settings, usage, {
|
|
155
|
+
temperature: true,
|
|
156
|
+
numPredict: true,
|
|
157
|
+
system: true,
|
|
158
|
+
})) {
|
|
170
159
|
continue;
|
|
171
160
|
}
|
|
172
|
-
|
|
173
|
-
|
|
161
|
+
const chat = takeFlag(arg, "--chat", args, usage);
|
|
162
|
+
if (chat !== undefined) {
|
|
163
|
+
chatId = chat;
|
|
174
164
|
continue;
|
|
175
165
|
}
|
|
176
|
-
|
|
177
|
-
|
|
166
|
+
const machine = takeFlag(arg, "--machine", args, usage);
|
|
167
|
+
if (machine !== undefined) {
|
|
168
|
+
machineFlag = machine;
|
|
178
169
|
continue;
|
|
179
170
|
}
|
|
180
|
-
|
|
181
|
-
|
|
171
|
+
const model = takeFlag(arg, "--model", args, usage);
|
|
172
|
+
if (model !== undefined) {
|
|
173
|
+
modelFlag = model;
|
|
182
174
|
continue;
|
|
183
175
|
}
|
|
184
|
-
if (arg === "--
|
|
185
|
-
|
|
186
|
-
continue;
|
|
187
|
-
}
|
|
188
|
-
if (arg === "--file" || arg === "-f" || arg.startsWith("--file=")) {
|
|
189
|
-
file = arg.includes("=") ? arg.slice("--file=".length) : takeValue(args, "--file");
|
|
190
|
-
continue;
|
|
191
|
-
}
|
|
192
|
-
if (arg === "--system" || arg.startsWith("--system=")) {
|
|
193
|
-
settings.system = arg.includes("=")
|
|
194
|
-
? arg.slice("--system=".length)
|
|
195
|
-
: takeValue(args, "--system");
|
|
196
|
-
continue;
|
|
197
|
-
}
|
|
198
|
-
if (arg === "--temperature" || arg === "-t" || arg.startsWith("--temperature=")) {
|
|
199
|
-
const raw = arg.includes("=") ? arg.slice("--temperature=".length) : takeValue(args, "--temperature");
|
|
200
|
-
settings.temperature = parseNumberFlag(raw, "--temperature");
|
|
201
|
-
continue;
|
|
202
|
-
}
|
|
203
|
-
if (arg === "--num-predict" || arg.startsWith("--num-predict=")) {
|
|
204
|
-
const raw = arg.includes("=") ? arg.slice("--num-predict=".length) : takeValue(args, "--num-predict");
|
|
205
|
-
settings.num_predict = Math.trunc(parseNumberFlag(raw, "--num-predict"));
|
|
206
|
-
continue;
|
|
207
|
-
}
|
|
208
|
-
if (arg === "--num-ctx" || arg.startsWith("--num-ctx=")) {
|
|
209
|
-
const raw = arg.includes("=") ? arg.slice("--num-ctx=".length) : takeValue(args, "--num-ctx");
|
|
210
|
-
settings.num_ctx = Math.trunc(parseNumberFlag(raw, "--num-ctx"));
|
|
211
|
-
continue;
|
|
212
|
-
}
|
|
213
|
-
if (arg === "--keep-alive" || arg.startsWith("--keep-alive=")) {
|
|
214
|
-
const raw = arg.includes("=") ? arg.slice("--keep-alive=".length) : takeValue(args, "--keep-alive");
|
|
215
|
-
const asNum = Number(raw);
|
|
216
|
-
settings.keep_alive = raw.trim() !== "" && Number.isFinite(asNum) && String(asNum) === raw ? asNum : raw;
|
|
176
|
+
if (arg === "-f" || arg === "--file" || arg.startsWith("--file=")) {
|
|
177
|
+
file = arg === "-f" ? takeValue(args, "--file", usage) : takeFlag(arg, "--file", args, usage);
|
|
217
178
|
continue;
|
|
218
179
|
}
|
|
219
180
|
if (arg === "--format" || arg.startsWith("--format=")) {
|
|
220
|
-
const raw = arg
|
|
181
|
+
const raw = takeFlag(arg, "--format", args, usage) ?? "";
|
|
221
182
|
const format = parseFormat(raw);
|
|
222
183
|
if (format !== undefined)
|
|
223
184
|
settings.format = format;
|
|
@@ -325,10 +286,6 @@ export async function runPrompt(opts) {
|
|
|
325
286
|
const writeStdout = opts.writeStdout !== false;
|
|
326
287
|
let promptParts = opts.prompt ? [opts.prompt] : [];
|
|
327
288
|
const config = opts.config ? configFromPartial(opts.config) : await loadConfig();
|
|
328
|
-
const { hosts: targets } = await discoverHosts({
|
|
329
|
-
hosts: config.hosts,
|
|
330
|
-
discovery: config.discovery,
|
|
331
|
-
});
|
|
332
289
|
let chat;
|
|
333
290
|
let isNewChat = false;
|
|
334
291
|
let machineQuery = opts.machine;
|
|
@@ -339,10 +296,7 @@ export async function runPrompt(opts) {
|
|
|
339
296
|
if (!machineQuery) {
|
|
340
297
|
throw new Error("Machine is required for a new chat (or pass chatId).");
|
|
341
298
|
}
|
|
342
|
-
const host =
|
|
343
|
-
if (!host.online && !host.isSelf && host.source === "tailscale") {
|
|
344
|
-
throw new Error(`Machine "${shortName(host)}" appears offline.`);
|
|
345
|
-
}
|
|
299
|
+
const host = await resolveTarget(machineQuery, config);
|
|
346
300
|
let peeledModel;
|
|
347
301
|
if (!opts.chatId && !opts.model) {
|
|
348
302
|
const peeled = await maybePeelModel(host, promptParts, "");
|
|
@@ -456,10 +410,7 @@ export async function main() {
|
|
|
456
410
|
}
|
|
457
411
|
}
|
|
458
412
|
const config = await loadConfig();
|
|
459
|
-
const
|
|
460
|
-
hosts: config.hosts,
|
|
461
|
-
discovery: config.discovery,
|
|
462
|
-
});
|
|
413
|
+
const targets = await listTargets(config);
|
|
463
414
|
let machineQuery = parsed.machine;
|
|
464
415
|
if (parsed.chatId) {
|
|
465
416
|
// Allow `ollanet prompt <host> --chat HASH "follow-up"` only when the
|
package/dist/ps.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { configFromPartial, loadConfig } from "./config.js";
|
|
8
8
|
import { discoverHosts, envInt, ollamaBaseUrl, shortName, } from "./hosts.js";
|
|
9
9
|
import { ollamaPs, ollamaPsRequired } from "./ollama-chat.js";
|
|
10
|
+
import { takeFlag } from "./argv.js";
|
|
10
11
|
import { resolveTarget } from "./target.js";
|
|
11
12
|
import { looksTuned } from "./tuned.js";
|
|
12
13
|
function psTimeoutMs() {
|
|
@@ -29,14 +30,6 @@ Options:
|
|
|
29
30
|
--json Emit result JSON on stdout`);
|
|
30
31
|
process.exit(1);
|
|
31
32
|
}
|
|
32
|
-
function takeValue(args, flag) {
|
|
33
|
-
const value = args.shift();
|
|
34
|
-
if (!value) {
|
|
35
|
-
console.error(`${flag} requires a value`);
|
|
36
|
-
usage();
|
|
37
|
-
}
|
|
38
|
-
return value;
|
|
39
|
-
}
|
|
40
33
|
function parseArgs(argv) {
|
|
41
34
|
const args = [...argv];
|
|
42
35
|
let machineFlag;
|
|
@@ -52,8 +45,9 @@ function parseArgs(argv) {
|
|
|
52
45
|
json = true;
|
|
53
46
|
continue;
|
|
54
47
|
}
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
const machine = takeFlag(arg, "--machine", args, usage);
|
|
49
|
+
if (machine !== undefined) {
|
|
50
|
+
machineFlag = machine;
|
|
57
51
|
continue;
|
|
58
52
|
}
|
|
59
53
|
if (arg.startsWith("-")) {
|
package/dist/pull.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { envInt, ollamaBaseUrl, shortName } from "./hosts.js";
|
|
10
10
|
import { ollamaPull } from "./ollama-chat.js";
|
|
11
|
+
import { takeFlag } from "./argv.js";
|
|
11
12
|
import { resolveTarget } from "./target.js";
|
|
12
13
|
/** Pull HTTP timeout (ms). 0 = none. Large models can take hours. */
|
|
13
14
|
function pullTimeoutMs() {
|
|
@@ -35,14 +36,6 @@ Options:
|
|
|
35
36
|
--json Emit result JSON on stdout`);
|
|
36
37
|
process.exit(1);
|
|
37
38
|
}
|
|
38
|
-
function takeValue(args, flag) {
|
|
39
|
-
const value = args.shift();
|
|
40
|
-
if (!value) {
|
|
41
|
-
console.error(`${flag} requires a value`);
|
|
42
|
-
usage();
|
|
43
|
-
}
|
|
44
|
-
return value;
|
|
45
|
-
}
|
|
46
39
|
function parseArgs(argv) {
|
|
47
40
|
const args = [...argv];
|
|
48
41
|
let machineFlag;
|
|
@@ -69,12 +62,14 @@ function parseArgs(argv) {
|
|
|
69
62
|
json = true;
|
|
70
63
|
continue;
|
|
71
64
|
}
|
|
72
|
-
|
|
73
|
-
|
|
65
|
+
const machine = takeFlag(arg, "--machine", args, usage);
|
|
66
|
+
if (machine !== undefined) {
|
|
67
|
+
machineFlag = machine;
|
|
74
68
|
continue;
|
|
75
69
|
}
|
|
76
|
-
|
|
77
|
-
|
|
70
|
+
const model = takeFlag(arg, "--model", args, usage);
|
|
71
|
+
if (model !== undefined) {
|
|
72
|
+
modelFlag = model;
|
|
78
73
|
continue;
|
|
79
74
|
}
|
|
80
75
|
if (arg.startsWith("-")) {
|
package/dist/rm.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { createInterface } from "node:readline";
|
|
7
7
|
import { envInt, ollamaBaseUrl, shortName } from "./hosts.js";
|
|
8
8
|
import { ollamaDelete } from "./ollama-chat.js";
|
|
9
|
+
import { takeFlag } from "./argv.js";
|
|
9
10
|
import { resolveTarget } from "./target.js";
|
|
10
11
|
function rmTimeoutMs() {
|
|
11
12
|
return envInt("OLLAMA_RM_TIMEOUT_MS", 30_000);
|
|
@@ -29,14 +30,6 @@ Options:
|
|
|
29
30
|
--json Emit result JSON on stdout`);
|
|
30
31
|
process.exit(1);
|
|
31
32
|
}
|
|
32
|
-
function takeValue(args, flag) {
|
|
33
|
-
const value = args.shift();
|
|
34
|
-
if (!value) {
|
|
35
|
-
console.error(`${flag} requires a value`);
|
|
36
|
-
usage();
|
|
37
|
-
}
|
|
38
|
-
return value;
|
|
39
|
-
}
|
|
40
33
|
function parseArgs(argv) {
|
|
41
34
|
const args = [...argv];
|
|
42
35
|
let machineFlag;
|
|
@@ -58,12 +51,14 @@ function parseArgs(argv) {
|
|
|
58
51
|
json = true;
|
|
59
52
|
continue;
|
|
60
53
|
}
|
|
61
|
-
|
|
62
|
-
|
|
54
|
+
const machine = takeFlag(arg, "--machine", args, usage);
|
|
55
|
+
if (machine !== undefined) {
|
|
56
|
+
machineFlag = machine;
|
|
63
57
|
continue;
|
|
64
58
|
}
|
|
65
|
-
|
|
66
|
-
|
|
59
|
+
const model = takeFlag(arg, "--model", args, usage);
|
|
60
|
+
if (model !== undefined) {
|
|
61
|
+
modelFlag = model;
|
|
67
62
|
continue;
|
|
68
63
|
}
|
|
69
64
|
if (arg.startsWith("-")) {
|
package/dist/show.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { envInt, ollamaBaseUrl, shortName } from "./hosts.js";
|
|
7
7
|
import { ollamaShow } from "./ollama-chat.js";
|
|
8
|
+
import { takeFlag } from "./argv.js";
|
|
8
9
|
import { resolveTarget } from "./target.js";
|
|
9
10
|
import { looksTuned } from "./tuned.js";
|
|
10
11
|
function showTimeoutMs() {
|
|
@@ -28,14 +29,6 @@ Options:
|
|
|
28
29
|
--json Emit result JSON on stdout`);
|
|
29
30
|
process.exit(1);
|
|
30
31
|
}
|
|
31
|
-
function takeValue(args, flag) {
|
|
32
|
-
const value = args.shift();
|
|
33
|
-
if (!value) {
|
|
34
|
-
console.error(`${flag} requires a value`);
|
|
35
|
-
usage();
|
|
36
|
-
}
|
|
37
|
-
return value;
|
|
38
|
-
}
|
|
39
32
|
function parseArgs(argv) {
|
|
40
33
|
const args = [...argv];
|
|
41
34
|
let machineFlag;
|
|
@@ -52,12 +45,14 @@ function parseArgs(argv) {
|
|
|
52
45
|
json = true;
|
|
53
46
|
continue;
|
|
54
47
|
}
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
const machine = takeFlag(arg, "--machine", args, usage);
|
|
49
|
+
if (machine !== undefined) {
|
|
50
|
+
machineFlag = machine;
|
|
57
51
|
continue;
|
|
58
52
|
}
|
|
59
|
-
|
|
60
|
-
|
|
53
|
+
const model = takeFlag(arg, "--model", args, usage);
|
|
54
|
+
if (model !== undefined) {
|
|
55
|
+
modelFlag = model;
|
|
61
56
|
continue;
|
|
62
57
|
}
|
|
63
58
|
if (arg.startsWith("-")) {
|
package/dist/target.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type AppConfig } from "./config.js";
|
|
2
2
|
import { type HostTarget } from "./hosts.js";
|
|
3
|
+
/** Discover hosts the same way every command does (config + Tailscale + …). */
|
|
4
|
+
export declare function listTargets(config?: Partial<AppConfig>): Promise<HostTarget[]>;
|
|
3
5
|
/** Resolve a machine name the same way pull / prompt / bench do. */
|
|
4
6
|
export declare function resolveTarget(machine: string, config?: Partial<AppConfig>): Promise<HostTarget>;
|
package/dist/target.js
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import { configFromPartial, loadConfig } from "./config.js";
|
|
2
2
|
import { discoverHosts, resolveHost, shortName } from "./hosts.js";
|
|
3
|
-
/**
|
|
4
|
-
export async function
|
|
5
|
-
const query = machine.trim();
|
|
6
|
-
if (!query)
|
|
7
|
-
throw new Error("Machine is required.");
|
|
3
|
+
/** Discover hosts the same way every command does (config + Tailscale + …). */
|
|
4
|
+
export async function listTargets(config) {
|
|
8
5
|
const app = config ? configFromPartial(config) : await loadConfig();
|
|
9
6
|
const { hosts } = await discoverHosts({
|
|
10
7
|
hosts: app.hosts,
|
|
11
8
|
discovery: app.discovery,
|
|
12
9
|
});
|
|
10
|
+
return hosts;
|
|
11
|
+
}
|
|
12
|
+
/** Resolve a machine name the same way pull / prompt / bench do. */
|
|
13
|
+
export async function resolveTarget(machine, config) {
|
|
14
|
+
const query = machine.trim();
|
|
15
|
+
if (!query)
|
|
16
|
+
throw new Error("Machine is required.");
|
|
17
|
+
const hosts = await listTargets(config);
|
|
13
18
|
const host = resolveHost(hosts, query);
|
|
14
19
|
if (!host.online && !host.isSelf && host.source === "tailscale") {
|
|
15
20
|
throw new Error(`Machine "${shortName(host)}" appears offline.`);
|