@superatomai/sdk-node 0.0.58-dsp → 0.0.59-dsp

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
@@ -2095,6 +2095,34 @@ interface DashCompModelConfig {
2095
2095
  */
2096
2096
  fastModel?: string;
2097
2097
  }
2098
+ /**
2099
+ * Everything a replacement answer flow is handed for one question. Deliberately
2100
+ * the same material the built-in flow gets, so a provider is a drop-in and not a
2101
+ * second-class path.
2102
+ */
2103
+ interface AnswerProviderContext {
2104
+ prompt: string;
2105
+ /** The live frontend component catalog. */
2106
+ components: Component[];
2107
+ collections?: any;
2108
+ externalTools?: any[];
2109
+ userId?: string;
2110
+ threadId?: string;
2111
+ /** Per-user authorization config (users.config) — row policies come from here. */
2112
+ userConfig?: any;
2113
+ conversationHistory?: string;
2114
+ /** Stream user-facing prose. Do NOT stream tool/command output through this. */
2115
+ onStream?: (chunk: string) => void;
2116
+ signal?: AbortSignal;
2117
+ }
2118
+ /**
2119
+ * An alternative to the built-in MainAgent/SourceAgent flow.
2120
+ *
2121
+ * Returns the same T_RESPONSE the built-in flow does, so everything downstream —
2122
+ * the UIBlock, streaming, abort, the conversation save, component rendering — is
2123
+ * unchanged and the two flows stay comparable.
2124
+ */
2125
+ type AnswerProvider = (ctx: AnswerProviderContext) => Promise<T_RESPONSE>;
2098
2126
  interface SuperatomSDKConfig {
2099
2127
  url?: string;
2100
2128
  apiKey?: string;
@@ -2132,6 +2160,16 @@ interface SuperatomSDKConfig {
2132
2160
  * If not set, uses the provider's default model.
2133
2161
  */
2134
2162
  sourceAgentModel?: string;
2163
+ /**
2164
+ * Which flow answers a user question.
2165
+ * 'agents' — the built-in MainAgent + SourceAgent flow (default).
2166
+ * 'custom' — call `answerProvider` instead.
2167
+ * Set 'custom' WITHOUT a provider and the SDK warns and uses 'agents', rather
2168
+ * than failing every question.
2169
+ */
2170
+ answerFlow?: 'agents' | 'custom';
2171
+ /** Required when answerFlow is 'custom'. See AnswerProvider. */
2172
+ answerProvider?: AnswerProvider;
2135
2173
  /**
2136
2174
  * Separate model configuration for DASH_COMP flow (dashboard component picking)
2137
2175
  * If not provided, falls back to provider-based model selection
@@ -3258,6 +3296,26 @@ declare class MainAgent {
3258
3296
  getSourceSummaries(): SourceSummary[];
3259
3297
  }
3260
3298
 
3299
+ interface FmtConfig {
3300
+ /** BCP-47 tag driving grouping and the scale vocabulary, e.g. 'en-IN', 'en-US'. */
3301
+ locale: string;
3302
+ /** ISO-4217 code for money, e.g. 'INR', 'USD'. */
3303
+ currency: string;
3304
+ }
3305
+ declare const DEFAULT_FMT_CONFIG: FmtConfig;
3306
+ interface Fmt {
3307
+ money(v: unknown, decimals?: number): string;
3308
+ num(v: unknown, decimals?: number): string;
3309
+ count(v: unknown, decimals?: number): string;
3310
+ pct(part: unknown, whole: unknown, decimals?: number): string;
3311
+ delta(current: unknown, previous: unknown, decimals?: number): string;
3312
+ date(v: unknown): string;
3313
+ range(from: unknown, to: unknown): string;
3314
+ list(items: unknown[], conjunction?: string): string;
3315
+ }
3316
+ /** Build a `fmt` bound to one locale/currency. */
3317
+ declare function makeFmt(cfg?: Partial<FmtConfig>): Fmt;
3318
+
3261
3319
  type SystemPrompt = string | Anthropic.Messages.TextBlockParam[];
3262
3320
  interface LLMMessages {
3263
3321
  sys: SystemPrompt;
@@ -5237,6 +5295,12 @@ interface AgentRunContext {
5237
5295
  /** Live progress. Populated for chat mode; a task run may also stream to a log. */
5238
5296
  onOutput?: (chunk: string) => void;
5239
5297
  onEvent?: (event: AgentEvent) => void;
5298
+ /**
5299
+ * Assistant prose only — safe to show a non-technical user as progress.
5300
+ * Distinct from onOutput, which also carries command and tool lines and so
5301
+ * would leak SQL and shell text into a user-facing stream.
5302
+ */
5303
+ onNarration?: (text: string) => void;
5240
5304
  onUsage?: (usage: AgentUsage) => void;
5241
5305
  }
5242
5306
  /**
@@ -5532,6 +5596,19 @@ declare function writeBridgeShims(ws: Workspace, opts: {
5532
5596
  description?: string;
5533
5597
  }>;
5534
5598
  maxRows?: number;
5599
+ /**
5600
+ * Identity for the queries this agent runs, from mintContextToken().
5601
+ *
5602
+ * The agent is a separate OS process calling the bridge over loopback
5603
+ * HTTP, so nothing ambient crosses that gap — the same break the script
5604
+ * flow has (see utils/context-token.ts). Without this the bridge sees an
5605
+ * anonymous query, and under SA_SQL_REWRITE_MODE=enforce the data seam
5606
+ * refuses it outright rather than guessing whose data it is.
5607
+ *
5608
+ * Omit ONLY when the caller genuinely has no identity to grant; the
5609
+ * queries are then anonymous, which is the truth rather than a default.
5610
+ */
5611
+ contextToken?: string;
5535
5612
  }): void;
5536
5613
 
5537
5614
  /**
@@ -5679,6 +5756,117 @@ interface RunScriptOptions {
5679
5756
  */
5680
5757
  declare function runScript(recipe: ScriptRecipe, scriptPath: string, params: Record<string, any>, options: RunScriptOptions): Promise<ScriptResult>;
5681
5758
 
5759
+ /**
5760
+ * Answer-flow component catalog (§2.6 a/e).
5761
+ *
5762
+ * The frontend sends ONE catalog to the SDK; five consumers read it and four of
5763
+ * them narrow it for their own purpose (dashComp strips the container,
5764
+ * create-filter selects Filter*, suggestions selects isDisplayComp). The answer
5765
+ * flow was the only one that didn't. These helpers are its narrowing.
5766
+ *
5767
+ * Nothing here mutates the stored `Metadata` — dashboard and report generation
5768
+ * legitimately need the SQL-authoring contract that the answer flow must not see,
5769
+ * so the answer flow gets a PROJECTION instead.
5770
+ *
5771
+ * See backend/docs/COMPONENT-GENERATION-V2.md §2.6.
5772
+ */
5773
+
5774
+ /**
5775
+ * The only components that can answer a data question. Everything else in the
5776
+ * catalog belongs to dashboards (filters, forms), is a whole page (Home,
5777
+ * DatabaseOverview), is a UI primitive, or is the wrapper this flow builds.
5778
+ *
5779
+ * DynamicWaterfallChart is deliberately excluded — see §2.6(e). Adding it back
5780
+ * is a one-line change here.
5781
+ */
5782
+ declare const ANSWER_COMPONENT_NAMES: readonly string[];
5783
+ /**
5784
+ * Narrow the registered catalog to the components that can answer a question.
5785
+ * Safe for every answer-flow generator — none of them should ever nominate a
5786
+ * filter widget, a text input, or the MultiComponentContainer the flow itself
5787
+ * builds around their output.
5788
+ */
5789
+ declare function answerComponents(components: Component[] | undefined): Component[];
5790
+ /**
5791
+ * Rewrite the catalog for a flow that binds pre-executed datasets rather than
5792
+ * authoring SQL. Apply ONLY where the flow discards component-authored SQL —
5793
+ * `generateScriptComponents` and the `write_components` tool.
5794
+ *
5795
+ * Do NOT apply to `generateAgentComponents`: that path really does write SQL
5796
+ * into externalTool.parameters.sql and validates it by executing it.
5797
+ */
5798
+ declare function projectForDatasetBinding(components: Component[]): Component[];
5799
+ /** Filter + project in one call — the catalog the tool and script generator see. */
5800
+ declare function answerCatalogForBinding(components: Component[] | undefined): Component[];
5801
+
5802
+ /**
5803
+ * Component Spec Validator — V1–V8
5804
+ *
5805
+ * Deterministic checks of a component spec against the REAL columns of the
5806
+ * dataset it binds. Pure: no LLM, no mutation, no I/O. Shared by the fallback
5807
+ * generator (report-only today) and the `write_components` tool, which hands the
5808
+ * findings back to the agent so it can fix getComponents and retry.
5809
+ *
5810
+ * See backend/docs/COMPONENT-GENERATION-V2.md §2.3.
5811
+ */
5812
+ type ColType = 'NUMBER' | 'TEXT' | 'DATE' | 'BOOLEAN';
5813
+ interface ColInfo {
5814
+ name: string;
5815
+ type: ColType;
5816
+ /** Every sampled non-null value is identical — a per-row invariant (e.g. a
5817
+ * total the script computed the same on every row). Must not be summed. */
5818
+ invariant: boolean;
5819
+ }
5820
+ /** Infer column name + type + invariance from a sample of rows. */
5821
+ declare function inferColumns(rows: any[]): Map<string, ColInfo>;
5822
+ /** Keys that must resolve to a NUMBER column. */
5823
+ declare const NUMERIC_KEYS: readonly ["yAxisKey", "valueKey", "aggregationField", "sizeKey", "latitudeField", "longitudeField", "orderField"];
5824
+ /** Keys that must resolve to a TEXT or DATE column. */
5825
+ declare const CATEGORY_KEYS: readonly ["xAxisKey", "nameKey", "seriesKey", "groupBy", "categoryKey", "dimensionKey", "labelField", "stageField"];
5826
+ /**
5827
+ * Every config key that names a column. Superset of the generator's original
5828
+ * list — it omitted dimensionKey (Radar), sizeKey (Scatter) and the five
5829
+ * MapView geo fields, so those passed through unvalidated. §2.6(d).
5830
+ */
5831
+ declare const ALL_COLUMN_KEYS: string[];
5832
+ type FindingCode = 'V1' | 'V2' | 'V3' | 'V4' | 'V5' | 'V6' | 'V7' | 'V8';
5833
+ interface ValidationFinding {
5834
+ code: FindingCode;
5835
+ /** `error` blocks the spec; `warn` is advisory (logged, never rejects). */
5836
+ severity: 'error' | 'warn';
5837
+ componentType: string;
5838
+ /** Message written FOR THE AGENT — states the problem and the fix. */
5839
+ message: string;
5840
+ }
5841
+ interface SpecToValidate {
5842
+ componentType: string;
5843
+ sourceRef?: string;
5844
+ title?: string;
5845
+ description?: string;
5846
+ content?: string;
5847
+ config?: Record<string, any>;
5848
+ }
5849
+ interface ValidationContext {
5850
+ /** Columns of the bound dataset. */
5851
+ cols: Map<string, ColInfo>;
5852
+ /** UNCAPPED row count of the bound dataset — the cap is applied later, so
5853
+ * validating on the capped count would hide exactly the truncation we check. */
5854
+ rowCount: number;
5855
+ /** Rows for the mark-identity check (V4). Pass every row: a sample that happens
5856
+ * to hold no duplicate would report a collapsing chart as sound. */
5857
+ rows: any[];
5858
+ /** Valid `sourceRef` values for this run. */
5859
+ availableSourceRefs: string[];
5860
+ renderCap?: number;
5861
+ }
5862
+ /**
5863
+ * Validate one component spec. Returns every finding; the caller decides
5864
+ * whether to reject (tool path) or log (fallback path).
5865
+ */
5866
+ declare function validateComponentSpec(spec: SpecToValidate, ctx: ValidationContext): ValidationFinding[];
5867
+ /** Render findings as the text tool-result the agent reads on a rejection. */
5868
+ declare function formatFindingsForAgent(findings: ValidationFinding[]): string;
5869
+
5682
5870
  type MessageTypeHandler = (message: IncomingMessage) => void | Promise<void>;
