chainlesschain 0.47.9 → 0.51.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/bin/chainlesschain.js +0 -0
- package/package.json +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AppLayout-6SPt_8Y_.js → AppLayout-Rvi759IS.js} +1 -1
- package/src/assets/web-panel/assets/Dashboard-BS-tzGNj.css +1 -0
- package/src/assets/web-panel/assets/{Dashboard-Br7kCwKJ.js → Dashboard-DBhFxXYQ.js} +2 -2
- package/src/assets/web-panel/assets/{index-tN-8TosE.js → index-uL0cZ8N_.js} +2 -2
- package/src/assets/web-panel/index.html +2 -2
- package/src/commands/codegen.js +303 -0
- package/src/commands/collab.js +482 -0
- package/src/commands/crosschain.js +382 -0
- package/src/commands/dbevo.js +388 -0
- package/src/commands/dev.js +411 -0
- package/src/commands/federation.js +427 -0
- package/src/commands/fusion.js +332 -0
- package/src/commands/governance.js +505 -0
- package/src/commands/hardening.js +110 -0
- package/src/commands/incentive.js +373 -0
- package/src/commands/inference.js +304 -0
- package/src/commands/infra.js +361 -0
- package/src/commands/ipfs.js +392 -0
- package/src/commands/kg.js +371 -0
- package/src/commands/marketplace.js +326 -0
- package/src/commands/mcp.js +97 -18
- package/src/commands/multimodal.js +404 -0
- package/src/commands/nlprog.js +329 -0
- package/src/commands/ops.js +408 -0
- package/src/commands/perception.js +385 -0
- package/src/commands/pqc.js +34 -0
- package/src/commands/privacy.js +345 -0
- package/src/commands/quantization.js +280 -0
- package/src/commands/recommend.js +336 -0
- package/src/commands/reputation.js +349 -0
- package/src/commands/runtime.js +500 -0
- package/src/commands/sla.js +352 -0
- package/src/commands/stress.js +252 -0
- package/src/commands/tech.js +268 -0
- package/src/commands/tenant.js +576 -0
- package/src/commands/trust.js +366 -0
- package/src/harness/mcp-client.js +330 -54
- package/src/index.js +118 -0
- package/src/lib/aiops.js +523 -0
- package/src/lib/autonomous-developer.js +524 -0
- package/src/lib/code-agent.js +442 -0
- package/src/lib/collaboration-governance.js +556 -0
- package/src/lib/community-governance.js +649 -0
- package/src/lib/content-recommendation.js +600 -0
- package/src/lib/cross-chain.js +669 -0
- package/src/lib/dbevo.js +669 -0
- package/src/lib/decentral-infra.js +445 -0
- package/src/lib/federation-hardening.js +587 -0
- package/src/lib/hardening-manager.js +409 -0
- package/src/lib/inference-network.js +407 -0
- package/src/lib/ipfs-storage.js +575 -0
- package/src/lib/knowledge-graph.js +530 -0
- package/src/lib/mcp-client.js +3 -0
- package/src/lib/multimodal.js +725 -0
- package/src/lib/nl-programming.js +595 -0
- package/src/lib/perception.js +500 -0
- package/src/lib/pqc-manager.js +141 -9
- package/src/lib/privacy-computing.js +575 -0
- package/src/lib/protocol-fusion.js +535 -0
- package/src/lib/quantization.js +362 -0
- package/src/lib/reputation-optimizer.js +509 -0
- package/src/lib/skill-marketplace.js +397 -0
- package/src/lib/sla-manager.js +484 -0
- package/src/lib/stress-tester.js +383 -0
- package/src/lib/tech-learning-engine.js +651 -0
- package/src/lib/tenant-saas.js +831 -0
- package/src/lib/token-incentive.js +513 -0
- package/src/lib/trust-security.js +473 -0
- package/src/lib/universal-runtime.js +771 -0
- package/src/assets/web-panel/assets/Dashboard-CKeMmCoT.css +0 -1
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cc privacy` — CLI surface for Phase 91 Privacy Computing.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
FL_STATUS,
|
|
9
|
+
MPC_PROTOCOL,
|
|
10
|
+
DP_MECHANISM,
|
|
11
|
+
HE_SCHEME,
|
|
12
|
+
DEFAULT_CONFIG,
|
|
13
|
+
ensurePrivacyTables,
|
|
14
|
+
createModel,
|
|
15
|
+
trainRound,
|
|
16
|
+
failModel,
|
|
17
|
+
getModel,
|
|
18
|
+
listModels,
|
|
19
|
+
createComputation,
|
|
20
|
+
submitShare,
|
|
21
|
+
getComputation,
|
|
22
|
+
listComputations,
|
|
23
|
+
dpPublish,
|
|
24
|
+
heQuery,
|
|
25
|
+
getPrivacyReport,
|
|
26
|
+
} from "../lib/privacy-computing.js";
|
|
27
|
+
|
|
28
|
+
function _dbFromCtx(cmd) {
|
|
29
|
+
const root = cmd?.parent?.parent ?? cmd?.parent;
|
|
30
|
+
return root?._db;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function registerPrivacyCommand(program) {
|
|
34
|
+
const pc = new Command("privacy")
|
|
35
|
+
.description("Privacy computing (Phase 91)")
|
|
36
|
+
.hook("preAction", (thisCmd) => {
|
|
37
|
+
const db = _dbFromCtx(thisCmd);
|
|
38
|
+
if (db) ensurePrivacyTables(db);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
/* ── Catalogs ────────────────────────────────────── */
|
|
42
|
+
|
|
43
|
+
pc.command("protocols")
|
|
44
|
+
.description("List MPC protocols")
|
|
45
|
+
.option("--json", "JSON output")
|
|
46
|
+
.action((opts) => {
|
|
47
|
+
const protocols = Object.values(MPC_PROTOCOL);
|
|
48
|
+
if (opts.json) return console.log(JSON.stringify(protocols, null, 2));
|
|
49
|
+
for (const p of protocols)
|
|
50
|
+
console.log(
|
|
51
|
+
` ${p.id.padEnd(10)} ${p.name.padEnd(26)} ${p.description}`,
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
pc.command("dp-mechanisms")
|
|
56
|
+
.description("List differential privacy mechanisms")
|
|
57
|
+
.option("--json", "JSON output")
|
|
58
|
+
.action((opts) => {
|
|
59
|
+
const mechs = Object.values(DP_MECHANISM);
|
|
60
|
+
if (opts.json) return console.log(JSON.stringify(mechs, null, 2));
|
|
61
|
+
for (const m of mechs)
|
|
62
|
+
console.log(
|
|
63
|
+
` ${m.id.padEnd(14)} ${m.name.padEnd(14)} ${m.description}`,
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
pc.command("he-schemes")
|
|
68
|
+
.description("List homomorphic encryption schemes")
|
|
69
|
+
.option("--json", "JSON output")
|
|
70
|
+
.action((opts) => {
|
|
71
|
+
const schemes = Object.values(HE_SCHEME);
|
|
72
|
+
if (opts.json) return console.log(JSON.stringify(schemes, null, 2));
|
|
73
|
+
for (const s of schemes)
|
|
74
|
+
console.log(
|
|
75
|
+
` ${s.id.padEnd(12)} ${s.name.padEnd(12)} ${s.description}`,
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
pc.command("fl-statuses")
|
|
80
|
+
.description("List federated learning statuses")
|
|
81
|
+
.option("--json", "JSON output")
|
|
82
|
+
.action((opts) => {
|
|
83
|
+
const statuses = Object.values(FL_STATUS);
|
|
84
|
+
if (opts.json) return console.log(JSON.stringify(statuses, null, 2));
|
|
85
|
+
for (const s of statuses) console.log(` ${s}`);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
/* ── Federated Learning ──────────────────────────── */
|
|
89
|
+
|
|
90
|
+
pc.command("create-model <name>")
|
|
91
|
+
.description("Create federated learning model")
|
|
92
|
+
.option("-t, --type <type>", "Model type", "neural_network")
|
|
93
|
+
.option("-a, --arch <architecture>", "Architecture", "mlp")
|
|
94
|
+
.option("-r, --rounds <n>", "Total training rounds", parseInt)
|
|
95
|
+
.option("-l, --lr <rate>", "Learning rate", parseFloat)
|
|
96
|
+
.option("-p, --participants <n>", "Participant count", parseInt)
|
|
97
|
+
.option("--json", "JSON output")
|
|
98
|
+
.action((name, opts) => {
|
|
99
|
+
const db = _dbFromCtx(pc);
|
|
100
|
+
const result = createModel(db, name, {
|
|
101
|
+
modelType: opts.type,
|
|
102
|
+
architecture: opts.arch,
|
|
103
|
+
totalRounds: opts.rounds,
|
|
104
|
+
learningRate: opts.lr,
|
|
105
|
+
participants: opts.participants,
|
|
106
|
+
});
|
|
107
|
+
if (opts.json) return console.log(JSON.stringify(result, null, 2));
|
|
108
|
+
console.log(`Model created: ${result.modelId}`);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
pc.command("train <model-id>")
|
|
112
|
+
.description("Run one training round")
|
|
113
|
+
.option("--json", "JSON output")
|
|
114
|
+
.action((modelId, opts) => {
|
|
115
|
+
const db = _dbFromCtx(pc);
|
|
116
|
+
const result = trainRound(db, modelId);
|
|
117
|
+
if (opts.json) return console.log(JSON.stringify(result, null, 2));
|
|
118
|
+
if (result.trained)
|
|
119
|
+
console.log(
|
|
120
|
+
`Round ${result.round}: accuracy=${result.accuracy} status=${result.status}`,
|
|
121
|
+
);
|
|
122
|
+
else console.log(`Failed: ${result.reason}`);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
pc.command("fail-model <model-id>")
|
|
126
|
+
.description("Mark model as failed")
|
|
127
|
+
.option("-r, --reason <text>", "Failure reason")
|
|
128
|
+
.option("--json", "JSON output")
|
|
129
|
+
.action((modelId, opts) => {
|
|
130
|
+
const db = _dbFromCtx(pc);
|
|
131
|
+
const result = failModel(db, modelId, opts.reason);
|
|
132
|
+
if (opts.json) return console.log(JSON.stringify(result, null, 2));
|
|
133
|
+
console.log(
|
|
134
|
+
result.failed ? "Model marked as failed." : `Failed: ${result.reason}`,
|
|
135
|
+
);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
pc.command("show-model <model-id>")
|
|
139
|
+
.description("Show model details")
|
|
140
|
+
.option("--json", "JSON output")
|
|
141
|
+
.action((modelId, opts) => {
|
|
142
|
+
const db = _dbFromCtx(pc);
|
|
143
|
+
const m = getModel(db, modelId);
|
|
144
|
+
if (!m) return console.log("Model not found.");
|
|
145
|
+
if (opts.json) return console.log(JSON.stringify(m, null, 2));
|
|
146
|
+
console.log(`ID: ${m.id}`);
|
|
147
|
+
console.log(`Name: ${m.name}`);
|
|
148
|
+
console.log(`Type: ${m.model_type}`);
|
|
149
|
+
console.log(`Architecture: ${m.architecture}`);
|
|
150
|
+
console.log(`Status: ${m.status}`);
|
|
151
|
+
console.log(`Round: ${m.current_round}/${m.total_rounds}`);
|
|
152
|
+
console.log(`Accuracy: ${m.accuracy}`);
|
|
153
|
+
if (m.loss !== null) console.log(`Loss: ${m.loss}`);
|
|
154
|
+
console.log(`Privacy spent: ${m.privacy_budget_spent}`);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
pc.command("models")
|
|
158
|
+
.description("List federated learning models")
|
|
159
|
+
.option("-s, --status <status>", "Filter by status")
|
|
160
|
+
.option("--limit <n>", "Max results", parseInt)
|
|
161
|
+
.option("--json", "JSON output")
|
|
162
|
+
.action((opts) => {
|
|
163
|
+
const db = _dbFromCtx(pc);
|
|
164
|
+
const models = listModels(db, {
|
|
165
|
+
status: opts.status,
|
|
166
|
+
limit: opts.limit,
|
|
167
|
+
});
|
|
168
|
+
if (opts.json) return console.log(JSON.stringify(models, null, 2));
|
|
169
|
+
if (models.length === 0) return console.log("No models.");
|
|
170
|
+
for (const m of models) {
|
|
171
|
+
console.log(
|
|
172
|
+
` ${m.status.padEnd(14)} ${m.name.padEnd(20)} ${m.current_round}/${m.total_rounds} acc=${m.accuracy} ${m.id.slice(0, 8)}`,
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
/* ── MPC Computation ─────────────────────────────── */
|
|
178
|
+
|
|
179
|
+
pc.command("create-computation <type>")
|
|
180
|
+
.description("Create MPC computation")
|
|
181
|
+
.option("-p, --protocol <proto>", "Protocol (shamir/beaver/gmw)", "shamir")
|
|
182
|
+
.option("-i, --participants <ids>", "Comma-separated participant IDs")
|
|
183
|
+
.option("-t, --threshold <n>", "Shares required", parseInt)
|
|
184
|
+
.option("--json", "JSON output")
|
|
185
|
+
.action((type, opts) => {
|
|
186
|
+
const db = _dbFromCtx(pc);
|
|
187
|
+
const ids = opts.participants ? opts.participants.split(",") : [];
|
|
188
|
+
const result = createComputation(db, type, {
|
|
189
|
+
protocol: opts.protocol,
|
|
190
|
+
participantIds: ids,
|
|
191
|
+
sharesRequired: opts.threshold,
|
|
192
|
+
});
|
|
193
|
+
if (opts.json) return console.log(JSON.stringify(result, null, 2));
|
|
194
|
+
if (result.computationId)
|
|
195
|
+
console.log(`Computation created: ${result.computationId}`);
|
|
196
|
+
else console.log(`Failed: ${result.reason}`);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
pc.command("submit-share <computation-id>")
|
|
200
|
+
.description("Submit a share to MPC computation")
|
|
201
|
+
.option("--json", "JSON output")
|
|
202
|
+
.action((computationId, opts) => {
|
|
203
|
+
const db = _dbFromCtx(pc);
|
|
204
|
+
const result = submitShare(db, computationId);
|
|
205
|
+
if (opts.json) return console.log(JSON.stringify(result, null, 2));
|
|
206
|
+
if (result.submitted)
|
|
207
|
+
console.log(
|
|
208
|
+
`Share submitted (${result.sharesReceived} received, status=${result.status})`,
|
|
209
|
+
);
|
|
210
|
+
else console.log(`Failed: ${result.reason}`);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
pc.command("show-computation <computation-id>")
|
|
214
|
+
.description("Show computation details")
|
|
215
|
+
.option("--json", "JSON output")
|
|
216
|
+
.action((computationId, opts) => {
|
|
217
|
+
const db = _dbFromCtx(pc);
|
|
218
|
+
const c = getComputation(db, computationId);
|
|
219
|
+
if (!c) return console.log("Computation not found.");
|
|
220
|
+
if (opts.json) return console.log(JSON.stringify(c, null, 2));
|
|
221
|
+
console.log(`ID: ${c.id}`);
|
|
222
|
+
console.log(`Type: ${c.computation_type}`);
|
|
223
|
+
console.log(`Protocol: ${c.protocol}`);
|
|
224
|
+
console.log(`Status: ${c.status}`);
|
|
225
|
+
console.log(`Shares: ${c.shares_received}/${c.shares_required}`);
|
|
226
|
+
if (c.result_hash) console.log(`Result: ${c.result_hash}`);
|
|
227
|
+
if (c.computation_time_ms)
|
|
228
|
+
console.log(`Time: ${c.computation_time_ms}ms`);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
pc.command("computations")
|
|
232
|
+
.description("List MPC computations")
|
|
233
|
+
.option("-p, --protocol <proto>", "Filter by protocol")
|
|
234
|
+
.option("-s, --status <status>", "Filter by status")
|
|
235
|
+
.option("--limit <n>", "Max results", parseInt)
|
|
236
|
+
.option("--json", "JSON output")
|
|
237
|
+
.action((opts) => {
|
|
238
|
+
const db = _dbFromCtx(pc);
|
|
239
|
+
const comps = listComputations(db, {
|
|
240
|
+
protocol: opts.protocol,
|
|
241
|
+
status: opts.status,
|
|
242
|
+
limit: opts.limit,
|
|
243
|
+
});
|
|
244
|
+
if (opts.json) return console.log(JSON.stringify(comps, null, 2));
|
|
245
|
+
if (comps.length === 0) return console.log("No computations.");
|
|
246
|
+
for (const c of comps) {
|
|
247
|
+
console.log(
|
|
248
|
+
` ${c.status.padEnd(12)} ${c.protocol.padEnd(8)} ${c.computation_type.padEnd(16)} ${c.shares_received}/${c.shares_required} ${c.id.slice(0, 8)}`,
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
/* ── Differential Privacy ────────────────────────── */
|
|
254
|
+
|
|
255
|
+
pc.command("dp-publish")
|
|
256
|
+
.description("Publish data with differential privacy noise")
|
|
257
|
+
.option("-d, --data <json>", "Data (number or JSON array)")
|
|
258
|
+
.option("-e, --epsilon <n>", "Privacy parameter epsilon", parseFloat)
|
|
259
|
+
.option("--delta <n>", "Privacy parameter delta", parseFloat)
|
|
260
|
+
.option(
|
|
261
|
+
"-m, --mechanism <type>",
|
|
262
|
+
"Noise mechanism (laplace/gaussian/exponential)",
|
|
263
|
+
)
|
|
264
|
+
.option("-s, --sensitivity <n>", "Sensitivity", parseFloat)
|
|
265
|
+
.option("--json", "JSON output")
|
|
266
|
+
.action((opts) => {
|
|
267
|
+
const db = _dbFromCtx(pc);
|
|
268
|
+
let data;
|
|
269
|
+
try {
|
|
270
|
+
data = JSON.parse(opts.data || "0");
|
|
271
|
+
} catch (_e) {
|
|
272
|
+
data = parseFloat(opts.data) || 0;
|
|
273
|
+
}
|
|
274
|
+
const result = dpPublish(db, {
|
|
275
|
+
data,
|
|
276
|
+
epsilon: opts.epsilon,
|
|
277
|
+
delta: opts.delta,
|
|
278
|
+
mechanism: opts.mechanism,
|
|
279
|
+
sensitivity: opts.sensitivity,
|
|
280
|
+
});
|
|
281
|
+
if (opts.json) return console.log(JSON.stringify(result, null, 2));
|
|
282
|
+
if (result.published) {
|
|
283
|
+
console.log(`Published: ${JSON.stringify(result.data)}`);
|
|
284
|
+
console.log(
|
|
285
|
+
`Mechanism: ${result.mechanism} epsilon=${result.epsilon}`,
|
|
286
|
+
);
|
|
287
|
+
console.log(
|
|
288
|
+
`Budget: ${result.budgetSpent}/${DEFAULT_CONFIG.maxBudget} spent`,
|
|
289
|
+
);
|
|
290
|
+
} else console.log(`Failed: ${result.reason}`);
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
/* ── Homomorphic Encryption ──────────────────────── */
|
|
294
|
+
|
|
295
|
+
pc.command("he-query")
|
|
296
|
+
.description("Query encrypted data (simulated HE)")
|
|
297
|
+
.option("-d, --data <json>", "Data array (JSON)")
|
|
298
|
+
.option("-o, --operation <op>", "Operation (sum/product/mean/count)")
|
|
299
|
+
.option("-s, --scheme <scheme>", "HE scheme (paillier/bfv/ckks)")
|
|
300
|
+
.option("--json", "JSON output")
|
|
301
|
+
.action((opts) => {
|
|
302
|
+
let data;
|
|
303
|
+
try {
|
|
304
|
+
data = JSON.parse(opts.data || "[]");
|
|
305
|
+
} catch (_e) {
|
|
306
|
+
return console.log("Invalid data JSON.");
|
|
307
|
+
}
|
|
308
|
+
const result = heQuery({
|
|
309
|
+
data,
|
|
310
|
+
operation: opts.operation,
|
|
311
|
+
scheme: opts.scheme,
|
|
312
|
+
});
|
|
313
|
+
if (opts.json) return console.log(JSON.stringify(result, null, 2));
|
|
314
|
+
if (result.result !== null)
|
|
315
|
+
console.log(
|
|
316
|
+
`Result: ${result.result} (${result.operation} over ${result.inputCount} items, scheme=${result.scheme})`,
|
|
317
|
+
);
|
|
318
|
+
else console.log(`Failed: ${result.reason}`);
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
/* ── Report ──────────────────────────────────────── */
|
|
322
|
+
|
|
323
|
+
pc.command("report")
|
|
324
|
+
.description("Privacy computing report")
|
|
325
|
+
.option("--json", "JSON output")
|
|
326
|
+
.action((opts) => {
|
|
327
|
+
const db = _dbFromCtx(pc);
|
|
328
|
+
const report = getPrivacyReport(db);
|
|
329
|
+
if (opts.json) return console.log(JSON.stringify(report, null, 2));
|
|
330
|
+
const b = report.privacyBudget;
|
|
331
|
+
console.log(
|
|
332
|
+
`Privacy Budget: ${b.spent}/${b.limit} (${b.remaining} remaining)`,
|
|
333
|
+
);
|
|
334
|
+
const fl = report.federatedLearning;
|
|
335
|
+
console.log(
|
|
336
|
+
`FL Models: ${fl.totalModels} (${fl.completed} completed, ${fl.training} training, avg acc=${fl.avgAccuracy})`,
|
|
337
|
+
);
|
|
338
|
+
const mpc = report.mpc;
|
|
339
|
+
console.log(
|
|
340
|
+
`MPC: ${mpc.totalComputations} (${mpc.completed} completed, ${mpc.pending} pending)`,
|
|
341
|
+
);
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
program.addCommand(pc);
|
|
345
|
+
}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cc quantize` — CLI surface for Phase 20 Model Quantization.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
JOB_STATUS,
|
|
9
|
+
QUANT_TYPE,
|
|
10
|
+
GGUF_LEVELS,
|
|
11
|
+
GPTQ_BITS,
|
|
12
|
+
ensureQuantizationTables,
|
|
13
|
+
createJob,
|
|
14
|
+
getJob,
|
|
15
|
+
listJobs,
|
|
16
|
+
startJob,
|
|
17
|
+
updateProgress,
|
|
18
|
+
completeJob,
|
|
19
|
+
failJob,
|
|
20
|
+
cancelJob,
|
|
21
|
+
deleteJob,
|
|
22
|
+
getQuantizationStats,
|
|
23
|
+
} from "../lib/quantization.js";
|
|
24
|
+
|
|
25
|
+
function _dbFromCtx(cmd) {
|
|
26
|
+
const root = cmd?.parent?.parent ?? cmd?.parent;
|
|
27
|
+
return root?._db;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function registerQuantizationCommand(program) {
|
|
31
|
+
const quant = new Command("quantize")
|
|
32
|
+
.description("Model quantization system (Phase 20)")
|
|
33
|
+
.hook("preAction", (thisCmd) => {
|
|
34
|
+
const db = _dbFromCtx(thisCmd);
|
|
35
|
+
if (db) ensureQuantizationTables(db);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
/* ── Catalogs ────────────────────────────────────── */
|
|
39
|
+
|
|
40
|
+
quant
|
|
41
|
+
.command("statuses")
|
|
42
|
+
.description("List job statuses")
|
|
43
|
+
.option("--json", "JSON output")
|
|
44
|
+
.action((opts) => {
|
|
45
|
+
const statuses = Object.values(JOB_STATUS);
|
|
46
|
+
if (opts.json) return console.log(JSON.stringify(statuses, null, 2));
|
|
47
|
+
for (const s of statuses) console.log(` ${s}`);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
quant
|
|
51
|
+
.command("types")
|
|
52
|
+
.description("List quantization types (gguf/gptq)")
|
|
53
|
+
.option("--json", "JSON output")
|
|
54
|
+
.action((opts) => {
|
|
55
|
+
const types = Object.values(QUANT_TYPE);
|
|
56
|
+
if (opts.json) return console.log(JSON.stringify(types, null, 2));
|
|
57
|
+
for (const t of types) console.log(` ${t}`);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
quant
|
|
61
|
+
.command("levels")
|
|
62
|
+
.description("List GGUF quantization levels (14 levels)")
|
|
63
|
+
.option("--json", "JSON output")
|
|
64
|
+
.action((opts) => {
|
|
65
|
+
if (opts.json) return console.log(JSON.stringify(GGUF_LEVELS, null, 2));
|
|
66
|
+
for (const l of GGUF_LEVELS) {
|
|
67
|
+
console.log(
|
|
68
|
+
` ${l.level.padEnd(8)} ${String(l.bits).padEnd(4)}bit ${l.description}`,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
quant
|
|
74
|
+
.command("gptq-bits")
|
|
75
|
+
.description("List GPTQ bit widths")
|
|
76
|
+
.option("--json", "JSON output")
|
|
77
|
+
.action((opts) => {
|
|
78
|
+
if (opts.json) return console.log(JSON.stringify(GPTQ_BITS, null, 2));
|
|
79
|
+
for (const b of GPTQ_BITS) console.log(` ${b}-bit`);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
/* ── Job Lifecycle ─────────────────────────────────── */
|
|
83
|
+
|
|
84
|
+
quant
|
|
85
|
+
.command("create")
|
|
86
|
+
.description("Create a quantization job")
|
|
87
|
+
.requiredOption("-i, --input <path>", "Source model path")
|
|
88
|
+
.option("-o, --output <path>", "Output path")
|
|
89
|
+
.requiredOption("-t, --type <gguf|gptq>", "Quantization type")
|
|
90
|
+
.option("-l, --level <level>", "GGUF quantization level (e.g. Q4_K_M)")
|
|
91
|
+
.option(
|
|
92
|
+
"-c, --config <json>",
|
|
93
|
+
"Config JSON (for GPTQ: bits, groupSize, etc.)",
|
|
94
|
+
)
|
|
95
|
+
.option("--json", "JSON output")
|
|
96
|
+
.action((opts) => {
|
|
97
|
+
const db = _dbFromCtx(quant);
|
|
98
|
+
let config = null;
|
|
99
|
+
if (opts.config) {
|
|
100
|
+
try {
|
|
101
|
+
config = JSON.parse(opts.config);
|
|
102
|
+
} catch (_e) {
|
|
103
|
+
config = opts.config;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const result = createJob(db, {
|
|
107
|
+
inputPath: opts.input,
|
|
108
|
+
outputPath: opts.output,
|
|
109
|
+
quantType: opts.type,
|
|
110
|
+
quantLevel: opts.level,
|
|
111
|
+
config,
|
|
112
|
+
});
|
|
113
|
+
if (opts.json) return console.log(JSON.stringify(result, null, 2));
|
|
114
|
+
if (result.created) console.log(`Job created: ${result.jobId}`);
|
|
115
|
+
else console.log(`Failed: ${result.reason}`);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
quant
|
|
119
|
+
.command("start <id>")
|
|
120
|
+
.description("Start a pending job (simulated)")
|
|
121
|
+
.option("--json", "JSON output")
|
|
122
|
+
.action((id, opts) => {
|
|
123
|
+
const db = _dbFromCtx(quant);
|
|
124
|
+
const result = startJob(db, id);
|
|
125
|
+
if (opts.json) return console.log(JSON.stringify(result, null, 2));
|
|
126
|
+
console.log(
|
|
127
|
+
result.started ? `Job started: ${id}` : `Failed: ${result.reason}`,
|
|
128
|
+
);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
quant
|
|
132
|
+
.command("progress <id> <percent>")
|
|
133
|
+
.description("Update job progress (0-100)")
|
|
134
|
+
.option("--json", "JSON output")
|
|
135
|
+
.action((id, percent, opts) => {
|
|
136
|
+
const db = _dbFromCtx(quant);
|
|
137
|
+
const result = updateProgress(db, id, Number(percent));
|
|
138
|
+
if (opts.json) return console.log(JSON.stringify(result, null, 2));
|
|
139
|
+
console.log(
|
|
140
|
+
result.updated
|
|
141
|
+
? `Progress: ${result.progress}%`
|
|
142
|
+
: `Failed: ${result.reason}`,
|
|
143
|
+
);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
quant
|
|
147
|
+
.command("complete <id>")
|
|
148
|
+
.description("Mark a running job as completed")
|
|
149
|
+
.option("-o, --output <path>", "Output file path")
|
|
150
|
+
.option("-s, --size <bytes>", "Output file size in bytes", parseInt)
|
|
151
|
+
.option("--json", "JSON output")
|
|
152
|
+
.action((id, opts) => {
|
|
153
|
+
const db = _dbFromCtx(quant);
|
|
154
|
+
const result = completeJob(db, id, {
|
|
155
|
+
outputPath: opts.output,
|
|
156
|
+
fileSizeBytes: opts.size,
|
|
157
|
+
});
|
|
158
|
+
if (opts.json) return console.log(JSON.stringify(result, null, 2));
|
|
159
|
+
console.log(
|
|
160
|
+
result.completed ? "Job completed." : `Failed: ${result.reason}`,
|
|
161
|
+
);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
quant
|
|
165
|
+
.command("fail <id>")
|
|
166
|
+
.description("Mark a job as failed")
|
|
167
|
+
.option("-e, --error <message>", "Error message")
|
|
168
|
+
.option("--json", "JSON output")
|
|
169
|
+
.action((id, opts) => {
|
|
170
|
+
const db = _dbFromCtx(quant);
|
|
171
|
+
const result = failJob(db, id, opts.error);
|
|
172
|
+
if (opts.json) return console.log(JSON.stringify(result, null, 2));
|
|
173
|
+
console.log(
|
|
174
|
+
result.failed ? "Job marked as failed." : `Failed: ${result.reason}`,
|
|
175
|
+
);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
quant
|
|
179
|
+
.command("cancel <id>")
|
|
180
|
+
.description("Cancel a pending or running job")
|
|
181
|
+
.option("--json", "JSON output")
|
|
182
|
+
.action((id, opts) => {
|
|
183
|
+
const db = _dbFromCtx(quant);
|
|
184
|
+
const result = cancelJob(db, id);
|
|
185
|
+
if (opts.json) return console.log(JSON.stringify(result, null, 2));
|
|
186
|
+
console.log(
|
|
187
|
+
result.cancelled ? "Job cancelled." : `Failed: ${result.reason}`,
|
|
188
|
+
);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
quant
|
|
192
|
+
.command("delete <id>")
|
|
193
|
+
.description("Delete a non-running job")
|
|
194
|
+
.option("--json", "JSON output")
|
|
195
|
+
.action((id, opts) => {
|
|
196
|
+
const db = _dbFromCtx(quant);
|
|
197
|
+
const result = deleteJob(db, id);
|
|
198
|
+
if (opts.json) return console.log(JSON.stringify(result, null, 2));
|
|
199
|
+
console.log(result.deleted ? "Job deleted." : `Failed: ${result.reason}`);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
/* ── Query ─────────────────────────────────────────── */
|
|
203
|
+
|
|
204
|
+
quant
|
|
205
|
+
.command("show <id>")
|
|
206
|
+
.description("Show job details")
|
|
207
|
+
.option("--json", "JSON output")
|
|
208
|
+
.action((id, opts) => {
|
|
209
|
+
const db = _dbFromCtx(quant);
|
|
210
|
+
const j = getJob(db, id);
|
|
211
|
+
if (!j) return console.log("Job not found.");
|
|
212
|
+
if (opts.json) return console.log(JSON.stringify(j, null, 2));
|
|
213
|
+
console.log(`ID: ${j.id}`);
|
|
214
|
+
console.log(`Input: ${j.input_path}`);
|
|
215
|
+
if (j.output_path) console.log(`Output: ${j.output_path}`);
|
|
216
|
+
console.log(`Type: ${j.quant_type}`);
|
|
217
|
+
if (j.quant_level) console.log(`Level: ${j.quant_level}`);
|
|
218
|
+
console.log(`Status: ${j.status}`);
|
|
219
|
+
console.log(`Progress: ${j.progress}%`);
|
|
220
|
+
if (j.file_size_bytes)
|
|
221
|
+
console.log(`Size: ${j.file_size_bytes} bytes`);
|
|
222
|
+
if (j.error_message) console.log(`Error: ${j.error_message}`);
|
|
223
|
+
if (j.config) console.log(`Config: ${j.config}`);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
quant
|
|
227
|
+
.command("list")
|
|
228
|
+
.description("List quantization jobs")
|
|
229
|
+
.option("-s, --status <status>", "Filter by status")
|
|
230
|
+
.option("-t, --type <type>", "Filter by quant type (gguf/gptq)")
|
|
231
|
+
.option("--limit <n>", "Max results", parseInt)
|
|
232
|
+
.option("--json", "JSON output")
|
|
233
|
+
.action((opts) => {
|
|
234
|
+
const db = _dbFromCtx(quant);
|
|
235
|
+
const results = listJobs(db, {
|
|
236
|
+
status: opts.status,
|
|
237
|
+
quantType: opts.type,
|
|
238
|
+
limit: opts.limit,
|
|
239
|
+
});
|
|
240
|
+
if (opts.json) return console.log(JSON.stringify(results, null, 2));
|
|
241
|
+
if (results.length === 0) return console.log("No jobs.");
|
|
242
|
+
for (const j of results) {
|
|
243
|
+
console.log(
|
|
244
|
+
` ${j.status.padEnd(10)} ${j.quant_type.padEnd(5)} ${(j.quant_level || "-").padEnd(8)} ${String(j.progress).padEnd(6)}% ${j.input_path.slice(0, 30).padEnd(32)} ${j.id.slice(0, 8)}`,
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
/* ── Stats ─────────────────────────────────────────── */
|
|
250
|
+
|
|
251
|
+
quant
|
|
252
|
+
.command("stats")
|
|
253
|
+
.description("Quantization statistics")
|
|
254
|
+
.option("--json", "JSON output")
|
|
255
|
+
.action((opts) => {
|
|
256
|
+
const db = _dbFromCtx(quant);
|
|
257
|
+
const s = getQuantizationStats(db);
|
|
258
|
+
if (opts.json) return console.log(JSON.stringify(s, null, 2));
|
|
259
|
+
console.log(`Total jobs: ${s.total} (completed: ${s.completed})`);
|
|
260
|
+
for (const [status, count] of Object.entries(s.byStatus)) {
|
|
261
|
+
if (count > 0) console.log(` ${status.padEnd(10)} ${count}`);
|
|
262
|
+
}
|
|
263
|
+
console.log(`By type:`);
|
|
264
|
+
for (const [type, count] of Object.entries(s.byType)) {
|
|
265
|
+
if (count > 0) console.log(` ${type.padEnd(6)} ${count}`);
|
|
266
|
+
}
|
|
267
|
+
if (Object.keys(s.byLevel).length > 0) {
|
|
268
|
+
console.log(`By level:`);
|
|
269
|
+
for (const [level, count] of Object.entries(s.byLevel)) {
|
|
270
|
+
console.log(` ${level.padEnd(8)} ${count}`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (s.totalSizeBytes > 0)
|
|
274
|
+
console.log(`Total output: ${s.totalSizeBytes} bytes`);
|
|
275
|
+
if (s.avgDurationMs > 0)
|
|
276
|
+
console.log(`Avg duration: ${s.avgDurationMs}ms`);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
program.addCommand(quant);
|
|
280
|
+
}
|