@bike4mind/cli 0.2.66 → 0.2.67-feat-tavern-leveling-system.21886

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,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { $ as RegInviteEvents, A as ImageGenerationUsageTransaction, B as OpenAIEmbeddingModel, C as FileEvents, Ct as isGPTImageModel, D as GenericCreditAddTransaction, E as GenerateImageToolCallSchema, 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, Ot as CollectionType, P as InviteType, Q as RechartsChartTypeList, R as ModalEvents, S as FeedbackEvents, St as getViewById, T as GEMINI_IMAGE_MODELS, Tt as sanitizeTelemetryError, 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 getDataLakeTags, 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, 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 resolveNavigationIntents, x as FavoriteDocumentType, xt as getMcpProviderMetadata, y as ElabsEvents, yt as b4mLLMTools, z as ModelBackend } from "./ConfigStore-DRYo2iO1.mjs";
3
- import { n as isPathAllowed, t as assertPathAllowed } from "./pathValidation-Cgjh5WQO-DiCZTcq6.mjs";
2
+ import { $ as RegInviteEvents, A as ImageGenerationUsageTransaction, B as OpenAIEmbeddingModel, C as FileEvents, Ct as isGPTImageModel, D as GenericCreditAddTransaction, E as GenerateImageToolCallSchema, 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, Ot as CollectionType, P as InviteType, Q as RechartsChartTypeList, R as ModalEvents, S as FeedbackEvents, St as getViewById, T as GEMINI_IMAGE_MODELS, Tt as sanitizeTelemetryError, 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 getDataLakeTags, 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, 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 resolveNavigationIntents, x as FavoriteDocumentType, xt as getMcpProviderMetadata, y as ElabsEvents, yt as b4mLLMTools, z as ModelBackend } from "./ConfigStore-Ylkl1TGh.mjs";
3
+ import { n as isPathAllowed, t as assertPathAllowed } from "./pathValidation-B8P0stPW-DMWmrxnc.mjs";
4
4
  import { execFile, execFileSync, spawn } from "child_process";
5
5
  import { createHash, randomBytes } from "crypto";
6
6
  import { existsSync, promises, readFileSync, readdirSync, rmSync, statSync, unlinkSync, writeFileSync } from "fs";
@@ -48,9 +48,16 @@ import "mammoth";
48
48
  import "unpdf";
49
49
  import "@aws-sdk/client-apigatewaymanagementapi";
50
50
  import { InvokeCommand, LambdaClient } from "@aws-sdk/client-lambda";
51
+ import FirecrawlApp, { FirecrawlError } from "@mendable/firecrawl-js";
52
+ import * as Diff from "diff";
53
+ import { diffLines } from "diff";
54
+ import random from "lodash/random.js";
55
+ import sum from "lodash/sum.js";
56
+ import times from "lodash/times.js";
57
+ import { all, create } from "mathjs";
58
+ import ExcelJS from "exceljs";
51
59
  import "speakeasy";
52
60
  import "qrcode";
53
- import FirecrawlApp, { FirecrawlError } from "@mendable/firecrawl-js";
54
61
  import "lodash/throttle.js";
55
62
  import "lodash/range.js";
56
63
  import "bcryptjs";
@@ -59,8 +66,6 @@ import "yauzl";
59
66
  import "lodash/last.js";
60
67
  import "lodash/uniq.js";
61
68
  import "lodash/isEqual.js";
62
- import * as Diff from "diff";
63
- import { diffLines } from "diff";
64
69
  import "turndown";
65
70
  import "@joplin/turndown-plugin-gfm";
66
71
  import "cheerio";
@@ -71,17 +76,12 @@ import "@opensearch-project/opensearch/aws-v3";
71
76
  import "openai/uploads";
72
77
  import "@aws-sdk/client-transcribe";
73
78
  import { Mutex } from "async-mutex";
74
- import random from "lodash/random.js";
75
- import sum from "lodash/sum.js";
76
- import times from "lodash/times.js";
77
- import { all, create } from "mathjs";
78
- import ExcelJS from "exceljs";
79
79
  import "zod-validation-error";
80
80
  import { homedir as homedir$1 } from "node:os";
81
81
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
82
82
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
83
83
  import { fileURLToPath } from "url";
84
- import WebSocket from "ws";
84
+ import WsWebSocket from "ws";
85
85
  import { createParser } from "eventsource-parser";
86
86
  import { createRequire } from "module";
87
87
  //#region src/utils/fileSearch.ts
@@ -5991,14 +5991,6 @@ z.object({
5991
5991
  relativePath: z.string().optional()
5992
5992
  });
5993
5993
  //#endregion
5994
- //#region ../../b4m-core/packages/services/dist/mfaService/utils.mjs
5995
- const originalEmitWarning = process.emitWarning;
5996
- process.emitWarning = (warning, name) => {
5997
- if (name === "DeprecationWarning" && warning?.toString().includes("Buffer")) return;
5998
- return originalEmitWarning.call(process, warning, name);
5999
- };
6000
- process.emitWarning = originalEmitWarning;
6001
- //#endregion
6002
5994
  //#region ../../b4m-core/packages/services/dist/llm/tools/implementation/websearch/index.mjs
6003
5995
  async function serpApiSearch(adapters, query, num_results) {
6004
5996
  const apiKey = await getSerperKey(adapters);
@@ -6243,122 +6235,6 @@ const webFetchTool = {
6243
6235
  })
6244
6236
  };
6245
6237
  //#endregion
6246
- //#region ../../b4m-core/packages/services/dist/askUserQuestion-Bsx9OWmD.mjs
6247
- let _showUserQuestion = null;
6248
- /**
6249
- * Inject the CLI callback that displays the question UI.
6250
- * Called once during CLI startup wiring.
6251
- */
6252
- function setShowUserQuestionFn(fn) {
6253
- _showUserQuestion = fn;
6254
- }
6255
- function validateArgs(args) {
6256
- if (args === null || typeof args !== "object") return { error: "Invalid arguments: expected an object." };
6257
- const obj = args;
6258
- if (!Array.isArray(obj.questions) || obj.questions.length === 0) return { error: "At least one question is required." };
6259
- if (obj.questions.length > 4) return { error: `Maximum 4 questions allowed.` };
6260
- const questions = [];
6261
- for (const raw of obj.questions) {
6262
- if (raw === null || typeof raw !== "object") return { error: "Each question must be an object." };
6263
- const q = raw;
6264
- if (typeof q.question !== "string" || q.question.trim() === "") return { error: "Each question must have a non-empty \"question\" string." };
6265
- if (!Array.isArray(q.options)) return { error: `Question "${q.question}" must have an "options" array.` };
6266
- const options = [];
6267
- for (const rawOpt of q.options.slice(0, 4)) {
6268
- if (rawOpt === null || typeof rawOpt !== "object") continue;
6269
- const opt = rawOpt;
6270
- options.push({
6271
- label: typeof opt.label === "string" ? opt.label : "(untitled)",
6272
- description: typeof opt.description === "string" ? opt.description : ""
6273
- });
6274
- }
6275
- if (options.length < 2) return { error: `Question "${q.question}" must have at least 2 options.` };
6276
- questions.push({
6277
- question: q.question,
6278
- options,
6279
- multiSelect: q.multiSelect === true ? true : void 0
6280
- });
6281
- }
6282
- return { questions };
6283
- }
6284
- const askUserQuestionTool = {
6285
- name: "ask_user_question",
6286
- implementation: () => ({
6287
- toolFn: async (args) => {
6288
- if (!_showUserQuestion) return JSON.stringify({ error: "ask_user_question is only available in the CLI environment." });
6289
- const validated = validateArgs(args);
6290
- if ("error" in validated) return JSON.stringify({ error: validated.error });
6291
- const payload = { questions: validated.questions.map((q) => ({
6292
- question: q.question,
6293
- options: q.options,
6294
- multiSelect: q.multiSelect === true
6295
- })) };
6296
- const response = await _showUserQuestion(payload);
6297
- return JSON.stringify(response);
6298
- },
6299
- toolSchema: {
6300
- name: "ask_user_question",
6301
- description: `Ask the user one or more structured questions with selectable options. Use this when you need clarification, user preferences, or decisions. Each question has 2-4 options. The user can also provide free-text via "Other". For multiSelect questions, the user can pick multiple options.`,
6302
- parameters: {
6303
- type: "object",
6304
- properties: { questions: {
6305
- type: "array",
6306
- description: `Array of questions to ask (1-4 questions)`,
6307
- minItems: 1,
6308
- maxItems: 4,
6309
- items: {
6310
- type: "object",
6311
- properties: {
6312
- question: {
6313
- type: "string",
6314
- description: "The question to ask. Should be clear and end with a question mark."
6315
- },
6316
- options: {
6317
- type: "array",
6318
- description: `Available choices (2-4 options). An "Other" free-text option is always appended automatically.`,
6319
- minItems: 2,
6320
- maxItems: 4,
6321
- items: {
6322
- type: "object",
6323
- properties: {
6324
- label: {
6325
- type: "string",
6326
- description: "Short display text for this option (1-5 words)"
6327
- },
6328
- description: {
6329
- type: "string",
6330
- description: "Explanation of what this option means"
6331
- }
6332
- },
6333
- required: ["label", "description"]
6334
- }
6335
- },
6336
- multiSelect: {
6337
- type: "boolean",
6338
- description: "If true, the user can select multiple options. Default: false.",
6339
- default: false
6340
- }
6341
- },
6342
- required: ["question", "options"]
6343
- }
6344
- } },
6345
- required: ["questions"]
6346
- }
6347
- }
6348
- })
6349
- };
6350
- z.object({
6351
- rootCause: z.string(),
6352
- proposedFix: z.string(),
6353
- confidence: z.number().min(0).max(100),
6354
- riskAssessment: z.string(),
6355
- affectedFiles: z.array(z.object({
6356
- filePath: z.string(),
6357
- before: z.string().min(1),
6358
- after: z.string()
6359
- })).max(10)
6360
- });
6361
- //#endregion
6362
6238
  //#region ../../b4m-core/packages/quantum/dist/index.mjs
