@dxo/studio 0.0.0 → 0.0.9
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 +5 -1
- package/dist/api-server.d.ts +17 -0
- package/dist/api-server.d.ts.map +1 -0
- package/dist/api-server.js +147 -0
- package/dist/api-server.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/start.d.ts +24 -0
- package/dist/start.d.ts.map +1 -0
- package/dist/start.js +58 -0
- package/dist/start.js.map +1 -0
- package/package.json +38 -8
package/README.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
# @dxo/studio
|
|
2
2
|
|
|
3
|
-
Placeholder
|
|
3
|
+
**Placeholder — developer preview, API unstable.**
|
|
4
|
+
|
|
5
|
+
Future VMZ workbench for runs, system metrics, artifacts, model graphs, profiler, and UI playground. This package currently only wires protocol package versions; it does **not** listen on a port yet.
|
|
6
|
+
|
|
7
|
+
Default future bind: loopback only. Remote deploy requires explicit auth (see Living design).
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Server } from 'node:http';
|
|
2
|
+
export type InspectApiServerOptions = {
|
|
3
|
+
host?: string;
|
|
4
|
+
port?: number;
|
|
5
|
+
runsRoot?: string;
|
|
6
|
+
};
|
|
7
|
+
export type InspectApiServer = {
|
|
8
|
+
host: string;
|
|
9
|
+
port: number;
|
|
10
|
+
url: string;
|
|
11
|
+
runsRoot: string;
|
|
12
|
+
server: Server;
|
|
13
|
+
close: () => Promise<void>;
|
|
14
|
+
};
|
|
15
|
+
/** Loopback HTTP API over the append-only inspect run store. */
|
|
16
|
+
export declare function createInspectApiServer(options?: InspectApiServerOptions): Promise<InspectApiServer>;
|
|
17
|
+
//# sourceMappingURL=api-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-server.d.ts","sourceRoot":"","sources":["../src/api-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAKtD,MAAM,MAAM,uBAAuB,GAAG;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,CAAC;AAmIF,gEAAgE;AAChE,wBAAsB,sBAAsB,CAAC,OAAO,GAAE,uBAA4B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAoC7G"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { createServer } from 'node:http';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { defaultRunsRoot, listRuns, readEvents, readRunMeta } from '@dxo/inspect';
|
|
5
|
+
function json(res, status, body) {
|
|
6
|
+
const text = JSON.stringify(body);
|
|
7
|
+
res.writeHead(status, {
|
|
8
|
+
'content-type': 'application/json; charset=utf-8',
|
|
9
|
+
'content-length': Buffer.byteLength(text),
|
|
10
|
+
'access-control-allow-origin': '*',
|
|
11
|
+
});
|
|
12
|
+
res.end(text);
|
|
13
|
+
}
|
|
14
|
+
function notFound(res) {
|
|
15
|
+
json(res, 404, { error: 'not_found' });
|
|
16
|
+
}
|
|
17
|
+
function parsePath(url) {
|
|
18
|
+
const u = new URL(url, 'http://127.0.0.1');
|
|
19
|
+
return { pathname: u.pathname, searchParams: u.searchParams };
|
|
20
|
+
}
|
|
21
|
+
function metricsFromEvents(events) {
|
|
22
|
+
const out = [];
|
|
23
|
+
for (const event of events) {
|
|
24
|
+
if (event.type === 'metric/scalar')
|
|
25
|
+
out.push(event.metric);
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
function artifactsFromEvents(events) {
|
|
30
|
+
const out = [];
|
|
31
|
+
for (const event of events) {
|
|
32
|
+
if (event.type === 'artifact/ref')
|
|
33
|
+
out.push(event.artifact);
|
|
34
|
+
}
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
async function handleRequest(req, res, runsRoot) {
|
|
38
|
+
if (req.method !== 'GET') {
|
|
39
|
+
json(res, 405, { error: 'method_not_allowed' });
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const { pathname } = parsePath(req.url ?? '/');
|
|
43
|
+
if (pathname === '/api/health') {
|
|
44
|
+
json(res, 200, { ok: true, service: 'dxo-studio-api' });
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (pathname === '/api/runs') {
|
|
48
|
+
const runs = await listRuns(runsRoot);
|
|
49
|
+
json(res, 200, { runs });
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const runMatch = /^\/api\/runs\/([^/]+)(\/.*)?$/.exec(pathname);
|
|
53
|
+
if (!runMatch) {
|
|
54
|
+
notFound(res);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const runId = decodeURIComponent(runMatch[1]);
|
|
58
|
+
const sub = runMatch[2] ?? '';
|
|
59
|
+
if (sub === '' || sub === '/meta') {
|
|
60
|
+
const meta = await readRunMeta(runsRoot, runId);
|
|
61
|
+
if (!meta) {
|
|
62
|
+
notFound(res);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
json(res, 200, { meta });
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (sub === '/events') {
|
|
69
|
+
const events = await readEvents(runsRoot, runId);
|
|
70
|
+
json(res, 200, { runId, events });
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (sub === '/metrics') {
|
|
74
|
+
const events = await readEvents(runsRoot, runId);
|
|
75
|
+
json(res, 200, { runId, metrics: metricsFromEvents(events) });
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (sub === '/artifacts') {
|
|
79
|
+
const events = await readEvents(runsRoot, runId);
|
|
80
|
+
json(res, 200, { runId, artifacts: artifactsFromEvents(events) });
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (sub === '/checkpoints') {
|
|
84
|
+
const events = await readEvents(runsRoot, runId);
|
|
85
|
+
const checkpoints = artifactsFromEvents(events).filter((a) => a.kind === 'checkpoint');
|
|
86
|
+
json(res, 200, { runId, checkpoints });
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (sub === '/model-graph') {
|
|
90
|
+
const abs = path.join(runsRoot, runId, 'artifacts', 'model-graph.json');
|
|
91
|
+
try {
|
|
92
|
+
const body = await readFile(abs, 'utf8');
|
|
93
|
+
json(res, 200, { runId, graph: JSON.parse(body) });
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
notFound(res);
|
|
97
|
+
}
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const artifactMatch = /^\/artifacts\/(.+)$/.exec(sub);
|
|
101
|
+
if (artifactMatch) {
|
|
102
|
+
const rel = decodeURIComponent(artifactMatch[1]);
|
|
103
|
+
const abs = path.join(runsRoot, runId, rel);
|
|
104
|
+
try {
|
|
105
|
+
const body = await readFile(abs, 'utf8');
|
|
106
|
+
json(res, 200, { runId, path: rel, body });
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
notFound(res);
|
|
110
|
+
}
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
notFound(res);
|
|
114
|
+
}
|
|
115
|
+
/** Loopback HTTP API over the append-only inspect run store. */
|
|
116
|
+
export async function createInspectApiServer(options = {}) {
|
|
117
|
+
const host = options.host ?? '127.0.0.1';
|
|
118
|
+
const port = options.port ?? 0;
|
|
119
|
+
const runsRoot = options.runsRoot ?? defaultRunsRoot();
|
|
120
|
+
const server = createServer((req, res) => {
|
|
121
|
+
void handleRequest(req, res, runsRoot).catch((err) => {
|
|
122
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
123
|
+
json(res, 500, { error: 'internal_error', message });
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
await new Promise((resolve, reject) => {
|
|
127
|
+
server.once('error', reject);
|
|
128
|
+
server.listen(port, host, () => resolve());
|
|
129
|
+
});
|
|
130
|
+
const addr = server.address();
|
|
131
|
+
if (!addr || typeof addr === 'string') {
|
|
132
|
+
throw new Error('failed to bind inspect API server');
|
|
133
|
+
}
|
|
134
|
+
const boundPort = addr.port;
|
|
135
|
+
const url = `http://${host}:${boundPort}`;
|
|
136
|
+
return {
|
|
137
|
+
host,
|
|
138
|
+
port: boundPort,
|
|
139
|
+
url,
|
|
140
|
+
runsRoot,
|
|
141
|
+
server,
|
|
142
|
+
close: () => new Promise((resolve, reject) => {
|
|
143
|
+
server.close((err) => (err ? reject(err) : resolve()));
|
|
144
|
+
}),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=api-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-server.js","sourceRoot":"","sources":["../src/api-server.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,KAAK,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC9G,OAAO,EAAE,YAAY,EAAE,KAAK,kBAAkB,EAAE,KAAK,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAuD,MAAM,iBAAiB,CAAC;AAC9G,OAAO,EAAE,YAAY,EAA+C,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/start.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ChildProcess } from 'node:child_process';
|
|
2
|
+
import { type InspectApiServer, type InspectApiServerOptions } from './api-server.js';
|
|
3
|
+
export type StartStudioOptions = InspectApiServerOptions & {
|
|
4
|
+
/** Start the VMZ dev server for `projects/studio`. Default true. */
|
|
5
|
+
ui?: boolean;
|
|
6
|
+
/** VMZ dev port; 0 picks a free port when supported. */
|
|
7
|
+
uiPort?: number;
|
|
8
|
+
};
|
|
9
|
+
export type StudioProcess = InspectApiServer & {
|
|
10
|
+
ui?: ChildProcess;
|
|
11
|
+
closeAll: () => Promise<void>;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Start loopback inspect API and optionally the VMZ Studio dev app.
|
|
15
|
+
* Binds API to 127.0.0.1 by default.
|
|
16
|
+
*/
|
|
17
|
+
export declare function startStudio(options?: StartStudioOptions): Promise<StudioProcess>;
|
|
18
|
+
/** @deprecated Use {@link startStudio}. */
|
|
19
|
+
export declare function createStudio(options?: StartStudioOptions): {
|
|
20
|
+
kind: 'launcher';
|
|
21
|
+
options: StartStudioOptions;
|
|
22
|
+
};
|
|
23
|
+
export declare function studioVersion(): string;
|
|
24
|
+
//# sourceMappingURL=start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,oBAAoB,CAAC;AAI9D,OAAO,EAA0B,KAAK,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE9G,MAAM,MAAM,kBAAkB,GAAG,uBAAuB,GAAG;IACvD,oEAAoE;IACpE,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,gBAAgB,GAAG;IAC3C,EAAE,CAAC,EAAE,YAAY,CAAC;IAClB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC,CAAC;AA0BF;;;GAGG;AACH,wBAAsB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,aAAa,CAAC,CAsB1F;AAED,2CAA2C;AAC3C,wBAAgB,YAAY,CAAC,OAAO,GAAE,kBAAuB,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAA;CAAE,CAEhH;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
|
package/dist/start.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { writeFile } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { createInspectApiServer } from './api-server.js';
|
|
6
|
+
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
7
|
+
const studioAppRoot = path.resolve(packageRoot, '../../studio');
|
|
8
|
+
function spawnVmzDev(apiUrl, port) {
|
|
9
|
+
const env = {
|
|
10
|
+
...process.env,
|
|
11
|
+
DXO_STUDIO_API: apiUrl,
|
|
12
|
+
...(port ? { PORT: String(port), VMZ_PORT: String(port) } : {}),
|
|
13
|
+
};
|
|
14
|
+
const isWin = process.platform === 'win32';
|
|
15
|
+
const cmd = isWin ? 'pnpm.cmd' : 'pnpm';
|
|
16
|
+
return spawn(cmd, ['exec', 'vmz', 'dev', '.'], {
|
|
17
|
+
cwd: studioAppRoot,
|
|
18
|
+
env,
|
|
19
|
+
stdio: 'inherit',
|
|
20
|
+
shell: isWin,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async function writeStudioApiBootstrap(apiUrl) {
|
|
24
|
+
const out = path.join(studioAppRoot, 'public', 'dxo-studio-api.js');
|
|
25
|
+
await writeFile(out, `window.__DXO_STUDIO_API__=${JSON.stringify(apiUrl)};\n`, 'utf8');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Start loopback inspect API and optionally the VMZ Studio dev app.
|
|
29
|
+
* Binds API to 127.0.0.1 by default.
|
|
30
|
+
*/
|
|
31
|
+
export async function startStudio(options = {}) {
|
|
32
|
+
const api = await createInspectApiServer({
|
|
33
|
+
host: options.host ?? '127.0.0.1',
|
|
34
|
+
port: options.port ?? 4310,
|
|
35
|
+
runsRoot: options.runsRoot,
|
|
36
|
+
});
|
|
37
|
+
const uiEnabled = options.ui !== false;
|
|
38
|
+
let ui;
|
|
39
|
+
if (uiEnabled) {
|
|
40
|
+
await writeStudioApiBootstrap(api.url);
|
|
41
|
+
ui = spawnVmzDev(api.url, options.uiPort);
|
|
42
|
+
}
|
|
43
|
+
const closeAll = async () => {
|
|
44
|
+
if (ui && !ui.killed) {
|
|
45
|
+
ui.kill();
|
|
46
|
+
}
|
|
47
|
+
await api.close();
|
|
48
|
+
};
|
|
49
|
+
return { ...api, ui, closeAll };
|
|
50
|
+
}
|
|
51
|
+
/** @deprecated Use {@link startStudio}. */
|
|
52
|
+
export function createStudio(options = {}) {
|
|
53
|
+
return { kind: 'launcher', options };
|
|
54
|
+
}
|
|
55
|
+
export function studioVersion() {
|
|
56
|
+
return 'dxo-studio@0.1.0-preview';
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,40 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
|
|
2
|
+
"name": "@dxo/studio",
|
|
3
|
+
"version": "0.0.9",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "DXO training / model workbench (VMZ app placeholder, API unstable)",
|
|
6
|
+
"license": "MIT OR Apache-2.0",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc -p tsconfig.json"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@dxo/graph": "0.0.9",
|
|
24
|
+
"@dxo/inspect": "0.0.9"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"dxo",
|
|
28
|
+
"studio",
|
|
29
|
+
"tensorboard",
|
|
30
|
+
"vmz",
|
|
31
|
+
"typescript"
|
|
32
|
+
],
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "git+https://github.com/ai4waifu/dxo-framework.git"
|
|
39
|
+
}
|
|
10
40
|
}
|