@probelabs/probe 0.6.0-rc306 → 0.6.0-rc308

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.
@@ -17714,10 +17714,10 @@ var init_dist2 = __esm({
17714
17714
  "ETIMEDOUT",
17715
17715
  "EPIPE"
17716
17716
  ];
17717
- VERSION = true ? "4.0.19" : "0.0.0-test";
17717
+ VERSION = true ? "4.0.21" : "0.0.0-test";
17718
17718
  suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/;
17719
17719
  suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
17720
- ignoreOverride = Symbol(
17720
+ ignoreOverride = /* @__PURE__ */ Symbol(
17721
17721
  "Let zodToJsonSchema decide on which parser to use"
17722
17722
  );
17723
17723
  defaultOptions = {
@@ -18053,7 +18053,7 @@ var init_dist2 = __esm({
18053
18053
  combined.$schema = "http://json-schema.org/draft-07/schema#";
18054
18054
  return combined;
18055
18055
  };
18056
- schemaSymbol = Symbol.for("vercel.ai.schema");
18056
+ schemaSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
18057
18057
  getOriginalFetch2 = () => globalThis.fetch;
18058
18058
  postJsonToApi = async ({
18059
18059
  url: url2,
@@ -20145,7 +20145,8 @@ async function prepareTools({
20145
20145
  } = await (0, import_internal2.prepareTools)({
20146
20146
  tools: ProviderTools,
20147
20147
  toolChoice,
20148
- supportsStructuredOutput: false
20148
+ supportsStructuredOutput: false,
20149
+ supportsStrictTools: false
20149
20150
  });
20150
20151
  toolWarnings.push(...anthropicToolWarnings);
20151
20152
  anthropicBetas.forEach((beta) => betas.add(beta));
@@ -22165,7 +22166,7 @@ var init_dist3 = __esm({
22165
22166
  details: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
22166
22167
  preview: external_exports.unknown().optional()
22167
22168
  });
22168
- VERSION2 = true ? "4.0.77" : "0.0.0-test";
22169
+ VERSION2 = true ? "4.0.82" : "0.0.0-test";
22169
22170
  bedrockRerankingResponseSchema = lazySchema(
22170
22171
  () => zodSchema(
22171
22172
  external_exports.object({
@@ -24897,7 +24898,10 @@ var init_HookManager = __esm({
24897
24898
  }
24898
24899
  });
24899
24900
 
24900
- // src/agent/imageConfig.js
24901
+ // src/agent/mediaConfig.js
24902
+ function isDocumentExtension(extension) {
24903
+ return SUPPORTED_DOCUMENT_EXTENSIONS.includes(extension?.toLowerCase());
24904
+ }
24901
24905
  function isFormatSupportedByProvider(extension, provider) {
24902
24906
  if (!extension || typeof extension !== "string") {
24903
24907
  return false;
@@ -24906,7 +24910,7 @@ function isFormatSupportedByProvider(extension, provider) {
24906
24910
  return false;
24907
24911
  }
24908
24912
  const ext2 = extension.toLowerCase();
24909
- if (!SUPPORTED_IMAGE_EXTENSIONS.includes(ext2)) {
24913
+ if (!SUPPORTED_MEDIA_EXTENSIONS.includes(ext2)) {
24910
24914
  return false;
24911
24915
  }
24912
24916
  if (!provider || typeof provider !== "string") {
@@ -24918,18 +24922,21 @@ function isFormatSupportedByProvider(extension, provider) {
24918
24922
  }
24919
24923
  return true;
24920
24924
  }
24921
- var SUPPORTED_IMAGE_EXTENSIONS, IMAGE_MIME_TYPES, PROVIDER_UNSUPPORTED_FORMATS;
24922
- var init_imageConfig = __esm({
24923
- "src/agent/imageConfig.js"() {
24925
+ var SUPPORTED_IMAGE_EXTENSIONS, SUPPORTED_DOCUMENT_EXTENSIONS, SUPPORTED_MEDIA_EXTENSIONS, MEDIA_MIME_TYPES, PROVIDER_UNSUPPORTED_FORMATS;
24926
+ var init_mediaConfig = __esm({
24927
+ "src/agent/mediaConfig.js"() {
24924
24928
  "use strict";
24925
24929
  SUPPORTED_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "webp", "bmp", "svg"];
24926
- IMAGE_MIME_TYPES = {
24930
+ SUPPORTED_DOCUMENT_EXTENSIONS = ["pdf"];
24931
+ SUPPORTED_MEDIA_EXTENSIONS = [...SUPPORTED_IMAGE_EXTENSIONS, ...SUPPORTED_DOCUMENT_EXTENSIONS];
24932
+ MEDIA_MIME_TYPES = {
24927
24933
  "png": "image/png",
24928
24934
  "jpg": "image/jpeg",
24929
24935
  "jpeg": "image/jpeg",
24930
24936
  "webp": "image/webp",
24931
24937
  "bmp": "image/bmp",
24932
- "svg": "image/svg+xml"
24938
+ "svg": "image/svg+xml",
24939
+ "pdf": "application/pdf"
24933
24940
  };
24934
24941
  PROVIDER_UNSUPPORTED_FORMATS = {
24935
24942
  "google": ["svg"]
@@ -27899,7 +27906,7 @@ function resolveTargetPath(target, cwd) {
27899
27906
  }
27900
27907
  return filePart + suffix;
27901
27908
  }
27902
- var import_path6, searchDelegateSchema, searchSchema, searchAllSchema, querySchema, extractSchema, delegateSchema, listSkillsSchema, useSkillSchema, listFilesSchema, searchFilesSchema, readImageSchema, bashSchema, analyzeAllSchema, executePlanSchema, cleanupExecutePlanSchema, searchDescription, searchDelegateDescription, queryDescription, extractDescription, delegateDescription, analyzeAllDescription;
27909
+ var import_path6, searchDelegateSchema, searchSchema, searchAllSchema, querySchema, extractSchema, delegateSchema, listSkillsSchema, useSkillSchema, listFilesSchema, searchFilesSchema, readImageSchema, readMediaSchema, bashSchema, analyzeAllSchema, executePlanSchema, cleanupExecutePlanSchema, searchDescription, searchDelegateDescription, queryDescription, extractDescription, delegateDescription, analyzeAllDescription;
27903
27910
  var init_common = __esm({
27904
27911
  "src/tools/common.js"() {
27905
27912
  "use strict";
@@ -27955,6 +27962,9 @@ var init_common = __esm({
27955
27962
  readImageSchema = external_exports2.object({
27956
27963
  path: external_exports2.string().describe("Path to the image file to read. Supports png, jpg, jpeg, webp, bmp, and svg formats.")
27957
27964
  });
27965
+ readMediaSchema = external_exports2.object({
27966
+ path: external_exports2.string().describe("Path to the media file to read. Supports images (png, jpg, jpeg, webp, bmp, svg) and documents (pdf).")
27967
+ });
27958
27968
  bashSchema = external_exports2.object({
27959
27969
  command: external_exports2.string().describe("The bash command to execute"),
27960
27970
  workingDirectory: external_exports2.string().optional().describe("Directory to execute the command in (optional)"),
@@ -100906,7 +100916,7 @@ function debugLogToolResults(toolResults) {
100906
100916
  console.log(`[DEBUG] tool: ${tr.toolName} | args: ${debugTruncate(argsStr)} | result: ${debugTruncate(resultStr)}`);
100907
100917
  }
100908
100918
  }
100909
- var import_dotenv2, import_ai6, import_crypto9, import_events4, import_fs15, import_promises6, import_path18, ENGINE_ACTIVITY_TIMEOUT_DEFAULT, ENGINE_ACTIVITY_TIMEOUT_MIN, ENGINE_ACTIVITY_TIMEOUT_MAX, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, MAX_IMAGE_FILE_SIZE, ProbeAgent;
100919
+ var import_dotenv2, import_ai6, import_crypto9, import_events4, import_fs15, import_promises6, import_path18, ENGINE_ACTIVITY_TIMEOUT_DEFAULT, ENGINE_ACTIVITY_TIMEOUT_MIN, ENGINE_ACTIVITY_TIMEOUT_MAX, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, MAX_IMAGE_FILE_SIZE, MAX_DOCUMENT_FILE_SIZE, ProbeAgent;
100910
100920
  var init_ProbeAgent = __esm({
100911
100921
  "src/agent/ProbeAgent.js"() {
100912
100922
  import_dotenv2 = __toESM(require_main(), 1);
@@ -100921,7 +100931,7 @@ var init_ProbeAgent = __esm({
100921
100931
  init_simpleTelemetry();
100922
100932
  init_InMemoryStorageAdapter();
100923
100933
  init_HookManager();
100924
- init_imageConfig();
100934
+ init_mediaConfig();
100925
100935
  init_tools2();
100926
100936
  init_common();
100927
100937
  init_taskTool();
@@ -100959,6 +100969,7 @@ var init_ProbeAgent = __esm({
100959
100969
  })();
100960
100970
  MAX_HISTORY_MESSAGES = 100;
100961
100971
  MAX_IMAGE_FILE_SIZE = 20 * 1024 * 1024;
100972
+ MAX_DOCUMENT_FILE_SIZE = 32 * 1024 * 1024;
100962
100973
  ProbeAgent = class _ProbeAgent {
100963
100974
  /**
100964
100975
  * Create a new ProbeAgent instance
@@ -101587,28 +101598,29 @@ var init_ProbeAgent = __esm({
101587
101598
  this.toolImplementations.useSkill = useSkillToolInstance;
101588
101599
  }
101589
101600
  }
101590
- if (isToolAllowed("readImage")) {
101591
- this.toolImplementations.readImage = {
101592
- execute: async (params) => {
101593
- const imagePath = params.path;
101594
- if (!imagePath) {
101595
- throw new Error("Image path is required");
101596
- }
101597
- const filename = (0, import_path18.basename)(imagePath);
101598
- const extension = filename.toLowerCase().split(".").pop();
101599
- if (!extension || !SUPPORTED_IMAGE_EXTENSIONS.includes(extension)) {
101600
- throw new Error(`Invalid or unsupported image extension: ${extension}. Supported formats: ${SUPPORTED_IMAGE_EXTENSIONS.join(", ")}`);
101601
- }
101602
- if (this.apiType && !isFormatSupportedByProvider(extension, this.apiType)) {
101603
- throw new Error(`Image format '${extension}' is not supported by the current AI provider (${this.apiType}). Try using a different image format like PNG or JPEG.`);
101604
- }
101605
- const loaded = await this.loadImageIfValid(imagePath);
101606
- if (!loaded) {
101607
- throw new Error(`Failed to load image: ${imagePath}. The file may not exist, be too large, have an unsupported format, or be outside allowed directories.`);
101608
- }
101609
- return `Image loaded successfully: ${imagePath}. The image is now available for analysis in the conversation.`;
101610
- }
101611
- };
101601
+ const readMediaExecute = async (params) => {
101602
+ const mediaPath = params.path;
101603
+ if (!mediaPath) {
101604
+ throw new Error("File path is required");
101605
+ }
101606
+ const filename = (0, import_path18.basename)(mediaPath);
101607
+ const extension = filename.toLowerCase().split(".").pop();
101608
+ if (!extension || !SUPPORTED_MEDIA_EXTENSIONS.includes(extension)) {
101609
+ throw new Error(`Unsupported file format: ${extension}. Supported formats: ${SUPPORTED_MEDIA_EXTENSIONS.join(", ")}`);
101610
+ }
101611
+ if (this.apiType && !isFormatSupportedByProvider(extension, this.apiType)) {
101612
+ throw new Error(`File format '${extension}' is not supported by the current AI provider (${this.apiType}). Try converting to a different format.`);
101613
+ }
101614
+ const loaded = await this.loadMediaIfValid(mediaPath);
101615
+ if (!loaded) {
101616
+ throw new Error(`Failed to load file: ${mediaPath}. The file may not exist, be too large, have an unsupported format, or be outside allowed directories.`);
101617
+ }
101618
+ const mediaType = isDocumentExtension(extension) ? "Document" : "Image";
101619
+ return `${mediaType} loaded successfully: ${mediaPath}. The file is now available for analysis in the conversation.`;
101620
+ };
101621
+ if (isToolAllowed("readMedia") || isToolAllowed("readImage")) {
101622
+ this.toolImplementations.readMedia = { execute: readMediaExecute };
101623
+ this.toolImplementations.readImage = { execute: readMediaExecute };
101612
101624
  }
101613
101625
  if (this.enableBash && wrappedTools.bashToolInstance && isToolAllowed("bash")) {
101614
101626
  this.toolImplementations.bash = wrappedTools.bashToolInstance;
@@ -102604,9 +102616,9 @@ var init_ProbeAgent = __esm({
102604
102616
  schema: searchFilesSchema,
102605
102617
  description: "Find files matching a glob pattern with recursive search capability."
102606
102618
  },
102607
- readImage: {
102608
- schema: readImageSchema,
102609
- description: "Read and load an image file for AI analysis."
102619
+ readMedia: {
102620
+ schema: readMediaSchema,
102621
+ description: "Read and load a media file (image or PDF document) for AI analysis. Supports: png, jpg, jpeg, webp, bmp, svg, pdf."
102610
102622
  },
102611
102623
  listSkills: {
102612
102624
  schema: listSkillsSchema,
@@ -102751,7 +102763,7 @@ var init_ProbeAgent = __esm({
102751
102763
  async processImageReferences(content) {
102752
102764
  if (!content) return;
102753
102765
  const listFilesDirectories = this.extractListFilesDirectories(content);
102754
- const extensionsPattern = `(?:${SUPPORTED_IMAGE_EXTENSIONS.join("|")})`;
102766
+ const extensionsPattern = `(?:${SUPPORTED_MEDIA_EXTENSIONS.join("|")})`;
102755
102767
  const imagePatterns = [
102756
102768
  // Direct file path mentions: "./screenshot.png", "/path/to/image.jpg", etc.
102757
102769
  new RegExp(`(?:\\.?\\.\\/)?[^\\s"'<>\\[\\]]+\\.${extensionsPattern}(?!\\w)`, "gi"),
@@ -102833,23 +102845,23 @@ var init_ProbeAgent = __esm({
102833
102845
  return directories;
102834
102846
  }
102835
102847
  /**
102836
- * Load and cache an image if it's valid and accessible
102837
- * @param {string} imagePath - Path to the image file
102838
- * @returns {Promise<boolean>} - True if image was loaded successfully
102848
+ * Load and cache a media file (image or PDF) if it's valid and accessible
102849
+ * @param {string} mediaPath - Path to the media file
102850
+ * @returns {Promise<boolean>} - True if file was loaded successfully
102839
102851
  */
102840
- async loadImageIfValid(imagePath) {
102852
+ async loadMediaIfValid(mediaPath) {
102841
102853
  try {
102842
- if (this.pendingImages.has(imagePath)) {
102854
+ if (this.pendingImages.has(mediaPath)) {
102843
102855
  if (this.debug) {
102844
- console.log(`[DEBUG] Image already loaded: ${imagePath}`);
102856
+ console.log(`[DEBUG] Media already loaded: ${mediaPath}`);
102845
102857
  }
102846
102858
  return true;
102847
102859
  }
102848
102860
  const allowedDirs = this.allowedFolders && this.allowedFolders.length > 0 ? this.allowedFolders : [process.cwd()];
102849
102861
  let absolutePath;
102850
102862
  let isPathAllowed2 = false;
102851
- if ((0, import_path18.isAbsolute)(imagePath)) {
102852
- absolutePath = safeRealpath((0, import_path18.resolve)(imagePath));
102863
+ if ((0, import_path18.isAbsolute)(mediaPath)) {
102864
+ absolutePath = safeRealpath((0, import_path18.resolve)(mediaPath));
102853
102865
  isPathAllowed2 = allowedDirs.some((dir) => {
102854
102866
  const resolvedDir = safeRealpath(dir);
102855
102867
  return absolutePath === resolvedDir || absolutePath.startsWith(resolvedDir + import_path18.sep);
@@ -102857,7 +102869,7 @@ var init_ProbeAgent = __esm({
102857
102869
  } else {
102858
102870
  for (const dir of allowedDirs) {
102859
102871
  const resolvedDir = safeRealpath(dir);
102860
- const resolvedPath = safeRealpath((0, import_path18.resolve)(dir, imagePath));
102872
+ const resolvedPath = safeRealpath((0, import_path18.resolve)(dir, mediaPath));
102861
102873
  if (resolvedPath === resolvedDir || resolvedPath.startsWith(resolvedDir + import_path18.sep)) {
102862
102874
  absolutePath = resolvedPath;
102863
102875
  isPathAllowed2 = true;
@@ -102867,7 +102879,7 @@ var init_ProbeAgent = __esm({
102867
102879
  }
102868
102880
  if (!isPathAllowed2) {
102869
102881
  if (this.debug) {
102870
- console.log(`[DEBUG] Image path outside allowed directories: ${imagePath}`);
102882
+ console.log(`[DEBUG] Media path outside allowed directories: ${mediaPath}`);
102871
102883
  }
102872
102884
  return false;
102873
102885
  }
@@ -102876,91 +102888,126 @@ var init_ProbeAgent = __esm({
102876
102888
  fileStats = await (0, import_promises6.stat)(absolutePath);
102877
102889
  } catch (error40) {
102878
102890
  if (this.debug) {
102879
- console.log(`[DEBUG] Image file not found: ${absolutePath}`);
102891
+ console.log(`[DEBUG] Media file not found: ${absolutePath}`);
102880
102892
  }
102881
102893
  return false;
102882
102894
  }
102883
- if (fileStats.size > MAX_IMAGE_FILE_SIZE) {
102895
+ const extension = absolutePath.toLowerCase().split(".").pop();
102896
+ if (!SUPPORTED_MEDIA_EXTENSIONS.includes(extension)) {
102884
102897
  if (this.debug) {
102885
- console.log(`[DEBUG] Image file too large: ${absolutePath} (${fileStats.size} bytes, max: ${MAX_IMAGE_FILE_SIZE})`);
102898
+ console.log(`[DEBUG] Unsupported media format: ${extension}`);
102886
102899
  }
102887
102900
  return false;
102888
102901
  }
102889
- const extension = absolutePath.toLowerCase().split(".").pop();
102890
- if (!SUPPORTED_IMAGE_EXTENSIONS.includes(extension)) {
102902
+ const maxSize = isDocumentExtension(extension) ? MAX_DOCUMENT_FILE_SIZE : MAX_IMAGE_FILE_SIZE;
102903
+ if (fileStats.size > maxSize) {
102891
102904
  if (this.debug) {
102892
- console.log(`[DEBUG] Unsupported image format: ${extension}`);
102905
+ console.log(`[DEBUG] Media file too large: ${absolutePath} (${fileStats.size} bytes, max: ${maxSize})`);
102893
102906
  }
102894
102907
  return false;
102895
102908
  }
102896
- const mimeType = IMAGE_MIME_TYPES[extension];
102909
+ const mimeType = MEDIA_MIME_TYPES[extension];
102897
102910
  const fileBuffer = await (0, import_promises6.readFile)(absolutePath);
102898
102911
  const base64Data = fileBuffer.toString("base64");
102899
- const dataUrl = `data:${mimeType};base64,${base64Data}`;
102900
- this.pendingImages.set(imagePath, dataUrl);
102912
+ if (isDocumentExtension(extension)) {
102913
+ this.pendingImages.set(mediaPath, {
102914
+ type: "document",
102915
+ mimeType,
102916
+ data: base64Data,
102917
+ filename: (0, import_path18.basename)(mediaPath)
102918
+ });
102919
+ } else {
102920
+ const dataUrl = `data:${mimeType};base64,${base64Data}`;
102921
+ this.pendingImages.set(mediaPath, dataUrl);
102922
+ }
102901
102923
  if (this.debug) {
102902
- console.log(`[DEBUG] Successfully loaded image: ${imagePath} (${fileBuffer.length} bytes)`);
102924
+ console.log(`[DEBUG] Successfully loaded media: ${mediaPath} (${fileBuffer.length} bytes, ${mimeType})`);
102903
102925
  }
102904
102926
  return true;
102905
102927
  } catch (error40) {
102906
102928
  if (this.debug) {
102907
- console.log(`[DEBUG] Failed to load image ${imagePath}: ${error40.message}`);
102929
+ console.log(`[DEBUG] Failed to load media ${mediaPath}: ${error40.message}`);
102908
102930
  }
102909
102931
  return false;
102910
102932
  }
102911
102933
  }
102934
+ /**
102935
+ * Backward-compatible alias for loadMediaIfValid
102936
+ * @param {string} imagePath - Path to the image file
102937
+ * @returns {Promise<boolean>}
102938
+ */
102939
+ async loadImageIfValid(imagePath) {
102940
+ return this.loadMediaIfValid(imagePath);
102941
+ }
102912
102942
  /**
102913
102943
  * Get all currently loaded images as an array for AI model consumption
102914
- * @returns {Array<string>} - Array of base64 data URLs
102944
+ * @returns {Array<string>} - Array of base64 data URLs (images only, for backward compat)
102915
102945
  */
102916
102946
  getCurrentImages() {
102917
- return Array.from(this.pendingImages.values());
102947
+ return Array.from(this.pendingImages.values()).filter((v) => typeof v === "string");
102918
102948
  }
102919
102949
  /**
102920
- * Clear loaded images (useful for new conversations)
102950
+ * Get all currently loaded media as an array of content parts
102951
+ * @returns {Array<Object>} - Array of Vercel AI SDK content parts
102952
+ */
102953
+ getCurrentMedia() {
102954
+ const parts = [];
102955
+ for (const entry of this.pendingImages.values()) {
102956
+ if (typeof entry === "string") {
102957
+ parts.push({ type: "image", image: entry });
102958
+ } else if (entry && entry.type === "document") {
102959
+ parts.push({
102960
+ type: "file",
102961
+ mediaType: entry.mimeType,
102962
+ data: entry.data,
102963
+ filename: entry.filename
102964
+ });
102965
+ }
102966
+ }
102967
+ return parts;
102968
+ }
102969
+ /**
102970
+ * Clear loaded media (useful for new conversations)
102921
102971
  */
102922
102972
  clearLoadedImages() {
102923
102973
  this.pendingImages.clear();
102924
102974
  this.currentImages = [];
102925
102975
  if (this.debug) {
102926
- console.log("[DEBUG] Cleared all loaded images");
102976
+ console.log("[DEBUG] Cleared all loaded media");
102927
102977
  }
102928
102978
  }
102929
102979
  /**
102930
- * Prepare messages for AI consumption, adding images to the latest user message if available
102980
+ * Prepare messages for AI consumption, adding media to the latest user message if available
102931
102981
  * @param {Array} messages - Current conversation messages
102932
- * @returns {Array} - Messages formatted for AI SDK with potential image content
102982
+ * @returns {Array} - Messages formatted for AI SDK with potential media content
102933
102983
  */
102934
102984
  prepareMessagesWithImages(messages) {
102935
- const loadedImages = this.getCurrentImages();
102936
- if (loadedImages.length === 0) {
102985
+ const mediaParts = this.getCurrentMedia();
102986
+ if (mediaParts.length === 0) {
102937
102987
  return messages;
102938
102988
  }
102939
- const messagesWithImages = [...messages];
102940
- const lastUserMessageIndex = messagesWithImages.map((m) => m.role).lastIndexOf("user");
102989
+ const messagesWithMedia = [...messages];
102990
+ const lastUserMessageIndex = messagesWithMedia.map((m) => m.role).lastIndexOf("user");
102941
102991
  if (lastUserMessageIndex === -1) {
102942
102992
  if (this.debug) {
102943
- console.log("[DEBUG] No user messages found to attach images to");
102993
+ console.log("[DEBUG] No user messages found to attach media to");
102944
102994
  }
102945
102995
  return messages;
102946
102996
  }
102947
- const lastUserMessage = messagesWithImages[lastUserMessageIndex];
102997
+ const lastUserMessage = messagesWithMedia[lastUserMessageIndex];
102948
102998
  if (typeof lastUserMessage.content === "string") {
102949
- messagesWithImages[lastUserMessageIndex] = {
102999
+ messagesWithMedia[lastUserMessageIndex] = {
102950
103000
  ...lastUserMessage,
102951
103001
  content: [
102952
103002
  { type: "text", text: lastUserMessage.content },
102953
- ...loadedImages.map((imageData) => ({
102954
- type: "image",
102955
- image: imageData
102956
- }))
103003
+ ...mediaParts
102957
103004
  ]
102958
103005
  };
102959
103006
  if (this.debug) {
102960
- console.log(`[DEBUG] Added ${loadedImages.length} images to the latest user message`);
103007
+ console.log(`[DEBUG] Added ${mediaParts.length} media items to the latest user message`);
102961
103008
  }
102962
103009
  }
102963
- return messagesWithImages;
103010
+ return messagesWithMedia;
102964
103011
  }
102965
103012
  /**
102966
103013
  * Initialize mock model for testing
@@ -103858,40 +103905,42 @@ or
103858
103905
  }
103859
103906
  const jsonStr = responseText.replace(/^```(?:json)?\s*/, "").replace(/\s*```$/, "");
103860
103907
  const decision = JSON.parse(jsonStr);
103908
+ let grantedMs = 0;
103909
+ let grantedMin = 0;
103861
103910
  if (decision.extend && decision.minutes > 0) {
103862
103911
  const requestedMs = Math.min(decision.minutes, maxPerReqMin) * 6e4;
103863
- const grantedMs2 = Math.min(requestedMs, remainingBudgetMs, negotiatedTimeoutState.maxPerRequestMs);
103864
- const grantedMin2 = Math.round(grantedMs2 / 6e4 * 10) / 10;
103912
+ grantedMs = Math.min(requestedMs, remainingBudgetMs, negotiatedTimeoutState.maxPerRequestMs);
103913
+ grantedMin = Math.round(grantedMs / 6e4 * 10) / 10;
103865
103914
  negotiatedTimeoutState.extensionsUsed++;
103866
- negotiatedTimeoutState.totalExtraTimeMs += grantedMs2;
103867
- negotiatedTimeoutState.extensionMessage = `\u23F0 Time limit was reached. The timeout observer granted ${grantedMin2} more minute(s) (reason: ${decision.reason || "work in progress"}). Extensions remaining: ${negotiatedTimeoutState.maxRequests - negotiatedTimeoutState.extensionsUsed}. Continue your work efficiently.`;
103915
+ negotiatedTimeoutState.totalExtraTimeMs += grantedMs;
103916
+ negotiatedTimeoutState.extensionMessage = `\u23F0 Time limit was reached. The timeout observer granted ${grantedMin} more minute(s) (reason: ${decision.reason || "work in progress"}). Extensions remaining: ${negotiatedTimeoutState.maxRequests - negotiatedTimeoutState.extensionsUsed}. Continue your work efficiently.`;
103868
103917
  negotiatedTimeoutState.softTimeoutId = setTimeout(() => {
103869
103918
  runTimeoutObserver();
103870
- }, grantedMs2);
103919
+ }, grantedMs);
103871
103920
  if (this.debug) {
103872
- console.log(`[DEBUG] Timeout observer: granted ${grantedMin2} min (reason: ${decision.reason}). Extensions: ${negotiatedTimeoutState.extensionsUsed}/${negotiatedTimeoutState.maxRequests}`);
103921
+ console.log(`[DEBUG] Timeout observer: granted ${grantedMin} min (reason: ${decision.reason}). Extensions: ${negotiatedTimeoutState.extensionsUsed}/${negotiatedTimeoutState.maxRequests}`);
103873
103922
  }
103874
103923
  if (this.tracer) {
103875
103924
  this.tracer.addEvent("negotiated_timeout.observer_extended", {
103876
103925
  decision_reason: decision.reason,
103877
103926
  requested_minutes: decision.minutes,
103878
- granted_ms: grantedMs2,
103879
- granted_min: grantedMin2,
103927
+ granted_ms: grantedMs,
103928
+ granted_min: grantedMin,
103880
103929
  extensions_used: negotiatedTimeoutState.extensionsUsed,
103881
103930
  max_requests: negotiatedTimeoutState.maxRequests,
103882
103931
  total_extra_time_ms: negotiatedTimeoutState.totalExtraTimeMs,
103883
- budget_remaining_ms: remainingBudgetMs - grantedMs2,
103932
+ budget_remaining_ms: remainingBudgetMs - grantedMs,
103884
103933
  active_tools: activeToolsList.map((t) => t.name),
103885
103934
  active_tools_count: activeToolsList.length
103886
103935
  });
103887
103936
  }
103888
103937
  this.events.emit("timeout.extended", {
103889
- grantedMs: grantedMs2,
103938
+ grantedMs,
103890
103939
  reason: decision.reason || "work in progress",
103891
103940
  extensionsUsed: negotiatedTimeoutState.extensionsUsed,
103892
103941
  extensionsRemaining: negotiatedTimeoutState.maxRequests - negotiatedTimeoutState.extensionsUsed,
103893
103942
  totalExtraTimeMs: negotiatedTimeoutState.totalExtraTimeMs,
103894
- budgetRemainingMs: remainingBudgetMs - grantedMs2
103943
+ budgetRemainingMs: remainingBudgetMs - grantedMs
103895
103944
  });
103896
103945
  } else {
103897
103946
  if (this.debug) {