@bike4mind/cli 0.17.1 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +116 -0
- package/README.md +5 -2
- package/dist/{BackgroundAgentManager-C5HEirFN.mjs → BackgroundAgentManager-ChmoEU9H.mjs} +214 -121
- package/dist/{ConfigStore-gV8aHo9b.mjs → ConfigStore-yJU1dxpP.mjs} +150 -23
- package/dist/commands/apiCommand.mjs +4 -3
- package/dist/commands/doctorCommand.mjs +1 -1
- package/dist/commands/envCommand.mjs +1 -1
- package/dist/commands/headlessCommand.mjs +2 -2
- package/dist/commands/mcpCommand.mjs +1 -1
- package/dist/commands/updateCommand.mjs +1 -1
- package/dist/index.mjs +7 -6
- package/dist/{package-Dzetdo6D.mjs → package-B3f78bSl.mjs} +1 -1
- package/dist/utils-CLjLKvqQ.mjs +3 -0
- package/dist/{utils-PpNti-tY.mjs → utils-fqhJmuB8.mjs} +2 -2
- package/package.json +8 -8
- package/dist/utils-BGtSXfce.mjs +0 -3
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as
|
|
3
|
-
import { a as isUserLockedOut, c as userCanDisableMFA, d as userRequiresMFA, f as verifyBackupCode, i as getLockoutTimeRemaining, l as userEligibleForMFA, n as generateBackupCodes, o as recordFailedAttempt, p as verifyTOTPToken, r as generateTOTPSetup, s as shouldResetFailedAttempts, t as clearFailedAttempts, u as userHasMFAConfigured } from "./utils-
|
|
2
|
+
import { $ as PermissionDeniedError, $t as extractSnippetMeta, A as FriendshipEvents, At as XAI_IMAGE_MODELS, B as InboxEvents, Bt as isZodError, C as CorruptedFileError, Ct as TransferCreditTransaction, D as FeedbackEvents, Dt as VIDEO_SIZE_CONSTRAINTS, E as FavoriteDocumentType, Et as UnprocessableEntityError, F as HTTPError, Ft as getViewById, G as LLMEvents, Gt as sanitizeTelemetryError, H as InviteEvents, Ht as obfuscateApiKey, I as HttpStatus, It as isGPTImage2Model, J as ModelBackend, Jt as substituteArguments$1, K as MiscEvents, Kt as secureParameters, L as ImageEditUsageTransaction, Lt as isGPTImageModel, M as GenerateImageToolCallSchema, Mt as dayjsConfig_default, N as GenericCreditAddTransaction, Nt as getAccessibleDataLakes, O as FileEvents, Ot as VideoGenerationUsageTransaction, P as GenericCreditDeductTransaction, Pt as getMcpProviderMetadata, Q as Permission, Qt as buildRateLimitLogEntry, R as ImageGenerationUsageTransaction, Rt as isModelAccessible, S as CompletionApiUsageTransaction, St as ToolUsageTransaction, T as ElabsEvents, Tt as UnauthorizedError, U as InviteType, Ut as parseSkillArguments, V as InternalServerError, Vt as mapMimeTypeToArtifactType, W as KnowledgeType, Wt as resolveNavigationIntents, X as OpenAIEmbeddingModel, Y as NotFoundError, Yt as toDataLakeConfig, Z as OpenAIImageGenerationInput, _ as BadRequestError, _t as SupportedFabFileMimeTypes, at as QuestMasterParamsSchema, b as ChatModels, bt as TextGenerationUsageTransaction, c as AiEvents, ct as RechartsChartTypeList, d as ApiKeyType, dt as ResearchTaskExecutionType, en as isNearLimit, et as ProfileEvents, f as AppFileEvents, ft as ResearchTaskPeriodicFrequencyType, g as BFL_SAFETY_TOLERANCE, gt as SubscriptionCreditTransaction, h as BFL_IMAGE_MODELS, ht as SpeechToTextUsageTransaction, it as PurchaseTransaction, j as GEMINI_IMAGE_MODELS, jt as b4mLLMTools, k as ForbiddenError, kt as VideoModels, l as ApiKeyEvents, lt as RegInviteEvents, m as AuthEvents, mt as SessionEvents, n as logger, nn as CollectionType, nt as PromptIntentSchema, ot as RealtimeVoiceUsageTransaction, p as ArtifactTypeSchema, pt as ResearchTaskType, q as ModalEvents, qt as settingsMap, rt as PromptMetaZodSchema, s as ALERT_THRESHOLDS, st as ReceivedCreditTransaction, t as ConfigStore, tn as parseRateLimitHeaders, tt as ProjectEvents, u as ApiKeyScope, ut as ResearchModeParamsSchema, vt as TagType, w as DashboardParamsSchema, wt as UiNavigationEvents, x as ClaudeArtifactMimeTypes, xt as TooManyRequestsError, y as ChatCompletionCreateInputSchema, yt as TaskScheduleHandler, z as ImageModels, zt as isSupportedEmbeddingModel } from "./ConfigStore-yJU1dxpP.mjs";
|
|
3
|
+
import { a as isUserLockedOut, c as userCanDisableMFA, d as userRequiresMFA, f as verifyBackupCode, i as getLockoutTimeRemaining, l as userEligibleForMFA, n as generateBackupCodes, o as recordFailedAttempt, p as verifyTOTPToken, r as generateTOTPSetup, s as shouldResetFailedAttempts, t as clearFailedAttempts, u as userHasMFAConfigured } from "./utils-fqhJmuB8.mjs";
|
|
4
4
|
import { n as isPathAllowed, t as assertPathAllowed } from "./pathValidation-D8tjkQXE-1HwvsuYT.mjs";
|
|
5
|
-
import { t as version } from "./package-
|
|
5
|
+
import { t as version } from "./package-B3f78bSl.mjs";
|
|
6
6
|
import { execFile, execFileSync, spawn } from "child_process";
|
|
7
7
|
import crypto, { createHash, randomBytes, randomUUID } from "crypto";
|
|
8
8
|
import { existsSync, promises, readFileSync, readdirSync, rmSync, statSync, unlinkSync, writeFileSync } from "fs";
|
|
@@ -3300,6 +3300,12 @@ const MIME_TO_EXT = {
|
|
|
3300
3300
|
};
|
|
3301
3301
|
const INFINITE_VALUE = 14;
|
|
3302
3302
|
const MAX_FILE_SIZE$2 = 6e3;
|
|
3303
|
+
/** Cap on generated images surfaced to the model for editing (keeps the context note small). */
|
|
3304
|
+
const MAX_RECENT_GENERATED_IMAGES = 6;
|
|
3305
|
+
/** Chars of the originating prompt kept per generated image, for context without bloat. */
|
|
3306
|
+
const RECENT_IMAGE_PROMPT_PREVIEW_CHARS = 120;
|
|
3307
|
+
/** quest.images also holds non-image generated artifacts (e.g. .xlsx); only these extensions are editable. */
|
|
3308
|
+
const EDITABLE_IMAGE_KEY_RE = /\.(jpe?g|png|webp|gif)$/i;
|
|
3303
3309
|
const PREVIEW_CHUNK = 700;
|
|
3304
3310
|
const CHARS_PER_TOKEN = 3.5;
|
|
3305
3311
|
const MAX_IMAGE_DIMENSION_PX = 2e3;
|
|
@@ -3407,70 +3413,85 @@ async function fetchAndProcessPreviousMessages(session, historyCount = null, { d
|
|
|
3407
3413
|
chatHistoryItems.splice(0, chatHistoryItems.length, ...filtered);
|
|
3408
3414
|
}
|
|
3409
3415
|
const oldestIncludedQuestId = chatHistoryItems[0]?.id ?? null;
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3416
|
+
const convertedMessages = chatHistoryItems.reduce((acc, cur) => {
|
|
3417
|
+
if (cur.prompt) acc.push({
|
|
3418
|
+
role: "user",
|
|
3419
|
+
content: cur.prompt
|
|
3420
|
+
});
|
|
3421
|
+
if (cur.structuredReplies && cur.structuredReplies.length > 0) {
|
|
3422
|
+
for (const structuredReply of cur.structuredReplies) acc.push({
|
|
3423
|
+
role: "assistant",
|
|
3424
|
+
content: structuredReply.content
|
|
3425
|
+
});
|
|
3426
|
+
if (cur.toolResults && cur.toolResults.length > 0) acc.push({
|
|
3413
3427
|
role: "user",
|
|
3414
|
-
content: cur.
|
|
3428
|
+
content: cur.toolResults.map((tr) => ({
|
|
3429
|
+
type: "tool_result",
|
|
3430
|
+
tool_use_id: tr.tool_use_id,
|
|
3431
|
+
content: tr.content,
|
|
3432
|
+
is_error: tr.is_error
|
|
3433
|
+
}))
|
|
3434
|
+
});
|
|
3435
|
+
} else if (cur.promptMeta?.functionCalls && cur.promptMeta.functionCalls.length > 0 && cur.promptMeta.functionCalls.some((fc) => fc.id)) {
|
|
3436
|
+
const textReply = cur.replies?.find((reply) => !reply.trim().startsWith("<think>")) || "";
|
|
3437
|
+
const assistantContent = [];
|
|
3438
|
+
if (textReply) assistantContent.push({
|
|
3439
|
+
type: "text",
|
|
3440
|
+
text: textReply
|
|
3415
3441
|
});
|
|
3416
|
-
|
|
3417
|
-
|
|
3442
|
+
for (const fc of cur.promptMeta.functionCalls) if (fc.id && fc.name) assistantContent.push({
|
|
3443
|
+
type: "tool_use",
|
|
3444
|
+
id: fc.id,
|
|
3445
|
+
name: fc.name,
|
|
3446
|
+
input: fc.parameters || {}
|
|
3447
|
+
});
|
|
3448
|
+
if (assistantContent.length > 0) {
|
|
3449
|
+
acc.push({
|
|
3418
3450
|
role: "assistant",
|
|
3419
|
-
content:
|
|
3451
|
+
content: assistantContent
|
|
3420
3452
|
});
|
|
3421
|
-
|
|
3453
|
+
const toolResults = cur.promptMeta.functionCalls.filter((fc) => fc.id && fc.name).map((fc) => ({
|
|
3454
|
+
type: "tool_result",
|
|
3455
|
+
tool_use_id: fc.id,
|
|
3456
|
+
content: fc.returnValue ?? (fc.success === false ? "Tool execution failed" : ""),
|
|
3457
|
+
is_error: fc.success === false
|
|
3458
|
+
}));
|
|
3459
|
+
if (toolResults.length > 0) acc.push({
|
|
3422
3460
|
role: "user",
|
|
3423
|
-
content:
|
|
3424
|
-
type: "tool_result",
|
|
3425
|
-
tool_use_id: tr.tool_use_id,
|
|
3426
|
-
content: tr.content,
|
|
3427
|
-
is_error: tr.is_error
|
|
3428
|
-
}))
|
|
3429
|
-
});
|
|
3430
|
-
} else if (cur.promptMeta?.functionCalls && cur.promptMeta.functionCalls.length > 0 && cur.promptMeta.functionCalls.some((fc) => fc.id)) {
|
|
3431
|
-
const textReply = cur.replies?.find((reply) => !reply.trim().startsWith("<think>")) || "";
|
|
3432
|
-
const assistantContent = [];
|
|
3433
|
-
if (textReply) assistantContent.push({
|
|
3434
|
-
type: "text",
|
|
3435
|
-
text: textReply
|
|
3436
|
-
});
|
|
3437
|
-
for (const fc of cur.promptMeta.functionCalls) if (fc.id && fc.name) assistantContent.push({
|
|
3438
|
-
type: "tool_use",
|
|
3439
|
-
id: fc.id,
|
|
3440
|
-
name: fc.name,
|
|
3441
|
-
input: fc.parameters || {}
|
|
3442
|
-
});
|
|
3443
|
-
if (assistantContent.length > 0) {
|
|
3444
|
-
acc.push({
|
|
3445
|
-
role: "assistant",
|
|
3446
|
-
content: assistantContent
|
|
3447
|
-
});
|
|
3448
|
-
const toolResults = cur.promptMeta.functionCalls.filter((fc) => fc.id && fc.name).map((fc) => ({
|
|
3449
|
-
type: "tool_result",
|
|
3450
|
-
tool_use_id: fc.id,
|
|
3451
|
-
content: fc.returnValue ?? (fc.success === false ? "Tool execution failed" : ""),
|
|
3452
|
-
is_error: fc.success === false
|
|
3453
|
-
}));
|
|
3454
|
-
if (toolResults.length > 0) acc.push({
|
|
3455
|
-
role: "user",
|
|
3456
|
-
content: toolResults
|
|
3457
|
-
});
|
|
3458
|
-
}
|
|
3459
|
-
} else if (cur.replies && Array.isArray(cur.replies)) {
|
|
3460
|
-
const validReply = cur.replies.find((reply) => !reply.trim().startsWith("<think>"));
|
|
3461
|
-
if (validReply) acc.push({
|
|
3462
|
-
role: "assistant",
|
|
3463
|
-
content: validReply
|
|
3461
|
+
content: toolResults
|
|
3464
3462
|
});
|
|
3465
3463
|
}
|
|
3466
|
-
|
|
3467
|
-
|
|
3464
|
+
} else if (cur.replies && Array.isArray(cur.replies)) {
|
|
3465
|
+
const validReply = cur.replies.find((reply) => !reply.trim().startsWith("<think>"));
|
|
3466
|
+
if (validReply) acc.push({
|
|
3467
|
+
role: "assistant",
|
|
3468
|
+
content: validReply
|
|
3469
|
+
});
|
|
3470
|
+
}
|
|
3471
|
+
return acc;
|
|
3472
|
+
}, new Array());
|
|
3473
|
+
const recentGeneratedImages = [];
|
|
3474
|
+
for (let i = chatHistoryItems.length - 1; i >= 0 && recentGeneratedImages.length < MAX_RECENT_GENERATED_IMAGES; i--) {
|
|
3475
|
+
const item = chatHistoryItems[i];
|
|
3476
|
+
if (!Array.isArray(item.images) || item.images.length === 0) continue;
|
|
3477
|
+
const prompt = (item.prompt ?? "").slice(0, RECENT_IMAGE_PROMPT_PREVIEW_CHARS);
|
|
3478
|
+
for (const key of item.images) {
|
|
3479
|
+
if (recentGeneratedImages.length >= MAX_RECENT_GENERATED_IMAGES) break;
|
|
3480
|
+
if (typeof key === "string" && EDITABLE_IMAGE_KEY_RE.test(key)) recentGeneratedImages.push({
|
|
3481
|
+
key,
|
|
3482
|
+
prompt
|
|
3483
|
+
});
|
|
3484
|
+
}
|
|
3485
|
+
}
|
|
3486
|
+
return [
|
|
3487
|
+
convertedMessages,
|
|
3468
3488
|
chatHistoryItems.length,
|
|
3469
3489
|
{
|
|
3470
3490
|
cacheHit: fetchTime < 50,
|
|
3471
3491
|
fetchTime,
|
|
3472
3492
|
itemCount: chatHistoryItems.length,
|
|
3473
|
-
oldestIncludedQuestId
|
|
3493
|
+
oldestIncludedQuestId,
|
|
3494
|
+
recentGeneratedImages
|
|
3474
3495
|
}
|
|
3475
3496
|
];
|
|
3476
3497
|
}
|
|
@@ -8822,6 +8843,36 @@ function sanitizeJsonStringWithMeta(jsonStr, options) {
|
|
|
8822
8843
|
}
|
|
8823
8844
|
//#endregion
|
|
8824
8845
|
//#region ../../b4m-core/quantum/dist/index.mjs
|
|
8846
|
+
/**
|
|
8847
|
+
* Scheduling's objective is makespan (lower is better), rendered in time units.
|
|
8848
|
+
* This is the `ObjectiveMeta` every scheduling `SolverResult` carries so that
|
|
8849
|
+
* shared, family-agnostic UI can render scheduling results too.
|
|
8850
|
+
*/
|
|
8851
|
+
const SCHEDULING_OBJECTIVE_META = {
|
|
8852
|
+
label: "makespan",
|
|
8853
|
+
unit: "t",
|
|
8854
|
+
direction: "min",
|
|
8855
|
+
format: { suffix: "t" }
|
|
8856
|
+
};
|
|
8857
|
+
/**
|
|
8858
|
+
* Build a scheduling `SolverResult` from the domain-native quantities a solver
|
|
8859
|
+
* produces (a schedule + its makespan), filling in the shared-contract fields.
|
|
8860
|
+
* Keeps the makespan→objective mapping in one place across all 11 solvers.
|
|
8861
|
+
*/
|
|
8862
|
+
function makeSchedulingResult(args) {
|
|
8863
|
+
return {
|
|
8864
|
+
solverId: args.solverId,
|
|
8865
|
+
solverName: args.solverName,
|
|
8866
|
+
objective: args.makespan,
|
|
8867
|
+
internalCost: args.makespan,
|
|
8868
|
+
objectiveMeta: SCHEDULING_OBJECTIVE_META,
|
|
8869
|
+
solution: args.schedule,
|
|
8870
|
+
elapsedMs: args.elapsedMs,
|
|
8871
|
+
iterations: args.iterations,
|
|
8872
|
+
trace: args.trace,
|
|
8873
|
+
metadata: args.metadata
|
|
8874
|
+
};
|
|
8875
|
+
}
|
|
8825
8876
|
const OperationSchema = z.object({
|
|
8826
8877
|
jobId: z.number(),
|
|
8827
8878
|
machineId: z.number(),
|
|
@@ -8899,19 +8950,19 @@ const greedySolver = {
|
|
|
8899
8950
|
if (options?.onProgress) options.onProgress({
|
|
8900
8951
|
solverId: "greedy",
|
|
8901
8952
|
percentage: Math.round(opsScheduled / totalOps * 100),
|
|
8902
|
-
|
|
8953
|
+
bestObjective: opEnd,
|
|
8903
8954
|
currentIteration: opsScheduled,
|
|
8904
8955
|
totalIterations: totalOps
|
|
8905
8956
|
});
|
|
8906
8957
|
}
|
|
8907
|
-
return {
|
|
8958
|
+
return makeSchedulingResult({
|
|
8908
8959
|
solverId: "greedy",
|
|
8909
8960
|
solverName: "Greedy (Earliest Start)",
|
|
8910
8961
|
makespan: Math.max(...schedule.map((op) => op.endTime)),
|
|
8911
8962
|
schedule,
|
|
8912
8963
|
elapsedMs: performance.now() - startTime,
|
|
8913
8964
|
iterations: totalOps
|
|
8914
|
-
};
|
|
8965
|
+
});
|
|
8915
8966
|
}
|
|
8916
8967
|
};
|
|
8917
8968
|
/**
|
|
@@ -9094,7 +9145,7 @@ const naiveSolver = {
|
|
|
9094
9145
|
if (options?.onProgress && count % 100 === 0) options.onProgress({
|
|
9095
9146
|
solverId: "naive",
|
|
9096
9147
|
percentage: Math.min(99, Math.round(count / cappedTotal * 100)),
|
|
9097
|
-
bestMakespan,
|
|
9148
|
+
bestObjective: bestMakespan,
|
|
9098
9149
|
currentIteration: count,
|
|
9099
9150
|
totalIterations: cappedTotal
|
|
9100
9151
|
});
|
|
@@ -9102,18 +9153,18 @@ const naiveSolver = {
|
|
|
9102
9153
|
options?.onProgress?.({
|
|
9103
9154
|
solverId: "naive",
|
|
9104
9155
|
percentage: 100,
|
|
9105
|
-
bestMakespan,
|
|
9156
|
+
bestObjective: bestMakespan,
|
|
9106
9157
|
currentIteration: count,
|
|
9107
9158
|
totalIterations: cappedTotal
|
|
9108
9159
|
});
|
|
9109
|
-
return {
|
|
9160
|
+
return makeSchedulingResult({
|
|
9110
9161
|
solverId: "naive",
|
|
9111
9162
|
solverName: "Naive (Brute Force)",
|
|
9112
9163
|
makespan: bestMakespan,
|
|
9113
9164
|
schedule: bestSchedule,
|
|
9114
9165
|
elapsedMs: performance.now() - startTime,
|
|
9115
9166
|
iterations: count
|
|
9116
|
-
};
|
|
9167
|
+
});
|
|
9117
9168
|
}
|
|
9118
9169
|
};
|
|
9119
9170
|
function factorial(n) {
|
|
@@ -9166,19 +9217,19 @@ const randomRestartSolver = {
|
|
|
9166
9217
|
options?.onProgress?.({
|
|
9167
9218
|
solverId: "random-restart",
|
|
9168
9219
|
percentage: Math.round((restart + 1) / RESTARTS * 100),
|
|
9169
|
-
|
|
9220
|
+
bestObjective: globalBestMakespan,
|
|
9170
9221
|
currentIteration: restart + 1,
|
|
9171
9222
|
totalIterations: RESTARTS
|
|
9172
9223
|
});
|
|
9173
9224
|
}
|
|
9174
|
-
return {
|
|
9225
|
+
return makeSchedulingResult({
|
|
9175
9226
|
solverId: "random-restart",
|
|
9176
9227
|
solverName: "Random Restart Hill Climbing",
|
|
9177
9228
|
makespan: globalBestMakespan,
|
|
9178
9229
|
schedule: globalBestSchedule,
|
|
9179
9230
|
elapsedMs: performance.now() - startTime,
|
|
9180
9231
|
iterations: totalIterations
|
|
9181
|
-
};
|
|
9232
|
+
});
|
|
9182
9233
|
}
|
|
9183
9234
|
};
|
|
9184
9235
|
const SA_CONFIGS = [
|
|
@@ -9242,7 +9293,7 @@ function createSASolver(config) {
|
|
|
9242
9293
|
if (options?.onProgress && i % progressInterval === 0) options.onProgress({
|
|
9243
9294
|
solverId: config.id,
|
|
9244
9295
|
percentage: Math.round(i / config.iterations * 100),
|
|
9245
|
-
bestMakespan,
|
|
9296
|
+
bestObjective: bestMakespan,
|
|
9246
9297
|
currentIteration: i,
|
|
9247
9298
|
totalIterations: config.iterations
|
|
9248
9299
|
});
|
|
@@ -9250,18 +9301,18 @@ function createSASolver(config) {
|
|
|
9250
9301
|
options?.onProgress?.({
|
|
9251
9302
|
solverId: config.id,
|
|
9252
9303
|
percentage: 100,
|
|
9253
|
-
bestMakespan,
|
|
9304
|
+
bestObjective: bestMakespan,
|
|
9254
9305
|
currentIteration: config.iterations,
|
|
9255
9306
|
totalIterations: config.iterations
|
|
9256
9307
|
});
|
|
9257
|
-
return {
|
|
9308
|
+
return makeSchedulingResult({
|
|
9258
9309
|
solverId: config.id,
|
|
9259
9310
|
solverName: config.name,
|
|
9260
9311
|
makespan: bestMakespan,
|
|
9261
9312
|
schedule: bestSchedule,
|
|
9262
9313
|
elapsedMs: performance.now() - startTime,
|
|
9263
9314
|
iterations: config.iterations
|
|
9264
|
-
};
|
|
9315
|
+
});
|
|
9265
9316
|
}
|
|
9266
9317
|
};
|
|
9267
9318
|
}
|
|
@@ -9328,7 +9379,7 @@ const tabuSolver = {
|
|
|
9328
9379
|
if (options?.onProgress && iter % progressInterval === 0) options.onProgress({
|
|
9329
9380
|
solverId: "tabu",
|
|
9330
9381
|
percentage: Math.round(iter / ITERATIONS$1 * 100),
|
|
9331
|
-
bestMakespan,
|
|
9382
|
+
bestObjective: bestMakespan,
|
|
9332
9383
|
currentIteration: iter,
|
|
9333
9384
|
totalIterations: ITERATIONS$1
|
|
9334
9385
|
});
|
|
@@ -9336,18 +9387,18 @@ const tabuSolver = {
|
|
|
9336
9387
|
options?.onProgress?.({
|
|
9337
9388
|
solverId: "tabu",
|
|
9338
9389
|
percentage: 100,
|
|
9339
|
-
bestMakespan,
|
|
9390
|
+
bestObjective: bestMakespan,
|
|
9340
9391
|
currentIteration: ITERATIONS$1,
|
|
9341
9392
|
totalIterations: ITERATIONS$1
|
|
9342
9393
|
});
|
|
9343
|
-
return {
|
|
9394
|
+
return makeSchedulingResult({
|
|
9344
9395
|
solverId: "tabu",
|
|
9345
9396
|
solverName: "Tabu Search",
|
|
9346
9397
|
makespan: bestMakespan,
|
|
9347
9398
|
schedule: bestSchedule,
|
|
9348
9399
|
elapsedMs: performance.now() - startTime,
|
|
9349
9400
|
iterations: ITERATIONS$1
|
|
9350
|
-
};
|
|
9401
|
+
});
|
|
9351
9402
|
}
|
|
9352
9403
|
};
|
|
9353
9404
|
/**
|
|
@@ -9399,20 +9450,20 @@ const geneticAlgorithmSolver = {
|
|
|
9399
9450
|
options?.onProgress?.({
|
|
9400
9451
|
solverId: "genetic-algorithm",
|
|
9401
9452
|
percentage: Math.round((gen + 1) / GENERATIONS * 100),
|
|
9402
|
-
|
|
9453
|
+
bestObjective: bestIndividual.makespan,
|
|
9403
9454
|
currentIteration: gen + 1,
|
|
9404
9455
|
totalIterations: GENERATIONS
|
|
9405
9456
|
});
|
|
9406
9457
|
}
|
|
9407
9458
|
const bestSchedule = decodePermutation(bestIndividual.perm, problem);
|
|
9408
|
-
return {
|
|
9459
|
+
return makeSchedulingResult({
|
|
9409
9460
|
solverId: "genetic-algorithm",
|
|
9410
9461
|
solverName: "Genetic Algorithm",
|
|
9411
9462
|
makespan: bestIndividual.makespan,
|
|
9412
9463
|
schedule: bestSchedule,
|
|
9413
9464
|
elapsedMs: performance.now() - startTime,
|
|
9414
9465
|
iterations: GENERATIONS * POPULATION_SIZE
|
|
9415
|
-
};
|
|
9466
|
+
});
|
|
9416
9467
|
}
|
|
9417
9468
|
};
|
|
9418
9469
|
function tournamentSelect(population, size, rng) {
|
|
@@ -9504,19 +9555,19 @@ const antColonySolver = {
|
|
|
9504
9555
|
options?.onProgress?.({
|
|
9505
9556
|
solverId: "ant-colony",
|
|
9506
9557
|
percentage: Math.round((iter + 1) / ITERATIONS * 100),
|
|
9507
|
-
bestMakespan,
|
|
9558
|
+
bestObjective: bestMakespan,
|
|
9508
9559
|
currentIteration: iter + 1,
|
|
9509
9560
|
totalIterations: ITERATIONS
|
|
9510
9561
|
});
|
|
9511
9562
|
}
|
|
9512
|
-
return {
|
|
9563
|
+
return makeSchedulingResult({
|
|
9513
9564
|
solverId: "ant-colony",
|
|
9514
9565
|
solverName: "Ant Colony Optimization",
|
|
9515
9566
|
makespan: bestMakespan,
|
|
9516
9567
|
schedule: bestSchedule,
|
|
9517
9568
|
elapsedMs: performance.now() - startTime,
|
|
9518
9569
|
iterations: ITERATIONS * NUM_ANTS
|
|
9519
|
-
};
|
|
9570
|
+
});
|
|
9520
9571
|
}
|
|
9521
9572
|
};
|
|
9522
9573
|
/**
|
|
@@ -9792,7 +9843,7 @@ const highsSolver = {
|
|
|
9792
9843
|
options?.onProgress?.({
|
|
9793
9844
|
solverId: "highs",
|
|
9794
9845
|
percentage,
|
|
9795
|
-
bestMakespan
|
|
9846
|
+
bestObjective: bestMakespan
|
|
9796
9847
|
});
|
|
9797
9848
|
};
|
|
9798
9849
|
reportProgress(0);
|
|
@@ -9842,14 +9893,14 @@ const highsSolver = {
|
|
|
9842
9893
|
throw new Error(`[HiGHS] Solution validation failed: ${errorDetails}`);
|
|
9843
9894
|
}
|
|
9844
9895
|
reportProgress(100, makespan);
|
|
9845
|
-
return {
|
|
9896
|
+
return makeSchedulingResult({
|
|
9846
9897
|
solverId: "highs",
|
|
9847
9898
|
solverName: "HiGHS (WASM)",
|
|
9848
9899
|
makespan,
|
|
9849
9900
|
schedule,
|
|
9850
9901
|
elapsedMs: elapsed(startTime),
|
|
9851
9902
|
iterations: 1
|
|
9852
|
-
};
|
|
9903
|
+
});
|
|
9853
9904
|
} catch (error) {
|
|
9854
9905
|
reportProgress(0);
|
|
9855
9906
|
throw error;
|
|
@@ -10496,26 +10547,27 @@ const allSolvers = [
|
|
|
10496
10547
|
progress(0);
|
|
10497
10548
|
const greedyResult = await greedySolver.solve(problem, {});
|
|
10498
10549
|
progress(10);
|
|
10499
|
-
const
|
|
10500
|
-
const
|
|
10550
|
+
const greedyMakespan = greedyResult.objective;
|
|
10551
|
+
const greedySchedule = greedyResult.solution;
|
|
10552
|
+
const encoded = encodeSchedulingWithMetadata(problem, greedyMakespan);
|
|
10501
10553
|
const numQubits = encoded.qubo.size;
|
|
10502
10554
|
if (numQubits > MAX_QUBITS || numQubits === 0) {
|
|
10503
10555
|
progress(100);
|
|
10504
|
-
return {
|
|
10556
|
+
return makeSchedulingResult({
|
|
10505
10557
|
solverId: "qaoa-local",
|
|
10506
10558
|
solverName: "QAOA (Local)",
|
|
10507
|
-
makespan:
|
|
10508
|
-
schedule:
|
|
10559
|
+
makespan: greedyMakespan,
|
|
10560
|
+
schedule: greedySchedule,
|
|
10509
10561
|
elapsedMs: elapsed(),
|
|
10510
10562
|
metadata: {
|
|
10511
10563
|
layers: LAYERS$1,
|
|
10512
10564
|
shots: 0,
|
|
10513
10565
|
gamma: 0,
|
|
10514
10566
|
beta: 0,
|
|
10515
|
-
rawMakespan:
|
|
10567
|
+
rawMakespan: greedyMakespan,
|
|
10516
10568
|
usedFallback: true
|
|
10517
10569
|
}
|
|
10518
|
-
};
|
|
10570
|
+
});
|
|
10519
10571
|
}
|
|
10520
10572
|
const ising = quboToIsing(encoded.qubo);
|
|
10521
10573
|
const backend = new LocalSimBackend();
|
|
@@ -10530,26 +10582,27 @@ const allSolvers = [
|
|
|
10530
10582
|
const { probabilities } = await backend.run(numQubits, gates);
|
|
10531
10583
|
const samples = sampleFromProbabilities(probabilities, FINAL_SHOTS$1);
|
|
10532
10584
|
progress(90);
|
|
10533
|
-
const candidates = [decodeFromArgmax(problem, encoded.variables, probabilities,
|
|
10585
|
+
const candidates = [decodeFromArgmax(problem, encoded.variables, probabilities, greedySchedule), decodeSamples(problem, encoded.variables, samples)].filter((d) => d !== null);
|
|
10534
10586
|
const bestQuantum = candidates.length > 0 ? candidates.reduce((a, b) => b.makespan < a.makespan ? b : a) : null;
|
|
10535
|
-
const usedFallback = bestQuantum === null || bestQuantum.makespan >=
|
|
10536
|
-
const
|
|
10587
|
+
const usedFallback = bestQuantum === null || bestQuantum.makespan >= greedyMakespan;
|
|
10588
|
+
const winnerMakespan = usedFallback ? greedyMakespan : bestQuantum.makespan;
|
|
10589
|
+
const winnerSchedule = usedFallback ? greedySchedule : bestQuantum.schedule;
|
|
10537
10590
|
progress(100);
|
|
10538
|
-
return {
|
|
10591
|
+
return makeSchedulingResult({
|
|
10539
10592
|
solverId: "qaoa-local",
|
|
10540
10593
|
solverName: "QAOA (Local)",
|
|
10541
|
-
makespan:
|
|
10542
|
-
schedule:
|
|
10594
|
+
makespan: winnerMakespan,
|
|
10595
|
+
schedule: winnerSchedule,
|
|
10543
10596
|
elapsedMs: elapsed(),
|
|
10544
10597
|
metadata: {
|
|
10545
10598
|
layers: LAYERS$1,
|
|
10546
10599
|
shots: FINAL_SHOTS$1,
|
|
10547
10600
|
gamma,
|
|
10548
10601
|
beta,
|
|
10549
|
-
rawMakespan: bestQuantum?.makespan ??
|
|
10602
|
+
rawMakespan: bestQuantum?.makespan ?? greedyMakespan,
|
|
10550
10603
|
usedFallback
|
|
10551
10604
|
}
|
|
10552
|
-
};
|
|
10605
|
+
});
|
|
10553
10606
|
}
|
|
10554
10607
|
}
|
|
10555
10608
|
];
|
|
@@ -11228,7 +11281,7 @@ function continuousToy() {
|
|
|
11228
11281
|
}
|
|
11229
11282
|
schedulingToy(), routingToy(), packingToy(), assignmentToy(), networkToy(), partitioningToy(), selectionToy(), economicToy(), continuousToy();
|
|
11230
11283
|
//#endregion
|
|
11231
|
-
//#region ../../b4m-core/services/dist/tools-
|
|
11284
|
+
//#region ../../b4m-core/services/dist/tools-B2RLL9dT.mjs
|
|
11232
11285
|
async function performDeepResearch(context, params, config = {}) {
|
|
11233
11286
|
const maxDepth = config.maxDepth || 7;
|
|
11234
11287
|
const duration = config.duration || 4.5;
|
|
@@ -12966,6 +13019,39 @@ async function getImageFromFileId(fileId, context) {
|
|
|
12966
13019
|
if (fabFile.fileUrl) return fabFile.fileUrl;
|
|
12967
13020
|
throw new Error(`File ${fileId} has no accessible URL`);
|
|
12968
13021
|
}
|
|
13022
|
+
/**
|
|
13023
|
+
* Resolve a generated-image storage key (the bare key persisted in
|
|
13024
|
+
* `quest.images`, e.g. "86cdc650-….jpg") to a downloadable URL.
|
|
13025
|
+
*
|
|
13026
|
+
* image_generation / edit_image upload their output to `imageGenerateStorage`
|
|
13027
|
+
* and persist only the bare key — no fabFile record is created — so a generated
|
|
13028
|
+
* image is NOT addressable as a fabFile ObjectId. Resolving it against the image
|
|
13029
|
+
* bucket is what lets a follow-up edit ("make it cartoonish") target a
|
|
13030
|
+
* previously generated image. The model learns these keys from the "Recently
|
|
13031
|
+
* generated images" system note assembled in ChatCompletionProcess.
|
|
13032
|
+
*/
|
|
13033
|
+
async function getGeneratedImageUrl(storageKey, context) {
|
|
13034
|
+
try {
|
|
13035
|
+
return await context.imageGenerateStorage.getSignedUrl(storageKey);
|
|
13036
|
+
} catch (error) {
|
|
13037
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
13038
|
+
throw new Error(`Could not resolve generated image "${storageKey}". Use the exact id from the "Recently generated images" system note, a fabFile ID from "Available Files", or a full URL. (${detail})`);
|
|
13039
|
+
}
|
|
13040
|
+
}
|
|
13041
|
+
/**
|
|
13042
|
+
* Resolve an image input (source or mask) to a downloadable URL. Accepts, in
|
|
13043
|
+
* priority order:
|
|
13044
|
+
* • an http(s)/data URL — passed straight through
|
|
13045
|
+
* • a fabFile ObjectId (24-char hex) — an uploaded image from "Available Files"
|
|
13046
|
+
* • otherwise a generated-image storage key (the bare key in quest.images,
|
|
13047
|
+
* e.g. "86cdc650-….jpg") — resolved against the image bucket
|
|
13048
|
+
* Source and mask share this so a generated-image key works for either.
|
|
13049
|
+
*/
|
|
13050
|
+
async function resolveImageInputUrl(input, context) {
|
|
13051
|
+
if (input.startsWith("http://") || input.startsWith("https://") || input.startsWith("data:")) return input;
|
|
13052
|
+
if (/^[0-9a-fA-F]{24}$/.test(input)) return getImageFromFileId(input, context);
|
|
13053
|
+
return getGeneratedImageUrl(input, context);
|
|
13054
|
+
}
|
|
12969
13055
|
async function processAndStoreImage(imageUrl, context) {
|
|
12970
13056
|
const buffer = await downloadImage(imageUrl);
|
|
12971
13057
|
const fileType = await fileTypeFromBuffer(buffer);
|
|
@@ -13039,17 +13125,9 @@ Please select a supported edit model in your image settings modal.`;
|
|
|
13039
13125
|
quality: imageConfig?.quality,
|
|
13040
13126
|
prompt
|
|
13041
13127
|
});
|
|
13042
|
-
|
|
13043
|
-
if (toolImage.startsWith("http://") || toolImage.startsWith("https://") || toolImage.startsWith("data:")) sourceImageUrl = toolImage;
|
|
13044
|
-
else sourceImageUrl = await getImageFromFileId(toolImage, context);
|
|
13045
|
-
const sourceBase64Image = await imageUrlToBase64(sourceImageUrl);
|
|
13128
|
+
const sourceBase64Image = await imageUrlToBase64(await resolveImageInputUrl(toolImage, context));
|
|
13046
13129
|
let maskBase64Image = null;
|
|
13047
|
-
if (toolMask)
|
|
13048
|
-
let maskImageUrl;
|
|
13049
|
-
if (toolMask.startsWith("http://") || toolMask.startsWith("https://") || toolMask.startsWith("data:")) maskImageUrl = toolMask;
|
|
13050
|
-
else maskImageUrl = await getImageFromFileId(toolMask, context);
|
|
13051
|
-
maskBase64Image = await imageUrlToBase64(maskImageUrl);
|
|
13052
|
-
}
|
|
13130
|
+
if (toolMask) maskBase64Image = await imageUrlToBase64(await resolveImageInputUrl(toolMask, context));
|
|
13053
13131
|
if (isBFLModel) {
|
|
13054
13132
|
const service = new BFLImageService(await (0, apiKeyService_exports.getEffectiveApiKey)(context.userId, { type: ApiKeyType.bfl }, { db: context.db }), context.logger, context.imageProcessorLambdaName);
|
|
13055
13133
|
let bflModel = editModel;
|
|
@@ -13143,13 +13221,13 @@ Please check your BFL API key in settings and ensure it is configured correctly.
|
|
|
13143
13221
|
},
|
|
13144
13222
|
toolSchema: {
|
|
13145
13223
|
name: "edit_image",
|
|
13146
|
-
description: "Edit an existing image based on a text prompt. Use this when the user wants to modify, change, edit, or transform an image they
|
|
13224
|
+
description: "Edit an existing image based on a text prompt. Use this when the user wants to modify, change, edit, or transform an image — whether they uploaded/attached it OR it was generated earlier in this conversation (e.g. \"make the previous image more cartoonish\", \"adjust the angle\"). Supports removing backgrounds, changing colors, adding/removing objects, and other visual modifications.",
|
|
13147
13225
|
parameters: {
|
|
13148
13226
|
type: "object",
|
|
13149
13227
|
properties: {
|
|
13150
13228
|
image: {
|
|
13151
13229
|
type: "string",
|
|
13152
|
-
description: "The
|
|
13230
|
+
description: "The image to edit. Provide one of: the exact id of a previously generated image from the \"Recently generated images\" system note (e.g. \"86cdc650-43d2-416e-aca6-23ff4fe23081.jpg\"); a fabFile ID of an uploaded image from the \"Available Files\" system message (e.g. \"67abc123def456\"); or a full http(s)/data URL."
|
|
13153
13231
|
},
|
|
13154
13232
|
prompt: {
|
|
13155
13233
|
type: "string",
|
|
@@ -13613,9 +13691,12 @@ const getWikipediaOnThisDay = async (parameters = {}) => {
|
|
|
13613
13691
|
try {
|
|
13614
13692
|
const { month, day } = parseMonthDay(date);
|
|
13615
13693
|
const url = `https://en.wikipedia.org/api/rest_v1/feed/onthisday/${type}/${month}/${day}`;
|
|
13694
|
+
const brand = process.env.APP_NAME || "";
|
|
13695
|
+
const websiteUrl = process.env.WEBSITE_URL || "";
|
|
13696
|
+
const userAgent = brand ? `${brand}/1.0${websiteUrl ? ` (${websiteUrl})` : ""}` : "App/1.0";
|
|
13616
13697
|
const response = await fetch(url, { headers: {
|
|
13617
13698
|
Accept: "application/json",
|
|
13618
|
-
"User-Agent":
|
|
13699
|
+
"User-Agent": userAgent
|
|
13619
13700
|
} });
|
|
13620
13701
|
if (!response.ok) {
|
|
13621
13702
|
if (response.status === 404) throw new Error(`No data available for ${month}-${day}. The date may be invalid.`);
|
|
@@ -15229,13 +15310,13 @@ const knowledgeBaseRetrieveTool = {
|
|
|
15229
15310
|
function formatResult$1(result) {
|
|
15230
15311
|
const lines = [
|
|
15231
15312
|
`Solver: ${result.solverName} (${result.solverId})`,
|
|
15232
|
-
`Makespan: ${result.
|
|
15313
|
+
`Makespan: ${result.objective}`,
|
|
15233
15314
|
`Elapsed: ${result.elapsedMs.toFixed(1)}ms`
|
|
15234
15315
|
];
|
|
15235
15316
|
if (result.iterations !== void 0) lines.push(`Iterations: ${result.iterations}`);
|
|
15236
15317
|
lines.push("Schedule:");
|
|
15237
15318
|
const byMachine = /* @__PURE__ */ new Map();
|
|
15238
|
-
for (const op of result.
|
|
15319
|
+
for (const op of result.solution) {
|
|
15239
15320
|
if (!byMachine.has(op.machineId)) byMachine.set(op.machineId, []);
|
|
15240
15321
|
byMachine.get(op.machineId).push(op);
|
|
15241
15322
|
}
|
|
@@ -15272,13 +15353,13 @@ async function runQuantumSchedule(params) {
|
|
|
15272
15353
|
}
|
|
15273
15354
|
}
|
|
15274
15355
|
if (results.length === 0) return `Error: No solvers completed successfully.\n${errors.join("\n")}`;
|
|
15275
|
-
results.sort((a, b) => a.
|
|
15356
|
+
results.sort((a, b) => a.objective - b.objective);
|
|
15276
15357
|
const lines = [];
|
|
15277
15358
|
lines.push(`## Scheduling Results for "${problem.name}"`);
|
|
15278
15359
|
lines.push(`Problem: ${problem.jobs.length} jobs, ${problem.machines.length} machines, ${problem.jobs.reduce((s, j) => s + j.operations.length, 0)} operations`);
|
|
15279
15360
|
lines.push("");
|
|
15280
15361
|
if (results.length > 1) {
|
|
15281
|
-
lines.push(`### Winner: ${results[0].solverName} (makespan: ${results[0].
|
|
15362
|
+
lines.push(`### Winner: ${results[0].solverName} (makespan: ${results[0].objective})`);
|
|
15282
15363
|
lines.push("");
|
|
15283
15364
|
}
|
|
15284
15365
|
for (const result of results) {
|
|
@@ -16053,7 +16134,8 @@ function applyCellStyle(cell, style) {
|
|
|
16053
16134
|
*/
|
|
16054
16135
|
async function generateExcel(params) {
|
|
16055
16136
|
const workbook = new ExcelJS.Workbook();
|
|
16056
|
-
|
|
16137
|
+
const brand = process.env.APP_NAME || "";
|
|
16138
|
+
workbook.creator = brand ? `${brand} AI` : "AI";
|
|
16057
16139
|
workbook.created = /* @__PURE__ */ new Date();
|
|
16058
16140
|
for (const sheetData of params.sheets) {
|
|
16059
16141
|
const worksheet = workbook.addWorksheet(sheetData.name.slice(0, LIMITS.MAX_SHEET_NAME_LENGTH));
|
|
@@ -16118,7 +16200,18 @@ const excelGenerationTool = {
|
|
|
16118
16200
|
},
|
|
16119
16201
|
toolSchema: {
|
|
16120
16202
|
name: "excel_generation",
|
|
16121
|
-
description: `Generate Excel (.xlsx)
|
|
16203
|
+
description: `Generate a well-formed Excel (.xlsx) workbook. Supports: multiple sheets, formulas (SUM, AVERAGE, IF, VLOOKUP, etc.; only a safe whitelisted subset), styling (bold, colors, borders), number formats, merged cells, frozen panes.
|
|
16204
|
+
|
|
16205
|
+
HARD LIMITS (the request is REJECTED if any are exceeded, not truncated, so data is never silently dropped):
|
|
16206
|
+
- At most ${LIMITS.MAX_SHEETS} sheets per workbook.
|
|
16207
|
+
- At most ${LIMITS.MAX_CELLS_PER_SHEET} populated cells per sheet (count the cell objects you pass in "data", not the grid area).
|
|
16208
|
+
- Row numbers 1-${LIMITS.MAX_ROW} and column numbers 1-${LIMITS.MAX_COL} only.
|
|
16209
|
+
- Sheet names: 1-${LIMITS.MAX_SHEET_NAME_LENGTH} characters.
|
|
16210
|
+
- Formulas may only use whitelisted functions; volatile/external ones (HYPERLINK, WEBSERVICE, CMD, etc.) are blocked.
|
|
16211
|
+
|
|
16212
|
+
Addressing is 1-indexed numeric row/col (row 1, col 1 = cell A1); do NOT pass A1-style strings. Provide only the cells you want populated; empty cells need no entry.
|
|
16213
|
+
|
|
16214
|
+
Before calling: if the user's request would exceed any limit (e.g. a dataset larger than ${LIMITS.MAX_CELLS_PER_SHEET} cells or more than ${LIMITS.MAX_SHEETS} sheets), do not promise the full result; tell the user what you can deliver within these limits and either split the data across sheets/files or summarize. Only commit to what this tool can actually produce.`,
|
|
16122
16215
|
parameters: {
|
|
16123
16216
|
type: "object",
|
|
16124
16217
|
properties: {
|
|
@@ -17695,7 +17788,7 @@ var mfaService_exports$1 = /* @__PURE__ */ __exportAll$3({
|
|
|
17695
17788
|
* This generates the secret and backup codes but doesn't enable MFA yet
|
|
17696
17789
|
* The user must verify the setup before MFA is enabled
|
|
17697
17790
|
*/
|
|
17698
|
-
async function setupMFA({ user, appName = "
|
|
17791
|
+
async function setupMFA({ user, appName = process.env.APP_NAME || "" }, userRepository) {
|
|
17699
17792
|
if (!userEligibleForMFA(user)) throw new Error("User is not eligible for MFA setup.");
|
|
17700
17793
|
if (user.mfa && user.mfa.totpEnabled) throw new Error("MFA is already enabled for this user.");
|
|
17701
17794
|
if (user.mfa && user.mfa.totpEnabled === false) user.mfa = null;
|
|
@@ -17725,7 +17818,7 @@ async function setupMFA({ user, appName = "Bike4Mind" }, userRepository) {
|
|
|
17725
17818
|
async function verifyMFASetup(user, token, userRepository) {
|
|
17726
17819
|
if (!user.mfa || !user.mfa.totpSecret) throw new Error("No MFA setup in progress for this user.");
|
|
17727
17820
|
if (user.mfa.totpEnabled) throw new Error("MFA is already enabled for this user.");
|
|
17728
|
-
const { verifyTOTPToken } = await import("./utils-
|
|
17821
|
+
const { verifyTOTPToken } = await import("./utils-CLjLKvqQ.mjs");
|
|
17729
17822
|
if (!verifyTOTPToken(user.mfa.totpSecret, token)) throw new Error("Invalid TOTP code.");
|
|
17730
17823
|
const updatedMFA = { ...user.mfa };
|
|
17731
17824
|
updatedMFA.totpEnabled = true;
|
|
@@ -20146,6 +20239,7 @@ z.object({
|
|
|
20146
20239
|
surface: z.string().optional(),
|
|
20147
20240
|
enabledTools: z.array(z.string()).optional(),
|
|
20148
20241
|
disabledTools: z.array(z.string()).optional(),
|
|
20242
|
+
disableUserIntegrations: z.boolean().optional(),
|
|
20149
20243
|
forceKnowledgeRetrieval: z.boolean().optional(),
|
|
20150
20244
|
retrievalTags: z.array(z.string()).optional(),
|
|
20151
20245
|
citationStyle: z.enum(["named", "indexed"]).optional(),
|
|
@@ -20160,8 +20254,7 @@ z.object({
|
|
|
20160
20254
|
clonedSourceId: z.string().optional().nullable(),
|
|
20161
20255
|
forkedSourceId: z.string().optional().nullable(),
|
|
20162
20256
|
projectId: z.string().optional(),
|
|
20163
|
-
lastUsedModel: z.string().optional().nullable()
|
|
20164
|
-
optiHashi: z.boolean().optional()
|
|
20257
|
+
lastUsedModel: z.string().optional().nullable()
|
|
20165
20258
|
});
|
|
20166
20259
|
z.object({ id: z.string() });
|
|
20167
20260
|
z.object({ id: z.string() });
|