6363
6239
  const OperationSchema = z.object({
6364
6240
  jobId: z.number(),
@@ -8203,1207 +8079,352 @@ No markdown, no explanation, no code blocks — just the raw JSON object.`;
8203
8079
  " \\/ <- fit here",
8204
8080
  "Minimize: sum(error^2)"
8205
8081
  ].join("\n");
8206
- z.object({
8207
- count: z.number().optional(),
8208
- unlimitedUse: z.boolean().optional(),
8209
- expiresAt: z.date().optional(),
8210
- tags: z.array(z.string().min(1).max(100)).max(20).optional(),
8211
- startingCredits: z.number().int().min(0).max(1e6).optional(),
8212
- startingStorage: z.number().int().min(0).max(1e5).optional()
8213
- });
8214
- z.object({ ids: z.array(z.string()) });
8215
- z.object({
8216
- usernameOrEmail: z.string(),
8217
- password: z.string(),
8218
- metadata: z.object({
8219
- loginTime: z.date(),
8220
- userAgent: z.string(),
8221
- browser: z.string(),
8222
- operatingSystem: z.string(),
8223
- deviceType: z.string(),
8224
- screenResolution: z.string(),
8225
- viewportSize: z.string(),
8226
- colorDepth: z.number(),
8227
- pixelDepth: z.number(),
8228
- devicePixelRatio: z.number(),
8229
- ip: z.string().optional().prefault(""),
8230
- location: z.string().optional()
8231
- }).optional()
8232
- });
8233
- z.object({ email: z.email() });
8234
- const updateUserSchema = z.object({
8235
- name: z.string().optional(),
8236
- username: z.string().optional(),
8237
- password: z.string().nullable().optional(),
8238
- team: z.string().nullable().optional(),
8239
- role: z.string().nullable().optional(),
8240
- phone: z.string().nullable().optional(),
8241
- preferredLanguage: z.string().nullable().optional(),
8242
- preferredContact: z.string().nullable().optional(),
8243
- preferredVoice: z.string().nullable().optional(),
8244
- preferredReasoningEffort: z.enum([
8245
- "auto",
8246
- "none",
8247
- "minimal",
8248
- "low",
8249
- "medium",
8250
- "high",
8251
- "xhigh"
8252
- ]).nullable().optional(),
8253
- tshirtSize: z.string().nullable().optional(),
8254
- geoLocation: z.string().nullable().optional(),
8255
- lastNotebookId: z.string().nullable().optional(),
8256
- tags: z.array(z.string()).nullable().optional(),
8257
- lastCreditsPurchasedAt: z.date().nullable().optional(),
8258
- systemFiles: z.array(z.object({
8259
- fileId: z.string(),
8260
- enabled: z.boolean()
8261
- })).nullable().optional(),
8262
- securityQuestions: z.array(z.object({
8263
- question: z.string(),
8264
- answer: z.string()
8265
- })).nullable().optional(),
8266
- photoUrl: z.string().nullable().optional(),
8267
- showCreditsUsed: z.boolean().optional(),
8268
- preferences: z.object({
8269
- language: z.string().optional(),
8270
- favoriteTags: z.array(z.string()).optional(),
8271
- favoriteModelIds: z.array(z.string()).optional(),
8272
- fileBrowserViewMode: z.enum([
8273
- "home",
8274
- "list",
8275
- "grid",
8276
- "tags"
8277
- ]).optional(),
8278
- optiSessionId: z.string().nullable().optional(),
8279
- lastUsedTextModel: z.string().nullable().optional(),
8280
- lastUsedImageModel: z.string().nullable().optional(),
8281
- lastUsedImageEditModel: z.string().nullable().optional(),
8282
- showDebug: z.boolean().optional(),
8283
- showHelp: z.boolean().optional(),
8284
- maxVisibleLines: z.number().optional(),
8285
- autoCollapseContent: z.boolean().optional(),
8286
- enableAutoScroll: z.boolean().optional(),
8287
- scrollbarWidth: z.number().optional(),
8288
- experimentalFeatures: z.record(z.string(), z.boolean()).optional(),
8289
- rechartsDisplayMode: z.enum(["inline", "artifact"]).optional(),
8290
- docxTemplateFileId: z.string().nullable().optional()
8291
- }).nullable().optional()
8292
- });
8293
- z.object({
8294
- requesterId: z.string(),
8295
- recipientId: z.string(),
8296
- message: z.string().optional()
8297
- });
8298
- updateUserSchema.extend({
8299
- id: z.string(),
8300
- email: z.email().optional(),
8301
- role: z.string().optional().nullable(),
8302
- isAdmin: z.boolean().optional(),
8303
- organizationId: z.string().optional().nullable(),
8304
- storageLimit: z.number().optional(),
8305
- currentCredits: z.number().optional(),
8306
- isBanned: z.boolean().optional(),
8307
- isModerated: z.boolean().optional(),
8308
- subscribedUntil: z.string().optional().nullable(),
8309
- systemFiles: z.array(z.object({
8310
- fileId: z.string(),
8311
- enabled: z.boolean()
8312
- })).optional(),
8313
- level: z.enum([
8314
- "DemoUser",
8315
- "PaidUser",
8316
- "VIPUser",
8317
- "ManagerUser",
8318
- "AdminUser"
8319
- ]).optional(),
8320
- lastNotebookId: z.string().optional().nullable(),
8321
- userNotes: z.array(z.object({
8322
- timestamp: z.string(),
8323
- note: z.string(),
8324
- userName: z.string()
8325
- })).optional(),
8326
- numReferralsAvailable: z.number().optional()
8327
- });
8328
- z.object({
8329
- username: z.string(),
8330
- email: z.string(),
8331
- name: z.string(),
8332
- inviteCode: z.string(),
8333
- password: z.string(),
8334
- metadata: z.object({
8335
- loginTime: z.date(),
8336
- userAgent: z.string(),
8337
- browser: z.string(),
8338
- operatingSystem: z.string(),
8339
- deviceType: z.string(),
8340
- screenResolution: z.string(),
8341
- viewportSize: z.string(),
8342
- colorDepth: z.number(),
8343
- pixelDepth: z.number(),
8344
- devicePixelRatio: z.number(),
8345
- ip: z.string().optional().prefault(""),
8346
- location: z.string().optional()
8347
- }).optional()
8348
- });
8349
- z.object({ id: z.string() });
8350
- z.object({
8351
- userId: z.string(),
8352
- page: z.coerce.number().optional().prefault(1),
8353
- limit: z.coerce.number().optional().prefault(10),
8354
- search: z.string().optional().prefault(""),
8355
- type: z.enum(CollectionType).optional()
8356
- });
8357
- z.object({ userId: z.string() });
8358
- z.object({
8359
- coverage: z.enum(["all", "important"]).prefault("important"),
8360
- userId: z.string().optional()
8361
- });
8362
- SessionEvents.CREATE_SESSION, SessionEvents.UPDATE_SESSION, SessionEvents.DELETE_SESSION, SessionEvents.CLONE_SESSION, FileEvents.CREATE_FILE, FileEvents.DELETE_FILE, FileEvents.UPDATE_FILE;
8363
- z.object({ userId: z.string() });
8364
- z.object({ token: z.string() });
8365
- z.object({ userId: z.string() });
8366
- z.object({
8367
- userId: z.string(),
8368
- newEmail: z.email(),
8369
- password: z.string()
8370
- });
8371
- z.object({ token: z.string() });
8372
- z.object({ userId: z.string() });
8373
- z.object({
8374
- name: z.string().min(1).max(100),
8375
- scopes: z.array(z.enum(ApiKeyScope)).min(1),
8376
- expiresAt: z.date().optional(),
8377
- rateLimit: z.object({
8378
- requestsPerMinute: z.number().min(1).max(1e3).prefault(60),
8379
- requestsPerDay: z.number().min(1).max(1e4).prefault(1e3)
8380
- }).optional(),
8381
- metadata: z.object({
8382
- clientIP: z.string().optional(),
8383
- userAgent: z.string().optional(),
8384
- createdFrom: z.enum([
8385
- "dashboard",
8386
- "cli",
8387
- "api"
8388
- ])
8389
- })
8390
- });
8391
- z.object({
8392
- keyId: z.string(),
8393
- reason: z.string().optional()
8394
- });
8395
- z.object({ keyId: z.string() });
8396
- dayjs.extend(utc);
8397
- dayjs.extend(timezone);
8398
- AuthEvents.REGISTER, AuthEvents.RESET_PASSWORD, AuthEvents.RESET_LAND_PASSWORD, AuthEvents.RESET_PASSWORD_TOKEN_EXPIRED, ApiKeyEvents.CREATE_API_KEY, ApiKeyEvents.DELETE_API_KEY, ApiKeyEvents.SET_API_KEY, SessionEvents.CREATE_SESSION, SessionEvents.UPDATE_SESSION, SessionEvents.DELETE_SESSION, SessionEvents.DELETE_ALL_SESSIONS, SessionEvents.CLONE_SESSION, FileEvents.CREATE_FILE, FileEvents.UPDATE_FILE, FileEvents.DELETE_FILE, FileEvents.DELETE_ALL_FILES, FileEvents.CREATE_FILE_URL, FileEvents.FILE_UPLOADED, FileEvents.FILE_DOWNLOADED, FileEvents.GENERATE_FILE_PRESIGNED_URL, AppFileEvents.CREATE_APP_FILE, AppFileEvents.DELETE_APP_FILE, AppFileEvents.UPDATE_APP_FILE_TAGS, LLMEvents.QUEUE_HANDLER_START_MODEL, LLMEvents.QUEUE_HANDLER_START_HEARD_PROMPT, LLMEvents.QUEUE_HANDLER_START_AUTO_NAMED_SESSION, LLMEvents.QUEUE_HANDLER_IMAGE_GENERATE, AiEvents.AI_GENERATE_IMAGE, AiEvents.NOTEBOOK_SUMMARIZATION, ElabsEvents.CREATE_ELABS_VOICE, ElabsEvents.DELETE_ELABS_VOICE, ElabsEvents.SET_ACTIVE_ELABS_VOICE, ProjectEvents.CREATE_PROJECT, ProjectEvents.UPDATE_PROJECT, ProjectEvents.DELETE_PROJECT, ProjectEvents.VIEW_PROJECT, ProjectEvents.ADD_SESSION, ProjectEvents.REMOVE_SESSION, ProjectEvents.ADD_FILE, ProjectEvents.REMOVE_FILE, ProjectEvents.ADD_SYSTEM_PROMPT, ProjectEvents.REMOVE_SYSTEM_PROMPT, ProjectEvents.ADD_MEMBER, ProjectEvents.REMOVE_MEMBER, ProjectEvents.UPDATE_MEMBER_ROLE, ProjectEvents.ADD_GROUP, ProjectEvents.REMOVE_GROUP, ProjectEvents.UPDATE_GROUP_ROLE, ProjectEvents.PROJECT_JOINED, ProjectEvents.PROJECT_LEAVED, ProjectEvents.UPDATE_SHARING, ProfileEvents.PROFILE_VIEW, FriendshipEvents.FRIENDSHIP_REQUEST, FriendshipEvents.FRIENDSHIP_ACCEPT, FriendshipEvents.FRIENDSHIP_REJECT, FriendshipEvents.FRIENDSHIP_CANCEL, InviteEvents.CREATE_INVITE, InviteEvents.DELETE_INVITE, RegInviteEvents.CREATE_REGINVITE, RegInviteEvents.DELETE_REGINVITE, RegInviteEvents.UPDATE_REGINVITE, RegInviteEvents.REFER_REGINVITE, RegInviteEvents.REGINVITE_USER_INVITE, RegInviteEvents.MIGRATE_REGINVITE, FeedbackEvents.CREATE_FEEDBACK, FeedbackEvents.UPDATE_FEEDBACK, FeedbackEvents.DELETE_FEEDBACK, FeedbackEvents.FEEDBACK_SENT, InboxEvents.CREATE_INBOX, InboxEvents.DELETE_INBOX, InboxEvents.READ_INBOX, ModalEvents.VIEW_MODAL, ModalEvents.AGREE_MODAL, ModalEvents.VIEW_BANNER, MiscEvents.ROLLED_DICE, LLMEvents.MEMENTO_CREATION_ERROR, LLMEvents.QUEST_MASTER_ERROR, LLMEvents.AUTO_NAMING_ERROR, MiscEvents.DOWNLOAD_FAILED, UiNavigationEvents.MORE_CREDITS_CLICKED, UiNavigationEvents.SUBSCRIBE_CLICKED, UiNavigationEvents.PROFILE_CLICKED, UiNavigationEvents.WHATS_NEW_CLICKED;
8399
- z.object({
8400
- date: z.string(),
8401
- endDate: z.string().optional()
8402
- });
8403
- z.object({
8404
- date: z.string(),
8405
- startDate: z.string().optional(),
8406
- endDate: z.string().optional()
8407
- });
8408
- z.object({
8409
- action: z.string(),
8410
- increment: z.coerce.number().prefault(1).optional(),
8411
- metadata: z.record(z.string(), z.unknown()).optional()
8412
- });
8413
- const epochDate = () => z.preprocess((val) => /* @__PURE__ */ new Date(Number(val) * 1e3), z.date());
8414
- z.looseObject({
8415
- id: z.string(),
8416
- title: z.string(),
8417
- create_time: epochDate(),
8418
- update_time: epochDate().nullable(),
8419
- mapping: z.record(z.string(), z.looseObject({
8420
- id: z.string(),
8421
- parent: z.string().nullable(),
8422
- children: z.array(z.string()),
8423
- message: z.looseObject({
8424
- id: z.string(),
8425
- create_time: epochDate(),
8426
- update_time: epochDate().nullable(),
8427
- author: z.looseObject({
8428
- role: z.string(),
8429
- name: z.string().nullable(),
8430
- metadata: z.any()
8431
- }),
8432
- content: z.looseObject({
8433
- content_type: z.string(),
8434
- parts: z.array(z.any()).optional()
8435
- }),
8436
- status: z.string(),
8437
- end_turn: z.boolean().nullable(),
8438
- metadata: z.any(),
8439
- recipient: z.string()
8440
- }).nullable()
8441
- }))
8442
- });
8443
- const claudeChatMessageSchema = z.looseObject({
8444
- uuid: z.uuid(),
8445
- text: z.string(),
8446
- content: z.array(z.looseObject({
8447
- type: z.string(),
8448
- text: z.string().optional()
8449
- })),
8450
- sender: z.enum(["human", "assistant"]),
8451
- created_at: z.coerce.date(),
8452
- updated_at: z.coerce.date(),
8453
- attachments: z.array(z.any()),
8454
- files: z.array(z.any())
8455
- });
8456
- z.looseObject({
8457
- uuid: z.uuid(),
8458
- name: z.string(),
8459
- summary: z.string().optional(),
8460
- created_at: z.coerce.date(),
8461
- updated_at: z.coerce.date(),
8462
- account: z.looseObject({ uuid: z.uuid() }),
8463
- chat_messages: z.array(claudeChatMessageSchema)
8464
- });
8465
- z.object({
8466
- name: z.string(),
8467
- knowledgeIds: z.array(z.string()).optional(),
8468
- artifactIds: z.array(z.string()).optional(),
8469
- agentIds: z.array(z.string()).optional(),
8470
- tags: z.array(z.object({
8471
- name: z.string(),
8472
- strength: z.number()
8473
- })).optional(),
8474
- summary: z.string().optional(),
8475
- summaryAt: z.date().optional(),
8476
- clonedSourceId: z.string().optional().nullable(),
8477
- forkedSourceId: z.string().optional().nullable(),
8478
- projectId: z.string().optional(),
8479
- lastUsedModel: z.string().optional().nullable()
8480
- });
8481
- z.object({ id: z.string() });
8482
- z.object({ id: z.string() });
8483
- z.object({
8484
- name: z.string().min(1),
8485
- description: z.string().min(1),
8486
- sessionIds: z.array(z.string()).optional(),
8487
- fileIds: z.array(z.string()).optional()
8488
- });
8489
- z.object({
8490
- search: z.string().optional(),
8491
- filters: z.object({
8492
- favorite: z.coerce.boolean().optional(),
8493
- scope: z.record(z.string(), z.any()).optional()
8494
- }).optional(),
8495
- pagination: z.object({
8496
- page: z.coerce.number().optional(),
8497
- limit: z.coerce.number().optional()
8498
- }).optional(),
8499
- orderBy: z.object({
8500
- by: z.enum(["createdAt", "updatedAt"]).optional(),
8501
- direction: z.enum(["asc", "desc"]).optional()
8502
- }).optional()
8503
- });
8504
- z.object({ id: z.string() });
8505
- z.object({
8506
- id: z.string(),
8507
- type: z.enum(InviteType),
8508
- email: z.email().optional()
8509
- });
8510
- z.object({
8511
- documentId: z.string(),
8512
- type: z.enum(InviteType)
8513
- });
8514
- const defaultExpiration = () => new Date((/* @__PURE__ */ new Date()).getFullYear() + 100, (/* @__PURE__ */ new Date()).getMonth(), (/* @__PURE__ */ new Date()).getDate());
8515
- z.object({
8516
- id: z.string(),
8517
- type: z.enum(InviteType),
8518
- permissions: z.array(z.enum(Permission)),
8519
- recipients: z.string().array().optional(),
8520
- description: z.string().optional(),
8521
- expiresAt: z.date().optional().prefault(defaultExpiration()),
8522
- available: z.number().optional().prefault(1)
8523
- });
8524
- z.object({
8525
- id: z.string(),
8526
- withUsername: z.boolean().optional()
8527
- });
8528
- z.object({
8529
- documentId: z.string(),
8530
- type: z.enum(InviteType)
8531
- });
8532
- z.object({
8533
- limit: z.number().min(1).max(100).prefault(20),
8534
- page: z.number().min(1).prefault(1)
8535
- });
8536
- z.object({ id: z.string() });
8537
- z.object({
8538
- id: z.string(),
8539
- type: z.enum([
8540
- "files",
8541
- "sessions",
8542
- "projects"
8543
- ]),
8544
- userId: z.string(),
8545
- projectId: z.string().optional()
8546
- });
8547
- z.object({
8548
- projectId: z.string().nonempty(),
8549
- fileIds: z.tuple([z.string()], z.string())
8550
- });
8551
- z.object({
8552
- projectId: z.string().nonempty(),
8553
- sessionIds: z.tuple([z.string()], z.string())
8554
- });
8555
- z.object({ id: z.string() });
8556
- z.object({
8557
- id: z.string(),
8558
- name: z.string().optional(),
8559
- description: z.string().optional()
8560
- });
8561
- z.object({ id: z.string() });
8562
- z.object({
8563
- projectId: z.string(),
8564
- fileIds: z.array(z.string())
8565
- });
8566
- z.object({
8567
- projectId: z.string(),
8568
- sessionIds: z.array(z.string())
8569
- });
8570
- z.object({ projectId: z.string() });
8571
- z.object({ projectId: z.string() });
8572
- z.object({
8573
- id: z.string(),
8574
- statuses: z.string().optional().prefault(""),
8575
- limit: z.coerce.number().optional().prefault(10),
8576
- page: z.coerce.number().optional().prefault(1)
8577
- });
8578
- z.object({
8579
- projectId: z.string(),
8580
- fileIds: z.array(z.string())
8581
- });
8582
- z.object({
8583
- projectId: z.string(),
8584
- fileId: z.string()
8585
- });
8586
- z.object({
8587
- projectId: z.string(),
8588
- fileId: z.string()
8589
- });
8590
- z.object({
8591
- documentId: z.string(),
8592
- documentType: z.enum(FavoriteDocumentType)
8593
- });
8594
- z.object({
8595
- documentId: z.string(),
8596
- documentType: z.enum(FavoriteDocumentType)
8597
- });
8598
- z.object({ projectId: z.string() });
8599
- z.object({ projectId: z.string() });
8600
- z.object({ projectId: z.string() });
8601
- z.object({
8602
- id: z.string(),
8603
- userIdToRemove: z.string().optional()
8604
- });
8605
- z.object({
8606
- id: z.string(),
8607
- name: z.string().optional(),
8608
- knowledgeIds: z.array(z.string()).optional(),
8609
- artifactIds: z.array(z.string()).optional(),
8610
- tags: z.array(z.object({
8611
- name: z.string(),
8612
- strength: z.number()
8613
- })).optional(),
8614
- lastUsedModel: z.string().optional()
8615
- });
8616
- z.object({ id: z.string() });
8617
- z.object({
8618
- sessionId: z.string(),
8619
- messageId: z.string()
8620
- });
8621
- z.object({
8622
- sessionId: z.string(),
8623
- messageId: z.string()
8624
- });
8625
- z.object({ id: z.string() });
8626
- z.object({
8627
- sessionId: z.string(),
8628
- messageId: z.string()
8629
- });
8630
- z.object({ sessionId: z.string() });
8631
- z.object({ sessionId: z.string() });
8632
- z.object({
8633
- sessionId: z.string(),
8634
- maxWords: z.number().optional()
8635
- });
8636
- z.object({
8637
- query: z.string().optional(),
8638
- filters: z.object({
8639
- personal: z.union([z.enum(["true", "false"]).transform((val) => val === "true"), z.boolean()]).optional(),
8640
- userId: z.string().optional()
8641
- }).prefault({}),
8642
- pagination: z.object({
8643
- page: z.coerce.number().int().positive().prefault(1),
8644
- limit: z.coerce.number().int().positive().max(100).prefault(10)
8645
- }).prefault({
8646
- page: 1,
8647
- limit: 10
8648
- }),
8649
- orderBy: z.object({
8650
- field: z.enum([
8651
- "name",
8652
- "createdAt",
8653
- "updatedAt"
8654
- ]).prefault("name"),
8655
- direction: z.enum(["asc", "desc"]).prefault("asc")
8656
- }).prefault({
8657
- field: "name",
8658
- direction: "asc"
8659
- })
8660
- });
8661
- z.object({ id: z.string().min(1) });
8662
- z.object({
8663
- userId: z.string().optional(),
8664
- email: z.string().optional(),
8665
- organizationId: z.string(),
8666
- force: z.boolean().optional()
8667
- });
8668
- z.object({ id: z.string() });
8669
- z.object({ id: z.string().min(1) });
8670
- z.object({ organizationId: z.string() });
8671
- z.object({ id: z.string() });
8672
- z.object({ id: z.string() });
8673
- z.object({ ids: z.array(z.string()).optional() });
8674
- z.object({
8675
- id: z.string(),
8676
- fileName: z.string().optional(),
8677
- mimeType: z.string().optional(),
8678
- fileContent: z.string().optional(),
8679
- type: z.enum(KnowledgeType).optional(),
8680
- system: z.boolean().optional(),
8681
- systemPriority: z.number().min(0).max(999).optional(),
8682
- sessionId: z.string().optional(),
8683
- notes: z.string().optional(),
8684
- primaryTag: z.string().optional(),
8685
- tags: z.array(z.object({
8686
- name: z.string(),
8687
- strength: z.number()
8688
- })).optional(),
8689
- error: z.string().nullable().optional()
8690
- });
8691
- z.object({ id: z.string() });
8692
- z.object({
8693
- fabFileId: z.string(),
8694
- embeddingModel: z.string()
8695
- });
8696
- z.object({
8697
- fabFileId: z.string(),
8698
- chunkId: z.string()
8699
- });
8700
- z.object({ sessionId: z.string() });
8701
- z.object({ questId: z.string() });
8702
- z.object({ url: z.string().regex(/^(?!https?:\/\/(drive|docs)\.google\.com\/(?:file\/d\/|open\?id=|uc\?id=|document\/d\/|spreadsheets\/d\/|presentation\/d\/|forms\/d\/|drive\/folders\/)([a-zA-Z0-9_-]{10,})).+/) });
8703
- z.object({
8704
- search: z.string().optional(),
8705
- filters: z.object({
8706
- tags: z.array(z.string()).optional(),
8707
- type: z.enum([
8708
- "text",
8709
- "pdf",
8710
- "url",
8711
- "image",
8712
- "excel",
8713
- "word",
8714
- "json",
8715
- "csv",
8716
- "markdown",
8717
- "code"
8718
- ]).optional(),
8719
- shared: z.coerce.boolean().optional(),
8720
- curated: z.coerce.boolean().optional(),
8721
- projectId: z.string().optional(),
8722
- ids: z.array(z.string()).optional()
8723
- }).optional(),
8724
- pagination: z.object({
8725
- page: z.coerce.number(),
8726
- limit: z.coerce.number()
8727
- }).optional(),
8728
- order: z.object({
8729
- by: z.enum([
8730
- "createdAt",
8731
- "fileName",
8732
- "fileSize"
8733
- ]),
8734
- direction: z.enum(["asc", "desc"])
8735
- }).optional(),
8736
- options: z.object({
8737
- includeShared: z.coerce.boolean().optional(),
8738
- userGroups: z.array(z.string()).optional(),
8739
- dataLakeTags: z.array(z.string()).optional()
8740
- }).optional()
8741
- });
8742
- z.object({ fileId: z.string() });
8743
- z.object({ fileId: z.string() });
8744
- z.object({
8745
- ids: z.array(z.string()),
8746
- tags: z.array(z.string())
8747
- });
8748
- z.object({
8749
- id: z.string(),
8750
- instruction: z.string(),
8751
- selection: z.object({
8752
- start: z.number(),
8753
- end: z.number()
8754
- }).optional(),
8755
- preserveFormatting: z.boolean().optional().prefault(true),
8756
- applyImmediately: z.boolean().optional().prefault(false)
8757
- });
8758
- z.object({
8759
- id: z.string(),
8760
- modifiedContent: z.string(),
8761
- createBackup: z.boolean().optional().prefault(true)
8762
- });
8763
- z.object({
8764
- id: z.string(),
8765
- userId: z.string(),
8766
- accept: z.boolean()
8767
- });
8768
- z.object({
8769
- friendshipId: z.string(),
8770
- userId: z.string()
8771
- });
8772
- z.object({ userId: z.string() });
8773
- z.object({ userId: z.string() });
8774
- z.object({ targetUserId: z.string() });
8775
- z.object({ key: z.string() });
8776
- z.object({
8777
- key: z.string(),
8778
- value: z.any(),
8779
- ttl: z.number(),
8780
- recache: z.boolean().optional()
8781
- });
8782
- z.object({ key: z.string() });
8783
- z.object({
8784
- startDate: z.string(),
8785
- endDate: z.string(),
8786
- report: z.string(),
8787
- aiInsights: z.string().nullable()
8788
- });
8789
- z.object({
8790
- name: z.string().min(1),
8791
- description: z.string().min(1)
8792
- });
8793
- z.object({
8794
- id: z.string(),
8795
- name: z.string().min(1),
8796
- description: z.string().min(1)
8797
- });
8798
- z.object({ id: z.string() });
8799
- z.object({ id: z.string() });
8800
- z.object({ id: z.string() });
8801
- async function performDeepResearch(context, params, config) {
8802
- const maxDepth = config.maxDepth || 7;
8803
- const duration = config.duration || 4.5;
8804
- const startTime = Date.now();
8805
- const timeLimit = duration * 60 * 1e3;
8806
- let topic = params.topic;
8807
- const log = console.log;
8808
- log(`🔬 Deep Research: Starting research on "${params.topic} with maxDepth ${maxDepth} and duration ${duration} minutes"`);
8809
- const state = {
8810
- findings: [],
8811
- activities: [],
8812
- sources: [],
8813
- depth: 0,
8814
- completed: false,
8815
- nextSearchQueries: [params.topic],
8816
- completedSteps: 0,
8817
- totalExpectedSteps: maxDepth * 3,
8818
- topic,
8819
- startTime,
8820
- summaries: [],
8821
- urlToSearch: "",
8822
- failedAttempts: 0,
8823
- maxFailedAttempts: 3
8824
- };
8825
- const addActivity = (activity) => {
8826
- const activityWithTimestamp = {
8827
- ...activity,
8828
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
8829
- };
8830
- if (activity.status === "complete") state.completedSteps++;
8831
- state.activities.push(activityWithTimestamp);
8832
- context.statusUpdate({ deepResearchState: state });
8833
- };
8834
- const addSource = (source) => {
8835
- const sourceWithTimestamp = {
8836
- ...source,
8837
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
8838
- };
8839
- state.sources.push(sourceWithTimestamp);
8840
- };
8841
- let searchers = [];
8842
- const apiKeySetting = await context.db.adminSettings.findBySettingName("FirecrawlApiKey");
8843
- if (!apiKeySetting?.settingValue) {
8844
- log("🔬 Deep Research: Firecrawl API key not found");
8845
- return {
8846
- success: false,
8847
- error: "Firecrawl API key not configured",
8848
- data: {
8849
- findings: [],
8850
- finalAnalysisPrompt: "",
8851
- completedSteps: 0,
8852
- totalSteps: 0
8853
- }
8854
- };
8855
- }
8856
- const app = new FirecrawlApp({ apiKey: apiKeySetting.settingValue });
8857
- searchers = [{
8858
- name: "Firecrawl",
8859
- search: async (query) => {
8860
- try {
8861
- return (await app.search(query)).data.map((result) => ({
8862
- url: result.url,
8863
- title: result.title,
8864
- type: "web_url",
8865
- description: result.description
8866
- }));
8867
- } catch (error) {
8868
- log(`🔬 Deep Research: Firecrawl search failed for query "${query}":`, error);
8869
- return [];
8870
- }
8871
- },
8872
- extractContent: async (urls) => {
8873
- const extractPromises = urls.map(async (url) => {
8874
- try {
8875
- if (!url) return [];
8876
- addActivity({
8877
- type: "extract",
8878
- status: "pending",
8879
- message: `Extracting content from ${url}`,
8880
- depth: state.depth
8881
- });
8882
- const result = await app.scrapeUrl(url, {
8883
- formats: ["markdown"],
8884
- actions: [{
8885
- type: "wait",
8886
- milliseconds: 1e3
8887
- }]
8888
- });
8889
- if (result && !result.error && "markdown" in result && result.markdown) {
8890
- addActivity({
8891
- type: "extract",
8892
- status: "complete",
8893
- message: `Successfully extracted content from ${url}`,
8894
- depth: state.depth
8895
- });
8896
- return [{
8897
- text: result.markdown.slice(0, 1e4),
8898
- source: url
8899
- }];
8900
- }
8901
- return [];
8902
- } catch (error) {
8903
- addActivity({
8904
- type: "extract",
8905
- status: "error",
8906
- message: `Failed to extract content from ${url}`,
8907
- depth: state.depth
8908
- });
8909
- log(`🔬 Deep Research: Failed to extract content from ${url}:`);
8910
- return [];
8911
- }
8912
- });
8913
- return (await Promise.all(extractPromises)).flat();
8914
- }
8915
- }];
8916
- if (config.searchers && config.searchers.length > 0) {
8917
- searchers.push(...config.searchers);
8918
- log(`🔬 Deep Research: Using ${searchers.length} searcher(s): ${searchers.map((s) => s.name).join(", ")}`);
8919
- } else log("🔬 Deep Research: Using Firecrawl searcher only");
8920
- if (!searchers.length) throw new Error("No searchers configured");
8921
- const generateText = async (prompt) => {
8922
- let result = "";
8923
- let analysisLlm = context.llm;
8924
- let analysisModel = config.model || ChatModels.GPT4_1;
8925
- if (config.apiKeys?.openai) try {
8926
- analysisLlm = new OpenAIBackend(config.apiKeys.openai, context.logger);
8927
- analysisModel = ChatModels.GPT4_1;
8928
- log("🔬 Deep Research: Using GPT-4.1 for analysis");
8929
- } catch (error) {
8930
- log("🔬 Deep Research: Failed to create OpenAI backend, falling back to selected model");
8931
- }
8932
- else log(`🔬 Deep Research: No OpenAI key available, using selected model ${config.model || "default"} for analysis`);
8933
- await analysisLlm.complete(analysisModel, [{
8934
- role: "user",
8935
- content: prompt
8936
- }], {
8937
- temperature: .1,
8938
- stream: false
8939
- }, async (chunks) => {
8940
- result += chunks[0] || "";
8941
- });
8942
- return result;
8943
- };
8944
- const analyzeAndPlan = async (findings) => {
8945
- try {
8946
- const timeRemaining = timeLimit - (Date.now() - startTime);
8947
- const timeRemainingMinutes = Math.round(timeRemaining / 1e3 / 60 * 10) / 10;
8948
- const result = await generateText(`You are a research agent analyzing findings about: ${topic}
8949
- You have ${timeRemainingMinutes} minutes remaining to complete the research but you don't need to use all of it.
8950
- Current findings: ${findings.map((f) => `[From ${f.source}]: ${f.text}`).join("\n")}
8951
- What has been learned? What gaps remain? What specific aspects should be investigated next if any?
8952
- If you need to search for more information, include a nextSearchTopic.
8953
- If you need to search for more information in a specific URL, include a urlToSearch.
8954
- Important: If less than 1 minute remains, set shouldContinue to false to allow time for final synthesis.
8955
- If I have enough information, set shouldContinue to false.
8956
-
8957
- CRITICAL: Your response must be ONLY valid JSON. Do not include any text before or after the JSON.
8958
-
8959
- Respond in this exact JSON format (copy exactly):
8960
- {
8961
- "analysis": {
8962
- "summary": "summary of findings",
8963
- "gaps": ["gap1", "gap2"],
8964
- "nextSteps": ["step1", "step2"],
8965
- "shouldContinue": true/false,
8966
- "nextSearchTopic": "optional topic",
8967
- "urlToSearch": "optional url"
8968
- }
8969
- }
8970
-
8971
- Replace the placeholder values with actual content. Set shouldContinue to false if research is complete.`);
8972
- log(`🔬 Deep Research: Analysis result ${timeRemainingMinutes} minutes remaining`);
8973
- return JSON.parse(result).analysis;
8974
- } catch (error) {
8975
- log(`🔬 Deep Research: Error in analyzeAndPlan:`, error);
8976
- return null;
8977
- }
8978
- };
8979
- try {
8980
- log("state.depth", state.depth);
8981
- log("state.completed", state.completed);
8982
- while (state.depth < maxDepth && !state.completed) {
8983
- if (Date.now() - startTime >= timeLimit) break;
8984
- state.depth++;
8985
- log(`🔍 Deep Research: Iteration ${state.depth}/${maxDepth}`);
8986
- const currentQuery = state.nextSearchQueries.shift();
8987
- if (!currentQuery) break;
8988
- const allSearchResults = [];
8989
- for (const searcher of searchers) {
8990
- addActivity({
8991
- type: "search",
8992
- status: "pending",
8993
- message: `Searching with ${searcher.name} for: "${currentQuery}"`,
8994
- depth: state.depth
8995
- });
8996
- try {
8997
- const searchResults = await searcher.search(currentQuery);
8998
- log(`🔬 Deep Research: ${searcher.name} found ${searchResults.length} results`);
8999
- searchResults.forEach((src) => {
9000
- addSource({
9001
- url: src.url || "",
9002
- title: src.title || "",
9003
- description: src.description || "",
9004
- type: src.type || "",
9005
- status: "found"
9006
- });
9007
- });
9008
- allSearchResults.push(...searchResults);
9009
- addActivity({
9010
- type: "search",
9011
- status: "complete",
9012
- message: `${searcher.name} found ${searchResults.length} results for: "${currentQuery}"`,
9013
- depth: state.depth
9014
- });
9015
- } catch (error) {
9016
- addActivity({
9017
- type: "search",
9018
- status: "error",
9019
- message: `${searcher.name} search failed: ${error instanceof Error ? error.message : "Unknown error"}`,
9020
- depth: state.depth
9021
- });
9022
- log(`🔬 Deep Research: ${searcher.name} search failed:`, error);
9023
- }
9024
- }
9025
- const extractedContents = [];
9026
- const resultsWithContent = allSearchResults.filter((r) => r.content);
9027
- if (resultsWithContent.length > 0) extractedContents.push(...resultsWithContent.map((r) => ({
9028
- text: r.content.slice(0, 1e4),
9029
- source: r.url || r.title || "unknown"
9030
- })));
9031
- const urlsToExtract = [state.urlToSearch, ...allSearchResults.filter((r) => !r.content && r.url).map((r) => r.url)].filter(Boolean);
9032
- if (urlsToExtract.length > 0) {
9033
- const extractorSearcher = searchers.find((s) => s.extractContent);
9034
- if (extractorSearcher?.extractContent) {
9035
- const topUrls = urlsToExtract.slice(0, 3);
9036
- const extracted = await extractorSearcher.extractContent(topUrls);
9037
- extractedContents.push(...extracted);
9038
- }
9039
- }
9040
- state.findings.push(...extractedContents);
9041
- addActivity({
9042
- type: "analyze",
9043
- status: "pending",
9044
- message: `Analyzing findings`,
9045
- depth: state.depth
9046
- });
9047
- const analysis = await analyzeAndPlan(state.findings);
9048
- analysis?.nextSearchTopic && state.nextSearchQueries.push(analysis.nextSearchTopic);
9049
- state.urlToSearch = analysis?.urlToSearch || "";
9050
- state.summaries.push(analysis?.summary || "");
9051
- if (!analysis) {
9052
- addActivity({
9053
- type: "analyze",
9054
- status: "error",
9055
- message: "Failed to analyze findings",
9056
- depth: state.depth
9057
- });
9058
- state.failedAttempts++;
9059
- if (state.failedAttempts >= state.maxFailedAttempts) break;
9060
- continue;
9061
- }
9062
- addActivity({
9063
- type: "analyze",
9064
- status: "complete",
9065
- message: analysis.summary,
9066
- depth: state.depth
9067
- });
9068
- if (!analysis.shouldContinue || analysis.gaps.length === 0) break;
9069
- topic = analysis.gaps.shift() || topic;
9070
- }
9071
- addActivity({
9072
- type: "synthesis",
9073
- status: "pending",
9074
- message: `Synthesizing research findings into comprehensive report`,
9075
- depth: state.depth
9076
- });
9077
- const finalAnalysisPrompt = `Create a comprehensive long analysis of ${topic} based on these findings:
9078
- ${state.findings.map((f) => `[From ${f.source}]: ${f.text}`).join("\n")}
9079
- ${state.summaries.map((s) => `[Summary]: ${s}`).join("\n")}
9080
- Provide all the thoughts processes including findings details,key insights, conclusions, and any remaining uncertainties.
9081
- Include citations to sources with links for every section. This analysis should be very comprehensive and full of details.
9082
- It is expected to be very long, detailed and comprehensive.`;
9083
- addActivity({
9084
- type: "synthesis",
9085
- status: "complete",
9086
- message: "Research completed",
9087
- depth: state.depth
9088
- });
9089
- state.completed = true;
9090
- state.completedSteps = state.totalExpectedSteps;
9091
- context.statusUpdate({ deepResearchState: state });
9092
- log(`🔬 Deep Research: Completed research on "${topic}"`);
9093
- await context.onFinish?.("deep_research", state);
9094
- return {
9095
- success: true,
9096
- data: {
9097
- findings: state.findings,
9098
- finalAnalysisPrompt,
9099
- completedSteps: state.completedSteps,
9100
- totalSteps: state.totalExpectedSteps
9101
- }
9102
- };
9103
- } catch (error) {
9104
- log(`🔬 Deep Research: Error in iteration ${state.depth}:`, error);
9105
- addActivity({
9106
- type: "thought",
9107
- status: "error",
9108
- message: `Research failed: ${error instanceof Error ? error.message : "Unknown error"}`,
9109
- depth: state.depth
9110
- });
9111
- return {
9112
- success: false,
9113
- error: error instanceof Error ? error.message : "Unknown error",
9114
- data: {
9115
- findings: [],
9116
- finalAnalysisPrompt: "",
9117
- completedSteps: state.completedSteps,
9118
- totalSteps: state.totalExpectedSteps
9119
- }
9120
- };
9121
- }
9122
- }
9123
- const deepResearchTool = {
9124
- name: "deep_research",
9125
- implementation: (context, config) => ({
9126
- toolFn: async (value) => {
9127
- const result = await performDeepResearch(context, { topic: value.topic }, config);
9128
- return JSON.stringify(result);
9129
- },
9130
- toolSchema: {
9131
- name: "deep_research",
9132
- description: "Conduct comprehensive deep research on a topic using iterative web search and analysis. This tool performs multi-step research gathering information from various sources and perspectives.",
9133
- parameters: {
9134
- type: "object",
9135
- properties: { topic: {
9136
- type: "string",
9137
- description: "The research topic or question to investigate thoroughly"
9138
- } },
9139
- required: ["topic"],
9140
- additionalProperties: false
9141
- }
9142
- }
9143
- })
9144
- };
9145
- z.object({ id: z.string() });
9146
- const researchTaskCreateSchema = z.object({
9147
- researchAgentId: z.string(),
9148
- title: z.string().max(100),
9149
- description: z.string().max(500),
9150
- prompt: z.string().max(500).optional(),
9151
- type: z.enum(ResearchTaskType),
9152
- executionType: z.enum(ResearchTaskExecutionType).prefault(ResearchTaskExecutionType.ON_DEMAND),
9153
- fileTagId: z.string().optional(),
9154
- autoGeneratedTag: z.object({
9155
- name: z.string(),
9156
- icon: z.string(),
9157
- color: z.string()
9158
- }).optional()
9159
- });
9160
- researchTaskCreateSchema.extend({
9161
- urls: z.array(z.url()).min(1),
9162
- canDiscoverLinks: z.boolean()
9163
- });
9164
- researchTaskCreateSchema.extend({
9165
- executionPeriodicStartAt: z.coerce.date(),
9166
- executionPeriodicEndAt: z.coerce.date(),
9167
- executionPeriodicFrequency: z.enum(ResearchTaskPeriodicFrequencyType)
9168
- });
9169
- researchTaskCreateSchema.extend({ executionScheduledAt: z.coerce.date() });
9170
- researchTaskCreateSchema.extend({ maxDepth: z.number().min(1).max(10).optional() });
9171
- z.object({
9172
- search: z.string().optional(),
9173
- pagination: z.object({
9174
- page: z.coerce.number().optional(),
9175
- limit: z.coerce.number().optional()
9176
- }).optional(),
9177
- orderBy: z.object({
9178
- by: z.enum(["createdAt", "updatedAt"]).optional(),
9179
- direction: z.enum(["asc", "desc"]).optional()
9180
- }).optional()
9181
- });
9182
- z.object({ id: z.string().min(1) });
9183
- z.object({
9184
- id: z.string(),
9185
- title: z.string(),
9186
- description: z.string(),
9187
- type: z.enum(ResearchTaskType)
9188
- }).extend({
9189
- urls: z.array(z.url()).min(1),
9190
- canDiscoverLinks: z.boolean()
9191
- });
9192
- z.object({ researchAgentId: z.string() });
9193
- z.object({ id: z.string().min(1) });
9194
- z.object({
9195
- id: z.string(),
9196
- userId: z.string()
9197
- });
9198
- z.object({ id: z.string() });
9199
- z.object({ id: z.string() });
9200
- z.object({
9201
- id: z.string(),
9202
- researchAgentId: z.string()
9203
- });
9204
- const researchTaskPayload = z.object({
9205
- id: z.string(),
9206
- userId: z.string()
9207
- });
9208
- const customTaskPayload = z.object({ test: z.string() });
9209
- z.discriminatedUnion("handler", [z.object({
9210
- handler: z.literal(TaskScheduleHandler.RESEARCH_TASK_PROCESS),
9211
- payload: researchTaskPayload,
9212
- processDate: z.date()
9213
- }), z.object({
9214
- handler: z.literal(TaskScheduleHandler.CUSTOM_TASK_PROCESS),
9215
- payload: customTaskPayload,
9216
- processDate: z.date()
9217
- })]);
9218
- z.object({
9219
- name: z.string(),
9220
- icon: z.string().optional(),
9221
- color: z.string().optional(),
9222
- description: z.string().optional()
9223
- });
9224
- z.object({
9225
- name: z.string(),
9226
- icon: z.string().optional(),
9227
- description: z.string().optional(),
9228
- color: z.string().optional(),
9229
- type: z.enum(TagType)
9230
- });
9231
- z.object({
9232
- id: z.string(),
9233
- name: z.string().optional(),
9234
- icon: z.string().optional(),
9235
- description: z.string().optional(),
9236
- color: z.string().optional()
9237
- });
9238
- z.object({ id: z.string() });
9239
- z.object({
9240
- id: z.string().optional(),
9241
- type: ArtifactTypeSchema,
9242
- title: z.string().min(1).max(255),
9243
- description: z.string().max(1e3).optional(),
9244
- content: z.string().min(1),
9245
- projectId: z.string().optional(),
9246
- organizationId: z.string().optional(),
9247
- visibility: z.enum([
9248
- "private",
9249
- "project",
9250
- "organization",
9251
- "public"
9252
- ]).prefault("private"),
9253
- tags: z.array(z.string().max(50)).max(20).prefault([]),
9254
- versionTag: z.string().max(100).optional(),
9255
- sourceQuestId: z.string().optional(),
9256
- sessionId: z.string().optional(),
9257
- parentArtifactId: z.string().optional(),
9258
- permissions: z.object({
9259
- canRead: z.array(z.string()).prefault([]),
9260
- canWrite: z.array(z.string()).prefault([]),
9261
- canDelete: z.array(z.string()).prefault([]),
9262
- isPublic: z.boolean().prefault(false),
9263
- inheritFromProject: z.boolean().prefault(true)
9264
- }).optional(),
9265
- metadata: z.record(z.string(), z.unknown()).prefault({})
9266
- });
9267
- z.object({
9268
- id: z.string(),
9269
- includeContent: z.boolean().prefault(false),
9270
- includeVersions: z.boolean().prefault(false),
9271
- version: z.number().optional()
9272
- });
9273
- z.object({
9274
- type: z.string().optional(),
9275
- status: z.enum([
9276
- "draft",
9277
- "review",
9278
- "published",
9279
- "archived"
9280
- ]).optional(),
9281
- visibility: z.enum([
9282
- "private",
9283
- "project",
9284
- "organization",
9285
- "public"
9286
- ]).optional(),
9287
- projectId: z.string().optional(),
9288
- sessionId: z.string().optional(),
9289
- tags: z.array(z.string()).optional(),
9290
- search: z.string().optional(),
9291
- limit: z.number().min(1).max(100).prefault(20),
9292
- offset: z.number().min(0).prefault(0),
9293
- sortBy: z.enum([
9294
- "createdAt",
9295
- "updatedAt",
9296
- "title",
9297
- "type"
9298
- ]).prefault("updatedAt"),
9299
- sortOrder: z.enum(["asc", "desc"]).prefault("desc"),
9300
- includeDeleted: z.boolean().prefault(false)
9301
- });
9302
- z.object({
9303
- id: z.string(),
9304
- title: z.string().min(1).max(255).optional(),
9305
- description: z.string().max(1e3).optional(),
9306
- content: z.string().optional(),
9307
- visibility: z.enum([
9308
- "private",
9309
- "project",
9310
- "organization",
9311
- "public"
9312
- ]).optional(),
9313
- status: z.enum([
9314
- "draft",
9315
- "review",
9316
- "published",
9317
- "archived"
9318
- ]).optional(),
9319
- tags: z.array(z.string().max(50)).max(20).optional(),
9320
- versionTag: z.string().max(100).optional(),
9321
- permissions: z.object({
9322
- canRead: z.array(z.string()).optional(),
9323
- canWrite: z.array(z.string()).optional(),
9324
- canDelete: z.array(z.string()).optional(),
9325
- isPublic: z.boolean().optional(),
9326
- inheritFromProject: z.boolean().optional()
9327
- }).optional(),
9328
- metadata: z.record(z.string(), z.unknown()).optional(),
9329
- changes: z.array(z.string()).optional(),
9330
- changeDescription: z.string().max(1e3).optional(),
9331
- createNewVersion: z.boolean().optional(),
9332
- versionMessage: z.string().max(500).optional()
9333
- });
9334
- z.object({
9335
- id: z.string(),
9336
- hardDelete: z.boolean().prefault(false)
9337
- });
9338
- const questSchema = z.object({
9339
- id: z.string(),
9340
- title: z.string().min(1).max(255),
9341
- description: z.string().max(MAX_DESCRIPTION_LENGTH),
9342
- status: z.enum([
9343
- "not_started",
9344
- "in_progress",
9345
- "completed",
9346
- "blocked"
9347
- ]).prefault("not_started"),
9348
- order: z.number().min(0),
9349
- dependencies: z.array(z.string()).prefault([]),
9350
- estimatedTime: z.string().optional()
9351
- });
9352
- const questResourceSchema = z.object({
9353
- title: z.string().min(1).max(255),
9354
- url: z.url(),
9355
- type: z.enum([
9356
- "documentation",
9357
- "tutorial",
9358
- "reference",
9359
- "example"
9360
- ])
9361
- });
9362
- z.object({
9363
- title: z.string().min(1).max(255),
9364
- description: z.string().max(MAX_DESCRIPTION_LENGTH).optional(),
9365
- goal: z.string().min(1).max(MAX_GOAL_LENGTH),
9366
- complexity: z.enum([
9367
- "beginner",
9368
- "intermediate",
9369
- "advanced",
9370
- "expert"
9371
- ]),
9372
- estimatedTotalTime: z.string().optional(),
9373
- prerequisites: z.array(z.string().max(200)).prefault([]),
9374
- quests: z.array(questSchema).min(1),
9375
- resources: z.array(questResourceSchema).prefault([]),
9376
- projectId: z.string().optional(),
9377
- organizationId: z.string().optional(),
9378
- visibility: z.enum([
9379
- "private",
9380
- "project",
9381
- "organization",
9382
- "public"
9383
- ]).prefault("private"),
9384
- tags: z.array(z.string().max(50)).max(20).prefault([]),
9385
- permissions: z.object({
9386
- canRead: z.array(z.string()).prefault([]),
9387
- canWrite: z.array(z.string()).prefault([]),
9388
- canDelete: z.array(z.string()).prefault([]),
9389
- isPublic: z.boolean().prefault(false),
9390
- inheritFromProject: z.boolean().prefault(true)
9391
- }).optional(),
9392
- sourceQuestId: z.string().optional(),
9393
- sessionId: z.string().optional(),
9394
- metadata: z.record(z.string(), z.unknown()).prefault({})
9395
- });
9396
- z.object({
9397
- artifactId: z.string(),
9398
- questId: z.string(),
9399
- status: z.enum([
9400
- "not_started",
9401
- "in_progress",
9402
- "completed",
9403
- "blocked"
9404
- ]),
9405
- completionNote: z.string().max(500).optional()
9406
- });
8082
+ //#endregion
8083
+ //#region ../../b4m-core/packages/services/dist/tools-Cc3Su03g.mjs
8084
+ async function performDeepResearch(context, params, config) {
8085
+ const maxDepth = config.maxDepth || 7;
8086
+ const duration = config.duration || 4.5;
8087
+ const startTime = Date.now();
8088
+ const timeLimit = duration * 60 * 1e3;
8089
+ let topic = params.topic;
8090
+ const log = console.log;
8091
+ log(`🔬 Deep Research: Starting research on "${params.topic} with maxDepth ${maxDepth} and duration ${duration} minutes"`);
8092
+ const state = {
8093
+ findings: [],
8094
+ activities: [],
8095
+ sources: [],
8096
+ depth: 0,
8097
+ completed: false,
8098
+ nextSearchQueries: [params.topic],
8099
+ completedSteps: 0,
8100
+ totalExpectedSteps: maxDepth * 3,
8101
+ topic,
8102
+ startTime,
8103
+ summaries: [],
8104
+ urlToSearch: "",
8105
+ failedAttempts: 0,
8106
+ maxFailedAttempts: 3
8107
+ };
8108
+ const addActivity = (activity) => {
8109
+ const activityWithTimestamp = {
8110
+ ...activity,
8111
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
8112
+ };
8113
+ if (activity.status === "complete") state.completedSteps++;
8114
+ state.activities.push(activityWithTimestamp);
8115
+ context.statusUpdate({ deepResearchState: state });
8116
+ };
8117
+ const addSource = (source) => {
8118
+ const sourceWithTimestamp = {
8119
+ ...source,
8120
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
8121
+ };
8122
+ state.sources.push(sourceWithTimestamp);
8123
+ };
8124
+ let searchers = [];
8125
+ const apiKeySetting = await context.db.adminSettings.findBySettingName("FirecrawlApiKey");
8126
+ if (!apiKeySetting?.settingValue) {
8127
+ log("🔬 Deep Research: Firecrawl API key not found");
8128
+ return {
8129
+ success: false,
8130
+ error: "Firecrawl API key not configured",
8131
+ data: {
8132
+ findings: [],
8133
+ finalAnalysisPrompt: "",
8134
+ completedSteps: 0,
8135
+ totalSteps: 0
8136
+ }
8137
+ };
8138
+ }
8139
+ const app = new FirecrawlApp({ apiKey: apiKeySetting.settingValue });
8140
+ searchers = [{
8141
+ name: "Firecrawl",
8142
+ search: async (query) => {
8143
+ try {
8144
+ return (await app.search(query)).data.map((result) => ({
8145
+ url: result.url,
8146
+ title: result.title,
8147
+ type: "web_url",
8148
+ description: result.description
8149
+ }));
8150
+ } catch (error) {
8151
+ log(`🔬 Deep Research: Firecrawl search failed for query "${query}":`, error);
8152
+ return [];
8153
+ }
8154
+ },
8155
+ extractContent: async (urls) => {
8156
+ const extractPromises = urls.map(async (url) => {
8157
+ try {
8158
+ if (!url) return [];
8159
+ addActivity({
8160
+ type: "extract",
8161
+ status: "pending",
8162
+ message: `Extracting content from ${url}`,
8163
+ depth: state.depth
8164
+ });
8165
+ const result = await app.scrapeUrl(url, {
8166
+ formats: ["markdown"],
8167
+ actions: [{
8168
+ type: "wait",
8169
+ milliseconds: 1e3
8170
+ }]
8171
+ });
8172
+ if (result && !result.error && "markdown" in result && result.markdown) {
8173
+ addActivity({
8174
+ type: "extract",
8175
+ status: "complete",
8176
+ message: `Successfully extracted content from ${url}`,
8177
+ depth: state.depth
8178
+ });
8179
+ return [{
8180
+ text: result.markdown.slice(0, 1e4),
8181
+ source: url
8182
+ }];
8183
+ }
8184
+ return [];
8185
+ } catch (error) {
8186
+ addActivity({
8187
+ type: "extract",
8188
+ status: "error",
8189
+ message: `Failed to extract content from ${url}`,
8190
+ depth: state.depth
8191
+ });
8192
+ log(`🔬 Deep Research: Failed to extract content from ${url}:`);
8193
+ return [];
8194
+ }
8195
+ });
8196
+ return (await Promise.all(extractPromises)).flat();
8197
+ }
8198
+ }];
8199
+ if (config.searchers && config.searchers.length > 0) {
8200
+ searchers.push(...config.searchers);
8201
+ log(`🔬 Deep Research: Using ${searchers.length} searcher(s): ${searchers.map((s) => s.name).join(", ")}`);
8202
+ } else log("🔬 Deep Research: Using Firecrawl searcher only");
8203
+ if (!searchers.length) throw new Error("No searchers configured");
8204
+ const generateText = async (prompt) => {
8205
+ let result = "";
8206
+ let analysisLlm = context.llm;
8207
+ let analysisModel = config.model || ChatModels.GPT4_1;
8208
+ if (config.apiKeys?.openai) try {
8209
+ analysisLlm = new OpenAIBackend(config.apiKeys.openai, context.logger);
8210
+ analysisModel = ChatModels.GPT4_1;
8211
+ log("🔬 Deep Research: Using GPT-4.1 for analysis");
8212
+ } catch (error) {
8213
+ log("🔬 Deep Research: Failed to create OpenAI backend, falling back to selected model");
8214
+ }
8215
+ else log(`🔬 Deep Research: No OpenAI key available, using selected model ${config.model || "default"} for analysis`);
8216
+ await analysisLlm.complete(analysisModel, [{
8217
+ role: "user",
8218
+ content: prompt
8219
+ }], {
8220
+ temperature: .1,
8221
+ stream: false
8222
+ }, async (chunks) => {
8223
+ result += chunks[0] || "";
8224
+ });
8225
+ return result;
8226
+ };
8227
+ const analyzeAndPlan = async (findings) => {
8228
+ try {
8229
+ const timeRemaining = timeLimit - (Date.now() - startTime);
8230
+ const timeRemainingMinutes = Math.round(timeRemaining / 1e3 / 60 * 10) / 10;
8231
+ const result = await generateText(`You are a research agent analyzing findings about: ${topic}
8232
+ You have ${timeRemainingMinutes} minutes remaining to complete the research but you don't need to use all of it.
8233
+ Current findings: ${findings.map((f) => `[From ${f.source}]: ${f.text}`).join("\n")}
8234
+ What has been learned? What gaps remain? What specific aspects should be investigated next if any?
8235
+ If you need to search for more information, include a nextSearchTopic.
8236
+ If you need to search for more information in a specific URL, include a urlToSearch.
8237
+ Important: If less than 1 minute remains, set shouldContinue to false to allow time for final synthesis.
8238
+ If I have enough information, set shouldContinue to false.
8239
+
8240
+ CRITICAL: Your response must be ONLY valid JSON. Do not include any text before or after the JSON.
8241
+
8242
+ Respond in this exact JSON format (copy exactly):
8243
+ {
8244
+ "analysis": {
8245
+ "summary": "summary of findings",
8246
+ "gaps": ["gap1", "gap2"],
8247
+ "nextSteps": ["step1", "step2"],
8248
+ "shouldContinue": true/false,
8249
+ "nextSearchTopic": "optional topic",
8250
+ "urlToSearch": "optional url"
8251
+ }
8252
+ }
8253
+
8254
+ Replace the placeholder values with actual content. Set shouldContinue to false if research is complete.`);
8255
+ log(`🔬 Deep Research: Analysis result ${timeRemainingMinutes} minutes remaining`);
8256
+ return JSON.parse(result).analysis;
8257
+ } catch (error) {
8258
+ log(`🔬 Deep Research: Error in analyzeAndPlan:`, error);
8259
+ return null;
8260
+ }
8261
+ };
8262
+ try {
8263
+ log("state.depth", state.depth);
8264
+ log("state.completed", state.completed);
8265
+ while (state.depth < maxDepth && !state.completed) {
8266
+ if (Date.now() - startTime >= timeLimit) break;
8267
+ state.depth++;
8268
+ log(`🔍 Deep Research: Iteration ${state.depth}/${maxDepth}`);
8269
+ const currentQuery = state.nextSearchQueries.shift();
8270
+ if (!currentQuery) break;
8271
+ const allSearchResults = [];
8272
+ for (const searcher of searchers) {
8273
+ addActivity({
8274
+ type: "search",
8275
+ status: "pending",
8276
+ message: `Searching with ${searcher.name} for: "${currentQuery}"`,
8277
+ depth: state.depth
8278
+ });
8279
+ try {
8280
+ const searchResults = await searcher.search(currentQuery);
8281
+ log(`🔬 Deep Research: ${searcher.name} found ${searchResults.length} results`);
8282
+ searchResults.forEach((src) => {
8283
+ addSource({
8284
+ url: src.url || "",
8285
+ title: src.title || "",
8286
+ description: src.description || "",
8287
+ type: src.type || "",
8288
+ status: "found"
8289
+ });
8290
+ });
8291
+ allSearchResults.push(...searchResults);
8292
+ addActivity({
8293
+ type: "search",
8294
+ status: "complete",
8295
+ message: `${searcher.name} found ${searchResults.length} results for: "${currentQuery}"`,
8296
+ depth: state.depth
8297
+ });
8298
+ } catch (error) {
8299
+ addActivity({
8300
+ type: "search",
8301
+ status: "error",
8302
+ message: `${searcher.name} search failed: ${error instanceof Error ? error.message : "Unknown error"}`,
8303
+ depth: state.depth
8304
+ });
8305
+ log(`🔬 Deep Research: ${searcher.name} search failed:`, error);
8306
+ }
8307
+ }
8308
+ const extractedContents = [];
8309
+ const resultsWithContent = allSearchResults.filter((r) => r.content);
8310
+ if (resultsWithContent.length > 0) extractedContents.push(...resultsWithContent.map((r) => ({
8311
+ text: r.content.slice(0, 1e4),
8312
+ source: r.url || r.title || "unknown"
8313
+ })));
8314
+ const urlsToExtract = [state.urlToSearch, ...allSearchResults.filter((r) => !r.content && r.url).map((r) => r.url)].filter(Boolean);
8315
+ if (urlsToExtract.length > 0) {
8316
+ const extractorSearcher = searchers.find((s) => s.extractContent);
8317
+ if (extractorSearcher?.extractContent) {
8318
+ const topUrls = urlsToExtract.slice(0, 3);
8319
+ const extracted = await extractorSearcher.extractContent(topUrls);
8320
+ extractedContents.push(...extracted);
8321
+ }
8322
+ }
8323
+ state.findings.push(...extractedContents);
8324
+ addActivity({
8325
+ type: "analyze",
8326
+ status: "pending",
8327
+ message: `Analyzing findings`,
8328
+ depth: state.depth
8329
+ });
8330
+ const analysis = await analyzeAndPlan(state.findings);
8331
+ analysis?.nextSearchTopic && state.nextSearchQueries.push(analysis.nextSearchTopic);
8332
+ state.urlToSearch = analysis?.urlToSearch || "";
8333
+ state.summaries.push(analysis?.summary || "");
8334
+ if (!analysis) {
8335
+ addActivity({
8336
+ type: "analyze",
8337
+ status: "error",
8338
+ message: "Failed to analyze findings",
8339
+ depth: state.depth
8340
+ });
8341
+ state.failedAttempts++;
8342
+ if (state.failedAttempts >= state.maxFailedAttempts) break;
8343
+ continue;
8344
+ }
8345
+ addActivity({
8346
+ type: "analyze",
8347
+ status: "complete",
8348
+ message: analysis.summary,
8349
+ depth: state.depth
8350
+ });
8351
+ if (!analysis.shouldContinue || analysis.gaps.length === 0) break;
8352
+ topic = analysis.gaps.shift() || topic;
8353
+ }
8354
+ addActivity({
8355
+ type: "synthesis",
8356
+ status: "pending",
8357
+ message: `Synthesizing research findings into comprehensive report`,
8358
+ depth: state.depth
8359
+ });
8360
+ const finalAnalysisPrompt = `Create a comprehensive long analysis of ${topic} based on these findings:
8361
+ ${state.findings.map((f) => `[From ${f.source}]: ${f.text}`).join("\n")}
8362
+ ${state.summaries.map((s) => `[Summary]: ${s}`).join("\n")}
8363
+ Provide all the thoughts processes including findings details,key insights, conclusions, and any remaining uncertainties.
8364
+ Include citations to sources with links for every section. This analysis should be very comprehensive and full of details.
8365
+ It is expected to be very long, detailed and comprehensive.`;
8366
+ addActivity({
8367
+ type: "synthesis",
8368
+ status: "complete",
8369
+ message: "Research completed",
8370
+ depth: state.depth
8371
+ });
8372
+ state.completed = true;
8373
+ state.completedSteps = state.totalExpectedSteps;
8374
+ context.statusUpdate({ deepResearchState: state });
8375
+ log(`🔬 Deep Research: Completed research on "${topic}"`);
8376
+ await context.onFinish?.("deep_research", state);
8377
+ return {
8378
+ success: true,
8379
+ data: {
8380
+ findings: state.findings,
8381
+ finalAnalysisPrompt,
8382
+ completedSteps: state.completedSteps,
8383
+ totalSteps: state.totalExpectedSteps
8384
+ }
8385
+ };
8386
+ } catch (error) {
8387
+ log(`🔬 Deep Research: Error in iteration ${state.depth}:`, error);
8388
+ addActivity({
8389
+ type: "thought",
8390
+ status: "error",
8391
+ message: `Research failed: ${error instanceof Error ? error.message : "Unknown error"}`,
8392
+ depth: state.depth
8393
+ });
8394
+ return {
8395
+ success: false,
8396
+ error: error instanceof Error ? error.message : "Unknown error",
8397
+ data: {
8398
+ findings: [],
8399
+ finalAnalysisPrompt: "",
8400
+ completedSteps: state.completedSteps,
8401
+ totalSteps: state.totalExpectedSteps
8402
+ }
8403
+ };
8404
+ }
8405
+ }
8406
+ const deepResearchTool = {
8407
+ name: "deep_research",
8408
+ implementation: (context, config) => ({
8409
+ toolFn: async (value) => {
8410
+ const result = await performDeepResearch(context, { topic: value.topic }, config);
8411
+ return JSON.stringify(result);
8412
+ },
8413
+ toolSchema: {
8414
+ name: "deep_research",
8415
+ description: "Conduct comprehensive deep research on a topic using iterative web search and analysis. This tool performs multi-step research gathering information from various sources and perspectives.",
8416
+ parameters: {
8417
+ type: "object",
8418
+ properties: { topic: {
8419
+ type: "string",
8420
+ description: "The research topic or question to investigate thoroughly"
8421
+ } },
8422
+ required: ["topic"],
8423
+ additionalProperties: false
8424
+ }
8425
+ }
8426
+ })
8427
+ };
9407
8428
  /**
9408
8429
  * Fetches dynamic data lake configs from DB (if available) and returns
9409
8430
  * the merged datalake: tags for the user.
@@ -9423,72 +8444,6 @@ async function getDynamicDataLakeTags(context) {
9423
8444
  } catch {}
9424
8445
  return getDataLakeTags(context.user.tags || [], dynamicDataLakes);
9425
8446
  }
9426
- /**
9427
- * Zod schema for process ingested email options
9428
- */
9429
- const processIngestedEmailOptionsSchema = z.object({
9430
- platformDomain: z.string().optional(),
9431
- isNewsletter: z.boolean().optional()
9432
- }).optional();
9433
- /**
9434
- * Zod schema for attachment validation
9435
- */
9436
- const emailAttachmentSchema = z.object({
9437
- filename: z.string().optional(),
9438
- contentType: z.string().optional(),
9439
- contentDisposition: z.string().optional(),
9440
- size: z.number().min(0),
9441
- content: z.instanceof(Buffer),
9442
- related: z.boolean().optional()
9443
- });
9444
- /**
9445
- * Zod schema for parsed email validation
9446
- */
9447
- const parsedEmailObjectSchema = z.object({
9448
- messageId: z.string().optional(),
9449
- inReplyTo: z.string().optional(),
9450
- references: z.union([z.string(), z.array(z.string())]).optional(),
9451
- from: z.any().optional(),
9452
- to: z.any().optional(),
9453
- cc: z.any().optional(),
9454
- bcc: z.any().optional(),
9455
- subject: z.string().optional(),
9456
- date: z.date().optional(),
9457
- text: z.string().optional(),
9458
- html: z.string().optional(),
9459
- attachments: z.array(emailAttachmentSchema).optional()
9460
- });
9461
- z.object({
9462
- parsedEmail: parsedEmailObjectSchema,
9463
- rawEmailS3Key: z.string().min(1, "rawEmailS3Key cannot be empty"),
9464
- options: processIngestedEmailOptionsSchema
9465
- });
9466
- z.object({
9467
- summary: z.string().min(1, "Summary cannot be empty"),
9468
- entities: z.object({
9469
- companies: z.array(z.string()).prefault([]),
9470
- people: z.array(z.string()).prefault([]),
9471
- products: z.array(z.string()).prefault([]),
9472
- technologies: z.array(z.string()).prefault([])
9473
- }),
9474
- sentiment: z.enum([
9475
- "positive",
9476
- "neutral",
9477
- "negative",
9478
- "urgent"
9479
- ]),
9480
- actionItems: z.array(z.object({
9481
- description: z.string(),
9482
- deadline: z.string().optional()
9483
- })).prefault([]),
9484
- privacyRecommendation: z.enum([
9485
- "public",
9486
- "team",
9487
- "private"
9488
- ]),
9489
- embargoDetected: z.boolean().prefault(false),
9490
- suggestedTags: z.array(z.string()).prefault([])
9491
- });
9492
8447
  const diceRoll = async (parameters) => {
9493
8448
  if (!parameters?.sides || !parameters?.times) throw new Error("Tool dice roll: Missing required parameters");
9494
8449
  return sum(times(parameters.times, () => random(1, parameters.sides))).toString();
@@ -9562,7 +8517,7 @@ const weatherTool = {
9562
8517
  }
9563
8518
  })
9564
8519
  };
9565
- async function downloadImage$3(url) {
8520
+ async function downloadImage$1(url) {
9566
8521
  if (url.startsWith("data:image/")) {
9567
8522
  const base64Data = url.split(",")[1];
9568
8523
  return Buffer.from(base64Data, "base64");
@@ -9572,7 +8527,7 @@ async function downloadImage$3(url) {
9572
8527
  async function processAndStoreImages(images, context) {
9573
8528
  await context.statusUpdate({}, "Storing images...");
9574
8529
  return Promise.all(images.map(async (image) => {
9575
- const buffer = await downloadImage$3(image);
8530
+ const buffer = await downloadImage$1(image);
9576
8531
  const fileType = await fileTypeFromBuffer(buffer);
9577
8532
  const filename = `${v4()}.${fileType?.ext}`;
9578
8533
  return await context.imageGenerateStorage.upload(buffer, filename, {});
@@ -10690,7 +9645,7 @@ const EDIT_SUPPORTED_MODELS = [
10690
9645
  ImageModels.GEMINI_2_5_FLASH_IMAGE,
10691
9646
  ImageModels.GEMINI_3_PRO_IMAGE_PREVIEW
10692
9647
  ];
10693
- async function downloadImage$2(url) {
9648
+ async function downloadImage(url) {
10694
9649
  if (url.startsWith("data:image/")) {
10695
9650
  const base64Data = url.split(",")[1];
10696
9651
  return Buffer.from(base64Data, "base64");
@@ -10708,8 +9663,8 @@ async function downloadImage$2(url) {
10708
9663
  throw error;
10709
9664
  }
10710
9665
  }
10711
- async function imageUrlToBase64$2(imageUrl) {
10712
- const data = await downloadImage$2(imageUrl);
9666
+ async function imageUrlToBase64(imageUrl) {
9667
+ const data = await downloadImage(imageUrl);
10713
9668
  return Buffer.from(data, "binary").toString("base64");
10714
9669
  }
10715
9670
  async function getImageFromFileId(fileId, context) {
@@ -10721,7 +9676,7 @@ async function getImageFromFileId(fileId, context) {
10721
9676
  throw new Error(`File ${fileId} has no accessible URL`);
10722
9677
  }
10723
9678
  async function processAndStoreImage(imageUrl, context) {
10724
- const buffer = await downloadImage$2(imageUrl);
9679
+ const buffer = await downloadImage(imageUrl);
10725
9680
  const fileType = await fileTypeFromBuffer(buffer);
10726
9681
  const filename = `${v4()}.${fileType?.ext}`;
10727
9682
  return await context.imageGenerateStorage.upload(buffer, filename, {});
@@ -10796,13 +9751,13 @@ Please select a supported edit model in your image settings modal.`;
10796
9751
  let sourceImageUrl;
10797
9752
  if (toolImage.startsWith("http://") || toolImage.startsWith("https://") || toolImage.startsWith("data:")) sourceImageUrl = toolImage;
10798
9753
  else sourceImageUrl = await getImageFromFileId(toolImage, context);
10799
- const sourceBase64Image = await imageUrlToBase64$2(sourceImageUrl);
9754
+ const sourceBase64Image = await imageUrlToBase64(sourceImageUrl);
10800
9755
  let maskBase64Image = null;
10801
9756
  if (toolMask) {
10802
9757
  let maskImageUrl;
10803
9758
  if (toolMask.startsWith("http://") || toolMask.startsWith("https://") || toolMask.startsWith("data:")) maskImageUrl = toolMask;
10804
9759
  else maskImageUrl = await getImageFromFileId(toolMask, context);
10805
- maskBase64Image = await imageUrlToBase64$2(maskImageUrl);
9760
+ maskBase64Image = await imageUrlToBase64(maskImageUrl);
10806
9761
  }
10807
9762
  if (isBFLModel) {
10808
9763
  const service = new BFLImageService(await getEffectiveApiKey(context.userId, { type: ApiKeyType.bfl }, { db: context.db }), context.logger, context.imageProcessorLambdaName);
@@ -13879,183 +12834,1230 @@ const b4mTools = {
13879
12834
  ]
13880
12835
  }
13881
12836
  },
13882
- freezePane: {
13883
- type: "object",
13884
- description: "Freeze pane settings. Both row and col default to 1 (no freeze) if omitted.",
13885
- properties: {
13886
- row: {
13887
- type: "number",
13888
- description: "Freeze rows above this row (default: 1, meaning no row freeze)"
13889
- },
13890
- col: {
13891
- type: "number",
13892
- description: "Freeze columns to the left of this column (default: 1, meaning no column freeze)"
13893
- }
13894
- }
13895
- }
13896
- },
13897
- required: ["name", "data"]
12837
+ freezePane: {
12838
+ type: "object",
12839
+ description: "Freeze pane settings. Both row and col default to 1 (no freeze) if omitted.",
12840
+ properties: {
12841
+ row: {
12842
+ type: "number",
12843
+ description: "Freeze rows above this row (default: 1, meaning no row freeze)"
12844
+ },
12845
+ col: {
12846
+ type: "number",
12847
+ description: "Freeze columns to the left of this column (default: 1, meaning no column freeze)"
12848
+ }
12849
+ }
12850
+ }
12851
+ },
12852
+ required: ["name", "data"]
12853
+ }
12854
+ }
12855
+ },
12856
+ required: ["filename", "sheets"]
12857
+ }
12858
+ }
12859
+ })
12860
+ }
12861
+ };
12862
+ const generateTools = (userId, user, logger, { db }, storage, imageGenerateStorage, statusUpdate, onStart, onFinish, llm, config, model, imageProcessorLambdaName, tools = b4mTools, allowedDirectories) => {
12863
+ const context = {
12864
+ userId,
12865
+ user,
12866
+ logger,
12867
+ db,
12868
+ storage,
12869
+ imageGenerateStorage,
12870
+ statusUpdate,
12871
+ onStart,
12872
+ onFinish,
12873
+ llm,
12874
+ model,
12875
+ imageProcessorLambdaName,
12876
+ allowedDirectories
12877
+ };
12878
+ return Object.entries(tools).reduce((acc, [key, tool]) => ({
12879
+ ...acc,
12880
+ [key]: tool.implementation(context, config[key])
12881
+ }), {});
12882
+ };
12883
+ /**
12884
+ * Normalize MCP tool parameters for OpenAI compatibility.
12885
+ * OpenAI requires 'properties' on object schemas — MCP tools like current_user
12886
+ * return { type: 'object' } without it, causing 400 errors.
12887
+ */
12888
+ function normalizeToolParameters(rest) {
12889
+ const rawParameters = rest?.input_schema ?? rest?.inputSchema ?? rest?.parameters;
12890
+ if (rawParameters && typeof rawParameters === "object") return {
12891
+ ...rawParameters,
12892
+ properties: rawParameters.properties ?? {}
12893
+ };
12894
+ return {
12895
+ type: "object",
12896
+ properties: {},
12897
+ additionalProperties: true
12898
+ };
12899
+ }
12900
+ const ATLASSIAN_RECONNECT_MESSAGE = "⚠️ Your Atlassian connection has expired.\n\nPlease reconnect your Atlassian account in Settings > Connected Apps to continue using Confluence and Jira tools.";
12901
+ const generateMcpTools = async (mcpData) => {
12902
+ let tools;
12903
+ try {
12904
+ tools = await mcpData.getTools();
12905
+ } catch (error) {
12906
+ if ((error instanceof Error ? error.name : "") === "AtlassianReconnectRequiredError") {
12907
+ console.warn(`Atlassian reconnection required during getTools for ${mcpData.serverName}`);
12908
+ return [];
12909
+ }
12910
+ throw error;
12911
+ }
12912
+ const toolList = Array.isArray(tools) ? tools : tools?.tools || [];
12913
+ if (!Array.isArray(tools)) console.warn(`MCP server ${mcpData.serverName} returned unexpected tools payload:`, JSON.stringify(tools));
12914
+ if (!Array.isArray(toolList)) throw new Error(`Expected getTools() to return an array, but got ${typeof tools}`);
12915
+ const result = toolList.map((item) => {
12916
+ const { name: originalToolName, ...rest } = item;
12917
+ const serverName = (mcpData.serverName || "").toLowerCase();
12918
+ const namespacedToolName = `${serverName}__${originalToolName}`;
12919
+ const fallbackDescription = getMcpProviderMetadata(serverName)?.defaultToolDescriptions?.[originalToolName] ?? "";
12920
+ const parameters = normalizeToolParameters(rest);
12921
+ return {
12922
+ name: namespacedToolName,
12923
+ toolFn: async (args) => {
12924
+ Logger.debug(`Calling ${originalToolName} tool via ${mcpData.serverName}`, args);
12925
+ try {
12926
+ const toolResult = await mcpData.callTool(originalToolName, args);
12927
+ const contentBlocks = toolResult?.content;
12928
+ if (Array.isArray(contentBlocks) && contentBlocks.length > 0) {
12929
+ const normalized = contentBlocks.map((entry) => {
12930
+ if (entry && typeof entry === "object" && "text" in entry) return entry.text;
12931
+ return JSON.stringify(entry);
12932
+ }).join("\n");
12933
+ Logger.debug(`[Tool Result] ${originalToolName}:`, normalized);
12934
+ return normalized;
12935
+ }
12936
+ const serialized = typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult);
12937
+ Logger.debug(`[Tool Result] Unexpected format for ${originalToolName}, returning serialized output`);
12938
+ return serialized;
12939
+ } catch (error) {
12940
+ if (mcpData.serverName?.toLowerCase() === "atlassian") {
12941
+ const errorName = error instanceof Error ? error.name : "";
12942
+ const errorMessage = error instanceof Error ? error.message : String(error);
12943
+ if (errorName === "AtlassianReconnectRequiredError" || errorMessage.includes("401") || errorMessage.includes("403") || errorMessage.includes("unauthorized") || errorMessage.includes("expired")) {
12944
+ console.warn(`Atlassian token may be expired for tool ${originalToolName}, error:`, errorMessage);
12945
+ return ATLASSIAN_RECONNECT_MESSAGE;
12946
+ }
12947
+ }
12948
+ throw error;
12949
+ }
12950
+ },
12951
+ toolSchema: {
12952
+ name: namespacedToolName,
12953
+ description: rest.description || fallbackDescription,
12954
+ parameters
12955
+ },
12956
+ _isMcpTool: true
12957
+ };
12958
+ }, {});
12959
+ Logger.debug(`🔧 generateMcpTools: Generated ${result.length} tool implementations for ${mcpData.serverName}`);
12960
+ return result;
12961
+ };
12962
+ /**
12963
+ * Build MCP tool definitions from cached schemas without connecting to the MCP server.
12964
+ * The callTool function is invoked lazily only when the LLM actually calls a tool.
12965
+ */
12966
+ const generateMcpToolsFromCache = (serverName, cachedTools, callTool) => {
12967
+ const normalizedServerName = serverName.toLowerCase();
12968
+ const result = cachedTools.map((item) => {
12969
+ const { name: originalToolName, ...rest } = item;
12970
+ const namespacedToolName = `${normalizedServerName}__${originalToolName}`;
12971
+ const fallbackDescription = getMcpProviderMetadata(normalizedServerName)?.defaultToolDescriptions?.[originalToolName] ?? "";
12972
+ const parameters = normalizeToolParameters(rest);
12973
+ return {
12974
+ name: namespacedToolName,
12975
+ toolFn: async (args) => {
12976
+ Logger.debug(`Calling ${originalToolName} tool via ${serverName}`, args);
12977
+ try {
12978
+ const toolResult = await callTool(originalToolName, args);
12979
+ const contentBlocks = toolResult?.content;
12980
+ if (Array.isArray(contentBlocks) && contentBlocks.length > 0) {
12981
+ const normalized = contentBlocks.map((entry) => {
12982
+ if (entry && typeof entry === "object" && "text" in entry) return entry.text;
12983
+ return JSON.stringify(entry);
12984
+ }).join("\n");
12985
+ Logger.debug(`[Tool Result] ${originalToolName}:`, normalized);
12986
+ return normalized;
12987
+ }
12988
+ const serialized = typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult);
12989
+ Logger.debug(`[Tool Result] Unexpected format for ${originalToolName}, returning serialized output`);
12990
+ return serialized;
12991
+ } catch (error) {
12992
+ if (normalizedServerName === "atlassian") {
12993
+ const errorName = error instanceof Error ? error.name : "";
12994
+ const errorMessage = error instanceof Error ? error.message : String(error);
12995
+ if (errorName === "AtlassianReconnectRequiredError" || errorMessage.includes("401") || errorMessage.includes("403") || errorMessage.includes("unauthorized") || errorMessage.includes("expired")) {
12996
+ console.warn(`Atlassian token may be expired for tool ${originalToolName}, error:`, errorMessage);
12997
+ return ATLASSIAN_RECONNECT_MESSAGE;
12998
+ }
12999
+ }
13000
+ throw error;
13001
+ }
13002
+ },
13003
+ toolSchema: {
13004
+ name: namespacedToolName,
13005
+ description: rest.description || fallbackDescription,
13006
+ parameters
13007
+ },
13008
+ _isMcpTool: true
13009
+ };
13010
+ });
13011
+ Logger.debug(`🔧 generateMcpToolsFromCache: Generated ${result.length} tool implementations for ${serverName} (from cache)`);
13012
+ return result;
13013
+ };
13014
+ //#endregion
13015
+ //#region ../../b4m-core/packages/services/dist/mfaService/utils.mjs
13016
+ const originalEmitWarning = process.emitWarning;
13017
+ process.emitWarning = (warning, name) => {
13018
+ if (name === "DeprecationWarning" && warning?.toString().includes("Buffer")) return;
13019
+ return originalEmitWarning.call(process, warning, name);
13020
+ };
13021
+ process.emitWarning = originalEmitWarning;
13022
+ //#endregion
13023
+ //#region ../../b4m-core/packages/services/dist/askUserQuestion-Dqt6xswW.mjs
13024
+ let _showUserQuestion = null;
13025
+ /**
13026
+ * Inject the CLI callback that displays the question UI.
13027
+ * Called once during CLI startup wiring.
13028
+ */
13029
+ function setShowUserQuestionFn(fn) {
13030
+ _showUserQuestion = fn;
13031
+ }
13032
+ function validateArgs(args) {
13033
+ if (args === null || typeof args !== "object") return { error: "Invalid arguments: expected an object." };
13034
+ const obj = args;
13035
+ if (!Array.isArray(obj.questions) || obj.questions.length === 0) return { error: "At least one question is required." };
13036
+ if (obj.questions.length > 4) return { error: `Maximum 4 questions allowed.` };
13037
+ const questions = [];
13038
+ for (const raw of obj.questions) {
13039
+ if (raw === null || typeof raw !== "object") return { error: "Each question must be an object." };
13040
+ const q = raw;
13041
+ if (typeof q.question !== "string" || q.question.trim() === "") return { error: "Each question must have a non-empty \"question\" string." };
13042
+ if (!Array.isArray(q.options)) return { error: `Question "${q.question}" must have an "options" array.` };
13043
+ const options = [];
13044
+ for (const rawOpt of q.options.slice(0, 4)) {
13045
+ if (rawOpt === null || typeof rawOpt !== "object") continue;
13046
+ const opt = rawOpt;
13047
+ options.push({
13048
+ label: typeof opt.label === "string" ? opt.label : "(untitled)",
13049
+ description: typeof opt.description === "string" ? opt.description : ""
13050
+ });
13051
+ }
13052
+ if (options.length < 2) return { error: `Question "${q.question}" must have at least 2 options.` };
13053
+ questions.push({
13054
+ question: q.question,
13055
+ options,
13056
+ multiSelect: q.multiSelect === true ? true : void 0
13057
+ });
13058
+ }
13059
+ return { questions };
13060
+ }
13061
+ const askUserQuestionTool = {
13062
+ name: "ask_user_question",
13063
+ implementation: () => ({
13064
+ toolFn: async (args) => {
13065
+ if (!_showUserQuestion) return JSON.stringify({ error: "ask_user_question is only available in the CLI environment." });
13066
+ const validated = validateArgs(args);
13067
+ if ("error" in validated) return JSON.stringify({ error: validated.error });
13068
+ const payload = { questions: validated.questions.map((q) => ({
13069
+ question: q.question,
13070
+ options: q.options,
13071
+ multiSelect: q.multiSelect === true
13072
+ })) };
13073
+ const response = await _showUserQuestion(payload);
13074
+ return JSON.stringify(response);
13075
+ },
13076
+ toolSchema: {
13077
+ name: "ask_user_question",
13078
+ description: `Ask the user one or more structured questions with selectable options. Use this when you need clarification, user preferences, or decisions. Each question has 2-4 options. The user can also provide free-text via "Other". For multiSelect questions, the user can pick multiple options.`,
13079
+ parameters: {
13080
+ type: "object",
13081
+ properties: { questions: {
13082
+ type: "array",
13083
+ description: `Array of questions to ask (1-4 questions)`,
13084
+ minItems: 1,
13085
+ maxItems: 4,
13086
+ items: {
13087
+ type: "object",
13088
+ properties: {
13089
+ question: {
13090
+ type: "string",
13091
+ description: "The question to ask. Should be clear and end with a question mark."
13092
+ },
13093
+ options: {
13094
+ type: "array",
13095
+ description: `Available choices (2-4 options). An "Other" free-text option is always appended automatically.`,
13096
+ minItems: 2,
13097
+ maxItems: 4,
13098
+ items: {
13099
+ type: "object",
13100
+ properties: {
13101
+ label: {
13102
+ type: "string",
13103
+ description: "Short display text for this option (1-5 words)"
13104
+ },
13105
+ description: {
13106
+ type: "string",
13107
+ description: "Explanation of what this option means"
13108
+ }
13109
+ },
13110
+ required: ["label", "description"]
13111
+ }
13112
+ },
13113
+ multiSelect: {
13114
+ type: "boolean",
13115
+ description: "If true, the user can select multiple options. Default: false.",
13116
+ default: false
13898
13117
  }
13899
- }
13900
- },
13901
- required: ["filename", "sheets"]
13902
- }
13118
+ },
13119
+ required: ["question", "options"]
13120
+ }
13121
+ } },
13122
+ required: ["questions"]
13903
13123
  }
13904
- })
13905
- }
13906
- };
13907
- const generateTools = (userId, user, logger, { db }, storage, imageGenerateStorage, statusUpdate, onStart, onFinish, llm, config, model, imageProcessorLambdaName, tools = b4mTools, allowedDirectories) => {
13908
- const context = {
13909
- userId,
13910
- user,
13911
- logger,
13912
- db,
13913
- storage,
13914
- imageGenerateStorage,
13915
- statusUpdate,
13916
- onStart,
13917
- onFinish,
13918
- llm,
13919
- model,
13920
- imageProcessorLambdaName,
13921
- allowedDirectories
13922
- };
13923
- return Object.entries(tools).reduce((acc, [key, tool]) => ({
13924
- ...acc,
13925
- [key]: tool.implementation(context, config[key])
13926
- }), {});
13124
+ }
13125
+ })
13927
13126
  };
