@superatomai/sdk-node 0.0.41 → 0.0.42

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.
package/dist/index.d.mts CHANGED
@@ -628,19 +628,19 @@ declare const ComponentSchema: z.ZodObject<{
628
628
  description: z.ZodOptional<z.ZodString>;
629
629
  config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
630
630
  actions: z.ZodOptional<z.ZodArray<z.ZodAny, "many">>;
631
- }, "strip", z.ZodTypeAny, {
632
- description?: string | undefined;
633
- query?: string | {} | undefined;
634
- title?: string | undefined;
635
- config?: Record<string, unknown> | undefined;
636
- actions?: any[] | undefined;
637
- }, {
638
- description?: string | undefined;
639
- query?: string | {} | undefined;
640
- title?: string | undefined;
641
- config?: Record<string, unknown> | undefined;
642
- actions?: any[] | undefined;
643
- }>;
631
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
632
+ query: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>]>>;
633
+ title: z.ZodOptional<z.ZodString>;
634
+ description: z.ZodOptional<z.ZodString>;
635
+ config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
636
+ actions: z.ZodOptional<z.ZodArray<z.ZodAny, "many">>;
637
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
638
+ query: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>]>>;
639
+ title: z.ZodOptional<z.ZodString>;
640
+ description: z.ZodOptional<z.ZodString>;
641
+ config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
642
+ actions: z.ZodOptional<z.ZodArray<z.ZodAny, "many">>;
643
+ }, z.ZodTypeAny, "passthrough">>;
644
644
  category: z.ZodOptional<z.ZodString>;
645
645
  keywords: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
646
646
  }, "strip", z.ZodTypeAny, {
@@ -654,6 +654,8 @@ declare const ComponentSchema: z.ZodObject<{
654
654
  title?: string | undefined;
655
655
  config?: Record<string, unknown> | undefined;
656
656
  actions?: any[] | undefined;
657
+ } & {
658
+ [k: string]: unknown;
657
659
  };
658
660
  displayName?: string | undefined;
659
661
  isDisplayComp?: boolean | undefined;
@@ -670,6 +672,8 @@ declare const ComponentSchema: z.ZodObject<{
670
672
  title?: string | undefined;
671
673
  config?: Record<string, unknown> | undefined;
672
674
  actions?: any[] | undefined;
675
+ } & {
676
+ [k: string]: unknown;
673
677
  };
674
678
  displayName?: string | undefined;
675
679
  isDisplayComp?: boolean | undefined;
@@ -709,6 +713,22 @@ type DatabaseType = 'postgresql' | 'mssql' | 'snowflake' | 'mysql';
709
713
  * - 'balanced': Use best model for complex tasks, fast model for simple tasks (default)
710
714
  */
711
715
  type ModelStrategy = 'best' | 'fast' | 'balanced';
716
+ /**
717
+ * Model configuration for DASH_COMP flow (dashboard component picking)
718
+ * Allows separate control of models used for component selection
719
+ */
720
+ interface DashCompModelConfig {
721
+ /**
722
+ * Primary model for DASH_COMP requests
723
+ * Format: "provider/model-name" (e.g., "anthropic/claude-sonnet-4-5-20250929")
724
+ */
725
+ model?: string;
726
+ /**
727
+ * Fast model for simpler DASH_COMP tasks (optional)
728
+ * Format: "provider/model-name" (e.g., "anthropic/claude-haiku-4-5-20251001")
729
+ */
730
+ fastModel?: string;
731
+ }
712
732
  interface SuperatomSDKConfig {
713
733
  url?: string;
714
734
  apiKey?: string;
@@ -731,6 +751,11 @@ interface SuperatomSDKConfig {
731
751
  * - 'balanced': Use best model for complex tasks, fast model for simple tasks (default)
732
752
  */
733
753
  modelStrategy?: ModelStrategy;
754
+ /**
755
+ * Separate model configuration for DASH_COMP flow (dashboard component picking)
756
+ * If not provided, falls back to provider-based model selection
757
+ */
758
+ dashCompModels?: DashCompModelConfig;
734
759
  }
735
760
 
736
761
  declare const KbNodesQueryFiltersSchema: z.ZodObject<{
package/dist/index.d.ts CHANGED
@@ -628,19 +628,19 @@ declare const ComponentSchema: z.ZodObject<{
628
628
  description: z.ZodOptional<z.ZodString>;
629
629
  config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
630
630
  actions: z.ZodOptional<z.ZodArray<z.ZodAny, "many">>;
631
- }, "strip", z.ZodTypeAny, {
632
- description?: string | undefined;
633
- query?: string | {} | undefined;
634
- title?: string | undefined;
635
- config?: Record<string, unknown> | undefined;
636
- actions?: any[] | undefined;
637
- }, {
638
- description?: string | undefined;
639
- query?: string | {} | undefined;
640
- title?: string | undefined;
641
- config?: Record<string, unknown> | undefined;
642
- actions?: any[] | undefined;
643
- }>;
631
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
632
+ query: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>]>>;
633
+ title: z.ZodOptional<z.ZodString>;
634
+ description: z.ZodOptional<z.ZodString>;
635
+ config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
636
+ actions: z.ZodOptional<z.ZodArray<z.ZodAny, "many">>;
637
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
638
+ query: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>]>>;
639
+ title: z.ZodOptional<z.ZodString>;
640
+ description: z.ZodOptional<z.ZodString>;
641
+ config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
642
+ actions: z.ZodOptional<z.ZodArray<z.ZodAny, "many">>;
643
+ }, z.ZodTypeAny, "passthrough">>;
644
644
  category: z.ZodOptional<z.ZodString>;