5683
5871
  declare class SuperatomSDK {
5684
5872
  private ws;
@@ -5705,6 +5893,8 @@ declare class SuperatomSDK {
5705
5893
  private modelStrategy;
5706
5894
  private mainAgentModel;
5707
5895
  private sourceAgentModel;
5896
+ private answerFlow;
5897
+ private answerProvider?;
5708
5898
  private dashCompModels?;
5709
5899
  private conversationSimilarityThreshold;
5710
5900
  private userManager;
@@ -5882,4 +6072,4 @@ declare class SuperatomSDK {
5882
6072
  getConversationSimilarityThreshold(): number;
5883
6073
  }
5884
6074
 
5885
- export { type AgentConfig, type AgentEvent, type AgentResponse, type AgentRunContext, type AgentRunHandlers, type AgentRunRecord, type AgentRunResult, type AgentTrigger, type AgentUsage, type ApplySummary, BM25L, type BM25LOptions, type BaseLLMConfig, type BuildTriggerInput, CONTEXT_CONFIG, type CapturedLog, CleanupService, type CodexSessionOptions, type CodingAgentCollectionConfig, type CodingAgentDefinition, type CodingAgentSession, type CodingAgentSessionOptions, type CodingAgentsConfig, type CollectionHandler, type CollectionOperation, type DBUIBlock, DEFAULT_AGENT_CONFIG, type DashboardAgentCollectionConfig, type DatabaseType, type Harness, type HybridSearchOptions, type IncomingMessage, type KbNodesQueryFilters, type KbNodesRequestPayload, LLM, type LLMUsageEntry, type LogLevel, MainAgent, type McpServerSpec, type Message, MissingRequestContextError, type ModelStrategy, type OutputContract, type OutputField, type OutputValidator, type Principal, type RequestContext, type RerankedResult, type RowFilter, type RunAgentOptions, STORAGE_CONFIG, type ScriptComponentSpec, ScriptMatcher, type ScriptParameter, type ScriptRecipe, type ScriptRecipeMetaRow, type ScriptRecipeStore, type ScriptResult, ScriptStore, type ScriptStoreOptions, type SelectedWorkflow, type SourcePolicy, SuperatomSDK, type SuperatomSDKConfig, type TaskType, Thread, ThreadManager, type Tool$1 as Tool, type ToolOutputSchema, type TriggerEvent, type TriggerFireInfo, UIBlock, UILogCollector, type User, UserManager, type UsersData, type WorkflowDescriptor, type Workspace, anthropicLLM, assertReadOnlySql, bindContext, captureContext, clearContextTokens, contextTokenCount, createCodexSession, createCodingAgentSession, dashboardConversationHistory, dataFingerprint, describeContext, describeTriggers, emitAgentEvent, extractNamedExport, geminiLLM, getCodingAgent, getCodingAgentsConfig, getRequestContext, groqLLM, hybridRerank, isUserContext, listCodingAgents, llmUsageLogger, logger, mintContextToken, normalizeScriptBody, onAgentRun, openaiLLM, policiesFromConfig, queryCache, registerCodingAgentCollection, registerCodingAgents, registerDashboardAgentCollection, requireRequestContext, rerankChromaResults, rerankConversationResults, resolveContextToken, resolveScriptRecipeStore, revokeContextToken, runAsSystem, runAsUser, runCodingAgent, runScript, runWithContext, runWithMessageIdentity, startAgentTriggers, stopAgentTriggers, userPromptErrorLogger, withCapturedContext, writeBridgeShims };
6075
+ export { ALL_COLUMN_KEYS, ANSWER_COMPONENT_NAMES, type AgentConfig, type AgentEvent, type AgentResponse, type AgentRunContext, type AgentRunHandlers, type AgentRunRecord, type AgentRunResult, type AgentTrigger, type AgentUsage, type AnswerProvider, type AnswerProviderContext, type ApplySummary, BM25L, type BM25LOptions, type BaseLLMConfig, type BuildTriggerInput, CATEGORY_KEYS, CONTEXT_CONFIG, type CapturedLog, CleanupService, type CodexSessionOptions, type CodingAgentCollectionConfig, type CodingAgentDefinition, type CodingAgentSession, type CodingAgentSessionOptions, type CodingAgentsConfig, type ColInfo, type ColType, type CollectionHandler, type CollectionOperation, type Component, type DBUIBlock, DEFAULT_AGENT_CONFIG, DEFAULT_FMT_CONFIG, type DashboardAgentCollectionConfig, type DatabaseType, type FindingCode, type Fmt, type FmtConfig, type Harness, type HybridSearchOptions, type IncomingMessage, type KbNodesQueryFilters, type KbNodesRequestPayload, LLM, type LLMUsageEntry, type LogLevel, MainAgent, type McpServerSpec, type Message, MissingRequestContextError, type ModelStrategy, NUMERIC_KEYS, type OutputContract, type OutputField, type OutputValidator, type Principal, type RequestContext, type RerankedResult, type RowFilter, type RunAgentOptions, STORAGE_CONFIG, type ScriptComponentSpec, ScriptMatcher, type ScriptParameter, type ScriptRecipe, type ScriptRecipeMetaRow, type ScriptRecipeStore, type ScriptResult, ScriptStore, type ScriptStoreOptions, type SelectedWorkflow, type SourcePolicy, type SpecToValidate, SuperatomSDK, type SuperatomSDKConfig, type T_RESPONSE, type TaskType, Thread, ThreadManager, type Tool$1 as Tool, type ToolOutputSchema, type TriggerEvent, type TriggerFireInfo, UIBlock, UILogCollector, type User, UserManager, type UsersData, type ValidationContext, type ValidationFinding, type WorkflowDescriptor, type Workspace, answerCatalogForBinding, answerComponents, anthropicLLM, assertReadOnlySql, bindContext, captureContext, clearContextTokens, contextTokenCount, createCodexSession, createCodingAgentSession, dashboardConversationHistory, dataFingerprint, describeContext, describeTriggers, emitAgentEvent, extractNamedExport, formatFindingsForAgent, geminiLLM, getCodingAgent, getCodingAgentsConfig, getRequestContext, groqLLM, hybridRerank, inferColumns, isUserContext, listCodingAgents, llmUsageLogger, logger, makeFmt, mintContextToken, normalizeScriptBody, onAgentRun, openaiLLM, policiesFromConfig, projectForDatasetBinding, queryCache, registerCodingAgentCollection, registerCodingAgents, registerDashboardAgentCollection, requireRequestContext, rerankChromaResults, rerankConversationResults, resolveContextToken, resolveScriptRecipeStore, revokeContextToken, runAsSystem, runAsUser, runCodingAgent, runScript, runWithContext, runWithMessageIdentity, startAgentTriggers, stopAgentTriggers, userPromptErrorLogger, validateComponentSpec, withCapturedContext, writeBridgeShims };
package/dist/index.d.ts CHANGED
@@ -2095,6 +2095,34 @@ interface DashCompModelConfig {
2095
2095
  */
2096
2096
  fastModel?: string;
2097
2097
  }
2098
+ /**
2099
+ * Everything a replacement answer flow is handed for one question. Deliberately
2100
+ * the same material the built-in flow gets, so a provider is a drop-in and not a
2101
+ * second-class path.
2102
+ */
2103
+ interface AnswerProviderContext {
2104
+ prompt: string;
2105
+ /** The live frontend component catalog. */
2106
+ components: Component[];
2107
+ collections?: any;
2108
+ externalTools?: any[];
2109
+ userId?: string;
2110
+ threadId?: string;
2111
+ /** Per-user authorization config (users.config) — row policies come from here. */
2112
+ userConfig?: any;
2113
+ conversationHistory?: string;
2114
+ /** Stream user-facing prose. Do NOT stream tool/command output through this. */
2115
+ onStream?: (chunk: string) => void;
2116
+ signal?: AbortSignal;
2117
+ }
2118
+ /**
2119
+ * An alternative to the built-in MainAgent/SourceAgent flow.
2120
+ *
2121
+ * Returns the same T_RESPONSE the built-in flow does, so everything downstream —
2122
+ * the UIBlock, streaming, abort, the conversation save, component rendering — is
2123
+ * unchanged and the two flows stay comparable.
2124
+ */
2125
+ type AnswerProvider = (ctx: AnswerProviderContext) => Promise<T_RESPONSE>;
2098
2126
  interface SuperatomSDKConfig {
2099
2127
  url?: string;
2100
2128
  apiKey?: string;
@@ -2132,6 +2160,16 @@ interface SuperatomSDKConfig {
2132
2160
  * If not set, uses the provider's default model.
2133
2161
  */
2134
2162
  sourceAgentModel?: string;
2163
+ /**
2164
+ * Which flow answers a user question.
2165
+ * 'agents' — the built-in MainAgent + SourceAgent flow (default).
2166
+ * 'custom' — call `answerProvider` instead.
2167
+ * Set 'custom' WITHOUT a provider and the SDK warns and uses 'agents', rather
2168
+ * than failing every question.
2169
+ */
2170
+ answerFlow?: 'agents' | 'custom';
2171
+ /** Required when answerFlow is 'custom'. See AnswerProvider. */
2172
+ answerProvider?: AnswerProvider;
2135
2173
  /**
2136
2174
  * Separate model configuration for DASH_COMP flow (dashboard component picking)
2137
2175
  * If not provided, falls back to provider-based model selection
@@ -3258,6 +3296,26 @@ declare class MainAgent {
3258
3296
  getSourceSummaries(): SourceSummary[];
3259
3297
  }
3260
3298
 
3299
+ interface FmtConfig {
3300
+ /** BCP-47 tag driving grouping and the scale vocabulary, e.g. 'en-IN', 'en-US'. */
3301
+ locale: string;
3302
+ /** ISO-4217 code for money, e.g. 'INR', 'USD'. */
3303
+ currency: string;
3304
+ }
3305
+ declare const DEFAULT_FMT_CONFIG: FmtConfig;
3306
+ interface Fmt {
3307
+ money(v: unknown, decimals?: number): string;
3308
+ num(v: unknown, decimals?: number): string;
3309
+ count(v: unknown, decimals?: number): string;
3310
+ pct(part: unknown, whole: unknown, decimals?: number): string;
3311
+ delta(current: unknown, previous: unknown, decimals?: number): string;
3312
+ date(v: unknown): string;
3313
+ range(from: unknown, to: unknown): string;
3314
+ list(items: unknown[], conjunction?: string): string;
3315
+ }
3316
+ /** Build a `fmt` bound to one locale/currency. */
3317
+ declare function makeFmt(cfg?: Partial<FmtConfig>): Fmt;
3318
+
3261
3319
  type SystemPrompt = string | Anthropic.Messages.TextBlockParam[];
3262
3320
  interface LLMMessages {
3263
3321
  sys: SystemPrompt;
@@ -5237,6 +5295,12 @@ interface AgentRunContext {
5237
5295
  /** Live progress. Populated for chat mode; a task run may also stream to a log. */
5238
5296
  onOutput?: (chunk: string) => void;
5239
5297
  onEvent?: (event: AgentEvent) => void;
5298
+ /**
5299
+ * Assistant prose only — safe to show a non-technical user as progress.
5300
+ * Distinct from onOutput, which also carries command and tool lines and so
5301
+ * would leak SQL and shell text into a user-facing stream.
5302
+ */
5303
+ onNarration?: (text: string) => void;
5240
5304
  onUsage?: (usage: AgentUsage) => void;
5241
5305
  }
5242
5306
  /**
@@ -5532,6 +5596,19 @@ declare function writeBridgeShims(ws: Workspace, opts: {
5532
5596
  description?: string;
5533
5597
  }>;
5534
5598
  maxRows?: number;
5599
+ /**
5600
+ * Identity for the queries this agent runs, from mintContextToken().
5601
+ *
5602
+ * The agent is a separate OS process calling the bridge over loopback
5603
+ * HTTP, so nothing ambient crosses that gap — the same break the script
5604
+ * flow has (see utils/context-token.ts). Without this the bridge sees an
5605
+ * anonymous query, and under SA_SQL_REWRITE_MODE=enforce the data seam
5606
+ * refuses it outright rather than guessing whose data it is.
5607
+ *
5608
+ * Omit ONLY when the caller genuinely has no identity to grant; the
5609
+ * queries are then anonymous, which is the truth rather than a default.
5610
+ */
5611
+ contextToken?: string;
5535
5612
  }): void;
5536
5613
 
5537
5614
  /**
@@ -5679,6 +5756,117 @@ interface RunScriptOptions {
5679
5756
  */
5680
5757
  declare function runScript(recipe: ScriptRecipe, scriptPath: string, params: Record<string, any>, options: RunScriptOptions): Promise<ScriptResult>;
5681
5758
 
5759
+ /**
5760
+ * Answer-flow component catalog (§2.6 a/e).
5761
+ *
5762
+ * The frontend sends ONE catalog to the SDK; five consumers read it and four of
5763
+ * them narrow it for their own purpose (dashComp strips the container,
5764
+ * create-filter selects Filter*, suggestions selects isDisplayComp). The answer
5765
+ * flow was the only one that didn't. These helpers are its narrowing.
5766
+ *
5767
+ * Nothing here mutates the stored `Metadata` — dashboard and report generation
5768
+ * legitimately need the SQL-authoring contract that the answer flow must not see,
5769
+ * so the answer flow gets a PROJECTION instead.
5770
+ *
5771
+ * See backend/docs/COMPONENT-GENERATION-V2.md §2.6.
5772
+ */
5773
+
5774
+ /**
5775
+ * The only components that can answer a data question. Everything else in the
5776
+ * catalog belongs to dashboards (filters, forms), is a whole page (Home,
5777
+ * DatabaseOverview), is a UI primitive, or is the wrapper this flow builds.
5778
+ *
5779
+ * DynamicWaterfallChart is deliberately excluded — see §2.6(e). Adding it back
5780
+ * is a one-line change here.
5781
+ */
5782
+ declare const ANSWER_COMPONENT_NAMES: readonly string[];
5783
+ /**
5784
+ * Narrow the registered catalog to the components that can answer a question.
5785
+ * Safe for every answer-flow generator — none of them should ever nominate a
5786
+ * filter widget, a text input, or the MultiComponentContainer the flow itself
5787
+ * builds around their output.
5788
+ */
5789
+ declare function answerComponents(components: Component[] | undefined): Component[];
5790
+ /**
5791
+ * Rewrite the catalog for a flow that binds pre-executed datasets rather than
5792
+ * authoring SQL. Apply ONLY where the flow discards component-authored SQL —
5793
+ * `generateScriptComponents` and the `write_components` tool.
5794
+ *
5795
+ * Do NOT apply to `generateAgentComponents`: that path really does write SQL
5796
+ * into externalTool.parameters.sql and validates it by executing it.
5797
+ */
5798
+ declare function projectForDatasetBinding(components: Component[]): Component[];
5799
+ /** Filter + project in one call — the catalog the tool and script generator see. */
5800
+ declare function answerCatalogForBinding(components: Component[] | undefined): Component[];
5801
+
5802
+ /**
5803
+ * Component Spec Validator — V1–V8
5804
+ *
5805
+ * Deterministic checks of a component spec against the REAL columns of the
5806
+ * dataset it binds. Pure: no LLM, no mutation, no I/O. Shared by the fallback
5807
+ * generator (report-only today) and the `write_components` tool, which hands the
5808
+ * findings back to the agent so it can fix getComponents and retry.
5809
+ *
5810
+ * See backend/docs/COMPONENT-GENERATION-V2.md §2.3.
5811
+ */
5812
+ type ColType = 'NUMBER' | 'TEXT' | 'DATE' | 'BOOLEAN';
5813
+ interface ColInfo {
5814
+ name: string;
5815
+ type: ColType;
5816
+ /** Every sampled non-null value is identical — a per-row invariant (e.g. a
5817
+ * total the script computed the same on every row). Must not be summed. */
5818
+ invariant: boolean;
5819
+ }
5820
+ /** Infer column name + type + invariance from a sample of rows. */
5821
+ declare function inferColumns(rows: any[]): Map<string, ColInfo>;
5822
+ /** Keys that must resolve to a NUMBER column. */
5823
+ declare const NUMERIC_KEYS: readonly ["yAxisKey", "valueKey", "aggregationField", "sizeKey", "latitudeField", "longitudeField", "orderField"];
5824
+ /** Keys that must resolve to a TEXT or DATE column. */
5825
+ declare const CATEGORY_KEYS: readonly ["xAxisKey", "nameKey", "seriesKey", "groupBy", "categoryKey", "dimensionKey", "labelField", "stageField"];
5826
+ /**
5827
+ * Every config key that names a column. Superset of the generator's original
5828
+ * list — it omitted dimensionKey (Radar), sizeKey (Scatter) and the five
5829
+ * MapView geo fields, so those passed through unvalidated. §2.6(d).
5830
+ */
5831
+ declare const ALL_COLUMN_KEYS: string[];
5832
+ type FindingCode = 'V1' | 'V2' | 'V3' | 'V4' | 'V5' | 'V6' | 'V7' | 'V8';
5833
+ interface ValidationFinding {
5834
+ code: FindingCode;
5835
+ /** `error` blocks the spec; `warn` is advisory (logged, never rejects). */
5836
+ severity: 'error' | 'warn';
5837
+ componentType: string;
5838
+ /** Message written FOR THE AGENT — states the problem and the fix. */
5839
+ message: string;
5840
+ }
5841
+ interface SpecToValidate {
5842
+ componentType: string;
5843
+ sourceRef?: string;
5844
+ title?: string;
5845
+ description?: string;
5846
+ content?: string;
5847
+ config?: Record<string, any>;
5848
+ }
5849
+ interface ValidationContext {
5850
+ /** Columns of the bound dataset. */
5851
+ cols: Map<string, ColInfo>;
5852
+ /** UNCAPPED row count of the bound dataset — the cap is applied later, so
5853
+ * validating on the capped count would hide exactly the truncation we check. */
5854
+ rowCount: number;
5855
+ /** Rows for the mark-identity check (V4). Pass every row: a sample that happens
5856
+ * to hold no duplicate would report a collapsing chart as sound. */
5857
+ rows: any[];
5858
+ /** Valid `sourceRef` values for this run. */
5859
+ availableSourceRefs: string[];
5860
+ renderCap?: number;
5861
+ }
5862
+ /**
5863
+ * Validate one component spec. Returns every finding; the caller decides
5864
+ * whether to reject (tool path) or log (fallback path).
5865
+ */
5866
+ declare function validateComponentSpec(spec: SpecToValidate, ctx: ValidationContext): ValidationFinding[];
5867
+ /** Render findings as the text tool-result the agent reads on a rejection. */
5868
+ declare function formatFindingsForAgent(findings: ValidationFinding[]): string;
5869
+
5682
5870
  type MessageTypeHandler = (message: IncomingMessage) => void | Promise<void>;
5683
5871
  declare class SuperatomSDK {
5684
5872
  private ws;
@@ -5705,6 +5893,8 @@ declare class SuperatomSDK {
5705
5893
  private modelStrategy;
5706
5894
  private mainAgentModel;
5707
5895
  private sourceAgentModel;
5896
+ private answerFlow;
5897
+ private answerProvider?;
5708
5898
  private dashCompModels?;
5709
5899
  private conversationSimilarityThreshold;
5710
5900
  private userManager;
@@ -5882,4 +6072,4 @@ declare class SuperatomSDK {
5882
6072
  getConversationSimilarityThreshold(): number;
5883
6073
  }
5884
6074
 
5885
- export { type AgentConfig, type AgentEvent, type AgentResponse, type AgentRunContext, type AgentRunHandlers, type AgentRunRecord, type AgentRunResult, type AgentTrigger, type AgentUsage, type ApplySummary, BM25L, type BM25LOptions, type BaseLLMConfig, type BuildTriggerInput, CONTEXT_CONFIG, type CapturedLog, CleanupService, type CodexSessionOptions, type CodingAgentCollectionConfig, type CodingAgentDefinition, type CodingAgentSession, type CodingAgentSessionOptions, type CodingAgentsConfig, type CollectionHandler, type CollectionOperation, type DBUIBlock, DEFAULT_AGENT_CONFIG, type DashboardAgentCollectionConfig, type DatabaseType, type Harness, type HybridSearchOptions, type IncomingMessage, type KbNodesQueryFilters, type KbNodesRequestPayload, LLM, type LLMUsageEntry, type LogLevel, MainAgent, type McpServerSpec, type Message, MissingRequestContextError, type ModelStrategy, type OutputContract, type OutputField, type OutputValidator, type Principal, type RequestContext, type RerankedResult, type RowFilter, type RunAgentOptions, STORAGE_CONFIG, type ScriptComponentSpec, ScriptMatcher, type ScriptParameter, type ScriptRecipe, type ScriptRecipeMetaRow, type ScriptRecipeStore, type ScriptResult, ScriptStore, type ScriptStoreOptions, type SelectedWorkflow, type SourcePolicy, SuperatomSDK, type SuperatomSDKConfig, type TaskType, Thread, ThreadManager, type Tool$1 as Tool, type ToolOutputSchema, type TriggerEvent, type TriggerFireInfo, UIBlock, UILogCollector, type User, UserManager, type UsersData, type WorkflowDescriptor, type Workspace, anthropicLLM, assertReadOnlySql, bindContext, captureContext, clearContextTokens, contextTokenCount, createCodexSession, createCodingAgentSession, dashboardConversationHistory, dataFingerprint, describeContext, describeTriggers, emitAgentEvent, extractNamedExport, geminiLLM, getCodingAgent, getCodingAgentsConfig, getRequestContext, groqLLM, hybridRerank, isUserContext, listCodingAgents, llmUsageLogger, logger, mintContextToken, normalizeScriptBody, onAgentRun, openaiLLM, policiesFromConfig, queryCache, registerCodingAgentCollection, registerCodingAgents, registerDashboardAgentCollection, requireRequestContext, rerankChromaResults, rerankConversationResults, resolveContextToken, resolveScriptRecipeStore, revokeContextToken, runAsSystem, runAsUser, runCodingAgent, runScript, runWithContext, runWithMessageIdentity, startAgentTriggers, stopAgentTriggers, userPromptErrorLogger, withCapturedContext, writeBridgeShims };
6075
+ export { ALL_COLUMN_KEYS, ANSWER_COMPONENT_NAMES, type AgentConfig, type AgentEvent, type AgentResponse, type AgentRunContext, type AgentRunHandlers, type AgentRunRecord, type AgentRunResult, type AgentTrigger, type AgentUsage, type AnswerProvider, type AnswerProviderContext, type ApplySummary, BM25L, type BM25LOptions, type BaseLLMConfig, type BuildTriggerInput, CATEGORY_KEYS, CONTEXT_CONFIG, type CapturedLog, CleanupService, type CodexSessionOptions, type CodingAgentCollectionConfig, type CodingAgentDefinition, type CodingAgentSession, type CodingAgentSessionOptions, type CodingAgentsConfig, type ColInfo, type ColType, type CollectionHandler, type CollectionOperation, type Component, type DBUIBlock, DEFAULT_AGENT_CONFIG, DEFAULT_FMT_CONFIG, type DashboardAgentCollectionConfig, type DatabaseType, type FindingCode, type Fmt, type FmtConfig, type Harness, type HybridSearchOptions, type IncomingMessage, type KbNodesQueryFilters, type KbNodesRequestPayload, LLM, type LLMUsageEntry, type LogLevel, MainAgent, type McpServerSpec, type Message, MissingRequestContextError, type ModelStrategy, NUMERIC_KEYS, type OutputContract, type OutputField, type OutputValidator, type Principal, type RequestContext, type RerankedResult, type RowFilter, type RunAgentOptions, STORAGE_CONFIG, type ScriptComponentSpec, ScriptMatcher, type ScriptParameter, type ScriptRecipe, type ScriptRecipeMetaRow, type ScriptRecipeStore, type ScriptResult, ScriptStore, type ScriptStoreOptions, type SelectedWorkflow, type SourcePolicy, type SpecToValidate, SuperatomSDK, type SuperatomSDKConfig, type T_RESPONSE, type TaskType, Thread, ThreadManager, type Tool$1 as Tool, type ToolOutputSchema, type TriggerEvent, type TriggerFireInfo, UIBlock, UILogCollector, type User, UserManager, type UsersData, type ValidationContext, type ValidationFinding, type WorkflowDescriptor, type Workspace, answerCatalogForBinding, answerComponents, anthropicLLM, assertReadOnlySql, bindContext, captureContext, clearContextTokens, contextTokenCount, createCodexSession, createCodingAgentSession, dashboardConversationHistory, dataFingerprint, describeContext, describeTriggers, emitAgentEvent, extractNamedExport, formatFindingsForAgent, geminiLLM, getCodingAgent, getCodingAgentsConfig, getRequestContext, groqLLM, hybridRerank, inferColumns, isUserContext, listCodingAgents, llmUsageLogger, logger, makeFmt, mintContextToken, normalizeScriptBody, onAgentRun, openaiLLM, policiesFromConfig, projectForDatasetBinding, queryCache, registerCodingAgentCollection, registerCodingAgents, registerDashboardAgentCollection, requireRequestContext, rerankChromaResults, rerankConversationResults, resolveContextToken, resolveScriptRecipeStore, revokeContextToken, runAsSystem, runAsUser, runCodingAgent, runScript, runWithContext, runWithMessageIdentity, startAgentTriggers, stopAgentTriggers, userPromptErrorLogger, validateComponentSpec, withCapturedContext, writeBridgeShims };
package/dist/index.js CHANGED
@@ -30,13 +30,18 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ ALL_COLUMN_KEYS: () => ALL_COLUMN_KEYS,
34
+ ANSWER_COMPONENT_NAMES: () => ANSWER_COMPONENT_NAMES,
33
35
  BM25L: () => BM25L,
36
+ CATEGORY_KEYS: () => CATEGORY_KEYS,
34
37
  CONTEXT_CONFIG: () => CONTEXT_CONFIG,
35
38
  CleanupService: () => CleanupService,
36
39
  DEFAULT_AGENT_CONFIG: () => DEFAULT_AGENT_CONFIG,
40
+ DEFAULT_FMT_CONFIG: () => DEFAULT_FMT_CONFIG,
37
41
  LLM: () => LLM,
38
42
  MainAgent: () => MainAgent,
39
43
  MissingRequestContextError: () => MissingRequestContextError,
44
+ NUMERIC_KEYS: () => NUMERIC_KEYS,
40
45
  STORAGE_CONFIG: () => STORAGE_CONFIG,
41
46
  ScriptMatcher: () => ScriptMatcher,
42
47
  ScriptStore: () => ScriptStore,
@@ -46,6 +51,8 @@ __export(index_exports, {
46
51
  UIBlock: () => UIBlock,
47
52
  UILogCollector: () => UILogCollector,
48
53
  UserManager: () => UserManager,
54
+ answerCatalogForBinding: () => answerCatalogForBinding,
55
+ answerComponents: () => answerComponents,
49
56
  anthropicLLM: () => anthropicLLM,
50
57
  assertReadOnlySql: () => assertReadOnlySql,
51
58
  bindContext: () => bindContext,
@@ -60,21 +67,25 @@ __export(index_exports, {
60
67
  describeTriggers: () => describeTriggers,
61
68
  emitAgentEvent: () => emitAgentEvent,
62
69
  extractNamedExport: () => extractNamedExport,
70
+ formatFindingsForAgent: () => formatFindingsForAgent,
63
71
  geminiLLM: () => geminiLLM,
64
72
  getCodingAgent: () => getCodingAgent,
65
73
  getCodingAgentsConfig: () => getCodingAgentsConfig,
66
74
  getRequestContext: () => getRequestContext,
67
75
  groqLLM: () => groqLLM,
68
76
  hybridRerank: () => hybridRerank,
77
+ inferColumns: () => inferColumns,
69
78
  isUserContext: () => isUserContext,
70
79
  listCodingAgents: () => listCodingAgents,
71
80
  llmUsageLogger: () => llmUsageLogger,
72
81
  logger: () => logger,
82
+ makeFmt: () => makeFmt,
73
83
  mintContextToken: () => mintContextToken,
74
84
  normalizeScriptBody: () => normalizeScriptBody,
75
85
  onAgentRun: () => onAgentRun,
76
86
  openaiLLM: () => openaiLLM,
77
87
  policiesFromConfig: () => policiesFromConfig,
88
+ projectForDatasetBinding: () => projectForDatasetBinding,
78
89
  queryCache: () => queryCache,
79
90
  registerCodingAgentCollection: () => registerCodingAgentCollection,
80
91
  registerCodingAgents: () => registerCodingAgents,
@@ -94,6 +105,7 @@ __export(index_exports, {
94
105
  startAgentTriggers: () => startAgentTriggers,
95
106
  stopAgentTriggers: () => stopAgentTriggers,
96
107
  userPromptErrorLogger: () => userPromptErrorLogger,
108
+ validateComponentSpec: () => validateComponentSpec,
97
109
  withCapturedContext: () => withCapturedContext,
98
110
  writeBridgeShims: () => writeBridgeShims
99
111
  });
@@ -15896,6 +15908,9 @@ function projectForDatasetBinding(components) {
15896
15908
  props: projectProps(c.props)
15897
15909
  }));
15898
15910
  }
15911
+ function answerCatalogForBinding(components) {
15912
+ return projectForDatasetBinding(answerComponents(components));
15913
+ }
15899
15914
 
15900
15915
  // src/userResponse/anthropic.ts
15901
15916
  var import_dotenv = __toESM(require("dotenv"));
@@ -19368,7 +19383,7 @@ function handleUserPromptAbort(data, sendMessage) {
19368
19383
  logger.warn(`[UserPromptAbort] Failed to send abort ack: ${err instanceof Error ? err.message : String(err)}`);
19369
19384
  }
19370
19385
  }
19371
- var get_user_request = async (data, components, sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, externalTools, mainAgentModel, sourceAgentModel, workflows) => {
19386
+ var get_user_request = async (data, components, sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, externalTools, mainAgentModel, sourceAgentModel, workflows, answerProvider) => {
19372
19387
  const errors = [];
19373
19388
  const parseResult = UserPromptRequestMessageSchema.safeParse(data);
19374
19389
  if (!parseResult.success) {
@@ -19482,7 +19497,18 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
19482
19497
  }
19483
19498
  let userResponse;
19484
19499
  try {
19485
- userResponse = await get_agent_user_response(
19500
+ userResponse = answerProvider ? await answerProvider({
19501
+ prompt,
19502
+ components,
19503
+ collections,
19504
+ externalTools,
19505
+ userId,
19506
+ threadId,
19507
+ userConfig,
19508
+ conversationHistory,
19509
+ onStream: streamCallback,
19510
+ signal: abortController.signal
19511
+ }) : await get_agent_user_response(
19486
19512
  prompt,
19487
19513
  components,
19488
19514
  anthropicApiKey,
@@ -19746,8 +19772,8 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
19746
19772
  wsId
19747
19773
  };
19748
19774
  };
19749
- async function handleUserPromptRequest(data, components, sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, externalTools, mainAgentModel, sourceAgentModel, workflows) {
19750
- const response = await runWithMessageIdentity(data, () => get_user_request(data, components, sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, externalTools, mainAgentModel, sourceAgentModel, workflows));
19775
+ async function handleUserPromptRequest(data, components, sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, externalTools, mainAgentModel, sourceAgentModel, workflows, answerProvider) {
19776
+ const response = await runWithMessageIdentity(data, () => get_user_request(data, components, sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, externalTools, mainAgentModel, sourceAgentModel, workflows, answerProvider));
19751
19777
  if (response.data?.component?.props?.config?.components) {
19752
19778
  response.data.component.props.config.components = response.data.component.props.config.components.map((comp) => ({
19753
19779
  ...comp,
@@ -24531,6 +24557,7 @@ async function runCodingAgent(agentId, options = {}) {
24531
24557
  signal: options.signal,
24532
24558
  onOutput: options.onOutput,
24533
24559
  onEvent: options.onEvent,
24560
+ onNarration: options.onNarration,
24534
24561
  onUsage: options.onUsage
24535
24562
  };
24536
24563
  const input = options.input ?? {};
@@ -24573,6 +24600,17 @@ async function runCodingAgent(agentId, options = {}) {
24573
24600
  {
24574
24601
  onOutput: ctx.onOutput,
24575
24602
  onEvent: ctx.onEvent,
24603
+ // Narration is user-facing, so drop anything that mentions the
24604
+ // workspace. The harness closes a turn with its own line about the
24605
+ // deliverable ("Completed and validated [out/answer.json](/abs/path…)"),
24606
+ // which is internal chatter AND leaks a server path to whoever asked
24607
+ // the question. The real answer reaches the caller through the
24608
+ // deliverable and `answer`, never through this stream, so nothing is
24609
+ // lost by suppressing it. onOutput still sees everything.
24610
+ onNarration: ctx.onNarration ? (text) => {
24611
+ if (text.includes(dir)) return;
24612
+ ctx.onNarration(text.endsWith("\n") ? text : text + "\n\n");
24613
+ } : void 0,
24576
24614
  onUsage: ctx.onUsage,
24577
24615
  // Opt-in only: see stopOnDeliverable. Letting the turn end naturally
24578
24616
  // is what makes usage reporting work at all.
@@ -24702,6 +24740,7 @@ function writeBridgeShims(ws, opts) {
24702
24740
  ${READ_ONLY_SQL_SOURCE}
24703
24741
  const BRIDGE = ${JSON.stringify(opts.bridgeUrl)};
24704
24742
  const MAX_ROWS = ${maxRows};
24743
+ const CONTEXT_TOKEN = ${JSON.stringify(opts.contextToken ?? null)};
24705
24744
 
24706
24745
  const [toolId, sql, limitArg] = process.argv.slice(2);
24707
24746
  if (!toolId || !sql) {
@@ -24712,7 +24751,12 @@ try { assertReadOnlySql(sql); } catch (e) { console.error(String(e.message || e)
24712
24751
 
24713
24752
  fetch(BRIDGE + '/query', {
24714
24753
  method: 'POST',
24715
- headers: { 'content-type': 'application/json' },
24754
+ headers: {
24755
+ 'content-type': 'application/json',
24756
+ // Carries WHO this query runs as. The bridge resolves it back to the
24757
+ // request context; absent, the data seam treats the query as anonymous.
24758
+ ...(CONTEXT_TOKEN ? { 'x-sa-context': CONTEXT_TOKEN } : {}),
24759
+ },
24716
24760
  body: JSON.stringify({ toolId, sql, limit: Math.min(Number(limitArg) || MAX_ROWS, MAX_ROWS) }),
24717
24761
  })
24718
24762
  .then(async (r) => {
@@ -26759,6 +26803,127 @@ var ReportManager = class {
26759
26803
  }
26760
26804
  };
26761
26805
 
26806
+ // src/userResponse/scripts/fmt.ts
26807
+ var DASH = "\u2014";
26808
+ var DEFAULT_FMT_CONFIG = { locale: "en-IN", currency: "INR" };
26809
+ var MONEY_TIERS = {
26810
+ "en-IN": [[1e7, "Cr"], [1e5, "L"]],
26811
+ "hi-IN": [[1e7, "Cr"], [1e5, "L"]]
26812
+ };
26813
+ var DEFAULT_MONEY_TIERS = [[1e9, "B"], [1e6, "M"]];
26814
+ function moneyTiers(locale) {
26815
+ return MONEY_TIERS[locale] ?? DEFAULT_MONEY_TIERS;
26816
+ }
26817
+ var COUNT_SCALE_MIN = 1e7;
26818
+ function toNum(v) {
26819
+ if (v === null || v === void 0 || v === "") return null;
26820
+ const n = typeof v === "number" ? v : Number(v);
26821
+ return Number.isFinite(n) ? n : null;
26822
+ }
26823
+ var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
26824
+ var ISO_DATE = /^\d{4}-\d{2}-\d{2}([T ]|$)/;
26825
+ function toDate(v) {
26826
+ if (v === null || v === void 0 || v === "") return null;
26827
+ if (v instanceof Date) return Number.isNaN(v.getTime()) ? null : v;
26828
+ if (typeof v === "number") {
26829
+ const d = new Date(v);
26830
+ return Number.isNaN(d.getTime()) ? null : d;
26831
+ }
26832
+ if (typeof v === "string" && ISO_DATE.test(v.trim())) {
26833
+ const d = new Date(v.trim());
26834
+ return Number.isNaN(d.getTime()) ? null : d;
26835
+ }
26836
+ return null;
26837
+ }
26838
+ function makeFmt(cfg = {}) {
26839
+ const locale = cfg.locale || DEFAULT_FMT_CONFIG.locale;
26840
+ const currency = cfg.currency || DEFAULT_FMT_CONFIG.currency;
26841
+ const group = (n, decimals = 0) => n.toLocaleString(locale, { minimumFractionDigits: decimals, maximumFractionDigits: decimals });
26842
+ const symbol = (() => {
26843
+ try {
26844
+ const parts = new Intl.NumberFormat(locale, { style: "currency", currency }).formatToParts(0);
26845
+ return parts.find((p) => p.type === "currency")?.value ?? "";
26846
+ } catch {
26847
+ return "";
26848
+ }
26849
+ })();
26850
+ const scaled = (abs, tiers, decimals) => {
26851
+ for (const [threshold, unit] of tiers) {
26852
+ if (abs >= threshold) return `${group(abs / threshold, decimals)} ${unit}`;
26853
+ }
26854
+ return null;
26855
+ };
26856
+ function money(v, decimals = 2) {
26857
+ const n = toNum(v);
26858
+ if (n === null) return DASH;
26859
+ const sign = n < 0 ? "-" : "";
26860
+ const abs = Math.abs(n);
26861
+ const tiers = moneyTiers(locale);
26862
+ for (let i = 0; i < tiers.length; i++) {
26863
+ const [threshold, unit] = tiers[i];
26864
+ if (abs < threshold) continue;
26865
+ const value = Number((abs / threshold).toFixed(decimals));
26866
+ const higher = tiers[i - 1];
26867
+ if (higher && value * threshold >= higher[0]) {
26868
+ return `${sign}${symbol}${group(abs / higher[0], decimals)} ${higher[1]}`;
26869
+ }
26870
+ return `${sign}${symbol}${group(abs / threshold, decimals)} ${unit}`;
26871
+ }
26872
+ try {
26873
+ return new Intl.NumberFormat(locale, {
26874
+ style: "currency",
26875
+ currency,
26876
+ minimumFractionDigits: Number.isInteger(n) ? 0 : decimals,
26877
+ maximumFractionDigits: decimals
26878
+ }).format(n);
26879
+ } catch {
26880
+ return `${sign}${symbol}${group(abs, Number.isInteger(abs) ? 0 : decimals)}`;
26881
+ }
26882
+ }
26883
+ function num(v, decimals) {
26884
+ const n = toNum(v);
26885
+ if (n === null) return DASH;
26886
+ return group(n, decimals ?? (Number.isInteger(n) ? 0 : 2));
26887
+ }
26888
+ function count(v, decimals = 2) {
26889
+ const n = toNum(v);
26890
+ if (n === null) return DASH;
26891
+ const abs = Math.abs(n);
26892
+ const s = abs >= COUNT_SCALE_MIN ? scaled(abs, moneyTiers(locale), decimals) : null;
26893
+ if (s) return `${n < 0 ? "-" : ""}${s}`;
26894
+ return group(n, Number.isInteger(n) ? 0 : decimals);
26895
+ }
26896
+ function pct(part, whole, decimals = 1) {
26897
+ const p = toNum(part), w = toNum(whole);
26898
+ if (p === null || w === null || w === 0) return DASH;
26899
+ return `${group(p / w * 100, decimals)}%`;
26900
+ }
26901
+ function delta(current, previous, decimals = 1) {
26902
+ const c = toNum(current), p = toNum(previous);
26903
+ if (c === null || p === null || p === 0) return DASH;
26904
+ const change = (c - p) / Math.abs(p) * 100;
26905
+ return `${change >= 0 ? "+" : "-"}${group(Math.abs(change), decimals)}%`;
26906
+ }
26907
+ function date(v) {
26908
+ const d = toDate(v);
26909
+ if (!d) return DASH;
26910
+ return `${d.getUTCDate()} ${MONTHS[d.getUTCMonth()]} ${d.getUTCFullYear()}`;
26911
+ }
26912
+ function range(from, to) {
26913
+ const a = toDate(from), b = toDate(to);
26914
+ if (!a || !b) return DASH;
26915
+ const left = a.getUTCFullYear() === b.getUTCFullYear() ? `${a.getUTCDate()} ${MONTHS[a.getUTCMonth()]}` : date(a);
26916
+ return `${left} \u2013 ${date(b)}`;
26917
+ }
26918
+ function list(items, conjunction = "and") {
26919
+ const parts = (items || []).map((i) => String(i ?? "").trim()).filter(Boolean);
26920
+ if (!parts.length) return DASH;
26921
+ if (parts.length === 1) return parts[0];
26922
+ return `${parts.slice(0, -1).join(", ")} ${conjunction} ${parts[parts.length - 1]}`;
26923
+ }
26924
+ return { money, num, count, pct, delta, date, range, list };
26925
+ }
26926
+
26762
26927
  // src/utils/log-collector.ts
26763
26928
  var LOG_LEVEL_PRIORITY2 = {
26764
26929
  errors: 0,
@@ -27986,6 +28151,13 @@ var SuperatomSDK = class {
27986
28151
  this.modelStrategy = config2.modelStrategy || "fast";
27987
28152
  this.mainAgentModel = config2.mainAgentModel || "anthropic/claude-sonnet-4-5-20250929";
27988
28153
  this.sourceAgentModel = config2.sourceAgentModel || "anthropic/claude-sonnet-4-5-20250929";
28154
+ this.answerProvider = config2.answerProvider;
28155
+ this.answerFlow = config2.answerFlow || "agents";
28156
+ if (this.answerFlow === "custom" && !this.answerProvider) {
28157
+ logger.warn('[SDK] answerFlow is "custom" but no answerProvider was given \u2014 using the built-in agent flow.');
28158
+ this.answerFlow = "agents";
28159
+ }
28160
+ logger.info(`[SDK] Answer flow: ${this.answerFlow}${this.answerFlow === "custom" ? " (answerProvider)" : " (MainAgent + SourceAgent)"}`);
27989
28161
  this.dashCompModels = config2.dashCompModels;
27990
28162
  this.conversationSimilarityThreshold = config2.conversationSimilarityThreshold ?? 0.8;
27991
28163
  this.applyModelStrategy(this.modelStrategy);
@@ -28145,7 +28317,22 @@ var SuperatomSDK = class {
28145
28317
  });
28146
28318
  break;
28147
28319
  case "USER_PROMPT_REQ":
28148
- handleUserPromptRequest(parsed, this.components, (msg) => this.send(msg), this.anthropicApiKey, this.groqApiKey, this.geminiApiKey, this.openaiApiKey, this.llmProviders, this.collections, this.tools, this.mainAgentModel, this.sourceAgentModel, this.workflows).catch((error) => {
28320
+ handleUserPromptRequest(
28321
+ parsed,
28322
+ this.components,
28323
+ (msg) => this.send(msg),
28324
+ this.anthropicApiKey,
28325
+ this.groqApiKey,
28326
+ this.geminiApiKey,
28327
+ this.openaiApiKey,
28328
+ this.llmProviders,
28329
+ this.collections,
28330
+ this.tools,
28331
+ this.mainAgentModel,
28332
+ this.sourceAgentModel,
28333
+ this.workflows,
28334
+ this.answerFlow === "custom" ? this.answerProvider : void 0
28335
+ ).catch((error) => {
28149
28336
  logger.error("Failed to handle user prompt request:", error);
28150
28337
  });
28151
28338
  break;
@@ -28554,13 +28741,18 @@ var SuperatomSDK = class {
28554
28741
  };
28555
28742
  // Annotate the CommonJS export names for ESM import in node:
28556
28743
  0 && (module.exports = {
28744
+ ALL_COLUMN_KEYS,
28745
+ ANSWER_COMPONENT_NAMES,
28557
28746
  BM25L,
28747
+ CATEGORY_KEYS,
28558
28748
  CONTEXT_CONFIG,
28559
28749
  CleanupService,
28560
28750
  DEFAULT_AGENT_CONFIG,
28751
+ DEFAULT_FMT_CONFIG,
28561
28752
  LLM,
28562
28753
  MainAgent,
28563
28754
  MissingRequestContextError,
28755
+ NUMERIC_KEYS,
28564
28756
  STORAGE_CONFIG,
28565
28757
  ScriptMatcher,
28566
28758
  ScriptStore,
@@ -28570,6 +28762,8 @@ var SuperatomSDK = class {
28570
28762
  UIBlock,
28571
28763
  UILogCollector,
28572
28764
  UserManager,
28765
+ answerCatalogForBinding,
28766
+ answerComponents,
28573
28767
  anthropicLLM,
28574
28768
  assertReadOnlySql,
28575
28769
  bindContext,
@@ -28584,21 +28778,25 @@ var SuperatomSDK = class {
28584
28778
  describeTriggers,
28585
28779
  emitAgentEvent,
28586
28780
  extractNamedExport,
28781
+ formatFindingsForAgent,
28587
28782
  geminiLLM,
28588
28783
  getCodingAgent,
28589
28784
  getCodingAgentsConfig,
28590
28785
  getRequestContext,
28591
28786
  groqLLM,
28592
28787
  hybridRerank,
28788
+ inferColumns,
28593
28789
  isUserContext,
28594
28790
  listCodingAgents,
28595
28791
  llmUsageLogger,
28596
28792
  logger,
28793
+ makeFmt,
28597
28794
  mintContextToken,
28598
28795
  normalizeScriptBody,
28599
28796
  onAgentRun,
28600
28797
  openaiLLM,
28601
28798
  policiesFromConfig,
28799
+ projectForDatasetBinding,
28602
28800
  queryCache,
28603
28801
  registerCodingAgentCollection,
28604
28802
  registerCodingAgents,
@@ -28618,6 +28816,7 @@ var SuperatomSDK = class {
28618
28816
  startAgentTriggers,
28619
28817
  stopAgentTriggers,
28620
28818
  userPromptErrorLogger,
28819
+ validateComponentSpec,
28621
28820
  withCapturedContext,
28622
28821
  writeBridgeShims
28623
28822
  });
package/dist/index.mjs CHANGED
@@ -15802,6 +15802,9 @@ function projectForDatasetBinding(components) {
15802
15802
  props: projectProps(c.props)
15803
15803
  }));
15804
15804
  }
15805
+ function answerCatalogForBinding(components) {
15806
+ return projectForDatasetBinding(answerComponents(components));
15807
+ }
15805
15808
 
15806
15809
  // src/userResponse/anthropic.ts
15807
15810
  import dotenv from "dotenv";
@@ -19274,7 +19277,7 @@ function handleUserPromptAbort(data, sendMessage) {
19274
19277
  logger.warn(`[UserPromptAbort] Failed to send abort ack: ${err instanceof Error ? err.message : String(err)}`);
19275
19278
  }
19276
19279
  }
19277
- var get_user_request = async (data, components, sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, externalTools, mainAgentModel, sourceAgentModel, workflows) => {
19280
+ var get_user_request = async (data, components, sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, externalTools, mainAgentModel, sourceAgentModel, workflows, answerProvider) => {
19278
19281
  const errors = [];
19279
19282
  const parseResult = UserPromptRequestMessageSchema.safeParse(data);
19280
19283
  if (!parseResult.success) {
@@ -19388,7 +19391,18 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
19388
19391
  }
19389
19392
  let userResponse;
19390
19393
  try {
19391
- userResponse = await get_agent_user_response(
19394
+ userResponse = answerProvider ? await answerProvider({
19395
+ prompt,
19396
+ components,
19397
+ collections,
19398
+ externalTools,
19399
+ userId,
19400
+ threadId,
19401
+ userConfig,
19402
+ conversationHistory,
19403
+ onStream: streamCallback,
19404
+ signal: abortController.signal
19405
+ }) : await get_agent_user_response(
19392
19406
  prompt,
19393
19407
  components,
19394
19408
  anthropicApiKey,
@@ -19652,8 +19666,8 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
19652
19666
  wsId
19653
19667
  };
19654
19668
  };
19655
- async function handleUserPromptRequest(data, components, sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, externalTools, mainAgentModel, sourceAgentModel, workflows) {
19656
- const response = await runWithMessageIdentity(data, () => get_user_request(data, components, sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, externalTools, mainAgentModel, sourceAgentModel, workflows));
19669
+ async function handleUserPromptRequest(data, components, sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, externalTools, mainAgentModel, sourceAgentModel, workflows, answerProvider) {
19670
+ const response = await runWithMessageIdentity(data, () => get_user_request(data, components, sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, externalTools, mainAgentModel, sourceAgentModel, workflows, answerProvider));
19657
19671
  if (response.data?.component?.props?.config?.components) {
19658
19672
  response.data.component.props.config.components = response.data.component.props.config.components.map((comp) => ({
19659
19673
  ...comp,
@@ -24437,6 +24451,7 @@ async function runCodingAgent(agentId, options = {}) {
24437
24451
  signal: options.signal,
24438
24452
  onOutput: options.onOutput,
24439
24453
  onEvent: options.onEvent,
24454
+ onNarration: options.onNarration,
24440
24455
  onUsage: options.onUsage
24441
24456
  };
24442
24457
  const input = options.input ?? {};
@@ -24479,6 +24494,17 @@ async function runCodingAgent(agentId, options = {}) {
24479
24494
  {
24480
24495
  onOutput: ctx.onOutput,
24481
24496
  onEvent: ctx.onEvent,
24497
+ // Narration is user-facing, so drop anything that mentions the
24498
+ // workspace. The harness closes a turn with its own line about the
24499
+ // deliverable ("Completed and validated [out/answer.json](/abs/path…)"),
24500
+ // which is internal chatter AND leaks a server path to whoever asked
24501
+ // the question. The real answer reaches the caller through the
24502
+ // deliverable and `answer`, never through this stream, so nothing is
24503
+ // lost by suppressing it. onOutput still sees everything.
24504
+ onNarration: ctx.onNarration ? (text) => {
24505
+ if (text.includes(dir)) return;
24506
+ ctx.onNarration(text.endsWith("\n") ? text : text + "\n\n");
24507
+ } : void 0,
24482
24508
  onUsage: ctx.onUsage,
24483
24509
  // Opt-in only: see stopOnDeliverable. Letting the turn end naturally
24484
24510
  // is what makes usage reporting work at all.
@@ -24608,6 +24634,7 @@ function writeBridgeShims(ws, opts) {
24608
24634
  ${READ_ONLY_SQL_SOURCE}
24609
24635
  const BRIDGE = ${JSON.stringify(opts.bridgeUrl)};
24610
24636
  const MAX_ROWS = ${maxRows};
24637
+ const CONTEXT_TOKEN = ${JSON.stringify(opts.contextToken ?? null)};
24611
24638
 
24612
24639
  const [toolId, sql, limitArg] = process.argv.slice(2);
24613
24640
  if (!toolId || !sql) {
@@ -24618,7 +24645,12 @@ try { assertReadOnlySql(sql); } catch (e) { console.error(String(e.message || e)
24618
24645
 
24619
24646
  fetch(BRIDGE + '/query', {
24620
24647
  method: 'POST',
24621
- headers: { 'content-type': 'application/json' },
24648
+ headers: {
24649
+ 'content-type': 'application/json',
24650
+ // Carries WHO this query runs as. The bridge resolves it back to the
24651
+ // request context; absent, the data seam treats the query as anonymous.
24652
+ ...(CONTEXT_TOKEN ? { 'x-sa-context': CONTEXT_TOKEN } : {}),
24653
+ },
24622
24654
  body: JSON.stringify({ toolId, sql, limit: Math.min(Number(limitArg) || MAX_ROWS, MAX_ROWS) }),
24623
24655
  })
24624
24656
  .then(async (r) => {
@@ -26665,6 +26697,127 @@ var ReportManager = class {
26665
26697
  }
26666
26698
  };
26667
26699
 
26700
+ // src/userResponse/scripts/fmt.ts
26701
+ var DASH = "\u2014";
26702
+ var DEFAULT_FMT_CONFIG = { locale: "en-IN", currency: "INR" };
26703
+ var MONEY_TIERS = {
26704
+ "en-IN": [[1e7, "Cr"], [1e5, "L"]],
26705
+ "hi-IN": [[1e7, "Cr"], [1e5, "L"]]
26706
+ };
26707
+ var DEFAULT_MONEY_TIERS = [[1e9, "B"], [1e6, "M"]];
26708
+ function moneyTiers(locale) {
26709
+ return MONEY_TIERS[locale] ?? DEFAULT_MONEY_TIERS;
26710
+ }
26711
+ var COUNT_SCALE_MIN = 1e7;
26712
+ function toNum(v) {
26713
+ if (v === null || v === void 0 || v === "") return null;
26714
+ const n = typeof v === "number" ? v : Number(v);
26715
+ return Number.isFinite(n) ? n : null;
26716
+ }
26717
+ var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
26718
+ var ISO_DATE = /^\d{4}-\d{2}-\d{2}([T ]|$)/;
26719
+ function toDate(v) {
26720
+ if (v === null || v === void 0 || v === "") return null;
26721
+ if (v instanceof Date) return Number.isNaN(v.getTime()) ? null : v;
26722
+ if (typeof v === "number") {
26723
+ const d = new Date(v);
26724
+ return Number.isNaN(d.getTime()) ? null : d;
26725
+ }
26726
+ if (typeof v === "string" && ISO_DATE.test(v.trim())) {
26727
+ const d = new Date(v.trim());
26728
+ return Number.isNaN(d.getTime()) ? null : d;
26729
+ }
26730
+ return null;
26731
+ }
26732
+ function makeFmt(cfg = {}) {
26733
+ const locale = cfg.locale || DEFAULT_FMT_CONFIG.locale;
26734
+ const currency = cfg.currency || DEFAULT_FMT_CONFIG.currency;
26735
+ const group = (n, decimals = 0) => n.toLocaleString(locale, { minimumFractionDigits: decimals, maximumFractionDigits: decimals });
26736
+ const symbol = (() => {
26737
+ try {
26738
+ const parts = new Intl.NumberFormat(locale, { style: "currency", currency }).formatToParts(0);
26739
+ return parts.find((p) => p.type === "currency")?.value ?? "";
26740
+ } catch {
26741
+ return "";
26742
+ }
26743
+ })();
26744
+ const scaled = (abs, tiers, decimals) => {
26745
+ for (const [threshold, unit] of tiers) {
26746
+ if (abs >= threshold) return `${group(abs / threshold, decimals)} ${unit}`;
26747
+ }
26748
+ return null;
26749
+ };
26750
+ function money(v, decimals = 2) {
26751
+ const n = toNum(v);
26752
+ if (n === null) return DASH;
26753
+ const sign = n < 0 ? "-" : "";
26754
+ const abs = Math.abs(n);
26755
+ const tiers = moneyTiers(locale);
26756
+ for (let i = 0; i < tiers.length; i++) {
26757
+ const [threshold, unit] = tiers[i];
26758
+ if (abs < threshold) continue;
26759
+ const value = Number((abs / threshold).toFixed(decimals));
26760
+ const higher = tiers[i - 1];
26761
+ if (higher && value * threshold >= higher[0]) {
26762
+ return `${sign}${symbol}${group(abs / higher[0], decimals)} ${higher[1]}`;
26763
+ }
26764
+ return `${sign}${symbol}${group(abs / threshold, decimals)} ${unit}`;
26765
+ }
26766
+ try {
26767
+ return new Intl.NumberFormat(locale, {
26768
+ style: "currency",
26769
+ currency,
26770
+ minimumFractionDigits: Number.isInteger(n) ? 0 : decimals,
26771
+ maximumFractionDigits: decimals
26772
+ }).format(n);
26773
+ } catch {
26774
+ return `${sign}${symbol}${group(abs, Number.isInteger(abs) ? 0 : decimals)}`;
26775
+ }
26776
+ }
26777
+ function num(v, decimals) {
26778
+ const n = toNum(v);
26779
+ if (n === null) return DASH;
26780
+ return group(n, decimals ?? (Number.isInteger(n) ? 0 : 2));
26781
+ }
26782
+ function count(v, decimals = 2) {
26783
+ const n = toNum(v);
26784
+ if (n === null) return DASH;
26785
+ const abs = Math.abs(n);
26786
+ const s = abs >= COUNT_SCALE_MIN ? scaled(abs, moneyTiers(locale), decimals) : null;
26787
+ if (s) return `${n < 0 ? "-" : ""}${s}`;
26788
+ return group(n, Number.isInteger(n) ? 0 : decimals);
26789
+ }
26790
+ function pct(part, whole, decimals = 1) {
26791
+ const p = toNum(part), w = toNum(whole);
26792
+ if (p === null || w === null || w === 0) return DASH;
26793
+ return `${group(p / w * 100, decimals)}%`;
26794
+ }
26795
+ function delta(current, previous, decimals = 1) {
26796
+ const c = toNum(current), p = toNum(previous);
26797
+ if (c === null || p === null || p === 0) return DASH;
26798
+ const change = (c - p) / Math.abs(p) * 100;
26799
+ return `${change >= 0 ? "+" : "-"}${group(Math.abs(change), decimals)}%`;
26800
+ }
26801
+ function date(v) {
26802
+ const d = toDate(v);
26803
+ if (!d) return DASH;
26804
+ return `${d.getUTCDate()} ${MONTHS[d.getUTCMonth()]} ${d.getUTCFullYear()}`;
26805
+ }
26806
+ function range(from, to) {
26807
+ const a = toDate(from), b = toDate(to);
26808
+ if (!a || !b) return DASH;
26809
+ const left = a.getUTCFullYear() === b.getUTCFullYear() ? `${a.getUTCDate()} ${MONTHS[a.getUTCMonth()]}` : date(a);
26810
+ return `${left} \u2013 ${date(b)}`;
26811
+ }
26812
+ function list(items, conjunction = "and") {
26813
+ const parts = (items || []).map((i) => String(i ?? "").trim()).filter(Boolean);
26814
+ if (!parts.length) return DASH;
26815
+ if (parts.length === 1) return parts[0];
26816
+ return `${parts.slice(0, -1).join(", ")} ${conjunction} ${parts[parts.length - 1]}`;
26817
+ }
26818
+ return { money, num, count, pct, delta, date, range, list };
26819
+ }
26820
+
26668
26821
  // src/utils/log-collector.ts
26669
26822
  var LOG_LEVEL_PRIORITY2 = {
26670
26823
  errors: 0,
@@ -27892,6 +28045,13 @@ var SuperatomSDK = class {
27892
28045
  this.modelStrategy = config2.modelStrategy || "fast";
27893
28046
  this.mainAgentModel = config2.mainAgentModel || "anthropic/claude-sonnet-4-5-20250929";
27894
28047
  this.sourceAgentModel = config2.sourceAgentModel || "anthropic/claude-sonnet-4-5-20250929";
28048
+ this.answerProvider = config2.answerProvider;
28049
+ this.answerFlow = config2.answerFlow || "agents";
28050
+ if (this.answerFlow === "custom" && !this.answerProvider) {
28051
+ logger.warn('[SDK] answerFlow is "custom" but no answerProvider was given \u2014 using the built-in agent flow.');
28052
+ this.answerFlow = "agents";
28053
+ }
28054
+ logger.info(`[SDK] Answer flow: ${this.answerFlow}${this.answerFlow === "custom" ? " (answerProvider)" : " (MainAgent + SourceAgent)"}`);
27895
28055
  this.dashCompModels = config2.dashCompModels;
27896
28056
  this.conversationSimilarityThreshold = config2.conversationSimilarityThreshold ?? 0.8;
27897
28057
  this.applyModelStrategy(this.modelStrategy);
@@ -28051,7 +28211,22 @@ var SuperatomSDK = class {
28051
28211
  });
28052
28212
  break;
28053
28213
  case "USER_PROMPT_REQ":
28054
- handleUserPromptRequest(parsed, this.components, (msg) => this.send(msg), this.anthropicApiKey, this.groqApiKey, this.geminiApiKey, this.openaiApiKey, this.llmProviders, this.collections, this.tools, this.mainAgentModel, this.sourceAgentModel, this.workflows).catch((error) => {
28214
+ handleUserPromptRequest(
28215
+ parsed,
28216
+ this.components,
28217
+ (msg) => this.send(msg),
28218
+ this.anthropicApiKey,
28219
+ this.groqApiKey,
28220
+ this.geminiApiKey,
28221
+ this.openaiApiKey,
28222
+ this.llmProviders,
28223
+ this.collections,
28224
+ this.tools,
28225
+ this.mainAgentModel,
28226
+ this.sourceAgentModel,
28227
+ this.workflows,
28228
+ this.answerFlow === "custom" ? this.answerProvider : void 0
28229
+ ).catch((error) => {
28055
28230
  logger.error("Failed to handle user prompt request:", error);
28056
28231
  });
28057
28232
  break;
@@ -28459,13 +28634,18 @@ var SuperatomSDK = class {
28459
28634
  }
28460
28635
  };
28461
28636
  export {
28637
+ ALL_COLUMN_KEYS,
28638
+ ANSWER_COMPONENT_NAMES,
28462
28639
  BM25L,
28640
+ CATEGORY_KEYS,
28463
28641
  CONTEXT_CONFIG,
28464
28642
  CleanupService,
28465
28643
  DEFAULT_AGENT_CONFIG,
28644
+ DEFAULT_FMT_CONFIG,
28466
28645
  LLM,
28467
28646
  MainAgent,
28468
28647
  MissingRequestContextError,
28648
+ NUMERIC_KEYS,
28469
28649
  STORAGE_CONFIG,
28470
28650
  ScriptMatcher,
28471
28651
  ScriptStore,
@@ -28475,6 +28655,8 @@ export {
28475
28655
  UIBlock,
28476
28656
  UILogCollector,
28477
28657
  UserManager,
28658
+ answerCatalogForBinding,
28659
+ answerComponents,
28478
28660
  anthropicLLM,
28479
28661
  assertReadOnlySql,
28480
28662
  bindContext,
@@ -28489,21 +28671,25 @@ export {
28489
28671
  describeTriggers,
28490
28672
  emitAgentEvent,
28491
28673
  extractNamedExport,
28674
+ formatFindingsForAgent,
28492
28675
  geminiLLM,
28493
28676
  getCodingAgent,
28494
28677
  getCodingAgentsConfig,
28495
28678
  getRequestContext,
28496
28679
  groqLLM,
28497
28680
  hybridRerank,
28681
+ inferColumns,
28498
28682
  isUserContext,
28499
28683
  listCodingAgents,
28500
28684
  llmUsageLogger,
28501
28685
  logger,
28686
+ makeFmt,
28502
28687
  mintContextToken,
28503
28688
  normalizeScriptBody,
28504
28689
  onAgentRun,
28505
28690
  openaiLLM,
28506
28691
  policiesFromConfig,
28692
+ projectForDatasetBinding,
28507
28693
  queryCache,
28508
28694
  registerCodingAgentCollection,
28509
28695
  registerCodingAgents,
@@ -28523,6 +28709,7 @@ export {
28523
28709
  startAgentTriggers,
28524
28710
  stopAgentTriggers,
28525
28711
  userPromptErrorLogger,
28712
+ validateComponentSpec,
28526
28713
  withCapturedContext,
28527
28714
  writeBridgeShims
28528
28715
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superatomai/sdk-node",
3
- "version": "0.0.58-dsp",
3
+ "version": "0.0.59-dsp",
4
4
  "description": "Node.js TypeScript SDK for Superatom",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",