13127
+ z.object({
13128
+ rootCause: z.string(),
13129
+ proposedFix: z.string(),
13130
+ confidence: z.number().min(0).max(100),
13131
+ riskAssessment: z.string(),
13132
+ affectedFiles: z.array(z.object({
13133
+ filePath: z.string(),
13134
+ before: z.string().min(1),
13135
+ after: z.string()
13136
+ })).max(10)
13137
+ });
13138
+ z.object({
13139
+ count: z.number().optional(),
13140
+ unlimitedUse: z.boolean().optional(),
13141
+ expiresAt: z.date().optional(),
13142
+ tags: z.array(z.string().min(1).max(100)).max(20).optional(),
13143
+ startingCredits: z.number().int().min(0).max(1e6).optional(),
13144
+ startingStorage: z.number().int().min(0).max(1e5).optional()
13145
+ });
13146
+ z.object({ ids: z.array(z.string()) });
13147
+ z.object({
13148
+ usernameOrEmail: z.string(),
13149
+ password: z.string(),
13150
+ metadata: z.object({
13151
+ loginTime: z.date(),
13152
+ userAgent: z.string(),
13153
+ browser: z.string(),
13154
+ operatingSystem: z.string(),
13155
+ deviceType: z.string(),
13156
+ screenResolution: z.string(),
13157
+ viewportSize: z.string(),
13158
+ colorDepth: z.number(),
13159
+ pixelDepth: z.number(),
13160
+ devicePixelRatio: z.number(),
13161
+ ip: z.string().optional().prefault(""),
13162
+ location: z.string().optional()
13163
+ }).optional()
13164
+ });
13165
+ z.object({ email: z.email() });
13166
+ const updateUserSchema = z.object({
13167
+ name: z.string().optional(),
13168
+ username: z.string().optional(),
13169
+ password: z.string().nullable().optional(),
13170
+ team: z.string().nullable().optional(),
13171
+ role: z.string().nullable().optional(),
13172
+ phone: z.string().nullable().optional(),
13173
+ preferredLanguage: z.string().nullable().optional(),
13174
+ preferredContact: z.string().nullable().optional(),
13175
+ preferredVoice: z.string().nullable().optional(),
13176
+ preferredReasoningEffort: z.enum([
13177
+ "auto",
13178
+ "none",
13179
+ "minimal",
13180
+ "low",
13181
+ "medium",
13182
+ "high",
13183
+ "xhigh"
13184
+ ]).nullable().optional(),
13185
+ tshirtSize: z.string().nullable().optional(),
13186
+ geoLocation: z.string().nullable().optional(),
13187
+ lastNotebookId: z.string().nullable().optional(),
13188
+ tags: z.array(z.string()).nullable().optional(),
13189
+ lastCreditsPurchasedAt: z.date().nullable().optional(),
13190
+ systemFiles: z.array(z.object({
13191
+ fileId: z.string(),
13192
+ enabled: z.boolean()
13193
+ })).nullable().optional(),
13194
+ securityQuestions: z.array(z.object({
13195
+ question: z.string(),
13196
+ answer: z.string()
13197
+ })).nullable().optional(),
13198
+ photoUrl: z.string().nullable().optional(),
13199
+ showCreditsUsed: z.boolean().optional(),
13200
+ preferences: z.object({
13201
+ language: z.string().optional(),
13202
+ favoriteTags: z.array(z.string()).optional(),
13203
+ favoriteModelIds: z.array(z.string()).optional(),
13204
+ fileBrowserViewMode: z.enum([
13205
+ "home",
13206
+ "list",
13207
+ "grid",
13208
+ "tags"
13209
+ ]).optional(),
13210
+ optiSessionId: z.string().nullable().optional(),
13211
+ lastUsedTextModel: z.string().nullable().optional(),
13212
+ lastUsedImageModel: z.string().nullable().optional(),
13213
+ lastUsedImageEditModel: z.string().nullable().optional(),
13214
+ showDebug: z.boolean().optional(),
13215
+ showHelp: z.boolean().optional(),
13216
+ maxVisibleLines: z.number().optional(),
13217
+ autoCollapseContent: z.boolean().optional(),
13218
+ enableAutoScroll: z.boolean().optional(),
13219
+ scrollbarWidth: z.number().optional(),
13220
+ experimentalFeatures: z.record(z.string(), z.boolean()).optional(),
13221
+ rechartsDisplayMode: z.enum(["inline", "artifact"]).optional(),
13222
+ docxTemplateFileId: z.string().nullable().optional()
13223
+ }).nullable().optional()
13224
+ });
13225
+ z.object({
13226
+ requesterId: z.string(),
13227
+ recipientId: z.string(),
13228
+ message: z.string().optional()
13229
+ });
13230
+ updateUserSchema.extend({
13231
+ id: z.string(),
13232
+ email: z.email().optional(),
13233
+ role: z.string().optional().nullable(),
13234
+ isAdmin: z.boolean().optional(),
13235
+ organizationId: z.string().optional().nullable(),
13236
+ storageLimit: z.number().optional(),
13237
+ currentCredits: z.number().optional(),
13238
+ isBanned: z.boolean().optional(),
13239
+ isModerated: z.boolean().optional(),
13240
+ subscribedUntil: z.string().optional().nullable(),
13241
+ systemFiles: z.array(z.object({
13242
+ fileId: z.string(),
13243
+ enabled: z.boolean()
13244
+ })).optional(),
13245
+ level: z.enum([
13246
+ "DemoUser",
13247
+ "PaidUser",
13248
+ "VIPUser",
13249
+ "ManagerUser",
13250
+ "AdminUser"
13251
+ ]).optional(),
13252
+ lastNotebookId: z.string().optional().nullable(),
13253
+ userNotes: z.array(z.object({
13254
+ timestamp: z.string(),
13255
+ note: z.string(),
13256
+ userName: z.string()
13257
+ })).optional(),
13258
+ numReferralsAvailable: z.number().optional()
13259
+ });
13260
+ z.object({
13261
+ username: z.string(),
13262
+ email: z.string(),
13263
+ name: z.string(),
13264
+ inviteCode: z.string(),
13265
+ password: z.string(),
13266
+ metadata: z.object({
13267
+ loginTime: z.date(),
13268
+ userAgent: z.string(),
13269
+ browser: z.string(),
13270
+ operatingSystem: z.string(),
13271
+ deviceType: z.string(),
13272
+ screenResolution: z.string(),
13273
+ viewportSize: z.string(),
13274
+ colorDepth: z.number(),
13275
+ pixelDepth: z.number(),
13276
+ devicePixelRatio: z.number(),
13277
+ ip: z.string().optional().prefault(""),
13278
+ location: z.string().optional()
13279
+ }).optional()
13280
+ });
13281
+ z.object({ id: z.string() });
13282
+ z.object({
13283
+ userId: z.string(),
13284
+ page: z.coerce.number().optional().prefault(1),
13285
+ limit: z.coerce.number().optional().prefault(10),
13286
+ search: z.string().optional().prefault(""),
13287
+ type: z.enum(CollectionType).optional()
13288
+ });
13289
+ z.object({ userId: z.string() });
13290
+ z.object({
13291
+ coverage: z.enum(["all", "important"]).prefault("important"),
13292
+ userId: z.string().optional()
13293
+ });
13294
+ SessionEvents.CREATE_SESSION, SessionEvents.UPDATE_SESSION, SessionEvents.DELETE_SESSION, SessionEvents.CLONE_SESSION, FileEvents.CREATE_FILE, FileEvents.DELETE_FILE, FileEvents.UPDATE_FILE;
13295
+ z.object({ userId: z.string() });
13296
+ z.object({ token: z.string() });
13297
+ z.object({ userId: z.string() });
13298
+ z.object({
13299
+ userId: z.string(),
13300
+ newEmail: z.email(),
13301
+ password: z.string()
13302
+ });
13303
+ z.object({ token: z.string() });
13304
+ z.object({ userId: z.string() });
13305
+ z.object({
13306
+ name: z.string().min(1).max(100),
13307
+ scopes: z.array(z.enum(ApiKeyScope)).min(1),
13308
+ expiresAt: z.date().optional(),
13309
+ rateLimit: z.object({
13310
+ requestsPerMinute: z.number().min(1).max(1e3).prefault(60),
13311
+ requestsPerDay: z.number().min(1).max(1e4).prefault(1e3)
13312
+ }).optional(),
13313
+ metadata: z.object({
13314
+ clientIP: z.string().optional(),
13315
+ userAgent: z.string().optional(),
13316
+ createdFrom: z.enum([
13317
+ "dashboard",
13318
+ "cli",
13319
+ "api"
13320
+ ])
13321
+ })
13322
+ });
13323
+ z.object({
13324
+ keyId: z.string(),
13325
+ reason: z.string().optional()
13326
+ });
13327
+ z.object({ keyId: z.string() });
13328
+ dayjs.extend(utc);
13329
+ dayjs.extend(timezone);
13330
+ AuthEvents.REGISTER, AuthEvents.RESET_PASSWORD, AuthEvents.RESET_LAND_PASSWORD, AuthEvents.RESET_PASSWORD_TOKEN_EXPIRED, ApiKeyEvents.CREATE_API_KEY, ApiKeyEvents.DELETE_API_KEY, ApiKeyEvents.SET_API_KEY, SessionEvents.CREATE_SESSION, SessionEvents.UPDATE_SESSION, SessionEvents.DELETE_SESSION, SessionEvents.DELETE_ALL_SESSIONS, SessionEvents.CLONE_SESSION, FileEvents.CREATE_FILE, FileEvents.UPDATE_FILE, FileEvents.DELETE_FILE, FileEvents.DELETE_ALL_FILES, FileEvents.CREATE_FILE_URL, FileEvents.FILE_UPLOADED, FileEvents.FILE_DOWNLOADED, FileEvents.GENERATE_FILE_PRESIGNED_URL, AppFileEvents.CREATE_APP_FILE, AppFileEvents.DELETE_APP_FILE, AppFileEvents.UPDATE_APP_FILE_TAGS, LLMEvents.QUEUE_HANDLER_START_MODEL, LLMEvents.QUEUE_HANDLER_START_HEARD_PROMPT, LLMEvents.QUEUE_HANDLER_START_AUTO_NAMED_SESSION, LLMEvents.QUEUE_HANDLER_IMAGE_GENERATE, AiEvents.AI_GENERATE_IMAGE, AiEvents.NOTEBOOK_SUMMARIZATION, ElabsEvents.CREATE_ELABS_VOICE, ElabsEvents.DELETE_ELABS_VOICE, ElabsEvents.SET_ACTIVE_ELABS_VOICE, ProjectEvents.CREATE_PROJECT, ProjectEvents.UPDATE_PROJECT, ProjectEvents.DELETE_PROJECT, ProjectEvents.VIEW_PROJECT, ProjectEvents.ADD_SESSION, ProjectEvents.REMOVE_SESSION, ProjectEvents.ADD_FILE, ProjectEvents.REMOVE_FILE, ProjectEvents.ADD_SYSTEM_PROMPT, ProjectEvents.REMOVE_SYSTEM_PROMPT, ProjectEvents.ADD_MEMBER, ProjectEvents.REMOVE_MEMBER, ProjectEvents.UPDATE_MEMBER_ROLE, ProjectEvents.ADD_GROUP, ProjectEvents.REMOVE_GROUP, ProjectEvents.UPDATE_GROUP_ROLE, ProjectEvents.PROJECT_JOINED, ProjectEvents.PROJECT_LEAVED, ProjectEvents.UPDATE_SHARING, ProfileEvents.PROFILE_VIEW, FriendshipEvents.FRIENDSHIP_REQUEST, FriendshipEvents.FRIENDSHIP_ACCEPT, FriendshipEvents.FRIENDSHIP_REJECT, FriendshipEvents.FRIENDSHIP_CANCEL, InviteEvents.CREATE_INVITE, InviteEvents.DELETE_INVITE, RegInviteEvents.CREATE_REGINVITE, RegInviteEvents.DELETE_REGINVITE, RegInviteEvents.UPDATE_REGINVITE, RegInviteEvents.REFER_REGINVITE, RegInviteEvents.REGINVITE_USER_INVITE, RegInviteEvents.MIGRATE_REGINVITE, FeedbackEvents.CREATE_FEEDBACK, FeedbackEvents.UPDATE_FEEDBACK, FeedbackEvents.DELETE_FEEDBACK, FeedbackEvents.FEEDBACK_SENT, InboxEvents.CREATE_INBOX, InboxEvents.DELETE_INBOX, InboxEvents.READ_INBOX, ModalEvents.VIEW_MODAL, ModalEvents.AGREE_MODAL, ModalEvents.VIEW_BANNER, MiscEvents.ROLLED_DICE, LLMEvents.MEMENTO_CREATION_ERROR, LLMEvents.QUEST_MASTER_ERROR, LLMEvents.AUTO_NAMING_ERROR, MiscEvents.DOWNLOAD_FAILED, UiNavigationEvents.MORE_CREDITS_CLICKED, UiNavigationEvents.SUBSCRIBE_CLICKED, UiNavigationEvents.PROFILE_CLICKED, UiNavigationEvents.WHATS_NEW_CLICKED;
13331
+ z.object({
13332
+ date: z.string(),
13333
+ endDate: z.string().optional()
13334
+ });
13335
+ z.object({
13336
+ date: z.string(),
13337
+ startDate: z.string().optional(),
13338
+ endDate: z.string().optional()
13339
+ });
13340
+ z.object({
13341
+ action: z.string(),
13342
+ increment: z.coerce.number().prefault(1).optional(),
13343
+ metadata: z.record(z.string(), z.unknown()).optional()
13344
+ });
13345
+ const epochDate = () => z.preprocess((val) => /* @__PURE__ */ new Date(Number(val) * 1e3), z.date());
13346
+ z.looseObject({
13347
+ id: z.string(),
13348
+ title: z.string(),
13349
+ create_time: epochDate(),
13350
+ update_time: epochDate().nullable(),
13351
+ mapping: z.record(z.string(), z.looseObject({
13352
+ id: z.string(),
13353
+ parent: z.string().nullable(),
13354
+ children: z.array(z.string()),
13355
+ message: z.looseObject({
13356
+ id: z.string(),
13357
+ create_time: epochDate(),
13358
+ update_time: epochDate().nullable(),
13359
+ author: z.looseObject({
13360
+ role: z.string(),
13361
+ name: z.string().nullable(),
13362
+ metadata: z.any()
13363
+ }),
13364
+ content: z.looseObject({
13365
+ content_type: z.string(),
13366
+ parts: z.array(z.any()).optional()
13367
+ }),
13368
+ status: z.string(),
13369
+ end_turn: z.boolean().nullable(),
13370
+ metadata: z.any(),
13371
+ recipient: z.string()
13372
+ }).nullable()
13373
+ }))
13374
+ });
13375
+ const claudeChatMessageSchema = z.looseObject({
13376
+ uuid: z.uuid(),
13377
+ text: z.string(),
13378
+ content: z.array(z.looseObject({
13379
+ type: z.string(),
13380
+ text: z.string().optional()
13381
+ })),
13382
+ sender: z.enum(["human", "assistant"]),
13383
+ created_at: z.coerce.date(),
13384
+ updated_at: z.coerce.date(),
13385
+ attachments: z.array(z.any()),
13386
+ files: z.array(z.any())
13387
+ });
13388
+ z.looseObject({
13389
+ uuid: z.uuid(),
13390
+ name: z.string(),
13391
+ summary: z.string().optional(),
13392
+ created_at: z.coerce.date(),
13393
+ updated_at: z.coerce.date(),
13394
+ account: z.looseObject({ uuid: z.uuid() }),
13395
+ chat_messages: z.array(claudeChatMessageSchema)
13396
+ });
13397
+ z.object({
13398
+ name: z.string(),
13399
+ knowledgeIds: z.array(z.string()).optional(),
13400
+ artifactIds: z.array(z.string()).optional(),
13401
+ agentIds: z.array(z.string()).optional(),
13402
+ tags: z.array(z.object({
13403
+ name: z.string(),
13404
+ strength: z.number()
13405
+ })).optional(),
13406
+ summary: z.string().optional(),
13407
+ summaryAt: z.date().optional(),
13408
+ clonedSourceId: z.string().optional().nullable(),
13409
+ forkedSourceId: z.string().optional().nullable(),
13410
+ projectId: z.string().optional(),
13411
+ lastUsedModel: z.string().optional().nullable()
13412
+ });
13413
+ z.object({ id: z.string() });
13414
+ z.object({ id: z.string() });
13415
+ z.object({
13416
+ name: z.string().min(1),
13417
+ description: z.string().min(1),
13418
+ sessionIds: z.array(z.string()).optional(),
13419
+ fileIds: z.array(z.string()).optional()
13420
+ });
13421
+ z.object({
13422
+ search: z.string().optional(),
13423
+ filters: z.object({
13424
+ favorite: z.coerce.boolean().optional(),
13425
+ scope: z.record(z.string(), z.any()).optional()
13426
+ }).optional(),
13427
+ pagination: z.object({
13428
+ page: z.coerce.number().optional(),
13429
+ limit: z.coerce.number().optional()
13430
+ }).optional(),
13431
+ orderBy: z.object({
13432
+ by: z.enum(["createdAt", "updatedAt"]).optional(),
13433
+ direction: z.enum(["asc", "desc"]).optional()
13434
+ }).optional()
13435
+ });
13436
+ z.object({ id: z.string() });
13437
+ z.object({
13438
+ id: z.string(),
13439
+ type: z.enum(InviteType),
13440
+ email: z.email().optional()
13441
+ });
13442
+ z.object({
13443
+ documentId: z.string(),
13444
+ type: z.enum(InviteType)
13445
+ });
13446
+ const defaultExpiration = () => new Date((/* @__PURE__ */ new Date()).getFullYear() + 100, (/* @__PURE__ */ new Date()).getMonth(), (/* @__PURE__ */ new Date()).getDate());
13447
+ z.object({
13448
+ id: z.string(),
13449
+ type: z.enum(InviteType),
13450
+ permissions: z.array(z.enum(Permission)),
13451
+ recipients: z.string().array().optional(),
13452
+ description: z.string().optional(),
13453
+ expiresAt: z.date().optional().prefault(defaultExpiration()),
13454
+ available: z.number().optional().prefault(1)
13455
+ });
13456
+ z.object({
13457
+ id: z.string(),
13458
+ withUsername: z.boolean().optional()
13459
+ });
13460
+ z.object({
13461
+ documentId: z.string(),
13462
+ type: z.enum(InviteType)
13463
+ });
13464
+ z.object({
13465
+ limit: z.number().min(1).max(100).prefault(20),
13466
+ page: z.number().min(1).prefault(1)
13467
+ });
13468
+ z.object({ id: z.string() });
13469
+ z.object({
13470
+ id: z.string(),
13471
+ type: z.enum([
13472
+ "files",
13473
+ "sessions",
13474
+ "projects"
13475
+ ]),
13476
+ userId: z.string(),
13477
+ projectId: z.string().optional()
13478
+ });
13479
+ z.object({
13480
+ projectId: z.string().nonempty(),
13481
+ fileIds: z.tuple([z.string()], z.string())
13482
+ });
13483
+ z.object({
13484
+ projectId: z.string().nonempty(),
13485
+ sessionIds: z.tuple([z.string()], z.string())
13486
+ });
13487
+ z.object({ id: z.string() });
13488
+ z.object({
13489
+ id: z.string(),
13490
+ name: z.string().optional(),
13491
+ description: z.string().optional()
13492
+ });
13493
+ z.object({ id: z.string() });
13494
+ z.object({
13495
+ projectId: z.string(),
13496
+ fileIds: z.array(z.string())
13497
+ });
13498
+ z.object({
13499
+ projectId: z.string(),
13500
+ sessionIds: z.array(z.string())
13501
+ });
13502
+ z.object({ projectId: z.string() });
13503
+ z.object({ projectId: z.string() });
13504
+ z.object({
13505
+ id: z.string(),
13506
+ statuses: z.string().optional().prefault(""),
13507
+ limit: z.coerce.number().optional().prefault(10),
13508
+ page: z.coerce.number().optional().prefault(1)
13509
+ });
13510
+ z.object({
13511
+ projectId: z.string(),
13512
+ fileIds: z.array(z.string())
13513
+ });
13514
+ z.object({
13515
+ projectId: z.string(),
13516
+ fileId: z.string()
13517
+ });
13518
+ z.object({
13519
+ projectId: z.string(),
13520
+ fileId: z.string()
13521
+ });
13522
+ z.object({
13523
+ documentId: z.string(),
13524
+ documentType: z.enum(FavoriteDocumentType)
13525
+ });
13526
+ z.object({
13527
+ documentId: z.string(),
13528
+ documentType: z.enum(FavoriteDocumentType)
13529
+ });
13530
+ z.object({ projectId: z.string() });
13531
+ z.object({ projectId: z.string() });
13532
+ z.object({ projectId: z.string() });
13533
+ z.object({
13534
+ id: z.string(),
13535
+ userIdToRemove: z.string().optional()
13536
+ });
13537
+ z.object({
13538
+ id: z.string(),
13539
+ name: z.string().optional(),
13540
+ knowledgeIds: z.array(z.string()).optional(),
13541
+ artifactIds: z.array(z.string()).optional(),
13542
+ tags: z.array(z.object({
13543
+ name: z.string(),
13544
+ strength: z.number()
13545
+ })).optional(),
13546
+ lastUsedModel: z.string().optional()
13547
+ });
13548
+ z.object({ id: z.string() });
13549
+ z.object({
13550
+ sessionId: z.string(),
13551
+ messageId: z.string()
13552
+ });
13553
+ z.object({
13554
+ sessionId: z.string(),
13555
+ messageId: z.string()
13556
+ });
13557
+ z.object({ id: z.string() });
13558
+ z.object({
13559
+ sessionId: z.string(),
13560
+ messageId: z.string()
13561
+ });
13562
+ z.object({ sessionId: z.string() });
13563
+ z.object({ sessionId: z.string() });
13564
+ z.object({
13565
+ sessionId: z.string(),
13566
+ maxWords: z.number().optional()
13567
+ });
13568
+ z.object({
13569
+ query: z.string().optional(),
13570
+ filters: z.object({
13571
+ personal: z.union([z.enum(["true", "false"]).transform((val) => val === "true"), z.boolean()]).optional(),
13572
+ userId: z.string().optional()
13573
+ }).prefault({}),
13574
+ pagination: z.object({
13575
+ page: z.coerce.number().int().positive().prefault(1),
13576
+ limit: z.coerce.number().int().positive().max(100).prefault(10)
13577
+ }).prefault({
13578
+ page: 1,
13579
+ limit: 10
13580
+ }),
13581
+ orderBy: z.object({
13582
+ field: z.enum([
13583
+ "name",
13584
+ "createdAt",
13585
+ "updatedAt"
13586
+ ]).prefault("name"),
13587
+ direction: z.enum(["asc", "desc"]).prefault("asc")
13588
+ }).prefault({
13589
+ field: "name",
13590
+ direction: "asc"
13591
+ })
13592
+ });
13593
+ z.object({ id: z.string().min(1) });
13594
+ z.object({
13595
+ userId: z.string().optional(),
13596
+ email: z.string().optional(),
13597
+ organizationId: z.string(),
13598
+ force: z.boolean().optional()
13599
+ });
13600
+ z.object({ id: z.string() });
13601
+ z.object({ id: z.string().min(1) });
13602
+ z.object({ organizationId: z.string() });
13603
+ z.object({ id: z.string() });
13604
+ z.object({ id: z.string() });
13605
+ z.object({ ids: z.array(z.string()).optional() });
13606
+ z.object({
13607
+ id: z.string(),
13608
+ fileName: z.string().optional(),
13609
+ mimeType: z.string().optional(),
13610
+ fileContent: z.string().optional(),
13611
+ type: z.enum(KnowledgeType).optional(),
13612
+ system: z.boolean().optional(),
13613
+ systemPriority: z.number().min(0).max(999).optional(),
13614
+ sessionId: z.string().optional(),
13615
+ notes: z.string().optional(),
13616
+ primaryTag: z.string().optional(),
13617
+ tags: z.array(z.object({
13618
+ name: z.string(),
13619
+ strength: z.number()
13620
+ })).optional(),
13621
+ error: z.string().nullable().optional()
13622
+ });
13623
+ z.object({ id: z.string() });
13624
+ z.object({
13625
+ fabFileId: z.string(),
13626
+ embeddingModel: z.string()
13627
+ });
13628
+ z.object({
13629
+ fabFileId: z.string(),
13630
+ chunkId: z.string()
13631
+ });
13632
+ z.object({ sessionId: z.string() });
13633
+ z.object({ questId: z.string() });
13634
+ z.object({ url: z.string().regex(/^(?!https?:\/\/(drive|docs)\.google\.com\/(?:file\/d\/|open\?id=|uc\?id=|document\/d\/|spreadsheets\/d\/|presentation\/d\/|forms\/d\/|drive\/folders\/)([a-zA-Z0-9_-]{10,})).+/) });
13635
+ z.object({
13636
+ search: z.string().optional(),
13637
+ filters: z.object({
13638
+ tags: z.array(z.string()).optional(),
13639
+ type: z.enum([
13640
+ "text",
13641
+ "pdf",
13642
+ "url",
13643
+ "image",
13644
+ "excel",
13645
+ "word",
13646
+ "json",
13647
+ "csv",
13648
+ "markdown",
13649
+ "code"
13650
+ ]).optional(),
13651
+ shared: z.coerce.boolean().optional(),
13652
+ curated: z.coerce.boolean().optional(),
13653
+ projectId: z.string().optional(),
13654
+ ids: z.array(z.string()).optional()
13655
+ }).optional(),
13656
+ pagination: z.object({
13657
+ page: z.coerce.number(),
13658
+ limit: z.coerce.number()
13659
+ }).optional(),
13660
+ order: z.object({
13661
+ by: z.enum([
13662
+ "createdAt",
13663
+ "fileName",
13664
+ "fileSize"
13665
+ ]),
13666
+ direction: z.enum(["asc", "desc"])
13667
+ }).optional(),
13668
+ options: z.object({
13669
+ includeShared: z.coerce.boolean().optional(),
13670
+ userGroups: z.array(z.string()).optional(),
13671
+ dataLakeTags: z.array(z.string()).optional()
13672
+ }).optional()
13673
+ });
13674
+ z.object({ fileId: z.string() });
13675
+ z.object({ fileId: z.string() });
13676
+ z.object({
13677
+ ids: z.array(z.string()),
13678
+ tags: z.array(z.string())
13679
+ });
13680
+ z.object({
13681
+ id: z.string(),
13682
+ instruction: z.string(),
13683
+ selection: z.object({
13684
+ start: z.number(),
13685
+ end: z.number()
13686
+ }).optional(),
13687
+ preserveFormatting: z.boolean().optional().prefault(true),
13688
+ applyImmediately: z.boolean().optional().prefault(false)
13689
+ });
13690
+ z.object({
13691
+ id: z.string(),
13692
+ modifiedContent: z.string(),
13693
+ createBackup: z.boolean().optional().prefault(true)
13694
+ });
13695
+ z.object({
13696
+ id: z.string(),
13697
+ userId: z.string(),
13698
+ accept: z.boolean()
13699
+ });
13700
+ z.object({
13701
+ friendshipId: z.string(),
13702
+ userId: z.string()
13703
+ });
13704
+ z.object({ userId: z.string() });
13705
+ z.object({ userId: z.string() });
13706
+ z.object({ targetUserId: z.string() });
13707
+ z.object({ key: z.string() });
13708
+ z.object({
13709
+ key: z.string(),
13710
+ value: z.any(),
13711
+ ttl: z.number(),
13712
+ recache: z.boolean().optional()
13713
+ });
13714
+ z.object({ key: z.string() });
13715
+ z.object({
13716
+ startDate: z.string(),
13717
+ endDate: z.string(),
13718
+ report: z.string(),
13719
+ aiInsights: z.string().nullable()
13720
+ });
13721
+ z.object({
13722
+ name: z.string().min(1),
13723
+ description: z.string().min(1)
13724
+ });
13725
+ z.object({
13726
+ id: z.string(),
13727
+ name: z.string().min(1),
13728
+ description: z.string().min(1)
13729
+ });
13730
+ z.object({ id: z.string() });
13731
+ z.object({ id: z.string() });
13732
+ z.object({ id: z.string() });
13733
+ z.object({ id: z.string() });
13734
+ const researchTaskCreateSchema = z.object({
13735
+ researchAgentId: z.string(),
13736
+ title: z.string().max(100),
13737
+ description: z.string().max(500),
13738
+ prompt: z.string().max(500).optional(),
13739
+ type: z.enum(ResearchTaskType),
13740
+ executionType: z.enum(ResearchTaskExecutionType).prefault(ResearchTaskExecutionType.ON_DEMAND),
13741
+ fileTagId: z.string().optional(),
13742
+ autoGeneratedTag: z.object({
13743
+ name: z.string(),
13744
+ icon: z.string(),
13745
+ color: z.string()
13746
+ }).optional()
13747
+ });
13748
+ researchTaskCreateSchema.extend({
13749
+ urls: z.array(z.url()).min(1),
13750
+ canDiscoverLinks: z.boolean()
13751
+ });
13752
+ researchTaskCreateSchema.extend({
13753
+ executionPeriodicStartAt: z.coerce.date(),
13754
+ executionPeriodicEndAt: z.coerce.date(),
13755
+ executionPeriodicFrequency: z.enum(ResearchTaskPeriodicFrequencyType)
13756
+ });
13757
+ researchTaskCreateSchema.extend({ executionScheduledAt: z.coerce.date() });
13758
+ researchTaskCreateSchema.extend({ maxDepth: z.number().min(1).max(10).optional() });
13759
+ z.object({
13760
+ search: z.string().optional(),
13761
+ pagination: z.object({
13762
+ page: z.coerce.number().optional(),
13763
+ limit: z.coerce.number().optional()
13764
+ }).optional(),
13765
+ orderBy: z.object({
13766
+ by: z.enum(["createdAt", "updatedAt"]).optional(),
13767
+ direction: z.enum(["asc", "desc"]).optional()
13768
+ }).optional()
13769
+ });
13770
+ z.object({ id: z.string().min(1) });
13771
+ z.object({
13772
+ id: z.string(),
13773
+ title: z.string(),
13774
+ description: z.string(),
13775
+ type: z.enum(ResearchTaskType)
13776
+ }).extend({
13777
+ urls: z.array(z.url()).min(1),
13778
+ canDiscoverLinks: z.boolean()
13779
+ });
13780
+ z.object({ researchAgentId: z.string() });
13781
+ z.object({ id: z.string().min(1) });
13782
+ z.object({
13783
+ id: z.string(),
13784
+ userId: z.string()
13785
+ });
13786
+ z.object({ id: z.string() });
13787
+ z.object({ id: z.string() });
13788
+ z.object({
13789
+ id: z.string(),
13790
+ researchAgentId: z.string()
13791
+ });
13792
+ const researchTaskPayload = z.object({
13793
+ id: z.string(),
13794
+ userId: z.string()
13795
+ });
13796
+ const customTaskPayload = z.object({ test: z.string() });
13797
+ z.discriminatedUnion("handler", [z.object({
13798
+ handler: z.literal(TaskScheduleHandler.RESEARCH_TASK_PROCESS),
13799
+ payload: researchTaskPayload,
13800
+ processDate: z.date()
13801
+ }), z.object({
13802
+ handler: z.literal(TaskScheduleHandler.CUSTOM_TASK_PROCESS),
13803
+ payload: customTaskPayload,
13804
+ processDate: z.date()
13805
+ })]);
13806
+ z.object({
13807
+ name: z.string(),
13808
+ icon: z.string().optional(),
13809
+ color: z.string().optional(),
13810
+ description: z.string().optional()
13811
+ });
13812
+ z.object({
13813
+ name: z.string(),
13814
+ icon: z.string().optional(),
13815
+ description: z.string().optional(),
13816
+ color: z.string().optional(),
13817
+ type: z.enum(TagType)
13818
+ });
13819
+ z.object({
13820
+ id: z.string(),
13821
+ name: z.string().optional(),
13822
+ icon: z.string().optional(),
13823
+ description: z.string().optional(),
13824
+ color: z.string().optional()
13825
+ });
13826
+ z.object({ id: z.string() });
13827
+ z.object({
13828
+ id: z.string().optional(),
13829
+ type: ArtifactTypeSchema,
13830
+ title: z.string().min(1).max(255),
13831
+ description: z.string().max(1e3).optional(),
13832
+ content: z.string().min(1),
13833
+ projectId: z.string().optional(),
13834
+ organizationId: z.string().optional(),
13835
+ visibility: z.enum([
13836
+ "private",
13837
+ "project",
13838
+ "organization",
13839
+ "public"
13840
+ ]).prefault("private"),
13841
+ tags: z.array(z.string().max(50)).max(20).prefault([]),
13842
+ versionTag: z.string().max(100).optional(),
13843
+ sourceQuestId: z.string().optional(),
13844
+ sessionId: z.string().optional(),
13845
+ parentArtifactId: z.string().optional(),
13846
+ permissions: z.object({
13847
+ canRead: z.array(z.string()).prefault([]),
13848
+ canWrite: z.array(z.string()).prefault([]),
13849
+ canDelete: z.array(z.string()).prefault([]),
13850
+ isPublic: z.boolean().prefault(false),
13851
+ inheritFromProject: z.boolean().prefault(true)
13852
+ }).optional(),
13853
+ metadata: z.record(z.string(), z.unknown()).prefault({})
13854
+ });
13855
+ z.object({
13856
+ id: z.string(),
13857
+ includeContent: z.boolean().prefault(false),
13858
+ includeVersions: z.boolean().prefault(false),
13859
+ version: z.number().optional()
13860
+ });
13861
+ z.object({
13862
+ type: z.string().optional(),
13863
+ status: z.enum([
13864
+ "draft",
13865
+ "review",
13866
+ "published",
13867
+ "archived"
13868
+ ]).optional(),
13869
+ visibility: z.enum([
13870
+ "private",
13871
+ "project",
13872
+ "organization",
13873
+ "public"
13874
+ ]).optional(),
13875
+ projectId: z.string().optional(),
13876
+ sessionId: z.string().optional(),
13877
+ tags: z.array(z.string()).optional(),
13878
+ search: z.string().optional(),
13879
+ limit: z.number().min(1).max(100).prefault(20),
13880
+ offset: z.number().min(0).prefault(0),
13881
+ sortBy: z.enum([
13882
+ "createdAt",
13883
+ "updatedAt",
13884
+ "title",
13885
+ "type"
13886
+ ]).prefault("updatedAt"),
13887
+ sortOrder: z.enum(["asc", "desc"]).prefault("desc"),
13888
+ includeDeleted: z.boolean().prefault(false)
13889
+ });
13890
+ z.object({
13891
+ id: z.string(),
13892
+ title: z.string().min(1).max(255).optional(),
13893
+ description: z.string().max(1e3).optional(),
13894
+ content: z.string().optional(),
13895
+ visibility: z.enum([
13896
+ "private",
13897
+ "project",
13898
+ "organization",
13899
+ "public"
13900
+ ]).optional(),
13901
+ status: z.enum([
13902
+ "draft",
13903
+ "review",
13904
+ "published",
13905
+ "archived"
13906
+ ]).optional(),
13907
+ tags: z.array(z.string().max(50)).max(20).optional(),
13908
+ versionTag: z.string().max(100).optional(),
13909
+ permissions: z.object({
13910
+ canRead: z.array(z.string()).optional(),
13911
+ canWrite: z.array(z.string()).optional(),
13912
+ canDelete: z.array(z.string()).optional(),
13913
+ isPublic: z.boolean().optional(),
13914
+ inheritFromProject: z.boolean().optional()
13915
+ }).optional(),
13916
+ metadata: z.record(z.string(), z.unknown()).optional(),
13917
+ changes: z.array(z.string()).optional(),
13918
+ changeDescription: z.string().max(1e3).optional(),
13919
+ createNewVersion: z.boolean().optional(),
13920
+ versionMessage: z.string().max(500).optional()
13921
+ });
13922
+ z.object({
13923
+ id: z.string(),
13924
+ hardDelete: z.boolean().prefault(false)
13925
+ });
13926
+ const questSchema = z.object({
13927
+ id: z.string(),
13928
+ title: z.string().min(1).max(255),
13929
+ description: z.string().max(MAX_DESCRIPTION_LENGTH),
13930
+ status: z.enum([
13931
+ "not_started",
13932
+ "in_progress",
13933
+ "completed",
13934
+ "blocked"
13935
+ ]).prefault("not_started"),
13936
+ order: z.number().min(0),
13937
+ dependencies: z.array(z.string()).prefault([]),
13938
+ estimatedTime: z.string().optional()
13939
+ });
13940
+ const questResourceSchema = z.object({
13941
+ title: z.string().min(1).max(255),
13942
+ url: z.url(),
13943
+ type: z.enum([
13944
+ "documentation",
13945
+ "tutorial",
13946
+ "reference",
13947
+ "example"
13948
+ ])
13949
+ });
13950
+ z.object({
13951
+ title: z.string().min(1).max(255),
13952
+ description: z.string().max(MAX_DESCRIPTION_LENGTH).optional(),
13953
+ goal: z.string().min(1).max(MAX_GOAL_LENGTH),
13954
+ complexity: z.enum([
13955
+ "beginner",
13956
+ "intermediate",
13957
+ "advanced",
13958
+ "expert"
13959
+ ]),
13960
+ estimatedTotalTime: z.string().optional(),
13961
+ prerequisites: z.array(z.string().max(200)).prefault([]),
13962
+ quests: z.array(questSchema).min(1),
13963
+ resources: z.array(questResourceSchema).prefault([]),
13964
+ projectId: z.string().optional(),
13965
+ organizationId: z.string().optional(),
13966
+ visibility: z.enum([
13967
+ "private",
13968
+ "project",
13969
+ "organization",
13970
+ "public"
13971
+ ]).prefault("private"),
13972
+ tags: z.array(z.string().max(50)).max(20).prefault([]),
13973
+ permissions: z.object({
13974
+ canRead: z.array(z.string()).prefault([]),
13975
+ canWrite: z.array(z.string()).prefault([]),
13976
+ canDelete: z.array(z.string()).prefault([]),
13977
+ isPublic: z.boolean().prefault(false),
13978
+ inheritFromProject: z.boolean().prefault(true)
13979
+ }).optional(),
13980
+ sourceQuestId: z.string().optional(),
13981
+ sessionId: z.string().optional(),
13982
+ metadata: z.record(z.string(), z.unknown()).prefault({})
13983
+ });
13984
+ z.object({
13985
+ artifactId: z.string(),
13986
+ questId: z.string(),
13987
+ status: z.enum([
13988
+ "not_started",
13989
+ "in_progress",
13990
+ "completed",
13991
+ "blocked"
13992
+ ]),
13993
+ completionNote: z.string().max(500).optional()
13994
+ });
13928
13995
  /**
13929
- * Normalize MCP tool parameters for OpenAI compatibility.
13930
- * OpenAI requires 'properties' on object schemas — MCP tools like current_user
13931
- * return { type: 'object' } without it, causing 400 errors.
13996
+ * Zod schema for process ingested email options
13932
13997
  */