645
645
  keywords: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
646
646
  }, "strip", z.ZodTypeAny, {
@@ -654,6 +654,8 @@ declare const ComponentSchema: z.ZodObject<{
654
654
  title?: string | undefined;
655
655
  config?: Record<string, unknown> | undefined;
656
656
  actions?: any[] | undefined;
657
+ } & {
658
+ [k: string]: unknown;
657
659
  };
658
660
  displayName?: string | undefined;
659
661
  isDisplayComp?: boolean | undefined;
@@ -670,6 +672,8 @@ declare const ComponentSchema: z.ZodObject<{
670
672
  title?: string | undefined;
671
673
  config?: Record<string, unknown> | undefined;
672
674
  actions?: any[] | undefined;
675
+ } & {
676
+ [k: string]: unknown;
673
677
  };
674
678
  displayName?: string | undefined;
675
679
  isDisplayComp?: boolean | undefined;
@@ -709,6 +713,22 @@ type DatabaseType = 'postgresql' | 'mssql' | 'snowflake' | 'mysql';
709
713
  * - 'balanced': Use best model for complex tasks, fast model for simple tasks (default)
710
714
  */
711
715
  type ModelStrategy = 'best' | 'fast' | 'balanced';
716
+ /**
717
+ * Model configuration for DASH_COMP flow (dashboard component picking)
718
+ * Allows separate control of models used for component selection
719
+ */
720
+ interface DashCompModelConfig {
721
+ /**
722
+ * Primary model for DASH_COMP requests
723
+ * Format: "provider/model-name" (e.g., "anthropic/claude-sonnet-4-5-20250929")
724
+ */
725
+ model?: string;
726
+ /**
727
+ * Fast model for simpler DASH_COMP tasks (optional)
728
+ * Format: "provider/model-name" (e.g., "anthropic/claude-haiku-4-5-20251001")
729
+ */
730
+ fastModel?: string;
731
+ }
712
732
  interface SuperatomSDKConfig {
713
733
  url?: string;
714
734
  apiKey?: string;
@@ -731,6 +751,11 @@ interface SuperatomSDKConfig {
731
751
  * - 'balanced': Use best model for complex tasks, fast model for simple tasks (default)
732
752
  */
733
753
  modelStrategy?: ModelStrategy;
754
+ /**
755
+ * Separate model configuration for DASH_COMP flow (dashboard component picking)
756
+ * If not provided, falls back to provider-based model selection
757
+ */
758
+ dashCompModels?: DashCompModelConfig;
734
759
  }
735
760
 
736
761
  declare const KbNodesQueryFiltersSchema: z.ZodObject<{
package/dist/index.js CHANGED
@@ -1933,7 +1933,7 @@ var ComponentPropsSchema = import_zod3.z.object({
1933
1933
  description: import_zod3.z.string().optional(),
1934
1934
  config: import_zod3.z.record(import_zod3.z.unknown()).optional(),
1935
1935
  actions: import_zod3.z.array(import_zod3.z.any()).optional()
1936
- });
1936
+ }).passthrough();
1937
1937
  var ComponentSchema = import_zod3.z.object({
1938
1938
  id: import_zod3.z.string(),
1939
1939
  name: import_zod3.z.string(),
@@ -3458,9 +3458,9 @@ var PRICING = {
3458
3458
  "gpt-4": { input: 30, output: 60 },
3459
3459
  "gpt-3.5-turbo": { input: 0.5, output: 1.5 },
3460
3460
  // Google Gemini (December 2025)
3461
- "gemini-3-pro": { input: 2, output: 8 },
3461
+ "gemini-3-pro-preview": { input: 2, output: 12 },
3462
3462
  // New Gemini 3
3463
- "gemini-2.5-pro": { input: 1.25, output: 10 },
3463
+ "gemini-3-flash-preview": { input: 0.5, output: 3 },
3464
3464
  // For prompts ≤200K tokens, 2x for >200K
3465
3465
  "gemini-2.5-flash": { input: 0.15, output: 0.6 },
3466
3466
  // Standard mode (thinking disabled: $0.60, thinking enabled: $3.50)
@@ -4645,6 +4645,7 @@ var LLM = class {
4645
4645
  }
4646
4646
  }
4647
4647
  static async _geminiStreamWithTools(messages, tools, toolHandler, modelName, options, maxIterations) {
4648
+ const methodStartTime = Date.now();
4648
4649
  const apiKey = options.apiKey || process.env.GEMINI_API_KEY || "";
4649
4650
  const genAI = new import_generative_ai.GoogleGenerativeAI(apiKey);
4650
4651
  const systemPrompt = typeof messages.sys === "string" ? messages.sys : messages.sys.map((block) => block.text).join("\n");
@@ -4673,11 +4674,18 @@ var LLM = class {
4673
4674
  let iterations = 0;
4674
4675
  let finalText = "";
4675
4676
  let currentUserMessage = messages.user;
4677
+ let totalToolCalls = 0;
4678
+ let totalInputTokens = 0;
4679
+ let totalOutputTokens = 0;
4676
4680
  while (iterations < maxIterations) {
4677
4681
  iterations++;
4682
+ const iterationStartTime = Date.now();
4683
+ const requestId = llmUsageLogger.generateRequestId();
4678
4684
  const result = await chat.sendMessageStream(currentUserMessage);
4679
4685
  let responseText = "";
4680
4686
  const functionCalls = [];
4687
+ let inputTokens = 0;
4688
+ let outputTokens = 0;
4681
4689
  for await (const chunk of result.stream) {
4682
4690
  const candidate = chunk.candidates?.[0];
4683
4691
  if (!candidate) continue;
@@ -4694,7 +4702,37 @@ var LLM = class {
4694
4702
  });
4695
4703
  }
4696
4704
  }
4705
+ if (chunk.usageMetadata) {
4706
+ inputTokens = chunk.usageMetadata.promptTokenCount || 0;
4707
+ outputTokens = chunk.usageMetadata.candidatesTokenCount || 0;
4708
+ }
4697
4709
  }
4710
+ const iterationDuration = Date.now() - iterationStartTime;
4711
+ const toolCallsInIteration = functionCalls.length;
4712
+ totalToolCalls += toolCallsInIteration;
4713
+ if (inputTokens === 0) {
4714
+ const userMsg = typeof currentUserMessage === "string" ? currentUserMessage : JSON.stringify(currentUserMessage);
4715
+ inputTokens = Math.ceil((systemPrompt.length + userMsg.length) / 4);
4716
+ }
4717
+ if (outputTokens === 0) {
4718
+ outputTokens = Math.ceil(responseText.length / 4);
4719
+ }
4720
+ totalInputTokens += inputTokens;
4721
+ totalOutputTokens += outputTokens;
4722
+ llmUsageLogger.log({
4723
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
4724
+ requestId,
4725
+ provider: "gemini",
4726
+ model: modelName,
4727
+ method: `streamWithTools[iter=${iterations}]`,
4728
+ inputTokens,
4729
+ outputTokens,
4730
+ totalTokens: inputTokens + outputTokens,
4731
+ costUSD: llmUsageLogger.calculateCost(modelName, inputTokens, outputTokens),
4732
+ durationMs: iterationDuration,
4733
+ toolCalls: toolCallsInIteration,
4734
+ success: true
4735
+ });
4698
4736
  if (functionCalls.length === 0) {
4699
4737
  finalText = responseText;
4700
4738
  break;
@@ -4727,6 +4765,23 @@ var LLM = class {
4727
4765
  }));
4728
4766
  currentUserMessage = functionResponseParts;
4729
4767
  }
4768
+ const totalDuration = Date.now() - methodStartTime;
4769
+ if (iterations > 1) {
4770
+ llmUsageLogger.log({
4771
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
4772
+ requestId: llmUsageLogger.generateRequestId(),
4773
+ provider: "gemini",
4774
+ model: modelName,
4775
+ method: `streamWithTools[TOTAL:${iterations}iters]`,
4776
+ inputTokens: totalInputTokens,
4777
+ outputTokens: totalOutputTokens,
4778
+ totalTokens: totalInputTokens + totalOutputTokens,
4779
+ costUSD: llmUsageLogger.calculateCost(modelName, totalInputTokens, totalOutputTokens),
4780
+ durationMs: totalDuration,
4781
+ toolCalls: totalToolCalls,
4782
+ success: true
4783
+ });
4784
+ }
4730
4785
  if (iterations >= maxIterations) {
4731
4786
  throw new Error(`Max iterations (${maxIterations}) reached in tool calling loop`);
4732
4787
  }
@@ -6781,10 +6836,10 @@ var GeminiLLM = class extends BaseLLM {
6781
6836
  super(config);
6782
6837
  }
6783
6838
  getDefaultModel() {
6784
- return "gemini/gemini-2.5-flash";
6839
+ return "gemini/gemini-3-pro-preview";
6785
6840
  }
6786
6841
  getDefaultFastModel() {
6787
- return "gemini/gemini-2.0-flash-exp";
6842
+ return "gemini/gemini-3-flash-preview";
6788
6843
  }
6789
6844
  getDefaultApiKey() {
6790
6845
  return process.env.GEMINI_API_KEY;
@@ -10164,7 +10219,13 @@ function sendResponse8(id, res, sendMessage, clientId) {
10164
10219
  // src/handlers/dash-comp-request.ts
10165
10220
  init_logger();
10166
10221
  init_prompt_loader();
10167
- async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, _collections, tools) {
10222
+ var DEFAULT_DASH_COMP_MODELS = {
10223
+ anthropic: "anthropic/claude-haiku-4-5-20251001",
10224
+ gemini: "gemini/gemini-3-flash-preview",
10225
+ openai: "openai/gpt-4o-mini",
10226
+ groq: "groq/llama-3.3-70b-versatile"
10227
+ };
10228
+ async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, _collections, tools, dashCompModels) {
10168
10229
  const errors = [];
10169
10230
  let availableComponentsText = "No components available";
10170
10231
  if (components && components.length > 0) {
@@ -10202,27 +10263,37 @@ async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApi
10202
10263
  logger.debug("[DASH_COMP_REQ] Loaded dash-comp-picker prompts with schema and tools");
10203
10264
  const providers = llmProviders || ["anthropic", "gemini", "openai", "groq"];
10204
10265
  let apiKey;
10205
- let model = "anthropic/claude-sonnet-4-5-20250929";
10206
- for (const provider of providers) {
10207
- if (provider === "anthropic" && anthropicApiKey) {
10208
- apiKey = anthropicApiKey;
10209
- model = "anthropic/claude-sonnet-4-5-20250929";
10210
- break;
10211
- } else if (provider === "openai" && openaiApiKey) {
10212
- apiKey = openaiApiKey;
10213
- model = "openai/gpt-4o-mini";
10214
- break;
10215
- } else if (provider === "gemini" && geminiApiKey) {
10216
- apiKey = geminiApiKey;
10217
- model = "google/gemini-2.0-flash-001";
10218
- break;
10219
- } else if (provider === "groq" && groqApiKey) {
10220
- apiKey = groqApiKey;
10221
- model = "groq/llama-3.3-70b-versatile";
10222
- break;
10266
+ let model;
10267
+ if (dashCompModels?.model) {
10268
+ model = dashCompModels.model;
10269
+ const modelProvider = model.split("/")[0];
10270
+ if (modelProvider === "anthropic") apiKey = anthropicApiKey;
10271
+ else if (modelProvider === "gemini") apiKey = geminiApiKey;
10272
+ else if (modelProvider === "openai") apiKey = openaiApiKey;
10273
+ else if (modelProvider === "groq") apiKey = groqApiKey;
10274
+ logger.info(`[DASH_COMP_REQ] Using configured model: ${model}`);
10275
+ } else {
10276
+ for (const provider of providers) {
10277
+ if (provider === "anthropic" && anthropicApiKey) {
10278
+ apiKey = anthropicApiKey;
10279
+ model = DEFAULT_DASH_COMP_MODELS.anthropic;
10280
+ break;
10281
+ } else if (provider === "gemini" && geminiApiKey) {
10282
+ apiKey = geminiApiKey;
10283
+ model = DEFAULT_DASH_COMP_MODELS.gemini;
10284
+ break;
10285
+ } else if (provider === "openai" && openaiApiKey) {
10286
+ apiKey = openaiApiKey;
10287
+ model = DEFAULT_DASH_COMP_MODELS.openai;
10288
+ break;
10289
+ } else if (provider === "groq" && groqApiKey) {
10290
+ apiKey = groqApiKey;
10291
+ model = DEFAULT_DASH_COMP_MODELS.groq;
10292
+ break;
10293
+ }
10223
10294
  }
10224
10295
  }
10225
- if (!apiKey) {
10296
+ if (!apiKey || !model) {
10226
10297
  errors.push("No API key available for any LLM provider");
10227
10298
  return { success: false, errors };
10228
10299
  }
@@ -10245,11 +10316,21 @@ async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApi
10245
10316
  logger.file("[DASH_COMP_REQ] LLM response:", JSON.stringify(result, null, 2));
10246
10317
  if (!result.componentId || !result.props) {
10247
10318
  errors.push("Invalid LLM response: missing componentId or props");
10319
+ userPromptErrorLogger.logError("DASH_COMP_REQ", "Invalid LLM response structure", {
10320
+ prompt,
10321
+ result,
10322
+ missingFields: { componentId: !result.componentId, props: !result.props }
10323
+ });
10248
10324
  return { success: false, errors };
10249
10325
  }
10250
10326
  const originalComponent = components.find((c) => c.id === result.componentId);
10251
10327
  if (!originalComponent) {
10252
10328
  errors.push(`Component ${result.componentId} not found in available components`);
10329
+ userPromptErrorLogger.logError("DASH_COMP_REQ", "Component not found", {
10330
+ prompt,
10331
+ componentId: result.componentId,
10332
+ availableComponentIds: components.map((c) => c.id)
10333
+ });
10253
10334
  return { success: false, errors };
10254
10335
  }
10255
10336
  const finalComponent = {
@@ -10278,11 +10359,16 @@ async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApi
10278
10359
  } catch (error) {
10279
10360
  const errorMsg = error instanceof Error ? error.message : String(error);
10280
10361
  logger.error(`[DASH_COMP_REQ] Error picking component: ${errorMsg}`);
10362
+ userPromptErrorLogger.logError("DASH_COMP_REQ", error instanceof Error ? error : new Error(errorMsg), {
10363
+ prompt,
10364
+ componentsCount: components.length,
10365
+ toolsCount: tools?.length || 0
10366
+ });
10281
10367
  errors.push(errorMsg);
10282
10368
  return { success: false, errors };
10283
10369
  }
10284
10370
  }
10285
- var processDashCompRequest = async (data, components, _sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, tools) => {
10371
+ var processDashCompRequest = async (data, components, _sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, tools, dashCompModels) => {
10286
10372
  const errors = [];
10287
10373
  logger.debug("[DASH_COMP_REQ] Parsing incoming message data");
10288
10374
  const parseResult = DashCompRequestMessageSchema.safeParse(data);
@@ -10297,6 +10383,8 @@ var processDashCompRequest = async (data, components, _sendMessage, anthropicApi
10297
10383
  const { id, payload } = dashCompRequest;
10298
10384
  const prompt = payload.prompt;
10299
10385
  const wsId = dashCompRequest.from.id || "unknown";
10386
+ const promptContext = `DASH_COMP: ${prompt?.substring(0, 50)}${(prompt?.length || 0) > 50 ? "..." : ""}`;
10387
+ llmUsageLogger.resetLogFile(promptContext);
10300
10388
  if (!prompt) {
10301
10389
  errors.push("Prompt is required");
10302
10390
  }
@@ -10323,8 +10411,10 @@ var processDashCompRequest = async (data, components, _sendMessage, anthropicApi
10323
10411
  openaiApiKey,
10324
10412
  llmProviders,
10325
10413
  collections,
10326
- tools
10414
+ tools,
10415
+ dashCompModels
10327
10416
  );
10417
+ llmUsageLogger.logSessionSummary(`DASH_COMP: ${prompt?.substring(0, 30)}`);
10328
10418
  return {
10329
10419
  success: llmResponse.success,
10330
10420
  data: llmResponse.data,
@@ -10333,7 +10423,7 @@ var processDashCompRequest = async (data, components, _sendMessage, anthropicApi
10333
10423
  wsId
10334
10424
  };
10335
10425
  };
10336
- async function handleDashCompRequest(data, components, sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, tools) {
10426
+ async function handleDashCompRequest(data, components, sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, tools, dashCompModels) {
10337
10427
  const response = await processDashCompRequest(
10338
10428
  data,
10339
10429
  components,
@@ -10344,7 +10434,8 @@ async function handleDashCompRequest(data, components, sendMessage, anthropicApi
10344
10434
  openaiApiKey,
10345
10435
  llmProviders,
10346
10436
  collections,
10347
- tools
10437
+ tools,
10438
+ dashCompModels
10348
10439
  );
10349
10440
  sendDashCompResponse(
10350
10441
  response.id || data.id,