@bike4mind/cli 0.2.31-b4m-cli-undo-command.19535 → 0.2.31-b4m-cli-undo-command.19598
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/dist/{artifactExtractor-T6NJ7V7P.js → artifactExtractor-IKIJZW6C.js} +1 -1
- package/dist/{chunk-F4PXVLZX.js → chunk-4P27WV34.js} +2 -2
- package/dist/{chunk-M2QCFHVX.js → chunk-BXNVLTPU.js} +6 -6
- package/dist/{chunk-JWJF6O4L.js → chunk-DQHCE3TN.js} +2 -2
- package/dist/{chunk-NI22LIK3.js → chunk-PLA2VBQW.js} +13 -1
- package/dist/{chunk-3SPW5FYJ.js → chunk-PV6PZFPC.js} +67 -5
- package/dist/{chunk-ERV5G6MX.js → chunk-S6AUIWWB.js} +2 -2
- package/dist/commands/doctorCommand.js +1 -1
- package/dist/commands/updateCommand.js +1 -1
- package/dist/{create-XOEMSBER.js → create-PVJSCD5H.js} +3 -3
- package/dist/index.js +965 -29
- package/dist/{llmMarkdownGenerator-NPX7ULSW.js → llmMarkdownGenerator-BMYWIXYB.js} +1 -1
- package/dist/{markdownGenerator-TVJ2RQXC.js → markdownGenerator-H7BNB5KO.js} +1 -1
- package/dist/{mementoService-HGH2XVLM.js → mementoService-RDPCVXWF.js} +3 -3
- package/dist/{src-JZ6OHGTX.js → src-DCF72PTU.js} +2 -2
- package/dist/{src-2BRBILH7.js → src-IKK3N7TZ.js} +1 -1
- package/dist/{subtractCredits-4VIHTUR4.js → subtractCredits-K4PWRUF4.js} +3 -3
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "./chunk-GQGOWACU.js";
|
|
3
|
-
import "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
import "./chunk-4P27WV34.js";
|
|
4
|
+
import "./chunk-S6AUIWWB.js";
|
|
5
5
|
import "./chunk-BPFEGDC7.js";
|
|
6
6
|
import "./chunk-BDQBOLYG.js";
|
|
7
7
|
import {
|
|
8
8
|
getEffectiveApiKey,
|
|
9
9
|
getOpenWeatherKey,
|
|
10
10
|
getSerperKey
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-DQHCE3TN.js";
|
|
12
12
|
import {
|
|
13
13
|
ConfigStore,
|
|
14
14
|
logger
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
import {
|
|
17
17
|
checkForUpdate,
|
|
18
18
|
package_default
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-BXNVLTPU.js";
|
|
20
20
|
import {
|
|
21
21
|
selectActiveBackgroundAgents,
|
|
22
22
|
useCliStore
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
OpenAIBackend,
|
|
33
33
|
OpenAIImageService,
|
|
34
34
|
XAIImageService
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-PV6PZFPC.js";
|
|
36
36
|
import {
|
|
37
37
|
AiEvents,
|
|
38
38
|
ApiKeyEvents,
|
|
@@ -90,7 +90,7 @@ import {
|
|
|
90
90
|
getMcpProviderMetadata,
|
|
91
91
|
getViewById,
|
|
92
92
|
resolveNavigationIntents
|
|
93
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-PLA2VBQW.js";
|
|
94
94
|
import {
|
|
95
95
|
Logger
|
|
96
96
|
} from "./chunk-PFBYGCOW.js";
|
|
@@ -1368,11 +1368,11 @@ var JobItem = React8.memo(function JobItem2({
|
|
|
1368
1368
|
job,
|
|
1369
1369
|
indented = false
|
|
1370
1370
|
}) {
|
|
1371
|
-
const
|
|
1371
|
+
const elapsed2 = Math.round((Date.now() - job.startTime) / 1e3);
|
|
1372
1372
|
const maxTaskLength = indented ? 50 : 60;
|
|
1373
1373
|
const taskPreview = job.task.length > maxTaskLength ? job.task.slice(0, maxTaskLength - 3) + "..." : job.task;
|
|
1374
1374
|
const isQueued = job.status === "queued";
|
|
1375
|
-
return /* @__PURE__ */ React8.createElement(Box7, null, indented && /* @__PURE__ */ React8.createElement(Text7, null, " "), isQueued ? /* @__PURE__ */ React8.createElement(Text7, { color: "yellow" }, "\u23F3") : /* @__PURE__ */ React8.createElement(Text7, { color: "blue" }, /* @__PURE__ */ React8.createElement(Spinner2, { type: "dots" })), /* @__PURE__ */ React8.createElement(Text7, { color: isQueued ? "yellow" : "blue" }, " ", job.agentName), /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, " ", "[", job.id, "] ", taskPreview, " ", isQueued ? "(queued)" : `(${
|
|
1375
|
+
return /* @__PURE__ */ React8.createElement(Box7, null, indented && /* @__PURE__ */ React8.createElement(Text7, null, " "), isQueued ? /* @__PURE__ */ React8.createElement(Text7, { color: "yellow" }, "\u23F3") : /* @__PURE__ */ React8.createElement(Text7, { color: "blue" }, /* @__PURE__ */ React8.createElement(Spinner2, { type: "dots" })), /* @__PURE__ */ React8.createElement(Text7, { color: isQueued ? "yellow" : "blue" }, " ", job.agentName), /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, " ", "[", job.id, "] ", taskPreview, " ", isQueued ? "(queued)" : `(${elapsed2}s)`));
|
|
1376
1376
|
});
|
|
1377
1377
|
function formatStatusCounts(jobs) {
|
|
1378
1378
|
let running = 0;
|
|
@@ -10550,7 +10550,8 @@ var SchedulingProblemSchema = z139.object({
|
|
|
10550
10550
|
name: z139.string(),
|
|
10551
10551
|
description: z139.string().optional(),
|
|
10552
10552
|
jobs: z139.array(JobSchema),
|
|
10553
|
-
machines: z139.array(MachineSchema)
|
|
10553
|
+
machines: z139.array(MachineSchema),
|
|
10554
|
+
solvedJobUrl: z139.string().url().optional()
|
|
10554
10555
|
});
|
|
10555
10556
|
var SolverIdSchema = z139.enum([
|
|
10556
10557
|
"greedy",
|
|
@@ -11215,6 +11216,351 @@ function constructSolution(allOps, pheromone, heuristic, rng) {
|
|
|
11215
11216
|
return result;
|
|
11216
11217
|
}
|
|
11217
11218
|
|
|
11219
|
+
// ../../b4m-core/packages/quantum/dist/src/solvers/highs-formulation.js
|
|
11220
|
+
function analyzeProblemComplexity(problem) {
|
|
11221
|
+
const numJobs = problem.jobs.length;
|
|
11222
|
+
const numMachines = problem.machines.length;
|
|
11223
|
+
const opsPerJob = problem.jobs[0]?.operations.length || 0;
|
|
11224
|
+
const totalOps = problem.jobs.reduce((sum2, j) => sum2 + j.operations.length, 0);
|
|
11225
|
+
const machineOpCounts = /* @__PURE__ */ new Map();
|
|
11226
|
+
for (const job of problem.jobs) {
|
|
11227
|
+
for (const op of job.operations) {
|
|
11228
|
+
machineOpCounts.set(op.machineId, (machineOpCounts.get(op.machineId) || 0) + 1);
|
|
11229
|
+
}
|
|
11230
|
+
}
|
|
11231
|
+
const opCounts = Array.from(machineOpCounts.values());
|
|
11232
|
+
const minOps = opCounts.length > 0 ? Math.min(...opCounts) : 0;
|
|
11233
|
+
const maxOps = opCounts.length > 0 ? Math.max(...opCounts) : 0;
|
|
11234
|
+
const avgOps = opCounts.length > 0 ? opCounts.reduce((a, b) => a + b, 0) / opCounts.length : 0;
|
|
11235
|
+
let binaryVars = 0;
|
|
11236
|
+
for (const n of opCounts) {
|
|
11237
|
+
binaryVars += n * (n - 1) / 2;
|
|
11238
|
+
}
|
|
11239
|
+
const startTimeVars = totalOps;
|
|
11240
|
+
const totalVars = startTimeVars + binaryVars + 1;
|
|
11241
|
+
const jobPrecedenceConstraints = problem.jobs.reduce((sum2, j) => sum2 + Math.max(0, j.operations.length - 1), 0);
|
|
11242
|
+
const machineDisjunctionConstraints = 2 * binaryVars;
|
|
11243
|
+
const makespanConstraints = totalOps;
|
|
11244
|
+
const totalConstraints = jobPrecedenceConstraints + machineDisjunctionConstraints + makespanConstraints;
|
|
11245
|
+
return {
|
|
11246
|
+
numJobs,
|
|
11247
|
+
numMachines,
|
|
11248
|
+
opsPerJob,
|
|
11249
|
+
totalOps,
|
|
11250
|
+
startTimeVars,
|
|
11251
|
+
binaryVars,
|
|
11252
|
+
totalVars,
|
|
11253
|
+
jobPrecedenceConstraints,
|
|
11254
|
+
machineDisjunctionConstraints,
|
|
11255
|
+
makespanConstraints,
|
|
11256
|
+
totalConstraints,
|
|
11257
|
+
opsPerMachine: { min: minOps, max: maxOps, avg: Math.round(avgOps * 10) / 10 }
|
|
11258
|
+
};
|
|
11259
|
+
}
|
|
11260
|
+
function estimateViability(c) {
|
|
11261
|
+
if (c.opsPerMachine.max > 10) {
|
|
11262
|
+
return {
|
|
11263
|
+
viable: false,
|
|
11264
|
+
risk: "high",
|
|
11265
|
+
recommendation: `Too many ops on one machine (${c.opsPerMachine.max}). Add more machines to spread the load, or use Simulated Annealing.`
|
|
11266
|
+
};
|
|
11267
|
+
}
|
|
11268
|
+
if (c.binaryVars <= 80 && c.totalOps <= 40 && c.opsPerMachine.max <= 6) {
|
|
11269
|
+
return {
|
|
11270
|
+
viable: true,
|
|
11271
|
+
risk: "low",
|
|
11272
|
+
recommendation: "Should solve quickly (< 1 second)"
|
|
11273
|
+
};
|
|
11274
|
+
}
|
|
11275
|
+
if (c.binaryVars <= 150 && c.totalOps <= 80 && c.opsPerMachine.max <= 8) {
|
|
11276
|
+
return {
|
|
11277
|
+
viable: true,
|
|
11278
|
+
risk: "medium",
|
|
11279
|
+
recommendation: "Should solve in 1-30 seconds. WASM may have occasional instability."
|
|
11280
|
+
};
|
|
11281
|
+
}
|
|
11282
|
+
if (c.binaryVars > 150) {
|
|
11283
|
+
return {
|
|
11284
|
+
viable: false,
|
|
11285
|
+
risk: "high",
|
|
11286
|
+
recommendation: `Too many binary vars (${c.binaryVars} > 150). Use Simulated Annealing or Tabu Search for this size.`
|
|
11287
|
+
};
|
|
11288
|
+
}
|
|
11289
|
+
if (c.totalOps > 80) {
|
|
11290
|
+
return {
|
|
11291
|
+
viable: false,
|
|
11292
|
+
risk: "high",
|
|
11293
|
+
recommendation: `Too many operations (${c.totalOps} > 80). Use Simulated Annealing or Tabu Search for this size.`
|
|
11294
|
+
};
|
|
11295
|
+
}
|
|
11296
|
+
return {
|
|
11297
|
+
viable: false,
|
|
11298
|
+
risk: "high",
|
|
11299
|
+
recommendation: "Exceeds tested parameters. Consider using Simulated Annealing or Tabu Search."
|
|
11300
|
+
};
|
|
11301
|
+
}
|
|
11302
|
+
function generateLPFormulation(problem) {
|
|
11303
|
+
const ops = [];
|
|
11304
|
+
for (const job of problem.jobs) {
|
|
11305
|
+
for (let opIdx = 0; opIdx < job.operations.length; opIdx++) {
|
|
11306
|
+
const op = job.operations[opIdx];
|
|
11307
|
+
const varName = `sJ${job.id}O${opIdx + 1}`;
|
|
11308
|
+
ops.push({
|
|
11309
|
+
jobId: job.id,
|
|
11310
|
+
machineId: op.machineId,
|
|
11311
|
+
opIndex: opIdx,
|
|
11312
|
+
duration: op.duration,
|
|
11313
|
+
varName
|
|
11314
|
+
});
|
|
11315
|
+
}
|
|
11316
|
+
}
|
|
11317
|
+
const bigM = ops.reduce((sum2, op) => sum2 + op.duration, 0);
|
|
11318
|
+
const machineOps = /* @__PURE__ */ new Map();
|
|
11319
|
+
for (const op of ops) {
|
|
11320
|
+
const machOps = machineOps.get(op.machineId) || [];
|
|
11321
|
+
machOps.push(op);
|
|
11322
|
+
machineOps.set(op.machineId, machOps);
|
|
11323
|
+
}
|
|
11324
|
+
const lines = [];
|
|
11325
|
+
lines.push("Minimize obj: Cmax");
|
|
11326
|
+
lines.push("");
|
|
11327
|
+
lines.push("Subject To");
|
|
11328
|
+
for (const job of problem.jobs) {
|
|
11329
|
+
for (let i = 0; i < job.operations.length - 1; i++) {
|
|
11330
|
+
const op1VarName = `sJ${job.id}O${i + 1}`;
|
|
11331
|
+
const op2VarName = `sJ${job.id}O${i + 2}`;
|
|
11332
|
+
const duration = job.operations[i].duration;
|
|
11333
|
+
const constraintName = `job${op1VarName}to${op2VarName}`;
|
|
11334
|
+
lines.push(` ${constraintName}: ${op1VarName} - ${op2VarName} <= ${-duration}`);
|
|
11335
|
+
}
|
|
11336
|
+
}
|
|
11337
|
+
const binaryVars = [];
|
|
11338
|
+
for (const [, machOps] of machineOps) {
|
|
11339
|
+
if (machOps.length < 2)
|
|
11340
|
+
continue;
|
|
11341
|
+
for (let i = 0; i < machOps.length; i++) {
|
|
11342
|
+
for (let j = i + 1; j < machOps.length; j++) {
|
|
11343
|
+
const op1 = machOps[i];
|
|
11344
|
+
const op2 = machOps[j];
|
|
11345
|
+
const yVar = `y${op1.varName}x${op2.varName}`;
|
|
11346
|
+
binaryVars.push(yVar);
|
|
11347
|
+
const c1Name = `d${op1.varName}b${op2.varName}`;
|
|
11348
|
+
lines.push(` ${c1Name}: ${op1.varName} - ${op2.varName} + ${bigM} ${yVar} <= ${bigM - op1.duration}`);
|
|
11349
|
+
const c2Name = `d${op2.varName}b${op1.varName}`;
|
|
11350
|
+
lines.push(` ${c2Name}: ${op2.varName} - ${op1.varName} - ${bigM} ${yVar} <= ${-op2.duration}`);
|
|
11351
|
+
}
|
|
11352
|
+
}
|
|
11353
|
+
}
|
|
11354
|
+
for (const op of ops) {
|
|
11355
|
+
const constraintName = `mk${op.varName}`;
|
|
11356
|
+
lines.push(` ${constraintName}: ${op.varName} - Cmax <= ${-op.duration}`);
|
|
11357
|
+
}
|
|
11358
|
+
lines.push("");
|
|
11359
|
+
lines.push("Bounds");
|
|
11360
|
+
for (const op of ops) {
|
|
11361
|
+
lines.push(` ${op.varName} >= 0`);
|
|
11362
|
+
}
|
|
11363
|
+
lines.push(" Cmax >= 0");
|
|
11364
|
+
lines.push("");
|
|
11365
|
+
if (binaryVars.length > 0) {
|
|
11366
|
+
lines.push("Binary");
|
|
11367
|
+
for (const v of binaryVars) {
|
|
11368
|
+
lines.push(` ${v}`);
|
|
11369
|
+
}
|
|
11370
|
+
lines.push("");
|
|
11371
|
+
}
|
|
11372
|
+
lines.push("End");
|
|
11373
|
+
return lines.join("\n");
|
|
11374
|
+
}
|
|
11375
|
+
function parseSolution(problem, columns) {
|
|
11376
|
+
const schedule = [];
|
|
11377
|
+
const varToOp = /* @__PURE__ */ new Map();
|
|
11378
|
+
for (const job of problem.jobs) {
|
|
11379
|
+
for (let opIdx = 0; opIdx < job.operations.length; opIdx++) {
|
|
11380
|
+
const op = job.operations[opIdx];
|
|
11381
|
+
const varName = `sJ${job.id}O${opIdx + 1}`;
|
|
11382
|
+
varToOp.set(varName, {
|
|
11383
|
+
jobId: job.id,
|
|
11384
|
+
machineId: op.machineId,
|
|
11385
|
+
opIndex: opIdx,
|
|
11386
|
+
duration: op.duration
|
|
11387
|
+
});
|
|
11388
|
+
}
|
|
11389
|
+
}
|
|
11390
|
+
for (const [varName, col] of Object.entries(columns)) {
|
|
11391
|
+
if (varName.startsWith("sJ")) {
|
|
11392
|
+
const opInfo = varToOp.get(varName);
|
|
11393
|
+
if (opInfo) {
|
|
11394
|
+
const startTime = Math.round(col.Primal);
|
|
11395
|
+
schedule.push({
|
|
11396
|
+
jobId: opInfo.jobId,
|
|
11397
|
+
machineId: opInfo.machineId,
|
|
11398
|
+
operationIndex: opInfo.opIndex,
|
|
11399
|
+
startTime,
|
|
11400
|
+
endTime: startTime + opInfo.duration
|
|
11401
|
+
});
|
|
11402
|
+
}
|
|
11403
|
+
}
|
|
11404
|
+
}
|
|
11405
|
+
schedule.sort((a, b) => a.startTime - b.startTime);
|
|
11406
|
+
return schedule;
|
|
11407
|
+
}
|
|
11408
|
+
function validateSchedule(problem, schedule) {
|
|
11409
|
+
const errors = [];
|
|
11410
|
+
const scheduledKeys = new Set(schedule.map((s) => `${s.jobId}-${s.operationIndex}`));
|
|
11411
|
+
for (const job of problem.jobs) {
|
|
11412
|
+
for (let opIdx = 0; opIdx < job.operations.length; opIdx++) {
|
|
11413
|
+
if (!scheduledKeys.has(`${job.id}-${opIdx}`)) {
|
|
11414
|
+
errors.push(`Operation (job=${job.id}, opIndex=${opIdx}) not scheduled`);
|
|
11415
|
+
}
|
|
11416
|
+
}
|
|
11417
|
+
}
|
|
11418
|
+
const byMachine = /* @__PURE__ */ new Map();
|
|
11419
|
+
for (const s of schedule) {
|
|
11420
|
+
const mOps = byMachine.get(s.machineId) || [];
|
|
11421
|
+
mOps.push(s);
|
|
11422
|
+
byMachine.set(s.machineId, mOps);
|
|
11423
|
+
}
|
|
11424
|
+
for (const [machineId, mOps] of byMachine) {
|
|
11425
|
+
mOps.sort((a, b) => a.startTime - b.startTime);
|
|
11426
|
+
for (let i = 0; i < mOps.length - 1; i++) {
|
|
11427
|
+
if (mOps[i].endTime > mOps[i + 1].startTime) {
|
|
11428
|
+
errors.push(`Machine ${machineId}: (job=${mOps[i].jobId},op=${mOps[i].operationIndex}) ends ${mOps[i].endTime} overlaps (job=${mOps[i + 1].jobId},op=${mOps[i + 1].operationIndex}) starts ${mOps[i + 1].startTime}`);
|
|
11429
|
+
}
|
|
11430
|
+
}
|
|
11431
|
+
}
|
|
11432
|
+
const opEndTime = /* @__PURE__ */ new Map();
|
|
11433
|
+
for (const s of schedule) {
|
|
11434
|
+
opEndTime.set(`${s.jobId}-${s.operationIndex}`, s.endTime);
|
|
11435
|
+
}
|
|
11436
|
+
for (const job of problem.jobs) {
|
|
11437
|
+
for (let i = 0; i < job.operations.length - 1; i++) {
|
|
11438
|
+
const op1End = opEndTime.get(`${job.id}-${i}`) || 0;
|
|
11439
|
+
const op2 = schedule.find((s) => s.jobId === job.id && s.operationIndex === i + 1);
|
|
11440
|
+
if (op2 && op1End > op2.startTime) {
|
|
11441
|
+
errors.push(`Job ${job.id}: op ${i} ends at ${op1End} but op ${i + 1} starts at ${op2.startTime}`);
|
|
11442
|
+
}
|
|
11443
|
+
}
|
|
11444
|
+
}
|
|
11445
|
+
return { valid: errors.length === 0, errors };
|
|
11446
|
+
}
|
|
11447
|
+
|
|
11448
|
+
// ../../b4m-core/packages/quantum/dist/src/solvers/highs-solver.js
|
|
11449
|
+
var MAX_BINARY_VARS = 150;
|
|
11450
|
+
var MAX_TOTAL_OPS = 80;
|
|
11451
|
+
var MAX_OPS_PER_MACHINE = 8;
|
|
11452
|
+
async function loadHiGHS() {
|
|
11453
|
+
const highsLoader = (await import("highs")).default;
|
|
11454
|
+
const highs = await highsLoader({
|
|
11455
|
+
locateFile: (file) => {
|
|
11456
|
+
const globalSelf = globalThis;
|
|
11457
|
+
if (globalSelf.location?.origin) {
|
|
11458
|
+
return `${globalSelf.location.origin}/${file}`;
|
|
11459
|
+
}
|
|
11460
|
+
return file;
|
|
11461
|
+
}
|
|
11462
|
+
});
|
|
11463
|
+
return highs;
|
|
11464
|
+
}
|
|
11465
|
+
function elapsed(startTime) {
|
|
11466
|
+
return typeof performance !== "undefined" ? performance.now() - startTime : Date.now() - startTime;
|
|
11467
|
+
}
|
|
11468
|
+
var highsSolver = {
|
|
11469
|
+
id: "highs",
|
|
11470
|
+
name: "HiGHS (WASM)",
|
|
11471
|
+
description: "Open-source MIP solver providing provably optimal solutions for small-to-medium scheduling problems via WASM.",
|
|
11472
|
+
async solve(problem, options) {
|
|
11473
|
+
const startTime = typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
11474
|
+
const reportProgress = (percentage, bestMakespan) => {
|
|
11475
|
+
options?.onProgress?.({
|
|
11476
|
+
solverId: "highs",
|
|
11477
|
+
percentage,
|
|
11478
|
+
bestMakespan
|
|
11479
|
+
});
|
|
11480
|
+
};
|
|
11481
|
+
reportProgress(0);
|
|
11482
|
+
try {
|
|
11483
|
+
reportProgress(5);
|
|
11484
|
+
const highs = await loadHiGHS();
|
|
11485
|
+
reportProgress(10);
|
|
11486
|
+
const complexity = analyzeProblemComplexity(problem);
|
|
11487
|
+
const viability = estimateViability(complexity);
|
|
11488
|
+
if (complexity.binaryVars > MAX_BINARY_VARS) {
|
|
11489
|
+
throw new Error(`Problem has too many binary variables for HiGHS WASM: ${complexity.binaryVars} (max ${MAX_BINARY_VARS}). Tip: More machines spreads ops and reduces binary vars. Current: ${complexity.numMachines} machines. For this size, use Simulated Annealing or Tabu Search.`);
|
|
11490
|
+
}
|
|
11491
|
+
if (complexity.totalOps > MAX_TOTAL_OPS) {
|
|
11492
|
+
throw new Error(`Problem too large for HiGHS WASM: ${complexity.totalOps} operations (max ${MAX_TOTAL_OPS}). For larger problems, use Simulated Annealing or Tabu Search.`);
|
|
11493
|
+
}
|
|
11494
|
+
if (complexity.opsPerMachine.max > MAX_OPS_PER_MACHINE) {
|
|
11495
|
+
throw new Error(`Too many operations on one machine: ${complexity.opsPerMachine.max} ops (max ${MAX_OPS_PER_MACHINE}). Tip: Add more machines to spread the load. For this size, use Simulated Annealing or Tabu Search.`);
|
|
11496
|
+
}
|
|
11497
|
+
if (viability.risk === "high") {
|
|
11498
|
+
console.warn(`[HiGHS] Warning: ${viability.recommendation}`);
|
|
11499
|
+
}
|
|
11500
|
+
reportProgress(15);
|
|
11501
|
+
const lpString = generateLPFormulation(problem);
|
|
11502
|
+
if (!lpString.includes("Subject To") || !lpString.includes("Bounds")) {
|
|
11503
|
+
throw new Error("Invalid LP formulation - missing required sections");
|
|
11504
|
+
}
|
|
11505
|
+
reportProgress(20);
|
|
11506
|
+
let solution;
|
|
11507
|
+
try {
|
|
11508
|
+
solution = highs.solve(lpString, {
|
|
11509
|
+
time_limit: options?.timeoutMs ? options.timeoutMs / 1e3 : 60,
|
|
11510
|
+
mip_rel_gap: 0,
|
|
11511
|
+
presolve: "on",
|
|
11512
|
+
log_to_console: true,
|
|
11513
|
+
// MUST BE TRUE - see file header
|
|
11514
|
+
output_flag: true
|
|
11515
|
+
// MUST BE TRUE - see file header
|
|
11516
|
+
});
|
|
11517
|
+
} catch (solveError) {
|
|
11518
|
+
console.error("[HiGHS] Solve error:", solveError);
|
|
11519
|
+
console.error("[HiGHS] Problem config:", {
|
|
11520
|
+
jobs: problem.jobs.length,
|
|
11521
|
+
machines: problem.machines.length,
|
|
11522
|
+
totalOps: problem.jobs.reduce((sum2, j) => sum2 + j.operations.length, 0)
|
|
11523
|
+
});
|
|
11524
|
+
const errMsg = solveError instanceof Error ? solveError.message : String(solveError);
|
|
11525
|
+
if (errMsg.includes("Aborted")) {
|
|
11526
|
+
throw new Error(`HiGHS WASM crashed. This may be a numerical issue with the problem configuration. Jobs: ${problem.jobs.length}, Machines: ${problem.machines.length}. Check browser console for details.`);
|
|
11527
|
+
}
|
|
11528
|
+
throw solveError;
|
|
11529
|
+
}
|
|
11530
|
+
if (solution.Status === "Infeasible") {
|
|
11531
|
+
throw new Error("Problem is infeasible - check constraints");
|
|
11532
|
+
}
|
|
11533
|
+
if (solution.Status === "Unbounded") {
|
|
11534
|
+
throw new Error("Problem is unbounded - check objective");
|
|
11535
|
+
}
|
|
11536
|
+
if (solution.Status !== "Optimal" && solution.Status !== "Time limit reached" && solution.Status !== "Bound on objective reached") {
|
|
11537
|
+
throw new Error(`HiGHS returned unexpected status: ${solution.Status}`);
|
|
11538
|
+
}
|
|
11539
|
+
reportProgress(90);
|
|
11540
|
+
const schedule = parseSolution(problem, solution.Columns);
|
|
11541
|
+
const makespan = Math.ceil(solution.ObjectiveValue);
|
|
11542
|
+
const validation = validateSchedule(problem, schedule);
|
|
11543
|
+
if (!validation.valid) {
|
|
11544
|
+
console.warn("[HiGHS] Solution validation failed:", validation.errors);
|
|
11545
|
+
const errorDetails = validation.errors && validation.errors.length > 0 ? validation.errors.join("; ") : "Unknown validation error";
|
|
11546
|
+
throw new Error(`[HiGHS] Solution validation failed: ${errorDetails}`);
|
|
11547
|
+
}
|
|
11548
|
+
reportProgress(100, makespan);
|
|
11549
|
+
return {
|
|
11550
|
+
solverId: "highs",
|
|
11551
|
+
solverName: "HiGHS (WASM)",
|
|
11552
|
+
makespan,
|
|
11553
|
+
schedule,
|
|
11554
|
+
elapsedMs: elapsed(startTime),
|
|
11555
|
+
iterations: 1
|
|
11556
|
+
};
|
|
11557
|
+
} catch (error) {
|
|
11558
|
+
reportProgress(0);
|
|
11559
|
+
throw error;
|
|
11560
|
+
}
|
|
11561
|
+
}
|
|
11562
|
+
};
|
|
11563
|
+
|
|
11218
11564
|
// ../../b4m-core/packages/quantum/dist/src/solvers/metadata.js
|
|
11219
11565
|
var solverMetadata = {
|
|
11220
11566
|
naive: {
|
|
@@ -11483,7 +11829,6 @@ var solverMetadata = {
|
|
|
11483
11829
|
color: "success",
|
|
11484
11830
|
complexity: "Seconds to minutes",
|
|
11485
11831
|
requires: "Browser compute (WASM)",
|
|
11486
|
-
available: false,
|
|
11487
11832
|
tagline: "Open-source solver rivaling commercial giants",
|
|
11488
11833
|
fullDescription: "HiGHS (High-performance Interior-point, Gradient-descent, Simplex) is an MIT-licensed open-source solver that achieves 90%+ of commercial solver performance. Developed at the University of Edinburgh, it has rapidly become the leading open-source alternative to Gurobi and COPT for linear and mixed-integer programming.",
|
|
11489
11834
|
howItWorks: [
|
|
@@ -11557,7 +11902,10 @@ var solverMetadata = {
|
|
|
11557
11902
|
wikipedia: "https://en.wikipedia.org/wiki/Quantum_approximate_optimization_algorithm",
|
|
11558
11903
|
otherResources: [
|
|
11559
11904
|
{ label: "Farhi et al. (2014) \u2014 Original QAOA Paper", url: "https://arxiv.org/abs/1411.4028" },
|
|
11560
|
-
{
|
|
11905
|
+
{
|
|
11906
|
+
label: "QUBO Formulation Guide",
|
|
11907
|
+
url: "https://en.wikipedia.org/wiki/Quadratic_unconstrained_binary_optimization"
|
|
11908
|
+
}
|
|
11561
11909
|
]
|
|
11562
11910
|
},
|
|
11563
11911
|
"ionq-qaoa": {
|
|
@@ -11615,7 +11963,8 @@ var allSolvers = [
|
|
|
11615
11963
|
simulatedAnnealingLargeSolver,
|
|
11616
11964
|
tabuSolver,
|
|
11617
11965
|
geneticAlgorithmSolver,
|
|
11618
|
-
antColonySolver
|
|
11966
|
+
antColonySolver,
|
|
11967
|
+
highsSolver
|
|
11619
11968
|
];
|
|
11620
11969
|
var solverRegistry = new Map(allSolvers.map((s) => [s.id, s]));
|
|
11621
11970
|
function getSolver(id) {
|
|
@@ -11626,7 +11975,6 @@ function getAvailableSolverIds() {
|
|
|
11626
11975
|
}
|
|
11627
11976
|
var displaySolvers = [
|
|
11628
11977
|
...allSolvers.map((s) => ({ id: s.id, name: s.name, description: s.description })),
|
|
11629
|
-
{ id: "highs", name: "HiGHS (WASM)", description: solverMetadata.highs.tagline },
|
|
11630
11978
|
{ id: "simulated-qaoa", name: "Simulated QAOA", description: solverMetadata["simulated-qaoa"].tagline },
|
|
11631
11979
|
{ id: "ionq-qaoa", name: "IonQ QAOA", description: solverMetadata["ionq-qaoa"].tagline }
|
|
11632
11980
|
];
|
|
@@ -11651,11 +11999,17 @@ ${allSolvers.map((s) => `- **${s.name}** (\`${s.id}\`): ${s.description}`).join(
|
|
|
11651
11999
|
|
|
11652
12000
|
## How to Help Users
|
|
11653
12001
|
|
|
11654
|
-
###
|
|
11655
|
-
When a user describes a scheduling
|
|
11656
|
-
1. Use \`quantum_formulate\` to convert their description into
|
|
11657
|
-
2.
|
|
11658
|
-
3.
|
|
12002
|
+
### Concierge Flow (Default)
|
|
12003
|
+
When a user describes a scheduling problem:
|
|
12004
|
+
1. Use \`quantum_formulate\` to convert their description \u2014 the problem auto-loads into the Problem Editor
|
|
12005
|
+
2. Call \`navigate_view\` with viewId "opti.scheduling.problem" so the user gets a button to open the Problem tab
|
|
12006
|
+
3. Let the user review, tweak machines/durations, and run solvers from the dashboard
|
|
12007
|
+
Do NOT auto-call \`quantum_schedule\` unless the user explicitly asks to solve in chat.
|
|
12008
|
+
|
|
12009
|
+
### Power User Fast Path
|
|
12010
|
+
If the user says "solve it", "find the optimal schedule", or explicitly requests an in-chat solution,
|
|
12011
|
+
use both \`quantum_formulate\` AND \`quantum_schedule\`. The problem still loads into the Editor
|
|
12012
|
+
so the user can explore results in the dashboard too.
|
|
11659
12013
|
|
|
11660
12014
|
### Running Solvers
|
|
11661
12015
|
When solving a problem:
|
|
@@ -11720,6 +12074,581 @@ RESPOND WITH ONLY A JSON OBJECT matching this schema:
|
|
|
11720
12074
|
|
|
11721
12075
|
No markdown, no explanation, no code blocks \u2014 just the raw JSON object.`;
|
|
11722
12076
|
|
|
12077
|
+
// ../../b4m-core/packages/quantum/dist/src/patterns.js
|
|
12078
|
+
var patternFamilies = [
|
|
12079
|
+
{
|
|
12080
|
+
id: "scheduling",
|
|
12081
|
+
name: "Scheduling",
|
|
12082
|
+
description: "Job shop, flow shop, resource allocation over time",
|
|
12083
|
+
complexity: "NP-hard",
|
|
12084
|
+
color: "#e53935",
|
|
12085
|
+
quboFit: "excellent",
|
|
12086
|
+
examples: ["Job Shop Scheduling", "Task Scheduling", "Production Planning"],
|
|
12087
|
+
status: "available",
|
|
12088
|
+
tagline: "When to do things, in what order, on what resources",
|
|
12089
|
+
asciiDiagram: [
|
|
12090
|
+
" 0 2 4 6 8 10 12",
|
|
12091
|
+
" \u251C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u253C\u2500\u2500\u2524",
|
|
12092
|
+
"A [\u25A0\u25A0\u25A0\u25A0\u25A0][ \u2591\u2591\u2591\u2591\u2591\u2591 ]",
|
|
12093
|
+
"B [\u2591\u2591\u2591\u2591\u2591][ \u25A0\u25A0\u25A0\u25A0\u25A0 ]",
|
|
12094
|
+
"C [\u25A0\u25A0\u25A0] [\u2591\u2591\u2591\u2591\u2591\u2591]",
|
|
12095
|
+
" \u2500\u2500\u2500\u2500 time \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25BA"
|
|
12096
|
+
].join("\n"),
|
|
12097
|
+
subPatterns: [
|
|
12098
|
+
{
|
|
12099
|
+
name: "Job Shop Scheduling",
|
|
12100
|
+
subtitle: "The Classic",
|
|
12101
|
+
description: "Assign jobs to machines with precedence constraints. Each job has a sequence of operations that must be processed on specific machines in order. The goal is to minimize the total makespan.",
|
|
12102
|
+
asciiDiagram: [
|
|
12103
|
+
"J1: [M-A 3t]->[M-B 2t]->[M-C 4t]",
|
|
12104
|
+
"J2: [M-B 2t]->[M-C 3t]->[M-A 2t]",
|
|
12105
|
+
"J3: [M-C 4t]->[M-A 1t]->[M-B 3t]",
|
|
12106
|
+
"",
|
|
12107
|
+
"Objective: Minimize total completion time"
|
|
12108
|
+
].join("\n"),
|
|
12109
|
+
quboFitStars: 5
|
|
12110
|
+
},
|
|
12111
|
+
{
|
|
12112
|
+
name: "Flow Shop Scheduling",
|
|
12113
|
+
subtitle: "Fixed Sequence",
|
|
12114
|
+
description: "All jobs follow the same machine order. Simpler than job shop but still NP-hard for 3+ machines. Common in assembly lines and manufacturing pipelines.",
|
|
12115
|
+
asciiDiagram: [
|
|
12116
|
+
"Job 1: -->[M1]-->[M2]-->[M3]--> Done",
|
|
12117
|
+
"Job 2: -->[M1]-->[M2]-->[M3]--> Done",
|
|
12118
|
+
"Job 3: -->[M1]-->[M2]-->[M3]--> Done",
|
|
12119
|
+
" Fixed order through all machines"
|
|
12120
|
+
].join("\n"),
|
|
12121
|
+
quboFitStars: 5
|
|
12122
|
+
},
|
|
12123
|
+
{
|
|
12124
|
+
name: "Timetabling",
|
|
12125
|
+
subtitle: "Conflict Avoidance",
|
|
12126
|
+
description: "Schedule events into time slots while avoiding conflicts. No professor teaches two classes at once, no student has overlapping classes, room capacities are respected.",
|
|
12127
|
+
asciiDiagram: [
|
|
12128
|
+
" Mon Tue Wed Thu",
|
|
12129
|
+
" 9:00 |CS101| |CS101| |",
|
|
12130
|
+
"10:00 | |MATH | |MATH |",
|
|
12131
|
+
"11:00 |PHYS | |PHYS | |",
|
|
12132
|
+
" No conflicts for shared resources!"
|
|
12133
|
+
].join("\n"),
|
|
12134
|
+
quboFitStars: 4
|
|
12135
|
+
},
|
|
12136
|
+
{
|
|
12137
|
+
name: "Sequencing with Changeover",
|
|
12138
|
+
subtitle: "Order Matters",
|
|
12139
|
+
description: "Transition costs between tasks depend on the sequence. Paint lines minimize cleaning by ordering light-to-dark. Semiconductor fabs batch similar wafers together.",
|
|
12140
|
+
asciiDiagram: [
|
|
12141
|
+
"White->Yellow->Orange $0 each",
|
|
12142
|
+
"Orange->Red->Black $0 each",
|
|
12143
|
+
"White->Black directly $50 clean!",
|
|
12144
|
+
"",
|
|
12145
|
+
"Objective: Minimize total changeover cost"
|
|
12146
|
+
].join("\n"),
|
|
12147
|
+
quboFitStars: 4
|
|
12148
|
+
},
|
|
12149
|
+
{
|
|
12150
|
+
name: "Dynamic Scheduling",
|
|
12151
|
+
subtitle: "Continuous Arrival",
|
|
12152
|
+
description: "New jobs arrive during execution, requiring real-time rescheduling. Common in hospitals, data centers, and cloud computing where demand is unpredictable.",
|
|
12153
|
+
asciiDiagram: [
|
|
12154
|
+
"Time --------------------------->",
|
|
12155
|
+
"J1 ========",
|
|
12156
|
+
" J2 ==========",
|
|
12157
|
+
" J3 ======= (arrived t=3)",
|
|
12158
|
+
" J4 === (arrived t=5)",
|
|
12159
|
+
" Must reschedule as jobs arrive!"
|
|
12160
|
+
].join("\n"),
|
|
12161
|
+
quboFitStars: 3
|
|
12162
|
+
}
|
|
12163
|
+
],
|
|
12164
|
+
quboExplainer: "Each binary variable x(j,m,t) = 1 if job j starts on machine m at time t. Penalty terms enforce: (1) each operation scheduled exactly once, (2) precedence constraints respected, (3) no machine processes two jobs simultaneously. Qubit count scales as O(jobs x machines x time_horizon).",
|
|
12165
|
+
useCases: [
|
|
12166
|
+
{ industry: "Manufacturing", application: "Factory floor scheduling" },
|
|
12167
|
+
{ industry: "Healthcare", application: "Operating room scheduling" },
|
|
12168
|
+
{ industry: "Airlines", application: "Crew and gate scheduling" },
|
|
12169
|
+
{ industry: "Data Centers", application: "Batch job scheduling" },
|
|
12170
|
+
{ industry: "Construction", application: "Project task sequencing" },
|
|
12171
|
+
{ industry: "Restaurants", application: "Kitchen order optimization" }
|
|
12172
|
+
]
|
|
12173
|
+
},
|
|
12174
|
+
{
|
|
12175
|
+
id: "routing",
|
|
12176
|
+
name: "Routing",
|
|
12177
|
+
description: "Vehicle routing, TSP, network path optimization",
|
|
12178
|
+
complexity: "NP-hard",
|
|
12179
|
+
color: "#66bb6a",
|
|
12180
|
+
quboFit: "excellent",
|
|
12181
|
+
examples: ["Traveling Salesman", "Vehicle Routing", "Delivery Optimization"],
|
|
12182
|
+
status: "coming-soon",
|
|
12183
|
+
tagline: "How to move through space efficiently",
|
|
12184
|
+
asciiDiagram: [
|
|
12185
|
+
" A",
|
|
12186
|
+
" /|\\",
|
|
12187
|
+
" 5/ | \\3",
|
|
12188
|
+
" / | \\",
|
|
12189
|
+
" B---+---C",
|
|
12190
|
+
" \\ | /",
|
|
12191
|
+
" 7\\ | /2",
|
|
12192
|
+
" \\|/",
|
|
12193
|
+
" D"
|
|
12194
|
+
].join("\n"),
|
|
12195
|
+
subPatterns: [
|
|
12196
|
+
{
|
|
12197
|
+
name: "Traveling Salesman (TSP)",
|
|
12198
|
+
subtitle: "The Classic",
|
|
12199
|
+
description: "Visit all cities exactly once and return home via the shortest route. One of the most famous optimization problems \u2014 100+ cities makes exhaustive search impossible.",
|
|
12200
|
+
asciiDiagram: [
|
|
12201
|
+
"Start -> A -> B -> C -> D -> Start",
|
|
12202
|
+
"",
|
|
12203
|
+
"Find the shortest tour that visits",
|
|
12204
|
+
"every city exactly once!"
|
|
12205
|
+
].join("\n"),
|
|
12206
|
+
quboFitStars: 5
|
|
12207
|
+
},
|
|
12208
|
+
{
|
|
12209
|
+
name: "Vehicle Routing (VRP)",
|
|
12210
|
+
subtitle: "Multiple Vehicles",
|
|
12211
|
+
description: "Partition customers among a fleet of vehicles, each with capacity limits and time windows. TSP generalized to multiple routes from a central depot.",
|
|
12212
|
+
asciiDiagram: [
|
|
12213
|
+
" Depot",
|
|
12214
|
+
" / | \\",
|
|
12215
|
+
" / | \\",
|
|
12216
|
+
" Route1 Route2 Route3",
|
|
12217
|
+
" A->B D->E G->H",
|
|
12218
|
+
" ->C ->F ->I"
|
|
12219
|
+
].join("\n"),
|
|
12220
|
+
quboFitStars: 4
|
|
12221
|
+
},
|
|
12222
|
+
{
|
|
12223
|
+
name: "Shortest Path",
|
|
12224
|
+
subtitle: "Point-to-Point",
|
|
12225
|
+
description: "Find the minimum-cost path between two nodes in a weighted graph. Foundation for GPS navigation, network routing, and supply chain logistics.",
|
|
12226
|
+
asciiDiagram: [
|
|
12227
|
+
"S --3-- A --2-- T",
|
|
12228
|
+
"| | |",
|
|
12229
|
+
"5 1 4",
|
|
12230
|
+
"| | |",
|
|
12231
|
+
"B --6-- C --2-- D"
|
|
12232
|
+
].join("\n"),
|
|
12233
|
+
quboFitStars: 3
|
|
12234
|
+
}
|
|
12235
|
+
],
|
|
12236
|
+
quboExplainer: "Binary variable x(i,t) = 1 if city i is visited at step t. Constraints: each city visited exactly once, each step visits exactly one city. Objective minimizes total edge weights along the tour. Classic QUBO formulation.",
|
|
12237
|
+
useCases: [
|
|
12238
|
+
{ industry: "Logistics", application: "Delivery route optimization" },
|
|
12239
|
+
{ industry: "Ride-sharing", application: "Driver dispatch routing" },
|
|
12240
|
+
{ industry: "Telecom", application: "Network packet routing" },
|
|
12241
|
+
{ industry: "Retail", application: "Supply chain distribution" },
|
|
12242
|
+
{ industry: "Field Service", application: "Technician visit scheduling" }
|
|
12243
|
+
]
|
|
12244
|
+
},
|
|
12245
|
+
{
|
|
12246
|
+
id: "packing",
|
|
12247
|
+
name: "Packing",
|
|
12248
|
+
description: "Bin packing, knapsack, container optimization",
|
|
12249
|
+
complexity: "NP-complete",
|
|
12250
|
+
color: "#e91e63",
|
|
12251
|
+
quboFit: "good",
|
|
12252
|
+
examples: ["Bin Packing", "Knapsack Problem", "Container Loading"],
|
|
12253
|
+
status: "coming-soon",
|
|
12254
|
+
tagline: "How to fit things into space efficiently",
|
|
12255
|
+
asciiDiagram: [
|
|
12256
|
+
"\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
|
|
12257
|
+
"\u2502 \u2588\u2588\u2588\u2588 \u2591\u2591\u2591\u2591 \u2588\u2588\u2588\u2588\u2588\u2588 \u2502 92%",
|
|
12258
|
+
"\u2502 \u2588\u2588\u2588\u2588 \u2591\u2591\u2591\u2591 \u2588\u2588\u2588\u2588\u2588\u2588 \u2502",
|
|
12259
|
+
"\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524",
|
|
12260
|
+
"\u2502 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2591\u2591\u2591\u2591\u2591\u2591\u2591 \u2502 68%",
|
|
12261
|
+
"\u2502 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2591\u2591\u2591\u2591\u2591\u2591\u2591 \u2502",
|
|
12262
|
+
"\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"
|
|
12263
|
+
].join("\n"),
|
|
12264
|
+
subPatterns: [
|
|
12265
|
+
{
|
|
12266
|
+
name: "Bin Packing",
|
|
12267
|
+
subtitle: "1D/2D/3D",
|
|
12268
|
+
description: "Fit items into the minimum number of bins. 1D (rod cutting, memory), 2D (sheet cutting, floor plans), 3D (container loading, truck packing). Items arrive online or in batch.",
|
|
12269
|
+
asciiDiagram: [
|
|
12270
|
+
"Items: [3] [5] [2] [4] [6]",
|
|
12271
|
+
"",
|
|
12272
|
+
"Bin 1: [3][5][2] = 10/10",
|
|
12273
|
+
"Bin 2: [4][6] = 10/10",
|
|
12274
|
+
"Minimum bins: 2"
|
|
12275
|
+
].join("\n"),
|
|
12276
|
+
quboFitStars: 4
|
|
12277
|
+
},
|
|
12278
|
+
{
|
|
12279
|
+
name: "Knapsack",
|
|
12280
|
+
subtitle: "Value vs Weight",
|
|
12281
|
+
description: "Select items to maximize total value without exceeding weight capacity. The 0/1 knapsack is a direct binary problem \u2014 include or exclude each item.",
|
|
12282
|
+
asciiDiagram: [
|
|
12283
|
+
"Item Value Weight",
|
|
12284
|
+
" A 60 10",
|
|
12285
|
+
" B 100 20 <-- pick",
|
|
12286
|
+
" C 120 30 <-- pick",
|
|
12287
|
+
"Capacity: 50 Best: $220"
|
|
12288
|
+
].join("\n"),
|
|
12289
|
+
quboFitStars: 5
|
|
12290
|
+
},
|
|
12291
|
+
{
|
|
12292
|
+
name: "Cutting Stock",
|
|
12293
|
+
subtitle: "Minimize Waste",
|
|
12294
|
+
description: "Cut raw material (steel rolls, fabric bolts, lumber) into required pieces with minimal waste. Dual of bin packing \u2014 subtract from fixed-size stock.",
|
|
12295
|
+
asciiDiagram: [
|
|
12296
|
+
"Stock roll: |============|",
|
|
12297
|
+
"Cut: |==A==|==B==|=C=|xx|",
|
|
12298
|
+
" waste",
|
|
12299
|
+
"Objective: Minimize total waste"
|
|
12300
|
+
].join("\n"),
|
|
12301
|
+
quboFitStars: 4
|
|
12302
|
+
}
|
|
12303
|
+
],
|
|
12304
|
+
quboExplainer: "Binary variable x(i,b) = 1 if item i is placed in bin b. Constraints: each item in exactly one bin, bin capacity not exceeded. For knapsack, x(i) = 1 if item i is selected, with weight constraint as penalty term.",
|
|
12305
|
+
useCases: [
|
|
12306
|
+
{ industry: "Shipping", application: "Container loading optimization" },
|
|
12307
|
+
{ industry: "Manufacturing", application: "Raw material cutting" },
|
|
12308
|
+
{ industry: "Cloud Computing", application: "VM placement on servers" },
|
|
12309
|
+
{ industry: "Retail", application: "Warehouse space allocation" },
|
|
12310
|
+
{ industry: "Finance", application: "Budget allocation (knapsack)" }
|
|
12311
|
+
]
|
|
12312
|
+
},
|
|
12313
|
+
{
|
|
12314
|
+
id: "assignment",
|
|
12315
|
+
name: "Assignment",
|
|
12316
|
+
description: "Matching agents to tasks, resource allocation",
|
|
12317
|
+
complexity: "NP-complete",
|
|
12318
|
+
color: "#42a5f5",
|
|
12319
|
+
quboFit: "excellent",
|
|
12320
|
+
examples: ["Task Assignment", "Resource Matching", "Workforce Allocation"],
|
|
12321
|
+
status: "coming-soon",
|
|
12322
|
+
tagline: "Who does what \u2014 optimal matching",
|
|
12323
|
+
asciiDiagram: [
|
|
12324
|
+
" Agents Tasks",
|
|
12325
|
+
" [A] \u2500\u2500\u2500\u2500\u2500\u2500 [1]",
|
|
12326
|
+
" [B] \u2500\u2500\u2510",
|
|
12327
|
+
" \u2514\u2500\u2500 [2]",
|
|
12328
|
+
" [C] \u2500\u2500\u2500\u2500\u2500\u2500 [3]",
|
|
12329
|
+
" [D] \u2500\u2500\u2500\u2500\u2500\u2500 [4]"
|
|
12330
|
+
].join("\n"),
|
|
12331
|
+
subPatterns: [
|
|
12332
|
+
{
|
|
12333
|
+
name: "Bipartite Matching",
|
|
12334
|
+
subtitle: "One-to-One",
|
|
12335
|
+
description: "Match agents to tasks where each agent handles exactly one task and vice versa. Minimize total cost or maximize total benefit across all assignments.",
|
|
12336
|
+
asciiDiagram: [
|
|
12337
|
+
"Workers Jobs",
|
|
12338
|
+
" Alice ---> Design cost: 3",
|
|
12339
|
+
" Bob -----> Code cost: 2",
|
|
12340
|
+
" Carol ---> Test cost: 4",
|
|
12341
|
+
"Total cost: 9 (optimal)"
|
|
12342
|
+
].join("\n"),
|
|
12343
|
+
quboFitStars: 5
|
|
12344
|
+
},
|
|
12345
|
+
{
|
|
12346
|
+
name: "Quadratic Assignment",
|
|
12347
|
+
subtitle: "Location Matters",
|
|
12348
|
+
description: "Assign facilities to locations minimizing the product of flow between facilities and distance between locations. Used for factory layout and chip placement.",
|
|
12349
|
+
asciiDiagram: [
|
|
12350
|
+
"Facility Flow Location Dist",
|
|
12351
|
+
" A <-50-> B L1 <-3-> L2",
|
|
12352
|
+
" A <-20-> C L1 <-5-> L3",
|
|
12353
|
+
"Minimize: sum(flow*distance)"
|
|
12354
|
+
].join("\n"),
|
|
12355
|
+
quboFitStars: 5
|
|
12356
|
+
},
|
|
12357
|
+
{
|
|
12358
|
+
name: "Generalized Assignment",
|
|
12359
|
+
subtitle: "Many-to-One",
|
|
12360
|
+
description: "Assign tasks to agents where each agent can handle multiple tasks within their capacity. Workers have different skills and capacities across task types.",
|
|
12361
|
+
asciiDiagram: [
|
|
12362
|
+
"Agent A (cap 10): [T1:3][T2:4][T3:3]",
|
|
12363
|
+
"Agent B (cap 8): [T4:5][T5:3]",
|
|
12364
|
+
"Agent C (cap 12): [T6:6][T7:4]",
|
|
12365
|
+
"Maximize quality within capacity"
|
|
12366
|
+
].join("\n"),
|
|
12367
|
+
quboFitStars: 4
|
|
12368
|
+
}
|
|
12369
|
+
],
|
|
12370
|
+
quboExplainer: "Binary variable x(i,j) = 1 if agent i is assigned to task j. Constraints: each task assigned to exactly one agent (row sums = 1), each agent at most one task (column sums <= 1). Cost matrix entries become QUBO coefficients.",
|
|
12371
|
+
useCases: [
|
|
12372
|
+
{ industry: "HR", application: "Employee-to-project matching" },
|
|
12373
|
+
{ industry: "Education", application: "Student-to-course assignment" },
|
|
12374
|
+
{ industry: "Healthcare", application: "Doctor-to-shift assignment" },
|
|
12375
|
+
{ industry: "Military", application: "Weapon-target assignment" },
|
|
12376
|
+
{ industry: "Sports", application: "Referee-to-game assignment" }
|
|
12377
|
+
]
|
|
12378
|
+
},
|
|
12379
|
+
{
|
|
12380
|
+
id: "network",
|
|
12381
|
+
name: "Network",
|
|
12382
|
+
description: "Graph partitioning, max cut, community detection",
|
|
12383
|
+
complexity: "NP-hard",
|
|
12384
|
+
color: "#f4511e",
|
|
12385
|
+
quboFit: "excellent",
|
|
12386
|
+
examples: ["Graph Partitioning", "Max Cut", "Network Design"],
|
|
12387
|
+
status: "coming-soon",
|
|
12388
|
+
tagline: "How to structure and divide networks",
|
|
12389
|
+
asciiDiagram: [
|
|
12390
|
+
" a-b-c | d-e",
|
|
12391
|
+
" | | | | |",
|
|
12392
|
+
" f-g | h-i",
|
|
12393
|
+
" -------+-------",
|
|
12394
|
+
" Group A | Group B",
|
|
12395
|
+
" max cut \u2702"
|
|
12396
|
+
].join("\n"),
|
|
12397
|
+
subPatterns: [
|
|
12398
|
+
{
|
|
12399
|
+
name: "Max Cut",
|
|
12400
|
+
subtitle: "The QUBO Natural",
|
|
12401
|
+
description: "Partition graph nodes into two groups to maximize edges crossing the cut. The most natural QUBO problem \u2014 maps directly without any reformulation tricks.",
|
|
12402
|
+
asciiDiagram: [
|
|
12403
|
+
"Group 0 | Group 1",
|
|
12404
|
+
" a--b | d--e",
|
|
12405
|
+
" | | |",
|
|
12406
|
+
" c ------+------ f",
|
|
12407
|
+
" cut edges = 3 (max!)"
|
|
12408
|
+
].join("\n"),
|
|
12409
|
+
quboFitStars: 5
|
|
12410
|
+
},
|
|
12411
|
+
{
|
|
12412
|
+
name: "Graph Partitioning",
|
|
12413
|
+
subtitle: "Balanced Split",
|
|
12414
|
+
description: "Divide nodes into k equal-sized groups minimizing edges between groups. Used for parallel computing load balancing and VLSI chip layout.",
|
|
12415
|
+
asciiDiagram: [
|
|
12416
|
+
"Before: tangled graph",
|
|
12417
|
+
"After: [ A ] | [ B ] | [ C ]",
|
|
12418
|
+
" n/3 | n/3 | n/3",
|
|
12419
|
+
"Minimize cross-partition edges"
|
|
12420
|
+
].join("\n"),
|
|
12421
|
+
quboFitStars: 5
|
|
12422
|
+
},
|
|
12423
|
+
{
|
|
12424
|
+
name: "Community Detection",
|
|
12425
|
+
subtitle: "Find Clusters",
|
|
12426
|
+
description: "Discover densely connected groups within a network. Social networks, protein interactions, citation graphs. Related to modularity maximization.",
|
|
12427
|
+
asciiDiagram: [
|
|
12428
|
+
"(a-b-c) (d-e-f)",
|
|
12429
|
+
" dense dense",
|
|
12430
|
+
" \\ /",
|
|
12431
|
+
" sparse",
|
|
12432
|
+
"Find the natural communities"
|
|
12433
|
+
].join("\n"),
|
|
12434
|
+
quboFitStars: 4
|
|
12435
|
+
}
|
|
12436
|
+
],
|
|
12437
|
+
quboExplainer: "For Max Cut: x(i) = 0 or 1 assigns node i to a group. Objective maximizes sum of w(i,j) * x(i) * (1-x(j)) over all edges. This is already a QUBO \u2014 no reformulation needed! Graph partitioning adds a balance constraint as a penalty term.",
|
|
12438
|
+
useCases: [
|
|
12439
|
+
{ industry: "Social Media", application: "Community detection" },
|
|
12440
|
+
{ industry: "VLSI Design", application: "Chip layout partitioning" },
|
|
12441
|
+
{ industry: "HPC", application: "Parallel workload balancing" },
|
|
12442
|
+
{ industry: "Biology", application: "Protein interaction clustering" },
|
|
12443
|
+
{ industry: "Telecom", application: "Network segmentation" }
|
|
12444
|
+
]
|
|
12445
|
+
},
|
|
12446
|
+
{
|
|
12447
|
+
id: "selection",
|
|
12448
|
+
name: "Selection",
|
|
12449
|
+
description: "Portfolio optimization, feature selection, subset problems",
|
|
12450
|
+
complexity: "NP-complete",
|
|
12451
|
+
color: "#00897b",
|
|
12452
|
+
quboFit: "good",
|
|
12453
|
+
examples: ["Portfolio Selection", "Feature Selection", "Subset Sum"],
|
|
12454
|
+
status: "coming-soon",
|
|
12455
|
+
tagline: "Which items to choose from a set",
|
|
12456
|
+
asciiDiagram: [
|
|
12457
|
+
" [\u25A0] [\xB7] [\u25A0] [\xB7]",
|
|
12458
|
+
" [\xB7] [\u25A0] [\xB7] [\u25A0]",
|
|
12459
|
+
" [\u25A0] [\xB7] [\xB7] [\xB7]",
|
|
12460
|
+
" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
12461
|
+
" \u25A0 = selected 5/12",
|
|
12462
|
+
" score: 847 / 1000"
|
|
12463
|
+
].join("\n"),
|
|
12464
|
+
subPatterns: [
|
|
12465
|
+
{
|
|
12466
|
+
name: "Portfolio Optimization",
|
|
12467
|
+
subtitle: "Risk vs Return",
|
|
12468
|
+
description: "Select assets to maximize return while minimizing risk (variance). Markowitz model is naturally quadratic \u2014 covariance matrix maps directly to QUBO interactions.",
|
|
12469
|
+
asciiDiagram: [
|
|
12470
|
+
"Return ^",
|
|
12471
|
+
" | * efficient frontier",
|
|
12472
|
+
" | *",
|
|
12473
|
+
" | * <- optimal portfolio",
|
|
12474
|
+
" |* ",
|
|
12475
|
+
" +---------> Risk"
|
|
12476
|
+
].join("\n"),
|
|
12477
|
+
quboFitStars: 5
|
|
12478
|
+
},
|
|
12479
|
+
{
|
|
12480
|
+
name: "Feature Selection",
|
|
12481
|
+
subtitle: "Signal vs Noise",
|
|
12482
|
+
description: "Choose the best subset of features for a machine learning model. Too many features cause overfitting; too few miss signal. Binary choice per feature makes this naturally QUBO.",
|
|
12483
|
+
asciiDiagram: [
|
|
12484
|
+
"Features: [x1] [x2] [x3] ... [xN]",
|
|
12485
|
+
"Select: Y N Y ... N",
|
|
12486
|
+
"",
|
|
12487
|
+
"Maximize: accuracy - lambda*count"
|
|
12488
|
+
].join("\n"),
|
|
12489
|
+
quboFitStars: 4
|
|
12490
|
+
},
|
|
12491
|
+
{
|
|
12492
|
+
name: "Set Cover",
|
|
12493
|
+
subtitle: "Minimum Coverage",
|
|
12494
|
+
description: "Choose the fewest subsets that together cover all elements. Used for sensor placement, test suite minimization, and service location planning.",
|
|
12495
|
+
asciiDiagram: [
|
|
12496
|
+
"Universe: {1,2,3,4,5,6,7}",
|
|
12497
|
+
"S1={1,2,3} S2={2,4} S3={3,4,5}",
|
|
12498
|
+
"S4={5,6,7} S5={1,6}",
|
|
12499
|
+
"Solution: S1 + S3 + S4 (covers all)"
|
|
12500
|
+
].join("\n"),
|
|
12501
|
+
quboFitStars: 4
|
|
12502
|
+
}
|
|
12503
|
+
],
|
|
12504
|
+
quboExplainer: "Binary variable x(i) = 1 if item i is selected. For portfolio: minimize x^T * Sigma * x - lambda * mu^T * x where Sigma is covariance and mu is expected return. The quadratic form IS the QUBO \u2014 no conversion needed.",
|
|
12505
|
+
useCases: [
|
|
12506
|
+
{ industry: "Finance", application: "Portfolio construction" },
|
|
12507
|
+
{ industry: "Machine Learning", application: "Feature subset selection" },
|
|
12508
|
+
{ industry: "Telecom", application: "Cell tower placement" },
|
|
12509
|
+
{ industry: "Insurance", application: "Product bundle selection" },
|
|
12510
|
+
{ industry: "Military", application: "Sensor network deployment" }
|
|
12511
|
+
]
|
|
12512
|
+
},
|
|
12513
|
+
{
|
|
12514
|
+
id: "economic",
|
|
12515
|
+
name: "Economic",
|
|
12516
|
+
description: "Market equilibrium, auction design, pricing",
|
|
12517
|
+
complexity: "NP-hard",
|
|
12518
|
+
color: "#ab47bc",
|
|
12519
|
+
quboFit: "experimental",
|
|
12520
|
+
examples: ["Market Clearing", "Auction Optimization", "Price Discovery"],
|
|
12521
|
+
status: "coming-soon",
|
|
12522
|
+
tagline: "Finding optimal prices and market equilibria",
|
|
12523
|
+
asciiDiagram: [
|
|
12524
|
+
" P \u2502\\ /",
|
|
12525
|
+
" \u2502 \\ / Supply",
|
|
12526
|
+
" \u2502 \\/",
|
|
12527
|
+
" \u2502 /\\ \u2190 equilibrium",
|
|
12528
|
+
" \u2502 / \\",
|
|
12529
|
+
" \u2502/ \\ Demand",
|
|
12530
|
+
" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Q"
|
|
12531
|
+
].join("\n"),
|
|
12532
|
+
subPatterns: [
|
|
12533
|
+
{
|
|
12534
|
+
name: "Market Clearing",
|
|
12535
|
+
subtitle: "Equilibrium",
|
|
12536
|
+
description: "Find prices where supply meets demand across multiple goods simultaneously. Power grid markets clear hourly; financial exchanges clear in microseconds.",
|
|
12537
|
+
asciiDiagram: [
|
|
12538
|
+
"Buyers: B1=$50 B2=$40 B3=$30",
|
|
12539
|
+
"Sellers: S1=$20 S2=$35 S3=$45",
|
|
12540
|
+
"Clear price: $35-40 (2 trades)",
|
|
12541
|
+
"Maximize social welfare"
|
|
12542
|
+
].join("\n"),
|
|
12543
|
+
quboFitStars: 3
|
|
12544
|
+
},
|
|
12545
|
+
{
|
|
12546
|
+
name: "Combinatorial Auction",
|
|
12547
|
+
subtitle: "Bundle Bidding",
|
|
12548
|
+
description: "Bidders submit bids on bundles of items. Winner determination maximizes revenue while ensuring each item sold at most once. Directly maps to weighted set packing.",
|
|
12549
|
+
asciiDiagram: [
|
|
12550
|
+
"Bid 1: {A,B} = $100",
|
|
12551
|
+
"Bid 2: {B,C} = $80",
|
|
12552
|
+
"Bid 3: {A} = $60",
|
|
12553
|
+
"Bid 4: {C} = $50",
|
|
12554
|
+
"Best: Bid 1 + Bid 4 = $150"
|
|
12555
|
+
].join("\n"),
|
|
12556
|
+
quboFitStars: 4
|
|
12557
|
+
},
|
|
12558
|
+
{
|
|
12559
|
+
name: "Pricing Optimization",
|
|
12560
|
+
subtitle: "Revenue Maximization",
|
|
12561
|
+
description: "Set prices across products to maximize total revenue considering demand elasticity, competition, and cross-product effects (substitutes and complements).",
|
|
12562
|
+
asciiDiagram: [
|
|
12563
|
+
"Price Demand Revenue",
|
|
12564
|
+
" $10 100 $1000",
|
|
12565
|
+
" $15 70 $1050 <- optimal",
|
|
12566
|
+
" $20 40 $800",
|
|
12567
|
+
" $25 15 $375"
|
|
12568
|
+
].join("\n"),
|
|
12569
|
+
quboFitStars: 2
|
|
12570
|
+
}
|
|
12571
|
+
],
|
|
12572
|
+
quboExplainer: "Auction winner determination: x(i) = 1 if bid i is accepted. Maximize sum of bid values. Constraint: for each item, sum of accepted bids containing that item <= 1. Requires discretizing continuous prices into binary tiers for QUBO encoding.",
|
|
12573
|
+
useCases: [
|
|
12574
|
+
{ industry: "Energy", application: "Power market clearing" },
|
|
12575
|
+
{ industry: "Advertising", application: "Ad auction optimization" },
|
|
12576
|
+
{ industry: "Spectrum", application: "FCC spectrum auctions" },
|
|
12577
|
+
{ industry: "Retail", application: "Dynamic pricing strategy" },
|
|
12578
|
+
{ industry: "Agriculture", application: "Commodity market design" }
|
|
12579
|
+
]
|
|
12580
|
+
},
|
|
12581
|
+
{
|
|
12582
|
+
id: "continuous",
|
|
12583
|
+
name: "Continuous",
|
|
12584
|
+
description: "Continuous optimization with discretization",
|
|
12585
|
+
complexity: "NP-hard",
|
|
12586
|
+
color: "#78909c",
|
|
12587
|
+
quboFit: "fair",
|
|
12588
|
+
examples: ["Parameter Tuning", "Function Optimization", "Calibration"],
|
|
12589
|
+
status: "coming-soon",
|
|
12590
|
+
tagline: "Finding the best point in continuous space",
|
|
12591
|
+
asciiDiagram: [
|
|
12592
|
+
" f(x)",
|
|
12593
|
+
" \u2502 \u2571\u2572",
|
|
12594
|
+
" \u2502 \u2571 \u2572 \u2571\u2572",
|
|
12595
|
+
" \u2502\u2571 \u2572 \u2571 \u2572",
|
|
12596
|
+
" \u2502 \u2573 \u2572",
|
|
12597
|
+
" \u2502 \u2191 min \u2572",
|
|
12598
|
+
" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 x"
|
|
12599
|
+
].join("\n"),
|
|
12600
|
+
subPatterns: [
|
|
12601
|
+
{
|
|
12602
|
+
name: "Parameter Tuning",
|
|
12603
|
+
subtitle: "Find the Sweet Spot",
|
|
12604
|
+
description: "Optimize continuous parameters (temperature, pressure, learning rate) by discretizing into binary-encoded levels. Each parameter gets log2(levels) qubits.",
|
|
12605
|
+
asciiDiagram: [
|
|
12606
|
+
"Param A: [0.1, 0.2, 0.3, 0.4]",
|
|
12607
|
+
"Param B: [10, 20, 30, 40, 50]",
|
|
12608
|
+
"",
|
|
12609
|
+
"Encode: 2 bits per param (4 levels)",
|
|
12610
|
+
"Search 4x5 = 20 combinations"
|
|
12611
|
+
].join("\n"),
|
|
12612
|
+
quboFitStars: 3
|
|
12613
|
+
},
|
|
12614
|
+
{
|
|
12615
|
+
name: "Function Minimization",
|
|
12616
|
+
subtitle: "Global Optimum",
|
|
12617
|
+
description: "Find the global minimum of a multivariate function with many local minima. Discretize the domain and encode as QUBO. Quantum tunneling helps escape local optima.",
|
|
12618
|
+
asciiDiagram: [
|
|
12619
|
+
"f(x) ^",
|
|
12620
|
+
" | /\\ /\\",
|
|
12621
|
+
" | / \\ / \\",
|
|
12622
|
+
" |/ \\/ \\",
|
|
12623
|
+
" | global \\",
|
|
12624
|
+
" +-----min-----> x"
|
|
12625
|
+
].join("\n"),
|
|
12626
|
+
quboFitStars: 3
|
|
12627
|
+
},
|
|
12628
|
+
{
|
|
12629
|
+
name: "Calibration",
|
|
12630
|
+
subtitle: "Model Fitting",
|
|
12631
|
+
description: "Adjust model parameters to best fit observed data. When the error landscape is non-convex, classical gradient descent gets stuck. QUBO explores the full landscape.",
|
|
12632
|
+
asciiDiagram: [
|
|
12633
|
+
"Data: * * * * * *",
|
|
12634
|
+
"Model: ----\\--/--------",
|
|
12635
|
+
" \\/ <- fit here",
|
|
12636
|
+
"Minimize: sum(error^2)"
|
|
12637
|
+
].join("\n"),
|
|
12638
|
+
quboFitStars: 2
|
|
12639
|
+
}
|
|
12640
|
+
],
|
|
12641
|
+
quboExplainer: "Continuous variables are discretized into binary representation. For N levels, use log2(N) qubits per variable. The continuous objective function is approximated as a polynomial in binary variables, yielding a QUBO. Precision trades off against qubit count.",
|
|
12642
|
+
useCases: [
|
|
12643
|
+
{ industry: "Engineering", application: "Design parameter optimization" },
|
|
12644
|
+
{ industry: "ML/AI", application: "Hyperparameter tuning" },
|
|
12645
|
+
{ industry: "Chemistry", application: "Reaction condition optimization" },
|
|
12646
|
+
{ industry: "Finance", application: "Model calibration" },
|
|
12647
|
+
{ industry: "Manufacturing", application: "Process control tuning" }
|
|
12648
|
+
]
|
|
12649
|
+
}
|
|
12650
|
+
];
|
|
12651
|
+
|
|
11723
12652
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/quantumSchedule/index.js
|
|
11724
12653
|
function formatResult(result) {
|
|
11725
12654
|
const lines = [
|
|
@@ -11944,14 +12873,15 @@ ${problem.description}` : "",
|
|
|
11944
12873
|
"### Machines:",
|
|
11945
12874
|
...problem.machines.map((m) => `- ${m.name} (id: ${m.id})`),
|
|
11946
12875
|
"",
|
|
11947
|
-
|
|
11948
|
-
"```json",
|
|
11949
|
-
JSON.stringify(problem, null, 2),
|
|
11950
|
-
"```",
|
|
11951
|
-
"",
|
|
11952
|
-
"You can now use the `quantum_schedule` tool to solve this problem with various optimization algorithms."
|
|
12876
|
+
'A problem is ready to load. Navigate to the Problem tab and click "Load Problem" to review, tweak, and run solvers.'
|
|
11953
12877
|
];
|
|
11954
|
-
|
|
12878
|
+
const humanReadableSummary = lines.filter((l) => l !== void 0).join("\n");
|
|
12879
|
+
return JSON.stringify({
|
|
12880
|
+
__uiSideEffect: true,
|
|
12881
|
+
type: "populateProblem",
|
|
12882
|
+
payload: problem,
|
|
12883
|
+
displayMessage: humanReadableSummary
|
|
12884
|
+
});
|
|
11955
12885
|
} catch (err) {
|
|
11956
12886
|
return `Error formulating problem: ${err instanceof Error ? err.message : String(err)}`;
|
|
11957
12887
|
}
|
|
@@ -16752,6 +17682,10 @@ var ServerLlmBackend = class {
|
|
|
16752
17682
|
*/
|
|
16753
17683
|
getFallbackModels() {
|
|
16754
17684
|
return [
|
|
17685
|
+
{
|
|
17686
|
+
id: "claude-sonnet-4-6",
|
|
17687
|
+
name: "Claude 4.6 Sonnet"
|
|
17688
|
+
},
|
|
16755
17689
|
{
|
|
16756
17690
|
id: "claude-sonnet-4-5-20250929",
|
|
16757
17691
|
name: "Claude 4.5 Sonnet"
|
|
@@ -16962,6 +17896,7 @@ var WebSocketLlmBackend = class {
|
|
|
16962
17896
|
}
|
|
16963
17897
|
getFallbackModels() {
|
|
16964
17898
|
return [
|
|
17899
|
+
{ id: "claude-sonnet-4-6", name: "Claude 4.6 Sonnet" },
|
|
16965
17900
|
{ id: "claude-sonnet-4-5-20250929", name: "Claude 4.5 Sonnet" },
|
|
16966
17901
|
{ id: "claude-3-5-haiku-20241022", name: "Claude 3.5 Haiku" },
|
|
16967
17902
|
{ id: "gpt-4o", name: "GPT-4o" },
|
|
@@ -17863,6 +18798,7 @@ var MODEL_ALIASES = {
|
|
|
17863
18798
|
"claude-haiku": "claude-3-5-haiku-20241022",
|
|
17864
18799
|
// Version-specific Claude aliases
|
|
17865
18800
|
"claude-4.6-opus": "claude-opus-4-6",
|
|
18801
|
+
"claude-4.6-sonnet": "claude-sonnet-4-6",
|
|
17866
18802
|
"claude-4.5-opus": "claude-opus-4-5-20251101",
|
|
17867
18803
|
"claude-4.5-sonnet": "claude-sonnet-4-5-20250929",
|
|
17868
18804
|
"claude-4.5-haiku": "claude-haiku-4-5-20251001",
|
|
@@ -18624,8 +19560,8 @@ function createBackgroundAgentTools(manager) {
|
|
|
18624
19560
|
case "queued":
|
|
18625
19561
|
return `Agent "${job.agentName}" is queued (waiting for a concurrency slot). Task: ${job.task}`;
|
|
18626
19562
|
case "running": {
|
|
18627
|
-
const
|
|
18628
|
-
return `Agent "${job.agentName}" is still running (${
|
|
19563
|
+
const elapsed2 = Math.round((Date.now() - job.startTime) / 1e3);
|
|
19564
|
+
return `Agent "${job.agentName}" is still running (${elapsed2}s elapsed). Task: ${job.task}`;
|
|
18629
19565
|
}
|
|
18630
19566
|
case "completed": {
|
|
18631
19567
|
const result = manager.getResult(job_id);
|
|
@@ -18657,7 +19593,7 @@ function createBackgroundAgentTools(manager) {
|
|
|
18657
19593
|
const jobs = manager.listJobs();
|
|
18658
19594
|
if (jobs.length === 0) return "No background agents.";
|
|
18659
19595
|
return jobs.map((job) => {
|
|
18660
|
-
const
|
|
19596
|
+
const elapsed2 = Math.round(((job.endTime || Date.now()) - job.startTime) / 1e3);
|
|
18661
19597
|
const statusIcons = {
|
|
18662
19598
|
queued: "\u{1F550}",
|
|
18663
19599
|
running: "\u23F3",
|
|
@@ -18666,7 +19602,7 @@ function createBackgroundAgentTools(manager) {
|
|
|
18666
19602
|
cancelled: "\u{1F6AB}"
|
|
18667
19603
|
};
|
|
18668
19604
|
const statusIcon = statusIcons[job.status] || "\u2753";
|
|
18669
|
-
return `${statusIcon} [${job.id}] ${job.agentName} (${job.status}, ${
|
|
19605
|
+
return `${statusIcon} [${job.id}] ${job.agentName} (${job.status}, ${elapsed2}s) - ${job.task.slice(0, 80)}`;
|
|
18670
19606
|
}).join("\n");
|
|
18671
19607
|
},
|
|
18672
19608
|
toolSchema: {
|