@superatomai/sdk-node 0.0.11-mds → 0.0.12-mds

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
@@ -741,6 +741,10 @@ declare const ToolSchema: z.ZodObject<{
741
741
  id: z.ZodString;
742
742
  name: z.ZodString;
743
743
  description: z.ZodString;
744
+ /** Tool type: "source" = routed through SourceAgent, "direct" = called directly by MainAgent */
745
+ toolType: z.ZodOptional<z.ZodEnum<["source", "direct"]>>;
746
+ /** Full untruncated schema for source agent (all columns visible) */
747
+ fullSchema: z.ZodOptional<z.ZodString>;
744
748
  params: z.ZodRecord<z.ZodString, z.ZodString>;
745
749
  fn: z.ZodFunction<z.ZodTuple<[z.ZodAny], z.ZodUnknown>, z.ZodAny>;
746
750
  outputSchema: z.ZodOptional<z.ZodObject<{
@@ -779,6 +783,8 @@ declare const ToolSchema: z.ZodObject<{
779
783
  name: string;
780
784
  description: string;
781
785
  fn: (args_0: any, ...args: unknown[]) => any;
786
+ toolType?: "source" | "direct" | undefined;
787
+ fullSchema?: string | undefined;
782
788
  outputSchema?: {
783
789
  description: string;
784
790
  fields: {
@@ -793,6 +799,8 @@ declare const ToolSchema: z.ZodObject<{
793
799
  name: string;
794
800
  description: string;
795
801
  fn: (args_0: any, ...args: unknown[]) => any;
802
+ toolType?: "source" | "direct" | undefined;
803
+ fullSchema?: string | undefined;
796
804
  outputSchema?: {
797
805
  description: string;
798
806
  fields: {
package/dist/index.d.ts CHANGED
@@ -741,6 +741,10 @@ declare const ToolSchema: z.ZodObject<{
741
741
  id: z.ZodString;
742
742
  name: z.ZodString;
743
743
  description: z.ZodString;
744
+ /** Tool type: "source" = routed through SourceAgent, "direct" = called directly by MainAgent */
745
+ toolType: z.ZodOptional<z.ZodEnum<["source", "direct"]>>;
746
+ /** Full untruncated schema for source agent (all columns visible) */
747
+ fullSchema: z.ZodOptional<z.ZodString>;
744
748
  params: z.ZodRecord<z.ZodString, z.ZodString>;
745
749
  fn: z.ZodFunction<z.ZodTuple<[z.ZodAny], z.ZodUnknown>, z.ZodAny>;
746
750
  outputSchema: z.ZodOptional<z.ZodObject<{
@@ -779,6 +783,8 @@ declare const ToolSchema: z.ZodObject<{
779
783
  name: string;
780
784
  description: string;
781
785
  fn: (args_0: any, ...args: unknown[]) => any;
786
+ toolType?: "source" | "direct" | undefined;
787
+ fullSchema?: string | undefined;
782
788
  outputSchema?: {
783
789
  description: string;
784
790
  fields: {
@@ -793,6 +799,8 @@ declare const ToolSchema: z.ZodObject<{
793
799
  name: string;
794
800
  description: string;
795
801
  fn: (args_0: any, ...args: unknown[]) => any;
802
+ toolType?: "source" | "direct" | undefined;
803
+ fullSchema?: string | undefined;
796
804
  outputSchema?: {
797
805
  description: string;
798
806
  fields: {
package/dist/index.js CHANGED
@@ -393,6 +393,10 @@ var ToolSchema = import_zod3.z.object({
393
393
  id: import_zod3.z.string(),
394
394
  name: import_zod3.z.string(),
395
395
  description: import_zod3.z.string(),
396
+ /** Tool type: "source" = routed through SourceAgent, "direct" = called directly by MainAgent */
397
+ toolType: import_zod3.z.enum(["source", "direct"]).optional(),
398
+ /** Full untruncated schema for source agent (all columns visible) */
399
+ fullSchema: import_zod3.z.string().optional(),
396
400
  params: import_zod3.z.record(import_zod3.z.string()),
397
401
  fn: import_zod3.z.function().args(import_zod3.z.any()).returns(import_zod3.z.any()),
398
402
  outputSchema: OutputSchema.optional()
@@ -7178,28 +7182,35 @@ var MainAgent = class {
7178
7182
  * Handle a user question using the multi-agent system.
7179
7183
  *
7180
7184
  * This is ONE LLM.streamWithTools() call. The LLM:
7181
- * 1. Sees source summaries in system prompt (~100 tokens each)
7182
- * 2. Decides which source(s) to query (routing)
7183
- * 3. Calls source tools → SourceAgent runs independently → returns data
7184
- * 4. Sees data, decides if it needs more calls tools again if needed
7185
+ * 1. Sees source summaries + direct tool descriptions in system prompt
7186
+ * 2. Decides which tool(s) to call (routing)
7187
+ * 3. Source tools → SourceAgent runs independently → returns data
7188
+ * 4. Direct tools fn() called directly with LLM params returns data
7185
7189
  * 5. Generates final analysis text
7186
7190
  */
7187
7191
  async handleQuestion(userPrompt, apiKey, conversationHistory, streamCallback) {
7188
7192
  const startTime = Date.now();
7189
7193
  logger.info(`[MainAgent] Starting | prompt: "${userPrompt.substring(0, 50)}..."`);
7190
- const summaries = buildSourceSummaries(this.externalTools);
7191
- logger.info(`[MainAgent] ${summaries.length} source(s) available`);
7192
- const systemPrompt = await this.buildSystemPrompt(summaries, conversationHistory);
7194
+ const sourceTools = this.externalTools.filter((t) => t.toolType !== "direct");
7195
+ const directTools = this.externalTools.filter((t) => t.toolType === "direct");
7196
+ logger.info(`[MainAgent] ${sourceTools.length} source tool(s), ${directTools.length} direct tool(s)`);
7197
+ const summaries = buildSourceSummaries(sourceTools);
7198
+ const systemPrompt = await this.buildSystemPrompt(summaries, directTools, conversationHistory);
7193
7199
  logger.logLLMPrompt("mainAgent", "system", extractPromptText(systemPrompt));
7194
7200
  logger.logLLMPrompt("mainAgent", "user", userPrompt);
7195
- const tools = this.buildSourceToolDefinitions(summaries);
7201
+ const sourceToolDefs = this.buildSourceToolDefinitions(summaries);
7202
+ const directToolDefs = this.buildDirectToolDefinitions(directTools);
7203
+ const tools = [...sourceToolDefs, ...directToolDefs];
7196
7204
  const sourceResults = [];
7197
7205
  const executedTools = [];
7198
7206
  const toolHandler = async (toolName, toolInput) => {
7199
7207
  const externalTool = this.externalTools.find((t) => t.id === toolName);
7200
7208
  if (!externalTool) {
7201
7209
  logger.error(`[MainAgent] Unknown tool called: ${toolName}`);
7202
- return `Error: Unknown data source "${toolName}"`;
7210
+ return `Error: Unknown tool "${toolName}"`;
7211
+ }
7212
+ if (externalTool.toolType === "direct") {
7213
+ return this.handleDirectTool(externalTool, toolInput, executedTools);
7203
7214
  }
7204
7215
  const sourceInput = {
7205
7216
  intent: toolInput.intent || toolInput.query || JSON.stringify(toolInput),
@@ -7239,17 +7250,93 @@ var MainAgent = class {
7239
7250
  };
7240
7251
  }
7241
7252
  // ============================================
7253
+ // Direct Tool Execution
7254
+ // ============================================
7255
+ /**
7256
+ * Execute a direct tool — call fn() with LLM-provided params, no SourceAgent.
7257
+ */
7258
+ async handleDirectTool(tool, toolInput, executedTools) {
7259
+ const startTime = Date.now();
7260
+ logger.info(`[MainAgent] Executing direct tool "${tool.name}" | params: ${JSON.stringify(toolInput).substring(0, 200)}`);
7261
+ if (this.streamBuffer.hasCallback()) {
7262
+ this.streamBuffer.write(`
7263
+
7264
+ \u{1F527} **Running ${tool.name}...**
7265
+
7266
+ `);
7267
+ await streamDelay();
7268
+ }
7269
+ try {
7270
+ const result = await tool.fn(toolInput);
7271
+ const executionTimeMs = Date.now() - startTime;
7272
+ if (result && result.error) {
7273
+ const errorMsg = typeof result.error === "string" ? result.error : JSON.stringify(result.error);
7274
+ logger.warn(`[MainAgent] Direct tool "${tool.name}" returned error: ${errorMsg}`);
7275
+ return `\u274C Tool "${tool.name}" error: ${errorMsg}`;
7276
+ }
7277
+ const resultData = result.data || result;
7278
+ const rowCount = Array.isArray(resultData) ? resultData.length : 1;
7279
+ if (this.streamBuffer.hasCallback()) {
7280
+ this.streamBuffer.write(`\u2705 **${tool.name}** completed (${rowCount} results, ${executionTimeMs}ms)
7281
+
7282
+ `);
7283
+ }
7284
+ const formattedResult = formatToolResultForLLM(result, {
7285
+ toolName: tool.name,
7286
+ maxRows: 5,
7287
+ maxCharsPerField: 200
7288
+ });
7289
+ executedTools.push({
7290
+ id: tool.id,
7291
+ name: tool.name,
7292
+ params: toolInput,
7293
+ result: {
7294
+ _totalRecords: result.totalItems || result.count || rowCount,
7295
+ _recordsShown: rowCount,
7296
+ _metadata: result.metadata,
7297
+ _sampleData: Array.isArray(resultData) ? resultData.slice(0, 3) : [resultData]
7298
+ },
7299
+ outputSchema: tool.outputSchema
7300
+ });
7301
+ const formatted = typeof formattedResult === "string" ? formattedResult : JSON.stringify(formattedResult);
7302
+ return `\u2705 Tool "${tool.name}" executed successfully. ${rowCount} results returned.
7303
+
7304
+ ${formatted}`;
7305
+ } catch (error) {
7306
+ const executionTimeMs = Date.now() - startTime;
7307
+ const errorMsg = error instanceof Error ? error.message : String(error);
7308
+ logger.error(`[MainAgent] Direct tool "${tool.name}" failed in ${executionTimeMs}ms: ${errorMsg}`);
7309
+ if (this.streamBuffer.hasCallback()) {
7310
+ this.streamBuffer.write(`
7311
+
7312
+ \u274C **${tool.name} failed:** ${errorMsg}
7313
+
7314
+ `);
7315
+ }
7316
+ return `\u274C Tool "${tool.name}" failed: ${errorMsg}`;
7317
+ }
7318
+ }
7319
+ // ============================================
7242
7320
  // System Prompt
7243
7321
  // ============================================
7244
7322
  /**
7245
- * Build the main agent's system prompt with source summaries.
7246
- * Loads from prompt loader (file system → hardcoded fallback in prompts.ts).
7323
+ * Build the main agent's system prompt with source summaries and direct tool descriptions.
7247
7324
  */
7248
- async buildSystemPrompt(summaries, conversationHistory) {
7325
+ async buildSystemPrompt(summaries, directTools, conversationHistory) {
7249
7326
  const summariesText = formatSummariesForPrompt(summaries);
7250
7327
  const maxSourceCalls = Math.max(2, this.config.maxIterations - 2);
7328
+ let directToolsText = "";
7329
+ if (directTools.length > 0) {
7330
+ directToolsText = directTools.map((t, idx) => {
7331
+ const params = t.params || {};
7332
+ const paramList = Object.entries(params).map(([k, v]) => ` - ${k}: ${v}`).join("\n");
7333
+ return `${idx + 1}. **${t.name}** (tool: ${t.id})
7334
+ ${t.description || "No description"}${paramList ? "\n Parameters:\n" + paramList : ""}`;
7335
+ }).join("\n\n");
7336
+ }
7251
7337
  const prompts = await promptLoader.loadPrompts("agent-main", {
7252
7338
  SOURCE_SUMMARIES: summariesText,
7339
+ DIRECT_TOOLS: directToolsText,
7253
7340
  MAX_ROWS: String(this.config.maxRowsPerSource),
7254
7341
  MAX_SOURCE_CALLS: String(maxSourceCalls),
7255
7342
  GLOBAL_KNOWLEDGE_BASE: this.config.globalKnowledgeBase || "No global knowledge base available.",
@@ -7260,11 +7347,10 @@ var MainAgent = class {
7260
7347
  return prompts.system;
7261
7348
  }
7262
7349
  // ============================================
7263
- // Tool Definitions (summary-only, no full schema)
7350
+ // Tool Definitions
7264
7351
  // ============================================
7265
7352
  /**
7266
- * Build tool definitions for the main agent one per source.
7267
- * Descriptions include entity names with column names for routing.
7353
+ * Build tool definitions for source toolssummary-only descriptions.
7268
7354
  * The full schema is inside the SourceAgent which runs independently.
7269
7355
  */
7270
7356
  buildSourceToolDefinitions(summaries) {
@@ -7296,14 +7382,51 @@ var MainAgent = class {
7296
7382
  };
7297
7383
  });
7298
7384
  }
7385
+ /**
7386
+ * Build tool definitions for direct tools — expose their actual params.
7387
+ * These are called directly by the main agent LLM, no SourceAgent.
7388
+ */
7389
+ buildDirectToolDefinitions(directTools) {
7390
+ return directTools.map((tool) => {
7391
+ const properties = {};
7392
+ const required = [];
7393
+ const toolParams = tool.params || {};
7394
+ Object.entries(toolParams).forEach(([key, typeOrValue]) => {
7395
+ const valueStr = String(typeOrValue).toLowerCase();
7396
+ let schemaType = "string";
7397
+ const typeMatch = valueStr.match(/^(string|number|integer|boolean|array|object)\b/);
7398
+ if (typeMatch) {
7399
+ schemaType = typeMatch[1];
7400
+ }
7401
+ const isOptional = valueStr.includes("(optional)") || valueStr.includes("optional");
7402
+ const description = typeof typeOrValue === "string" ? typeOrValue : `Parameter: ${key}`;
7403
+ if (schemaType === "array") {
7404
+ properties[key] = { type: "array", items: { type: "string" }, description };
7405
+ } else if (schemaType === "object") {
7406
+ properties[key] = { type: "object", description };
7407
+ } else {
7408
+ properties[key] = { type: schemaType, description };
7409
+ }
7410
+ if (!isOptional) {
7411
+ required.push(key);
7412
+ }
7413
+ });
7414
+ return {
7415
+ name: tool.id,
7416
+ description: tool.description || `Call ${tool.name}`,
7417
+ input_schema: {
7418
+ type: "object",
7419
+ properties,
7420
+ required: required.length > 0 ? required : void 0
7421
+ }
7422
+ };
7423
+ });
7424
+ }
7299
7425
  // ============================================
7300
7426
  // Format Result for Main Agent
7301
7427
  // ============================================
7302
7428
  /**
7303
7429
  * Format a source agent's result as a clean string for the main agent LLM.
7304
- * Passes through the data as-is — no server-side aggregation.
7305
- * If the main agent needs aggregates, it should request aggregation: "pre-aggregate"
7306
- * from the source agent, which handles it at the query level (SQL GROUP BY, etc.).
7307
7430
  */
7308
7431
  formatResultForMainAgent(result) {
7309
7432
  if (!result.success) {
@@ -9969,6 +10092,7 @@ var get_agent_user_response = async (prompt, components, anthropicApiKey, groqAp
9969
10092
  id: t.id,
9970
10093
  name: t.name,
9971
10094
  description: t.description,
10095
+ toolType: t.toolType,
9972
10096
  fullSchema: t.fullSchema,
9973
10097
  fn: t.fn,
9974
10098
  limit: t.limit,