13933
- function normalizeToolParameters(rest) {
13934
- const rawParameters = rest?.input_schema ?? rest?.inputSchema ?? rest?.parameters;
13935
- if (rawParameters && typeof rawParameters === "object") return {
13936
- ...rawParameters,
13937
- properties: rawParameters.properties ?? {}
13938
- };
13939
- return {
13940
- type: "object",
13941
- properties: {},
13942
- additionalProperties: true
13943
- };
13944
- }
13945
- const ATLASSIAN_RECONNECT_MESSAGE = "⚠️ Your Atlassian connection has expired.\n\nPlease reconnect your Atlassian account in Settings > Connected Apps to continue using Confluence and Jira tools.";
13946
- const generateMcpTools = async (mcpData) => {
13947
- let tools;
13948
- try {
13949
- tools = await mcpData.getTools();
13950
- } catch (error) {
13951
- if ((error instanceof Error ? error.name : "") === "AtlassianReconnectRequiredError") {
13952
- console.warn(`Atlassian reconnection required during getTools for ${mcpData.serverName}`);
13953
- return [];
13954
- }
13955
- throw error;
13956
- }
13957
- const toolList = Array.isArray(tools) ? tools : tools?.tools || [];
13958
- if (!Array.isArray(tools)) console.warn(`MCP server ${mcpData.serverName} returned unexpected tools payload:`, JSON.stringify(tools));
13959
- if (!Array.isArray(toolList)) throw new Error(`Expected getTools() to return an array, but got ${typeof tools}`);
13960
- const result = toolList.map((item) => {
13961
- const { name: originalToolName, ...rest } = item;
13962
- const serverName = (mcpData.serverName || "").toLowerCase();
13963
- const namespacedToolName = `${serverName}__${originalToolName}`;
13964
- const fallbackDescription = getMcpProviderMetadata(serverName)?.defaultToolDescriptions?.[originalToolName] ?? "";
13965
- const parameters = normalizeToolParameters(rest);
13966
- return {
13967
- name: namespacedToolName,
13968
- toolFn: async (args) => {
13969
- Logger.debug(`Calling ${originalToolName} tool via ${mcpData.serverName}`, args);
13970
- try {
13971
- const toolResult = await mcpData.callTool(originalToolName, args);
13972
- const contentBlocks = toolResult?.content;
13973
- if (Array.isArray(contentBlocks) && contentBlocks.length > 0) {
13974
- const normalized = contentBlocks.map((entry) => {
13975
- if (entry && typeof entry === "object" && "text" in entry) return entry.text;
13976
- return JSON.stringify(entry);
13977
- }).join("\n");
13978
- Logger.debug(`[Tool Result] ${originalToolName}:`, normalized);
13979
- return normalized;
13980
- }
13981
- const serialized = typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult);
13982
- Logger.debug(`[Tool Result] Unexpected format for ${originalToolName}, returning serialized output`);
13983
- return serialized;
13984
- } catch (error) {
13985
- if (mcpData.serverName?.toLowerCase() === "atlassian") {
13986
- const errorName = error instanceof Error ? error.name : "";
13987
- const errorMessage = error instanceof Error ? error.message : String(error);
13988
- if (errorName === "AtlassianReconnectRequiredError" || errorMessage.includes("401") || errorMessage.includes("403") || errorMessage.includes("unauthorized") || errorMessage.includes("expired")) {
13989
- console.warn(`Atlassian token may be expired for tool ${originalToolName}, error:`, errorMessage);
13990
- return ATLASSIAN_RECONNECT_MESSAGE;
13991
- }
13992
- }
13993
- throw error;
13994
- }
13995
- },
13996
- toolSchema: {
13997
- name: namespacedToolName,
13998
- description: rest.description || fallbackDescription,
13999
- parameters
14000
- },
14001
- _isMcpTool: true
14002
- };
14003
- }, {});
14004
- Logger.debug(`🔧 generateMcpTools: Generated ${result.length} tool implementations for ${mcpData.serverName}`);
14005
- return result;
14006
- };
13998
+ const processIngestedEmailOptionsSchema = z.object({
13999
+ platformDomain: z.string().optional(),
14000
+ isNewsletter: z.boolean().optional()
14001
+ }).optional();
14007
14002
  /**
14008
- * Build MCP tool definitions from cached schemas without connecting to the MCP server.
14009
- * The callTool function is invoked lazily only when the LLM actually calls a tool.
14003
+ * Zod schema for attachment validation
14010
14004
  */
