@probelabs/probe 0.6.0-rc152 → 0.6.0-rc154

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.
@@ -17,6 +17,7 @@ import { resolve, isAbsolute, dirname } from 'path';
17
17
  import { TokenCounter } from './tokenCounter.js';
18
18
  import { InMemoryStorageAdapter } from './storage/InMemoryStorageAdapter.js';
19
19
  import { HookManager, HOOK_TYPES } from './hooks/HookManager.js';
20
+ import { SUPPORTED_IMAGE_EXTENSIONS, IMAGE_MIME_TYPES } from './imageConfig.js';
20
21
  import {
21
22
  createTools,
22
23
  searchToolDefinition,
@@ -58,8 +59,7 @@ import {
58
59
  const MAX_TOOL_ITERATIONS = parseInt(process.env.MAX_TOOL_ITERATIONS || '30', 10);
59
60
  const MAX_HISTORY_MESSAGES = 100;
60
61
 
61
- // Supported image file extensions
62
- const SUPPORTED_IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'webp', 'gif', 'bmp', 'svg'];
62
+ // Supported image file extensions (imported from shared config)
63
63
 
64
64
  // Maximum image file size (20MB) to prevent OOM attacks
65
65
  const MAX_IMAGE_FILE_SIZE = 20 * 1024 * 1024;
@@ -134,6 +134,7 @@ export class ProbeAgent {
134
134
 
135
135
  // API configuration
136
136
  this.clientApiProvider = options.provider || null;
137
+ this.clientApiModel = options.model || null;
137
138
  this.clientApiKey = null; // Will be set from environment
138
139
  this.clientApiUrl = null;
139
140
 
@@ -302,9 +303,12 @@ export class ProbeAgent {
302
303
  * Initialize the AI model based on available API keys and forced provider setting
303
304
  */
304
305
  initializeModel() {
306
+ // Get model override if provided (options.model takes precedence over environment variable)
307
+ const modelName = this.clientApiModel || process.env.MODEL_NAME;
308
+
305
309
  // Check if we're in test mode and should use mock provider
306
310
  if (process.env.NODE_ENV === 'test' || process.env.USE_MOCK_AI === 'true') {
307
- this.initializeMockModel();
311
+ this.initializeMockModel(modelName);
308
312
  return;
309
313
  }
310
314
 
@@ -327,9 +331,6 @@ export class ProbeAgent {
327
331
  const googleApiUrl = process.env.GOOGLE_API_URL || llmBaseUrl;
328
332
  const awsBedrockBaseUrl = process.env.AWS_BEDROCK_BASE_URL || llmBaseUrl;
329
333
 
330
- // Get model override if provided
331
- const modelName = process.env.MODEL_NAME;
332
-
333
334
  // Use client-forced provider or environment variable
334
335
  const forceProvider = this.clientApiProvider || (process.env.FORCE_PROVIDER ? process.env.FORCE_PROVIDER.toLowerCase() : null);
335
336
 
@@ -671,17 +672,8 @@ export class ProbeAgent {
671
672
  return false;
672
673
  }
673
674
 
674
- // Determine MIME type
675
- const mimeTypes = {
676
- 'png': 'image/png',
677
- 'jpg': 'image/jpeg',
678
- 'jpeg': 'image/jpeg',
679
- 'webp': 'image/webp',
680
- 'gif': 'image/gif',
681
- 'bmp': 'image/bmp',
682
- 'svg': 'image/svg+xml'
683
- };
684
- const mimeType = mimeTypes[extension];
675
+ // Determine MIME type (from shared config)
676
+ const mimeType = IMAGE_MIME_TYPES[extension];
685
677
 
686
678
  // Read and encode file asynchronously
687
679
  const fileBuffer = await readFile(absolutePath);
@@ -2216,7 +2208,7 @@ Convert your previous response content into actual JSON data that follows this s
2216
2208
  path: this.allowedFolders[0], // Use first allowed folder as primary path
2217
2209
  allowedFolders: [...this.allowedFolders],
2218
2210
  provider: this.clientApiProvider,
2219
- model: this.modelName,
2211
+ model: this.clientApiModel,
2220
2212
  debug: this.debug,
2221
2213
  outline: this.outline,
2222
2214
  maxResponseTokens: this.maxResponseTokens,
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Shared image format configuration for Probe agent
3
+ *
4
+ * This module centralizes supported image formats and their MIME types
5
+ * to ensure consistency across all components.
6
+ *
7
+ * Note: GIF support was intentionally removed for compatibility with
8
+ * AI models like Google Gemini that don't support animated images.
9
+ */
10
+
11
+ // Supported image file extensions (without leading dot)
12
+ export const SUPPORTED_IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'webp', 'bmp', 'svg'];
13
+
14
+ // MIME type mapping for supported image formats
15
+ export const IMAGE_MIME_TYPES = {
16
+ 'png': 'image/png',
17
+ 'jpg': 'image/jpeg',
18
+ 'jpeg': 'image/jpeg',
19
+ 'webp': 'image/webp',
20
+ 'bmp': 'image/bmp',
21
+ 'svg': 'image/svg+xml'
22
+ };
23
+
24
+ /**
25
+ * Generate a regex pattern string for matching image file extensions
26
+ * @param {string[]} extensions - Array of extensions (without dots)
27
+ * @returns {string} Regex pattern string like "png|jpg|jpeg|webp|bmp|svg"
28
+ */
29
+ export function getExtensionPattern(extensions = SUPPORTED_IMAGE_EXTENSIONS) {
30
+ return extensions.join('|');
31
+ }
32
+
33
+ /**
34
+ * Get MIME type for a file extension
35
+ * @param {string} extension - File extension (without dot)
36
+ * @returns {string|undefined} MIME type or undefined if not supported
37
+ */
38
+ export function getMimeType(extension) {
39
+ return IMAGE_MIME_TYPES[extension.toLowerCase()];
40
+ }
@@ -1694,6 +1694,23 @@ var init_HookManager = __esm({
1694
1694
  }
1695
1695
  });
1696
1696
 
1697
+ // src/agent/imageConfig.js
1698
+ var SUPPORTED_IMAGE_EXTENSIONS, IMAGE_MIME_TYPES;
1699
+ var init_imageConfig = __esm({
1700
+ "src/agent/imageConfig.js"() {
1701
+ "use strict";
1702
+ SUPPORTED_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "webp", "bmp", "svg"];
1703
+ IMAGE_MIME_TYPES = {
1704
+ "png": "image/png",
1705
+ "jpg": "image/jpeg",
1706
+ "jpeg": "image/jpeg",
1707
+ "webp": "image/webp",
1708
+ "bmp": "image/bmp",
1709
+ "svg": "image/svg+xml"
1710
+ };
1711
+ }
1712
+ });
1713
+
1697
1714
  // src/directory-resolver.js
1698
1715
  import path from "path";
1699
1716
  import os from "os";
@@ -55389,13 +55406,14 @@ import { EventEmitter as EventEmitter3 } from "events";
55389
55406
  import { existsSync as existsSync4 } from "fs";
55390
55407
  import { readFile, stat } from "fs/promises";
55391
55408
  import { resolve as resolve3, isAbsolute, dirname as dirname3 } from "path";
55392
- var MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, SUPPORTED_IMAGE_EXTENSIONS, MAX_IMAGE_FILE_SIZE, ProbeAgent;
55409
+ var MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, MAX_IMAGE_FILE_SIZE, ProbeAgent;
55393
55410
  var init_ProbeAgent = __esm({
55394
55411
  "src/agent/ProbeAgent.js"() {
55395
55412
  "use strict";
55396
55413
  init_tokenCounter();
55397
55414
  init_InMemoryStorageAdapter();
55398
55415
  init_HookManager();
55416
+ init_imageConfig();
55399
55417
  init_tools2();
55400
55418
  init_common();
55401
55419
  init_probeTool();
@@ -55407,7 +55425,6 @@ var init_ProbeAgent = __esm({
55407
55425
  dotenv2.config();
55408
55426
  MAX_TOOL_ITERATIONS = parseInt(process.env.MAX_TOOL_ITERATIONS || "30", 10);
55409
55427
  MAX_HISTORY_MESSAGES = 100;
55410
- SUPPORTED_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "webp", "gif", "bmp", "svg"];
55411
55428
  MAX_IMAGE_FILE_SIZE = 20 * 1024 * 1024;
55412
55429
  ProbeAgent = class _ProbeAgent {
55413
55430
  /**
@@ -55463,6 +55480,7 @@ var init_ProbeAgent = __esm({
55463
55480
  this.allowedFolders = [process.cwd()];
55464
55481
  }
55465
55482
  this.clientApiProvider = options.provider || null;
55483
+ this.clientApiModel = options.model || null;
55466
55484
  this.clientApiKey = null;
55467
55485
  this.clientApiUrl = null;
55468
55486
  this.tokenCounter = new TokenCounter();
@@ -55584,8 +55602,9 @@ var init_ProbeAgent = __esm({
55584
55602
  * Initialize the AI model based on available API keys and forced provider setting
55585
55603
  */
55586
55604
  initializeModel() {
55605
+ const modelName = this.clientApiModel || process.env.MODEL_NAME;
55587
55606
  if (process.env.NODE_ENV === "test" || process.env.USE_MOCK_AI === "true") {
55588
- this.initializeMockModel();
55607
+ this.initializeMockModel(modelName);
55589
55608
  return;
55590
55609
  }
55591
55610
  const anthropicApiKey = process.env.ANTHROPIC_API_KEY || process.env.ANTHROPIC_AUTH_TOKEN;
@@ -55601,7 +55620,6 @@ var init_ProbeAgent = __esm({
55601
55620
  const openaiApiUrl = process.env.OPENAI_API_URL || llmBaseUrl;
55602
55621
  const googleApiUrl = process.env.GOOGLE_API_URL || llmBaseUrl;
55603
55622
  const awsBedrockBaseUrl = process.env.AWS_BEDROCK_BASE_URL || llmBaseUrl;
55604
- const modelName = process.env.MODEL_NAME;
55605
55623
  const forceProvider = this.clientApiProvider || (process.env.FORCE_PROVIDER ? process.env.FORCE_PROVIDER.toLowerCase() : null);
55606
55624
  if (this.debug) {
55607
55625
  const hasAwsCredentials = !!(awsAccessKeyId && awsSecretAccessKey && awsRegion);
@@ -55860,16 +55878,7 @@ var init_ProbeAgent = __esm({
55860
55878
  }
55861
55879
  return false;
55862
55880
  }
55863
- const mimeTypes = {
55864
- "png": "image/png",
55865
- "jpg": "image/jpeg",
55866
- "jpeg": "image/jpeg",
55867
- "webp": "image/webp",
55868
- "gif": "image/gif",
55869
- "bmp": "image/bmp",
55870
- "svg": "image/svg+xml"
55871
- };
55872
- const mimeType = mimeTypes[extension];
55881
+ const mimeType = IMAGE_MIME_TYPES[extension];
55873
55882
  const fileBuffer = await readFile(absolutePath);
55874
55883
  const base64Data = fileBuffer.toString("base64");
55875
55884
  const dataUrl = `data:${mimeType};base64,${base64Data}`;
@@ -57135,7 +57144,7 @@ Convert your previous response content into actual JSON data that follows this s
57135
57144
  // Use first allowed folder as primary path
57136
57145
  allowedFolders: [...this.allowedFolders],
57137
57146
  provider: this.clientApiProvider,
57138
- model: this.modelName,
57147
+ model: this.clientApiModel,
57139
57148
  debug: this.debug,
57140
57149
  outline: this.outline,
57141
57150
  maxResponseTokens: this.maxResponseTokens,
@@ -27453,6 +27453,23 @@ var init_HookManager = __esm({
27453
27453
  }
27454
27454
  });
27455
27455
 
27456
+ // src/agent/imageConfig.js
27457
+ var SUPPORTED_IMAGE_EXTENSIONS, IMAGE_MIME_TYPES;
27458
+ var init_imageConfig = __esm({
27459
+ "src/agent/imageConfig.js"() {
27460
+ "use strict";
27461
+ SUPPORTED_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "webp", "bmp", "svg"];
27462
+ IMAGE_MIME_TYPES = {
27463
+ "png": "image/png",
27464
+ "jpg": "image/jpeg",
27465
+ "jpeg": "image/jpeg",
27466
+ "webp": "image/webp",
27467
+ "bmp": "image/bmp",
27468
+ "svg": "image/svg+xml"
27469
+ };
27470
+ }
27471
+ });
27472
+
27456
27473
  // src/directory-resolver.js
27457
27474
  async function getPackageBinDir() {
27458
27475
  const debug = process.env.DEBUG === "1" || process.env.VERBOSE === "1";
@@ -80926,7 +80943,7 @@ __export(ProbeAgent_exports, {
80926
80943
  ProbeAgent: () => ProbeAgent
80927
80944
  });
80928
80945
  module.exports = __toCommonJS(ProbeAgent_exports);
80929
- var import_dotenv2, import_anthropic, import_openai, import_google, import_ai3, import_crypto5, import_events2, import_fs8, import_promises2, import_path10, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, SUPPORTED_IMAGE_EXTENSIONS, MAX_IMAGE_FILE_SIZE, ProbeAgent;
80946
+ var import_dotenv2, import_anthropic, import_openai, import_google, import_ai3, import_crypto5, import_events2, import_fs8, import_promises2, import_path10, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, MAX_IMAGE_FILE_SIZE, ProbeAgent;
80930
80947
  var init_ProbeAgent = __esm({
80931
80948
  "src/agent/ProbeAgent.js"() {
80932
80949
  import_dotenv2 = __toESM(require_main(), 1);
@@ -80943,6 +80960,7 @@ var init_ProbeAgent = __esm({
80943
80960
  init_tokenCounter();
80944
80961
  init_InMemoryStorageAdapter();
80945
80962
  init_HookManager();
80963
+ init_imageConfig();
80946
80964
  init_tools2();
80947
80965
  init_common2();
80948
80966
  init_probeTool();
@@ -80954,7 +80972,6 @@ var init_ProbeAgent = __esm({
80954
80972
  import_dotenv2.default.config();
80955
80973
  MAX_TOOL_ITERATIONS = parseInt(process.env.MAX_TOOL_ITERATIONS || "30", 10);
80956
80974
  MAX_HISTORY_MESSAGES = 100;
80957
- SUPPORTED_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "webp", "gif", "bmp", "svg"];
80958
80975
  MAX_IMAGE_FILE_SIZE = 20 * 1024 * 1024;
80959
80976
  ProbeAgent = class _ProbeAgent {
80960
80977
  /**
@@ -81010,6 +81027,7 @@ var init_ProbeAgent = __esm({
81010
81027
  this.allowedFolders = [process.cwd()];
81011
81028
  }
81012
81029
  this.clientApiProvider = options.provider || null;
81030
+ this.clientApiModel = options.model || null;
81013
81031
  this.clientApiKey = null;
81014
81032
  this.clientApiUrl = null;
81015
81033
  this.tokenCounter = new TokenCounter();
@@ -81131,8 +81149,9 @@ var init_ProbeAgent = __esm({
81131
81149
  * Initialize the AI model based on available API keys and forced provider setting
81132
81150
  */
81133
81151
  initializeModel() {
81152
+ const modelName = this.clientApiModel || process.env.MODEL_NAME;
81134
81153
  if (process.env.NODE_ENV === "test" || process.env.USE_MOCK_AI === "true") {
81135
- this.initializeMockModel();
81154
+ this.initializeMockModel(modelName);
81136
81155
  return;
81137
81156
  }
81138
81157
  const anthropicApiKey = process.env.ANTHROPIC_API_KEY || process.env.ANTHROPIC_AUTH_TOKEN;
@@ -81148,7 +81167,6 @@ var init_ProbeAgent = __esm({
81148
81167
  const openaiApiUrl = process.env.OPENAI_API_URL || llmBaseUrl;
81149
81168
  const googleApiUrl = process.env.GOOGLE_API_URL || llmBaseUrl;
81150
81169
  const awsBedrockBaseUrl = process.env.AWS_BEDROCK_BASE_URL || llmBaseUrl;
81151
- const modelName = process.env.MODEL_NAME;
81152
81170
  const forceProvider = this.clientApiProvider || (process.env.FORCE_PROVIDER ? process.env.FORCE_PROVIDER.toLowerCase() : null);
81153
81171
  if (this.debug) {
81154
81172
  const hasAwsCredentials = !!(awsAccessKeyId && awsSecretAccessKey && awsRegion);
@@ -81407,16 +81425,7 @@ var init_ProbeAgent = __esm({
81407
81425
  }
81408
81426
  return false;
81409
81427
  }
81410
- const mimeTypes = {
81411
- "png": "image/png",
81412
- "jpg": "image/jpeg",
81413
- "jpeg": "image/jpeg",
81414
- "webp": "image/webp",
81415
- "gif": "image/gif",
81416
- "bmp": "image/bmp",
81417
- "svg": "image/svg+xml"
81418
- };
81419
- const mimeType = mimeTypes[extension];
81428
+ const mimeType = IMAGE_MIME_TYPES[extension];
81420
81429
  const fileBuffer = await (0, import_promises2.readFile)(absolutePath);
81421
81430
  const base64Data = fileBuffer.toString("base64");
81422
81431
  const dataUrl = `data:${mimeType};base64,${base64Data}`;
@@ -82682,7 +82691,7 @@ Convert your previous response content into actual JSON data that follows this s
82682
82691
  // Use first allowed folder as primary path
82683
82692
  allowedFolders: [...this.allowedFolders],
82684
82693
  provider: this.clientApiProvider,
82685
- model: this.modelName,
82694
+ model: this.clientApiModel,
82686
82695
  debug: this.debug,
82687
82696
  outline: this.outline,
82688
82697
  maxResponseTokens: this.maxResponseTokens,
package/cjs/index.cjs CHANGED
@@ -35371,6 +35371,23 @@ var init_HookManager = __esm({
35371
35371
  }
35372
35372
  });
35373
35373
 
35374
+ // src/agent/imageConfig.js
35375
+ var SUPPORTED_IMAGE_EXTENSIONS, IMAGE_MIME_TYPES;
35376
+ var init_imageConfig = __esm({
35377
+ "src/agent/imageConfig.js"() {
35378
+ "use strict";
35379
+ SUPPORTED_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "webp", "bmp", "svg"];
35380
+ IMAGE_MIME_TYPES = {
35381
+ "png": "image/png",
35382
+ "jpg": "image/jpeg",
35383
+ "jpeg": "image/jpeg",
35384
+ "webp": "image/webp",
35385
+ "bmp": "image/bmp",
35386
+ "svg": "image/svg+xml"
35387
+ };
35388
+ }
35389
+ });
35390
+
35374
35391
  // src/agent/xmlParsingUtils.js
35375
35392
  function removeThinkingTags(xmlString) {
35376
35393
  let result = xmlString;
@@ -81102,7 +81119,7 @@ var ProbeAgent_exports = {};
81102
81119
  __export(ProbeAgent_exports, {
81103
81120
  ProbeAgent: () => ProbeAgent
81104
81121
  });
81105
- var import_dotenv, import_anthropic, import_openai, import_google, import_ai3, import_crypto5, import_events2, import_fs7, import_promises2, import_path9, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, SUPPORTED_IMAGE_EXTENSIONS, MAX_IMAGE_FILE_SIZE, ProbeAgent;
81122
+ var import_dotenv, import_anthropic, import_openai, import_google, import_ai3, import_crypto5, import_events2, import_fs7, import_promises2, import_path9, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, MAX_IMAGE_FILE_SIZE, ProbeAgent;
81106
81123
  var init_ProbeAgent = __esm({
81107
81124
  "src/agent/ProbeAgent.js"() {
81108
81125
  "use strict";
@@ -81120,6 +81137,7 @@ var init_ProbeAgent = __esm({
81120
81137
  init_tokenCounter();
81121
81138
  init_InMemoryStorageAdapter();
81122
81139
  init_HookManager();
81140
+ init_imageConfig();
81123
81141
  init_tools2();
81124
81142
  init_common();
81125
81143
  init_probeTool();
@@ -81131,7 +81149,6 @@ var init_ProbeAgent = __esm({
81131
81149
  import_dotenv.default.config();
81132
81150
  MAX_TOOL_ITERATIONS = parseInt(process.env.MAX_TOOL_ITERATIONS || "30", 10);
81133
81151
  MAX_HISTORY_MESSAGES = 100;
81134
- SUPPORTED_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "webp", "gif", "bmp", "svg"];
81135
81152
  MAX_IMAGE_FILE_SIZE = 20 * 1024 * 1024;
81136
81153
  ProbeAgent = class _ProbeAgent {
81137
81154
  /**
@@ -81187,6 +81204,7 @@ var init_ProbeAgent = __esm({
81187
81204
  this.allowedFolders = [process.cwd()];
81188
81205
  }
81189
81206
  this.clientApiProvider = options.provider || null;
81207
+ this.clientApiModel = options.model || null;
81190
81208
  this.clientApiKey = null;
81191
81209
  this.clientApiUrl = null;
81192
81210
  this.tokenCounter = new TokenCounter();
@@ -81308,8 +81326,9 @@ var init_ProbeAgent = __esm({
81308
81326
  * Initialize the AI model based on available API keys and forced provider setting
81309
81327
  */
81310
81328
  initializeModel() {
81329
+ const modelName = this.clientApiModel || process.env.MODEL_NAME;
81311
81330
  if (process.env.NODE_ENV === "test" || process.env.USE_MOCK_AI === "true") {
81312
- this.initializeMockModel();
81331
+ this.initializeMockModel(modelName);
81313
81332
  return;
81314
81333
  }
81315
81334
  const anthropicApiKey = process.env.ANTHROPIC_API_KEY || process.env.ANTHROPIC_AUTH_TOKEN;
@@ -81325,7 +81344,6 @@ var init_ProbeAgent = __esm({
81325
81344
  const openaiApiUrl = process.env.OPENAI_API_URL || llmBaseUrl;
81326
81345
  const googleApiUrl = process.env.GOOGLE_API_URL || llmBaseUrl;
81327
81346
  const awsBedrockBaseUrl = process.env.AWS_BEDROCK_BASE_URL || llmBaseUrl;
81328
- const modelName = process.env.MODEL_NAME;
81329
81347
  const forceProvider = this.clientApiProvider || (process.env.FORCE_PROVIDER ? process.env.FORCE_PROVIDER.toLowerCase() : null);
81330
81348
  if (this.debug) {
81331
81349
  const hasAwsCredentials = !!(awsAccessKeyId && awsSecretAccessKey && awsRegion);
@@ -81584,16 +81602,7 @@ var init_ProbeAgent = __esm({
81584
81602
  }
81585
81603
  return false;
81586
81604
  }
81587
- const mimeTypes = {
81588
- "png": "image/png",
81589
- "jpg": "image/jpeg",
81590
- "jpeg": "image/jpeg",
81591
- "webp": "image/webp",
81592
- "gif": "image/gif",
81593
- "bmp": "image/bmp",
81594
- "svg": "image/svg+xml"
81595
- };
81596
- const mimeType = mimeTypes[extension];
81605
+ const mimeType = IMAGE_MIME_TYPES[extension];
81597
81606
  const fileBuffer = await (0, import_promises2.readFile)(absolutePath);
81598
81607
  const base64Data = fileBuffer.toString("base64");
81599
81608
  const dataUrl = `data:${mimeType};base64,${base64Data}`;
@@ -82859,7 +82868,7 @@ Convert your previous response content into actual JSON data that follows this s
82859
82868
  // Use first allowed folder as primary path
82860
82869
  allowedFolders: [...this.allowedFolders],
82861
82870
  provider: this.clientApiProvider,
82862
- model: this.modelName,
82871
+ model: this.clientApiModel,
82863
82872
  debug: this.debug,
82864
82873
  outline: this.outline,
82865
82874
  maxResponseTokens: this.maxResponseTokens,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@probelabs/probe",
3
- "version": "0.6.0-rc152",
3
+ "version": "0.6.0-rc154",
4
4
  "description": "Node.js wrapper for the probe code search tool",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
@@ -23,6 +23,9 @@
23
23
  },
24
24
  "./agent/mcp": {
25
25
  "import": "./src/agent/mcp/index.js"
26
+ },
27
+ "./agent/imageConfig": {
28
+ "import": "./src/agent/imageConfig.js"
26
29
  }
27
30
  },
28
31
  "bin": {
@@ -17,6 +17,7 @@ import { resolve, isAbsolute, dirname } from 'path';
17
17
  import { TokenCounter } from './tokenCounter.js';
18
18
  import { InMemoryStorageAdapter } from './storage/InMemoryStorageAdapter.js';
19
19
  import { HookManager, HOOK_TYPES } from './hooks/HookManager.js';
20
+ import { SUPPORTED_IMAGE_EXTENSIONS, IMAGE_MIME_TYPES } from './imageConfig.js';
20
21
  import {
21
22
  createTools,
22
23
  searchToolDefinition,
@@ -58,8 +59,7 @@ import {
58
59
  const MAX_TOOL_ITERATIONS = parseInt(process.env.MAX_TOOL_ITERATIONS || '30', 10);
59
60
  const MAX_HISTORY_MESSAGES = 100;
60
61
 
61
- // Supported image file extensions
62
- const SUPPORTED_IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'webp', 'gif', 'bmp', 'svg'];
62
+ // Supported image file extensions (imported from shared config)
63
63
 
64
64
  // Maximum image file size (20MB) to prevent OOM attacks
65
65
  const MAX_IMAGE_FILE_SIZE = 20 * 1024 * 1024;
@@ -134,6 +134,7 @@ export class ProbeAgent {
134
134
 
135
135
  // API configuration
136
136
  this.clientApiProvider = options.provider || null;
137
+ this.clientApiModel = options.model || null;
137
138
  this.clientApiKey = null; // Will be set from environment
138
139
  this.clientApiUrl = null;
139
140
 
@@ -302,9 +303,12 @@ export class ProbeAgent {
302
303
  * Initialize the AI model based on available API keys and forced provider setting
303
304
  */
304
305
  initializeModel() {
306
+ // Get model override if provided (options.model takes precedence over environment variable)
307
+ const modelName = this.clientApiModel || process.env.MODEL_NAME;
308
+
305
309
  // Check if we're in test mode and should use mock provider
306
310
  if (process.env.NODE_ENV === 'test' || process.env.USE_MOCK_AI === 'true') {
307
- this.initializeMockModel();
311
+ this.initializeMockModel(modelName);
308
312
  return;
309
313
  }
310
314
 
@@ -327,9 +331,6 @@ export class ProbeAgent {
327
331
  const googleApiUrl = process.env.GOOGLE_API_URL || llmBaseUrl;
328
332
  const awsBedrockBaseUrl = process.env.AWS_BEDROCK_BASE_URL || llmBaseUrl;
329
333
 
330
- // Get model override if provided
331
- const modelName = process.env.MODEL_NAME;
332
-
333
334
  // Use client-forced provider or environment variable
334
335
  const forceProvider = this.clientApiProvider || (process.env.FORCE_PROVIDER ? process.env.FORCE_PROVIDER.toLowerCase() : null);
335
336
 
@@ -671,17 +672,8 @@ export class ProbeAgent {
671
672
  return false;
672
673
  }
673
674
 
674
- // Determine MIME type
675
- const mimeTypes = {
676
- 'png': 'image/png',
677
- 'jpg': 'image/jpeg',
678
- 'jpeg': 'image/jpeg',
679
- 'webp': 'image/webp',
680
- 'gif': 'image/gif',
681
- 'bmp': 'image/bmp',
682
- 'svg': 'image/svg+xml'
683
- };
684
- const mimeType = mimeTypes[extension];
675
+ // Determine MIME type (from shared config)
676
+ const mimeType = IMAGE_MIME_TYPES[extension];
685
677
 
686
678
  // Read and encode file asynchronously
687
679
  const fileBuffer = await readFile(absolutePath);
@@ -2216,7 +2208,7 @@ Convert your previous response content into actual JSON data that follows this s
2216
2208
  path: this.allowedFolders[0], // Use first allowed folder as primary path
2217
2209
  allowedFolders: [...this.allowedFolders],
2218
2210
  provider: this.clientApiProvider,
2219
- model: this.modelName,
2211
+ model: this.clientApiModel,
2220
2212
  debug: this.debug,
2221
2213
  outline: this.outline,
2222
2214
  maxResponseTokens: this.maxResponseTokens,
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Shared image format configuration for Probe agent
3
+ *
4
+ * This module centralizes supported image formats and their MIME types
5
+ * to ensure consistency across all components.
6
+ *
7
+ * Note: GIF support was intentionally removed for compatibility with
8
+ * AI models like Google Gemini that don't support animated images.
9
+ */
10
+
11
+ // Supported image file extensions (without leading dot)
12
+ export const SUPPORTED_IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'webp', 'bmp', 'svg'];
13
+
14
+ // MIME type mapping for supported image formats
15
+ export const IMAGE_MIME_TYPES = {
16
+ 'png': 'image/png',
17
+ 'jpg': 'image/jpeg',
18
+ 'jpeg': 'image/jpeg',
19
+ 'webp': 'image/webp',
20
+ 'bmp': 'image/bmp',
21
+ 'svg': 'image/svg+xml'
22
+ };
23
+
24
+ /**
25
+ * Generate a regex pattern string for matching image file extensions
26
+ * @param {string[]} extensions - Array of extensions (without dots)
27
+ * @returns {string} Regex pattern string like "png|jpg|jpeg|webp|bmp|svg"
28
+ */
29
+ export function getExtensionPattern(extensions = SUPPORTED_IMAGE_EXTENSIONS) {
30
+ return extensions.join('|');
31
+ }
32
+
33
+ /**
34
+ * Get MIME type for a file extension
35
+ * @param {string} extension - File extension (without dot)
36
+ * @returns {string|undefined} MIME type or undefined if not supported
37
+ */
38
+ export function getMimeType(extension) {
39
+ return IMAGE_MIME_TYPES[extension.toLowerCase()];
40
+ }