@superatomai/sdk-node 0.0.6-s → 0.0.7-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 +386 -137
- package/dist/index.d.ts +386 -137
- package/dist/index.js +3536 -1838
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3530 -1837
- package/dist/index.mjs.map +1 -1
- package/dist/userResponse/scripts/script-bootstrap.js +89 -56
- package/dist/userResponse/scripts/script-bootstrap.js.map +1 -1
- package/dist/userResponse/scripts/script-bootstrap.mjs +89 -56
- package/dist/userResponse/scripts/script-bootstrap.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1406,6 +1406,10 @@ interface ExecutedToolInfo {
|
|
|
1406
1406
|
_recordsShown: number;
|
|
1407
1407
|
_metadata?: any;
|
|
1408
1408
|
_sampleData: any[];
|
|
1409
|
+
/** Bounded summary over the FULL fetched result (complete structure). */
|
|
1410
|
+
_summary?: any;
|
|
1411
|
+
/** Up to MAIN_AGENT_COMPLETE_ROWS rows — the complete result when small. */
|
|
1412
|
+
_mainAgentRows?: any[];
|
|
1409
1413
|
};
|
|
1410
1414
|
outputSchema?: any;
|
|
1411
1415
|
sourceSchema?: string;
|
|
@@ -1619,8 +1623,16 @@ interface AgentWrittenScript {
|
|
|
1619
1623
|
* Controls limits, models, and behavior.
|
|
1620
1624
|
*/
|
|
1621
1625
|
interface AgentConfig {
|
|
1622
|
-
/** Max rows
|
|
1626
|
+
/** Max rows shown to the UI preview / inlined per source (default: 10) */
|
|
1623
1627
|
maxRowsPerSource: number;
|
|
1628
|
+
/**
|
|
1629
|
+
* Max rows a source query may FETCH from the DB server-side (default: 2000).
|
|
1630
|
+
* Decoupled from what the main agent is shown: the full result is fetched and
|
|
1631
|
+
* summarized (bounded), but only a small/complete slice enters LLM context.
|
|
1632
|
+
* This lets small lookups (benchmark maps) arrive COMPLETE without letting
|
|
1633
|
+
* large results blow up context.
|
|
1634
|
+
*/
|
|
1635
|
+
maxRowsFetched: number;
|
|
1624
1636
|
/** Model for the main agent (routing + analysis in one LLM call) */
|
|
1625
1637
|
mainAgentModel: string;
|
|
1626
1638
|
/** Model for source agent query generation */
|
|
@@ -1674,8 +1686,18 @@ interface ScriptRecipe {
|
|
|
1674
1686
|
tables: string[];
|
|
1675
1687
|
/** Parameter definitions — what can vary */
|
|
1676
1688
|
parameters: ScriptParameter[];
|
|
1677
|
-
/** The script function body as a string */
|
|
1689
|
+
/** The script function body as a string. Loaded from disk (scripts-store/<fileBase>.ts). */
|
|
1678
1690
|
scriptBody: string;
|
|
1691
|
+
/**
|
|
1692
|
+
* On-disk filename stem for the body: scripts-store/<fileBase>.ts.
|
|
1693
|
+
* Editable in the IDE. Decided at authoring time (slug of `name`, with a
|
|
1694
|
+
* short id suffix on collision) and stable across promotion.
|
|
1695
|
+
*/
|
|
1696
|
+
fileBase?: string;
|
|
1697
|
+
/** sha256 of the on-disk body — lets the runtime detect manual edits. */
|
|
1698
|
+
bodyHash?: string;
|
|
1699
|
+
/** Project scope (single-VM deployments may leave this undefined). */
|
|
1700
|
+
projectId?: string;
|
|
1679
1701
|
/** Times this script was used successfully */
|
|
1680
1702
|
successCount: number;
|
|
1681
1703
|
/** Times this script failed */
|
|
@@ -1713,7 +1735,7 @@ interface ScriptRecipe {
|
|
|
1713
1735
|
/**
|
|
1714
1736
|
* Lifecycle stage of this recipe on disk.
|
|
1715
1737
|
* - 'draft': written by MainAgent's write_script during a turn; filtered out
|
|
1716
|
-
* of
|
|
1738
|
+
* of FTS results (status='verified' only) so the matcher never picks it.
|
|
1717
1739
|
* Filename is suffixed with `turnId` to keep concurrent turns
|
|
1718
1740
|
* from clobbering each other's drafts.
|
|
1719
1741
|
* - 'verified': promoted after `execute_script` succeeded; the matcher sees it.
|
|
@@ -1763,34 +1785,219 @@ interface ScriptParameter {
|
|
|
1763
1785
|
interface ScriptComponentSpec {
|
|
1764
1786
|
/** Registered component name (e.g. "DynamicBarChart") — matched against the available component library. */
|
|
1765
1787
|
componentType: string;
|
|
1766
|
-
/** `executedQuery.sourceId` to bind to (e.g. a tool id or 'computed:_final'),
|
|
1788
|
+
/** `executedQuery.sourceId` to bind to (e.g. a tool id or 'computed:_final'), 'federation' for a cross-source component, or 'markdown' for a content-only narrative block (no data source). */
|
|
1767
1789
|
sourceRef: string;
|
|
1768
1790
|
/** Present only when sourceRef === 'federation' — the DuckDB SQL to re-execute on replay. */
|
|
1769
1791
|
federationSql?: string;
|
|
1792
|
+
/** Present only when sourceRef === 'markdown' — the narrative text to render on replay (markdown has no data source, so its content must be persisted). */
|
|
1793
|
+
content?: string;
|
|
1770
1794
|
title?: string;
|
|
1771
1795
|
description?: string;
|
|
1772
1796
|
/** Validated axis/value keys + aggregation — all referencing real columns of the bound source. */
|
|
1773
1797
|
config: Record<string, any>;
|
|
1774
1798
|
}
|
|
1799
|
+
/**
|
|
1800
|
+
* Result from executing a script via ScriptRunner.
|
|
1801
|
+
*/
|
|
1802
|
+
interface ScriptResult {
|
|
1803
|
+
/** Whether the script executed successfully */
|
|
1804
|
+
success: boolean;
|
|
1805
|
+
/** Combined data from all queries */
|
|
1806
|
+
data: any[];
|
|
1807
|
+
/** Individual query results tracked during execution */
|
|
1808
|
+
executedQueries: ScriptQueryResult[];
|
|
1809
|
+
/** Error message if failed */
|
|
1810
|
+
error?: string;
|
|
1811
|
+
/**
|
|
1812
|
+
* Where in the lifecycle the error occurred. Lets MainAgent's fix-loop
|
|
1813
|
+
* decide between "rewrite the whole draft" (compile) and "patch the
|
|
1814
|
+
* specific line" (runtime).
|
|
1815
|
+
*/
|
|
1816
|
+
errorPhase?: 'compile' | 'runtime' | 'timeout' | 'ipc';
|
|
1817
|
+
/** Total execution time in milliseconds */
|
|
1818
|
+
executionTimeMs: number;
|
|
1819
|
+
}
|
|
1820
|
+
/**
|
|
1821
|
+
* A single query executed during script runtime.
|
|
1822
|
+
* Tracked by ScriptContext for component generation and debugging.
|
|
1823
|
+
*/
|
|
1824
|
+
interface ScriptQueryResult {
|
|
1825
|
+
/** Source tool ID */
|
|
1826
|
+
sourceId: string;
|
|
1827
|
+
/** Human-readable source name */
|
|
1828
|
+
sourceName: string;
|
|
1829
|
+
/** The SQL that was executed */
|
|
1830
|
+
sql: string;
|
|
1831
|
+
/** Result data rows */
|
|
1832
|
+
data: any[];
|
|
1833
|
+
/** Number of rows returned */
|
|
1834
|
+
count: number;
|
|
1835
|
+
/** Total rows that matched before limit (if available) */
|
|
1836
|
+
totalCount?: number;
|
|
1837
|
+
/** Query execution time in milliseconds */
|
|
1838
|
+
executionTimeMs: number;
|
|
1839
|
+
/**
|
|
1840
|
+
* True for rows that did NOT come from a real SQL execution — either a
|
|
1841
|
+
* ctx.emit() dataset or the synthesized "computed:_final" entry that
|
|
1842
|
+
* carries the script's post-JS returned data. The component generator
|
|
1843
|
+
* uses this to route the resulting component through the script_dataset
|
|
1844
|
+
* sentinel toolId so the frontend resolves it via the queryCache short-circuit.
|
|
1845
|
+
*/
|
|
1846
|
+
virtual?: boolean;
|
|
1847
|
+
}
|
|
1848
|
+
/**
|
|
1849
|
+
* Match tier returned by the LLM script matcher.
|
|
1850
|
+
*
|
|
1851
|
+
* - 'high': the script answers the question directly; only parameter values
|
|
1852
|
+
* may differ. The runtime replays it with extracted params (cheapest path).
|
|
1853
|
+
* - 'near': the script answers a STRUCTURALLY similar question but needs
|
|
1854
|
+
* body modification (different metric, dimension, table, filter shape).
|
|
1855
|
+
* The runtime forks the parent and adapts the body via MainAgent's normal
|
|
1856
|
+
* write_script + execute_script loop — no SourceAgent dispatch needed.
|
|
1857
|
+
* See backend/docs/SCRIPT-FLOW-FORK-ADAPT.md for the full design.
|
|
1858
|
+
* - 'none': no script is relevant; full agent flow runs.
|
|
1859
|
+
*/
|
|
1860
|
+
type MatchTier = 'high' | 'near' | 'none';
|
|
1861
|
+
/**
|
|
1862
|
+
* Result from the LLM-based script matcher.
|
|
1863
|
+
*
|
|
1864
|
+
* For `tier: 'high'`, `extractedParams` carries the values to pass to the
|
|
1865
|
+
* existing script. For `tier: 'near'`, `gaps` and `modificationHint` describe
|
|
1866
|
+
* what the fork-author needs to change in the parent body.
|
|
1867
|
+
*/
|
|
1868
|
+
interface ScriptMatch {
|
|
1869
|
+
/** The matched script recipe */
|
|
1870
|
+
recipe: ScriptRecipe;
|
|
1871
|
+
/** Match tier — see MatchTier docs */
|
|
1872
|
+
tier: MatchTier;
|
|
1873
|
+
/** Similarity score (0-1, derived from LLM tier) */
|
|
1874
|
+
similarity: number;
|
|
1875
|
+
/**
|
|
1876
|
+
* Legacy confidence level. Mirrors `tier === 'high'`/`'near'` for now;
|
|
1877
|
+
* kept so existing callers compile while we migrate to tier-based logic.
|
|
1878
|
+
*/
|
|
1879
|
+
confidence: 'high' | 'medium';
|
|
1880
|
+
/** Parameters extracted from the user question by the LLM (tier='high') */
|
|
1881
|
+
extractedParams?: Record<string, any>;
|
|
1882
|
+
/** What the user question needs that the parent doesn't cover (tier='near') */
|
|
1883
|
+
gaps?: string[];
|
|
1884
|
+
/** One-sentence description of the change the fork-author should make (tier='near') */
|
|
1885
|
+
modificationHint?: string;
|
|
1886
|
+
/** Why the matcher made this choice (for logs and telemetry) */
|
|
1887
|
+
reasoning?: string;
|
|
1888
|
+
}
|
|
1775
1889
|
|
|
1776
1890
|
/**
|
|
1777
|
-
*
|
|
1891
|
+
* ScriptRecipeStore — injected metadata backend for the script flow.
|
|
1778
1892
|
*
|
|
1779
|
-
*
|
|
1780
|
-
*
|
|
1781
|
-
*
|
|
1782
|
-
*
|
|
1893
|
+
* The SDK is standalone (no DB dependency). The backend implements this
|
|
1894
|
+
* interface over Postgres (full-text search + atomic counters) and injects it
|
|
1895
|
+
* via `collections['script-recipes']`, exactly like `collections['source-embeddings']`.
|
|
1896
|
+
* `ScriptStore` consumes it for all METADATA operations while keeping the
|
|
1897
|
+
* executable body on disk as scripts-store/<fileBase>.ts.
|
|
1783
1898
|
*
|
|
1784
|
-
*
|
|
1785
|
-
*
|
|
1786
|
-
* for backwards compatibility and auto-migrated to the split format on next save.
|
|
1899
|
+
* All metadata rows are plain JSON (no scriptBody — that lives on disk).
|
|
1900
|
+
* See backend/docs/SCRIPT-FLOW-SCALING-ISSUES.md (#1, #3, #7).
|
|
1787
1901
|
*/
|
|
1788
1902
|
|
|
1903
|
+
/** One recipe's metadata as stored in Postgres (mirrors the script_recipes table). */
|
|
1904
|
+
interface ScriptRecipeMetaRow {
|
|
1905
|
+
id: string;
|
|
1906
|
+
projectId?: string | null;
|
|
1907
|
+
version: number;
|
|
1908
|
+
name: string;
|
|
1909
|
+
intentDescription: string;
|
|
1910
|
+
tags: string[] | null;
|
|
1911
|
+
createdFrom: string | null;
|
|
1912
|
+
sourceIds: string[] | null;
|
|
1913
|
+
tables: string[] | null;
|
|
1914
|
+
parameters: ScriptParameter[] | null;
|
|
1915
|
+
components?: ScriptComponentSpec[] | null;
|
|
1916
|
+
fileBase: string;
|
|
1917
|
+
bodyHash?: string | null;
|
|
1918
|
+
successCount: number;
|
|
1919
|
+
failureCount: number;
|
|
1920
|
+
lastUsed: string | null;
|
|
1921
|
+
parentId?: string | null;
|
|
1922
|
+
forkDepth?: number | null;
|
|
1923
|
+
forkReason?: string | null;
|
|
1924
|
+
status: 'draft' | 'verified' | string;
|
|
1925
|
+
turnId?: string | null;
|
|
1926
|
+
lastError?: {
|
|
1927
|
+
phase: 'compile' | 'runtime' | 'timeout' | 'ipc';
|
|
1928
|
+
message: string;
|
|
1929
|
+
at: string;
|
|
1930
|
+
attempt: number;
|
|
1931
|
+
} | null;
|
|
1932
|
+
createdAt?: string | null;
|
|
1933
|
+
updatedAt?: string | null;
|
|
1934
|
+
}
|
|
1935
|
+
interface ScriptRecipeStore {
|
|
1936
|
+
/** FTS shortlist of healthy verified recipes for the matcher (metadata only). */
|
|
1937
|
+
search(params: {
|
|
1938
|
+
prompt: string;
|
|
1939
|
+
projectId?: string;
|
|
1940
|
+
limit?: number;
|
|
1941
|
+
}): Promise<ScriptRecipeMetaRow[]>;
|
|
1942
|
+
/** Fetch one recipe by id (any status). */
|
|
1943
|
+
getById(id: string): Promise<ScriptRecipeMetaRow | null>;
|
|
1944
|
+
/** Count healthy verified recipes (drives the "any scripts?" gate). */
|
|
1945
|
+
count(params?: {
|
|
1946
|
+
projectId?: string;
|
|
1947
|
+
}): Promise<number>;
|
|
1948
|
+
/** Insert or update a recipe row (keyed by id). */
|
|
1949
|
+
upsert(row: ScriptRecipeMetaRow): Promise<void>;
|
|
1950
|
+
/** Atomically bump counters / last-used. */
|
|
1951
|
+
updateStats(id: string, patch: {
|
|
1952
|
+
successDelta?: number;
|
|
1953
|
+
failureDelta?: number;
|
|
1954
|
+
lastUsed?: string;
|
|
1955
|
+
}): Promise<void>;
|
|
1956
|
+
/** Flip a draft to verified, applying provenance + optional fork lineage. */
|
|
1957
|
+
promote(id: string, patch: {
|
|
1958
|
+
sourceIds: string[];
|
|
1959
|
+
tables: string[];
|
|
1960
|
+
fileBase?: string;
|
|
1961
|
+
parentId?: string;
|
|
1962
|
+
forkDepth?: number;
|
|
1963
|
+
forkReason?: string;
|
|
1964
|
+
components?: ScriptComponentSpec[];
|
|
1965
|
+
}): Promise<ScriptRecipeMetaRow | null>;
|
|
1966
|
+
/** Stamp a draft's last execution error. */
|
|
1967
|
+
recordDraftError(id: string, err: {
|
|
1968
|
+
phase: string;
|
|
1969
|
+
message: string;
|
|
1970
|
+
attempt: number;
|
|
1971
|
+
at: string;
|
|
1972
|
+
}): Promise<void>;
|
|
1973
|
+
/** Delete a recipe row (body file removed separately). */
|
|
1974
|
+
remove(id: string): Promise<void>;
|
|
1975
|
+
/** True if `fileBase` is taken by a different recipe in this project. */
|
|
1976
|
+
fileBaseTaken(fileBase: string, excludeId: string, projectId?: string): Promise<boolean>;
|
|
1977
|
+
}
|
|
1978
|
+
/** Pull the injected store off the collections bag (or null if not wired). */
|
|
1979
|
+
declare function resolveScriptRecipeStore(collections: any): ScriptRecipeStore | null;
|
|
1980
|
+
|
|
1789
1981
|
/**
|
|
1790
|
-
*
|
|
1791
|
-
*
|
|
1792
|
-
*
|
|
1982
|
+
* ScriptStore — Postgres metadata + on-disk body for script recipes.
|
|
1983
|
+
*
|
|
1984
|
+
* Split of responsibilities:
|
|
1985
|
+
* - METADATA → injected `ScriptRecipeStore` (Postgres FTS + atomic counters),
|
|
1986
|
+
* resolved from `collections['script-recipes']`.
|
|
1987
|
+
* - BODY → scripts-store/<fileBase>.ts, editable in your IDE. Written
|
|
1988
|
+
* atomically (temp + rename); `bodyHash` (sha256) detects edits.
|
|
1989
|
+
*
|
|
1990
|
+
* The old "read every file every turn + send the whole catalog to the LLM"
|
|
1991
|
+
* matcher is gone — matching is `store.search(prompt)` (FTS shortlist). The
|
|
1992
|
+
* draft/verified filename dance is gone too: `status` is a DB column and the
|
|
1993
|
+
* file keeps a stable `<fileBase>.ts` name across promotion.
|
|
1994
|
+
*
|
|
1995
|
+
* When no metadata store is injected, the store degrades to a safe no-op
|
|
1996
|
+
* (count 0 → script flow disabled) instead of crashing.
|
|
1997
|
+
*
|
|
1998
|
+
* See backend/docs/SCRIPT-FLOW-SCALING-ISSUES.md.
|
|
1793
1999
|
*/
|
|
2000
|
+
|
|
1794
2001
|
interface SaveDraftInput {
|
|
1795
2002
|
/** Reuse an existing draft (retry); omit to mint a new one. */
|
|
1796
2003
|
recipeId?: string;
|
|
@@ -1803,142 +2010,92 @@ interface SaveDraftInput {
|
|
|
1803
2010
|
scriptBody: string;
|
|
1804
2011
|
createdFrom: string;
|
|
1805
2012
|
}
|
|
1806
|
-
/**
|
|
1807
|
-
* Lineage + provenance fields applied when a draft is promoted to verified.
|
|
1808
|
-
* MainAgent gathers `sourceIds` and `tables` from the verified execution; the
|
|
1809
|
-
* caller (agent-user-response.ts) supplies the optional fork lineage.
|
|
1810
|
-
*/
|
|
1811
2013
|
interface PromoteToVerifiedInput {
|
|
1812
2014
|
sourceIds: string[];
|
|
1813
2015
|
tables: string[];
|
|
1814
2016
|
parentId?: string;
|
|
1815
2017
|
forkDepth?: number;
|
|
1816
2018
|
forkReason?: string;
|
|
1817
|
-
/** Validated component specs to persist on the recipe (component recipe). */
|
|
1818
2019
|
components?: ScriptComponentSpec[];
|
|
1819
2020
|
}
|
|
2021
|
+
interface ScriptStoreOptions {
|
|
2022
|
+
/** Explicit metadata store, or resolved from `collections['script-recipes']`. */
|
|
2023
|
+
store?: ScriptRecipeStore | null;
|
|
2024
|
+
collections?: any;
|
|
2025
|
+
/** Body directory (defaults to <cwd>/scripts-store). */
|
|
2026
|
+
baseDir?: string;
|
|
2027
|
+
/** Project scope stamped on every row. */
|
|
2028
|
+
projectId?: string;
|
|
2029
|
+
}
|
|
2030
|
+
/**
|
|
2031
|
+
* Normalize a scriptBody into the on-disk form (strip a leading comment block,
|
|
2032
|
+
* ensure `export async function getData`). Exported for MainAgent.
|
|
2033
|
+
*/
|
|
2034
|
+
declare function normalizeScriptBody(scriptBody: string): string;
|
|
1820
2035
|
declare class ScriptStore {
|
|
1821
|
-
private
|
|
2036
|
+
private store;
|
|
1822
2037
|
private storeDir;
|
|
1823
|
-
private
|
|
1824
|
-
constructor(
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
/**
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
*
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
/**
|
|
1847
|
-
* Get a recipe by ID — returns drafts as well as verified scripts.
|
|
1848
|
-
* Used by MainAgent and the promotion path.
|
|
1849
|
-
*/
|
|
1850
|
-
get(id: string): ScriptRecipe | null;
|
|
1851
|
-
/**
|
|
1852
|
-
* Number of verified recipes (matches `getAll().length`).
|
|
1853
|
-
*/
|
|
1854
|
-
count(): number;
|
|
1855
|
-
/**
|
|
1856
|
-
* Save a recipe (create or update).
|
|
1857
|
-
* File is named after the script: "order-status-distribution.json"
|
|
1858
|
-
*/
|
|
1859
|
-
save(recipe: ScriptRecipe): void;
|
|
1860
|
-
/**
|
|
1861
|
-
* Persist (or update) a draft recipe to disk. Always writes immediately so
|
|
1862
|
-
* the `.ts` body is visible in the IDE the moment MainAgent calls
|
|
1863
|
-
* `write_script`. Within one turn, retries that pass the same `recipeId`
|
|
1864
|
-
* overwrite the same files (the LLM rewriting itself); a fresh `recipeId`
|
|
1865
|
-
* is minted only on the first call of the turn.
|
|
1866
|
-
*
|
|
1867
|
-
* Filename includes the `turnId` suffix so concurrent turns never collide.
|
|
1868
|
-
*/
|
|
1869
|
-
saveDraft(input: SaveDraftInput): ScriptRecipe;
|
|
1870
|
-
/**
|
|
1871
|
-
* Stamp the draft with the most recent execution failure so it is visible
|
|
1872
|
-
* in the metadata JSON without grepping logs. No-op if the recipe doesn't
|
|
1873
|
-
* exist or has already been promoted.
|
|
1874
|
-
*/
|
|
2038
|
+
private projectId?;
|
|
2039
|
+
constructor(opts?: ScriptStoreOptions);
|
|
2040
|
+
/** Whether a metadata store is wired (matcher / authoring are gated on this). */
|
|
2041
|
+
hasStore(): boolean;
|
|
2042
|
+
/** Number of healthy verified recipes (gates the script-matching path). */
|
|
2043
|
+
count(): Promise<number>;
|
|
2044
|
+
/**
|
|
2045
|
+
* FTS shortlist for the matcher (metadata only — bodies are loaded lazily by
|
|
2046
|
+
* `get()` once the LLM picks one). Returns verified, healthy recipes ranked
|
|
2047
|
+
* by relevance.
|
|
2048
|
+
*/
|
|
2049
|
+
search(prompt: string, limit?: number): Promise<ScriptRecipe[]>;
|
|
2050
|
+
/** Fetch one recipe by id with its body loaded from disk. */
|
|
2051
|
+
get(id: string): Promise<ScriptRecipe | null>;
|
|
2052
|
+
/** Create or update a recipe (metadata upsert + body write when changed). */
|
|
2053
|
+
save(recipe: ScriptRecipe): Promise<void>;
|
|
2054
|
+
/**
|
|
2055
|
+
* Persist (or update) a draft. Within a turn, retries that pass the same
|
|
2056
|
+
* `recipeId` overwrite the same row + file; a fresh `recipeId` mints a new
|
|
2057
|
+
* draft. The body is visible at scripts-store/<fileBase>.ts immediately.
|
|
2058
|
+
*/
|
|
2059
|
+
saveDraft(input: SaveDraftInput): Promise<ScriptRecipe>;
|
|
2060
|
+
/** Stamp a draft's last execution error (metadata only). */
|
|
1875
2061
|
recordDraftError(recipeId: string, err: {
|
|
1876
2062
|
phase: 'compile' | 'runtime' | 'timeout' | 'ipc';
|
|
1877
2063
|
message: string;
|
|
1878
2064
|
attempt: number;
|
|
1879
|
-
}): void
|
|
2065
|
+
}): Promise<void>;
|
|
1880
2066
|
/**
|
|
1881
2067
|
* Promote a successfully-executed draft into a verified script.
|
|
1882
|
-
*
|
|
1883
|
-
*
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
*
|
|
1888
|
-
*
|
|
1889
|
-
*
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
/**
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
*/
|
|
1914
|
-
getFailureRate(id: string): number;
|
|
1915
|
-
private ensureLoaded;
|
|
1916
|
-
/**
|
|
1917
|
-
* Convert a script name to a safe filename.
|
|
1918
|
-
* "Order Status Distribution" → "order-status-distribution"
|
|
1919
|
-
*/
|
|
1920
|
-
private toFileName;
|
|
1921
|
-
/**
|
|
1922
|
-
* Load all script files from disk.
|
|
1923
|
-
*
|
|
1924
|
-
* Supports two layouts:
|
|
1925
|
-
* - New (preferred): metadata/<name>.json + <name>.ts
|
|
1926
|
-
* - Legacy: <name>.json with embedded scriptBody (auto-migrated on next save)
|
|
1927
|
-
*/
|
|
1928
|
-
private loadAllFromDisk;
|
|
1929
|
-
/**
|
|
1930
|
-
* Save a recipe to disk in split format:
|
|
1931
|
-
* metadata/<name>.json (metadata, no scriptBody)
|
|
1932
|
-
* <name>.ts (just the function body)
|
|
1933
|
-
*
|
|
1934
|
-
* If a legacy top-level <name>.json exists for the same recipe, remove it
|
|
1935
|
-
* so we don't end up with duplicate sources of truth.
|
|
1936
|
-
*/
|
|
1937
|
-
private saveRecipeToDisk;
|
|
1938
|
-
/**
|
|
1939
|
-
* Delete a recipe's files from disk (both metadata + body, plus any legacy file).
|
|
1940
|
-
*/
|
|
1941
|
-
private deleteRecipeFromDisk;
|
|
2068
|
+
* The on-disk body already exists at <fileBase>.ts (written at write_script
|
|
2069
|
+
* time) and keeps its name — only the DB row flips status + provenance.
|
|
2070
|
+
*/
|
|
2071
|
+
promoteToVerified(recipeId: string, input: PromoteToVerifiedInput): Promise<ScriptRecipe | null>;
|
|
2072
|
+
/**
|
|
2073
|
+
* Drop a draft (row + body file). MainAgent calls this at end-of-turn when a
|
|
2074
|
+
* draft was authored but never verified — failed drafts are never matched, so
|
|
2075
|
+
* deleting them immediately avoids unbounded accumulation (#5). No-op if the
|
|
2076
|
+
* recipe isn't a draft (so a promoted/verified script is never removed here).
|
|
2077
|
+
*/
|
|
2078
|
+
discardDraft(recipeId: string): Promise<void>;
|
|
2079
|
+
/** Delete a recipe (row + body file). */
|
|
2080
|
+
delete(id: string): Promise<void>;
|
|
2081
|
+
/** Record a successful execution (atomic counter bump). */
|
|
2082
|
+
recordSuccess(id: string): Promise<void>;
|
|
2083
|
+
/** Record a failed execution (atomic counter bump). */
|
|
2084
|
+
recordFailure(id: string): Promise<void>;
|
|
2085
|
+
/** Absolute path to the .ts body for a recipe (used by the runner/MainAgent). */
|
|
2086
|
+
getScriptPath(recipe: ScriptRecipe): string;
|
|
2087
|
+
private removeById;
|
|
2088
|
+
private rowToRecipe;
|
|
2089
|
+
private recipeToRow;
|
|
2090
|
+
/** slug of name, with a short id suffix when the bare slug is already taken. */
|
|
2091
|
+
private computeFileBase;
|
|
2092
|
+
private toSlug;
|
|
2093
|
+
private hash;
|
|
2094
|
+
private bodyPath;
|
|
2095
|
+
private readBody;
|
|
2096
|
+
/** Atomic body write (temp + rename) so concurrent reads never see a partial file. */
|
|
2097
|
+
private writeBody;
|
|
2098
|
+
private unlinkBody;
|
|
1942
2099
|
}
|
|
1943
2100
|
|
|
1944
2101
|
/**
|
|
@@ -1972,7 +2129,16 @@ declare class MainAgent {
|
|
|
1972
2129
|
private turnId;
|
|
1973
2130
|
private createdFromPrompt;
|
|
1974
2131
|
private scriptState;
|
|
1975
|
-
|
|
2132
|
+
/**
|
|
2133
|
+
* Fork mode — set when this turn is adapting a near-matching parent script.
|
|
2134
|
+
* In fork mode there is no legitimate "answer with bare text" outcome: the
|
|
2135
|
+
* only correct first move is a tool call (write_script, or a source tool for
|
|
2136
|
+
* schema discovery). We therefore force tool use on the first LLM iteration
|
|
2137
|
+
* so the model can't end its turn with a bare "I'll adapt…" preamble and zero
|
|
2138
|
+
* tool calls. Never set on the fresh-authoring / general-question path.
|
|
2139
|
+
*/
|
|
2140
|
+
private forkMode;
|
|
2141
|
+
constructor(externalTools: ExternalTool[], config: AgentConfig, scriptStore?: ScriptStore, turnId?: string, streamBuffer?: StreamBuffer, workflows?: WorkflowDescriptor[], forkMode?: boolean);
|
|
1976
2142
|
private get scriptingEnabled();
|
|
1977
2143
|
/**
|
|
1978
2144
|
* Handle a user question using the multi-agent system.
|
|
@@ -2069,7 +2235,22 @@ interface LLMOptions {
|
|
|
2069
2235
|
temperature?: number;
|
|
2070
2236
|
topP?: number;
|
|
2071
2237
|
apiKey?: string;
|
|
2238
|
+
baseURL?: string;
|
|
2072
2239
|
partial?: (chunk: string) => void;
|
|
2240
|
+
/**
|
|
2241
|
+
* Forces a tool call on the FIRST iteration of streamWithTools only
|
|
2242
|
+
* (subsequent iterations revert to auto). Used by fork mode to stop the
|
|
2243
|
+
* model from ending its turn with a bare "I'll adapt the script…" preamble
|
|
2244
|
+
* and zero tool calls. `{ type: 'any' }` lets the model pick which tool
|
|
2245
|
+
* (write_script in the common case, a source tool for schema discovery);
|
|
2246
|
+
* `{ type: 'tool', name }` pins a specific tool. Anthropic only.
|
|
2247
|
+
*/
|
|
2248
|
+
firstIterationToolChoice?: {
|
|
2249
|
+
type: 'any';
|
|
2250
|
+
} | {
|
|
2251
|
+
type: 'tool';
|
|
2252
|
+
name: string;
|
|
2253
|
+
};
|
|
2073
2254
|
}
|
|
2074
2255
|
interface Tool {
|
|
2075
2256
|
name: string;
|
|
@@ -2117,6 +2298,15 @@ declare class LLM {
|
|
|
2117
2298
|
* "claude-sonnet-4-5" → ["anthropic", "claude-sonnet-4-5"] (default)
|
|
2118
2299
|
*/
|
|
2119
2300
|
private static _parseModel;
|
|
2301
|
+
/**
|
|
2302
|
+
* Map an Anthropic model id (e.g. "claude-sonnet-4-5-20250929") to the OpenRouter slug
|
|
2303
|
+
* (e.g. "claude-sonnet-4.5"). OpenRouter slugs drop the date suffix and use dotted versions.
|
|
2304
|
+
*/
|
|
2305
|
+
private static _toOpenRouterSlug;
|
|
2306
|
+
private static _openrouterOptions;
|
|
2307
|
+
private static _openrouterText;
|
|
2308
|
+
private static _openrouterStream;
|
|
2309
|
+
private static _openrouterStreamWithTools;
|
|
2120
2310
|
private static _anthropicText;
|
|
2121
2311
|
private static _anthropicStream;
|
|
2122
2312
|
private static _anthropicStreamWithTools;
|
|
@@ -3262,6 +3452,65 @@ declare class DashboardConversationHistory {
|
|
|
3262
3452
|
}
|
|
3263
3453
|
declare const dashboardConversationHistory: DashboardConversationHistory;
|
|
3264
3454
|
|
|
3455
|
+
/**
|
|
3456
|
+
* ScriptMatcher — LLM-Based Script Matching + Parameter Extraction
|
|
3457
|
+
*
|
|
3458
|
+
* Uses ONE LLM call to:
|
|
3459
|
+
* 1. Pick the best matching script from the library (or "none")
|
|
3460
|
+
* 2. Extract parameter values from the user question
|
|
3461
|
+
*
|
|
3462
|
+
* Why LLM over embeddings:
|
|
3463
|
+
* - Embeddings capture topic similarity ("overstock" ≈ "inventory" ≈ "revenue")
|
|
3464
|
+
* but can't distinguish structurally different questions about the same domain
|
|
3465
|
+
* - LLM understands that "overstock by warehouse" needs a different script than
|
|
3466
|
+
* "revenue by warehouse" even though they're semantically close
|
|
3467
|
+
* - One call does both matching AND parameter extraction
|
|
3468
|
+
*
|
|
3469
|
+
* When script library grows past ~50, add an embedding pre-filter
|
|
3470
|
+
* (ChromaDB narrows to top 10 → LLM picks from those 10).
|
|
3471
|
+
*/
|
|
3472
|
+
|
|
3473
|
+
declare class ScriptMatcher {
|
|
3474
|
+
private store;
|
|
3475
|
+
constructor(store: ScriptStore);
|
|
3476
|
+
/**
|
|
3477
|
+
* Find the best matching script for a user question.
|
|
3478
|
+
* Uses ONE LLM call that picks the script AND extracts parameters.
|
|
3479
|
+
* Returns null if no script matches.
|
|
3480
|
+
*/
|
|
3481
|
+
match(userPrompt: string, apiKey?: string, model?: string): Promise<ScriptMatch | null>;
|
|
3482
|
+
/**
|
|
3483
|
+
* Build the script catalog string for the LLM prompt.
|
|
3484
|
+
* Each script gets: index, ID, name, description, and parameter definitions.
|
|
3485
|
+
*/
|
|
3486
|
+
private buildScriptCatalog;
|
|
3487
|
+
}
|
|
3488
|
+
|
|
3489
|
+
/**
|
|
3490
|
+
* ScriptRunner — Execute scripts in an isolated tsx subprocess.
|
|
3491
|
+
*
|
|
3492
|
+
* The subprocess approach replaces the earlier `new Function()` eval and gives us:
|
|
3493
|
+
* - Real sandbox (separate process, SIGKILL on timeout).
|
|
3494
|
+
* - Real TypeScript (tsx transpiles on the fly).
|
|
3495
|
+
* - npm imports available to scripts (clustering, stats, geo, etc.).
|
|
3496
|
+
*
|
|
3497
|
+
* Protocol: NDJSON over the child's stdin/stdout. See script-ipc.ts + backend/docs/SCRIPT-FLOW-IMPLEMENTATION.md.
|
|
3498
|
+
*/
|
|
3499
|
+
|
|
3500
|
+
interface RunScriptOptions {
|
|
3501
|
+
/** Data sources the script is allowed to query via ctx.query */
|
|
3502
|
+
externalTools: ExternalTool[];
|
|
3503
|
+
/** Optional — for propagating per-query UI progress to the user */
|
|
3504
|
+
streamBuffer?: StreamBuffer;
|
|
3505
|
+
/** Override the wall-clock timeout (default `SCRIPT_TIMEOUT_MS`, 60s). */
|
|
3506
|
+
timeoutMs?: number;
|
|
3507
|
+
}
|
|
3508
|
+
/**
|
|
3509
|
+
* Execute a recipe by spawning a tsx child on the script's .ts file.
|
|
3510
|
+
* `scriptPath` is the absolute path to the saved `.ts` body.
|
|
3511
|
+
*/
|
|
3512
|
+
declare function runScript(recipe: ScriptRecipe, scriptPath: string, params: Record<string, any>, options: RunScriptOptions): Promise<ScriptResult>;
|
|
3513
|
+
|
|
3265
3514
|
type MessageTypeHandler = (message: IncomingMessage) => void | Promise<void>;
|
|
3266
3515
|
declare class SuperatomSDK {
|
|
3267
3516
|
private ws;
|
|
@@ -3431,4 +3680,4 @@ declare class SuperatomSDK {
|
|
|
3431
3680
|
getConversationSimilarityThreshold(): number;
|
|
3432
3681
|
}
|
|
3433
3682
|
|
|
3434
|
-
export { type Action, type AgentConfig, type AgentResponse, BM25L, type BM25LOptions, type BaseLLMConfig, CONTEXT_CONFIG, type CapturedLog, CleanupService, type CollectionHandler, type CollectionOperation, type DBUIBlock, DEFAULT_AGENT_CONFIG, type DatabaseType, type HybridSearchOptions, type IncomingMessage, type KbNodesQueryFilters, type KbNodesRequestPayload, LLM, type LLMUsageEntry, type LogLevel, MainAgent, type Message, type ModelStrategy, type OutputField, type RerankedResult, STORAGE_CONFIG, type SelectedWorkflow, SuperatomSDK, type SuperatomSDKConfig, type TaskType, Thread, ThreadManager, type Tool$1 as Tool, type ToolOutputSchema, UIBlock, UILogCollector, type User, UserManager, type UsersData, type WorkflowDescriptor, anthropicLLM, dashboardConversationHistory, geminiLLM, groqLLM, hybridRerank, llmUsageLogger, logger, openaiLLM, queryCache, rerankChromaResults, rerankConversationResults, userPromptErrorLogger };
|
|
3683
|
+
export { type Action, type AgentConfig, type AgentResponse, BM25L, type BM25LOptions, type BaseLLMConfig, CONTEXT_CONFIG, type CapturedLog, CleanupService, type CollectionHandler, type CollectionOperation, type DBUIBlock, DEFAULT_AGENT_CONFIG, type DatabaseType, type HybridSearchOptions, type IncomingMessage, type KbNodesQueryFilters, type KbNodesRequestPayload, LLM, type LLMUsageEntry, type LogLevel, MainAgent, type Message, type ModelStrategy, type OutputField, type RerankedResult, STORAGE_CONFIG, type ScriptComponentSpec, ScriptMatcher, type ScriptParameter, type ScriptRecipe, type ScriptRecipeMetaRow, type ScriptRecipeStore, type ScriptResult, ScriptStore, type ScriptStoreOptions, type SelectedWorkflow, SuperatomSDK, type SuperatomSDKConfig, type TaskType, Thread, ThreadManager, type Tool$1 as Tool, type ToolOutputSchema, UIBlock, UILogCollector, type User, UserManager, type UsersData, type WorkflowDescriptor, anthropicLLM, dashboardConversationHistory, geminiLLM, groqLLM, hybridRerank, llmUsageLogger, logger, normalizeScriptBody, openaiLLM, queryCache, rerankChromaResults, rerankConversationResults, resolveScriptRecipeStore, runScript, userPromptErrorLogger };
|