14011
- const generateMcpToolsFromCache = (serverName, cachedTools, callTool) => {
14012
- const normalizedServerName = serverName.toLowerCase();
14013
- const result = cachedTools.map((item) => {
14014
- const { name: originalToolName, ...rest } = item;
14015
- const namespacedToolName = `${normalizedServerName}__${originalToolName}`;
14016
- const fallbackDescription = getMcpProviderMetadata(normalizedServerName)?.defaultToolDescriptions?.[originalToolName] ?? "";
14017
- const parameters = normalizeToolParameters(rest);
14018
- return {
14019
- name: namespacedToolName,
14020
- toolFn: async (args) => {
14021
- Logger.debug(`Calling ${originalToolName} tool via ${serverName}`, args);
14022
- try {
14023
- const toolResult = await callTool(originalToolName, args);
14024
- const contentBlocks = toolResult?.content;
14025
- if (Array.isArray(contentBlocks) && contentBlocks.length > 0) {
14026
- const normalized = contentBlocks.map((entry) => {
14027
- if (entry && typeof entry === "object" && "text" in entry) return entry.text;
14028
- return JSON.stringify(entry);
14029
- }).join("\n");
14030
- Logger.debug(`[Tool Result] ${originalToolName}:`, normalized);
14031
- return normalized;
14032
- }
14033
- const serialized = typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult);
14034
- Logger.debug(`[Tool Result] Unexpected format for ${originalToolName}, returning serialized output`);
14035
- return serialized;
14036
- } catch (error) {
14037
- if (normalizedServerName === "atlassian") {
14038
- const errorName = error instanceof Error ? error.name : "";
14039
- const errorMessage = error instanceof Error ? error.message : String(error);
14040
- if (errorName === "AtlassianReconnectRequiredError" || errorMessage.includes("401") || errorMessage.includes("403") || errorMessage.includes("unauthorized") || errorMessage.includes("expired")) {
14041
- console.warn(`Atlassian token may be expired for tool ${originalToolName}, error:`, errorMessage);
14042
- return ATLASSIAN_RECONNECT_MESSAGE;
14043
- }
14044
- }
14045
- throw error;
14046
- }
14047
- },
14048
- toolSchema: {
14049
- name: namespacedToolName,
14050
- description: rest.description || fallbackDescription,
14051
- parameters
14052
- },
14053
- _isMcpTool: true
14054
- };
14055
- });
14056
- Logger.debug(`🔧 generateMcpToolsFromCache: Generated ${result.length} tool implementations for ${serverName} (from cache)`);
14057
- return result;
14058
- };
14005
+ const emailAttachmentSchema = z.object({
14006
+ filename: z.string().optional(),
14007
+ contentType: z.string().optional(),
14008
+ contentDisposition: z.string().optional(),
14009
+ size: z.number().min(0),
14010
+ content: z.instanceof(Buffer),
14011
+ related: z.boolean().optional()
14012
+ });
14013
+ /**
14014
+ * Zod schema for parsed email validation
14015
+ */
14016
+ const parsedEmailObjectSchema = z.object({
14017
+ messageId: z.string().optional(),
14018
+ inReplyTo: z.string().optional(),
14019
+ references: z.union([z.string(), z.array(z.string())]).optional(),
14020
+ from: z.any().optional(),
14021
+ to: z.any().optional(),
14022
+ cc: z.any().optional(),
14023
+ bcc: z.any().optional(),
14024
+ subject: z.string().optional(),
14025
+ date: z.date().optional(),
14026
+ text: z.string().optional(),
14027
+ html: z.string().optional(),
14028
+ attachments: z.array(emailAttachmentSchema).optional()
14029
+ });
14030
+ z.object({
14031
+ parsedEmail: parsedEmailObjectSchema,
14032
+ rawEmailS3Key: z.string().min(1, "rawEmailS3Key cannot be empty"),
14033
+ options: processIngestedEmailOptionsSchema
14034
+ });
14035
+ z.object({
14036
+ summary: z.string().min(1, "Summary cannot be empty"),
14037
+ entities: z.object({
14038
+ companies: z.array(z.string()).prefault([]),
14039
+ people: z.array(z.string()).prefault([]),
14040
+ products: z.array(z.string()).prefault([]),
14041
+ technologies: z.array(z.string()).prefault([])
14042
+ }),
14043
+ sentiment: z.enum([
14044
+ "positive",
14045
+ "neutral",
14046
+ "negative",
14047
+ "urgent"
14048
+ ]),
14049
+ actionItems: z.array(z.object({
14050
+ description: z.string(),
14051
+ deadline: z.string().optional()
14052
+ })).prefault([]),
14053
+ privacyRecommendation: z.enum([
14054
+ "public",
14055
+ "team",
14056
+ "private"
14057
+ ]),
14058
+ embargoDetected: z.boolean().prefault(false),
14059
+ suggestedTags: z.array(z.string()).prefault([])
14060
+ });
14059
14061
  z.object({
14060
14062
  userId: z.string(),
14061
14063
  sessionId: z.string(),
@@ -16380,11 +16382,11 @@ function parseQuery(query) {
16380
16382
  */
16381
16383
  const getCliOnlyTools = async () => {
16382
16384
  const [{ createFileTool }, { globFilesTool }, { grepSearchTool }, { deleteFileTool }, { bashExecuteTool }] = await Promise.all([
16383
- import("./createFile-yQfh8uvk-I-yM5DxC.mjs"),
16384
- import("./globFiles-D1en6joM-8jekiXdX.mjs"),
16385
- import("./grepSearch-aMamoBn_-DCJcY8JS.mjs"),
16386
- import("./deleteFile-DKHfnyny-G3b1Kj2T.mjs"),
16387
- import("./bashExecute-BTkdqlSs-5foM20Lb.mjs")
16385
+ import("./createFile-U1V-Ael_-j2ptPMop.mjs"),
16386
+ import("./globFiles-Cm98oQml-XQ578QKX.mjs"),
16387
+ import("./grepSearch-Dqpkuj21-JCTE3vmi.mjs"),
16388
+ import("./deleteFile-BFsQ8m7A-BLovBqN2.mjs"),
16389
+ import("./bashExecute-CFg0Cl-k-CzHtpiJK.mjs")
16388
16390
  ]);
16389
16391
  return {
16390
16392
  file_read: fileReadTool,
@@ -18718,7 +18720,7 @@ var WebSocketLlmBackend = class {
18718
18720
  //#endregion
18719
18721
  //#region src/ws/WebSocketConnectionManager.ts
18720
18722
  const useWsPolyfill = typeof globalThis.WebSocket === "undefined";
18721
- const WS = useWsPolyfill ? WebSocket : globalThis.WebSocket;
18723
+ const WS = useWsPolyfill ? WsWebSocket : globalThis.WebSocket;
18722
18724
  /**
18723
18725
  * Manages a persistent WebSocket connection for CLI ↔ server communication.
18724
18726
  * Handles heartbeat, reconnection, and message routing by requestId.
@@ -18755,7 +18757,7 @@ var WebSocketConnectionManager = class {
18755
18757
  }
18756
18758
  return new Promise((resolve, reject) => {
18757
18759
  logger.debug(`[WS] Connecting to ${this.wsUrl}...`);
18758
- if (useWsPolyfill) this.ws = new WebSocket(this.wsUrl, { headers: { "Sec-WebSocket-Protocol": `access_token.${token}` } });
18760
+ if (useWsPolyfill) this.ws = new WsWebSocket(this.wsUrl, { headers: { "Sec-WebSocket-Protocol": `access_token.${token}` } });
18759
18761
  else this.ws = new WS(this.wsUrl, [`access_token.${token}`]);
18760
18762
  this.ws.onopen = () => {
18761
18763
  logger.debug("[WS] Connected");