@superatomai/sdk-node 0.0.84-dsp → 0.0.86-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 +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +17 -10
- package/dist/index.mjs +17 -10
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1624,6 +1624,8 @@ interface PromptContext {
|
|
|
1624
1624
|
dashboardId?: string;
|
|
1625
1625
|
/** The filter values set on that dashboard, keyed by parameter name. */
|
|
1626
1626
|
filters?: Record<string, unknown>;
|
|
1627
|
+
/** Follow the question already running in this thread (a reloaded page); never starts a new one. */
|
|
1628
|
+
follow?: boolean;
|
|
1627
1629
|
}
|
|
1628
1630
|
/**
|
|
1629
1631
|
* Everything a replacement answer flow is handed for one question. Deliberately
|
|
@@ -4449,6 +4451,8 @@ interface PolicyExceptionTable {
|
|
|
4449
4451
|
link?: string;
|
|
4450
4452
|
columns?: string[];
|
|
4451
4453
|
own?: string;
|
|
4454
|
+
/** A predicate (`{t}` is the table) that makes more rows visible, with only `columns` readable; no key list. */
|
|
4455
|
+
visibleWhere?: string;
|
|
4452
4456
|
}
|
|
4453
4457
|
/**
|
|
4454
4458
|
* A named grant: extra rows a restricted user may see outside their branch. `visibleKeys` is
|
package/dist/index.d.ts
CHANGED
|
@@ -1624,6 +1624,8 @@ interface PromptContext {
|
|
|
1624
1624
|
dashboardId?: string;
|
|
1625
1625
|
/** The filter values set on that dashboard, keyed by parameter name. */
|
|
1626
1626
|
filters?: Record<string, unknown>;
|
|
1627
|
+
/** Follow the question already running in this thread (a reloaded page); never starts a new one. */
|
|
1628
|
+
follow?: boolean;
|
|
1627
1629
|
}
|
|
1628
1630
|
/**
|
|
1629
1631
|
* Everything a replacement answer flow is handed for one question. Deliberately
|
|
@@ -4449,6 +4451,8 @@ interface PolicyExceptionTable {
|
|
|
4449
4451
|
link?: string;
|
|
4450
4452
|
columns?: string[];
|
|
4451
4453
|
own?: string;
|
|
4454
|
+
/** A predicate (`{t}` is the table) that makes more rows visible, with only `columns` readable; no key list. */
|
|
4455
|
+
visibleWhere?: string;
|
|
4452
4456
|
}
|
|
4453
4457
|
/**
|
|
4454
4458
|
* A named grant: extra rows a restricted user may see outside their branch. `visibleKeys` is
|
package/dist/index.js
CHANGED
|
@@ -2694,16 +2694,18 @@ function exceptionsFromConfig(raw) {
|
|
|
2694
2694
|
const s = spec;
|
|
2695
2695
|
const link = str(s.link);
|
|
2696
2696
|
const own = str(s.own);
|
|
2697
|
+
const visibleWhere = str(s.visibleWhere);
|
|
2697
2698
|
const columns = Array.isArray(s.columns) ? s.columns.filter((c) => typeof c === "string" && !!c) : [];
|
|
2698
2699
|
let bad = null;
|
|
2699
2700
|
if (!own && !link) bad = 'it has neither "link" nor "own"';
|
|
2700
2701
|
else if (!own && columns.length === 0) bad = 'it lists no "columns"';
|
|
2701
|
-
else if (
|
|
2702
|
+
else if (own && visibleWhere && columns.length === 0) bad = 'it has "visibleWhere" with "own" but lists no "columns"';
|
|
2703
|
+
else if (!own && !visibleKeys && !visibleWhere) bad = 'the exception has no "visibleKeys" and the table no "visibleWhere"';
|
|
2702
2704
|
if (bad) {
|
|
2703
2705
|
logger.warn(`[RequestIdentity] Exception "${name ?? "?"}": table "${table}" dropped because ${bad}.`);
|
|
2704
2706
|
continue;
|
|
2705
2707
|
}
|
|
2706
|
-
tables[table] = own ? { own } : { link, columns };
|
|
2708
|
+
tables[table] = own ? visibleWhere ? { own, columns, visibleWhere } : { own } : { link, columns, ...visibleWhere ? { visibleWhere } : {} };
|
|
2707
2709
|
}
|
|
2708
2710
|
if (Object.keys(tables).length === 0) continue;
|
|
2709
2711
|
out.push({ name, visibleKeys, tables });
|
|
@@ -9839,6 +9841,8 @@ var PromptLoader = class {
|
|
|
9839
9841
|
// Excel sources use DuckDB engine
|
|
9840
9842
|
"csv": "duckdb",
|
|
9841
9843
|
// CSV sources use DuckDB engine
|
|
9844
|
+
"s3": "duckdb",
|
|
9845
|
+
// S3 Parquet sources use DuckDB engine
|
|
9842
9846
|
"dynamodb": "dynamodb",
|
|
9843
9847
|
// DynamoDB uses its own PartiQL rules (no JOIN/GROUP BY/aggregates)
|
|
9844
9848
|
"redis": "redis",
|
|
@@ -11007,6 +11011,7 @@ Analyze the error and try again with a corrected query.`;
|
|
|
11007
11011
|
"mysql": `Add LIMIT ${this.config.maxRowsFetched} at the end of every query`,
|
|
11008
11012
|
"excel": `Add LIMIT ${this.config.maxRowsFetched} at the end of every query`,
|
|
11009
11013
|
"csv": `Add LIMIT ${this.config.maxRowsFetched} at the end of every query`,
|
|
11014
|
+
"s3": `Add LIMIT ${this.config.maxRowsFetched} at the end of every query`,
|
|
11010
11015
|
"dynamodb": `Add LIMIT ${this.config.maxRowsFetched} at the end (this tool applies it \u2014 DynamoDB has no LIMIT clause) and always filter by the partition key`,
|
|
11011
11016
|
"redis": `Provide ONE Redis read command in the query field (e.g. HGETALL key, or SCAN 0 MATCH pattern:* COUNT ${this.config.maxRowsFetched}). Look up by exact key when known; never use KEYS`,
|
|
11012
11017
|
"netsuite": `Add LIMIT ${this.config.maxRowsFetched} at the end of every query (this tool converts it internally \u2014 SuiteQL itself has no LIMIT keyword, so never write FETCH FIRST/OFFSET/TOP yourself)`
|
|
@@ -11055,7 +11060,7 @@ Even if a table appears in the detailed schema above, search_schema returns samp
|
|
|
11055
11060
|
} catch (traceErr) {
|
|
11056
11061
|
logger.warn(`[SourceAgent:${this.tool.name}] Trace capture failed for schemaSearchInstructionsText (non-blocking): ${traceErr}`);
|
|
11057
11062
|
}
|
|
11058
|
-
const displaySourceType = sourceType === "excel" || sourceType === "csv" ? `${sourceType} \u2014 uses DuckDB SQL engine` : sourceType;
|
|
11063
|
+
const displaySourceType = sourceType === "excel" || sourceType === "csv" || sourceType === "s3" ? `${sourceType} \u2014 uses DuckDB SQL engine` : sourceType;
|
|
11059
11064
|
const userAccessContextText = buildAccessSection(this.config.userAccessContext ?? "", "source");
|
|
11060
11065
|
try {
|
|
11061
11066
|
if (this.traceSchemaEntry) this.traceSchemaEntry.userAccessContextText = userAccessContextText;
|
|
@@ -19725,6 +19730,7 @@ function promptContextFrom(raw) {
|
|
|
19725
19730
|
if (source.filters && typeof source.filters === "object" && !Array.isArray(source.filters)) {
|
|
19726
19731
|
context.filters = source.filters;
|
|
19727
19732
|
}
|
|
19733
|
+
if (source.follow === true) context.follow = true;
|
|
19728
19734
|
return Object.keys(context).length ? context : void 0;
|
|
19729
19735
|
}
|
|
19730
19736
|
var inFlightAborts = /* @__PURE__ */ new Map();
|
|
@@ -19907,7 +19913,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
19907
19913
|
};
|
|
19908
19914
|
let userResponse;
|
|
19909
19915
|
try {
|
|
19910
|
-
const replayed = answerProvider && !attachments ? (await replayExactMatch({ prompt, collections, userId, threadId, streamCallback, method: "custom-exact-match", startTime: Date.now() }))?.response : void 0;
|
|
19916
|
+
const replayed = answerProvider && !attachments && !payload.context?.follow ? (await replayExactMatch({ prompt, collections, userId, threadId, streamCallback, method: "custom-exact-match", startTime: Date.now() }))?.response : void 0;
|
|
19911
19917
|
userResponse = replayed ? replayed : answerProvider ? await answerProvider({
|
|
19912
19918
|
prompt,
|
|
19913
19919
|
components,
|
|
@@ -19952,6 +19958,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
19952
19958
|
if (Array.isArray(narration) && narration.length) uiBlock.setNarration(narration);
|
|
19953
19959
|
uiBlock.setDurationMs(Date.now() - requestStartTime);
|
|
19954
19960
|
const uiBlockId = existingUiBlockId;
|
|
19961
|
+
const recordable = !!userId && !userResponse?.data?.followed;
|
|
19955
19962
|
const wasAborted = abortController.signal.aborted || !userResponse.success && Array.isArray(userResponse.errors) && userResponse.errors.includes("aborted");
|
|
19956
19963
|
if (wasAborted) {
|
|
19957
19964
|
thread.removeUIBlock(uiBlockId);
|
|
@@ -19961,7 +19968,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
19961
19968
|
}
|
|
19962
19969
|
let savedConversationId2;
|
|
19963
19970
|
let savedResponse2;
|
|
19964
|
-
if (
|
|
19971
|
+
if (recordable) {
|
|
19965
19972
|
const saveResult = await saveConversation({
|
|
19966
19973
|
userId,
|
|
19967
19974
|
userPrompt: prompt,
|
|
@@ -19980,7 +19987,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
19980
19987
|
savedResponse2 = saveResult.response;
|
|
19981
19988
|
}
|
|
19982
19989
|
}
|
|
19983
|
-
if (
|
|
19990
|
+
if (recordable) {
|
|
19984
19991
|
const latencyMs = Date.now() - requestStartTime;
|
|
19985
19992
|
const turn = reported(userResponse);
|
|
19986
19993
|
const model = turn.model || mainAgentModel || "unknown";
|
|
@@ -20030,7 +20037,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
20030
20037
|
}
|
|
20031
20038
|
let savedConversationId2;
|
|
20032
20039
|
let savedResponse2;
|
|
20033
|
-
if (
|
|
20040
|
+
if (recordable) {
|
|
20034
20041
|
const saveResult = await saveConversation({
|
|
20035
20042
|
userId,
|
|
20036
20043
|
userPrompt: prompt,
|
|
@@ -20052,7 +20059,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
20052
20059
|
savedResponse2 = saveResult.response;
|
|
20053
20060
|
}
|
|
20054
20061
|
}
|
|
20055
|
-
if (
|
|
20062
|
+
if (recordable) {
|
|
20056
20063
|
const latencyMs = Date.now() - requestStartTime;
|
|
20057
20064
|
const turn = reported(userResponse);
|
|
20058
20065
|
const model = turn.model || mainAgentModel || "unknown";
|
|
@@ -20117,7 +20124,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
20117
20124
|
logger.info(`Completed UIBlock: ${uiBlockId} in Thread: ${threadId}`);
|
|
20118
20125
|
let savedConversationId;
|
|
20119
20126
|
let savedResponse;
|
|
20120
|
-
if (
|
|
20127
|
+
if (recordable) {
|
|
20121
20128
|
const responseMethod = userResponse.data?.method || "";
|
|
20122
20129
|
const semanticSimilarity = userResponse.data?.semanticSimilarity || 0;
|
|
20123
20130
|
const isExactMatch = responseMethod.includes("semantic-match") && semanticSimilarity >= 0.99;
|
|
@@ -20156,7 +20163,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
20156
20163
|
}
|
|
20157
20164
|
}
|
|
20158
20165
|
llmUsageLogger.logSessionSummary(prompt?.substring(0, 50));
|
|
20159
|
-
if (
|
|
20166
|
+
if (recordable) {
|
|
20160
20167
|
const latencyMs = Date.now() - requestStartTime;
|
|
20161
20168
|
const turn = reported(userResponse);
|
|
20162
20169
|
const model = turn.model || mainAgentModel || "unknown";
|
package/dist/index.mjs
CHANGED
|
@@ -2582,16 +2582,18 @@ function exceptionsFromConfig(raw) {
|
|
|
2582
2582
|
const s = spec;
|
|
2583
2583
|
const link = str(s.link);
|
|
2584
2584
|
const own = str(s.own);
|
|
2585
|
+
const visibleWhere = str(s.visibleWhere);
|
|
2585
2586
|
const columns = Array.isArray(s.columns) ? s.columns.filter((c) => typeof c === "string" && !!c) : [];
|
|
2586
2587
|
let bad = null;
|
|
2587
2588
|
if (!own && !link) bad = 'it has neither "link" nor "own"';
|
|
2588
2589
|
else if (!own && columns.length === 0) bad = 'it lists no "columns"';
|
|
2589
|
-
else if (
|
|
2590
|
+
else if (own && visibleWhere && columns.length === 0) bad = 'it has "visibleWhere" with "own" but lists no "columns"';
|
|
2591
|
+
else if (!own && !visibleKeys && !visibleWhere) bad = 'the exception has no "visibleKeys" and the table no "visibleWhere"';
|
|
2590
2592
|
if (bad) {
|
|
2591
2593
|
logger.warn(`[RequestIdentity] Exception "${name ?? "?"}": table "${table}" dropped because ${bad}.`);
|
|
2592
2594
|
continue;
|
|
2593
2595
|
}
|
|
2594
|
-
tables[table] = own ? { own } : { link, columns };
|
|
2596
|
+
tables[table] = own ? visibleWhere ? { own, columns, visibleWhere } : { own } : { link, columns, ...visibleWhere ? { visibleWhere } : {} };
|
|
2595
2597
|
}
|
|
2596
2598
|
if (Object.keys(tables).length === 0) continue;
|
|
2597
2599
|
out.push({ name, visibleKeys, tables });
|
|
@@ -9727,6 +9729,8 @@ var PromptLoader = class {
|
|
|
9727
9729
|
// Excel sources use DuckDB engine
|
|
9728
9730
|
"csv": "duckdb",
|
|
9729
9731
|
// CSV sources use DuckDB engine
|
|
9732
|
+
"s3": "duckdb",
|
|
9733
|
+
// S3 Parquet sources use DuckDB engine
|
|
9730
9734
|
"dynamodb": "dynamodb",
|
|
9731
9735
|
// DynamoDB uses its own PartiQL rules (no JOIN/GROUP BY/aggregates)
|
|
9732
9736
|
"redis": "redis",
|
|
@@ -10895,6 +10899,7 @@ Analyze the error and try again with a corrected query.`;
|
|
|
10895
10899
|
"mysql": `Add LIMIT ${this.config.maxRowsFetched} at the end of every query`,
|
|
10896
10900
|
"excel": `Add LIMIT ${this.config.maxRowsFetched} at the end of every query`,
|
|
10897
10901
|
"csv": `Add LIMIT ${this.config.maxRowsFetched} at the end of every query`,
|
|
10902
|
+
"s3": `Add LIMIT ${this.config.maxRowsFetched} at the end of every query`,
|
|
10898
10903
|
"dynamodb": `Add LIMIT ${this.config.maxRowsFetched} at the end (this tool applies it \u2014 DynamoDB has no LIMIT clause) and always filter by the partition key`,
|
|
10899
10904
|
"redis": `Provide ONE Redis read command in the query field (e.g. HGETALL key, or SCAN 0 MATCH pattern:* COUNT ${this.config.maxRowsFetched}). Look up by exact key when known; never use KEYS`,
|
|
10900
10905
|
"netsuite": `Add LIMIT ${this.config.maxRowsFetched} at the end of every query (this tool converts it internally \u2014 SuiteQL itself has no LIMIT keyword, so never write FETCH FIRST/OFFSET/TOP yourself)`
|
|
@@ -10943,7 +10948,7 @@ Even if a table appears in the detailed schema above, search_schema returns samp
|
|
|
10943
10948
|
} catch (traceErr) {
|
|
10944
10949
|
logger.warn(`[SourceAgent:${this.tool.name}] Trace capture failed for schemaSearchInstructionsText (non-blocking): ${traceErr}`);
|
|
10945
10950
|
}
|
|
10946
|
-
const displaySourceType = sourceType === "excel" || sourceType === "csv" ? `${sourceType} \u2014 uses DuckDB SQL engine` : sourceType;
|
|
10951
|
+
const displaySourceType = sourceType === "excel" || sourceType === "csv" || sourceType === "s3" ? `${sourceType} \u2014 uses DuckDB SQL engine` : sourceType;
|
|
10947
10952
|
const userAccessContextText = buildAccessSection(this.config.userAccessContext ?? "", "source");
|
|
10948
10953
|
try {
|
|
10949
10954
|
if (this.traceSchemaEntry) this.traceSchemaEntry.userAccessContextText = userAccessContextText;
|
|
@@ -19613,6 +19618,7 @@ function promptContextFrom(raw) {
|
|
|
19613
19618
|
if (source.filters && typeof source.filters === "object" && !Array.isArray(source.filters)) {
|
|
19614
19619
|
context.filters = source.filters;
|
|
19615
19620
|
}
|
|
19621
|
+
if (source.follow === true) context.follow = true;
|
|
19616
19622
|
return Object.keys(context).length ? context : void 0;
|
|
19617
19623
|
}
|
|
19618
19624
|
var inFlightAborts = /* @__PURE__ */ new Map();
|
|
@@ -19795,7 +19801,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
19795
19801
|
};
|
|
19796
19802
|
let userResponse;
|
|
19797
19803
|
try {
|
|
19798
|
-
const replayed = answerProvider && !attachments ? (await replayExactMatch({ prompt, collections, userId, threadId, streamCallback, method: "custom-exact-match", startTime: Date.now() }))?.response : void 0;
|
|
19804
|
+
const replayed = answerProvider && !attachments && !payload.context?.follow ? (await replayExactMatch({ prompt, collections, userId, threadId, streamCallback, method: "custom-exact-match", startTime: Date.now() }))?.response : void 0;
|
|
19799
19805
|
userResponse = replayed ? replayed : answerProvider ? await answerProvider({
|
|
19800
19806
|
prompt,
|
|
19801
19807
|
components,
|
|
@@ -19840,6 +19846,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
19840
19846
|
if (Array.isArray(narration) && narration.length) uiBlock.setNarration(narration);
|
|
19841
19847
|
uiBlock.setDurationMs(Date.now() - requestStartTime);
|
|
19842
19848
|
const uiBlockId = existingUiBlockId;
|
|
19849
|
+
const recordable = !!userId && !userResponse?.data?.followed;
|
|
19843
19850
|
const wasAborted = abortController.signal.aborted || !userResponse.success && Array.isArray(userResponse.errors) && userResponse.errors.includes("aborted");
|
|
19844
19851
|
if (wasAborted) {
|
|
19845
19852
|
thread.removeUIBlock(uiBlockId);
|
|
@@ -19849,7 +19856,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
19849
19856
|
}
|
|
19850
19857
|
let savedConversationId2;
|
|
19851
19858
|
let savedResponse2;
|
|
19852
|
-
if (
|
|
19859
|
+
if (recordable) {
|
|
19853
19860
|
const saveResult = await saveConversation({
|
|
19854
19861
|
userId,
|
|
19855
19862
|
userPrompt: prompt,
|
|
@@ -19868,7 +19875,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
19868
19875
|
savedResponse2 = saveResult.response;
|
|
19869
19876
|
}
|
|
19870
19877
|
}
|
|
19871
|
-
if (
|
|
19878
|
+
if (recordable) {
|
|
19872
19879
|
const latencyMs = Date.now() - requestStartTime;
|
|
19873
19880
|
const turn = reported(userResponse);
|
|
19874
19881
|
const model = turn.model || mainAgentModel || "unknown";
|
|
@@ -19918,7 +19925,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
19918
19925
|
}
|
|
19919
19926
|
let savedConversationId2;
|
|
19920
19927
|
let savedResponse2;
|
|
19921
|
-
if (
|
|
19928
|
+
if (recordable) {
|
|
19922
19929
|
const saveResult = await saveConversation({
|
|
19923
19930
|
userId,
|
|
19924
19931
|
userPrompt: prompt,
|
|
@@ -19940,7 +19947,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
19940
19947
|
savedResponse2 = saveResult.response;
|
|
19941
19948
|
}
|
|
19942
19949
|
}
|
|
19943
|
-
if (
|
|
19950
|
+
if (recordable) {
|
|
19944
19951
|
const latencyMs = Date.now() - requestStartTime;
|
|
19945
19952
|
const turn = reported(userResponse);
|
|
19946
19953
|
const model = turn.model || mainAgentModel || "unknown";
|
|
@@ -20005,7 +20012,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
20005
20012
|
logger.info(`Completed UIBlock: ${uiBlockId} in Thread: ${threadId}`);
|
|
20006
20013
|
let savedConversationId;
|
|
20007
20014
|
let savedResponse;
|
|
20008
|
-
if (
|
|
20015
|
+
if (recordable) {
|
|
20009
20016
|
const responseMethod = userResponse.data?.method || "";
|
|
20010
20017
|
const semanticSimilarity = userResponse.data?.semanticSimilarity || 0;
|
|
20011
20018
|
const isExactMatch = responseMethod.includes("semantic-match") && semanticSimilarity >= 0.99;
|
|
@@ -20044,7 +20051,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
20044
20051
|
}
|
|
20045
20052
|
}
|
|
20046
20053
|
llmUsageLogger.logSessionSummary(prompt?.substring(0, 50));
|
|
20047
|
-
if (
|
|
20054
|
+
if (recordable) {
|
|
20048
20055
|
const latencyMs = Date.now() - requestStartTime;
|
|
20049
20056
|
const turn = reported(userResponse);
|
|
20050
20057
|
const model = turn.model || mainAgentModel || "unknown";
|