peerllm-host-cli 0.1.2 → 0.3.0

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.
@@ -0,0 +1,22 @@
1
+ import type { AuthService } from "./auth.js";
2
+ import type { BackendClient } from "./backend-client.js";
3
+ export interface CatalogEntry {
4
+ id: string;
5
+ name: string;
6
+ url: string;
7
+ sha256: string;
8
+ sizeBytes: number;
9
+ arch?: string;
10
+ quantization?: string;
11
+ vramRequiredMB?: number;
12
+ description?: string;
13
+ tags?: string[];
14
+ }
15
+ export declare class CatalogService {
16
+ private readonly backend;
17
+ private readonly auth;
18
+ constructor(backend: BackendClient, auth: AuthService);
19
+ list(): Promise<CatalogEntry[]>;
20
+ get(modelId: string): Promise<CatalogEntry | undefined>;
21
+ }
22
+ //# sourceMappingURL=catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/core/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBADJ,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,WAAW;IAG9B,IAAI,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAU/B,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;CAI9D"}
@@ -0,0 +1,22 @@
1
+ export class CatalogService {
2
+ backend;
3
+ auth;
4
+ constructor(backend, auth) {
5
+ this.backend = backend;
6
+ this.auth = auth;
7
+ }
8
+ async list() {
9
+ const token = (await this.auth.getValidAccessToken()) ?? undefined;
10
+ const result = await this.backend.request({
11
+ method: "GET",
12
+ path: "/catalog/models",
13
+ bearerToken: token,
14
+ });
15
+ return Array.isArray(result) ? result : (result.models ?? []);
16
+ }
17
+ async get(modelId) {
18
+ const all = await this.list();
19
+ return all.find((m) => m.id === modelId);
20
+ }
21
+ }
22
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/core/catalog.ts"],"names":[],"mappings":"AAgBA,MAAM,OAAO,cAAc;IAEN;IACA;IAFnB,YACmB,OAAsB,EACtB,IAAiB;QADjB,YAAO,GAAP,OAAO,CAAe;QACtB,SAAI,GAAJ,IAAI,CAAa;IACjC,CAAC;IAEJ,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,IAAI,SAAS,CAAC;QACnE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAA8C;YACrF,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,iBAAiB;YACvB,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;QACH,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,OAAe;QACvB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC9B,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IAC3C,CAAC;CACF"}
@@ -0,0 +1,27 @@
1
+ import type { CatalogEntry } from "./catalog.js";
2
+ export interface DownloadProgress {
3
+ bytesDownloaded: number;
4
+ bytesTotal: number;
5
+ etaSeconds?: number;
6
+ }
7
+ export interface DownloadOptions {
8
+ /** Absolute path to write the final .gguf file to. */
9
+ destPath: string;
10
+ /** Catalog entry being downloaded — provides url, sha256, sizeBytes. */
11
+ entry: CatalogEntry;
12
+ /** Maximum allowed file size in bytes. Defaults to 50 GB (per SPEC §6.2). */
13
+ maxBytes?: number;
14
+ /** Called periodically with progress info. No-op by default. */
15
+ onProgress?: (p: DownloadProgress) => void;
16
+ /** Optional AbortSignal to cancel the download. */
17
+ signal?: AbortSignal;
18
+ }
19
+ export declare class DownloadError extends Error {
20
+ readonly code: "url_not_https" | "missing_content_length" | "size_mismatch" | "too_large" | "insufficient_disk_space" | "http_error" | "network_error" | "sha256_mismatch" | "invalid_gguf" | "destination_exists" | "aborted";
21
+ constructor(message: string, code: "url_not_https" | "missing_content_length" | "size_mismatch" | "too_large" | "insufficient_disk_space" | "http_error" | "network_error" | "sha256_mismatch" | "invalid_gguf" | "destination_exists" | "aborted");
22
+ }
23
+ export declare function downloadCatalogModel(opts: DownloadOptions): Promise<void>;
24
+ export declare function destPathFor(modelsDir: string, entry: CatalogEntry): string;
25
+ export declare function formatBytes(bytes: number): string;
26
+ export declare function formatEta(seconds: number | undefined): string;
27
+ //# sourceMappingURL=model-download.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-download.d.ts","sourceRoot":"","sources":["../../src/core/model-download.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAMjD,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,KAAK,EAAE,YAAY,CAAC;IACpB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC3C,mDAAmD;IACnD,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,qBAAa,aAAc,SAAQ,KAAK;aAGpB,IAAI,EAChB,eAAe,GACf,wBAAwB,GACxB,eAAe,GACf,WAAW,GACX,yBAAyB,GACzB,YAAY,GACZ,eAAe,GACf,iBAAiB,GACjB,cAAc,GACd,oBAAoB,GACpB,SAAS;gBAZb,OAAO,EAAE,MAAM,EACC,IAAI,EAChB,eAAe,GACf,wBAAwB,GACxB,eAAe,GACf,WAAW,GACX,yBAAyB,GACzB,YAAY,GACZ,eAAe,GACf,iBAAiB,GACjB,cAAc,GACd,oBAAoB,GACpB,SAAS;CAIhB;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAoH/E;AAgCD,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,MAAM,CAG1E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAQ7D"}
@@ -0,0 +1,160 @@
1
+ import { createHash } from "node:crypto";
2
+ import { createWriteStream } from "node:fs";
3
+ import { mkdir, open, rename, stat, statfs, unlink } from "node:fs/promises";
4
+ import { dirname, join } from "node:path";
5
+ import { pipeline } from "node:stream/promises";
6
+ import { Readable } from "node:stream";
7
+ const GGUF_MAGIC = Buffer.from([0x47, 0x47, 0x55, 0x46]); // "GGUF"
8
+ const DEFAULT_MAX_BYTES = 50 * 1024 * 1024 * 1024; // 50 GB
9
+ const FREE_SPACE_MULTIPLIER = 1.1;
10
+ export class DownloadError extends Error {
11
+ code;
12
+ constructor(message, code) {
13
+ super(message);
14
+ this.code = code;
15
+ }
16
+ }
17
+ export async function downloadCatalogModel(opts) {
18
+ const { destPath, entry } = opts;
19
+ const maxBytes = opts.maxBytes ?? DEFAULT_MAX_BYTES;
20
+ if (!/^https:\/\//i.test(entry.url)) {
21
+ throw new DownloadError(`catalog url must be https: ${entry.url}`, "url_not_https");
22
+ }
23
+ if ((await stat(destPath).catch(() => null)) !== null) {
24
+ throw new DownloadError(`destination already exists: ${destPath}`, "destination_exists");
25
+ }
26
+ const destDir = dirname(destPath);
27
+ await mkdir(destDir, { recursive: true });
28
+ let response;
29
+ try {
30
+ response = await fetch(entry.url, { signal: opts.signal });
31
+ }
32
+ catch (err) {
33
+ if (err.name === "AbortError") {
34
+ throw new DownloadError("aborted", "aborted");
35
+ }
36
+ throw new DownloadError(`network error: ${err.message}`, "network_error");
37
+ }
38
+ if (!response.ok || !response.body) {
39
+ throw new DownloadError(`HTTP ${response.status} fetching ${entry.url}`, "http_error");
40
+ }
41
+ const contentLengthRaw = response.headers.get("content-length");
42
+ if (!contentLengthRaw) {
43
+ throw new DownloadError("server did not send a Content-Length header", "missing_content_length");
44
+ }
45
+ const contentLength = Number.parseInt(contentLengthRaw, 10);
46
+ if (!Number.isFinite(contentLength) || contentLength <= 0) {
47
+ throw new DownloadError(`invalid Content-Length: ${contentLengthRaw}`, "missing_content_length");
48
+ }
49
+ if (contentLength > maxBytes) {
50
+ throw new DownloadError(`file is ${contentLength} bytes; exceeds limit of ${maxBytes}`, "too_large");
51
+ }
52
+ if (Math.abs(contentLength - entry.sizeBytes) > 1024) {
53
+ throw new DownloadError(`Content-Length (${contentLength}) does not match catalog sizeBytes (${entry.sizeBytes})`, "size_mismatch");
54
+ }
55
+ await assertFreeSpace(destDir, contentLength);
56
+ const partPath = `${destPath}.part`;
57
+ await unlink(partPath).catch(() => undefined);
58
+ const hash = createHash("sha256");
59
+ const fileStream = createWriteStream(partPath);
60
+ const start = Date.now();
61
+ let bytesDownloaded = 0;
62
+ let firstChunkChecked = false;
63
+ const onProgress = opts.onProgress;
64
+ // Wrap the web ReadableStream as a Node Readable so we can compute hash and progress.
65
+ const source = Readable.fromWeb(response.body);
66
+ source.on("data", (chunk) => {
67
+ if (!firstChunkChecked) {
68
+ firstChunkChecked = true;
69
+ if (chunk.length < 4 || !chunk.subarray(0, 4).equals(GGUF_MAGIC)) {
70
+ source.destroy(new DownloadError("file is not a valid GGUF (bad magic)", "invalid_gguf"));
71
+ return;
72
+ }
73
+ }
74
+ hash.update(chunk);
75
+ bytesDownloaded += chunk.length;
76
+ if (onProgress) {
77
+ const elapsed = (Date.now() - start) / 1000;
78
+ const rate = elapsed > 0 ? bytesDownloaded / elapsed : 0;
79
+ const remaining = Math.max(0, contentLength - bytesDownloaded);
80
+ const etaSeconds = rate > 0 ? remaining / rate : undefined;
81
+ onProgress({ bytesDownloaded, bytesTotal: contentLength, etaSeconds });
82
+ }
83
+ });
84
+ try {
85
+ await pipeline(source, fileStream, { signal: opts.signal });
86
+ }
87
+ catch (err) {
88
+ await unlink(partPath).catch(() => undefined);
89
+ if (err instanceof DownloadError)
90
+ throw err;
91
+ if (err.name === "AbortError") {
92
+ throw new DownloadError("aborted", "aborted");
93
+ }
94
+ throw new DownloadError(`download failed: ${err.message}`, "network_error");
95
+ }
96
+ const digest = hash.digest("hex").toLowerCase();
97
+ if (digest !== entry.sha256.toLowerCase()) {
98
+ await unlink(partPath).catch(() => undefined);
99
+ throw new DownloadError(`sha256 mismatch: expected ${entry.sha256}, got ${digest}`, "sha256_mismatch");
100
+ }
101
+ await verifyGgufHeader(partPath).catch(async (err) => {
102
+ await unlink(partPath).catch(() => undefined);
103
+ throw err;
104
+ });
105
+ await rename(partPath, destPath);
106
+ }
107
+ async function verifyGgufHeader(filePath) {
108
+ const fh = await open(filePath, "r");
109
+ try {
110
+ const buf = Buffer.alloc(4);
111
+ const { bytesRead } = await fh.read(buf, 0, 4, 0);
112
+ if (bytesRead < 4 || !buf.equals(GGUF_MAGIC)) {
113
+ throw new DownloadError("downloaded file is not a valid GGUF", "invalid_gguf");
114
+ }
115
+ }
116
+ finally {
117
+ await fh.close();
118
+ }
119
+ }
120
+ async function assertFreeSpace(dir, needBytes) {
121
+ try {
122
+ const fs = await statfs(dir);
123
+ const free = Number(fs.bavail) * Number(fs.bsize);
124
+ const required = Math.ceil(needBytes * FREE_SPACE_MULTIPLIER);
125
+ if (free < required) {
126
+ throw new DownloadError(`insufficient free disk space at ${dir}: have ${free} bytes, need ${required}`, "insufficient_disk_space");
127
+ }
128
+ }
129
+ catch (err) {
130
+ if (err instanceof DownloadError)
131
+ throw err;
132
+ // If statfs is unavailable (older platforms), skip the check.
133
+ }
134
+ }
135
+ export function destPathFor(modelsDir, entry) {
136
+ const fileBase = entry.id.endsWith(".gguf") ? entry.id : `${entry.id}.gguf`;
137
+ return join(modelsDir, fileBase);
138
+ }
139
+ export function formatBytes(bytes) {
140
+ if (bytes < 1024)
141
+ return `${bytes} B`;
142
+ if (bytes < 1024 ** 2)
143
+ return `${(bytes / 1024).toFixed(1)} KB`;
144
+ if (bytes < 1024 ** 3)
145
+ return `${(bytes / 1024 ** 2).toFixed(1)} MB`;
146
+ return `${(bytes / 1024 ** 3).toFixed(2)} GB`;
147
+ }
148
+ export function formatEta(seconds) {
149
+ if (seconds === undefined || !Number.isFinite(seconds))
150
+ return "--";
151
+ if (seconds < 60)
152
+ return `${Math.round(seconds)}s`;
153
+ const m = Math.floor(seconds / 60);
154
+ const s = Math.round(seconds % 60);
155
+ if (m < 60)
156
+ return `${m}m ${s}s`;
157
+ const h = Math.floor(m / 60);
158
+ return `${h}h ${m % 60}m`;
159
+ }
160
+ //# sourceMappingURL=model-download.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-download.js","sourceRoot":"","sources":["../../src/core/model-download.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIvC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;AACnE,MAAM,iBAAiB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,QAAQ;AAC3D,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAqBlC,MAAM,OAAO,aAAc,SAAQ,KAAK;IAGpB;IAFlB,YACE,OAAe,EACC,IAWH;QAEb,KAAK,CAAC,OAAO,CAAC,CAAC;QAbC,SAAI,GAAJ,IAAI,CAWP;IAGf,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAqB;IAC9D,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,iBAAiB,CAAC;IAEpD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,aAAa,CAAC,8BAA8B,KAAK,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;IACtF,CAAC;IAED,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACtD,MAAM,IAAI,aAAa,CAAC,+BAA+B,QAAQ,EAAE,EAAE,oBAAoB,CAAC,CAAC;IAC3F,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1C,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAAa,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YACzC,MAAM,IAAI,aAAa,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAChD,CAAC;QACD,MAAM,IAAI,aAAa,CAAC,kBAAmB,GAAa,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;IACvF,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,aAAa,CAAC,QAAQ,QAAQ,CAAC,MAAM,aAAa,KAAK,CAAC,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;IACzF,CAAC;IAED,MAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAChE,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,MAAM,IAAI,aAAa,CACrB,6CAA6C,EAC7C,wBAAwB,CACzB,CAAC;IACJ,CAAC;IACD,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAC5D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,aAAa,CACrB,2BAA2B,gBAAgB,EAAE,EAC7C,wBAAwB,CACzB,CAAC;IACJ,CAAC;IACD,IAAI,aAAa,GAAG,QAAQ,EAAE,CAAC;QAC7B,MAAM,IAAI,aAAa,CACrB,WAAW,aAAa,4BAA4B,QAAQ,EAAE,EAC9D,WAAW,CACZ,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,CAAC;QACrD,MAAM,IAAI,aAAa,CACrB,mBAAmB,aAAa,uCAAuC,KAAK,CAAC,SAAS,GAAG,EACzF,eAAe,CAChB,CAAC;IACJ,CAAC;IAED,MAAM,eAAe,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAE9C,MAAM,QAAQ,GAAG,GAAG,QAAQ,OAAO,CAAC;IACpC,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAE9C,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,IAAI,iBAAiB,GAAG,KAAK,CAAC;IAE9B,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;IACnC,sFAAsF;IACtF,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAa,CAAC,CAAC;IAExD,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;QAClC,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,iBAAiB,GAAG,IAAI,CAAC;YACzB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;gBACjE,MAAM,CAAC,OAAO,CAAC,IAAI,aAAa,CAAC,sCAAsC,EAAE,cAAc,CAAC,CAAC,CAAC;gBAC1F,OAAO;YACT,CAAC;QACH,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnB,eAAe,IAAI,KAAK,CAAC,MAAM,CAAC;QAChC,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC;YAC5C,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YACzD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,GAAG,eAAe,CAAC,CAAC;YAC/D,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YAC3D,UAAU,CAAC,EAAE,eAAe,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC,CAAC;QACzE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,GAAG,YAAY,aAAa;YAAE,MAAM,GAAG,CAAC;QAC5C,IAAK,GAAa,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YACzC,MAAM,IAAI,aAAa,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAChD,CAAC;QACD,MAAM,IAAI,aAAa,CAAC,oBAAqB,GAAa,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;IACzF,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IAChD,IAAI,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;QAC1C,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC9C,MAAM,IAAI,aAAa,CACrB,6BAA6B,KAAK,CAAC,MAAM,SAAS,MAAM,EAAE,EAC1D,iBAAiB,CAClB,CAAC;IACJ,CAAC;IAED,MAAM,gBAAgB,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACnD,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC9C,MAAM,GAAG,CAAC;IACZ,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,QAAgB;IAC9C,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAClD,IAAI,SAAS,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,aAAa,CAAC,qCAAqC,EAAE,cAAc,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,GAAW,EAAE,SAAiB;IAC3D,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,qBAAqB,CAAC,CAAC;QAC9D,IAAI,IAAI,GAAG,QAAQ,EAAE,CAAC;YACpB,MAAM,IAAI,aAAa,CACrB,mCAAmC,GAAG,UAAU,IAAI,gBAAgB,QAAQ,EAAE,EAC9E,yBAAyB,CAC1B,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,aAAa;YAAE,MAAM,GAAG,CAAC;QAC5C,8DAA8D;IAChE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,SAAiB,EAAE,KAAmB;IAChE,MAAM,QAAQ,GAAG,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,OAAO,CAAC;IAC5E,OAAO,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,IAAI,KAAK,GAAG,IAAI;QAAE,OAAO,GAAG,KAAK,IAAI,CAAC;IACtC,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAChE,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IACrE,OAAO,GAAG,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAA2B;IACnD,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACpE,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;IACnD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACnC,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;IACjC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7B,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC;AAC5B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "peerllm-host-cli",
3
- "version": "0.1.2",
3
+ "version": "0.3.0",
4
4
  "description": "Command-line PeerLLM host: serve decentralized AI compute from a headless machine.",
5
5
  "author": {
6
6
  "name": "Hassan Habib",