@bike4mind/cli 0.2.82 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { $ as RegInviteEvents, A as ImageGenerationUsageTransaction, B as OpenAIEmbeddingModel, C as FileEvents, Ct as getViewById, D as GenericCreditAddTransaction, E as GenerateImageToolCallSchema, Et as sanitizeTelemetryError, F as KnowledgeType, G as ProjectEvents, H as Permission, I as LLMEvents, J as QuestMasterParamsSchema, K as PromptMetaZodSchema, L as MiscEvents, M as InboxEvents, N as InviteEvents, O as GenericCreditDeductTransaction, P as InviteType, Q as RechartsChartTypeList, R as ModalEvents, S as FeedbackEvents, St as getMcpProviderMetadata, T as GEMINI_IMAGE_MODELS, Tt as resolveNavigationIntents, U as PermissionDeniedError, V as OpenAIImageGenerationInput, W as ProfileEvents, X as RealtimeVoiceUsageTransaction, Y as REASONING_SUPPORTED_MODELS, Z as ReceivedCreditTransaction, _ as CompletionApiUsageTransaction, _t as VoyageAIEmbeddingModel, a as ApiKeyEvents, at as SpeechToTextModels, b as FIXED_TEMPERATURE_MODELS, bt as getAccessibleDataLakes, c as AppFileEvents, ct as TagType, d as BFL_IMAGE_MODELS, dt as ToolUsageTransaction, et as ResearchModeParamsSchema, f as BFL_SAFETY_TOLERANCE, ft as TransferCreditTransaction, g as ChatModels, gt as VideoModels, h as ChatCompletionCreateInputSchema, ht as VideoGenerationUsageTransaction, i as AiEvents, it as SessionEvents, j as ImageModels, k as ImageEditUsageTransaction, kt as CollectionType, l as ArtifactTypeSchema, lt as TaskScheduleHandler, mt as VIDEO_SIZE_CONSTRAINTS, n as logger, nt as ResearchTaskPeriodicFrequencyType, o as ApiKeyScope, ot as SubscriptionCreditTransaction, p as BedrockEmbeddingModel, pt as UiNavigationEvents, q as PurchaseTransaction, r as ALERT_THRESHOLDS, rt as ResearchTaskType, s as ApiKeyType, st as SupportedFabFileMimeTypes, t as ConfigStore, tt as ResearchTaskExecutionType, u as AuthEvents, ut as TextGenerationUsageTransaction, v as DashboardParamsSchema, vt as XAI_IMAGE_MODELS, w as FriendshipEvents, wt as isGPTImageModel, x as FavoriteDocumentType, xt as getDataLakeTags, y as ElabsEvents, yt as b4mLLMTools, z as ModelBackend } from "./ConfigStore-DTyUBb3A.mjs";
2
+ import { $ as RechartsChartTypeList, A as ImageGenerationUsageTransaction, At as secureParameters, B as NotFoundError, C as FileEvents, Ct as getMcpProviderMetadata, D as GenericCreditAddTransaction, Dt as obfuscateApiKey, E as GenerateImageToolCallSchema, Et as isGPTImageModel, F as KnowledgeType, G as ProfileEvents, H as OpenAIImageGenerationInput, I as LLMEvents, J as PurchaseTransaction, K as ProjectEvents, L as MiscEvents, M as InboxEvents, N as InviteEvents, Nt as CollectionType, O as GenericCreditDeductTransaction, Ot as resolveNavigationIntents, P as InviteType, Q as ReceivedCreditTransaction, R as ModalEvents, S as FeedbackEvents, St as getDataLakeTags, T as GEMINI_IMAGE_MODELS, Tt as isGPTImage2Model, U as Permission, V as OpenAIEmbeddingModel, W as PermissionDeniedError, X as REASONING_SUPPORTED_MODELS, Y as QuestMasterParamsSchema, Z as RealtimeVoiceUsageTransaction, _ as CompletionApiUsageTransaction, _t as VideoModels, a as ApiKeyEvents, at as SessionEvents, b as FIXED_TEMPERATURE_MODELS, bt as b4mLLMTools, c as AppFileEvents, ct as SupportedFabFileMimeTypes, d as BFL_IMAGE_MODELS, dt as TextGenerationUsageTransaction, et as RegInviteEvents, f as BFL_SAFETY_TOLERANCE, ft as ToolUsageTransaction, g as ChatModels, gt as VideoGenerationUsageTransaction, h as ChatCompletionCreateInputSchema, ht as VIDEO_SIZE_CONSTRAINTS, i as AiEvents, it as ResearchTaskType, j as ImageModels, k as ImageEditUsageTransaction, kt as sanitizeTelemetryError, l as ArtifactTypeSchema, lt as TagType, mt as UiNavigationEvents, n as logger, nt as ResearchTaskExecutionType, o as ApiKeyScope, ot as SpeechToTextModels, p as BedrockEmbeddingModel, pt as TransferCreditTransaction, q as PromptMetaZodSchema, r as ALERT_THRESHOLDS, rt as ResearchTaskPeriodicFrequencyType, s as ApiKeyType, st as SubscriptionCreditTransaction, t as ConfigStore, tt as ResearchModeParamsSchema, u as AuthEvents, ut as TaskScheduleHandler, v as DashboardParamsSchema, vt as VoyageAIEmbeddingModel, w as FriendshipEvents, wt as getViewById, x as FavoriteDocumentType, xt as getAccessibleDataLakes, y as ElabsEvents, yt as XAI_IMAGE_MODELS, z as ModelBackend } from "./ConfigStore-DBUmvCfe.mjs";
3
3
  import { n as isPathAllowed, t as assertPathAllowed } from "./pathValidation-CIytuhr3-Dt5dntLx.mjs";
4
4
  import { execFile, execFileSync, spawn } from "child_process";
5
5
  import { createHash, randomBytes } from "crypto";
@@ -14,7 +14,7 @@ import { fdir } from "fdir";
14
14
  import ignore from "ignore";
15
15
  import Fuse from "fuse.js";
16
16
  import "marked";
17
- import { ZodError, z } from "zod";
17
+ import { z } from "zod";
18
18
  import dayjs from "dayjs";
19
19
  import timezone from "dayjs/plugin/timezone.js";
20
20
  import utc from "dayjs/plugin/utc.js";
