@bike4mind/cli 0.2.29 → 0.2.30-feat-quantum-optimize-architecture.19202
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-4SBIE5OK.js → artifactExtractor-32UT6LCJ.js} +1 -1
- package/dist/{chunk-TNFZP7FG.js → chunk-DUEP3HCS.js} +703 -3
- package/dist/{chunk-22VR7SKO.js → chunk-KKZY4BRH.js} +2 -2
- package/dist/{chunk-5J4RL57F.js → chunk-TSB6M7IB.js} +11 -3
- package/dist/{chunk-YQWFK5O2.js → chunk-VRGHGJAL.js} +2 -2
- package/dist/{chunk-UYN4HMRF.js → chunk-Z3I7SVZ6.js} +2 -2
- package/dist/{create-DCHG36CP.js → create-GWZUB27T.js} +3 -3
- package/dist/index.js +1380 -140
- package/dist/{llmMarkdownGenerator-6MQKVOWW.js → llmMarkdownGenerator-B23C23LK.js} +1 -1
- package/dist/{markdownGenerator-4GDO3PTY.js → markdownGenerator-XAWABETH.js} +1 -1
- package/dist/{mementoService-WDQFLLRV.js → mementoService-3VASE5H2.js} +3 -3
- package/dist/{src-ZAT7QMNA.js → src-BFBWKNAI.js} +15 -1
- package/dist/{src-DVEE3PS5.js → src-MCOAMTTD.js} +2 -2
- package/dist/{subtractCredits-LE54FRKC.js → subtractCredits-RBXIX27T.js} +3 -3
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
getEffectiveApiKey,
|
|
6
6
|
getOpenWeatherKey,
|
|
7
7
|
getSerperKey
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-KKZY4BRH.js";
|
|
9
9
|
import "./chunk-RUI6HNLO.js";
|
|
10
10
|
import {
|
|
11
11
|
ConfigStore,
|
|
@@ -15,8 +15,8 @@ import {
|
|
|
15
15
|
selectActiveBackgroundAgents,
|
|
16
16
|
useCliStore
|
|
17
17
|
} from "./chunk-TVW4ZESU.js";
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-Z3I7SVZ6.js";
|
|
19
|
+
import "./chunk-VRGHGJAL.js";
|
|
20
20
|
import {
|
|
21
21
|
BFLImageService,
|
|
22
22
|
BaseStorage,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
OpenAIBackend,
|
|
29
29
|
OpenAIImageService,
|
|
30
30
|
XAIImageService
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-TSB6M7IB.js";
|
|
32
32
|
import {
|
|
33
33
|
AiEvents,
|
|
34
34
|
ApiKeyEvents,
|
|
@@ -83,8 +83,10 @@ import {
|
|
|
83
83
|
VideoModels,
|
|
84
84
|
XAI_IMAGE_MODELS,
|
|
85
85
|
b4mLLMTools,
|
|
86
|
-
getMcpProviderMetadata
|
|
87
|
-
|
|
86
|
+
getMcpProviderMetadata,
|
|
87
|
+
getViewById,
|
|
88
|
+
resolveNavigationIntents
|
|
89
|
+
} from "./chunk-DUEP3HCS.js";
|
|
88
90
|
import {
|
|
89
91
|
Logger
|
|
90
92
|
} from "./chunk-OCYRD7D6.js";
|
|
@@ -3964,6 +3966,7 @@ var updateUserSchema = z7.object({
|
|
|
3964
3966
|
preferredLanguage: z7.string().nullable().optional(),
|
|
3965
3967
|
preferredContact: z7.string().nullable().optional(),
|
|
3966
3968
|
preferredVoice: z7.string().nullable().optional(),
|
|
3969
|
+
preferredReasoningEffort: z7.enum(["auto", "none", "minimal", "low", "medium", "high", "xhigh"]).nullable().optional(),
|
|
3967
3970
|
tshirtSize: z7.string().nullable().optional(),
|
|
3968
3971
|
geoLocation: z7.string().nullable().optional(),
|
|
3969
3972
|
lastNotebookId: z7.string().nullable().optional(),
|
|
@@ -9000,8 +9003,8 @@ var getHeliocentricCoords = (planet, T) => {
|
|
|
9000
9003
|
const sinNode = Math.sin(longNode);
|
|
9001
9004
|
const x = r * (cosNode * cosOmega - sinNode * sinOmega * cosI);
|
|
9002
9005
|
const y = r * (sinNode * cosOmega + cosNode * sinOmega * cosI);
|
|
9003
|
-
const
|
|
9004
|
-
return { x, y, z:
|
|
9006
|
+
const z148 = r * sinOmega * sinI;
|
|
9007
|
+
return { x, y, z: z148, r };
|
|
9005
9008
|
};
|
|
9006
9009
|
var getGeocentricEcliptic = (planet, earth) => {
|
|
9007
9010
|
const dx = planet.x - earth.x;
|
|
@@ -9885,13 +9888,13 @@ function formatSearchResults(files) {
|
|
|
9885
9888
|
const notes = file.notes ? `
|
|
9886
9889
|
Notes: ${file.notes}` : "";
|
|
9887
9890
|
const fileType = file.type || "FILE";
|
|
9888
|
-
return `${index + 1}. **${file.fileName}**
|
|
9891
|
+
return `${index + 1}. **${file.fileName}** (ID: ${file.id})
|
|
9889
9892
|
Type: ${fileType} | MIME: ${file.mimeType}
|
|
9890
9893
|
Tags: ${tags}${notes}`;
|
|
9891
9894
|
});
|
|
9892
9895
|
return `Found ${files.length} document(s) in your knowledge base:
|
|
9893
9896
|
|
|
9894
|
-
` + formattedFiles.join("\n\n") + "\n\n*
|
|
9897
|
+
` + formattedFiles.join("\n\n") + "\n\n*Use retrieve_knowledge_content with a file ID or tags to read the actual document content.*";
|
|
9895
9898
|
}
|
|
9896
9899
|
var knowledgeBaseSearchTool = {
|
|
9897
9900
|
name: "search_knowledge_base",
|
|
@@ -9918,6 +9921,8 @@ var knowledgeBaseSearchTool = {
|
|
|
9918
9921
|
by: "fileName",
|
|
9919
9922
|
direction: "asc"
|
|
9920
9923
|
}, {
|
|
9924
|
+
textSearch: true,
|
|
9925
|
+
// Search across fileName + tags + notes for better recall
|
|
9921
9926
|
includeShared: true,
|
|
9922
9927
|
// Include owned + explicitly shared + org-shared files
|
|
9923
9928
|
userGroups: context.user.groups || []
|
|
@@ -9932,18 +9937,18 @@ var knowledgeBaseSearchTool = {
|
|
|
9932
9937
|
},
|
|
9933
9938
|
toolSchema: {
|
|
9934
9939
|
name: "search_knowledge_base",
|
|
9935
|
-
description: "Search the user's uploaded knowledge base (fab files). Returns relevant documents from the user's own files, organization-shared files, and files explicitly shared with them. Use this tool when the user asks about their own documents, uploaded files, or organization knowledge.",
|
|
9940
|
+
description: "Search the user's uploaded knowledge base (fab files). Searches across file names, tags, and notes for broad recall. Returns relevant documents from the user's own files, organization-shared files, and files explicitly shared with them. Use this tool when the user asks about their own documents, uploaded files, or organization knowledge.",
|
|
9936
9941
|
parameters: {
|
|
9937
9942
|
type: "object",
|
|
9938
9943
|
properties: {
|
|
9939
9944
|
query: {
|
|
9940
9945
|
type: "string",
|
|
9941
|
-
description: "The search query to find relevant documents
|
|
9946
|
+
description: "The search query to find relevant documents. Matches against file names, tags, and notes."
|
|
9942
9947
|
},
|
|
9943
9948
|
tags: {
|
|
9944
9949
|
type: "array",
|
|
9945
9950
|
items: { type: "string" },
|
|
9946
|
-
description:
|
|
9951
|
+
description: 'Optional: filter results by tag names. Supports partial matching. For optimization docs, use tags like "opti:family:scheduling", "opti:QUBO", "opti:solver:highs", etc. Any matching tag qualifies the file.'
|
|
9947
9952
|
},
|
|
9948
9953
|
file_type: {
|
|
9949
9954
|
type: "string",
|
|
@@ -9963,6 +9968,1235 @@ var knowledgeBaseSearchTool = {
|
|
|
9963
9968
|
})
|
|
9964
9969
|
};
|
|
9965
9970
|
|
|
9971
|
+
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/knowledgeBaseRetrieve/index.js
|
|
9972
|
+
var DEFAULT_MAX_CHARS = 8e3;
|
|
9973
|
+
var ABSOLUTE_MAX_CHARS = 16e3;
|
|
9974
|
+
var knowledgeBaseRetrieveTool = {
|
|
9975
|
+
name: "retrieve_knowledge_content",
|
|
9976
|
+
implementation: (context) => ({
|
|
9977
|
+
toolFn: async (value) => {
|
|
9978
|
+
const params = value;
|
|
9979
|
+
const { file_id, tags, query, max_chars } = params;
|
|
9980
|
+
const charBudget = Math.min(max_chars ?? DEFAULT_MAX_CHARS, ABSOLUTE_MAX_CHARS);
|
|
9981
|
+
context.logger.log("\u{1F4D6} Knowledge Retrieve: params", { file_id, tags, query, max_chars: charBudget });
|
|
9982
|
+
if (!file_id && !tags?.length && !query) {
|
|
9983
|
+
return "Error: You must provide at least one of file_id, tags, or query.";
|
|
9984
|
+
}
|
|
9985
|
+
if (!context.db.fabfiles) {
|
|
9986
|
+
context.logger.error("\u274C Knowledge Retrieve: fabfiles repository not available");
|
|
9987
|
+
return "Knowledge base retrieval is not available at this time.";
|
|
9988
|
+
}
|
|
9989
|
+
if (!context.db.fabfilechunks) {
|
|
9990
|
+
context.logger.error("\u274C Knowledge Retrieve: fabfilechunks repository not available");
|
|
9991
|
+
return "Knowledge base retrieval is not available at this time (chunk reader unavailable).";
|
|
9992
|
+
}
|
|
9993
|
+
try {
|
|
9994
|
+
let files = [];
|
|
9995
|
+
if (file_id) {
|
|
9996
|
+
const file = await context.db.fabfiles.findByIdAndUserId(file_id, context.userId);
|
|
9997
|
+
if (file) {
|
|
9998
|
+
files = [file];
|
|
9999
|
+
} else {
|
|
10000
|
+
const searchResults = await context.db.fabfiles.search(context.userId, file_id, { tags: [], shared: false }, { page: 1, limit: 1 }, { by: "fileName", direction: "asc" }, { textSearch: true, includeShared: true, userGroups: context.user.groups || [] });
|
|
10001
|
+
files = searchResults.data;
|
|
10002
|
+
}
|
|
10003
|
+
if (files.length === 0) {
|
|
10004
|
+
return `No document found with ID "${file_id}". The file may not exist or you may not have access to it. Try using search_knowledge_base to find the correct file ID.`;
|
|
10005
|
+
}
|
|
10006
|
+
}
|
|
10007
|
+
if (files.length === 0 && (tags?.length || query)) {
|
|
10008
|
+
const searchResults = await context.db.fabfiles.search(context.userId, query || "", { tags: tags || [], shared: false }, { page: 1, limit: 5 }, { by: "fileName", direction: "asc" }, { textSearch: true, includeShared: true, userGroups: context.user.groups || [] });
|
|
10009
|
+
files = searchResults.data;
|
|
10010
|
+
if (files.length === 0) {
|
|
10011
|
+
const searchDesc = [
|
|
10012
|
+
query && `query "${query}"`,
|
|
10013
|
+
tags?.length && `tags [${tags.join(", ")}]`
|
|
10014
|
+
].filter(Boolean).join(" and ");
|
|
10015
|
+
return `No documents found matching ${searchDesc}. Try broadening your search with search_knowledge_base.`;
|
|
10016
|
+
}
|
|
10017
|
+
}
|
|
10018
|
+
let totalCharsUsed = 0;
|
|
10019
|
+
const sections = [];
|
|
10020
|
+
let filesRetrieved = 0;
|
|
10021
|
+
for (const file of files) {
|
|
10022
|
+
if (totalCharsUsed >= charBudget)
|
|
10023
|
+
break;
|
|
10024
|
+
const chunks = await context.db.fabfilechunks.findByFabFileId(file.id);
|
|
10025
|
+
if (chunks.length === 0) {
|
|
10026
|
+
context.logger.log(`\u{1F4D6} Knowledge Retrieve: No chunks for file ${file.fileName} (${file.id})`);
|
|
10027
|
+
continue;
|
|
10028
|
+
}
|
|
10029
|
+
const fullText = chunks.map((c) => c.text).join("\n");
|
|
10030
|
+
const remainingBudget = charBudget - totalCharsUsed;
|
|
10031
|
+
const truncated = fullText.length > remainingBudget;
|
|
10032
|
+
const content = truncated ? fullText.slice(0, remainingBudget) : fullText;
|
|
10033
|
+
const fileTags = file.tags?.map((t) => t.name).join(", ") || "none";
|
|
10034
|
+
const charLabel = truncated ? `${content.length} (truncated from ${fullText.length})` : `${content.length}`;
|
|
10035
|
+
sections.push(`### ${file.fileName} (ID: ${file.id})
|
|
10036
|
+
Tags: ${fileTags}
|
|
10037
|
+
Chunks: ${chunks.length} | Characters: ${charLabel}
|
|
10038
|
+
---
|
|
10039
|
+
` + content);
|
|
10040
|
+
totalCharsUsed += content.length;
|
|
10041
|
+
filesRetrieved++;
|
|
10042
|
+
}
|
|
10043
|
+
if (filesRetrieved === 0) {
|
|
10044
|
+
return "Found matching documents but they have no indexed content. The files may not have been processed yet.";
|
|
10045
|
+
}
|
|
10046
|
+
const header = `Retrieved content from ${filesRetrieved} of ${files.length} document(s):
|
|
10047
|
+
`;
|
|
10048
|
+
return header + "\n" + sections.join("\n\n---\n\n");
|
|
10049
|
+
} catch (error) {
|
|
10050
|
+
context.logger.error("\u274C Knowledge Retrieve: Error during retrieval:", error);
|
|
10051
|
+
return "An error occurred while retrieving document content. Please try again.";
|
|
10052
|
+
}
|
|
10053
|
+
},
|
|
10054
|
+
toolSchema: {
|
|
10055
|
+
name: "retrieve_knowledge_content",
|
|
10056
|
+
description: "Read the actual text content of knowledge base documents. Use this after search_knowledge_base to read documents by file ID, or provide tags/query to find and read documents in one step. Returns the full text content (up to the character budget) for grounding your responses in the user's curated knowledge.",
|
|
10057
|
+
parameters: {
|
|
10058
|
+
type: "object",
|
|
10059
|
+
properties: {
|
|
10060
|
+
file_id: {
|
|
10061
|
+
type: "string",
|
|
10062
|
+
description: "The file ID to retrieve (from search_knowledge_base results). Most efficient for single-document retrieval."
|
|
10063
|
+
},
|
|
10064
|
+
tags: {
|
|
10065
|
+
type: "array",
|
|
10066
|
+
items: { type: "string" },
|
|
10067
|
+
description: 'Filter documents by tags. For optimization docs, use tags like "opti:family:scheduling", "opti:solver:highs", etc.'
|
|
10068
|
+
},
|
|
10069
|
+
query: {
|
|
10070
|
+
type: "string",
|
|
10071
|
+
description: "Search query to find documents. Can be combined with tags for more targeted retrieval."
|
|
10072
|
+
},
|
|
10073
|
+
max_chars: {
|
|
10074
|
+
type: "number",
|
|
10075
|
+
description: "Maximum characters of content to return (default: 8000, max: 16000). Lower values for quick lookups, higher for detailed reading.",
|
|
10076
|
+
minimum: 500,
|
|
10077
|
+
maximum: 16e3
|
|
10078
|
+
}
|
|
10079
|
+
}
|
|
10080
|
+
}
|
|
10081
|
+
}
|
|
10082
|
+
})
|
|
10083
|
+
};
|
|
10084
|
+
|
|
10085
|
+
// ../../b4m-core/packages/quantum/dist/src/types.js
|
|
10086
|
+
import { z as z139 } from "zod";
|
|
10087
|
+
var OperationSchema = z139.object({
|
|
10088
|
+
jobId: z139.number(),
|
|
10089
|
+
machineId: z139.number(),
|
|
10090
|
+
duration: z139.number().positive()
|
|
10091
|
+
});
|
|
10092
|
+
var JobSchema = z139.object({
|
|
10093
|
+
id: z139.number(),
|
|
10094
|
+
name: z139.string(),
|
|
10095
|
+
operations: z139.array(OperationSchema)
|
|
10096
|
+
});
|
|
10097
|
+
var MachineSchema = z139.object({
|
|
10098
|
+
id: z139.number(),
|
|
10099
|
+
name: z139.string()
|
|
10100
|
+
});
|
|
10101
|
+
var SchedulingProblemSchema = z139.object({
|
|
10102
|
+
name: z139.string(),
|
|
10103
|
+
description: z139.string().optional(),
|
|
10104
|
+
jobs: z139.array(JobSchema),
|
|
10105
|
+
machines: z139.array(MachineSchema)
|
|
10106
|
+
});
|
|
10107
|
+
var SolverIdSchema = z139.enum([
|
|
10108
|
+
"greedy",
|
|
10109
|
+
"naive",
|
|
10110
|
+
"random-restart",
|
|
10111
|
+
"simulated-annealing",
|
|
10112
|
+
"simulated-annealing-medium",
|
|
10113
|
+
"simulated-annealing-large",
|
|
10114
|
+
"tabu",
|
|
10115
|
+
"genetic-algorithm",
|
|
10116
|
+
"ant-colony",
|
|
10117
|
+
"highs"
|
|
10118
|
+
]);
|
|
10119
|
+
|
|
10120
|
+
// ../../b4m-core/packages/quantum/dist/src/solvers/greedy-solver.js
|
|
10121
|
+
var greedySolver = {
|
|
10122
|
+
id: "greedy",
|
|
10123
|
+
name: "Greedy (Earliest Start)",
|
|
10124
|
+
description: "Schedules each operation at the earliest available time on its machine, respecting job ordering.",
|
|
10125
|
+
async solve(problem, options) {
|
|
10126
|
+
const startTime = performance.now();
|
|
10127
|
+
const machineAvailableAt = /* @__PURE__ */ new Map();
|
|
10128
|
+
for (const machine of problem.machines) {
|
|
10129
|
+
machineAvailableAt.set(machine.id, 0);
|
|
10130
|
+
}
|
|
10131
|
+
const jobCompletedAt = /* @__PURE__ */ new Map();
|
|
10132
|
+
for (const job of problem.jobs) {
|
|
10133
|
+
jobCompletedAt.set(job.id, 0);
|
|
10134
|
+
}
|
|
10135
|
+
const schedule = [];
|
|
10136
|
+
const totalOps = problem.jobs.reduce((sum2, job) => sum2 + job.operations.length, 0);
|
|
10137
|
+
let opsScheduled = 0;
|
|
10138
|
+
for (const job of problem.jobs) {
|
|
10139
|
+
for (let opIndex = 0; opIndex < job.operations.length; opIndex++) {
|
|
10140
|
+
const op = job.operations[opIndex];
|
|
10141
|
+
const machineReady = machineAvailableAt.get(op.machineId) ?? 0;
|
|
10142
|
+
const jobReady = jobCompletedAt.get(job.id) ?? 0;
|
|
10143
|
+
const opStart = Math.max(machineReady, jobReady);
|
|
10144
|
+
const opEnd = opStart + op.duration;
|
|
10145
|
+
schedule.push({
|
|
10146
|
+
jobId: job.id,
|
|
10147
|
+
machineId: op.machineId,
|
|
10148
|
+
operationIndex: opIndex,
|
|
10149
|
+
startTime: opStart,
|
|
10150
|
+
endTime: opEnd
|
|
10151
|
+
});
|
|
10152
|
+
machineAvailableAt.set(op.machineId, opEnd);
|
|
10153
|
+
jobCompletedAt.set(job.id, opEnd);
|
|
10154
|
+
opsScheduled++;
|
|
10155
|
+
if (options?.onProgress) {
|
|
10156
|
+
options.onProgress({
|
|
10157
|
+
solverId: "greedy",
|
|
10158
|
+
percentage: Math.round(opsScheduled / totalOps * 100),
|
|
10159
|
+
bestMakespan: opEnd,
|
|
10160
|
+
currentIteration: opsScheduled,
|
|
10161
|
+
totalIterations: totalOps
|
|
10162
|
+
});
|
|
10163
|
+
}
|
|
10164
|
+
}
|
|
10165
|
+
}
|
|
10166
|
+
const makespan = Math.max(...schedule.map((op) => op.endTime));
|
|
10167
|
+
const elapsedMs = performance.now() - startTime;
|
|
10168
|
+
return {
|
|
10169
|
+
solverId: "greedy",
|
|
10170
|
+
solverName: "Greedy (Earliest Start)",
|
|
10171
|
+
makespan,
|
|
10172
|
+
schedule,
|
|
10173
|
+
elapsedMs,
|
|
10174
|
+
iterations: totalOps
|
|
10175
|
+
};
|
|
10176
|
+
}
|
|
10177
|
+
};
|
|
10178
|
+
|
|
10179
|
+
// ../../b4m-core/packages/quantum/dist/src/solvers/schedule-utils.js
|
|
10180
|
+
function buildOperationList(problem) {
|
|
10181
|
+
const ops = [];
|
|
10182
|
+
for (const job of problem.jobs) {
|
|
10183
|
+
for (let i = 0; i < job.operations.length; i++) {
|
|
10184
|
+
ops.push({ jobId: job.id, opIndex: i });
|
|
10185
|
+
}
|
|
10186
|
+
}
|
|
10187
|
+
return ops;
|
|
10188
|
+
}
|
|
10189
|
+
function decodePermutation(permutation, problem) {
|
|
10190
|
+
const schedule = [];
|
|
10191
|
+
const machineAvailableAt = /* @__PURE__ */ new Map();
|
|
10192
|
+
const jobCompletedAt = /* @__PURE__ */ new Map();
|
|
10193
|
+
const jobNextOp = /* @__PURE__ */ new Map();
|
|
10194
|
+
for (const machine of problem.machines) {
|
|
10195
|
+
machineAvailableAt.set(machine.id, 0);
|
|
10196
|
+
}
|
|
10197
|
+
for (const job of problem.jobs) {
|
|
10198
|
+
jobCompletedAt.set(job.id, 0);
|
|
10199
|
+
jobNextOp.set(job.id, 0);
|
|
10200
|
+
}
|
|
10201
|
+
const remaining = [...permutation];
|
|
10202
|
+
const maxPasses = remaining.length * remaining.length;
|
|
10203
|
+
let passes = 0;
|
|
10204
|
+
while (remaining.length > 0 && passes < maxPasses) {
|
|
10205
|
+
let scheduled = false;
|
|
10206
|
+
for (let i = 0; i < remaining.length; i++) {
|
|
10207
|
+
const ref = remaining[i];
|
|
10208
|
+
const nextOp = jobNextOp.get(ref.jobId) ?? 0;
|
|
10209
|
+
if (ref.opIndex !== nextOp)
|
|
10210
|
+
continue;
|
|
10211
|
+
const job = problem.jobs.find((j) => j.id === ref.jobId);
|
|
10212
|
+
const op = job.operations[ref.opIndex];
|
|
10213
|
+
const machineReady = machineAvailableAt.get(op.machineId) ?? 0;
|
|
10214
|
+
const jobReady = jobCompletedAt.get(ref.jobId) ?? 0;
|
|
10215
|
+
const start = Math.max(machineReady, jobReady);
|
|
10216
|
+
const end = start + op.duration;
|
|
10217
|
+
schedule.push({
|
|
10218
|
+
jobId: ref.jobId,
|
|
10219
|
+
machineId: op.machineId,
|
|
10220
|
+
operationIndex: ref.opIndex,
|
|
10221
|
+
startTime: start,
|
|
10222
|
+
endTime: end
|
|
10223
|
+
});
|
|
10224
|
+
machineAvailableAt.set(op.machineId, end);
|
|
10225
|
+
jobCompletedAt.set(ref.jobId, end);
|
|
10226
|
+
jobNextOp.set(ref.jobId, nextOp + 1);
|
|
10227
|
+
remaining.splice(i, 1);
|
|
10228
|
+
scheduled = true;
|
|
10229
|
+
break;
|
|
10230
|
+
}
|
|
10231
|
+
if (!scheduled) {
|
|
10232
|
+
remaining.push(remaining.shift());
|
|
10233
|
+
}
|
|
10234
|
+
passes++;
|
|
10235
|
+
}
|
|
10236
|
+
return schedule;
|
|
10237
|
+
}
|
|
10238
|
+
function computeMakespan(schedule) {
|
|
10239
|
+
if (schedule.length === 0)
|
|
10240
|
+
return 0;
|
|
10241
|
+
return Math.max(...schedule.map((op) => op.endTime));
|
|
10242
|
+
}
|
|
10243
|
+
function randomPermutation(problem, rng = Math.random) {
|
|
10244
|
+
const ops = buildOperationList(problem);
|
|
10245
|
+
for (let i = ops.length - 1; i > 0; i--) {
|
|
10246
|
+
const j = Math.floor(rng() * (i + 1));
|
|
10247
|
+
[ops[i], ops[j]] = [ops[j], ops[i]];
|
|
10248
|
+
}
|
|
10249
|
+
return ops;
|
|
10250
|
+
}
|
|
10251
|
+
function swapNeighbor(perm, rng = Math.random) {
|
|
10252
|
+
const newPerm = [...perm];
|
|
10253
|
+
const i = Math.floor(rng() * newPerm.length);
|
|
10254
|
+
let j = Math.floor(rng() * (newPerm.length - 1));
|
|
10255
|
+
if (j >= i)
|
|
10256
|
+
j++;
|
|
10257
|
+
[newPerm[i], newPerm[j]] = [newPerm[j], newPerm[i]];
|
|
10258
|
+
return newPerm;
|
|
10259
|
+
}
|
|
10260
|
+
function createRng(seed) {
|
|
10261
|
+
let s = seed | 0;
|
|
10262
|
+
return () => {
|
|
10263
|
+
s = s + 1831565813 | 0;
|
|
10264
|
+
let t = Math.imul(s ^ s >>> 15, 1 | s);
|
|
10265
|
+
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|
10266
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
10267
|
+
};
|
|
10268
|
+
}
|
|
10269
|
+
|
|
10270
|
+
// ../../b4m-core/packages/quantum/dist/src/solvers/naive-solver.js
|
|
10271
|
+
var MAX_PERMUTATIONS = 40320;
|
|
10272
|
+
function* permutations(arr) {
|
|
10273
|
+
if (arr.length <= 1) {
|
|
10274
|
+
yield [...arr];
|
|
10275
|
+
return;
|
|
10276
|
+
}
|
|
10277
|
+
for (let i = 0; i < arr.length; i++) {
|
|
10278
|
+
const rest = [...arr.slice(0, i), ...arr.slice(i + 1)];
|
|
10279
|
+
for (const perm of permutations(rest)) {
|
|
10280
|
+
yield [arr[i], ...perm];
|
|
10281
|
+
}
|
|
10282
|
+
}
|
|
10283
|
+
}
|
|
10284
|
+
var naiveSolver = {
|
|
10285
|
+
id: "naive",
|
|
10286
|
+
name: "Naive (Brute Force)",
|
|
10287
|
+
description: "Evaluates all permutations to find the optimal schedule. Only feasible for small problems.",
|
|
10288
|
+
async solve(problem, options) {
|
|
10289
|
+
const startTime = performance.now();
|
|
10290
|
+
const ops = buildOperationList(problem);
|
|
10291
|
+
const totalPerms = factorial(ops.length);
|
|
10292
|
+
const cappedTotal = Math.min(totalPerms, MAX_PERMUTATIONS);
|
|
10293
|
+
let bestMakespan = Infinity;
|
|
10294
|
+
let bestSchedule = decodePermutation(ops, problem);
|
|
10295
|
+
let count = 0;
|
|
10296
|
+
for (const perm of permutations(ops)) {
|
|
10297
|
+
if (count >= MAX_PERMUTATIONS)
|
|
10298
|
+
break;
|
|
10299
|
+
const schedule = decodePermutation(perm, problem);
|
|
10300
|
+
const makespan = computeMakespan(schedule);
|
|
10301
|
+
if (makespan < bestMakespan) {
|
|
10302
|
+
bestMakespan = makespan;
|
|
10303
|
+
bestSchedule = schedule;
|
|
10304
|
+
}
|
|
10305
|
+
count++;
|
|
10306
|
+
if (options?.onProgress && count % 100 === 0) {
|
|
10307
|
+
options.onProgress({
|
|
10308
|
+
solverId: "naive",
|
|
10309
|
+
percentage: Math.min(99, Math.round(count / cappedTotal * 100)),
|
|
10310
|
+
bestMakespan,
|
|
10311
|
+
currentIteration: count,
|
|
10312
|
+
totalIterations: cappedTotal
|
|
10313
|
+
});
|
|
10314
|
+
}
|
|
10315
|
+
}
|
|
10316
|
+
options?.onProgress?.({
|
|
10317
|
+
solverId: "naive",
|
|
10318
|
+
percentage: 100,
|
|
10319
|
+
bestMakespan,
|
|
10320
|
+
currentIteration: count,
|
|
10321
|
+
totalIterations: cappedTotal
|
|
10322
|
+
});
|
|
10323
|
+
return {
|
|
10324
|
+
solverId: "naive",
|
|
10325
|
+
solverName: "Naive (Brute Force)",
|
|
10326
|
+
makespan: bestMakespan,
|
|
10327
|
+
schedule: bestSchedule,
|
|
10328
|
+
elapsedMs: performance.now() - startTime,
|
|
10329
|
+
iterations: count
|
|
10330
|
+
};
|
|
10331
|
+
}
|
|
10332
|
+
};
|
|
10333
|
+
function factorial(n) {
|
|
10334
|
+
if (n <= 1)
|
|
10335
|
+
return 1;
|
|
10336
|
+
let result = 1;
|
|
10337
|
+
for (let i = 2; i <= n; i++)
|
|
10338
|
+
result *= i;
|
|
10339
|
+
return result;
|
|
10340
|
+
}
|
|
10341
|
+
|
|
10342
|
+
// ../../b4m-core/packages/quantum/dist/src/solvers/random-restart-solver.js
|
|
10343
|
+
var RESTARTS = 50;
|
|
10344
|
+
var HILL_CLIMB_ITERATIONS = 500;
|
|
10345
|
+
var randomRestartSolver = {
|
|
10346
|
+
id: "random-restart",
|
|
10347
|
+
name: "Random Restart Hill Climbing",
|
|
10348
|
+
description: "Multiple random starts with local search improvement via operation swaps.",
|
|
10349
|
+
async solve(problem, options) {
|
|
10350
|
+
const startTime = performance.now();
|
|
10351
|
+
const timeoutMs = options?.timeoutMs ?? 1e4;
|
|
10352
|
+
const rng = createRng(42);
|
|
10353
|
+
let globalBestMakespan = Infinity;
|
|
10354
|
+
let globalBestSchedule = decodePermutation(randomPermutation(problem, rng), problem);
|
|
10355
|
+
let totalIterations = 0;
|
|
10356
|
+
for (let restart = 0; restart < RESTARTS; restart++) {
|
|
10357
|
+
if (performance.now() - startTime > timeoutMs)
|
|
10358
|
+
break;
|
|
10359
|
+
let currentPerm = randomPermutation(problem, rng);
|
|
10360
|
+
let currentSchedule = decodePermutation(currentPerm, problem);
|
|
10361
|
+
let currentMakespan = computeMakespan(currentSchedule);
|
|
10362
|
+
for (let i = 0; i < HILL_CLIMB_ITERATIONS; i++) {
|
|
10363
|
+
if (performance.now() - startTime > timeoutMs)
|
|
10364
|
+
break;
|
|
10365
|
+
const neighborPerm = swapNeighbor(currentPerm, rng);
|
|
10366
|
+
const neighborSchedule = decodePermutation(neighborPerm, problem);
|
|
10367
|
+
const neighborMakespan = computeMakespan(neighborSchedule);
|
|
10368
|
+
if (neighborMakespan < currentMakespan) {
|
|
10369
|
+
currentPerm = neighborPerm;
|
|
10370
|
+
currentSchedule = neighborSchedule;
|
|
10371
|
+
currentMakespan = neighborMakespan;
|
|
10372
|
+
}
|
|
10373
|
+
totalIterations++;
|
|
10374
|
+
}
|
|
10375
|
+
if (currentMakespan < globalBestMakespan) {
|
|
10376
|
+
globalBestMakespan = currentMakespan;
|
|
10377
|
+
globalBestSchedule = currentSchedule;
|
|
10378
|
+
}
|
|
10379
|
+
options?.onProgress?.({
|
|
10380
|
+
solverId: "random-restart",
|
|
10381
|
+
percentage: Math.round((restart + 1) / RESTARTS * 100),
|
|
10382
|
+
bestMakespan: globalBestMakespan,
|
|
10383
|
+
currentIteration: restart + 1,
|
|
10384
|
+
totalIterations: RESTARTS
|
|
10385
|
+
});
|
|
10386
|
+
}
|
|
10387
|
+
return {
|
|
10388
|
+
solverId: "random-restart",
|
|
10389
|
+
solverName: "Random Restart Hill Climbing",
|
|
10390
|
+
makespan: globalBestMakespan,
|
|
10391
|
+
schedule: globalBestSchedule,
|
|
10392
|
+
elapsedMs: performance.now() - startTime,
|
|
10393
|
+
iterations: totalIterations
|
|
10394
|
+
};
|
|
10395
|
+
}
|
|
10396
|
+
};
|
|
10397
|
+
|
|
10398
|
+
// ../../b4m-core/packages/quantum/dist/src/solvers/simulated-annealing-solver.js
|
|
10399
|
+
var SA_CONFIGS = [
|
|
10400
|
+
{
|
|
10401
|
+
id: "simulated-annealing",
|
|
10402
|
+
name: "Simulated Annealing (S)",
|
|
10403
|
+
description: "Fast simulated annealing with 5,000 iterations. Good for quick estimates.",
|
|
10404
|
+
initialTemp: 100,
|
|
10405
|
+
coolingRate: 0.995,
|
|
10406
|
+
iterations: 5e3
|
|
10407
|
+
},
|
|
10408
|
+
{
|
|
10409
|
+
id: "simulated-annealing-medium",
|
|
10410
|
+
name: "Simulated Annealing (M)",
|
|
10411
|
+
description: "Medium simulated annealing with 25,000 iterations. Balanced speed/quality.",
|
|
10412
|
+
initialTemp: 200,
|
|
10413
|
+
coolingRate: 0.9985,
|
|
10414
|
+
iterations: 25e3
|
|
10415
|
+
},
|
|
10416
|
+
{
|
|
10417
|
+
id: "simulated-annealing-large",
|
|
10418
|
+
name: "Simulated Annealing (L)",
|
|
10419
|
+
description: "Long simulated annealing with 100,000 iterations. Best solution quality.",
|
|
10420
|
+
initialTemp: 500,
|
|
10421
|
+
coolingRate: 0.99995,
|
|
10422
|
+
iterations: 1e5
|
|
10423
|
+
}
|
|
10424
|
+
];
|
|
10425
|
+
function createSASolver(config) {
|
|
10426
|
+
return {
|
|
10427
|
+
id: config.id,
|
|
10428
|
+
name: config.name,
|
|
10429
|
+
description: config.description,
|
|
10430
|
+
async solve(problem, options) {
|
|
10431
|
+
const startTime = performance.now();
|
|
10432
|
+
const timeoutMs = options?.timeoutMs ?? 3e4;
|
|
10433
|
+
const rng = createRng(42);
|
|
10434
|
+
let currentPerm = randomPermutation(problem, rng);
|
|
10435
|
+
let currentSchedule = decodePermutation(currentPerm, problem);
|
|
10436
|
+
let currentMakespan = computeMakespan(currentSchedule);
|
|
10437
|
+
let bestPerm = currentPerm;
|
|
10438
|
+
let bestSchedule = currentSchedule;
|
|
10439
|
+
let bestMakespan = currentMakespan;
|
|
10440
|
+
let temperature = config.initialTemp;
|
|
10441
|
+
const progressInterval = Math.max(1, Math.floor(config.iterations / 100));
|
|
10442
|
+
for (let i = 0; i < config.iterations; i++) {
|
|
10443
|
+
if (performance.now() - startTime > timeoutMs)
|
|
10444
|
+
break;
|
|
10445
|
+
const neighborPerm = swapNeighbor(currentPerm, rng);
|
|
10446
|
+
const neighborSchedule = decodePermutation(neighborPerm, problem);
|
|
10447
|
+
const neighborMakespan = computeMakespan(neighborSchedule);
|
|
10448
|
+
const delta = neighborMakespan - currentMakespan;
|
|
10449
|
+
if (delta < 0 || rng() < Math.exp(-delta / temperature)) {
|
|
10450
|
+
currentPerm = neighborPerm;
|
|
10451
|
+
currentSchedule = neighborSchedule;
|
|
10452
|
+
currentMakespan = neighborMakespan;
|
|
10453
|
+
if (currentMakespan < bestMakespan) {
|
|
10454
|
+
bestPerm = currentPerm;
|
|
10455
|
+
bestSchedule = currentSchedule;
|
|
10456
|
+
bestMakespan = currentMakespan;
|
|
10457
|
+
}
|
|
10458
|
+
}
|
|
10459
|
+
temperature *= config.coolingRate;
|
|
10460
|
+
if (options?.onProgress && i % progressInterval === 0) {
|
|
10461
|
+
options.onProgress({
|
|
10462
|
+
solverId: config.id,
|
|
10463
|
+
percentage: Math.round(i / config.iterations * 100),
|
|
10464
|
+
bestMakespan,
|
|
10465
|
+
currentIteration: i,
|
|
10466
|
+
totalIterations: config.iterations
|
|
10467
|
+
});
|
|
10468
|
+
}
|
|
10469
|
+
}
|
|
10470
|
+
options?.onProgress?.({
|
|
10471
|
+
solverId: config.id,
|
|
10472
|
+
percentage: 100,
|
|
10473
|
+
bestMakespan,
|
|
10474
|
+
currentIteration: config.iterations,
|
|
10475
|
+
totalIterations: config.iterations
|
|
10476
|
+
});
|
|
10477
|
+
return {
|
|
10478
|
+
solverId: config.id,
|
|
10479
|
+
solverName: config.name,
|
|
10480
|
+
makespan: bestMakespan,
|
|
10481
|
+
schedule: bestSchedule,
|
|
10482
|
+
elapsedMs: performance.now() - startTime,
|
|
10483
|
+
iterations: config.iterations
|
|
10484
|
+
};
|
|
10485
|
+
}
|
|
10486
|
+
};
|
|
10487
|
+
}
|
|
10488
|
+
var simulatedAnnealingSolver = createSASolver(SA_CONFIGS[0]);
|
|
10489
|
+
var simulatedAnnealingMediumSolver = createSASolver(SA_CONFIGS[1]);
|
|
10490
|
+
var simulatedAnnealingLargeSolver = createSASolver(SA_CONFIGS[2]);
|
|
10491
|
+
|
|
10492
|
+
// ../../b4m-core/packages/quantum/dist/src/solvers/tabu-solver.js
|
|
10493
|
+
var ITERATIONS = 1e4;
|
|
10494
|
+
var TABU_TENURE = 15;
|
|
10495
|
+
var NEIGHBORHOOD_SIZE = 20;
|
|
10496
|
+
var tabuSolver = {
|
|
10497
|
+
id: "tabu",
|
|
10498
|
+
name: "Tabu Search",
|
|
10499
|
+
description: "Hill climbing with short-term memory to avoid revisiting recent solutions.",
|
|
10500
|
+
async solve(problem, options) {
|
|
10501
|
+
const startTime = performance.now();
|
|
10502
|
+
const timeoutMs = options?.timeoutMs ?? 15e3;
|
|
10503
|
+
const rng = createRng(42);
|
|
10504
|
+
let currentPerm = randomPermutation(problem, rng);
|
|
10505
|
+
let currentSchedule = decodePermutation(currentPerm, problem);
|
|
10506
|
+
let currentMakespan = computeMakespan(currentSchedule);
|
|
10507
|
+
let bestSchedule = currentSchedule;
|
|
10508
|
+
let bestMakespan = currentMakespan;
|
|
10509
|
+
const tabuList = /* @__PURE__ */ new Map();
|
|
10510
|
+
const progressInterval = Math.max(1, Math.floor(ITERATIONS / 100));
|
|
10511
|
+
for (let iter = 0; iter < ITERATIONS; iter++) {
|
|
10512
|
+
if (performance.now() - startTime > timeoutMs)
|
|
10513
|
+
break;
|
|
10514
|
+
let bestNeighborPerm = null;
|
|
10515
|
+
let bestNeighborMakespan = Infinity;
|
|
10516
|
+
let bestSwapKey = "";
|
|
10517
|
+
for (let n = 0; n < NEIGHBORHOOD_SIZE; n++) {
|
|
10518
|
+
const i = Math.floor(rng() * currentPerm.length);
|
|
10519
|
+
let j = Math.floor(rng() * (currentPerm.length - 1));
|
|
10520
|
+
if (j >= i)
|
|
10521
|
+
j++;
|
|
10522
|
+
const swapKey = `${Math.min(i, j)},${Math.max(i, j)}`;
|
|
10523
|
+
const candidatePerm = [...currentPerm];
|
|
10524
|
+
[candidatePerm[i], candidatePerm[j]] = [candidatePerm[j], candidatePerm[i]];
|
|
10525
|
+
const candidateSchedule = decodePermutation(candidatePerm, problem);
|
|
10526
|
+
const candidateMakespan = computeMakespan(candidateSchedule);
|
|
10527
|
+
const isTabu = (tabuList.get(swapKey) ?? 0) > iter;
|
|
10528
|
+
const aspirationMet = candidateMakespan < bestMakespan;
|
|
10529
|
+
if ((!isTabu || aspirationMet) && candidateMakespan < bestNeighborMakespan) {
|
|
10530
|
+
bestNeighborPerm = candidatePerm;
|
|
10531
|
+
bestNeighborMakespan = candidateMakespan;
|
|
10532
|
+
bestSwapKey = swapKey;
|
|
10533
|
+
}
|
|
10534
|
+
}
|
|
10535
|
+
if (bestNeighborPerm) {
|
|
10536
|
+
currentPerm = bestNeighborPerm;
|
|
10537
|
+
currentSchedule = decodePermutation(currentPerm, problem);
|
|
10538
|
+
currentMakespan = bestNeighborMakespan;
|
|
10539
|
+
tabuList.set(bestSwapKey, iter + TABU_TENURE);
|
|
10540
|
+
if (currentMakespan < bestMakespan) {
|
|
10541
|
+
bestMakespan = currentMakespan;
|
|
10542
|
+
bestSchedule = currentSchedule;
|
|
10543
|
+
}
|
|
10544
|
+
}
|
|
10545
|
+
if (iter % 100 === 0) {
|
|
10546
|
+
for (const [key, expiry] of tabuList) {
|
|
10547
|
+
if (expiry <= iter)
|
|
10548
|
+
tabuList.delete(key);
|
|
10549
|
+
}
|
|
10550
|
+
}
|
|
10551
|
+
if (options?.onProgress && iter % progressInterval === 0) {
|
|
10552
|
+
options.onProgress({
|
|
10553
|
+
solverId: "tabu",
|
|
10554
|
+
percentage: Math.round(iter / ITERATIONS * 100),
|
|
10555
|
+
bestMakespan,
|
|
10556
|
+
currentIteration: iter,
|
|
10557
|
+
totalIterations: ITERATIONS
|
|
10558
|
+
});
|
|
10559
|
+
}
|
|
10560
|
+
}
|
|
10561
|
+
options?.onProgress?.({
|
|
10562
|
+
solverId: "tabu",
|
|
10563
|
+
percentage: 100,
|
|
10564
|
+
bestMakespan,
|
|
10565
|
+
currentIteration: ITERATIONS,
|
|
10566
|
+
totalIterations: ITERATIONS
|
|
10567
|
+
});
|
|
10568
|
+
return {
|
|
10569
|
+
solverId: "tabu",
|
|
10570
|
+
solverName: "Tabu Search",
|
|
10571
|
+
makespan: bestMakespan,
|
|
10572
|
+
schedule: bestSchedule,
|
|
10573
|
+
elapsedMs: performance.now() - startTime,
|
|
10574
|
+
iterations: ITERATIONS
|
|
10575
|
+
};
|
|
10576
|
+
}
|
|
10577
|
+
};
|
|
10578
|
+
|
|
10579
|
+
// ../../b4m-core/packages/quantum/dist/src/solvers/genetic-algorithm-solver.js
|
|
10580
|
+
var POPULATION_SIZE = 50;
|
|
10581
|
+
var GENERATIONS = 200;
|
|
10582
|
+
var TOURNAMENT_SIZE = 5;
|
|
10583
|
+
var MUTATION_RATE = 0.15;
|
|
10584
|
+
var geneticAlgorithmSolver = {
|
|
10585
|
+
id: "genetic-algorithm",
|
|
10586
|
+
name: "Genetic Algorithm",
|
|
10587
|
+
description: "Population-based search with tournament selection, crossover, and mutation.",
|
|
10588
|
+
async solve(problem, options) {
|
|
10589
|
+
const startTime = performance.now();
|
|
10590
|
+
const timeoutMs = options?.timeoutMs ?? 2e4;
|
|
10591
|
+
const rng = createRng(42);
|
|
10592
|
+
let population = [];
|
|
10593
|
+
for (let i = 0; i < POPULATION_SIZE; i++) {
|
|
10594
|
+
const perm = randomPermutation(problem, rng);
|
|
10595
|
+
const schedule = decodePermutation(perm, problem);
|
|
10596
|
+
const makespan = computeMakespan(schedule);
|
|
10597
|
+
population.push({ perm, makespan });
|
|
10598
|
+
}
|
|
10599
|
+
let bestIndividual = population.reduce((best, ind) => ind.makespan < best.makespan ? ind : best);
|
|
10600
|
+
for (let gen = 0; gen < GENERATIONS; gen++) {
|
|
10601
|
+
if (performance.now() - startTime > timeoutMs)
|
|
10602
|
+
break;
|
|
10603
|
+
const newPopulation = [];
|
|
10604
|
+
newPopulation.push({ ...bestIndividual });
|
|
10605
|
+
while (newPopulation.length < POPULATION_SIZE) {
|
|
10606
|
+
const parent1 = tournamentSelect(population, TOURNAMENT_SIZE, rng);
|
|
10607
|
+
const parent2 = tournamentSelect(population, TOURNAMENT_SIZE, rng);
|
|
10608
|
+
let childPerm = crossover(parent1.perm, parent2.perm, rng);
|
|
10609
|
+
if (rng() < MUTATION_RATE) {
|
|
10610
|
+
childPerm = swapNeighbor(childPerm, rng);
|
|
10611
|
+
}
|
|
10612
|
+
const childSchedule = decodePermutation(childPerm, problem);
|
|
10613
|
+
const childMakespan = computeMakespan(childSchedule);
|
|
10614
|
+
newPopulation.push({ perm: childPerm, makespan: childMakespan });
|
|
10615
|
+
}
|
|
10616
|
+
population = newPopulation;
|
|
10617
|
+
const genBest = population.reduce((best, ind) => ind.makespan < best.makespan ? ind : best);
|
|
10618
|
+
if (genBest.makespan < bestIndividual.makespan) {
|
|
10619
|
+
bestIndividual = genBest;
|
|
10620
|
+
}
|
|
10621
|
+
options?.onProgress?.({
|
|
10622
|
+
solverId: "genetic-algorithm",
|
|
10623
|
+
percentage: Math.round((gen + 1) / GENERATIONS * 100),
|
|
10624
|
+
bestMakespan: bestIndividual.makespan,
|
|
10625
|
+
currentIteration: gen + 1,
|
|
10626
|
+
totalIterations: GENERATIONS
|
|
10627
|
+
});
|
|
10628
|
+
}
|
|
10629
|
+
const bestSchedule = decodePermutation(bestIndividual.perm, problem);
|
|
10630
|
+
return {
|
|
10631
|
+
solverId: "genetic-algorithm",
|
|
10632
|
+
solverName: "Genetic Algorithm",
|
|
10633
|
+
makespan: bestIndividual.makespan,
|
|
10634
|
+
schedule: bestSchedule,
|
|
10635
|
+
elapsedMs: performance.now() - startTime,
|
|
10636
|
+
iterations: GENERATIONS * POPULATION_SIZE
|
|
10637
|
+
};
|
|
10638
|
+
}
|
|
10639
|
+
};
|
|
10640
|
+
function tournamentSelect(population, size, rng) {
|
|
10641
|
+
let best = population[Math.floor(rng() * population.length)];
|
|
10642
|
+
for (let i = 1; i < size; i++) {
|
|
10643
|
+
const candidate = population[Math.floor(rng() * population.length)];
|
|
10644
|
+
if (candidate.makespan < best.makespan) {
|
|
10645
|
+
best = candidate;
|
|
10646
|
+
}
|
|
10647
|
+
}
|
|
10648
|
+
return best;
|
|
10649
|
+
}
|
|
10650
|
+
function crossover(parent1, parent2, rng) {
|
|
10651
|
+
const len = parent1.length;
|
|
10652
|
+
const start = Math.floor(rng() * len);
|
|
10653
|
+
const end = start + Math.floor(rng() * (len - start));
|
|
10654
|
+
const child = new Array(len).fill(null);
|
|
10655
|
+
const used = /* @__PURE__ */ new Set();
|
|
10656
|
+
for (let i = start; i <= end && i < len; i++) {
|
|
10657
|
+
child[i] = parent1[i];
|
|
10658
|
+
used.add(`${parent1[i].jobId}-${parent1[i].opIndex}`);
|
|
10659
|
+
}
|
|
10660
|
+
let pos = 0;
|
|
10661
|
+
for (const op of parent2) {
|
|
10662
|
+
const key = `${op.jobId}-${op.opIndex}`;
|
|
10663
|
+
if (!used.has(key)) {
|
|
10664
|
+
while (child[pos] !== null)
|
|
10665
|
+
pos++;
|
|
10666
|
+
child[pos] = op;
|
|
10667
|
+
used.add(key);
|
|
10668
|
+
}
|
|
10669
|
+
}
|
|
10670
|
+
return child;
|
|
10671
|
+
}
|
|
10672
|
+
|
|
10673
|
+
// ../../b4m-core/packages/quantum/dist/src/solvers/ant-colony-solver.js
|
|
10674
|
+
var NUM_ANTS = 20;
|
|
10675
|
+
var ITERATIONS2 = 100;
|
|
10676
|
+
var ALPHA = 1;
|
|
10677
|
+
var BETA = 2;
|
|
10678
|
+
var EVAPORATION = 0.1;
|
|
10679
|
+
var Q = 100;
|
|
10680
|
+
var antColonySolver = {
|
|
10681
|
+
id: "ant-colony",
|
|
10682
|
+
name: "Ant Colony Optimization",
|
|
10683
|
+
description: "Swarm intelligence using pheromone trails to guide solution construction.",
|
|
10684
|
+
async solve(problem, options) {
|
|
10685
|
+
const startTime = performance.now();
|
|
10686
|
+
const timeoutMs = options?.timeoutMs ?? 2e4;
|
|
10687
|
+
const rng = createRng(42);
|
|
10688
|
+
const allOps = buildOperationList(problem);
|
|
10689
|
+
const numOps = allOps.length;
|
|
10690
|
+
const pheromone = Array.from({ length: numOps }, () => new Array(numOps).fill(1));
|
|
10691
|
+
const heuristic = allOps.map((ref) => {
|
|
10692
|
+
const job = problem.jobs.find((j) => j.id === ref.jobId);
|
|
10693
|
+
const op = job.operations[ref.opIndex];
|
|
10694
|
+
return 1 / op.duration;
|
|
10695
|
+
});
|
|
10696
|
+
let bestMakespan = Infinity;
|
|
10697
|
+
let bestSchedule = decodePermutation(allOps, problem);
|
|
10698
|
+
for (let iter = 0; iter < ITERATIONS2; iter++) {
|
|
10699
|
+
if (performance.now() - startTime > timeoutMs)
|
|
10700
|
+
break;
|
|
10701
|
+
const antSolutions = [];
|
|
10702
|
+
for (let ant = 0; ant < NUM_ANTS; ant++) {
|
|
10703
|
+
const perm = constructSolution(allOps, pheromone, heuristic, rng);
|
|
10704
|
+
const schedule = decodePermutation(perm, problem);
|
|
10705
|
+
const makespan = computeMakespan(schedule);
|
|
10706
|
+
antSolutions.push({ perm, makespan });
|
|
10707
|
+
if (makespan < bestMakespan) {
|
|
10708
|
+
bestMakespan = makespan;
|
|
10709
|
+
bestSchedule = schedule;
|
|
10710
|
+
}
|
|
10711
|
+
}
|
|
10712
|
+
for (let i = 0; i < numOps; i++) {
|
|
10713
|
+
for (let j = 0; j < numOps; j++) {
|
|
10714
|
+
pheromone[i][j] *= 1 - EVAPORATION;
|
|
10715
|
+
}
|
|
10716
|
+
}
|
|
10717
|
+
for (const solution of antSolutions) {
|
|
10718
|
+
const deposit = Q / solution.makespan;
|
|
10719
|
+
for (let pos = 0; pos < solution.perm.length; pos++) {
|
|
10720
|
+
const opIdx = allOps.findIndex((o) => o.jobId === solution.perm[pos].jobId && o.opIndex === solution.perm[pos].opIndex);
|
|
10721
|
+
if (opIdx >= 0) {
|
|
10722
|
+
pheromone[pos][opIdx] += deposit;
|
|
10723
|
+
}
|
|
10724
|
+
}
|
|
10725
|
+
}
|
|
10726
|
+
options?.onProgress?.({
|
|
10727
|
+
solverId: "ant-colony",
|
|
10728
|
+
percentage: Math.round((iter + 1) / ITERATIONS2 * 100),
|
|
10729
|
+
bestMakespan,
|
|
10730
|
+
currentIteration: iter + 1,
|
|
10731
|
+
totalIterations: ITERATIONS2
|
|
10732
|
+
});
|
|
10733
|
+
}
|
|
10734
|
+
return {
|
|
10735
|
+
solverId: "ant-colony",
|
|
10736
|
+
solverName: "Ant Colony Optimization",
|
|
10737
|
+
makespan: bestMakespan,
|
|
10738
|
+
schedule: bestSchedule,
|
|
10739
|
+
elapsedMs: performance.now() - startTime,
|
|
10740
|
+
iterations: ITERATIONS2 * NUM_ANTS
|
|
10741
|
+
};
|
|
10742
|
+
}
|
|
10743
|
+
};
|
|
10744
|
+
function constructSolution(allOps, pheromone, heuristic, rng) {
|
|
10745
|
+
const remaining = new Set(allOps.map((_, i) => i));
|
|
10746
|
+
const result = [];
|
|
10747
|
+
for (let pos = 0; pos < allOps.length; pos++) {
|
|
10748
|
+
const candidates = Array.from(remaining);
|
|
10749
|
+
const weights = candidates.map((opIdx) => {
|
|
10750
|
+
const tau = Math.pow(pheromone[pos][opIdx], ALPHA);
|
|
10751
|
+
const eta = Math.pow(heuristic[opIdx], BETA);
|
|
10752
|
+
return tau * eta;
|
|
10753
|
+
});
|
|
10754
|
+
const totalWeight = weights.reduce((sum2, w) => sum2 + w, 0);
|
|
10755
|
+
let r = rng() * totalWeight;
|
|
10756
|
+
let selectedIdx = candidates[0];
|
|
10757
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
10758
|
+
r -= weights[i];
|
|
10759
|
+
if (r <= 0) {
|
|
10760
|
+
selectedIdx = candidates[i];
|
|
10761
|
+
break;
|
|
10762
|
+
}
|
|
10763
|
+
}
|
|
10764
|
+
result.push(allOps[selectedIdx]);
|
|
10765
|
+
remaining.delete(selectedIdx);
|
|
10766
|
+
}
|
|
10767
|
+
return result;
|
|
10768
|
+
}
|
|
10769
|
+
|
|
10770
|
+
// ../../b4m-core/packages/quantum/dist/src/solvers/index.js
|
|
10771
|
+
var allSolvers = [
|
|
10772
|
+
greedySolver,
|
|
10773
|
+
naiveSolver,
|
|
10774
|
+
randomRestartSolver,
|
|
10775
|
+
simulatedAnnealingSolver,
|
|
10776
|
+
simulatedAnnealingMediumSolver,
|
|
10777
|
+
simulatedAnnealingLargeSolver,
|
|
10778
|
+
tabuSolver,
|
|
10779
|
+
geneticAlgorithmSolver,
|
|
10780
|
+
antColonySolver
|
|
10781
|
+
];
|
|
10782
|
+
var solverRegistry = new Map(allSolvers.map((s) => [s.id, s]));
|
|
10783
|
+
function getSolver(id) {
|
|
10784
|
+
return solverRegistry.get(id);
|
|
10785
|
+
}
|
|
10786
|
+
function getAvailableSolverIds() {
|
|
10787
|
+
return Array.from(solverRegistry.keys());
|
|
10788
|
+
}
|
|
10789
|
+
|
|
10790
|
+
// ../../b4m-core/packages/quantum/dist/src/prompts/system-prompt.js
|
|
10791
|
+
var QUANTUM_CANVASSER_SYSTEM_PROMPT = `You are the Optimization Canvasser, an AI agent specializing in combinatorial optimization and job-shop scheduling. You help users formulate scheduling problems, run solver algorithms, and interpret optimization results. You are solver-agnostic \u2014 you route problems to the best solver whether classical (greedy, simulated annealing, genetic algorithms, HiGHS MIP) or quantum (QAOA), building credibility through honest recommendations.
|
|
10792
|
+
|
|
10793
|
+
## Your Capabilities
|
|
10794
|
+
|
|
10795
|
+
You have two specialized tools:
|
|
10796
|
+
|
|
10797
|
+
### quantum_formulate
|
|
10798
|
+
Converts natural language descriptions into structured SchedulingProblem definitions. When a user describes a scheduling scenario in plain English, use this tool to extract:
|
|
10799
|
+
- Jobs (ordered sequences of operations)
|
|
10800
|
+
- Machines (resources that process operations)
|
|
10801
|
+
- Operation durations and machine assignments
|
|
10802
|
+
- Precedence constraints (operations within a job must execute in order)
|
|
10803
|
+
|
|
10804
|
+
### quantum_schedule
|
|
10805
|
+
Runs optimization solvers on a structured SchedulingProblem. Available solvers:
|
|
10806
|
+
${allSolvers.map((s) => `- **${s.name}** (\`${s.id}\`): ${s.description}`).join("\n")}
|
|
10807
|
+
|
|
10808
|
+
## How to Help Users
|
|
10809
|
+
|
|
10810
|
+
### Problem Formulation
|
|
10811
|
+
When a user describes a scheduling scenario:
|
|
10812
|
+
1. Use \`quantum_formulate\` to convert their description into a structured problem
|
|
10813
|
+
2. Present the formulated problem clearly, showing jobs, machines, and operation sequences
|
|
10814
|
+
3. Ask if adjustments are needed before solving
|
|
10815
|
+
|
|
10816
|
+
### Running Solvers
|
|
10817
|
+
When solving a problem:
|
|
10818
|
+
1. Start with the \`greedy\` solver for a quick baseline result
|
|
10819
|
+
2. For better solutions, suggest running multiple solvers: \`greedy\`, \`simulated-annealing\`, \`tabu\`, \`genetic-algorithm\`
|
|
10820
|
+
3. Explain that metaheuristic solvers explore larger solution spaces but take longer
|
|
10821
|
+
4. Compare results across solvers when multiple are run
|
|
10822
|
+
|
|
10823
|
+
### Interpreting Results
|
|
10824
|
+
When presenting solver results:
|
|
10825
|
+
- Explain the **makespan** (total schedule length) and why lower is better
|
|
10826
|
+
- Walk through the schedule showing which jobs run on which machines at what times
|
|
10827
|
+
- Identify bottleneck machines (those with the most continuous utilization)
|
|
10828
|
+
- Suggest improvements if the problem structure allows (e.g., rebalancing operations)
|
|
10829
|
+
|
|
10830
|
+
### QUBO Encoding
|
|
10831
|
+
If asked about quantum computing aspects:
|
|
10832
|
+
- Explain how scheduling problems are encoded as QUBO (Quadratic Unconstrained Binary Optimization) matrices
|
|
10833
|
+
- Time-indexed binary variables: x_{o,t} = 1 if operation o starts at time t
|
|
10834
|
+
- Three constraint families: exactly-once (each operation starts exactly once), no-overlap (no two operations on same machine at same time), precedence (operations within a job maintain order)
|
|
10835
|
+
- QUBO matrices can be solved by quantum annealers (D-Wave) or quantum-inspired classical solvers
|
|
10836
|
+
|
|
10837
|
+
## Communication Style
|
|
10838
|
+
- Be precise with numbers and scheduling terminology
|
|
10839
|
+
- Use clear formatting: tables for schedules, bullet points for comparisons
|
|
10840
|
+
- When explaining optimization concepts, ground them in the user's specific problem
|
|
10841
|
+
- Proactively suggest next steps (e.g., "Would you like to try more solvers?" or "Should I adjust the problem?")
|
|
10842
|
+
|
|
10843
|
+
## Important Notes
|
|
10844
|
+
- All solvers run client-side in the browser via Web Workers \u2014 no server compute needed
|
|
10845
|
+
- The greedy solver is deterministic and instant; metaheuristic solvers involve randomness
|
|
10846
|
+
- For very large problems (50+ operations), recommend the greedy and simulated-annealing solvers
|
|
10847
|
+
- The HiGHS MIP solver uses WASM and provides optimal solutions for small problems but may be slow on large ones`;
|
|
10848
|
+
var PROBLEM_FORMULATION_PROMPT = `You are a job-shop scheduling problem formulator. Convert the user's natural language description into a structured SchedulingProblem JSON object.
|
|
10849
|
+
|
|
10850
|
+
RULES:
|
|
10851
|
+
1. Each job has an id (number starting from 0), a name, and an ordered array of operations
|
|
10852
|
+
2. Each machine has an id (number starting from 0) and a name
|
|
10853
|
+
3. Each operation has jobId (matching its parent job), machineId (which machine it runs on), and duration (positive integer)
|
|
10854
|
+
4. Operations within a job execute in order (first operation must finish before second starts)
|
|
10855
|
+
5. Each machine can only process one operation at a time
|
|
10856
|
+
6. Assign reasonable durations if not specified (use whole numbers)
|
|
10857
|
+
7. Create meaningful names for jobs and machines based on context
|
|
10858
|
+
|
|
10859
|
+
RESPOND WITH ONLY A JSON OBJECT matching this schema:
|
|
10860
|
+
{
|
|
10861
|
+
"name": "string - descriptive problem name",
|
|
10862
|
+
"description": "string - brief description",
|
|
10863
|
+
"jobs": [
|
|
10864
|
+
{
|
|
10865
|
+
"id": 0,
|
|
10866
|
+
"name": "Job Name",
|
|
10867
|
+
"operations": [
|
|
10868
|
+
{ "jobId": 0, "machineId": 0, "duration": 3 }
|
|
10869
|
+
]
|
|
10870
|
+
}
|
|
10871
|
+
],
|
|
10872
|
+
"machines": [
|
|
10873
|
+
{ "id": 0, "name": "Machine Name" }
|
|
10874
|
+
]
|
|
10875
|
+
}
|
|
10876
|
+
|
|
10877
|
+
No markdown, no explanation, no code blocks \u2014 just the raw JSON object.`;
|
|
10878
|
+
|
|
10879
|
+
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/quantumSchedule/index.js
|
|
10880
|
+
function formatResult(result) {
|
|
10881
|
+
const lines = [
|
|
10882
|
+
`Solver: ${result.solverName} (${result.solverId})`,
|
|
10883
|
+
`Makespan: ${result.makespan}`,
|
|
10884
|
+
`Elapsed: ${result.elapsedMs.toFixed(1)}ms`
|
|
10885
|
+
];
|
|
10886
|
+
if (result.iterations !== void 0) {
|
|
10887
|
+
lines.push(`Iterations: ${result.iterations}`);
|
|
10888
|
+
}
|
|
10889
|
+
lines.push("Schedule:");
|
|
10890
|
+
const byMachine = /* @__PURE__ */ new Map();
|
|
10891
|
+
for (const op of result.schedule) {
|
|
10892
|
+
if (!byMachine.has(op.machineId))
|
|
10893
|
+
byMachine.set(op.machineId, []);
|
|
10894
|
+
byMachine.get(op.machineId).push(op);
|
|
10895
|
+
}
|
|
10896
|
+
for (const [machineId, ops] of byMachine) {
|
|
10897
|
+
const sorted = ops.sort((a, b) => a.startTime - b.startTime);
|
|
10898
|
+
const timeline = sorted.map((op) => `Job${op.jobId}[${op.startTime}-${op.endTime}]`).join(" -> ");
|
|
10899
|
+
lines.push(` Machine ${machineId}: ${timeline}`);
|
|
10900
|
+
}
|
|
10901
|
+
return lines.join("\n");
|
|
10902
|
+
}
|
|
10903
|
+
async function runQuantumSchedule(params) {
|
|
10904
|
+
const parseResult = SchedulingProblemSchema.safeParse(params.problem);
|
|
10905
|
+
if (!parseResult.success) {
|
|
10906
|
+
return `Error: Invalid scheduling problem format.
|
|
10907
|
+
${parseResult.error.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n")}
|
|
10908
|
+
|
|
10909
|
+
Expected format: { name, jobs: [{ id, name, operations: [{ jobId, machineId, duration }] }], machines: [{ id, name }] }`;
|
|
10910
|
+
}
|
|
10911
|
+
const problem = parseResult.data;
|
|
10912
|
+
let solverIds;
|
|
10913
|
+
if (params.solverIds && params.solverIds.length > 0) {
|
|
10914
|
+
const invalid = params.solverIds.filter((id) => !SolverIdSchema.safeParse(id).success);
|
|
10915
|
+
if (invalid.length > 0) {
|
|
10916
|
+
return `Error: Unknown solver IDs: ${invalid.join(", ")}.
|
|
10917
|
+
Available solvers: ${getAvailableSolverIds().join(", ")}`;
|
|
10918
|
+
}
|
|
10919
|
+
solverIds = params.solverIds;
|
|
10920
|
+
} else {
|
|
10921
|
+
solverIds = ["greedy"];
|
|
10922
|
+
}
|
|
10923
|
+
const timeoutMs = params.timeoutMs ?? 1e4;
|
|
10924
|
+
const results = [];
|
|
10925
|
+
const errors = [];
|
|
10926
|
+
for (const solverId of solverIds) {
|
|
10927
|
+
const solver = getSolver(solverId);
|
|
10928
|
+
if (!solver) {
|
|
10929
|
+
errors.push(`Solver "${solverId}" not found`);
|
|
10930
|
+
continue;
|
|
10931
|
+
}
|
|
10932
|
+
try {
|
|
10933
|
+
const result = await solver.solve(problem, { timeoutMs });
|
|
10934
|
+
results.push(result);
|
|
10935
|
+
} catch (err) {
|
|
10936
|
+
errors.push(`${solver.name}: ${err instanceof Error ? err.message : String(err)}`);
|
|
10937
|
+
}
|
|
10938
|
+
}
|
|
10939
|
+
if (results.length === 0) {
|
|
10940
|
+
return `Error: No solvers completed successfully.
|
|
10941
|
+
${errors.join("\n")}`;
|
|
10942
|
+
}
|
|
10943
|
+
results.sort((a, b) => a.makespan - b.makespan);
|
|
10944
|
+
const lines = [];
|
|
10945
|
+
lines.push(`## Scheduling Results for "${problem.name}"`);
|
|
10946
|
+
lines.push(`Problem: ${problem.jobs.length} jobs, ${problem.machines.length} machines, ${problem.jobs.reduce((s, j) => s + j.operations.length, 0)} operations`);
|
|
10947
|
+
lines.push("");
|
|
10948
|
+
if (results.length > 1) {
|
|
10949
|
+
lines.push(`### Winner: ${results[0].solverName} (makespan: ${results[0].makespan})`);
|
|
10950
|
+
lines.push("");
|
|
10951
|
+
}
|
|
10952
|
+
for (const result of results) {
|
|
10953
|
+
lines.push(`### ${result.solverName}`);
|
|
10954
|
+
lines.push(formatResult(result));
|
|
10955
|
+
lines.push("");
|
|
10956
|
+
}
|
|
10957
|
+
if (errors.length > 0) {
|
|
10958
|
+
lines.push("### Errors");
|
|
10959
|
+
errors.forEach((e) => lines.push(`- ${e}`));
|
|
10960
|
+
}
|
|
10961
|
+
return lines.join("\n");
|
|
10962
|
+
}
|
|
10963
|
+
var quantumScheduleTool = {
|
|
10964
|
+
name: "quantum_schedule",
|
|
10965
|
+
implementation: () => ({
|
|
10966
|
+
toolFn: (value) => runQuantumSchedule(value),
|
|
10967
|
+
toolSchema: {
|
|
10968
|
+
name: "quantum_schedule",
|
|
10969
|
+
description: `Run quantum-inspired optimization solvers on a job-shop scheduling problem. Finds optimal or near-optimal schedules that minimize makespan (total completion time).
|
|
10970
|
+
|
|
10971
|
+
Available solvers: ${allSolvers.map((s) => `${s.id} (${s.name})`).join(", ")}.
|
|
10972
|
+
|
|
10973
|
+
The "greedy" solver runs instantly. Metaheuristic solvers (simulated-annealing, tabu, genetic-algorithm, ant-colony) explore larger solution spaces but take longer. Use multiple solvers to race them against each other.
|
|
10974
|
+
|
|
10975
|
+
The problem must define jobs (each with ordered operations) and machines. Each operation runs on a specific machine for a specific duration. Operations within a job must run in order.`,
|
|
10976
|
+
parameters: {
|
|
10977
|
+
type: "object",
|
|
10978
|
+
properties: {
|
|
10979
|
+
problem: {
|
|
10980
|
+
type: "object",
|
|
10981
|
+
description: "The scheduling problem to solve. Must include name, jobs array, and machines array.",
|
|
10982
|
+
properties: {
|
|
10983
|
+
name: { type: "string", description: "Name of the scheduling problem" },
|
|
10984
|
+
description: { type: "string", description: "Optional description" },
|
|
10985
|
+
jobs: {
|
|
10986
|
+
type: "array",
|
|
10987
|
+
description: "Array of jobs, each with id, name, and operations",
|
|
10988
|
+
items: {
|
|
10989
|
+
type: "object",
|
|
10990
|
+
properties: {
|
|
10991
|
+
id: { type: "number" },
|
|
10992
|
+
name: { type: "string" },
|
|
10993
|
+
operations: {
|
|
10994
|
+
type: "array",
|
|
10995
|
+
items: {
|
|
10996
|
+
type: "object",
|
|
10997
|
+
properties: {
|
|
10998
|
+
jobId: { type: "number", description: "Must match the parent job id" },
|
|
10999
|
+
machineId: { type: "number", description: "Which machine this operation runs on" },
|
|
11000
|
+
duration: { type: "number", description: "Processing time" }
|
|
11001
|
+
},
|
|
11002
|
+
required: ["jobId", "machineId", "duration"]
|
|
11003
|
+
}
|
|
11004
|
+
}
|
|
11005
|
+
},
|
|
11006
|
+
required: ["id", "name", "operations"]
|
|
11007
|
+
}
|
|
11008
|
+
},
|
|
11009
|
+
machines: {
|
|
11010
|
+
type: "array",
|
|
11011
|
+
description: "Array of machines with id and name",
|
|
11012
|
+
items: {
|
|
11013
|
+
type: "object",
|
|
11014
|
+
properties: {
|
|
11015
|
+
id: { type: "number" },
|
|
11016
|
+
name: { type: "string" }
|
|
11017
|
+
},
|
|
11018
|
+
required: ["id", "name"]
|
|
11019
|
+
}
|
|
11020
|
+
}
|
|
11021
|
+
},
|
|
11022
|
+
required: ["name", "jobs", "machines"]
|
|
11023
|
+
},
|
|
11024
|
+
solverIds: {
|
|
11025
|
+
type: "array",
|
|
11026
|
+
items: { type: "string" },
|
|
11027
|
+
description: `Which solvers to run. Defaults to ["greedy"]. Available: ${getAvailableSolverIds().join(", ")}. Use multiple to race solvers.`
|
|
11028
|
+
},
|
|
11029
|
+
timeoutMs: {
|
|
11030
|
+
type: "number",
|
|
11031
|
+
description: "Maximum time per solver in milliseconds (default: 10000)"
|
|
11032
|
+
}
|
|
11033
|
+
},
|
|
11034
|
+
required: ["problem"]
|
|
11035
|
+
}
|
|
11036
|
+
}
|
|
11037
|
+
})
|
|
11038
|
+
};
|
|
11039
|
+
|
|
11040
|
+
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/quantumFormulate/index.js
|
|
11041
|
+
var quantumFormulateTool = {
|
|
11042
|
+
name: "quantum_formulate",
|
|
11043
|
+
implementation: (context) => ({
|
|
11044
|
+
toolFn: async (value) => {
|
|
11045
|
+
const params = value;
|
|
11046
|
+
const userDescription = params.description?.trim();
|
|
11047
|
+
if (!userDescription) {
|
|
11048
|
+
return "Error: Please provide a description of the scheduling problem to formulate.";
|
|
11049
|
+
}
|
|
11050
|
+
try {
|
|
11051
|
+
let rawContent = "";
|
|
11052
|
+
await context.llm.complete(context.model ?? "gpt-4", [
|
|
11053
|
+
{ role: "system", content: PROBLEM_FORMULATION_PROMPT },
|
|
11054
|
+
{ role: "user", content: userDescription }
|
|
11055
|
+
], { temperature: 0.2, stream: false }, async (texts) => {
|
|
11056
|
+
rawContent = texts.filter((t) => t !== null && t !== void 0).join("");
|
|
11057
|
+
});
|
|
11058
|
+
let jsonStr = rawContent.trim();
|
|
11059
|
+
const codeBlockMatch = jsonStr.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
11060
|
+
if (codeBlockMatch) {
|
|
11061
|
+
jsonStr = codeBlockMatch[1].trim();
|
|
11062
|
+
}
|
|
11063
|
+
let parsed;
|
|
11064
|
+
try {
|
|
11065
|
+
parsed = JSON.parse(jsonStr);
|
|
11066
|
+
} catch {
|
|
11067
|
+
return `Error: Could not parse LLM response as JSON. Raw response:
|
|
11068
|
+
${rawContent}
|
|
11069
|
+
|
|
11070
|
+
Please try rephrasing your description with more specific details about jobs, machines, and processing times.`;
|
|
11071
|
+
}
|
|
11072
|
+
const validated = SchedulingProblemSchema.safeParse(parsed);
|
|
11073
|
+
if (!validated.success) {
|
|
11074
|
+
return `Error: LLM generated an invalid problem structure.
|
|
11075
|
+
${validated.error.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n")}
|
|
11076
|
+
|
|
11077
|
+
Raw output:
|
|
11078
|
+
${jsonStr}
|
|
11079
|
+
|
|
11080
|
+
Please try rephrasing your description.`;
|
|
11081
|
+
}
|
|
11082
|
+
const problem = validated.data;
|
|
11083
|
+
const totalOps = problem.jobs.reduce((s, j) => s + j.operations.length, 0);
|
|
11084
|
+
const lines = [
|
|
11085
|
+
`## Formulated: "${problem.name}"`,
|
|
11086
|
+
problem.description ? `
|
|
11087
|
+
${problem.description}` : "",
|
|
11088
|
+
"",
|
|
11089
|
+
`**${problem.jobs.length} jobs, ${problem.machines.length} machines, ${totalOps} operations**`,
|
|
11090
|
+
"",
|
|
11091
|
+
"### Jobs:",
|
|
11092
|
+
...problem.jobs.map((j) => {
|
|
11093
|
+
const ops = j.operations.map((op, i) => {
|
|
11094
|
+
const machine = problem.machines.find((m) => m.id === op.machineId);
|
|
11095
|
+
return `Step ${i + 1}: ${machine?.name ?? `Machine ${op.machineId}`} (${op.duration}t)`;
|
|
11096
|
+
});
|
|
11097
|
+
return `- **${j.name}**: ${ops.join(" -> ")}`;
|
|
11098
|
+
}),
|
|
11099
|
+
"",
|
|
11100
|
+
"### Machines:",
|
|
11101
|
+
...problem.machines.map((m) => `- ${m.name} (id: ${m.id})`),
|
|
11102
|
+
"",
|
|
11103
|
+
"### Structured Problem (JSON):",
|
|
11104
|
+
"```json",
|
|
11105
|
+
JSON.stringify(problem, null, 2),
|
|
11106
|
+
"```",
|
|
11107
|
+
"",
|
|
11108
|
+
"You can now use the `quantum_schedule` tool to solve this problem with various optimization algorithms."
|
|
11109
|
+
];
|
|
11110
|
+
return lines.filter((l) => l !== void 0).join("\n");
|
|
11111
|
+
} catch (err) {
|
|
11112
|
+
return `Error formulating problem: ${err instanceof Error ? err.message : String(err)}`;
|
|
11113
|
+
}
|
|
11114
|
+
},
|
|
11115
|
+
toolSchema: {
|
|
11116
|
+
name: "quantum_formulate",
|
|
11117
|
+
description: `Convert a natural language description of a scheduling/optimization problem into a structured SchedulingProblem that can be solved by the quantum_schedule tool.
|
|
11118
|
+
|
|
11119
|
+
Describe the problem in plain English \u2014 what jobs need to be done, what machines or resources are available, how long each step takes, and any ordering constraints. The tool will produce a structured problem definition.
|
|
11120
|
+
|
|
11121
|
+
Examples:
|
|
11122
|
+
- "I have 3 orders to manufacture. Each needs cutting, welding, and painting. Cutting takes 2h, welding 3h, painting 1h."
|
|
11123
|
+
- "Schedule 4 software builds across 2 CI runners. Build A needs compile (5min) then test (3min)..."
|
|
11124
|
+
- "A bakery needs to make 5 cakes. Each cake goes through mixing, baking, and decorating on separate stations."`,
|
|
11125
|
+
parameters: {
|
|
11126
|
+
type: "object",
|
|
11127
|
+
properties: {
|
|
11128
|
+
description: {
|
|
11129
|
+
type: "string",
|
|
11130
|
+
description: "Natural language description of the scheduling problem to formulate"
|
|
11131
|
+
}
|
|
11132
|
+
},
|
|
11133
|
+
required: ["description"]
|
|
11134
|
+
}
|
|
11135
|
+
}
|
|
11136
|
+
})
|
|
11137
|
+
};
|
|
11138
|
+
|
|
11139
|
+
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/navigateView/index.js
|
|
11140
|
+
var navigateViewTool = {
|
|
11141
|
+
name: "navigate_view",
|
|
11142
|
+
implementation: (context) => ({
|
|
11143
|
+
toolFn: async (value) => {
|
|
11144
|
+
const params = value;
|
|
11145
|
+
const { suggestions } = params;
|
|
11146
|
+
context.logger.log("\u{1F9ED} navigate_view: Received suggestions:", JSON.stringify(suggestions));
|
|
11147
|
+
if (!suggestions || !Array.isArray(suggestions) || suggestions.length === 0) {
|
|
11148
|
+
return "No navigation suggestions provided.";
|
|
11149
|
+
}
|
|
11150
|
+
const capped = suggestions.slice(0, 3);
|
|
11151
|
+
const invalid = capped.filter((s) => !getViewById(s.viewId));
|
|
11152
|
+
if (invalid.length > 0) {
|
|
11153
|
+
context.logger.log("\u{1F9ED} navigate_view: Unknown viewIds:", invalid.map((s) => s.viewId));
|
|
11154
|
+
}
|
|
11155
|
+
const isAdmin = context.user?.isAdmin === true;
|
|
11156
|
+
const intents = resolveNavigationIntents(capped, isAdmin);
|
|
11157
|
+
if (intents.length === 0) {
|
|
11158
|
+
return "No valid navigation views matched the provided viewIds.";
|
|
11159
|
+
}
|
|
11160
|
+
context.logger.log("\u{1F9ED} navigate_view: Resolved intents:", intents.map((i) => i.viewId));
|
|
11161
|
+
return JSON.stringify({
|
|
11162
|
+
__navigationIntents: true,
|
|
11163
|
+
intents,
|
|
11164
|
+
message: `Suggested ${intents.length} navigation option(s): ${intents.map((i) => i.label).join(", ")}`
|
|
11165
|
+
});
|
|
11166
|
+
},
|
|
11167
|
+
toolSchema: {
|
|
11168
|
+
name: "navigate_view",
|
|
11169
|
+
description: "Suggest navigation to relevant app views. Returns inline action buttons the user can click. ALWAYS use this tool when your response discusses a topic that has a matching view (e.g., scheduling \u2192 opti.scheduling, user management \u2192 admin.users). Call this tool alongside your text answer \u2014 answer the question AND suggest where to go.",
|
|
11170
|
+
parameters: {
|
|
11171
|
+
type: "object",
|
|
11172
|
+
properties: {
|
|
11173
|
+
suggestions: {
|
|
11174
|
+
type: "array",
|
|
11175
|
+
description: "Navigation suggestions (1-3 items). Each suggests a view the user might want to visit.",
|
|
11176
|
+
items: {
|
|
11177
|
+
type: "object",
|
|
11178
|
+
properties: {
|
|
11179
|
+
viewId: {
|
|
11180
|
+
type: "string",
|
|
11181
|
+
description: 'The view ID from the available views list (e.g., "opti.scheduling", "admin.users")'
|
|
11182
|
+
},
|
|
11183
|
+
reason: {
|
|
11184
|
+
type: "string",
|
|
11185
|
+
description: "Brief reason why this view is relevant (max 80 chars, shown as tooltip)"
|
|
11186
|
+
}
|
|
11187
|
+
},
|
|
11188
|
+
required: ["viewId", "reason"]
|
|
11189
|
+
},
|
|
11190
|
+
maxItems: 3,
|
|
11191
|
+
minItems: 1
|
|
11192
|
+
}
|
|
11193
|
+
},
|
|
11194
|
+
required: ["suggestions"]
|
|
11195
|
+
}
|
|
11196
|
+
}
|
|
11197
|
+
})
|
|
11198
|
+
};
|
|
11199
|
+
|
|
9966
11200
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/bashExecute/index.js
|
|
9967
11201
|
import { spawn } from "child_process";
|
|
9968
11202
|
import path12 from "path";
|
|
@@ -10212,7 +11446,7 @@ async function executeBashCommand(params) {
|
|
|
10212
11446
|
});
|
|
10213
11447
|
});
|
|
10214
11448
|
}
|
|
10215
|
-
function
|
|
11449
|
+
function formatResult2(result, command) {
|
|
10216
11450
|
const parts = [];
|
|
10217
11451
|
parts.push(`$ ${command}`);
|
|
10218
11452
|
parts.push("");
|
|
@@ -10266,7 +11500,7 @@ var bashExecuteTool = {
|
|
|
10266
11500
|
}
|
|
10267
11501
|
try {
|
|
10268
11502
|
const result = await executeBashCommand(params);
|
|
10269
|
-
const formattedResult =
|
|
11503
|
+
const formattedResult = formatResult2(result, params.command);
|
|
10270
11504
|
context.logger.info("Bash: Command completed", {
|
|
10271
11505
|
exitCode: result.exitCode,
|
|
10272
11506
|
timedOut: result.timedOut,
|
|
@@ -11435,7 +12669,7 @@ async function getFileStats(files, since, filterPath) {
|
|
|
11435
12669
|
});
|
|
11436
12670
|
});
|
|
11437
12671
|
}
|
|
11438
|
-
function
|
|
12672
|
+
function formatResult3(result) {
|
|
11439
12673
|
const parts = [];
|
|
11440
12674
|
if (result.error) {
|
|
11441
12675
|
parts.push(`Error: ${result.error}`);
|
|
@@ -11510,7 +12744,7 @@ var recentChangesTool = {
|
|
|
11510
12744
|
}
|
|
11511
12745
|
try {
|
|
11512
12746
|
const result = await getRecentChanges(params);
|
|
11513
|
-
const formattedResult =
|
|
12747
|
+
const formattedResult = formatResult3(result);
|
|
11514
12748
|
context.logger.info("RecentChanges: Retrieved file changes", {
|
|
11515
12749
|
totalFiles: result.totalFiles,
|
|
11516
12750
|
displayedFiles: result.files.length,
|
|
@@ -11608,8 +12842,14 @@ var b4mTools = {
|
|
|
11608
12842
|
sunrise_sunset: sunriseSunsetTool,
|
|
11609
12843
|
iss_tracker: issTrackerTool,
|
|
11610
12844
|
planet_visibility: planetVisibilityTool,
|
|
11611
|
-
// Knowledge base
|
|
11612
|
-
search_knowledge_base: knowledgeBaseSearchTool
|
|
12845
|
+
// Knowledge base tools
|
|
12846
|
+
search_knowledge_base: knowledgeBaseSearchTool,
|
|
12847
|
+
retrieve_knowledge_content: knowledgeBaseRetrieveTool,
|
|
12848
|
+
// Quantum optimization tools
|
|
12849
|
+
quantum_schedule: quantumScheduleTool,
|
|
12850
|
+
quantum_formulate: quantumFormulateTool,
|
|
12851
|
+
// Navigation tool
|
|
12852
|
+
navigate_view: navigateViewTool
|
|
11613
12853
|
};
|
|
11614
12854
|
var cliOnlyTools = {
|
|
11615
12855
|
// File operation tools
|
|
@@ -11739,50 +12979,50 @@ var generateMcpTools = async (mcpData) => {
|
|
|
11739
12979
|
import throttle2 from "lodash/throttle.js";
|
|
11740
12980
|
|
|
11741
12981
|
// ../../b4m-core/packages/services/dist/src/llm/ChatCompletionFeatures.js
|
|
11742
|
-
import { z as
|
|
12982
|
+
import { z as z140 } from "zod";
|
|
11743
12983
|
import uniq4 from "lodash/uniq.js";
|
|
11744
|
-
var QuestStartBodySchema =
|
|
11745
|
-
userId:
|
|
11746
|
-
sessionId:
|
|
11747
|
-
questId:
|
|
11748
|
-
message:
|
|
11749
|
-
messageFileIds:
|
|
11750
|
-
historyCount:
|
|
11751
|
-
fabFileIds:
|
|
12984
|
+
var QuestStartBodySchema = z140.object({
|
|
12985
|
+
userId: z140.string(),
|
|
12986
|
+
sessionId: z140.string(),
|
|
12987
|
+
questId: z140.string(),
|
|
12988
|
+
message: z140.string(),
|
|
12989
|
+
messageFileIds: z140.array(z140.string()),
|
|
12990
|
+
historyCount: z140.number(),
|
|
12991
|
+
fabFileIds: z140.array(z140.string()),
|
|
11752
12992
|
params: ChatCompletionCreateInputSchema,
|
|
11753
12993
|
dashboardParams: DashboardParamsSchema.optional(),
|
|
11754
|
-
enableQuestMaster:
|
|
11755
|
-
enableMementos:
|
|
11756
|
-
enableArtifacts:
|
|
11757
|
-
enableAgents:
|
|
11758
|
-
enableLattice:
|
|
12994
|
+
enableQuestMaster: z140.boolean().optional(),
|
|
12995
|
+
enableMementos: z140.boolean().optional(),
|
|
12996
|
+
enableArtifacts: z140.boolean().optional(),
|
|
12997
|
+
enableAgents: z140.boolean().optional(),
|
|
12998
|
+
enableLattice: z140.boolean().optional(),
|
|
11759
12999
|
promptMeta: PromptMetaZodSchema,
|
|
11760
|
-
tools:
|
|
11761
|
-
mcpServers:
|
|
11762
|
-
projectId:
|
|
11763
|
-
organizationId:
|
|
13000
|
+
tools: z140.array(z140.union([b4mLLMTools, z140.string()])).optional(),
|
|
13001
|
+
mcpServers: z140.array(z140.string()).optional(),
|
|
13002
|
+
projectId: z140.string().optional(),
|
|
13003
|
+
organizationId: z140.string().nullable().optional(),
|
|
11764
13004
|
questMaster: QuestMasterParamsSchema.optional(),
|
|
11765
|
-
toolPromptId:
|
|
13005
|
+
toolPromptId: z140.string().optional(),
|
|
11766
13006
|
researchMode: ResearchModeParamsSchema.optional(),
|
|
11767
|
-
fallbackModel:
|
|
11768
|
-
embeddingModel:
|
|
11769
|
-
queryComplexity:
|
|
13007
|
+
fallbackModel: z140.string().optional(),
|
|
13008
|
+
embeddingModel: z140.string().optional(),
|
|
13009
|
+
queryComplexity: z140.string(),
|
|
11770
13010
|
imageConfig: GenerateImageToolCallSchema.optional(),
|
|
11771
|
-
deepResearchConfig:
|
|
11772
|
-
maxDepth:
|
|
11773
|
-
duration:
|
|
13011
|
+
deepResearchConfig: z140.object({
|
|
13012
|
+
maxDepth: z140.number().optional(),
|
|
13013
|
+
duration: z140.number().optional(),
|
|
11774
13014
|
// Note: searchers are passed via ToolContext and not through this API schema
|
|
11775
|
-
searchers:
|
|
13015
|
+
searchers: z140.array(z140.any()).optional()
|
|
11776
13016
|
}).optional(),
|
|
11777
|
-
extraContextMessages:
|
|
11778
|
-
role:
|
|
11779
|
-
content:
|
|
11780
|
-
fabFileIds:
|
|
13017
|
+
extraContextMessages: z140.array(z140.object({
|
|
13018
|
+
role: z140.enum(["user", "assistant", "system", "function", "tool"]),
|
|
13019
|
+
content: z140.union([z140.string(), z140.array(z140.any())]),
|
|
13020
|
+
fabFileIds: z140.array(z140.string()).optional()
|
|
11781
13021
|
})).optional(),
|
|
11782
13022
|
/** User's timezone (IANA format, e.g., "America/New_York") */
|
|
11783
|
-
timezone:
|
|
13023
|
+
timezone: z140.string().optional(),
|
|
11784
13024
|
/** Pre-fetched API key table from invoke phase — avoids redundant DB call in process (#6616 P1-a) */
|
|
11785
|
-
apiKeyTable:
|
|
13025
|
+
apiKeyTable: z140.record(z140.string(), z140.string().nullable()).optional()
|
|
11786
13026
|
});
|
|
11787
13027
|
|
|
11788
13028
|
// ../../b4m-core/packages/services/dist/src/llm/StatusManager.js
|
|
@@ -12282,89 +13522,89 @@ var BUILT_IN_TOOL_SET = new Set(b4mLLMTools.options);
|
|
|
12282
13522
|
import axios8 from "axios";
|
|
12283
13523
|
import { fileTypeFromBuffer as fileTypeFromBuffer4 } from "file-type";
|
|
12284
13524
|
import { v4 as uuidv47 } from "uuid";
|
|
12285
|
-
import { z as
|
|
13525
|
+
import { z as z141 } from "zod";
|
|
12286
13526
|
import { fromZodError as fromZodError2 } from "zod-validation-error";
|
|
12287
13527
|
var ImageGenerationBodySchema = OpenAIImageGenerationInput.extend({
|
|
12288
|
-
sessionId:
|
|
12289
|
-
questId:
|
|
12290
|
-
userId:
|
|
12291
|
-
prompt:
|
|
12292
|
-
organizationId:
|
|
12293
|
-
safety_tolerance:
|
|
12294
|
-
prompt_upsampling:
|
|
12295
|
-
seed:
|
|
12296
|
-
output_format:
|
|
12297
|
-
width:
|
|
12298
|
-
height:
|
|
12299
|
-
aspect_ratio:
|
|
12300
|
-
fabFileIds:
|
|
13528
|
+
sessionId: z141.string(),
|
|
13529
|
+
questId: z141.string(),
|
|
13530
|
+
userId: z141.string(),
|
|
13531
|
+
prompt: z141.string(),
|
|
13532
|
+
organizationId: z141.string().nullable().optional(),
|
|
13533
|
+
safety_tolerance: z141.number().min(BFL_SAFETY_TOLERANCE.MIN).max(BFL_SAFETY_TOLERANCE.MAX).optional().default(BFL_SAFETY_TOLERANCE.DEFAULT),
|
|
13534
|
+
prompt_upsampling: z141.boolean().optional().default(false),
|
|
13535
|
+
seed: z141.number().nullable().optional(),
|
|
13536
|
+
output_format: z141.enum(["jpeg", "png"]).nullable().optional().default("png"),
|
|
13537
|
+
width: z141.number().optional(),
|
|
13538
|
+
height: z141.number().optional(),
|
|
13539
|
+
aspect_ratio: z141.string().optional(),
|
|
13540
|
+
fabFileIds: z141.array(z141.string()).optional()
|
|
12301
13541
|
});
|
|
12302
13542
|
|
|
12303
13543
|
// ../../b4m-core/packages/services/dist/src/llm/VideoGeneration.js
|
|
12304
13544
|
import axios9 from "axios";
|
|
12305
13545
|
import { v4 as uuidv48 } from "uuid";
|
|
12306
|
-
import { z as
|
|
13546
|
+
import { z as z142 } from "zod";
|
|
12307
13547
|
import { fromZodError as fromZodError3 } from "zod-validation-error";
|
|
12308
|
-
var VideoGenerationBodySchema =
|
|
12309
|
-
sessionId:
|
|
12310
|
-
questId:
|
|
12311
|
-
userId:
|
|
12312
|
-
prompt:
|
|
12313
|
-
model:
|
|
12314
|
-
seconds:
|
|
12315
|
-
size:
|
|
12316
|
-
organizationId:
|
|
13548
|
+
var VideoGenerationBodySchema = z142.object({
|
|
13549
|
+
sessionId: z142.string(),
|
|
13550
|
+
questId: z142.string(),
|
|
13551
|
+
userId: z142.string(),
|
|
13552
|
+
prompt: z142.string(),
|
|
13553
|
+
model: z142.nativeEnum(VideoModels).default(VideoModels.SORA_2),
|
|
13554
|
+
seconds: z142.union([z142.literal(4), z142.literal(8), z142.literal(12)]).default(4),
|
|
13555
|
+
size: z142.enum(["720x1280", "1280x720", "1024x1792", "1792x1024"]).default(VIDEO_SIZE_CONSTRAINTS.SORA.defaultSize),
|
|
13556
|
+
organizationId: z142.string().nullable().optional()
|
|
12317
13557
|
});
|
|
12318
13558
|
|
|
12319
13559
|
// ../../b4m-core/packages/services/dist/src/llm/ImageEdit.js
|
|
12320
13560
|
import axios10 from "axios";
|
|
12321
13561
|
import { fileTypeFromBuffer as fileTypeFromBuffer5 } from "file-type";
|
|
12322
13562
|
import { v4 as uuidv49 } from "uuid";
|
|
12323
|
-
import { z as
|
|
13563
|
+
import { z as z143 } from "zod";
|
|
12324
13564
|
import { fromZodError as fromZodError4 } from "zod-validation-error";
|
|
12325
13565
|
var ImageEditBodySchema = OpenAIImageGenerationInput.extend({
|
|
12326
|
-
sessionId:
|
|
12327
|
-
questId:
|
|
12328
|
-
userId:
|
|
12329
|
-
prompt:
|
|
12330
|
-
organizationId:
|
|
12331
|
-
safety_tolerance:
|
|
12332
|
-
prompt_upsampling:
|
|
12333
|
-
seed:
|
|
12334
|
-
output_format:
|
|
12335
|
-
width:
|
|
12336
|
-
height:
|
|
12337
|
-
aspect_ratio:
|
|
12338
|
-
size:
|
|
12339
|
-
fabFileIds:
|
|
12340
|
-
image:
|
|
13566
|
+
sessionId: z143.string(),
|
|
13567
|
+
questId: z143.string(),
|
|
13568
|
+
userId: z143.string(),
|
|
13569
|
+
prompt: z143.string(),
|
|
13570
|
+
organizationId: z143.string().nullable().optional(),
|
|
13571
|
+
safety_tolerance: z143.number().min(BFL_SAFETY_TOLERANCE.MIN).max(BFL_SAFETY_TOLERANCE.MAX).optional().default(BFL_SAFETY_TOLERANCE.DEFAULT),
|
|
13572
|
+
prompt_upsampling: z143.boolean().optional().default(false),
|
|
13573
|
+
seed: z143.number().nullable().optional(),
|
|
13574
|
+
output_format: z143.enum(["jpeg", "png"]).optional().default("png"),
|
|
13575
|
+
width: z143.number().optional(),
|
|
13576
|
+
height: z143.number().optional(),
|
|
13577
|
+
aspect_ratio: z143.string().optional(),
|
|
13578
|
+
size: z143.string().optional(),
|
|
13579
|
+
fabFileIds: z143.array(z143.string()).optional(),
|
|
13580
|
+
image: z143.string()
|
|
12341
13581
|
});
|
|
12342
13582
|
|
|
12343
13583
|
// ../../b4m-core/packages/services/dist/src/llm/refineText.js
|
|
12344
|
-
import { z as
|
|
12345
|
-
var refineTextLLMSchema =
|
|
12346
|
-
text:
|
|
12347
|
-
context:
|
|
13584
|
+
import { z as z144 } from "zod";
|
|
13585
|
+
var refineTextLLMSchema = z144.object({
|
|
13586
|
+
text: z144.string(),
|
|
13587
|
+
context: z144.string().optional()
|
|
12348
13588
|
// tone: z.enum(['formal', 'informal', 'neutral']).optional(),
|
|
12349
13589
|
// style: z.enum(['technical', 'creative', 'academic', 'business', 'narrative']).optional(),
|
|
12350
13590
|
});
|
|
12351
13591
|
|
|
12352
13592
|
// ../../b4m-core/packages/services/dist/src/llm/MementoEvaluationService.js
|
|
12353
|
-
import { z as
|
|
12354
|
-
var SingleMementoEvalSchema =
|
|
12355
|
-
importance:
|
|
13593
|
+
import { z as z145 } from "zod";
|
|
13594
|
+
var SingleMementoEvalSchema = z145.object({
|
|
13595
|
+
importance: z145.number().min(1).max(10),
|
|
12356
13596
|
// 1-10 scale for personal info importance
|
|
12357
|
-
summary:
|
|
12358
|
-
tags:
|
|
13597
|
+
summary: z145.string(),
|
|
13598
|
+
tags: z145.array(z145.string()).optional()
|
|
12359
13599
|
});
|
|
12360
|
-
var MementoEvalResponseSchema =
|
|
12361
|
-
isPersonal:
|
|
12362
|
-
mementos:
|
|
13600
|
+
var MementoEvalResponseSchema = z145.object({
|
|
13601
|
+
isPersonal: z145.boolean(),
|
|
13602
|
+
mementos: z145.array(SingleMementoEvalSchema).optional()
|
|
12363
13603
|
// Array of distinct personal information
|
|
12364
13604
|
});
|
|
12365
13605
|
|
|
12366
13606
|
// ../../b4m-core/packages/services/dist/src/llm/SmallLLMService.js
|
|
12367
|
-
import { z as
|
|
13607
|
+
import { z as z146 } from "zod";
|
|
12368
13608
|
|
|
12369
13609
|
// ../../b4m-core/packages/services/dist/src/auth/AccessTokenGeneratorService.js
|
|
12370
13610
|
import jwt2 from "jsonwebtoken";
|
|
@@ -12657,7 +13897,7 @@ function buildHookContext(params) {
|
|
|
12657
13897
|
}
|
|
12658
13898
|
|
|
12659
13899
|
// src/agents/types.ts
|
|
12660
|
-
import { z as
|
|
13900
|
+
import { z as z147 } from "zod";
|
|
12661
13901
|
var HookBlockedError = class extends Error {
|
|
12662
13902
|
constructor(toolName, reason) {
|
|
12663
13903
|
super(`Hook blocked execution of ${toolName}: ${reason || "No reason provided"}`);
|
|
@@ -12669,40 +13909,40 @@ var ALWAYS_DENIED_FOR_AGENTS = [
|
|
|
12669
13909
|
"agent_delegate"
|
|
12670
13910
|
// No agent chaining
|
|
12671
13911
|
];
|
|
12672
|
-
var CommandHookSchema =
|
|
12673
|
-
type:
|
|
12674
|
-
command:
|
|
12675
|
-
timeout:
|
|
13912
|
+
var CommandHookSchema = z147.object({
|
|
13913
|
+
type: z147.literal("command"),
|
|
13914
|
+
command: z147.string().min(1, "Command is required for command hooks"),
|
|
13915
|
+
timeout: z147.number().optional()
|
|
12676
13916
|
});
|
|
12677
|
-
var PromptHookSchema =
|
|
12678
|
-
type:
|
|
12679
|
-
prompt:
|
|
12680
|
-
timeout:
|
|
13917
|
+
var PromptHookSchema = z147.object({
|
|
13918
|
+
type: z147.literal("prompt"),
|
|
13919
|
+
prompt: z147.string().min(1, "Prompt is required for prompt hooks"),
|
|
13920
|
+
timeout: z147.number().optional()
|
|
12681
13921
|
});
|
|
12682
|
-
var HookDefinitionSchema =
|
|
12683
|
-
var HookMatcherSchema =
|
|
12684
|
-
matcher:
|
|
12685
|
-
hooks:
|
|
13922
|
+
var HookDefinitionSchema = z147.discriminatedUnion("type", [CommandHookSchema, PromptHookSchema]);
|
|
13923
|
+
var HookMatcherSchema = z147.object({
|
|
13924
|
+
matcher: z147.string().optional(),
|
|
13925
|
+
hooks: z147.array(HookDefinitionSchema)
|
|
12686
13926
|
});
|
|
12687
|
-
var AgentHooksSchema =
|
|
12688
|
-
PreToolUse:
|
|
12689
|
-
PostToolUse:
|
|
12690
|
-
PostToolUseFailure:
|
|
12691
|
-
Stop:
|
|
13927
|
+
var AgentHooksSchema = z147.object({
|
|
13928
|
+
PreToolUse: z147.array(HookMatcherSchema).optional(),
|
|
13929
|
+
PostToolUse: z147.array(HookMatcherSchema).optional(),
|
|
13930
|
+
PostToolUseFailure: z147.array(HookMatcherSchema).optional(),
|
|
13931
|
+
Stop: z147.array(HookMatcherSchema).optional()
|
|
12692
13932
|
}).optional();
|
|
12693
|
-
var AgentFrontmatterSchema =
|
|
12694
|
-
description:
|
|
12695
|
-
model:
|
|
12696
|
-
"allowed-tools":
|
|
12697
|
-
"denied-tools":
|
|
12698
|
-
skills:
|
|
12699
|
-
"max-iterations":
|
|
12700
|
-
quick:
|
|
12701
|
-
medium:
|
|
12702
|
-
very_thorough:
|
|
13933
|
+
var AgentFrontmatterSchema = z147.object({
|
|
13934
|
+
description: z147.string().min(1, "Agent description is required"),
|
|
13935
|
+
model: z147.string().optional(),
|
|
13936
|
+
"allowed-tools": z147.array(z147.string()).optional(),
|
|
13937
|
+
"denied-tools": z147.array(z147.string()).optional(),
|
|
13938
|
+
skills: z147.array(z147.string()).optional(),
|
|
13939
|
+
"max-iterations": z147.object({
|
|
13940
|
+
quick: z147.number().int().positive().optional(),
|
|
13941
|
+
medium: z147.number().int().positive().optional(),
|
|
13942
|
+
very_thorough: z147.number().int().positive().optional()
|
|
12703
13943
|
}).optional(),
|
|
12704
|
-
"default-thoroughness":
|
|
12705
|
-
variables:
|
|
13944
|
+
"default-thoroughness": z147.enum(["quick", "medium", "very_thorough"]).optional(),
|
|
13945
|
+
variables: z147.record(z147.string()).optional(),
|
|
12706
13946
|
hooks: AgentHooksSchema
|
|
12707
13947
|
});
|
|
12708
13948
|
var DEFAULT_MAX_ITERATIONS = {
|
|
@@ -14635,7 +15875,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
|
|
|
14635
15875
|
// package.json
|
|
14636
15876
|
var package_default = {
|
|
14637
15877
|
name: "@bike4mind/cli",
|
|
14638
|
-
version: "0.2.
|
|
15878
|
+
version: "0.2.30-feat-quantum-optimize-architecture.19202+f15461eb1",
|
|
14639
15879
|
type: "module",
|
|
14640
15880
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
14641
15881
|
license: "UNLICENSED",
|
|
@@ -14749,10 +15989,10 @@ var package_default = {
|
|
|
14749
15989
|
},
|
|
14750
15990
|
devDependencies: {
|
|
14751
15991
|
"@bike4mind/agents": "0.1.0",
|
|
14752
|
-
"@bike4mind/common": "2.51.
|
|
14753
|
-
"@bike4mind/mcp": "1.30.
|
|
14754
|
-
"@bike4mind/services": "2.49.
|
|
14755
|
-
"@bike4mind/utils": "2.6.
|
|
15992
|
+
"@bike4mind/common": "2.51.1-feat-quantum-optimize-architecture.19202+f15461eb1",
|
|
15993
|
+
"@bike4mind/mcp": "1.30.1-feat-quantum-optimize-architecture.19202+f15461eb1",
|
|
15994
|
+
"@bike4mind/services": "2.49.1-feat-quantum-optimize-architecture.19202+f15461eb1",
|
|
15995
|
+
"@bike4mind/utils": "2.6.1-feat-quantum-optimize-architecture.19202+f15461eb1",
|
|
14756
15996
|
"@types/better-sqlite3": "^7.6.13",
|
|
14757
15997
|
"@types/diff": "^5.0.9",
|
|
14758
15998
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -14770,7 +16010,7 @@ var package_default = {
|
|
|
14770
16010
|
optionalDependencies: {
|
|
14771
16011
|
"@vscode/ripgrep": "^1.17.0"
|
|
14772
16012
|
},
|
|
14773
|
-
gitHead: "
|
|
16013
|
+
gitHead: "f15461eb1db88413308b9575f8e000d99dcf36cd"
|
|
14774
16014
|
};
|
|
14775
16015
|
|
|
14776
16016
|
// src/config/constants.ts
|