@bike4mind/cli 0.2.28-slack-native-search.18717 → 0.2.28
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-75EEGBLM.js → artifactExtractor-36XHJYOZ.js} +1 -1
- package/dist/{chunk-5VZSKEEG.js → chunk-JJBDHUGY.js} +2 -2
- package/dist/{chunk-JQOZTED2.js → chunk-UNOJBVD2.js} +96 -121
- package/dist/{chunk-YY4HHPYV.js → chunk-VGYTNJXN.js} +2 -2
- package/dist/{chunk-F3HPUK2I.js → chunk-XJRPAAUS.js} +342 -9
- package/dist/{chunk-5ZYPV3TT.js → chunk-ZEMWV6IR.js} +2 -2
- package/dist/{create-JY3A3VKV.js → create-NGI7IIQ4.js} +3 -3
- package/dist/index.js +385 -270
- package/dist/{llmMarkdownGenerator-CXBTJVHZ.js → llmMarkdownGenerator-JDYKJUEC.js} +1 -1
- package/dist/{markdownGenerator-P5HR3BBR.js → markdownGenerator-QXBC2EW5.js} +1 -1
- package/dist/{mementoService-6XGTK6H6.js → mementoService-X35OMHVC.js} +3 -3
- package/dist/{src-ZA4LU3XB.js → src-6NIYIWZD.js} +15 -1
- package/dist/{src-LZQJBWV3.js → src-CBU6EAO3.js} +2 -2
- package/dist/{subtractCredits-NN6GZFZY.js → subtractCredits-RL6JVDMI.js} +3 -3
- package/package.json +7 -7
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-VGYTNJXN.js";
|
|
9
9
|
import {
|
|
10
10
|
ConfigStore
|
|
11
11
|
} from "./chunk-23T2XGSZ.js";
|
|
@@ -13,8 +13,8 @@ import {
|
|
|
13
13
|
selectActiveBackgroundAgents,
|
|
14
14
|
useCliStore
|
|
15
15
|
} from "./chunk-TVW4ZESU.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-JJBDHUGY.js";
|
|
17
|
+
import "./chunk-ZEMWV6IR.js";
|
|
18
18
|
import {
|
|
19
19
|
BFLImageService,
|
|
20
20
|
BaseStorage,
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
OpenAIBackend,
|
|
27
27
|
OpenAIImageService,
|
|
28
28
|
XAIImageService
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-UNOJBVD2.js";
|
|
30
30
|
import {
|
|
31
31
|
AiEvents,
|
|
32
32
|
ApiKeyEvents,
|
|
@@ -82,7 +82,7 @@ import {
|
|
|
82
82
|
XAI_IMAGE_MODELS,
|
|
83
83
|
b4mLLMTools,
|
|
84
84
|
getMcpProviderMetadata
|
|
85
|
-
} from "./chunk-
|
|
85
|
+
} from "./chunk-XJRPAAUS.js";
|
|
86
86
|
import {
|
|
87
87
|
Logger
|
|
88
88
|
} from "./chunk-OCYRD7D6.js";
|
|
@@ -6080,7 +6080,10 @@ var imageGenerationTool = {
|
|
|
6080
6080
|
return "Error: Image configuration is required";
|
|
6081
6081
|
}
|
|
6082
6082
|
const { prompt, n: toolN, quality: toolQuality, size: toolSize, safety_tolerance: toolSafetyTolerance } = val;
|
|
6083
|
-
|
|
6083
|
+
let model = imageConfig?.model || ImageModels.GPT_IMAGE_1_5;
|
|
6084
|
+
if (model === ImageModels.GPT_IMAGE_1) {
|
|
6085
|
+
model = ImageModels.GPT_IMAGE_1_5;
|
|
6086
|
+
}
|
|
6084
6087
|
const n = toolN ?? imageConfig?.n ?? 1;
|
|
6085
6088
|
const quality = imageConfig?.quality || toolQuality;
|
|
6086
6089
|
const size = imageConfig?.size || toolSize;
|
|
@@ -7331,6 +7334,14 @@ Return only the edited content without any markdown code blocks or explanations.
|
|
|
7331
7334
|
import axios7 from "axios";
|
|
7332
7335
|
import { fileTypeFromBuffer as fileTypeFromBuffer3 } from "file-type";
|
|
7333
7336
|
import { v4 as uuidv46 } from "uuid";
|
|
7337
|
+
var EDIT_SUPPORTED_MODELS = [
|
|
7338
|
+
ImageModels.GPT_IMAGE_1,
|
|
7339
|
+
ImageModels.GPT_IMAGE_1_5,
|
|
7340
|
+
ImageModels.GPT_IMAGE_1_MINI,
|
|
7341
|
+
ImageModels.FLUX_PRO_FILL,
|
|
7342
|
+
ImageModels.GEMINI_2_5_FLASH_IMAGE,
|
|
7343
|
+
ImageModels.GEMINI_3_PRO_IMAGE_PREVIEW
|
|
7344
|
+
];
|
|
7334
7345
|
async function downloadImage2(url) {
|
|
7335
7346
|
if (url.startsWith("data:image/")) {
|
|
7336
7347
|
const base64Data = url.split(",")[1];
|
|
@@ -7355,7 +7366,7 @@ async function imageUrlToBase64(imageUrl) {
|
|
|
7355
7366
|
return buffer.toString("base64");
|
|
7356
7367
|
}
|
|
7357
7368
|
async function getImageFromFileId(fileId, context) {
|
|
7358
|
-
const fabFile = await context.db.
|
|
7369
|
+
const fabFile = await context.db.fabfiles?.findById(fileId);
|
|
7359
7370
|
if (!fabFile) {
|
|
7360
7371
|
throw new NotFoundError(`File with ID ${fileId} not found`);
|
|
7361
7372
|
}
|
|
@@ -7378,6 +7389,24 @@ async function processAndStoreImage(imageUrl, context) {
|
|
|
7378
7389
|
const path18 = await context.imageGenerateStorage.upload(buffer, filename, {});
|
|
7379
7390
|
return path18;
|
|
7380
7391
|
}
|
|
7392
|
+
async function generateFullMask(imageBuffer) {
|
|
7393
|
+
const sharp = (await import("sharp")).default;
|
|
7394
|
+
const metadata = await sharp(imageBuffer).metadata();
|
|
7395
|
+
const width = metadata.width;
|
|
7396
|
+
const height = metadata.height;
|
|
7397
|
+
const maskData = Buffer.alloc(width * height * 4);
|
|
7398
|
+
for (let i = 0; i < maskData.length; i++) {
|
|
7399
|
+
maskData[i] = 255;
|
|
7400
|
+
}
|
|
7401
|
+
const maskBuffer = await sharp(maskData, {
|
|
7402
|
+
raw: {
|
|
7403
|
+
width,
|
|
7404
|
+
height,
|
|
7405
|
+
channels: 4
|
|
7406
|
+
}
|
|
7407
|
+
}).png().toBuffer();
|
|
7408
|
+
return maskBuffer.toString("base64");
|
|
7409
|
+
}
|
|
7381
7410
|
async function updateQuestAndReturnMarkdown2(storedImagePath, context) {
|
|
7382
7411
|
await context.onFinish?.("edit_image", storedImagePath);
|
|
7383
7412
|
await context.statusUpdate({ images: [storedImagePath] });
|
|
@@ -7389,14 +7418,32 @@ var imageEditTool = {
|
|
|
7389
7418
|
toolFn: async (val) => {
|
|
7390
7419
|
const imageConfig = config;
|
|
7391
7420
|
const { image: toolImage, prompt, mask: toolMask, n: toolN, size: toolSize, safety_tolerance: toolSafetyTolerance, steps: toolSteps, guidance: toolGuidance } = val;
|
|
7392
|
-
console.log(toolImage, "Image to edit");
|
|
7393
7421
|
if (!toolImage) {
|
|
7394
7422
|
return "Error: Image is required for editing";
|
|
7395
7423
|
}
|
|
7396
7424
|
if (!prompt) {
|
|
7397
7425
|
return "Error: Prompt is required for editing";
|
|
7398
7426
|
}
|
|
7399
|
-
const
|
|
7427
|
+
const generationModel = imageConfig?.model || ImageModels.GPT_IMAGE_1_5;
|
|
7428
|
+
let editModel = imageConfig?.editModel;
|
|
7429
|
+
if (!editModel) {
|
|
7430
|
+
const isGenBFLModel = BFL_IMAGE_MODELS.includes(generationModel);
|
|
7431
|
+
const isGenGeminiModel = GEMINI_IMAGE_MODELS.includes(generationModel);
|
|
7432
|
+
if (isGenBFLModel) {
|
|
7433
|
+
editModel = ImageModels.FLUX_PRO_FILL;
|
|
7434
|
+
} else if (isGenGeminiModel) {
|
|
7435
|
+
editModel = generationModel;
|
|
7436
|
+
} else {
|
|
7437
|
+
editModel = ImageModels.GPT_IMAGE_1_5;
|
|
7438
|
+
}
|
|
7439
|
+
console.log(`[DEBUG] No edit model specified, using fallback: ${editModel} (based on generation model: ${generationModel})`);
|
|
7440
|
+
}
|
|
7441
|
+
if (!EDIT_SUPPORTED_MODELS.includes(editModel)) {
|
|
7442
|
+
return `Error: Model ${editModel} does not support image editing. Supported models for editing: ${EDIT_SUPPORTED_MODELS.join(", ")}.
|
|
7443
|
+
|
|
7444
|
+
Please select a supported edit model in your image settings modal.`;
|
|
7445
|
+
}
|
|
7446
|
+
const model = generationModel;
|
|
7400
7447
|
const n = toolN ?? imageConfig?.n ?? 1;
|
|
7401
7448
|
const size = imageConfig?.size || toolSize;
|
|
7402
7449
|
const safety_tolerance = imageConfig?.safety_tolerance || toolSafetyTolerance;
|
|
@@ -7405,8 +7452,8 @@ var imageEditTool = {
|
|
|
7405
7452
|
const seed = imageConfig?.seed;
|
|
7406
7453
|
const steps = toolSteps || 50;
|
|
7407
7454
|
const guidance = toolGuidance || 60;
|
|
7408
|
-
const isBFLModel = BFL_IMAGE_MODELS.includes(
|
|
7409
|
-
const isGeminiModel = GEMINI_IMAGE_MODELS.includes(
|
|
7455
|
+
const isBFLModel = BFL_IMAGE_MODELS.includes(editModel);
|
|
7456
|
+
const isGeminiModel = GEMINI_IMAGE_MODELS.includes(editModel);
|
|
7410
7457
|
await context.onStart?.("edit_image", {
|
|
7411
7458
|
model,
|
|
7412
7459
|
n,
|
|
@@ -7433,67 +7480,135 @@ var imageEditTool = {
|
|
|
7433
7480
|
}
|
|
7434
7481
|
if (isBFLModel) {
|
|
7435
7482
|
const apiKey = await getEffectiveApiKey(context.userId, { type: ApiKeyType.bfl }, { db: context.db });
|
|
7436
|
-
const service = new BFLImageService(apiKey, context.logger);
|
|
7437
|
-
|
|
7483
|
+
const service = new BFLImageService(apiKey, context.logger, context.imageProcessorLambdaName);
|
|
7484
|
+
let bflModel = editModel;
|
|
7485
|
+
if (bflModel !== ImageModels.FLUX_PRO_FILL) {
|
|
7486
|
+
console.warn(`[WARN] BFL edit model ${bflModel} does not support editing. Falling back to FLUX_PRO_FILL.`);
|
|
7487
|
+
bflModel = ImageModels.FLUX_PRO_FILL;
|
|
7488
|
+
}
|
|
7438
7489
|
if (!maskBase64Image) {
|
|
7439
|
-
|
|
7490
|
+
const sourceBuffer = Buffer.from(sourceBase64Image, "base64");
|
|
7491
|
+
maskBase64Image = await generateFullMask(sourceBuffer);
|
|
7440
7492
|
}
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
|
|
7447
|
-
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7493
|
+
try {
|
|
7494
|
+
const editResponse = await service.edit(sourceBase64Image, prompt, {
|
|
7495
|
+
mask: maskBase64Image,
|
|
7496
|
+
model: bflModel,
|
|
7497
|
+
safety_tolerance: safety_tolerance ?? BFL_SAFETY_TOLERANCE.DEFAULT,
|
|
7498
|
+
prompt_upsampling,
|
|
7499
|
+
seed: seed ?? void 0,
|
|
7500
|
+
output_format: output_format ?? "jpeg",
|
|
7501
|
+
steps,
|
|
7502
|
+
guidance
|
|
7503
|
+
});
|
|
7504
|
+
if (editResponse.type === "success") {
|
|
7505
|
+
const storedImagePath = await processAndStoreImage(editResponse.dataUrl, context);
|
|
7506
|
+
return updateQuestAndReturnMarkdown2(storedImagePath, context);
|
|
7507
|
+
}
|
|
7508
|
+
return `Error: ${"question" in editResponse ? editResponse.question : "Failed to edit image"}`;
|
|
7509
|
+
} catch (error) {
|
|
7510
|
+
console.error("[ERROR] BFL image editing failed:", error);
|
|
7511
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
7512
|
+
if (axios7.isAxiosError(error)) {
|
|
7513
|
+
const status = error.response?.status;
|
|
7514
|
+
const responseData = error.response?.data;
|
|
7515
|
+
if (status === 403) {
|
|
7516
|
+
return `Error: BFL API access denied (403). This usually means:
|
|
7517
|
+
- Your BFL API key is not set, invalid, or expired
|
|
7518
|
+
- Your BFL account lacks permissions for FLUX-PRO-FILL
|
|
7519
|
+
- Your BFL API credits have run out
|
|
7520
|
+
|
|
7521
|
+
Please check your BFL API key in settings and ensure it is configured correctly.`;
|
|
7522
|
+
} else if (status === 429) {
|
|
7523
|
+
return `Error: BFL API rate limit exceeded (429). Please wait a moment and try again.`;
|
|
7524
|
+
} else if (status === 402) {
|
|
7525
|
+
return `Error: BFL API payment required (402). Please add credits to your BFL account.`;
|
|
7526
|
+
} else if (responseData?.error) {
|
|
7527
|
+
return `Error: BFL API error - ${responseData.error}`;
|
|
7528
|
+
}
|
|
7529
|
+
}
|
|
7530
|
+
return `Error: Failed to edit image with FLUX-PRO-FILL. ${errorMessage}. Please try a different edit model like GPT-Image-1.5 or Gemini.`;
|
|
7454
7531
|
}
|
|
7455
|
-
return `Error: ${"question" in editResponse ? editResponse.question : "Failed to edit image"}`;
|
|
7456
7532
|
} else if (isGeminiModel) {
|
|
7457
7533
|
const apiKey = await getEffectiveApiKey(context.userId, { type: ApiKeyType.gemini }, { db: context.db });
|
|
7458
|
-
const service = new GeminiImageService(apiKey, context.logger);
|
|
7534
|
+
const service = new GeminiImageService(apiKey, context.logger, context.imageProcessorLambdaName);
|
|
7459
7535
|
const dataUrlImage = sourceBase64Image.startsWith("data:") ? sourceBase64Image : `data:image/png;base64,${sourceBase64Image}`;
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
7463
|
-
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
|
|
7536
|
+
try {
|
|
7537
|
+
const editResponse = await service.edit(dataUrlImage, prompt, {
|
|
7538
|
+
aspect_ratio: imageConfig?.aspect_ratio,
|
|
7539
|
+
output_format: output_format ?? "png",
|
|
7540
|
+
safety_tolerance,
|
|
7541
|
+
model: editModel
|
|
7542
|
+
// Pass edit model to service
|
|
7543
|
+
});
|
|
7544
|
+
if (editResponse.type === "success") {
|
|
7545
|
+
const storedImagePath = await processAndStoreImage(editResponse.dataUrl, context);
|
|
7546
|
+
return updateQuestAndReturnMarkdown2(storedImagePath, context);
|
|
7547
|
+
}
|
|
7548
|
+
return `Error: ${"question" in editResponse ? editResponse.question : "Failed to edit image"}`;
|
|
7549
|
+
} catch (error) {
|
|
7550
|
+
console.error("[ERROR] Gemini image editing failed:", error);
|
|
7551
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
7552
|
+
if (axios7.isAxiosError(error)) {
|
|
7553
|
+
const status = error.response?.status;
|
|
7554
|
+
const responseData = error.response?.data;
|
|
7555
|
+
if (status === 403 || status === 401) {
|
|
7556
|
+
return `Error: Gemini API access denied (${status}). Your Gemini API key may be missing, invalid, or expired. Please check your Gemini API key in settings.`;
|
|
7557
|
+
} else if (status === 429) {
|
|
7558
|
+
return `Error: Gemini API rate limit exceeded (429). Please wait a moment and try again.`;
|
|
7559
|
+
} else if (responseData?.error) {
|
|
7560
|
+
return `Error: Gemini API error - ${JSON.stringify(responseData.error)}`;
|
|
7561
|
+
}
|
|
7562
|
+
}
|
|
7563
|
+
return `Error: Failed to edit image with Gemini. ${errorMessage}. Please try a different edit model like GPT-Image-1.5.`;
|
|
7468
7564
|
}
|
|
7469
|
-
return `Error: ${"question" in editResponse ? editResponse.question : "Failed to edit image"}`;
|
|
7470
7565
|
} else {
|
|
7471
7566
|
const apiKey = await getEffectiveApiKey(context.userId, { type: ApiKeyType.openai }, { db: context.db });
|
|
7472
|
-
const service = new OpenAIImageService(apiKey, context.logger);
|
|
7473
|
-
|
|
7474
|
-
|
|
7475
|
-
|
|
7476
|
-
|
|
7477
|
-
|
|
7478
|
-
|
|
7479
|
-
|
|
7480
|
-
|
|
7481
|
-
|
|
7482
|
-
|
|
7483
|
-
|
|
7567
|
+
const service = new OpenAIImageService(apiKey, context.logger, context.imageProcessorLambdaName);
|
|
7568
|
+
try {
|
|
7569
|
+
const editResponse = await service.edit(sourceBase64Image, prompt, {
|
|
7570
|
+
mask: maskBase64Image,
|
|
7571
|
+
model: editModel,
|
|
7572
|
+
// Use the configured edit model
|
|
7573
|
+
n,
|
|
7574
|
+
size,
|
|
7575
|
+
response_format: "url",
|
|
7576
|
+
user: context.userId
|
|
7577
|
+
});
|
|
7578
|
+
if (editResponse.type === "success") {
|
|
7579
|
+
const storedImagePath = await processAndStoreImage(editResponse.dataUrl, context);
|
|
7580
|
+
return updateQuestAndReturnMarkdown2(storedImagePath, context);
|
|
7581
|
+
}
|
|
7582
|
+
return `Error: ${"question" in editResponse ? editResponse.question : "Failed to edit image"}`;
|
|
7583
|
+
} catch (error) {
|
|
7584
|
+
console.error("[ERROR] OpenAI image editing failed:", error);
|
|
7585
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
7586
|
+
if (axios7.isAxiosError(error)) {
|
|
7587
|
+
const status = error.response?.status;
|
|
7588
|
+
const responseData = error.response?.data;
|
|
7589
|
+
if (status === 403 || status === 401) {
|
|
7590
|
+
return `Error: OpenAI API access denied (${status}). Your OpenAI API key may be missing, invalid, or expired. Please check your OpenAI API key in settings.`;
|
|
7591
|
+
} else if (status === 429) {
|
|
7592
|
+
return `Error: OpenAI API rate limit exceeded (429). Please wait a moment and try again.`;
|
|
7593
|
+
} else if (status === 402) {
|
|
7594
|
+
return `Error: OpenAI API payment required (402). Please add credits to your OpenAI account.`;
|
|
7595
|
+
} else if (responseData?.error) {
|
|
7596
|
+
return `Error: OpenAI API error - ${responseData.error.message || JSON.stringify(responseData.error)}`;
|
|
7597
|
+
}
|
|
7598
|
+
}
|
|
7599
|
+
return `Error: Failed to edit image with OpenAI. ${errorMessage}. Please try again or use a different edit model.`;
|
|
7484
7600
|
}
|
|
7485
|
-
return `Error: ${"question" in editResponse ? editResponse.question : "Failed to edit image"}`;
|
|
7486
7601
|
}
|
|
7487
7602
|
},
|
|
7488
7603
|
toolSchema: {
|
|
7489
7604
|
name: "edit_image",
|
|
7490
|
-
description: "Edit an existing image based on a prompt.
|
|
7605
|
+
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 have uploaded or attached to the conversation. Supports removing backgrounds, changing colors, adding/removing objects, and other visual modifications.",
|
|
7491
7606
|
parameters: {
|
|
7492
7607
|
type: "object",
|
|
7493
7608
|
properties: {
|
|
7494
7609
|
image: {
|
|
7495
7610
|
type: "string",
|
|
7496
|
-
description:
|
|
7611
|
+
description: 'The file ID of the image to edit (e.g., "67abc123def456"). Look for image file IDs in the "Available Files" system message. You can also use an S3 URL or data URL if provided by the user.'
|
|
7497
7612
|
},
|
|
7498
7613
|
prompt: {
|
|
7499
7614
|
type: "string",
|
|
@@ -10716,7 +10831,7 @@ var cliOnlyTools = {
|
|
|
10716
10831
|
// Git operations
|
|
10717
10832
|
recent_changes: recentChangesTool
|
|
10718
10833
|
};
|
|
10719
|
-
var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorage, statusUpdate, onStart, onFinish, llm, config, model, tools = b4mTools) => {
|
|
10834
|
+
var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorage, statusUpdate, onStart, onFinish, llm, config, model, imageProcessorLambdaName, tools = b4mTools) => {
|
|
10720
10835
|
const context = {
|
|
10721
10836
|
userId,
|
|
10722
10837
|
user,
|
|
@@ -10728,7 +10843,8 @@ var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorag
|
|
|
10728
10843
|
onStart,
|
|
10729
10844
|
onFinish,
|
|
10730
10845
|
llm,
|
|
10731
|
-
model
|
|
10846
|
+
model,
|
|
10847
|
+
imageProcessorLambdaName
|
|
10732
10848
|
};
|
|
10733
10849
|
return Object.entries(tools).reduce((acc, [key, tool]) => ({
|
|
10734
10850
|
...acc,
|
|
@@ -12062,6 +12178,8 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
|
|
|
12062
12178
|
llm,
|
|
12063
12179
|
{},
|
|
12064
12180
|
model,
|
|
12181
|
+
void 0,
|
|
12182
|
+
// imageProcessorLambdaName (not needed for CLI)
|
|
12065
12183
|
tools_to_generate
|
|
12066
12184
|
);
|
|
12067
12185
|
let tools = Object.entries(toolsMap).map(
|
|
@@ -13208,227 +13326,220 @@ var ServerLlmBackend = class {
|
|
|
13208
13326
|
logger.debug("[ServerLlmBackend] Request aborted before start");
|
|
13209
13327
|
return;
|
|
13210
13328
|
}
|
|
13211
|
-
|
|
13212
|
-
|
|
13213
|
-
|
|
13214
|
-
|
|
13215
|
-
|
|
13216
|
-
|
|
13217
|
-
|
|
13218
|
-
|
|
13219
|
-
|
|
13220
|
-
|
|
13221
|
-
|
|
13222
|
-
|
|
13223
|
-
|
|
13224
|
-
|
|
13225
|
-
|
|
13226
|
-
|
|
13227
|
-
|
|
13228
|
-
|
|
13229
|
-
|
|
13230
|
-
|
|
13231
|
-
|
|
13232
|
-
|
|
13233
|
-
|
|
13234
|
-
|
|
13235
|
-
|
|
13236
|
-
|
|
13237
|
-
|
|
13238
|
-
|
|
13239
|
-
|
|
13240
|
-
|
|
13241
|
-
|
|
13242
|
-
|
|
13243
|
-
|
|
13244
|
-
)
|
|
13245
|
-
|
|
13246
|
-
|
|
13247
|
-
reject(err);
|
|
13248
|
-
}).then(() => {
|
|
13249
|
-
logger.debug("[ServerLlmBackend] Callback completed, resolving");
|
|
13250
|
-
resolve3();
|
|
13251
|
-
});
|
|
13252
|
-
} else if (cleanedText) {
|
|
13253
|
-
callback([cleanedText], lastUsageInfo).catch((err) => {
|
|
13254
|
-
logger.error("[ServerLlmBackend] Callback error:", err);
|
|
13255
|
-
reject(err);
|
|
13256
|
-
}).then(() => resolve3());
|
|
13257
|
-
} else {
|
|
13258
|
-
resolve3();
|
|
13329
|
+
logger.debug("[ServerLlmBackend] Making streaming request...");
|
|
13330
|
+
let response;
|
|
13331
|
+
try {
|
|
13332
|
+
response = await this.makeStreamingRequest(model, messages, options);
|
|
13333
|
+
} catch (error) {
|
|
13334
|
+
if (options.abortSignal?.aborted) {
|
|
13335
|
+
logger.debug("[ServerLlmBackend] Request was aborted, resolving gracefully");
|
|
13336
|
+
return;
|
|
13337
|
+
}
|
|
13338
|
+
if (isAxiosError(error) && error.code === "ERR_CANCELED") {
|
|
13339
|
+
logger.debug("[ServerLlmBackend] Request was canceled, resolving gracefully");
|
|
13340
|
+
return;
|
|
13341
|
+
}
|
|
13342
|
+
logger.error("LLM completion failed", error);
|
|
13343
|
+
if (isAxiosError(error)) {
|
|
13344
|
+
logger.debug(
|
|
13345
|
+
`[ServerLlmBackend] Axios error details: ${JSON.stringify({
|
|
13346
|
+
status: error.response?.status,
|
|
13347
|
+
statusText: error.response?.statusText,
|
|
13348
|
+
url: error.config?.url,
|
|
13349
|
+
method: error.config?.method
|
|
13350
|
+
})}`
|
|
13351
|
+
);
|
|
13352
|
+
if (error.response?.status === 403 && error.response.data) {
|
|
13353
|
+
let errorDetails = "";
|
|
13354
|
+
try {
|
|
13355
|
+
let responseText = "";
|
|
13356
|
+
const stream = error.response.data;
|
|
13357
|
+
if (Buffer.isBuffer(stream)) {
|
|
13358
|
+
responseText = stream.toString("utf-8");
|
|
13359
|
+
} else if (stream?._readableState?.buffer?.length > 0) {
|
|
13360
|
+
const chunks = [];
|
|
13361
|
+
for (const chunk of stream._readableState.buffer) {
|
|
13362
|
+
if (chunk?.data) {
|
|
13363
|
+
chunks.push(Buffer.from(chunk.data));
|
|
13364
|
+
}
|
|
13259
13365
|
}
|
|
13260
|
-
|
|
13366
|
+
responseText = Buffer.concat(chunks).toString("utf-8");
|
|
13367
|
+
} else if (typeof stream === "string") {
|
|
13368
|
+
responseText = stream;
|
|
13261
13369
|
}
|
|
13262
|
-
|
|
13263
|
-
|
|
13264
|
-
|
|
13265
|
-
|
|
13266
|
-
|
|
13267
|
-
|
|
13268
|
-
}
|
|
13269
|
-
|
|
13270
|
-
const textChunk = parsed.text || "";
|
|
13271
|
-
accumulatedText += textChunk;
|
|
13272
|
-
if (parsed.usage) {
|
|
13273
|
-
lastUsageInfo = {
|
|
13274
|
-
inputTokens: parsed.usage.inputTokens,
|
|
13275
|
-
outputTokens: parsed.usage.outputTokens
|
|
13276
|
-
};
|
|
13277
|
-
}
|
|
13278
|
-
streamLogger.onContent(eventCount, textChunk, accumulatedText);
|
|
13279
|
-
} else if (parsed.type === "tool_use") {
|
|
13280
|
-
streamLogger.onCriticalEvent(eventCount, "TOOL_USE", `tools: ${parsed.tools?.length}`);
|
|
13281
|
-
if (parsed.tools && parsed.tools.length > 0) {
|
|
13282
|
-
for (const tool of parsed.tools) {
|
|
13283
|
-
logger.debug(`TOOL REQUEST: ${tool.name}`);
|
|
13284
|
-
try {
|
|
13285
|
-
const paramsStr = JSON.stringify(tool.input);
|
|
13286
|
-
logger.debug(` Params: ${paramsStr}`);
|
|
13287
|
-
} catch {
|
|
13288
|
-
logger.debug(` Params: [Unable to stringify]`);
|
|
13289
|
-
}
|
|
13290
|
-
}
|
|
13291
|
-
}
|
|
13292
|
-
const textChunk = parsed.text || "";
|
|
13293
|
-
if (textChunk) {
|
|
13294
|
-
accumulatedText += textChunk;
|
|
13295
|
-
}
|
|
13296
|
-
if (parsed.tools && parsed.tools.length > 0) {
|
|
13297
|
-
toolsUsed = parsed.tools;
|
|
13298
|
-
}
|
|
13299
|
-
if (parsed.thinking && parsed.thinking.length > 0) {
|
|
13300
|
-
thinkingBlocks = parsed.thinking;
|
|
13301
|
-
streamLogger.onCriticalEvent(eventCount, "THINKING", `${thinkingBlocks.length} thinking blocks`);
|
|
13302
|
-
}
|
|
13303
|
-
if (parsed.usage) {
|
|
13304
|
-
lastUsageInfo = {
|
|
13305
|
-
inputTokens: parsed.usage.inputTokens,
|
|
13306
|
-
outputTokens: parsed.usage.outputTokens
|
|
13307
|
-
};
|
|
13308
|
-
}
|
|
13370
|
+
logger.debug(`[ServerLlmBackend] Response preview: ${responseText.substring(0, 200)}`);
|
|
13371
|
+
if (responseText.includes("<!DOCTYPE") || responseText.includes("<html")) {
|
|
13372
|
+
const titleMatch = responseText.match(/<title>(.*?)<\/title>/i);
|
|
13373
|
+
const h1Match = responseText.match(/<h1>(.*?)<\/h1>/i);
|
|
13374
|
+
if (titleMatch && titleMatch[1] !== "Error") {
|
|
13375
|
+
errorDetails = titleMatch[1].trim();
|
|
13376
|
+
} else if (h1Match) {
|
|
13377
|
+
errorDetails = h1Match[1].trim();
|
|
13309
13378
|
}
|
|
13310
|
-
}
|
|
13311
|
-
|
|
13379
|
+
} else if (responseText) {
|
|
13380
|
+
errorDetails = responseText.substring(0, 100).trim();
|
|
13312
13381
|
}
|
|
13382
|
+
} catch (extractError) {
|
|
13383
|
+
logger.error("[ServerLlmBackend] Error extracting response:", extractError);
|
|
13313
13384
|
}
|
|
13314
|
-
|
|
13315
|
-
|
|
13316
|
-
const abortHandler = () => {
|
|
13317
|
-
logger.debug("[ServerLlmBackend] Abort signal received, destroying stream");
|
|
13318
|
-
response.data.destroy();
|
|
13319
|
-
resolve3();
|
|
13320
|
-
};
|
|
13321
|
-
if (options.abortSignal.aborted) {
|
|
13322
|
-
abortHandler();
|
|
13323
|
-
return;
|
|
13324
|
-
}
|
|
13325
|
-
options.abortSignal.addEventListener("abort", abortHandler, { once: true });
|
|
13326
|
-
response.data.on("close", () => {
|
|
13327
|
-
options.abortSignal?.removeEventListener("abort", abortHandler);
|
|
13328
|
-
});
|
|
13385
|
+
const errorMsg = errorDetails ? `403 Forbidden: ${errorDetails}` : "403 Forbidden - Request blocked by server. Check debug logs at ~/.bike4mind/debug/";
|
|
13386
|
+
throw new Error(errorMsg);
|
|
13329
13387
|
}
|
|
13330
|
-
|
|
13331
|
-
|
|
13332
|
-
|
|
13333
|
-
|
|
13334
|
-
parser.feed(chunk.toString());
|
|
13335
|
-
});
|
|
13336
|
-
response.data.on("end", () => {
|
|
13337
|
-
if (!receivedDone) {
|
|
13338
|
-
logger.debug("[ServerLlmBackend] Stream ended without [DONE], resolving anyway");
|
|
13339
|
-
resolve3();
|
|
13340
|
-
} else {
|
|
13341
|
-
logger.debug("[ServerLlmBackend] Stream ended, [DONE] handler will resolve");
|
|
13342
|
-
}
|
|
13343
|
-
});
|
|
13344
|
-
response.data.on("error", (error) => {
|
|
13345
|
-
if (options.abortSignal?.aborted) {
|
|
13346
|
-
resolve3();
|
|
13347
|
-
return;
|
|
13348
|
-
}
|
|
13349
|
-
reject(error);
|
|
13350
|
-
});
|
|
13351
|
-
} catch (error) {
|
|
13352
|
-
if (options.abortSignal?.aborted) {
|
|
13353
|
-
logger.debug("[ServerLlmBackend] Request was aborted, resolving gracefully");
|
|
13354
|
-
resolve3();
|
|
13355
|
-
return;
|
|
13388
|
+
if (error.response) {
|
|
13389
|
+
throw new Error(
|
|
13390
|
+
`Request failed with status ${error.response.status}: ${error.response.statusText || "Unknown error"}`
|
|
13391
|
+
);
|
|
13356
13392
|
}
|
|
13357
|
-
|
|
13358
|
-
|
|
13359
|
-
|
|
13360
|
-
|
|
13393
|
+
}
|
|
13394
|
+
if (error instanceof Error) {
|
|
13395
|
+
if (error.message.includes("Authentication expired") || error.message.includes("Authentication failed")) {
|
|
13396
|
+
throw error;
|
|
13397
|
+
} else if (error.message.includes("ECONNREFUSED")) {
|
|
13398
|
+
throw new Error("Cannot connect to Bike4Mind server. Please check your internet connection.");
|
|
13399
|
+
} else if (error.message.includes("Rate limit exceeded")) {
|
|
13400
|
+
throw error;
|
|
13401
|
+
} else {
|
|
13402
|
+
throw new Error(`Failed to complete LLM request: ${error.message}`);
|
|
13361
13403
|
}
|
|
13362
|
-
|
|
13363
|
-
|
|
13364
|
-
|
|
13365
|
-
|
|
13366
|
-
|
|
13367
|
-
|
|
13368
|
-
|
|
13369
|
-
|
|
13370
|
-
|
|
13371
|
-
|
|
13372
|
-
|
|
13373
|
-
|
|
13374
|
-
|
|
13375
|
-
|
|
13376
|
-
|
|
13377
|
-
|
|
13378
|
-
|
|
13379
|
-
|
|
13380
|
-
|
|
13381
|
-
|
|
13382
|
-
|
|
13383
|
-
|
|
13404
|
+
} else {
|
|
13405
|
+
throw error;
|
|
13406
|
+
}
|
|
13407
|
+
}
|
|
13408
|
+
logger.debug("[ServerLlmBackend] Got response, setting up SSE parser");
|
|
13409
|
+
return new Promise((resolve3, reject) => {
|
|
13410
|
+
const isVerbose = process.env.B4M_VERBOSE === "1";
|
|
13411
|
+
const isUltraVerbose = process.env.B4M_DEBUG_STREAM === "1";
|
|
13412
|
+
const streamLogger = new StreamLogger(logger, "ServerLlmBackend", isVerbose, isUltraVerbose);
|
|
13413
|
+
streamLogger.streamStart();
|
|
13414
|
+
let eventCount = 0;
|
|
13415
|
+
let accumulatedText = "";
|
|
13416
|
+
let lastUsageInfo = {};
|
|
13417
|
+
let toolsUsed = [];
|
|
13418
|
+
let thinkingBlocks = [];
|
|
13419
|
+
let receivedDone = false;
|
|
13420
|
+
const parser = createParser({
|
|
13421
|
+
onEvent: (event) => {
|
|
13422
|
+
eventCount++;
|
|
13423
|
+
streamLogger.onEvent(eventCount, event.data || "");
|
|
13424
|
+
const data = event.data;
|
|
13425
|
+
if (data === "[DONE]") {
|
|
13426
|
+
receivedDone = true;
|
|
13427
|
+
streamLogger.onCriticalEvent(eventCount, "[DONE]", `accumulated text length: ${accumulatedText.length}`);
|
|
13428
|
+
const cleanedText = stripThinkingBlocks(accumulatedText);
|
|
13429
|
+
streamLogger.streamComplete(accumulatedText);
|
|
13430
|
+
if (toolsUsed.length > 0) {
|
|
13431
|
+
const info = {
|
|
13432
|
+
toolsUsed,
|
|
13433
|
+
thinking: thinkingBlocks.length > 0 ? thinkingBlocks : void 0,
|
|
13434
|
+
...lastUsageInfo
|
|
13435
|
+
};
|
|
13436
|
+
logger.debug(`[ServerLlmBackend] Calling callback with tools, thinking blocks: ${thinkingBlocks.length}`);
|
|
13437
|
+
callback([cleanedText], info).catch((err) => {
|
|
13438
|
+
logger.error("[ServerLlmBackend] Callback error:", err);
|
|
13439
|
+
reject(err);
|
|
13440
|
+
}).then(() => {
|
|
13441
|
+
logger.debug("[ServerLlmBackend] Callback completed, resolving");
|
|
13442
|
+
resolve3();
|
|
13443
|
+
});
|
|
13444
|
+
} else if (cleanedText) {
|
|
13445
|
+
callback([cleanedText], lastUsageInfo).catch((err) => {
|
|
13446
|
+
logger.error("[ServerLlmBackend] Callback error:", err);
|
|
13447
|
+
reject(err);
|
|
13448
|
+
}).then(() => resolve3());
|
|
13449
|
+
} else {
|
|
13450
|
+
resolve3();
|
|
13451
|
+
}
|
|
13452
|
+
return;
|
|
13453
|
+
}
|
|
13454
|
+
try {
|
|
13455
|
+
const parsed = JSON.parse(data);
|
|
13456
|
+
if (parsed.type === "error") {
|
|
13457
|
+
streamLogger.onCriticalEvent(eventCount, "ERROR", parsed.message || "Server error");
|
|
13458
|
+
reject(new Error(parsed.message || "Server error"));
|
|
13459
|
+
return;
|
|
13460
|
+
}
|
|
13461
|
+
if (parsed.type === "content") {
|
|
13462
|
+
const textChunk = parsed.text || "";
|
|
13463
|
+
accumulatedText += textChunk;
|
|
13464
|
+
if (parsed.usage) {
|
|
13465
|
+
lastUsageInfo = {
|
|
13466
|
+
inputTokens: parsed.usage.inputTokens,
|
|
13467
|
+
outputTokens: parsed.usage.outputTokens
|
|
13468
|
+
};
|
|
13469
|
+
}
|
|
13470
|
+
streamLogger.onContent(eventCount, textChunk, accumulatedText);
|
|
13471
|
+
} else if (parsed.type === "tool_use") {
|
|
13472
|
+
streamLogger.onCriticalEvent(eventCount, "TOOL_USE", `tools: ${parsed.tools?.length}`);
|
|
13473
|
+
if (parsed.tools && parsed.tools.length > 0) {
|
|
13474
|
+
for (const tool of parsed.tools) {
|
|
13475
|
+
logger.debug(`TOOL REQUEST: ${tool.name}`);
|
|
13476
|
+
try {
|
|
13477
|
+
const paramsStr = JSON.stringify(tool.input);
|
|
13478
|
+
logger.debug(` Params: ${paramsStr}`);
|
|
13479
|
+
} catch {
|
|
13480
|
+
logger.debug(` Params: [Unable to stringify]`);
|
|
13384
13481
|
}
|
|
13385
13482
|
}
|
|
13386
|
-
responseText = Buffer.concat(chunks).toString("utf-8");
|
|
13387
|
-
} else if (typeof stream === "string") {
|
|
13388
|
-
responseText = stream;
|
|
13389
13483
|
}
|
|
13390
|
-
|
|
13391
|
-
if (
|
|
13392
|
-
|
|
13393
|
-
|
|
13394
|
-
|
|
13395
|
-
|
|
13396
|
-
|
|
13397
|
-
|
|
13398
|
-
|
|
13399
|
-
|
|
13400
|
-
|
|
13484
|
+
const textChunk = parsed.text || "";
|
|
13485
|
+
if (textChunk) {
|
|
13486
|
+
accumulatedText += textChunk;
|
|
13487
|
+
}
|
|
13488
|
+
if (parsed.tools && parsed.tools.length > 0) {
|
|
13489
|
+
toolsUsed = parsed.tools;
|
|
13490
|
+
}
|
|
13491
|
+
if (parsed.thinking && parsed.thinking.length > 0) {
|
|
13492
|
+
thinkingBlocks = parsed.thinking;
|
|
13493
|
+
streamLogger.onCriticalEvent(eventCount, "THINKING", `${thinkingBlocks.length} thinking blocks`);
|
|
13494
|
+
}
|
|
13495
|
+
if (parsed.usage) {
|
|
13496
|
+
lastUsageInfo = {
|
|
13497
|
+
inputTokens: parsed.usage.inputTokens,
|
|
13498
|
+
outputTokens: parsed.usage.outputTokens
|
|
13499
|
+
};
|
|
13401
13500
|
}
|
|
13402
|
-
} catch (extractError) {
|
|
13403
|
-
logger.error("[ServerLlmBackend] Error extracting response:", extractError);
|
|
13404
13501
|
}
|
|
13405
|
-
|
|
13406
|
-
|
|
13407
|
-
return;
|
|
13408
|
-
}
|
|
13409
|
-
if (error.response) {
|
|
13410
|
-
reject(
|
|
13411
|
-
new Error(
|
|
13412
|
-
`Request failed with status ${error.response.status}: ${error.response.statusText || "Unknown error"}`
|
|
13413
|
-
)
|
|
13414
|
-
);
|
|
13415
|
-
return;
|
|
13502
|
+
} catch (parseError) {
|
|
13503
|
+
streamLogger.streamError(parseError);
|
|
13416
13504
|
}
|
|
13417
13505
|
}
|
|
13418
|
-
|
|
13419
|
-
|
|
13420
|
-
|
|
13421
|
-
|
|
13422
|
-
|
|
13423
|
-
|
|
13424
|
-
|
|
13425
|
-
|
|
13426
|
-
|
|
13427
|
-
|
|
13428
|
-
} else {
|
|
13429
|
-
reject(error);
|
|
13506
|
+
});
|
|
13507
|
+
if (options.abortSignal) {
|
|
13508
|
+
const abortHandler = () => {
|
|
13509
|
+
logger.debug("[ServerLlmBackend] Abort signal received, destroying stream");
|
|
13510
|
+
response.data.destroy();
|
|
13511
|
+
resolve3();
|
|
13512
|
+
};
|
|
13513
|
+
if (options.abortSignal.aborted) {
|
|
13514
|
+
abortHandler();
|
|
13515
|
+
return;
|
|
13430
13516
|
}
|
|
13517
|
+
options.abortSignal.addEventListener("abort", abortHandler, { once: true });
|
|
13518
|
+
response.data.on("close", () => {
|
|
13519
|
+
options.abortSignal?.removeEventListener("abort", abortHandler);
|
|
13520
|
+
});
|
|
13431
13521
|
}
|
|
13522
|
+
response.data.on("data", (chunk) => {
|
|
13523
|
+
if (options.abortSignal?.aborted) {
|
|
13524
|
+
return;
|
|
13525
|
+
}
|
|
13526
|
+
parser.feed(chunk.toString());
|
|
13527
|
+
});
|
|
13528
|
+
response.data.on("end", () => {
|
|
13529
|
+
if (!receivedDone) {
|
|
13530
|
+
logger.debug("[ServerLlmBackend] Stream ended without [DONE], resolving anyway");
|
|
13531
|
+
resolve3();
|
|
13532
|
+
} else {
|
|
13533
|
+
logger.debug("[ServerLlmBackend] Stream ended, [DONE] handler will resolve");
|
|
13534
|
+
}
|
|
13535
|
+
});
|
|
13536
|
+
response.data.on("error", (error) => {
|
|
13537
|
+
if (options.abortSignal?.aborted) {
|
|
13538
|
+
resolve3();
|
|
13539
|
+
return;
|
|
13540
|
+
}
|
|
13541
|
+
reject(error);
|
|
13542
|
+
});
|
|
13432
13543
|
});
|
|
13433
13544
|
}
|
|
13434
13545
|
/**
|
|
@@ -13690,7 +13801,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
|
|
|
13690
13801
|
// package.json
|
|
13691
13802
|
var package_default = {
|
|
13692
13803
|
name: "@bike4mind/cli",
|
|
13693
|
-
version: "0.2.28
|
|
13804
|
+
version: "0.2.28",
|
|
13694
13805
|
type: "module",
|
|
13695
13806
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
13696
13807
|
license: "UNLICENSED",
|
|
@@ -13778,7 +13889,7 @@ var package_default = {
|
|
|
13778
13889
|
mongoose: "^8.8.3",
|
|
13779
13890
|
ollama: "^0.5.12",
|
|
13780
13891
|
open: "^11.0.0",
|
|
13781
|
-
openai: "^
|
|
13892
|
+
openai: "^6.18.0",
|
|
13782
13893
|
"p-limit": "^6.2.0",
|
|
13783
13894
|
qrcode: "^1.5.4",
|
|
13784
13895
|
react: "^19.2.3",
|
|
@@ -13798,10 +13909,10 @@ var package_default = {
|
|
|
13798
13909
|
},
|
|
13799
13910
|
devDependencies: {
|
|
13800
13911
|
"@bike4mind/agents": "0.1.0",
|
|
13801
|
-
"@bike4mind/common": "2.
|
|
13802
|
-
"@bike4mind/mcp": "1.
|
|
13803
|
-
"@bike4mind/services": "2.
|
|
13804
|
-
"@bike4mind/utils": "2.
|
|
13912
|
+
"@bike4mind/common": "2.50.0",
|
|
13913
|
+
"@bike4mind/mcp": "1.29.0",
|
|
13914
|
+
"@bike4mind/services": "2.48.0",
|
|
13915
|
+
"@bike4mind/utils": "2.5.0",
|
|
13805
13916
|
"@types/better-sqlite3": "^7.6.13",
|
|
13806
13917
|
"@types/diff": "^5.0.9",
|
|
13807
13918
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -13818,7 +13929,7 @@ var package_default = {
|
|
|
13818
13929
|
optionalDependencies: {
|
|
13819
13930
|
"@vscode/ripgrep": "^1.17.0"
|
|
13820
13931
|
},
|
|
13821
|
-
gitHead: "
|
|
13932
|
+
gitHead: "28d4afd2bd097efcd751a14cbda1eee68cae2ad2"
|
|
13822
13933
|
};
|
|
13823
13934
|
|
|
13824
13935
|
// src/config/constants.ts
|
|
@@ -16598,7 +16709,7 @@ Custom Commands:
|
|
|
16598
16709
|
await performCleanup();
|
|
16599
16710
|
exit();
|
|
16600
16711
|
break;
|
|
16601
|
-
case "save":
|
|
16712
|
+
case "save": {
|
|
16602
16713
|
if (!state.session) {
|
|
16603
16714
|
console.log("No active session to save");
|
|
16604
16715
|
return;
|
|
@@ -16612,6 +16723,7 @@ Custom Commands:
|
|
|
16612
16723
|
await state.sessionStore.save(state.session);
|
|
16613
16724
|
console.log(`\u2705 Session saved as "${sessionName}"`);
|
|
16614
16725
|
break;
|
|
16726
|
+
}
|
|
16615
16727
|
case "sessions": {
|
|
16616
16728
|
const sessions = await state.sessionStore.list(20);
|
|
16617
16729
|
if (sessions.length === 0) {
|
|
@@ -16800,7 +16912,7 @@ Custom Commands:
|
|
|
16800
16912
|
}));
|
|
16801
16913
|
break;
|
|
16802
16914
|
}
|
|
16803
|
-
case "untrust":
|
|
16915
|
+
case "untrust": {
|
|
16804
16916
|
if (!state.permissionManager) {
|
|
16805
16917
|
console.log("Permission manager not initialized");
|
|
16806
16918
|
return;
|
|
@@ -16814,7 +16926,8 @@ Custom Commands:
|
|
|
16814
16926
|
await state.configStore.untrustTool(toolToUntrust);
|
|
16815
16927
|
console.log(`\u2705 Tool '${toolToUntrust}' removed from trusted list`);
|
|
16816
16928
|
break;
|
|
16817
|
-
|
|
16929
|
+
}
|
|
16930
|
+
case "trusted": {
|
|
16818
16931
|
if (!state.permissionManager) {
|
|
16819
16932
|
console.log("Permission manager not initialized");
|
|
16820
16933
|
return;
|
|
@@ -16828,6 +16941,7 @@ Custom Commands:
|
|
|
16828
16941
|
}
|
|
16829
16942
|
console.log("");
|
|
16830
16943
|
break;
|
|
16944
|
+
}
|
|
16831
16945
|
case "login":
|
|
16832
16946
|
setState((prev) => ({ ...prev, showLoginFlow: true }));
|
|
16833
16947
|
break;
|
|
@@ -16836,7 +16950,7 @@ Custom Commands:
|
|
|
16836
16950
|
await state.configStore.clearAuthTokens();
|
|
16837
16951
|
console.log("\u2705 Successfully logged out");
|
|
16838
16952
|
break;
|
|
16839
|
-
case "whoami":
|
|
16953
|
+
case "whoami": {
|
|
16840
16954
|
const authTokens = await state.configStore.getAuthTokens();
|
|
16841
16955
|
if (!authTokens) {
|
|
16842
16956
|
console.log("Not authenticated. Run /login to authenticate.");
|
|
@@ -16849,6 +16963,7 @@ Custom Commands:
|
|
|
16849
16963
|
console.log(`Expires: ${new Date(authTokens.expiresAt).toLocaleString()}`);
|
|
16850
16964
|
console.log("");
|
|
16851
16965
|
break;
|
|
16966
|
+
}
|
|
16852
16967
|
case "clear":
|
|
16853
16968
|
case "new": {
|
|
16854
16969
|
console.clear();
|