@@ -997,13 +997,14 @@ var CommandHistoryStore = class {
997
997
  async load() {
998
998
  if (this.history) return this.history;
999
999
  try {
1000
- this.history = (await promises.readFile(this.historyPath, "utf-8")).trim().split("\n").filter((line) => line.length > 0).map((line) => {
1000
+ const entries = (await promises.readFile(this.historyPath, "utf-8")).trim().split("\n").filter((line) => line.length > 0).map((line) => {
1001
1001
  try {
1002
1002
  return JSON.parse(line);
1003
1003
  } catch {
1004
1004
  return null;
1005
1005
  }
1006
- }).filter((entry) => entry !== null).sort((a, b) => b.timestamp - a.timestamp).map((entry) => entry.command);
1006
+ }).filter((entry) => entry !== null);
1007
+ this.history = entries.sort((a, b) => b.timestamp - a.timestamp).map((entry) => entry.command);
1007
1008
  return this.history;
1008
1009
  } catch (error) {
1009
1010
  if (error.code === "ENOENT") {
@@ -1401,8 +1402,11 @@ function preprocessFrontmatter(content) {
1401
1402
  * Hooks are shell commands executed at different points in skill lifecycle
1402
1403
  */
1403
1404
  const HooksSchema = z.object({
1405
+ /** Script to run before skill execution */
1404
1406
  "pre-invoke": z.string().optional(),
1407
+ /** Script to run after successful skill execution */
1405
1408
  "post-invoke": z.string().optional(),
1409
+ /** Script to run when skill execution fails */
1406
1410
  "on-error": z.string().optional()
1407
1411
  }).optional();
1408
1412
  /**
@@ -1448,7 +1452,9 @@ const FrontmatterSchema = z.object({
1448
1452
  variables: z.record(z.string(), z.string()).optional(),
1449
1453
  "allowed-tools": flexibleStringArray,
1450
1454
  context: z.enum(["fork", "inline"]).prefault("inline"),
1455
+ /** When true, skill is hidden from AI's auto-loading in system prompt */
1451
1456
  "disable-model-invocation": z.boolean().prefault(false),
1457
+ /** When false, skill is hidden from /commands menu but still callable */
1452
1458
  "user-invocable": z.boolean().prefault(true),
1453
1459
  hooks: HooksSchema
1454
1460
  });
@@ -1882,6 +1888,12 @@ var ReActAgent = class extends EventEmitter {
1882
1888
  confidenceLog = [];
1883
1889
  /** Confidence scores collected during the current iteration (reset each iteration) */
1884
1890
  iterationConfidences = [];
1891
+ /** Conversation history, promoted from run()-local to instance for checkpoint/resume */
1892
+ messages = [];
1893
+ /** Current iteration count, promoted from run()-local to instance for checkpoint/resume */
1894
+ iterations = 0;
1895
+ /** Whether runIteration() has been initialized (messages built, state reset) */
1896
+ iterationInitialized = false;
1885
1897
  constructor(context) {
1886
1898
  super();
1887
1899
  this.context = {
@@ -1912,6 +1924,7 @@ var ReActAgent = class extends EventEmitter {
1912
1924
  const maxIterations = options.maxIterations ?? this.context.maxIterations ?? 5;
1913
1925
  const temperature = options.temperature ?? this.context.temperature ?? .7;
1914
1926
  const maxTokens = options.maxTokens ?? this.context.maxTokens ?? 4096;
1927
+ const maxHistoryIterations = options.maxHistoryIterations ?? 4;
1915
1928
  let iterations = 0;
1916
1929
  try {
1917
1930
  const messages = [
@@ -1925,6 +1938,7 @@ var ReActAgent = class extends EventEmitter {
1925
1938
  content: query
1926
1939
  }
1927
1940
  ];
1941
+ this.messages = messages;
1928
1942
  messages.forEach((msg, i) => {
1929
1943
  const content = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
1930
1944
  this.context.logger.debug(` [${i}] ${msg.role}: ${content.substring(0, 150)}...`);
@@ -1953,13 +1967,17 @@ var ReActAgent = class extends EventEmitter {
1953
1967
  return result;
1954
1968
  }
1955
1969
  iterations++;
1970
+ this.iterations = iterations;
1956
1971
  if (iterations > 1 && options.iterationDelayMs && options.iterationDelayMs > 0) await new Promise((resolve) => setTimeout(resolve, options.iterationDelayMs));
1957
1972
  this.context.logger.debug(`[ReActAgent] Starting iteration ${iterations}/${maxIterations}`);
1958
1973
  let iterationComplete = false;
1959
1974
  let currentText = "";
1960
1975
  const processedToolIds = /* @__PURE__ */ new Set();
1961
1976
  let hadToolCalls = false;
1962
- if (options.maxHistoryIterations && options.maxHistoryIterations > 0 && iterations > 1) trimConversationHistory(messages, options.maxHistoryIterations);
1977
+ if (maxHistoryIterations > 0 && iterations > 1) {
1978
+ trimConversationHistory(messages, maxHistoryIterations);
1979
+ trimSteps(this.steps, maxHistoryIterations);
1980
+ }
1963
1981
  const cacheStrategy = options.enableCaching ? {
1964
1982
  enableCaching: true,
1965
1983
  cacheSystemPrompt: true,
@@ -2216,9 +2234,366 @@ Remember: You are an autonomous AGENT. Act independently and solve problems proa
2216
2234
  return this.toolCallCount;
2217
2235
  }
2218
2236
  /**
2219
- * Create and emit an action step for a tool use
2237
+ * Serialize the agent's current execution state for persistence.
2238
+ *
2239
+ * Call this after each iteration to create a durable checkpoint that can
2240
+ * survive Lambda timeouts, process restarts, or network failures.
2241
+ * The checkpoint is JSON-serializable and can be stored in MongoDB, DynamoDB, etc.
2220
2242
  */
2221
- emitActionStep(toolUse) {
2243
+ toCheckpoint() {
2244
+ return {
2245
+ iteration: this.iterations,
2246
+ messages: structuredClone(this.messages),
2247
+ steps: structuredClone(this.steps),
2248
+ totalTokens: this.totalTokens,
2249
+ totalInputTokens: this.totalInputTokens,
2250
+ totalOutputTokens: this.totalOutputTokens,
2251
+ totalCacheReadTokens: this.totalCacheReadTokens,
2252
+ totalCacheWriteTokens: this.totalCacheWriteTokens,
2253
+ totalCredits: this.totalCredits,
2254
+ toolCallCount: this.toolCallCount,
2255
+ confidenceLog: structuredClone(this.confidenceLog),
2256
+ iterationConfidences: [...this.iterationConfidences]
2257
+ };
2258
+ }
2259
+ /**
2260
+ * Restore the agent's execution state from a previously saved checkpoint.
2261
+ *
2262
+ * Call this before `runIteration()` to resume execution from where it left off.
2263
+ * The agent will continue from the next iteration after the checkpoint.
2264
+ *
2265
+ * **Important:** The agent context (tools, LLM backend, model) must be compatible
2266
+ * with the checkpoint — tools are rebuilt per Lambda invocation, not serialized.
2267
+ */
2268
+ fromCheckpoint(checkpoint) {
2269
+ this.iterations = checkpoint.iteration;
2270
+ this.messages = structuredClone(checkpoint.messages);
2271
+ this.steps = structuredClone(checkpoint.steps);
2272
+ this.totalTokens = checkpoint.totalTokens;
2273
+ this.totalInputTokens = checkpoint.totalInputTokens;
2274
+ this.totalOutputTokens = checkpoint.totalOutputTokens;
2275
+ this.totalCacheReadTokens = checkpoint.totalCacheReadTokens;
2276
+ this.totalCacheWriteTokens = checkpoint.totalCacheWriteTokens;
2277
+ this.totalCredits = checkpoint.totalCredits;
2278
+ this.toolCallCount = checkpoint.toolCallCount;
2279
+ this.confidenceLog = structuredClone(checkpoint.confidenceLog);
2280
+ this.iterationConfidences = [...checkpoint.iterationConfidences];
2281
+ this.observationQueue = [];
2282
+ this.iterationInitialized = true;
2283
+ }
2284
+ /**
2285
+ * Execute a single ReAct iteration and return the result with a checkpoint.
2286
+ *
2287
+ * This is the serverless-native entry point. Unlike `run()` which loops internally,
2288
+ * `runIteration()` gives the caller control over the execution loop so it can:
2289
+ * - Checkpoint after each iteration (persist to MongoDB)
2290
+ * - Stream progress to the client
2291
+ * - Check timeout watchdog (self-dispatch before Lambda timeout)
2292
+ * - Apply permission prompts between iterations
2293
+ * - Deduct credits per iteration
2294
+ *
2295
+ * **First call:** Pass `query` to initialize the conversation.
2296
+ * **Subsequent calls / resumed from checkpoint:** `query` is ignored (messages already built).
2297
+ *
2298
+ * @param query - The user's question or task. Required on first call, ignored when resumed from checkpoint.
2299
+ * @param options - Run options (maxIterations, temperature, etc.)
2300
+ * @returns Iteration result with step, completion status, and checkpoint
2301
+ *
2302
+ * @remarks
2303
+ * **No `'complete'` event:** Unlike `run()`, this method does not emit a `'complete'` event.
2304
+ * The caller controls the iteration loop and is responsible for detecting completion
2305
+ * via `IterationResult.isComplete`.
2306
+ *
2307
+ * **Not concurrency-safe:** This method mutates agent state (messages, steps, tokens).
2308
+ * Do not call concurrently on the same instance. Designed for single-threaded Lambda execution.
2309
+ *
2310
+ * TODO(#8005): The iteration body (LLM call, tool execution, confidence gating) is
2311
+ * duplicated between run() and runIteration(). Extract into a shared private method
2312
+ * once runIteration() is validated in production. Tracked as a follow-up to avoid
2313
+ * regressing the battle-tested run() path in this PR.
2314
+ */
2315
+ async runIteration(query, options = {}) {
2316
+ const maxIterations = options.maxIterations ?? this.context.maxIterations ?? 5;
2317
+ const temperature = options.temperature ?? this.context.temperature ?? .7;
2318
+ const maxTokens = options.maxTokens ?? this.context.maxTokens ?? 4096;
2319
+ if (!this.iterationInitialized) {
2320
+ if (!query) throw new Error("query is required on the first call to runIteration(). Pass the user query, or call fromCheckpoint() first to resume.");
2321
+ this.steps = [];
2322
+ this.totalTokens = 0;
2323
+ this.totalInputTokens = 0;
2324
+ this.totalOutputTokens = 0;
2325
+ this.totalCredits = 0;
2326
+ this.totalCacheReadTokens = 0;
2327
+ this.totalCacheWriteTokens = 0;
2328
+ this.toolCallCount = 0;
2329
+ this.confidenceLog = [];
2330
+ this.iterationConfidences = [];
2331
+ this.iterations = 0;
2332
+ this.messages = [
2333
+ {
2334
+ role: "system",
2335
+ content: options.context ? `${this.getSystemPrompt()}\n\nAdditional context:\n${options.context}` : this.getSystemPrompt()
2336
+ },
2337
+ ...options.previousMessages || [],
2338
+ {
2339
+ role: "user",
2340
+ content: query
2341
+ }
2342
+ ];
2343
+ this.iterationInitialized = true;
2344
+ }
2345
+ if (this.iterations >= maxIterations) {
2346
+ const finalStep = {
2347
+ type: "final_answer",
2348
+ content: `I reached the maximum number of iterations (${this.iterations}/${maxIterations}) without arriving at a final answer.`,
2349
+ metadata: { timestamp: Date.now() }
2350
+ };
2351
+ this.steps.push(finalStep);
2352
+ return {
2353
+ step: finalStep,
2354
+ allSteps: [finalStep],
2355
+ isComplete: true,
2356
+ reachedMaxIterations: true,
2357
+ checkpoint: this.toCheckpoint()
2358
+ };
2359
+ }
2360
+ if (options.signal?.aborted) {
2361
+ const finalStep = {
2362
+ type: "final_answer",
2363
+ content: "Interrupted",
2364
+ metadata: { timestamp: Date.now() }
2365
+ };
2366
+ this.steps.push(finalStep);
2367
+ return {
2368
+ step: finalStep,
2369
+ allSteps: [finalStep],
2370
+ isComplete: true,
2371
+ reachedMaxIterations: false,
2372
+ checkpoint: this.toCheckpoint()
2373
+ };
2374
+ }
2375
+ const preIterationCheckpoint = this.toCheckpoint();
2376
+ this.iterations++;
2377
+ this.iterationConfidences = [];
2378
+ const iterationSteps = [];
2379
+ try {
2380
+ if (this.iterations > 1 && options.iterationDelayMs && options.iterationDelayMs > 0) await new Promise((resolve) => setTimeout(resolve, options.iterationDelayMs));
2381
+ this.context.logger.debug(`[ReActAgent] Starting iteration ${this.iterations}/${maxIterations}`);
2382
+ const maxHistoryIterations = options.maxHistoryIterations ?? 4;
2383
+ if (maxHistoryIterations > 0 && this.iterations > 1) {
2384
+ trimConversationHistory(this.messages, maxHistoryIterations);
2385
+ trimSteps(this.steps, maxHistoryIterations);
2386
+ }
2387
+ let iterationComplete = false;
2388
+ let currentText = "";
2389
+ let finalAnswer = "";
2390
+ const processedToolIds = /* @__PURE__ */ new Set();
2391
+ let hadToolCalls = false;
2392
+ const cacheStrategy = options.enableCaching ? {
2393
+ enableCaching: true,
2394
+ cacheSystemPrompt: true,
2395
+ cacheTools: this.context.tools.length > 0,
2396
+ cacheConversationHistory: false,
2397
+ cacheTTL: "5m"
2398
+ } : void 0;
2399
+ await this.context.llm.complete(this.context.model, this.messages, {
2400
+ stream: false,
2401
+ tools: this.context.tools,
2402
+ maxTokens,
2403
+ temperature,
2404
+ abortSignal: options.signal,
2405
+ tool_choice: this.context.toolChoice,
2406
+ executeTools: false,
2407
+ thinking: this.context.thinking,
2408
+ cacheStrategy
2409
+ }, async (texts, completionInfo) => {
2410
+ for (const text of texts) if (text) currentText += text;
2411
+ if (completionInfo) {
2412
+ const inputTokens = completionInfo.inputTokens || 0;
2413
+ const outputTokens = completionInfo.outputTokens || 0;
2414
+ this.totalTokens += inputTokens + outputTokens;
2415
+ this.totalInputTokens += inputTokens;
2416
+ this.totalOutputTokens += outputTokens;
2417
+ if (completionInfo.cacheStats) {
2418
+ this.totalCacheReadTokens += completionInfo.cacheStats.cacheReadTokens || 0;
2419
+ this.totalCacheWriteTokens += completionInfo.cacheStats.cacheWriteTokens || 0;
2420
+ }
2421
+ if (completionInfo.creditsUsed) this.totalCredits += completionInfo.creditsUsed;
2422
+ if (currentText.trim() && completionInfo.toolsUsed?.length) {
2423
+ const thoughtStep = {
2424
+ type: "thought",
2425
+ content: currentText.trim(),
2426
+ metadata: { timestamp: Date.now() }
2427
+ };
2428
+ this.steps.push(thoughtStep);
2429
+ iterationSteps.push(thoughtStep);
2430
+ this.emit("thought", thoughtStep);
2431
+ }
2432
+ if (!completionInfo.toolsUsed?.length && currentText.trim()) {
2433
+ finalAnswer = currentText.trim();
2434
+ const finalStep = {
2435
+ type: "final_answer",
2436
+ content: finalAnswer,
2437
+ metadata: {
2438
+ timestamp: Date.now(),
2439
+ tokenUsage: {
2440
+ prompt: inputTokens,
2441
+ completion: outputTokens,
2442
+ total: inputTokens + outputTokens
2443
+ }
2444
+ }
2445
+ };
2446
+ this.steps.push(finalStep);
2447
+ iterationSteps.push(finalStep);
2448
+ this.emit("final_answer", finalStep);
2449
+ iterationComplete = true;
2450
+ }
2451
+ if (completionInfo.toolsUsed && completionInfo.toolsUsed.length > 0) {
2452
+ hadToolCalls = true;
2453
+ const thinkingBlocks = completionInfo.thinking || [];
2454
+ const unprocessedTools = [];
2455
+ for (const toolUse of completionInfo.toolsUsed) {
2456
+ const toolCallIdStr = getToolId(toolUse);
2457
+ if (!processedToolIds.has(toolCallIdStr)) {
2458
+ processedToolIds.add(toolCallIdStr);
2459
+ unprocessedTools.push(toolUse);
2460
+ }
2461
+ }
2462
+ if (unprocessedTools.length > 0) if (options.parallelExecution && shouldUseParallelExecution(unprocessedTools, options.isReadOnlyTool ?? defaultIsReadOnlyTool)) {
2463
+ for (const toolUse of unprocessedTools) {
2464
+ const actionStep = this.buildActionStep(toolUse);
2465
+ iterationSteps.push(actionStep);
2466
+ }
2467
+ const results = await executeToolsInParallel(categorizeTools(unprocessedTools, options.isReadOnlyTool ?? defaultIsReadOnlyTool), (toolUse) => this.executeToolWithQueueFallback(toolUse), options.signal);
2468
+ for (const toolUse of unprocessedTools) {
2469
+ const toolIdStr = getToolId(toolUse);
2470
+ const result = results.get(toolIdStr);
2471
+ const observation = result?.status === "fulfilled" ? result.result ?? "" : `Error: ${result?.error?.message ?? "Unknown error"}`;
2472
+ this.appendToolMessages(this.messages, toolUse, observation, thinkingBlocks);
2473
+ const obsStep = this.buildObservationStep(toolUse.name, observation);
2474
+ iterationSteps.push(obsStep);
2475
+ }
2476
+ } else for (const toolUse of unprocessedTools) {
2477
+ const actionStep = this.buildActionStep(toolUse);
2478
+ iterationSteps.push(actionStep);
2479
+ const queuedObs = this.observationQueue.find((obs) => obs.toolId === getToolId(toolUse));
2480
+ let observation;
2481
+ if (queuedObs) {
2482
+ const result = queuedObs.result;
2483
+ const index = this.observationQueue.indexOf(queuedObs);
2484
+ this.observationQueue.splice(index, 1);
2485
+ observation = typeof result === "string" ? result : JSON.stringify(result);
2486
+ } else {
2487
+ observation = await this.executeToolWithQueueFallback(toolUse);
2488
+ this.appendToolMessages(this.messages, toolUse, observation, thinkingBlocks);
2489
+ }
2490
+ const obsStep = this.buildObservationStep(toolUse.name, observation);
2491
+ iterationSteps.push(obsStep);
2492
+ }
2493
+ }
2494
+ }
2495
+ });
2496
+ if (hadToolCalls && options.confidenceGate && this.iterationConfidences.length > 0) {
2497
+ const iterAvg = this.iterationConfidences.reduce((a, b) => a + b, 0) / this.iterationConfidences.length;
2498
+ const decision = options.confidenceGate(iterAvg, this.iterations);
2499
+ if (decision.action === "wait_for_human" || decision.action === "timed_gate") {
2500
+ const eventName = decision.action === "wait_for_human" ? "gate_paused" : "gate_timed";
2501
+ this.emit(eventName, {
2502
+ ...decision,
2503
+ iteration: this.iterations
2504
+ });
2505
+ finalAnswer = `[${decision.action === "wait_for_human" ? "Paused for review" : "Timed gate"} — confidence ${(iterAvg * 100).toFixed(0)}%] ${decision.reason}`;
2506
+ const gateStep = {
2507
+ type: "final_answer",
2508
+ content: finalAnswer,
2509
+ metadata: { timestamp: Date.now() }
2510
+ };
2511
+ this.steps.push(gateStep);
2512
+ iterationSteps.push(gateStep);
2513
+ return {
2514
+ step: gateStep,
2515
+ allSteps: iterationSteps,
2516
+ isComplete: true,
2517
+ reachedMaxIterations: false,
2518
+ checkpoint: this.toCheckpoint()
2519
+ };
2520
+ }
2521
+ this.emit("gate_proceed", {
2522
+ ...decision,
2523
+ iteration: this.iterations
2524
+ });
2525
+ }
2526
+ this.iterationConfidences = [];
2527
+ if (!iterationComplete && hadToolCalls) this.messages.push({
2528
+ role: "user",
2529
+ content: "Based on the tool results above, please provide a complete answer. If I asked for multiple things, make sure to address all of them."
2530
+ });
2531
+ if (!iterationComplete && this.iterations >= maxIterations) {
2532
+ finalAnswer = currentText.trim() || `I reached the maximum number of iterations (${this.iterations}/${maxIterations}) without arriving at a final answer.`;
2533
+ const maxStep = {
2534
+ type: "final_answer",
2535
+ content: finalAnswer,
2536
+ metadata: { timestamp: Date.now() }
2537
+ };
2538
+ this.steps.push(maxStep);
2539
+ iterationSteps.push(maxStep);
2540
+ this.emit("final_answer", maxStep);
2541
+ return {
2542
+ step: maxStep,
2543
+ allSteps: iterationSteps,
2544
+ isComplete: true,
2545
+ reachedMaxIterations: true,
2546
+ checkpoint: this.toCheckpoint()
2547
+ };
2548
+ }
2549
+ return {
2550
+ step: iterationSteps.find((s) => s.type === "final_answer") || iterationSteps[iterationSteps.length - 1] || {
2551
+ type: "thought",
2552
+ content: currentText.trim() || "No output from this iteration",
2553
+ metadata: { timestamp: Date.now() }
2554
+ },
2555
+ allSteps: iterationSteps,
2556
+ isComplete: iterationComplete,
2557
+ reachedMaxIterations: false,
2558
+ checkpoint: this.toCheckpoint()
2559
+ };
2560
+ } catch (error) {
2561
+ this.fromCheckpoint(preIterationCheckpoint);
2562
+ if (error instanceof PermissionDeniedError) {
2563
+ this.context.logger.info(`[ReActAgent] Permission denied for tool '${error.toolName}' in runIteration - ending gracefully`);
2564
+ const errorStep = {
2565
+ type: "final_answer",
2566
+ content: `Permission denied for tool '${error.toolName}'.`,
2567
+ metadata: { timestamp: Date.now() }
2568
+ };
2569
+ this.steps.push(errorStep);
2570
+ iterationSteps.push(errorStep);
2571
+ return {
2572
+ step: errorStep,
2573
+ allSteps: iterationSteps,
2574
+ isComplete: true,
2575
+ reachedMaxIterations: false,
2576
+ checkpoint: this.toCheckpoint()
2577
+ };
2578
+ }
2579
+ this.context.logger.error("[ReActAgent] Error during runIteration:", error);
2580
+ this.emit("error", error);
2581
+ throw error;
2582
+ }
2583
+ }
2584
+ /**
2585
+ * Reset the iteration state so the next `runIteration()` call starts fresh.
2586
+ * Call this when starting a new query (not when resuming from checkpoint).
2587
+ * The next `runIteration()` call will re-initialize all state from scratch.
2588
+ */
2589
+ resetIteration() {
2590
+ this.iterationInitialized = false;
2591
+ }
2592
+ /**
2593
+ * Build an action step, increment tool call count, push to steps, and emit.
2594
+ * Returns the step for callers that need to collect iteration steps.
2595
+ */
2596
+ buildActionStep(toolUse) {
2222
2597
  this.toolCallCount++;
2223
2598
  const actionStep = {
2224
2599
  type: "action",
@@ -2231,11 +2606,19 @@ Remember: You are an autonomous AGENT. Act independently and solve problems proa
2231
2606
  };
2232
2607
  this.steps.push(actionStep);
2233
2608
  this.emit("action", actionStep);
2609
+ return actionStep;
2234
2610
  }
2235
2611
  /**
2236
- * Create and emit an observation step, scoring confidence for the result
2612
+ * Create and emit an action step for a tool use (delegates to buildActionStep)
2237
2613
  */
2238
- emitObservationStep(toolName, observation) {
2614
+ emitActionStep(toolUse) {
2615
+ this.buildActionStep(toolUse);
2616
+ }
2617
+ /**
2618
+ * Build an observation step, score confidence, push to steps, and emit.
2619
+ * Returns the step for callers that need to collect iteration steps.
2620
+ */
2621
+ buildObservationStep(toolName, observation) {
2239
2622
  const confidence = this.scoreToolResult(toolName, observation);
2240
2623
  const confidenceSource = observation.startsWith("Error:") ? "deterministic" : "default";
2241
2624
  this.confidenceLog.push({
@@ -2257,6 +2640,13 @@ Remember: You are an autonomous AGENT. Act independently and solve problems proa
2257
2640
  };
2258
2641
  this.steps.push(observationStep);
2259
2642
  this.emit("observation", observationStep);
2643
+ return observationStep;
2644
+ }
2645
+ /**
2646
+ * Create and emit an observation step, scoring confidence for the result
2647
+ */
2648
+ emitObservationStep(toolName, observation) {
2649
+ this.buildObservationStep(toolName, observation);
2260
2650
  }
2261
2651
  /**
2262
2652
  * Score the confidence of a tool result.
@@ -2313,6 +2703,22 @@ Remember: You are an autonomous AGENT. Act independently and solve problems proa
2313
2703
  }
2314
2704
  };
2315
2705
  /**
2706
+ * Trim the steps array to keep only the last N iterations worth of steps.
2707
+ *
2708
+ * Each iteration produces 1-5 steps (thought, action(s), observation(s), final_answer).
2709
+ * With parallel tool calls an iteration can produce more: 1 thought + N actions + N observations.
2710
+ * For 3 parallel tools = 7 steps, so we use 7 as the estimate.
2711
+ * The failure mode is benign: over-trim loses old steps (harmless), under-trim keeps
2712
+ * a few extra (also harmless — bounded by the next trim call).
2713
+ */
2714
+ function trimSteps(steps, maxIterations) {
2715
+ const maxSteps = maxIterations * 7;
2716
+ if (steps.length > maxSteps) {
2717
+ const removeCount = steps.length - maxSteps;
2718
+ steps.splice(0, removeCount);
2719
+ }
2720
+ }
2721
+ /**
2316
2722
  * Trim conversation history to keep only the initial messages (system + user query)
2317
2723
  * plus the last N iterations of assistant/tool/user messages.
2318
2724
  *
@@ -2880,10 +3286,6 @@ var Logger = class Logger {
2880
3286
  });
2881
3287
  };
2882
3288
  dotenv.config();
2883
- function obfuscateApiKey(apiKey) {
2884
- if (!apiKey) return apiKey;
2885
- return `${apiKey.slice(0, 3)}${"*".repeat(apiKey.length - 6)}${apiKey.slice(-3)}`;
2886
- }
2887
3289
  /**
2888
3290
  * Execute an array of async tasks either in parallel (with concurrency limiting)
2889
3291
  * or sequentially, returning outcomes in the original order.
@@ -2966,50 +3368,6 @@ async function handleToolResultStreaming(toolName, toolResult, streamCallback) {
2966
3368
  }
2967
3369
  promisify(dns.resolve4);
2968
3370
  promisify(dns.resolve6);
2969
- let HttpStatus = /* @__PURE__ */ function(HttpStatus) {
2970
- HttpStatus[HttpStatus["Ok"] = 200] = "Ok";
2971
- HttpStatus[HttpStatus["Created"] = 201] = "Created";
2972
- HttpStatus[HttpStatus["BadRequest"] = 400] = "BadRequest";
2973
- HttpStatus[HttpStatus["Unauthorized"] = 401] = "Unauthorized";
2974
- HttpStatus[HttpStatus["Forbidden"] = 403] = "Forbidden";
2975
- HttpStatus[HttpStatus["NotFound"] = 404] = "NotFound";
2976
- HttpStatus[HttpStatus["UnprocessableEntity"] = 422] = "UnprocessableEntity";
2977
- HttpStatus[HttpStatus["TooManyRequests"] = 429] = "TooManyRequests";
2978
- HttpStatus[HttpStatus["InternalServerError"] = 500] = "InternalServerError";
2979
- return HttpStatus;
2980
- }({});
2981
- var HTTPError = class extends Error {
2982
- constructor(statusCode, message, additionalInfo) {
2983
- super(message);
2984
- this.statusCode = statusCode;
2985
- this.additionalInfo = additionalInfo;
2986
- this.name = "HTTPError";
2987
- }
2988
- };
2989
- var InternalServerError = class extends HTTPError {
2990
- constructor(message, additionalInfo) {
2991
- super(HttpStatus.InternalServerError, message, additionalInfo);
2992
- this.additionalInfo = additionalInfo;
2993
- this.name = "InternalServerError";
2994
- }
2995
- };
2996
- var NotFoundError = class extends HTTPError {
2997
- constructor(message, additionalInfo) {
2998
- super(HttpStatus.NotFound, message, additionalInfo);
2999
- this.additionalInfo = additionalInfo;
3000
- this.name = "NotFoundError";
3001
- }
3002
- };
3003
- var UnprocessableEntityError = class extends HTTPError {
3004
- constructor(message, additionalInfo) {
3005
- super(HttpStatus.UnprocessableEntity, message, additionalInfo);
3006
- this.additionalInfo = additionalInfo;
3007
- this.name = "UnprocessableEntityError";
3008
- }
3009
- };
3010
- function isZodError(err) {
3011
- return Boolean(err && (err instanceof ZodError || err.name === "ZodError"));
3012
- }
3013
3371
  SupportedFabFileMimeTypes.TXT_PLAIN, SupportedFabFileMimeTypes.TXT_MARKDOWN, SupportedFabFileMimeTypes.TXT_MD_LEGACY, SupportedFabFileMimeTypes.HTML, SupportedFabFileMimeTypes.CSV, SupportedFabFileMimeTypes.JPG, SupportedFabFileMimeTypes.PNG, SupportedFabFileMimeTypes.PDF, SupportedFabFileMimeTypes.JSON, SupportedFabFileMimeTypes.DOCX, SupportedFabFileMimeTypes.XLSX, SupportedFabFileMimeTypes.XLS, SupportedFabFileMimeTypes.JS, SupportedFabFileMimeTypes.JSX, SupportedFabFileMimeTypes.TS, SupportedFabFileMimeTypes.PY, SupportedFabFileMimeTypes.JAVA, SupportedFabFileMimeTypes.CPP, SupportedFabFileMimeTypes.CS, SupportedFabFileMimeTypes.PHP, SupportedFabFileMimeTypes.RUBY, SupportedFabFileMimeTypes.GO, SupportedFabFileMimeTypes.SWIFT, SupportedFabFileMimeTypes.KOTLIN, SupportedFabFileMimeTypes.RUST, SupportedFabFileMimeTypes.CSS, SupportedFabFileMimeTypes.LESS, SupportedFabFileMimeTypes.SASS, SupportedFabFileMimeTypes.SCSS, SupportedFabFileMimeTypes.YAML, SupportedFabFileMimeTypes.TOML, SupportedFabFileMimeTypes.SH, SupportedFabFileMimeTypes.BASH;
3014
3372
  /**
3015
3373
  * Anthropic-specific caching adapter
@@ -3676,6 +4034,7 @@ const GPT5_4_MODELS = [
3676
4034
  ChatModels.GPT5_4_MINI,
3677
4035
  ChatModels.GPT5_4_NANO
3678
4036
  ];
4037
+ const GPT5_5_MODELS = [ChatModels.GPT5_5];
3679
4038
  const effortMap = {
3680
4039
  simple: "low",
3681
4040
  contextual: "low",
@@ -3904,6 +4263,28 @@ var OpenAIBackend = class {
3904
4263
  description: "OpenAI's compact reasoning model optimized for fast, cost-efficient performance with strong multimodal and agentic capabilities. Excellent for STEM tasks and coding.",
3905
4264
  isSlowModel: true
3906
4265
  },
4266
+ {
4267
+ id: ChatModels.GPT5_5,
4268
+ type: "text",
4269
+ name: "GPT-5.5",
4270
+ backend: ModelBackend.OpenAI,
4271
+ contextWindow: 105e4,
4272
+ max_tokens: 128e3,
4273
+ can_stream: true,
4274
+ can_think: false,
4275
+ pricing: { 105e4: {
4276
+ input: 5 / 1e6,
4277
+ output: 30 / 1e6
4278
+ } },
4279
+ supportsVision: true,
4280
+ supportsImageVariation: false,
4281
+ supportsTools: true,
4282
+ logoFile: "OpenAI_Logo.svg",
4283
+ rank: 0,
4284
+ trainingCutoff: "2025-12-01",
4285
+ releaseDate: "2026-04-27",
4286
+ description: "OpenAI's next-generation flagship GPT-5.5 model. A new class of intelligence for coding and professional work with a 1M+ context window, advanced reasoning, vision, and tool use."
4287
+ },
3907
4288
  {
3908
4289
  id: ChatModels.GPT5_4,
3909
4290
  type: "text",
@@ -3924,7 +4305,7 @@ var OpenAIBackend = class {
3924
4305
  rank: 1,
3925
4306
  trainingCutoff: "2025-08-31",
3926
4307
  releaseDate: "2026-03-05",
3927
- description: "OpenAI's latest and most capable GPT model. Flagship of the GPT-5 family with top-tier reasoning, creativity, and vision understanding."
4308
+ description: "High-performing GPT-5.4 model with strong reasoning, creativity, and vision understanding. A reliable workhorse in the GPT-5 family."
3928
4309
  },
3929
4310
  {
3930
4311
  id: ChatModels.GPT5_4_MINI,
@@ -4255,6 +4636,22 @@ var OpenAIBackend = class {
4255
4636
  description: "OpenAI GPT-Image-1.5 - Enhanced version of GPT-Image-1 with improved image generation quality and text integration, supporting up to 2048x2048 resolution and image editing capabilities.",
4256
4637
  rank: 9
4257
4638
  },
4639
+ {
4640
+ id: ImageModels.GPT_IMAGE_2,
4641
+ type: "image",
4642
+ name: "GPT-Image-2",
4643
+ backend: ModelBackend.OpenAI,
4644
+ contextWindow: 1e4,
4645
+ supportsImageVariation: true,
4646
+ max_tokens: 1e4,
4647
+ pricing: { 1: {
4648
+ input: 8 / 1e6,
4649
+ output: 30 / 1e6
4650
+ } },
4651
+ description: "OpenAI GPT-Image-2 - State-of-the-art image generation with flexible resolutions up to 4K, improved quality, and fast generation. Supports editing and multi-image reference inputs.",
4652
+ rank: 8,
4653
+ releaseDate: "2026-04-21"
4654
+ },
4258
4655
  {
4259
4656
  id: ImageModels.GPT_IMAGE_1_MINI,
4260
4657
  type: "image",
@@ -4360,7 +4757,8 @@ var OpenAIBackend = class {
4360
4757
  const isGPT5_1Model = GPT5_1_MODELS.includes(model);
4361
4758
  const isGPT5_2Model = GPT5_2_MODELS.includes(model);
4362
4759
  const isGPT5_4Model = GPT5_4_MODELS.includes(model);
4363
- const usesMaxCompletionTokens = isO1Model || isGPT5Model || isGPT5_1Model || isGPT5_2Model || isGPT5_4Model;
4760
+ const isGPT5_5Model = GPT5_5_MODELS.includes(model);
4761
+ const usesMaxCompletionTokens = isO1Model || isGPT5Model || isGPT5_1Model || isGPT5_2Model || isGPT5_4Model || isGPT5_5Model;
4364
4762
  const parameters = {
4365
4763
  model,
4366
4764
  messages: this.formatMessages(messages, isO1Model, model, options),
@@ -4751,7 +5149,7 @@ var OpenAIBackend = class {
4751
5149
  formatMessages(messages, isO1Model, model, options) {
4752
5150
  const filteredMessages = isO1Model ? messages.filter((msg) => msg.role !== "system") : messages;
4753
5151
  const toolNames = options.tools?.map((tool) => tool.toolSchema.name) || [];
4754
- const isGPT5Family = GPT5_MODELS.includes(model) || GPT5_1_MODELS.includes(model) || GPT5_2_MODELS.includes(model) || GPT5_4_MODELS.includes(model);
5152
+ const isGPT5Family = GPT5_MODELS.includes(model) || GPT5_1_MODELS.includes(model) || GPT5_2_MODELS.includes(model) || GPT5_4_MODELS.includes(model) || GPT5_5_MODELS.includes(model);
4755
5153
  let systemContent;
4756
5154
  if (isGPT5Family) {
4757
5155
  systemContent = "You are a helpful assistant.";
@@ -4792,14 +5190,6 @@ var OpenAIBackend = class {
4792
5190
  }));
4793
5191
  }
4794
5192
  };
4795
- function secureParameters(params, schema) {
4796
- try {
4797
- return schema.parse(params);
4798
- } catch (e) {
4799
- if (isZodError(e)) throw new UnprocessableEntityError(e.issues.map((err) => `${err.path.join(".")}: ${err.message}`).join(", "));
4800
- throw new InternalServerError();
4801
- }
4802
- }
4803
5193
  var NotificationDeduplicator = class {
4804
5194
  errorGroups = /* @__PURE__ */ new Map();
4805
5195
  lowCreditTiers = {};
@@ -4923,28 +5313,22 @@ async function postMessageToSlack(slackWebhookUrl, message) {
4923
5313
  Logger.error("Error posting message to Slack:", error);
4924
5314
  }
4925
5315
  }
4926
- let EmbeddingModelProvider = /* @__PURE__ */ function(EmbeddingModelProvider) {
4927
- EmbeddingModelProvider["OPENAI"] = "OpenAI";
4928
- EmbeddingModelProvider["BEDROCK"] = "Amazon Bedrock";
4929
- EmbeddingModelProvider["VOYAGE_AI"] = "Voyage AI";
4930
- return EmbeddingModelProvider;
4931
- }({});
4932
- BedrockEmbeddingModel.TITAN_TEXT_EMBEDDINGS_V2, EmbeddingModelProvider.BEDROCK, BedrockEmbeddingModel.TITAN_TEXT_EMBEDDINGS_V2;
5316
+ BedrockEmbeddingModel.TITAN_TEXT_EMBEDDINGS_V2, BedrockEmbeddingModel.TITAN_TEXT_EMBEDDINGS_V2;
4933
5317
  const OPENAI_EMBEDDING_MODEL_MAP = {
4934
5318
  [OpenAIEmbeddingModel.TEXT_EMBEDDING_3_SMALL]: {
4935
- provider: EmbeddingModelProvider.OPENAI,
5319
+ provider: "OpenAI",
4936
5320
  model: OpenAIEmbeddingModel.TEXT_EMBEDDING_3_SMALL,
4937
5321
  contextWindow: 8192,
4938
5322
  dimensions: [1536]
4939
5323
  },
4940
5324
  [OpenAIEmbeddingModel.TEXT_EMBEDDING_3_LARGE]: {
4941
- provider: EmbeddingModelProvider.OPENAI,
5325
+ provider: "OpenAI",
4942
5326
  model: OpenAIEmbeddingModel.TEXT_EMBEDDING_3_LARGE,
4943
5327
  contextWindow: 8192,
4944
5328
  dimensions: [3072]
4945
5329
  },
4946
5330
  [OpenAIEmbeddingModel.TEXT_EMBEDDING_ADA_002]: {
4947
- provider: EmbeddingModelProvider.OPENAI,
5331
+ provider: "OpenAI",
4948
5332
  model: OpenAIEmbeddingModel.TEXT_EMBEDDING_ADA_002,
4949
5333
  contextWindow: 8192,
4950
5334
  dimensions: [1536]
@@ -5147,7 +5531,7 @@ const OPENAI_EMBEDDING_MODEL_MAP = {
5147
5531
  return OPENAI_EMBEDDING_MODEL_MAP[this.model];
5148
5532
  }
5149
5533
  });
5150
- VoyageAIEmbeddingModel.VOYAGE_3_LARGE, EmbeddingModelProvider.VOYAGE_AI, VoyageAIEmbeddingModel.VOYAGE_3_LARGE, VoyageAIEmbeddingModel.VOYAGE_3, EmbeddingModelProvider.VOYAGE_AI, VoyageAIEmbeddingModel.VOYAGE_3, VoyageAIEmbeddingModel.VOYAGE_3_LITE, EmbeddingModelProvider.VOYAGE_AI, VoyageAIEmbeddingModel.VOYAGE_3_LITE, VoyageAIEmbeddingModel.VOYAGE_CODE_3, EmbeddingModelProvider.VOYAGE_AI, VoyageAIEmbeddingModel.VOYAGE_CODE_3, VoyageAIEmbeddingModel.VOYAGE_FINANCE_3, EmbeddingModelProvider.VOYAGE_AI, VoyageAIEmbeddingModel.VOYAGE_FINANCE_3, VoyageAIEmbeddingModel.VOYAGE_LAW_3, EmbeddingModelProvider.VOYAGE_AI, VoyageAIEmbeddingModel.VOYAGE_LAW_3;
5534
+ VoyageAIEmbeddingModel.VOYAGE_3_LARGE, VoyageAIEmbeddingModel.VOYAGE_3_LARGE, VoyageAIEmbeddingModel.VOYAGE_3, VoyageAIEmbeddingModel.VOYAGE_3, VoyageAIEmbeddingModel.VOYAGE_3_LITE, VoyageAIEmbeddingModel.VOYAGE_3_LITE, VoyageAIEmbeddingModel.VOYAGE_CODE_3, VoyageAIEmbeddingModel.VOYAGE_CODE_3, VoyageAIEmbeddingModel.VOYAGE_FINANCE_3, VoyageAIEmbeddingModel.VOYAGE_FINANCE_3, VoyageAIEmbeddingModel.VOYAGE_LAW_3, VoyageAIEmbeddingModel.VOYAGE_LAW_3;
5151
5535
  z.object({
5152
5536
  text: z.string(),
5153
5537
  tokenCount: z.number()
@@ -5164,7 +5548,7 @@ z.object({
5164
5548
  */
5165
5549
  const MAX_GOAL_LENGTH = 1e3;
5166
5550
  const MAX_DESCRIPTION_LENGTH = 2e3;
5167
- ChatModels.GPT5, ChatModels.GPT5_MINI, ChatModels.GPT5_NANO, ChatModels.GPT5_1, ChatModels.GPT5_2, ChatModels.GPT5_4, ChatModels.GPT5_4_MINI, ChatModels.GPT5_4_NANO;
5551
+ ChatModels.GPT5, ChatModels.GPT5_MINI, ChatModels.GPT5_NANO, ChatModels.GPT5_1, ChatModels.GPT5_2, ChatModels.GPT5_4, ChatModels.GPT5_4_MINI, ChatModels.GPT5_4_NANO, ChatModels.GPT5_5;
5168
5552
  /**
5169
5553
  * Invokes the image processor Lambda to convert and resize images
5170
5554
  * This is a serverless alternative to using sharp directly
@@ -5256,18 +5640,34 @@ var OpenAIImageService = class extends AIImageService {
5256
5640
  parameterWarnings.push(`Quality parameter ('${openaiOptions.quality}') is not supported by ${modelName} text-to-image generation and was removed`);
5257
5641
  delete openaiOptions.quality;
5258
5642
  }
5259
- const validGPTSizes = [
5260
- "1024x1024",
5261
- "1536x1024",
5262
- "1024x1536"
5263
- ];
5264
- if (openaiOptions.size) {
5265
- if (!validGPTSizes.includes(openaiOptions.size)) {
5266
- const originalSize = openaiOptions.size;
5267
- openaiOptions.size = "1024x1024";
5268
- parameterWarnings.push(`Size '${originalSize}' is not supported by ${modelName}, changed to '1024x1024'`);
5269
- }
5270
- } else openaiOptions.size = "1024x1024";
5643
+ if (isGPTImage2Model(options.model)) {
5644
+ if (openaiOptions.size && openaiOptions.size !== "auto") {
5645
+ const [w, h] = openaiOptions.size.split("x").map(Number);
5646
+ if (w && h) {
5647
+ const maxEdge = Math.max(w, h);
5648
+ const minEdge = Math.min(w, h);
5649
+ const totalPixels = w * h;
5650
+ if (maxEdge > 3840 || w % 16 !== 0 || h % 16 !== 0 || maxEdge / minEdge > 3 || totalPixels < 655360 || totalPixels > 8294400) {
5651
+ const originalSize = openaiOptions.size;
5652
+ openaiOptions.size = "1024x1024";
5653
+ parameterWarnings.push(`Size '${originalSize}' violates gpt-image-2 constraints, changed to '1024x1024'`);
5654
+ }
5655
+ }
5656
+ } else if (!openaiOptions.size) openaiOptions.size = "auto";
5657
+ } else {
5658
+ const validGPTSizes = [
5659
+ "1024x1024",
5660
+ "1536x1024",
5661
+ "1024x1536"
5662
+ ];
5663
+ if (openaiOptions.size) {
5664
+ if (!validGPTSizes.includes(openaiOptions.size)) {
5665
+ const originalSize = openaiOptions.size;
5666
+ openaiOptions.size = "1024x1024";
5667
+ parameterWarnings.push(`Size '${originalSize}' is not supported by ${modelName}, changed to '1024x1024'`);
5668
+ }
5669
+ } else openaiOptions.size = "1024x1024";
5670
+ }
5271
5671
  if ("width" in openaiOptions || "height" in openaiOptions) {
5272
5672
  delete openaiOptions.width;
5273
5673
  delete openaiOptions.height;
@@ -5302,7 +5702,7 @@ var OpenAIImageService = class extends AIImageService {
5302
5702
  const pngBuffer = await invokeImageProcessor(imageBuffer, this.imageProcessorLambdaName, 4);
5303
5703
  const imageFile = new File([pngBuffer], "image.png", { type: "image/png" });
5304
5704
  if (isGPTImageModel(options.model)) {
5305
- const editModel = options.model || ImageModels.GPT_IMAGE_1_5;
5705
+ const editModel = options.model || ImageModels.GPT_IMAGE_2;
5306
5706
  result = await openai.images.edit({
5307
5707
  model: editModel,
5308
5708
  image: [imageFile],
@@ -5361,7 +5761,7 @@ If you believe this is an error, you can report it to OpenAI with request ID: ${
5361
5761
  throw new Error(`Image response contains neither url nor b64_json: ${JSON.stringify(Object.keys(imageData))}`);
5362
5762
  });
5363
5763
  }
5364
- async edit(image, prompt, { mask = null, model = ImageModels.GPT_IMAGE_1_5, n = 1, size, response_format = "url", user }) {
5764
+ async edit(image, prompt, { mask = null, model = ImageModels.GPT_IMAGE_2, n = 1, size, response_format = "url", user }) {
5365
5765
  try {
5366
5766
  const openai = new OpenAI({ apiKey: this.apiKey });
5367
5767
  const cleanImageBase64 = image.replace(/^data:image\/(png|jpeg|jpg);base64,/, "");
@@ -5379,8 +5779,8 @@ If you believe this is an error, you can report it to OpenAI with request ID: ${
5379
5779
  }
5380
5780
  let editModel = model;
5381
5781
  if (!isGPTImageModel(model) && model !== ImageModels.DALL_E_2) {
5382
- console.log(`[DEBUG] ⚠️ Edit endpoint doesn't support ${model}, defaulting to gpt-image-1.5`);
5383
- editModel = ImageModels.GPT_IMAGE_1_5;
5782
+ console.log(`[DEBUG] ⚠️ Edit endpoint doesn't support ${model}, defaulting to gpt-image-2`);
5783
+ editModel = ImageModels.GPT_IMAGE_2;
5384
5784
  }
5385
5785
  const response = await openai.images.edit(isGPTImageModel(editModel) ? {
5386
5786
  model: editModel,
@@ -6141,6 +6541,12 @@ z.object({
6141
6541
  type: z.enum(KnowledgeType),
6142
6542
  content: z.union([z.string(), z.instanceof(Buffer)]).optional(),
6143
6543
  organizationId: z.string().optional(),
6544
+ /**
6545
+ * Content type of the file
6546
+ * @example 'text/markdown'
6547
+ * @example 'application/pdf'
6548
+ * @example 'application/octet-stream' for binary files
6549
+ */
6144
6550
  contentType: z.string().optional(),
6145
6551
  public: z.boolean().optional(),
6146
6552
  prefix: z.string().optional(),
@@ -8314,7 +8720,7 @@ No markdown, no explanation, no code blocks — just the raw JSON object.`;
8314
8720
  "Minimize: sum(error^2)"
8315
8721
  ].join("\n");
8316
8722
  //#endregion
8317
- //#region ../../b4m-core/services/dist/tools-M5WOOsBu.mjs
8723
+ //#region ../../b4m-core/services/dist/tools-s4H4po60.mjs
8318
8724
  async function performDeepResearch(context, params, config) {
8319
8725
  const maxDepth = config.maxDepth || 7;
8320
8726
  const duration = config.duration || 4.5;
@@ -8794,8 +9200,8 @@ const imageGenerationTool = {
8794
9200
  return "Image model selection required. A model picker has been presented to the user.";
8795
9201
  }
8796
9202
  const { prompt, n: toolN, quality: toolQuality, size: toolSize, safety_tolerance: toolSafetyTolerance } = val;
8797
- let model = imageConfig?.model || ImageModels.GPT_IMAGE_1_5;
8798
- if (model === ImageModels.GPT_IMAGE_1) model = ImageModels.GPT_IMAGE_1_5;
9203
+ let model = imageConfig?.model || ImageModels.GPT_IMAGE_2;
9204
+ if (model === ImageModels.GPT_IMAGE_1) model = ImageModels.GPT_IMAGE_2;
8799
9205
  const n = toolN ?? imageConfig?.n ?? 1;
8800
9206
  const quality = imageConfig?.quality || toolQuality;
8801
9207
  const size = imageConfig?.size || toolSize;
@@ -9894,6 +10300,7 @@ const EDIT_SUPPORTED_MODELS = [
9894
10300
  ImageModels.GPT_IMAGE_1,
9895
10301
  ImageModels.GPT_IMAGE_1_5,
9896
10302
  ImageModels.GPT_IMAGE_1_MINI,
10303
+ ImageModels.GPT_IMAGE_2,
9897
10304
  ImageModels.FLUX_PRO_FILL,
9898
10305
  ImageModels.GEMINI_2_5_FLASH_IMAGE,
9899
10306
  ImageModels.GEMINI_3_PRO_IMAGE_PREVIEW
@@ -14549,7 +14956,11 @@ z.object({
14549
14956
  search: z.string().optional().prefault(""),
14550
14957
  type: z.enum(CollectionType).optional()
14551
14958
  });
14552
- z.object({ userId: z.string() });
14959
+ z.object({
14960
+ /**
14961
+ * The user to recalculate the storage for
14962
+ */
14963
+ userId: z.string() });
14553
14964
  z.object({
14554
14965
  coverage: z.enum(["all", "important"]).prefault("important"),
14555
14966
  userId: z.string().optional()
@@ -14827,10 +15238,17 @@ z.object({ sessionId: z.string() });
14827
15238
  z.object({ sessionId: z.string() });
14828
15239
  z.object({
14829
15240
  sessionId: z.string(),
15241
+ /** The maximum number of words to include in the title */
14830
15242
  maxWords: z.number().optional()
14831
15243
  });
14832
15244
  z.object({
15245
+ /**
15246
+ * Text search query (searches in name and description)
15247
+ */
14833
15248
  query: z.string().optional(),
15249
+ /**
15250
+ * Filter by personal organizations
15251
+ */
14834
15252
  filters: z.object({
14835
15253
  personal: z.union([z.enum(["true", "false"]).transform((val) => val === "true"), z.boolean()]).optional(),
14836
15254
  userId: z.string().optional()
@@ -14854,7 +15272,11 @@ z.object({
14854
15272
  direction: "asc"
14855
15273
  })
14856
15274
  });
14857
- z.object({ id: z.string().min(1) });
15275
+ z.object({
15276
+ /**
15277
+ * Organization ID
15278
+ */
15279
+ id: z.string().min(1) });
14858
15280
  z.object({
14859
15281
  userId: z.string().optional(),
14860
15282
  email: z.string().optional(),
@@ -14862,7 +15284,11 @@ z.object({
14862
15284
  force: z.boolean().optional()
14863
15285
  });
14864
15286
  z.object({ id: z.string() });
14865
- z.object({ id: z.string().min(1) });
15287
+ z.object({
15288
+ /**
15289
+ * Organization ID
15290
+ */
15291
+ id: z.string().min(1) });
14866
15292
  z.object({ organizationId: z.string() });
14867
15293
  z.object({ id: z.string() });
14868
15294
  z.object({ id: z.string() });
@@ -14930,9 +15356,12 @@ z.object({
14930
15356
  direction: z.enum(["asc", "desc"])
14931
15357
  }).optional(),
14932
15358
  options: z.object({
15359
+ textSearch: z.coerce.boolean().optional(),
14933
15360
  includeShared: z.coerce.boolean().optional(),
14934
15361
  userGroups: z.array(z.string()).optional(),
14935
- dataLakeTags: z.array(z.string()).optional()
15362
+ dataLakeTags: z.array(z.string()).optional(),
15363
+ dataLakeTagPrefixes: z.array(z.string()).optional(),
15364
+ excludeContent: z.coerce.boolean().optional()
14936
15365
  }).optional()
14937
15366
  });
14938
15367
  z.object({ fileId: z.string() });
@@ -14958,11 +15387,13 @@ z.object({
14958
15387
  });
14959
15388
  z.object({
14960
15389
  id: z.string(),
15390
+ /** The user ID of the recipient of the friend request */
14961
15391
  userId: z.string(),
14962
15392
  accept: z.boolean()
14963
15393
  });
14964
15394
  z.object({
14965
15395
  friendshipId: z.string(),
15396
+ /** The user ID of the user who wants to unfriend the other user */
14966
15397
  userId: z.string()
14967
15398
  });
14968
15399
  z.object({ userId: z.string() });
@@ -14972,6 +15403,9 @@ z.object({ key: z.string() });
14972
15403
  z.object({
14973
15404
  key: z.string(),
14974
15405
  value: z.any(),
15406
+ /**
15407
+ * Time to live in milliseconds
15408
+ */
14975
15409
  ttl: z.number(),
14976
15410
  recache: z.boolean().optional()
14977
15411
  });
@@ -14993,7 +15427,11 @@ z.object({
14993
15427
  });
14994
15428
  z.object({ id: z.string() });
14995
15429
  z.object({ id: z.string() });
14996
- z.object({ id: z.string() });
15430
+ z.object({
15431
+ /**
15432
+ * The ID of the research agent
15433
+ */
15434
+ id: z.string() });
14997
15435
  z.object({ id: z.string() });
14998
15436
  const researchTaskCreateSchema = z.object({
14999
15437
  researchAgentId: z.string(),
@@ -15365,8 +15803,11 @@ z.object({
15365
15803
  content: z.union([z.string(), z.array(z.any())]),
15366
15804
  fabFileIds: z.array(z.string()).optional()
15367
15805
  })).optional(),
15806
+ /** User's timezone (IANA format, e.g., "America/New_York") */
15368
15807
  timezone: z.string().optional(),
15808
+ /** Persona-based sub-agent filter — only these agent names are available for delegation */
15369
15809
  allowedAgents: z.array(z.string()).optional(),
15810
+ /** When true, Quest Processor injects Slack-specific tool configs (help, notebooks, curated files) */
15370
15811
  enableSlackTools: z.boolean().optional()
15371
15812
  });
15372
15813
  /**
@@ -18251,7 +18692,7 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
18251
18692
  return result;
18252
18693
  }
18253
18694
  if (!permissionManager.needsPermission(toolName, { isSandboxed })) return executeAndRecord();
18254
- const { useCliStore } = await import("./store-nZExNOWX.mjs");
18695
+ const { useCliStore } = await import("./store-B_ILRSdP.mjs");
18255
18696
  if (useCliStore.getState().autoAcceptEdits) return executeAndRecord();
18256
18697
  const response = await showPermissionPrompt(toolName, effectiveArgs, await generateToolPreview(toolName, args, isSandboxed));
18257
18698
  if (response.action === "deny") throw new PermissionDeniedError(toolName, args);
@@ -18974,7 +19415,7 @@ var MCPClient = class {
18974
19415
  console.log(`[MCP] Using server: ${this.serverName} at ${serverScriptPath}`);
18975
19416
  }
18976
19417
  const stderrMode = this.suppressStderr ? "ignore" : this.onStderrLine ? "pipe" : void 0;
18977
- this.transport = new StdioClientTransport({
19418
+ const transportConfig = {
18978
19419
  command,
18979
19420
  args,
18980
19421
  env: {
@@ -18982,14 +19423,16 @@ var MCPClient = class {
18982
19423
  ...envVarsObject
18983
19424
  },
18984
19425
  ...stderrMode && { stderr: stderrMode }
18985
- });
19426
+ };
19427
+ this.transport = new StdioClientTransport(transportConfig);
18986
19428
  this.transport.onerror = (error) => {
18987
19429
  console.error(`[MCP] Transport error for ${this.serverName}:`, error);
18988
19430
  };
18989
19431
  await this.mcp.connect(this.transport);
18990
19432
  if (this.onStderrLine && this.transport.stderr) this.readStderr(this.transport.stderr);
18991
19433
  await new Promise((resolve) => setTimeout(resolve, 100));
18992
- this.tools = (await this.mcp.listTools()).tools.map((tool) => {
19434
+ const toolsResult = await this.mcp.listTools();
19435
+ this.tools = toolsResult.tools.map((tool) => {
18993
19436
  return {
18994
19437
  name: tool.name,
18995
19438
  description: tool.description,
@@ -19539,9 +19982,13 @@ var ServerLlmBackend = class ServerLlmBackend {
19539
19982
  this.MAX_STREAM_RETRIES = 2;
19540
19983
  }
19541
19984
  constructor(options) {
19542
- this.completionsEndpoint = "/api/ai/v1/completions";
19543
19985
  this.apiClient = options.apiClient;
19544
19986
  this.currentModel = options.model;
19987
+ if (options.completionsUrl) this.completionsEndpoint = options.completionsUrl;
19988
+ else {
19989
+ logger.debug("[ServerLlmBackend] No completionsUrl from server — is sst dev running?");
19990
+ this.completionsEndpoint = "/api/ai/v1/completions";
19991
+ }
19545
19992
  }
19546
19993
  /**
19547
19994
  * Make authenticated LLM completion request via server
@@ -20841,7 +21288,8 @@ var SubagentOrchestrator = class {
20841
21288
  const { result: agentResult, attempts } = await withRetry(() => agent.run(task, {
20842
21289
  maxIterations,
20843
21290
  parallelExecution: this.deps.enableParallelToolExecution === true,
20844
- isReadOnlyTool
21291
+ isReadOnlyTool,
21292
+ maxHistoryIterations: 4
20845
21293
  }), {
20846
21294
  maxRetries: agentDef.retry.maxRetries,
20847
21295
  initialDelayMs: agentDef.retry.initialDelayMs,
@@ -21110,6 +21558,7 @@ const MODEL_ALIASES = {
21110
21558
  "gpt-5.4": ChatModels.GPT5_4,
21111
21559
  "gpt-5.4-mini": ChatModels.GPT5_4_MINI,
21112
21560
  "gpt-5.4-nano": ChatModels.GPT5_4_NANO,
21561
+ "gpt-5.5": ChatModels.GPT5_5,
21113
21562
  o1: ChatModels.O1,
21114
21563
  "o1-preview": ChatModels.O1_PREVIEW,
21115
21564
  "o1-mini": ChatModels.O1_MINI,
@@ -21952,8 +22401,11 @@ function createBackgroundAgentTools(manager) {
21952
22401
  * Schema for a single decomposed task in the pipeline
21953
22402
  */
21954
22403
  const DecomposedTaskSchema = z.object({
22404
+ /** Unique identifier for this task within the pipeline */
21955
22405
  id: z.string().min(1),
22406
+ /** Human-readable description of what needs to be done */
21956
22407
  description: z.string().min(1),
22408
+ /** Which agent type should handle this task */
21957
22409
  agentType: z.enum([
21958
22410
  "explore",
21959
22411
  "plan",
@@ -21961,6 +22413,7 @@ const DecomposedTaskSchema = z.object({
21961
22413
  "review",
21962
22414
  "test"
21963
22415
  ]),
22416
+ /** IDs of tasks that must complete before this one can start */
21964
22417
  dependsOn: z.array(z.string()).default([])
21965
22418
  });
21966
22419
  /**
@@ -23000,7 +23453,7 @@ function createGetFileStructureTool() {
23000
23453
  if (stats.isDirectory()) return `Error: Path is a directory, not a file: ${params.path}`;
23001
23454
  if (stats.size > MAX_FILE_SIZE) return `Error: File too large (${(stats.size / 1024 / 1024).toFixed(2)}MB). Max: ${MAX_FILE_SIZE / 1024 / 1024}MB`;
23002
23455
  const ext = path.extname(resolvedPath).toLowerCase();
23003
- const { getLanguageForExtension, parseFileStructure, getSupportedLanguages } = await import("./treeSitterEngine-DCSXcm_3.mjs");
23456
+ const { getLanguageForExtension, parseFileStructure, getSupportedLanguages } = await import("./treeSitterEngine-BFTHnDwH.mjs");
23004
23457
  const languageId = getLanguageForExtension(ext);
23005
23458
  if (!languageId) return `Error: Unsupported file type "${ext}". Supported languages: ${getSupportedLanguages().join(", ")}`;
23006
23459
  const sourceCode = await promises.readFile(resolvedPath, "utf-8");