@reconcrap/boss-recommend-mcp 1.3.29 → 1.3.31

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.
@@ -56,6 +56,8 @@ const DEFAULT_VISION_RETRY_MAX_IMAGE_PIXELS = 30000000;
56
56
  const DEFAULT_TEXT_MODEL_CHUNK_SIZE_CHARS = 24000;
57
57
  const DEFAULT_TEXT_MODEL_CHUNK_OVERLAP_CHARS = 1200;
58
58
  const DEFAULT_TEXT_MODEL_MAX_CHUNKS = 12;
59
+ const DEFAULT_LLM_TIMEOUT_MS = 60000;
60
+ const DEFAULT_LLM_MAX_RETRIES = 3;
59
61
  const MAX_EVIDENCE_TOKENS = 12;
60
62
  let visionSharpFactory = null;
61
63
  const PAGE_SCOPE_TAB_STATUS = {
@@ -1326,6 +1328,8 @@ function parseArgs(argv) {
1326
1328
  apiKey: null,
1327
1329
  model: null,
1328
1330
  thinkingLevel: null,
1331
+ llmTimeoutMs: DEFAULT_LLM_TIMEOUT_MS,
1332
+ llmMaxRetries: DEFAULT_LLM_MAX_RETRIES,
1329
1333
  openaiOrganization: null,
1330
1334
  openaiProject: null,
1331
1335
  criteria: null,
@@ -1348,6 +1352,8 @@ function parseArgs(argv) {
1348
1352
  apiKey: false,
1349
1353
  model: false,
1350
1354
  thinkingLevel: false,
1355
+ llmTimeoutMs: false,
1356
+ llmMaxRetries: false,
1351
1357
  criteria: false,
1352
1358
  targetCount: false,
1353
1359
  maxGreetCount: false,
@@ -1381,6 +1387,14 @@ function parseArgs(argv) {
1381
1387
  parsed.thinkingLevel = inlineValue || next;
1382
1388
  parsed.__provided.thinkingLevel = true;
1383
1389
  if (!inlineValue) index += 1;
1390
+ } else if ((token === "--llm-timeout-ms" || token === "--timeout-ms") && (inlineValue || next)) {
1391
+ parsed.llmTimeoutMs = parsePositiveInteger(inlineValue || next) || DEFAULT_LLM_TIMEOUT_MS;
1392
+ parsed.__provided.llmTimeoutMs = true;
1393
+ if (!inlineValue) index += 1;
1394
+ } else if ((token === "--llm-max-retries" || token === "--max-retries") && (inlineValue || next)) {
1395
+ parsed.llmMaxRetries = parsePositiveInteger(inlineValue || next) || DEFAULT_LLM_MAX_RETRIES;
1396
+ parsed.__provided.llmMaxRetries = true;
1397
+ if (!inlineValue) index += 1;
1384
1398
  } else if (token === "--openai-organization" && (inlineValue || next)) {
1385
1399
  parsed.openaiOrganization = inlineValue || next;
1386
1400
  if (!inlineValue) index += 1;
@@ -3340,6 +3354,34 @@ class RecommendScreenCli {
3340
3354
  fs.mkdirSync(this.debugDir, { recursive: true });
3341
3355
  }
3342
3356
 
3357
+ getLlmTimeoutMs() {
3358
+ return parsePositiveInteger(this.args?.llmTimeoutMs) || DEFAULT_LLM_TIMEOUT_MS;
3359
+ }
3360
+
3361
+ getLlmMaxRetries() {
3362
+ return parsePositiveInteger(this.args?.llmMaxRetries) || DEFAULT_LLM_MAX_RETRIES;
3363
+ }
3364
+
3365
+ async fetchWithLlmRetries(label, url, options) {
3366
+ const maxRetries = this.getLlmMaxRetries();
3367
+ let lastError = null;
3368
+ for (let attempt = 1; attempt <= maxRetries; attempt += 1) {
3369
+ try {
3370
+ return await fetch(url, {
3371
+ ...options,
3372
+ signal: AbortSignal.timeout(this.getLlmTimeoutMs())
3373
+ });
3374
+ } catch (error) {
3375
+ lastError = error;
3376
+ if (attempt >= maxRetries) {
3377
+ break;
3378
+ }
3379
+ }
3380
+ }
3381
+ const message = normalizeText(lastError?.message || String(lastError || ""));
3382
+ throw this.buildError(label, `${label} request failed after ${maxRetries} attempts: ${message || "unknown error"}`);
3383
+ }
3384
+
3343
3385
  readPauseControlState() {
3344
3386
  if (!this.pauseControlPath) return { pause_requested: false };
3345
3387
  try {
@@ -5236,7 +5278,7 @@ class RecommendScreenCli {
5236
5278
  if (this.args.openaiOrganization) headers["OpenAI-Organization"] = this.args.openaiOrganization;
5237
5279
  if (this.args.openaiProject) headers["OpenAI-Project"] = this.args.openaiProject;
5238
5280
 
5239
- const response = await fetch(`${baseUrl}/chat/completions`, {
5281
+ const response = await this.fetchWithLlmRetries("VISION_MODEL_FAILED", `${baseUrl}/chat/completions`, {
5240
5282
  method: "POST",
5241
5283
  headers,
5242
5284
  body: JSON.stringify(payload)
@@ -5405,7 +5447,7 @@ class RecommendScreenCli {
5405
5447
  if (this.args.openaiOrganization) headers["OpenAI-Organization"] = this.args.openaiOrganization;
5406
5448
  if (this.args.openaiProject) headers["OpenAI-Project"] = this.args.openaiProject;
5407
5449
 
5408
- const response = await fetch(`${baseUrl}/chat/completions`, {
5450
+ const response = await this.fetchWithLlmRetries("TEXT_MODEL_FAILED", `${baseUrl}/chat/completions`, {
5409
5451
  method: "POST",
5410
5452
  headers,
5411
5453
  body: JSON.stringify(payload)