@pie-project/server 0.5.2 → 0.6.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.
- package/README.md +6 -6
- package/index.d.ts +3 -2
- package/index.mjs +29 -10
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -14,10 +14,10 @@ import '@pie-project/language-python'; // Python inferlets run; one li
|
|
|
14
14
|
const server = await Server.start({
|
|
15
15
|
model: 'Qwen/Qwen3.5-0.8B', // Node: what `pie model import` fetched
|
|
16
16
|
// model: '/models/qwen3.5-0.8b.wgpu.zt', // browser: the artifact's URL, served with Range support
|
|
17
|
-
config: { server: {
|
|
17
|
+
config: { server: { listen: '127.0.0.1:0' } }, // the rest of `pie serve`'s config
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
await server.install(
|
|
20
|
+
await server.install('./beam_search.wasm'); // an inferlet of your own: a path or URL, or bytes with a file name
|
|
21
21
|
const client = await server.connect(); // a PieClient
|
|
22
22
|
const process = await client.launchProcess('text-completion', { prompt: 'Hello' });
|
|
23
23
|
console.log(await process.result());
|
|
@@ -27,11 +27,11 @@ await server.shutdown();
|
|
|
27
27
|
`Server.start` resolves once the model is loaded and the server is
|
|
28
28
|
listening, with every registered language component installed; `config` is
|
|
29
29
|
the file `pie serve --config` reads, minus the model, as an object. A bare
|
|
30
|
-
`Server.start(config)` with `model.
|
|
30
|
+
`Server.start(config)` with `model.source` inside, as an object or TOML text,
|
|
31
31
|
is accepted too. Under Node, `server.httpUrl` is where the HTTP routes live.
|
|
32
32
|
A handle garbage-collected without `shutdown()` still stops the engine.
|
|
33
33
|
|
|
34
|
-
The Python twin is the `pie-server` wheel (`python/server`).
|
|
34
|
+
The Python twin is the `pie-server` wheel (`packages/python/server`).
|
|
35
35
|
|
|
36
36
|
## Installing
|
|
37
37
|
|
|
@@ -47,7 +47,7 @@ config's `engine.type` picks one at boot. Under a bundler (Vite, webpack 5)
|
|
|
47
47
|
the `browser` export condition resolves to `@pie-project/server-web`: the
|
|
48
48
|
runtime and the WebGPU engine as wasm, run in a Web Worker. The page must be
|
|
49
49
|
cross-origin isolated and the browser needs WebGPU and JSPI (Chrome 137+);
|
|
50
|
-
`javascript/server-web/README.md` has the details.
|
|
50
|
+
`packages/javascript/server-web/README.md` has the details.
|
|
51
51
|
|
|
52
52
|
Language components (`@pie-project/language-python`,
|
|
53
53
|
`@pie-project/language-javascript`) register themselves on import; a
|
|
@@ -66,4 +66,4 @@ bash build.sh dev --no-default-features # no engine: loads, refuses to serve
|
|
|
66
66
|
|
|
67
67
|
It lands beside `index.mjs` as `pie-server.<platform>-<arch>.node`, which
|
|
68
68
|
the loader prefers over the platform package. The browser bundle is
|
|
69
|
-
`javascript/server-web/build.sh`.
|
|
69
|
+
`packages/javascript/server-web/build.sh`.
|
package/index.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export interface StartOptions {
|
|
|
11
11
|
model: string;
|
|
12
12
|
/** The rest of the config (server, engine, sandbox, …), as an object; TOML text is accepted for a bare `start(config)`. */
|
|
13
13
|
config?: Record<string, unknown> | string;
|
|
14
|
+
/** Node: where the runtime keeps its files (installed inferlets, languages, caches, models); `$PIE_HOME`, else `~/.pie`. */
|
|
15
|
+
home?: string;
|
|
14
16
|
/** Browser only: download progress of a lazy boot. */
|
|
15
17
|
onProgress?: (served: number, total: number, from: 'network' | 'cache') => void;
|
|
16
18
|
}
|
|
@@ -30,8 +32,7 @@ export class Server {
|
|
|
30
32
|
readonly running: boolean;
|
|
31
33
|
/** A language component (`python`, `javascript`) from bytes or a URL. */
|
|
32
34
|
installLanguage(language: 'python' | 'javascript' | string, source: Uint8Array | ArrayBuffer | URL | string): Promise<string>;
|
|
33
|
-
|
|
34
|
-
install(source: Uint8Array | ArrayBuffer | URL | string, manifest: string): Promise<string>;
|
|
35
|
+
install(source: Uint8Array | ArrayBuffer | URL | string, file?: string | null, version?: string | null): Promise<string>;
|
|
35
36
|
/** A `PieClient` connected to this engine; closed by `shutdown()`. */
|
|
36
37
|
connect(options?: { identity?: string }): Promise<PieClient>;
|
|
37
38
|
/** Stop the engine and release it. Idempotent. */
|
package/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// `@pie-project/server`: what `pie serve` boots, inside a Node process.
|
|
2
2
|
//
|
|
3
3
|
// import { Server } from '@pie-project/server';
|
|
4
|
-
// const server = await Server.start({ server: {
|
|
4
|
+
// const server = await Server.start({ server: { listen: '127.0.0.1:0' }, model: { source: 'Qwen/Qwen3.5-0.8B' } });
|
|
5
5
|
// const client = await server.connect();
|
|
6
6
|
// ...
|
|
7
7
|
// await server.shutdown();
|
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
// dependency; this wrapper loads it and adds `connect()`.
|
|
13
13
|
|
|
14
14
|
import { createRequire } from 'node:module';
|
|
15
|
-
import { fileURLToPath } from 'node:url';
|
|
15
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
16
|
+
import { homedir } from 'node:os';
|
|
16
17
|
import { dirname, join } from 'node:path';
|
|
17
18
|
import { existsSync } from 'node:fs';
|
|
18
19
|
import { readFile } from 'node:fs/promises';
|
|
19
20
|
import WebSocket from 'ws';
|
|
20
|
-
import { PieClient } from '@pie-project/client';
|
|
21
|
+
import { PieClient, programFile } from '@pie-project/client';
|
|
21
22
|
import { attachLanguages } from '@pie-project/server-web/languages';
|
|
22
23
|
|
|
23
24
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
@@ -50,11 +51,24 @@ function load() {
|
|
|
50
51
|
return native;
|
|
51
52
|
}
|
|
52
53
|
|
|
54
|
+
function isBytes(source) {
|
|
55
|
+
return source instanceof Uint8Array || source instanceof ArrayBuffer;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function urlOf(source) {
|
|
59
|
+
if (source instanceof URL) return source;
|
|
60
|
+
try {
|
|
61
|
+
return new URL(String(source));
|
|
62
|
+
} catch {
|
|
63
|
+
return pathToFileURL(String(source));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
53
67
|
/** Bytes from what `install*` accept: bytes, or a file/http URL to read. */
|
|
54
68
|
async function bytesOf(source) {
|
|
55
69
|
if (source instanceof Uint8Array) return source;
|
|
56
70
|
if (source instanceof ArrayBuffer) return new Uint8Array(source);
|
|
57
|
-
const url =
|
|
71
|
+
const url = urlOf(source);
|
|
58
72
|
if (url.protocol === 'file:') return new Uint8Array(await readFile(fileURLToPath(url)));
|
|
59
73
|
const response = await fetch(url);
|
|
60
74
|
if (!response.ok) throw new Error(`${url}: ${response.status} ${response.statusText}`);
|
|
@@ -86,19 +100,21 @@ export class Server {
|
|
|
86
100
|
* Boot the engine. `{ model, config }` names the model (`Qwen/Qwen3.5-0.8B`,
|
|
87
101
|
* a path, an artifact) and gives the rest of `pie serve`'s config as an
|
|
88
102
|
* object; a bare config — TOML text, or an object of the file's shape with
|
|
89
|
-
* `model.
|
|
103
|
+
* `model.source` inside — is accepted as well. `server.listen` at port 0 asks the OS
|
|
90
104
|
* for a free port; `url` says which. Resolves once the engine is serving,
|
|
91
105
|
* with every registered language component installed.
|
|
92
106
|
*/
|
|
93
107
|
static async start(options) {
|
|
94
108
|
let config = options;
|
|
109
|
+
let home = process.env.PIE_HOME?.trim() || join(homedir(), '.pie');
|
|
95
110
|
if (options && typeof options === 'object' && typeof options.model === 'string') {
|
|
96
111
|
const { model, config: rest = {} } = options;
|
|
97
112
|
if (typeof rest !== 'object') throw new Error('Server.start: with `model`, `config` is an object');
|
|
98
|
-
config = { ...rest, model: { name: 'default', ...(rest.model ?? {}), model } };
|
|
113
|
+
config = { ...rest, model: { name: 'default', ...(rest.model ?? {}), source: model } };
|
|
114
|
+
home = options.home ?? home;
|
|
99
115
|
}
|
|
100
116
|
const api = load();
|
|
101
|
-
const handle = typeof config === 'string' ? await api.startToml(config) : await api.start(config);
|
|
117
|
+
const handle = typeof config === 'string' ? await api.startToml(config, home) : await api.start(config, home);
|
|
102
118
|
const server = new Server(handle);
|
|
103
119
|
await importInstalledLanguages();
|
|
104
120
|
server.#detach = await attachLanguages(server);
|
|
@@ -126,10 +142,13 @@ export class Server {
|
|
|
126
142
|
return handle.installLanguage(language, Buffer.from(await bytesOf(source)));
|
|
127
143
|
}
|
|
128
144
|
|
|
129
|
-
|
|
130
|
-
async install(source, manifest) {
|
|
145
|
+
async install(source, file = null, version = null) {
|
|
131
146
|
const handle = this.#alive();
|
|
132
|
-
|
|
147
|
+
if (!file) {
|
|
148
|
+
if (isBytes(source)) throw new Error('Server.install: bytes need `file`, the program\'s file name (`x.wasm`, `x.py`, `x.js`)');
|
|
149
|
+
file = programFile(urlOf(source));
|
|
150
|
+
}
|
|
151
|
+
return handle.install(Buffer.from(await bytesOf(source)), file, version ?? undefined);
|
|
133
152
|
}
|
|
134
153
|
|
|
135
154
|
/** A `PieClient` connected to this engine (over Node's `ws`, which can send the identity header). Closed by `shutdown()`. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-project/server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "What `pie serve` boots, inside your process: on the native GPU engines under Node.js, on WebGPU under a bundler for the browser.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.mjs",
|
|
@@ -39,20 +39,20 @@
|
|
|
39
39
|
"win32"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@pie-project/client": "^0.
|
|
43
|
-
"@pie-project/server-web": "0.
|
|
44
|
-
"ws": "^8.
|
|
45
|
-
},
|
|
46
|
-
"optionalDependencies": {
|
|
47
|
-
"@pie-project/server-linux-x64": "0.5.2",
|
|
48
|
-
"@pie-project/server-linux-arm64": "0.5.2",
|
|
49
|
-
"@pie-project/server-darwin-arm64": "0.5.2",
|
|
50
|
-
"@pie-project/server-win32-x64": "0.5.2"
|
|
42
|
+
"@pie-project/client": "^0.6.0",
|
|
43
|
+
"@pie-project/server-web": "0.6.0",
|
|
44
|
+
"ws": "^8.22.0"
|
|
51
45
|
},
|
|
52
46
|
"license": "Apache-2.0",
|
|
53
47
|
"repository": {
|
|
54
48
|
"type": "git",
|
|
55
49
|
"url": "https://github.com/pie-project/pie",
|
|
56
|
-
"directory": "javascript/server"
|
|
50
|
+
"directory": "packages/javascript/server"
|
|
51
|
+
},
|
|
52
|
+
"optionalDependencies": {
|
|
53
|
+
"@pie-project/server-darwin-arm64": "0.6.0",
|
|
54
|
+
"@pie-project/server-linux-arm64": "0.6.0",
|
|
55
|
+
"@pie-project/server-linux-x64": "0.6.0",
|
|
56
|
+
"@pie-project/server-win32-x64": "0.6.0"
|
|
57
57
|
}
|
|
58
58
|
}
|