@superatomai/sdk-node 0.0.81-dsp → 0.0.83-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 +156 -800
- package/dist/index.d.ts +156 -800
- package/dist/index.js +88 -28
- package/dist/index.mjs +87 -28
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -52,6 +52,7 @@ __export(index_exports, {
|
|
|
52
52
|
UIBlock: () => UIBlock,
|
|
53
53
|
UILogCollector: () => UILogCollector,
|
|
54
54
|
UserManager: () => UserManager,
|
|
55
|
+
accessFromConfig: () => accessFromConfig,
|
|
55
56
|
analyticsClient: () => analyticsClient,
|
|
56
57
|
answerCatalogForBinding: () => answerCatalogForBinding,
|
|
57
58
|
answerComponents: () => answerComponents,
|
|
@@ -330,7 +331,7 @@ var UserSchema = import_zod3.z.object({
|
|
|
330
331
|
password: import_zod3.z.string().min(1, "Password is required"),
|
|
331
332
|
fullname: import_zod3.z.string().optional(),
|
|
332
333
|
role: import_zod3.z.string().optional(),
|
|
333
|
-
userInfo: import_zod3.z.record(import_zod3.z.unknown()).optional(),
|
|
334
|
+
userInfo: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).optional(),
|
|
334
335
|
wsIds: import_zod3.z.array(import_zod3.z.string()).optional()
|
|
335
336
|
// Only in memory, not persisted to file
|
|
336
337
|
});
|
|
@@ -358,8 +359,8 @@ var IncomingMessageSchema = import_zod3.z.object({
|
|
|
358
359
|
var DataRequestPayloadSchema = import_zod3.z.object({
|
|
359
360
|
collection: import_zod3.z.string(),
|
|
360
361
|
op: import_zod3.z.string(),
|
|
361
|
-
params: import_zod3.z.record(import_zod3.z.unknown()).optional(),
|
|
362
|
-
SA_RUNTIME: import_zod3.z.record(import_zod3.z.unknown()).optional()
|
|
362
|
+
params: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).optional(),
|
|
363
|
+
SA_RUNTIME: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).optional()
|
|
363
364
|
});
|
|
364
365
|
var DataRequestMessageSchema = import_zod3.z.object({
|
|
365
366
|
id: import_zod3.z.string(),
|
|
@@ -456,10 +457,12 @@ var UserPromptSuggestionsMessageSchema = import_zod3.z.object({
|
|
|
456
457
|
payload: UserPromptSuggestionsPayloadSchema
|
|
457
458
|
});
|
|
458
459
|
var ComponentPropsSchema = import_zod3.z.object({
|
|
460
|
+
// Same runtime schema as under zod 3; the cast keeps zod 3's inferred `{}`, since
|
|
461
|
+
// zod 4 infers z.object({}) as Record<string, never> and `query.sql` stops type-checking.
|
|
459
462
|
query: import_zod3.z.string().or(import_zod3.z.object({})).nullable().optional(),
|
|
460
463
|
title: import_zod3.z.string().optional(),
|
|
461
464
|
description: import_zod3.z.string().optional(),
|
|
462
|
-
config: import_zod3.z.record(import_zod3.z.unknown()).optional()
|
|
465
|
+
config: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).optional()
|
|
463
466
|
}).passthrough();
|
|
464
467
|
var ComponentSchema = import_zod3.z.object({
|
|
465
468
|
id: import_zod3.z.string(),
|
|
@@ -487,8 +490,8 @@ var WorkflowDescriptorSchema = import_zod3.z.object({
|
|
|
487
490
|
name: import_zod3.z.string(),
|
|
488
491
|
description: import_zod3.z.string(),
|
|
489
492
|
whenToUse: import_zod3.z.string(),
|
|
490
|
-
propsSchema: import_zod3.z.record(import_zod3.z.string()),
|
|
491
|
-
defaultProps: import_zod3.z.record(import_zod3.z.unknown()).optional()
|
|
493
|
+
propsSchema: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.string()),
|
|
494
|
+
defaultProps: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).optional()
|
|
492
495
|
});
|
|
493
496
|
var WorkflowsSchema = import_zod3.z.array(WorkflowDescriptorSchema);
|
|
494
497
|
var WorkflowListResponsePayloadSchema = import_zod3.z.object({
|
|
@@ -521,8 +524,9 @@ var ToolSchema = import_zod3.z.object({
|
|
|
521
524
|
toolType: import_zod3.z.enum(["source", "direct"]).optional(),
|
|
522
525
|
/** Full untruncated schema for source agent (all columns visible) */
|
|
523
526
|
fullSchema: import_zod3.z.string().optional(),
|
|
524
|
-
params: import_zod3.z.record(import_zod3.z.string()),
|
|
525
|
-
|
|
527
|
+
params: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.string()),
|
|
528
|
+
// zod 4: z.function() is no longer a schema, so a tool's handler is checked as a plain callable.
|
|
529
|
+
fn: import_zod3.z.custom((v) => typeof v === "function", { message: "fn must be a function" }),
|
|
526
530
|
outputSchema: OutputSchema.optional(),
|
|
527
531
|
// Optional: describes the data structure returned by this tool
|
|
528
532
|
/** Cache policy. `false` = never cache (live data, write ops). Mirrors HTTP `Cache-Control: no-store`. */
|
|
@@ -544,7 +548,7 @@ var UsersRequestPayloadSchema = import_zod3.z.object({
|
|
|
544
548
|
password: import_zod3.z.string().optional(),
|
|
545
549
|
fullname: import_zod3.z.string().optional(),
|
|
546
550
|
role: import_zod3.z.string().optional(),
|
|
547
|
-
userInfo: import_zod3.z.record(import_zod3.z.unknown()).optional(),
|
|
551
|
+
userInfo: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).optional(),
|
|
548
552
|
// Query operation fields
|
|
549
553
|
filters: UserQueryFiltersSchema.optional(),
|
|
550
554
|
limit: import_zod3.z.number().optional(),
|
|
@@ -563,7 +567,7 @@ var UILogsPayloadSchema = import_zod3.z.object({
|
|
|
563
567
|
level: import_zod3.z.enum(["info", "error", "warn", "debug"]),
|
|
564
568
|
message: import_zod3.z.string(),
|
|
565
569
|
type: import_zod3.z.enum(["explanation", "query", "general"]).optional(),
|
|
566
|
-
data: import_zod3.z.record(import_zod3.z.unknown()).optional()
|
|
570
|
+
data: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).optional()
|
|
567
571
|
}))
|
|
568
572
|
});
|
|
569
573
|
var UILogsMessageSchema = import_zod3.z.object({
|
|
@@ -681,7 +685,7 @@ var UIBlockSchema = import_zod3.z.object({
|
|
|
681
685
|
// DB field name / Legacy field
|
|
682
686
|
generatedComponentMetadata: ComponentSchema.optional(),
|
|
683
687
|
// Actual field used by UIBlock class
|
|
684
|
-
componentData: import_zod3.z.record(import_zod3.z.any()).optional(),
|
|
688
|
+
componentData: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.any()).optional(),
|
|
685
689
|
createdAt: import_zod3.z.string().optional(),
|
|
686
690
|
/**
|
|
687
691
|
* Which script recipe produced this answer. Set whenever the turn was answered
|
|
@@ -692,7 +696,7 @@ var UIBlockSchema = import_zod3.z.object({
|
|
|
692
696
|
*/
|
|
693
697
|
scriptBinding: import_zod3.z.object({
|
|
694
698
|
recipeId: import_zod3.z.string(),
|
|
695
|
-
params: import_zod3.z.record(import_zod3.z.any()).optional(),
|
|
699
|
+
params: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.any()).optional(),
|
|
696
700
|
name: import_zod3.z.string().optional(),
|
|
697
701
|
columns: import_zod3.z.array(import_zod3.z.string()).optional()
|
|
698
702
|
}).optional(),
|
|
@@ -773,7 +777,7 @@ var ArtifactsRequestPayloadSchema = import_zod3.z.object({
|
|
|
773
777
|
id: import_zod3.z.number().optional(),
|
|
774
778
|
name: import_zod3.z.string().optional(),
|
|
775
779
|
createdBy: import_zod3.z.string().optional(),
|
|
776
|
-
dsl: import_zod3.z.record(import_zod3.z.any()).optional(),
|
|
780
|
+
dsl: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.any()).optional(),
|
|
777
781
|
status: import_zod3.z.string().optional(),
|
|
778
782
|
deleted: import_zod3.z.boolean().optional(),
|
|
779
783
|
limit: import_zod3.z.number().optional(),
|
|
@@ -853,7 +857,7 @@ var MenusRequestPayloadSchema = import_zod3.z.object({
|
|
|
853
857
|
userMessage: import_zod3.z.string().optional(),
|
|
854
858
|
parentId: import_zod3.z.number().nullable().optional(),
|
|
855
859
|
sortOrder: import_zod3.z.number().optional(),
|
|
856
|
-
props: import_zod3.z.record(import_zod3.z.unknown()).optional(),
|
|
860
|
+
props: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).optional(),
|
|
857
861
|
isActive: import_zod3.z.boolean().optional(),
|
|
858
862
|
// Query operation fields
|
|
859
863
|
filters: MenusQueryFiltersSchema.optional(),
|
|
@@ -864,7 +868,7 @@ var MenusRequestPayloadSchema = import_zod3.z.object({
|
|
|
864
868
|
id: import_zod3.z.number(),
|
|
865
869
|
sortOrder: import_zod3.z.number()
|
|
866
870
|
})).optional(),
|
|
867
|
-
menuJson: import_zod3.z.record(import_zod3.z.unknown()).optional(),
|
|
871
|
+
menuJson: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).optional(),
|
|
868
872
|
version: import_zod3.z.number().optional()
|
|
869
873
|
}).optional()
|
|
870
874
|
});
|
|
@@ -1041,7 +1045,7 @@ var DashComponentSchema = import_zod3.z.object({
|
|
|
1041
1045
|
name: import_zod3.z.string(),
|
|
1042
1046
|
kind: import_zod3.z.string(),
|
|
1043
1047
|
purpose: import_zod3.z.string(),
|
|
1044
|
-
props: import_zod3.z.record(DashComponentPropSchema).optional(),
|
|
1048
|
+
props: import_zod3.z.record(import_zod3.z.string(), DashComponentPropSchema).optional(),
|
|
1045
1049
|
useWhen: import_zod3.z.string().optional(),
|
|
1046
1050
|
notes: import_zod3.z.string().optional()
|
|
1047
1051
|
});
|
|
@@ -1948,9 +1952,19 @@ function runWithContext(ctx, fn) {
|
|
|
1948
1952
|
return getStorage().run(ctx, fn);
|
|
1949
1953
|
}
|
|
1950
1954
|
function runAsUser(user, fn) {
|
|
1951
|
-
const { userId, orgId, role, projectId, requestId, policies, graphVersion } = user;
|
|
1955
|
+
const { userId, orgId, role, projectId, requestId, policies, allowedSources, graphVersion } = user;
|
|
1952
1956
|
return runWithContext(
|
|
1953
|
-
|
|
1957
|
+
// `allowedSources` is spread in only when given, so an absent restriction
|
|
1958
|
+
// stays absent rather than becoming an explicit `undefined` that a later
|
|
1959
|
+
// `'allowedSources' in ctx` check would read as present.
|
|
1960
|
+
{
|
|
1961
|
+
principal: { kind: "user", userId, orgId, role },
|
|
1962
|
+
projectId,
|
|
1963
|
+
requestId,
|
|
1964
|
+
policies,
|
|
1965
|
+
...allowedSources !== void 0 ? { allowedSources } : {},
|
|
1966
|
+
...graphVersion !== void 0 ? { graphVersion } : {}
|
|
1967
|
+
},
|
|
1954
1968
|
fn
|
|
1955
1969
|
);
|
|
1956
1970
|
}
|
|
@@ -2632,8 +2646,40 @@ function graphVersionOf(v) {
|
|
|
2632
2646
|
if (v === "draft") return "draft";
|
|
2633
2647
|
return Number.isInteger(v) && v > 0 ? v : void 0;
|
|
2634
2648
|
}
|
|
2649
|
+
function scopedForm(config2) {
|
|
2650
|
+
if (!config2 || typeof config2 !== "object" || Array.isArray(config2)) return void 0;
|
|
2651
|
+
const c = config2;
|
|
2652
|
+
return "allowedSources" in c || "policies" in c ? c : void 0;
|
|
2653
|
+
}
|
|
2654
|
+
function allowedSourcesFrom(value) {
|
|
2655
|
+
if (value === void 0 || value === null) return null;
|
|
2656
|
+
if (!Array.isArray(value)) {
|
|
2657
|
+
if (!warnedBadSources) {
|
|
2658
|
+
warnedBadSources = true;
|
|
2659
|
+
logger.warn(
|
|
2660
|
+
`[RequestIdentity] "allowedSources" is ${typeof value}, not a list of source ids \u2014 treating it as NO sources rather than all of them. Fix the config: "allowedSources": ["mssql-1a2b"].`
|
|
2661
|
+
);
|
|
2662
|
+
}
|
|
2663
|
+
return [];
|
|
2664
|
+
}
|
|
2665
|
+
const out = [];
|
|
2666
|
+
for (const item of value) {
|
|
2667
|
+
if (typeof item !== "string" || !item.trim()) continue;
|
|
2668
|
+
const id = item.trim();
|
|
2669
|
+
if (!out.includes(id)) out.push(id);
|
|
2670
|
+
}
|
|
2671
|
+
return out;
|
|
2672
|
+
}
|
|
2673
|
+
function accessFromConfig(config2) {
|
|
2674
|
+
const scoped = scopedForm(config2);
|
|
2675
|
+
return {
|
|
2676
|
+
policies: policiesFromConfig(config2),
|
|
2677
|
+
allowedSources: scoped ? allowedSourcesFrom(scoped.allowedSources) : null
|
|
2678
|
+
};
|
|
2679
|
+
}
|
|
2635
2680
|
function policiesFromConfig(config2) {
|
|
2636
|
-
const
|
|
2681
|
+
const raw = scopedForm(config2)?.policies ?? config2;
|
|
2682
|
+
const entries = Array.isArray(raw) ? raw : [raw];
|
|
2637
2683
|
const out = [];
|
|
2638
2684
|
for (const entry of entries) {
|
|
2639
2685
|
if (!entry || typeof entry !== "object") continue;
|
|
@@ -2676,12 +2722,13 @@ function policiesFromConfig(config2) {
|
|
|
2676
2722
|
var warnedUntrusted = false;
|
|
2677
2723
|
var warnedAnonymous = false;
|
|
2678
2724
|
var warnedUnlabelled = false;
|
|
2725
|
+
var warnedBadSources = false;
|
|
2679
2726
|
var announcedVerified = false;
|
|
2680
2727
|
var reportedIdMismatches = /* @__PURE__ */ new Set();
|
|
2681
2728
|
function runWithMessageIdentity(message, fn) {
|
|
2682
2729
|
const verified = message?.authContext;
|
|
2683
2730
|
const requestId = message?.id;
|
|
2684
|
-
const policies = verified ?
|
|
2731
|
+
const { policies, allowedSources } = verified ? accessFromConfig(verified.config) : accessFromConfig(message?.payload?.config);
|
|
2685
2732
|
if (verified?.userId) {
|
|
2686
2733
|
const claimedId = message?.payload?.userId;
|
|
2687
2734
|
if (!announcedVerified) {
|
|
@@ -2706,6 +2753,9 @@ function runWithMessageIdentity(message, fn) {
|
|
|
2706
2753
|
role: verified.role,
|
|
2707
2754
|
requestId,
|
|
2708
2755
|
policies,
|
|
2756
|
+
// `?? undefined` so "no restriction" leaves the key off the context
|
|
2757
|
+
// entirely; `[]` is passed through as the deny-everything it means.
|
|
2758
|
+
allowedSources: allowedSources ?? void 0,
|
|
2709
2759
|
// Only from the verified context: an unverified message has no say in which graph answers.
|
|
2710
2760
|
graphVersion: graphVersionOf(verified.graphVersion)
|
|
2711
2761
|
},
|
|
@@ -2720,7 +2770,7 @@ function runWithMessageIdentity(message, fn) {
|
|
|
2720
2770
|
"[RequestIdentity] Using the client-supplied payload.userId as the principal \u2014 the relay is not stamping a verified authContext yet, so this identity is NOT trustworthy. Fine for plumbing; do not enable policy enforcement until the relay change lands."
|
|
2721
2771
|
);
|
|
2722
2772
|
}
|
|
2723
|
-
return runAsUser({ userId: claimed, requestId, policies }, fn);
|
|
2773
|
+
return runAsUser({ userId: claimed, requestId, policies, allowedSources: allowedSources ?? void 0 }, fn);
|
|
2724
2774
|
}
|
|
2725
2775
|
if (!warnedAnonymous) {
|
|
2726
2776
|
warnedAnonymous = true;
|
|
@@ -18186,7 +18236,8 @@ function storeScriptDatasetQuery(q, ctx) {
|
|
|
18186
18236
|
return queryCache.storeQuery(q.sql, { data, count });
|
|
18187
18237
|
}
|
|
18188
18238
|
function buildUserAccessContext(userConfig) {
|
|
18189
|
-
const
|
|
18239
|
+
const config2 = userConfig && !Array.isArray(userConfig) && typeof userConfig === "object" && ("policies" in userConfig || "allowedSources" in userConfig) ? userConfig.policies : userConfig;
|
|
18240
|
+
const entries = Array.isArray(config2) ? config2 : [config2];
|
|
18190
18241
|
const restrictions = [];
|
|
18191
18242
|
const prompts = [];
|
|
18192
18243
|
let anyRestriction = false;
|
|
@@ -19692,7 +19743,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
19692
19743
|
const parseResult = UserPromptRequestMessageSchema.safeParse(data);
|
|
19693
19744
|
if (!parseResult.success) {
|
|
19694
19745
|
const zodError = parseResult.error;
|
|
19695
|
-
zodError.
|
|
19746
|
+
zodError.issues.forEach((err) => {
|
|
19696
19747
|
errors.push(`${err.path.join(".")}: ${err.message}`);
|
|
19697
19748
|
});
|
|
19698
19749
|
return { success: false, errors };
|
|
@@ -24205,7 +24256,7 @@ var processDashCompRequest = async (data, components, _sendMessage, anthropicApi
|
|
|
24205
24256
|
const parseResult = DashCompRequestMessageSchema.safeParse(data);
|
|
24206
24257
|
if (!parseResult.success) {
|
|
24207
24258
|
const zodError = parseResult.error;
|
|
24208
|
-
zodError.
|
|
24259
|
+
zodError.issues.forEach((err) => {
|
|
24209
24260
|
errors.push(`${err.path.join(".")}: ${err.message}`);
|
|
24210
24261
|
});
|
|
24211
24262
|
return { success: false, errors };
|
|
@@ -24376,7 +24427,7 @@ async function handleDashboardAgentRequest(data, collections, sendMessage) {
|
|
|
24376
24427
|
console.log("[DashboardAgentReq] Handler invoked. Raw message type/id:", data?.type, data?.id);
|
|
24377
24428
|
const parseResult = DashboardAgentRequestMessageSchema.safeParse(data);
|
|
24378
24429
|
if (!parseResult.success) {
|
|
24379
|
-
logger.error("[DashboardAgentReq] Invalid message \u2014 failed schema validation:", JSON.stringify(parseResult.error.
|
|
24430
|
+
logger.error("[DashboardAgentReq] Invalid message \u2014 failed schema validation:", JSON.stringify(parseResult.error.issues));
|
|
24380
24431
|
return;
|
|
24381
24432
|
}
|
|
24382
24433
|
const { id, payload, from } = parseResult.data;
|
|
@@ -25748,6 +25799,11 @@ fetch(BRIDGE + '/run-tool', {
|
|
|
25748
25799
|
// have been shown to you in full, and guessing column names wastes a turn on
|
|
25749
25800
|
// a failed query. Generated per run \u2014 do not edit.
|
|
25750
25801
|
const BRIDGE = ${JSON.stringify(opts.bridgeUrl)};
|
|
25802
|
+
// Sent for the same reason ./query sends it. A schema describes the data, so
|
|
25803
|
+
// WHICH tables may be described is the caller's access, not a free question \u2014
|
|
25804
|
+
// without this the bridge cannot tell whose run this is, and a source the run
|
|
25805
|
+
// may not read would be described to it in full.
|
|
25806
|
+
const CONTEXT_TOKEN = ${JSON.stringify(opts.contextToken ?? null)};
|
|
25751
25807
|
|
|
25752
25808
|
const [toolId, ...keywords] = process.argv.slice(2);
|
|
25753
25809
|
if (!toolId || !keywords.length) {
|
|
@@ -25757,7 +25813,10 @@ if (!toolId || !keywords.length) {
|
|
|
25757
25813
|
|
|
25758
25814
|
fetch(BRIDGE + '/schema-search', {
|
|
25759
25815
|
method: 'POST',
|
|
25760
|
-
headers: {
|
|
25816
|
+
headers: {
|
|
25817
|
+
'content-type': 'application/json',
|
|
25818
|
+
...(CONTEXT_TOKEN ? { 'x-sa-context': CONTEXT_TOKEN } : {}),
|
|
25819
|
+
},
|
|
25761
25820
|
body: JSON.stringify({ toolId, keywords }),
|
|
25762
25821
|
})
|
|
25763
25822
|
.then(async (r) => {
|
|
@@ -26223,7 +26282,7 @@ function handleCodingAgentAbort(data, sendMessage) {
|
|
|
26223
26282
|
async function handleCodingAgentRequest(data, collections, sendMessage) {
|
|
26224
26283
|
const parseResult = CodingAgentRequestMessageSchema.safeParse(data);
|
|
26225
26284
|
if (!parseResult.success) {
|
|
26226
|
-
logger.error("[CodingAgentReq] Invalid message:", JSON.stringify(parseResult.error.
|
|
26285
|
+
logger.error("[CodingAgentReq] Invalid message:", JSON.stringify(parseResult.error.issues));
|
|
26227
26286
|
return;
|
|
26228
26287
|
}
|
|
26229
26288
|
const { id, payload, from } = parseResult.data;
|
|
@@ -26343,7 +26402,7 @@ async function handleDashBuilderRequest(data, collections, sendMessage) {
|
|
|
26343
26402
|
async function handleDashBuilderRequestInner(data, collections, sendMessage) {
|
|
26344
26403
|
const parsed = DashBuilderRequestMessageSchema.safeParse(data);
|
|
26345
26404
|
if (!parsed.success) {
|
|
26346
|
-
logger.error("[DashBuilderReq] Invalid message:", JSON.stringify(parsed.error.
|
|
26405
|
+
logger.error("[DashBuilderReq] Invalid message:", JSON.stringify(parsed.error.issues));
|
|
26347
26406
|
return;
|
|
26348
26407
|
}
|
|
26349
26408
|
const { id, payload, from } = parsed.data;
|
|
@@ -30094,6 +30153,7 @@ var SuperatomSDK = class {
|
|
|
30094
30153
|
UIBlock,
|
|
30095
30154
|
UILogCollector,
|
|
30096
30155
|
UserManager,
|
|
30156
|
+
accessFromConfig,
|
|
30097
30157
|
analyticsClient,
|
|
30098
30158
|
answerCatalogForBinding,
|
|
30099
30159
|
answerComponents,
|
package/dist/index.mjs
CHANGED
|
@@ -219,7 +219,7 @@ var UserSchema = z3.object({
|
|
|
219
219
|
password: z3.string().min(1, "Password is required"),
|
|
220
220
|
fullname: z3.string().optional(),
|
|
221
221
|
role: z3.string().optional(),
|
|
222
|
-
userInfo: z3.record(z3.unknown()).optional(),
|
|
222
|
+
userInfo: z3.record(z3.string(), z3.unknown()).optional(),
|
|
223
223
|
wsIds: z3.array(z3.string()).optional()
|
|
224
224
|
// Only in memory, not persisted to file
|
|
225
225
|
});
|
|
@@ -247,8 +247,8 @@ var IncomingMessageSchema = z3.object({
|
|
|
247
247
|
var DataRequestPayloadSchema = z3.object({
|
|
248
248
|
collection: z3.string(),
|
|
249
249
|
op: z3.string(),
|
|
250
|
-
params: z3.record(z3.unknown()).optional(),
|
|
251
|
-
SA_RUNTIME: z3.record(z3.unknown()).optional()
|
|
250
|
+
params: z3.record(z3.string(), z3.unknown()).optional(),
|
|
251
|
+
SA_RUNTIME: z3.record(z3.string(), z3.unknown()).optional()
|
|
252
252
|
});
|
|
253
253
|
var DataRequestMessageSchema = z3.object({
|
|
254
254
|
id: z3.string(),
|
|
@@ -345,10 +345,12 @@ var UserPromptSuggestionsMessageSchema = z3.object({
|
|
|
345
345
|
payload: UserPromptSuggestionsPayloadSchema
|
|
346
346
|
});
|
|
347
347
|
var ComponentPropsSchema = z3.object({
|
|
348
|
+
// Same runtime schema as under zod 3; the cast keeps zod 3's inferred `{}`, since
|
|
349
|
+
// zod 4 infers z.object({}) as Record<string, never> and `query.sql` stops type-checking.
|
|
348
350
|
query: z3.string().or(z3.object({})).nullable().optional(),
|
|
349
351
|
title: z3.string().optional(),
|
|
350
352
|
description: z3.string().optional(),
|
|
351
|
-
config: z3.record(z3.unknown()).optional()
|
|
353
|
+
config: z3.record(z3.string(), z3.unknown()).optional()
|
|
352
354
|
}).passthrough();
|
|
353
355
|
var ComponentSchema = z3.object({
|
|
354
356
|
id: z3.string(),
|
|
@@ -376,8 +378,8 @@ var WorkflowDescriptorSchema = z3.object({
|
|
|
376
378
|
name: z3.string(),
|
|
377
379
|
description: z3.string(),
|
|
378
380
|
whenToUse: z3.string(),
|
|
379
|
-
propsSchema: z3.record(z3.string()),
|
|
380
|
-
defaultProps: z3.record(z3.unknown()).optional()
|
|
381
|
+
propsSchema: z3.record(z3.string(), z3.string()),
|
|
382
|
+
defaultProps: z3.record(z3.string(), z3.unknown()).optional()
|
|
381
383
|
});
|
|
382
384
|
var WorkflowsSchema = z3.array(WorkflowDescriptorSchema);
|
|
383
385
|
var WorkflowListResponsePayloadSchema = z3.object({
|
|
@@ -410,8 +412,9 @@ var ToolSchema = z3.object({
|
|
|
410
412
|
toolType: z3.enum(["source", "direct"]).optional(),
|
|
411
413
|
/** Full untruncated schema for source agent (all columns visible) */
|
|
412
414
|
fullSchema: z3.string().optional(),
|
|
413
|
-
params: z3.record(z3.string()),
|
|
414
|
-
|
|
415
|
+
params: z3.record(z3.string(), z3.string()),
|
|
416
|
+
// zod 4: z.function() is no longer a schema, so a tool's handler is checked as a plain callable.
|
|
417
|
+
fn: z3.custom((v) => typeof v === "function", { message: "fn must be a function" }),
|
|
415
418
|
outputSchema: OutputSchema.optional(),
|
|
416
419
|
// Optional: describes the data structure returned by this tool
|
|
417
420
|
/** Cache policy. `false` = never cache (live data, write ops). Mirrors HTTP `Cache-Control: no-store`. */
|
|
@@ -433,7 +436,7 @@ var UsersRequestPayloadSchema = z3.object({
|
|
|
433
436
|
password: z3.string().optional(),
|
|
434
437
|
fullname: z3.string().optional(),
|
|
435
438
|
role: z3.string().optional(),
|
|
436
|
-
userInfo: z3.record(z3.unknown()).optional(),
|
|
439
|
+
userInfo: z3.record(z3.string(), z3.unknown()).optional(),
|
|
437
440
|
// Query operation fields
|
|
438
441
|
filters: UserQueryFiltersSchema.optional(),
|
|
439
442
|
limit: z3.number().optional(),
|
|
@@ -452,7 +455,7 @@ var UILogsPayloadSchema = z3.object({
|
|
|
452
455
|
level: z3.enum(["info", "error", "warn", "debug"]),
|
|
453
456
|
message: z3.string(),
|
|
454
457
|
type: z3.enum(["explanation", "query", "general"]).optional(),
|
|
455
|
-
data: z3.record(z3.unknown()).optional()
|
|
458
|
+
data: z3.record(z3.string(), z3.unknown()).optional()
|
|
456
459
|
}))
|
|
457
460
|
});
|
|
458
461
|
var UILogsMessageSchema = z3.object({
|
|
@@ -570,7 +573,7 @@ var UIBlockSchema = z3.object({
|
|
|
570
573
|
// DB field name / Legacy field
|
|
571
574
|
generatedComponentMetadata: ComponentSchema.optional(),
|
|
572
575
|
// Actual field used by UIBlock class
|
|
573
|
-
componentData: z3.record(z3.any()).optional(),
|
|
576
|
+
componentData: z3.record(z3.string(), z3.any()).optional(),
|
|
574
577
|
createdAt: z3.string().optional(),
|
|
575
578
|
/**
|
|
576
579
|
* Which script recipe produced this answer. Set whenever the turn was answered
|
|
@@ -581,7 +584,7 @@ var UIBlockSchema = z3.object({
|
|
|
581
584
|
*/
|
|
582
585
|
scriptBinding: z3.object({
|
|
583
586
|
recipeId: z3.string(),
|
|
584
|
-
params: z3.record(z3.any()).optional(),
|
|
587
|
+
params: z3.record(z3.string(), z3.any()).optional(),
|
|
585
588
|
name: z3.string().optional(),
|
|
586
589
|
columns: z3.array(z3.string()).optional()
|
|
587
590
|
}).optional(),
|
|
@@ -662,7 +665,7 @@ var ArtifactsRequestPayloadSchema = z3.object({
|
|
|
662
665
|
id: z3.number().optional(),
|
|
663
666
|
name: z3.string().optional(),
|
|
664
667
|
createdBy: z3.string().optional(),
|
|
665
|
-
dsl: z3.record(z3.any()).optional(),
|
|
668
|
+
dsl: z3.record(z3.string(), z3.any()).optional(),
|
|
666
669
|
status: z3.string().optional(),
|
|
667
670
|
deleted: z3.boolean().optional(),
|
|
668
671
|
limit: z3.number().optional(),
|
|
@@ -742,7 +745,7 @@ var MenusRequestPayloadSchema = z3.object({
|
|
|
742
745
|
userMessage: z3.string().optional(),
|
|
743
746
|
parentId: z3.number().nullable().optional(),
|
|
744
747
|
sortOrder: z3.number().optional(),
|
|
745
|
-
props: z3.record(z3.unknown()).optional(),
|
|
748
|
+
props: z3.record(z3.string(), z3.unknown()).optional(),
|
|
746
749
|
isActive: z3.boolean().optional(),
|
|
747
750
|
// Query operation fields
|
|
748
751
|
filters: MenusQueryFiltersSchema.optional(),
|
|
@@ -753,7 +756,7 @@ var MenusRequestPayloadSchema = z3.object({
|
|
|
753
756
|
id: z3.number(),
|
|
754
757
|
sortOrder: z3.number()
|
|
755
758
|
})).optional(),
|
|
756
|
-
menuJson: z3.record(z3.unknown()).optional(),
|
|
759
|
+
menuJson: z3.record(z3.string(), z3.unknown()).optional(),
|
|
757
760
|
version: z3.number().optional()
|
|
758
761
|
}).optional()
|
|
759
762
|
});
|
|
@@ -930,7 +933,7 @@ var DashComponentSchema = z3.object({
|
|
|
930
933
|
name: z3.string(),
|
|
931
934
|
kind: z3.string(),
|
|
932
935
|
purpose: z3.string(),
|
|
933
|
-
props: z3.record(DashComponentPropSchema).optional(),
|
|
936
|
+
props: z3.record(z3.string(), DashComponentPropSchema).optional(),
|
|
934
937
|
useWhen: z3.string().optional(),
|
|
935
938
|
notes: z3.string().optional()
|
|
936
939
|
});
|
|
@@ -1837,9 +1840,19 @@ function runWithContext(ctx, fn) {
|
|
|
1837
1840
|
return getStorage().run(ctx, fn);
|
|
1838
1841
|
}
|
|
1839
1842
|
function runAsUser(user, fn) {
|
|
1840
|
-
const { userId, orgId, role, projectId, requestId, policies, graphVersion } = user;
|
|
1843
|
+
const { userId, orgId, role, projectId, requestId, policies, allowedSources, graphVersion } = user;
|
|
1841
1844
|
return runWithContext(
|
|
1842
|
-
|
|
1845
|
+
// `allowedSources` is spread in only when given, so an absent restriction
|
|
1846
|
+
// stays absent rather than becoming an explicit `undefined` that a later
|
|
1847
|
+
// `'allowedSources' in ctx` check would read as present.
|
|
1848
|
+
{
|
|
1849
|
+
principal: { kind: "user", userId, orgId, role },
|
|
1850
|
+
projectId,
|
|
1851
|
+
requestId,
|
|
1852
|
+
policies,
|
|
1853
|
+
...allowedSources !== void 0 ? { allowedSources } : {},
|
|
1854
|
+
...graphVersion !== void 0 ? { graphVersion } : {}
|
|
1855
|
+
},
|
|
1843
1856
|
fn
|
|
1844
1857
|
);
|
|
1845
1858
|
}
|
|
@@ -2521,8 +2534,40 @@ function graphVersionOf(v) {
|
|
|
2521
2534
|
if (v === "draft") return "draft";
|
|
2522
2535
|
return Number.isInteger(v) && v > 0 ? v : void 0;
|
|
2523
2536
|
}
|
|
2537
|
+
function scopedForm(config2) {
|
|
2538
|
+
if (!config2 || typeof config2 !== "object" || Array.isArray(config2)) return void 0;
|
|
2539
|
+
const c = config2;
|
|
2540
|
+
return "allowedSources" in c || "policies" in c ? c : void 0;
|
|
2541
|
+
}
|
|
2542
|
+
function allowedSourcesFrom(value) {
|
|
2543
|
+
if (value === void 0 || value === null) return null;
|
|
2544
|
+
if (!Array.isArray(value)) {
|
|
2545
|
+
if (!warnedBadSources) {
|
|
2546
|
+
warnedBadSources = true;
|
|
2547
|
+
logger.warn(
|
|
2548
|
+
`[RequestIdentity] "allowedSources" is ${typeof value}, not a list of source ids \u2014 treating it as NO sources rather than all of them. Fix the config: "allowedSources": ["mssql-1a2b"].`
|
|
2549
|
+
);
|
|
2550
|
+
}
|
|
2551
|
+
return [];
|
|
2552
|
+
}
|
|
2553
|
+
const out = [];
|
|
2554
|
+
for (const item of value) {
|
|
2555
|
+
if (typeof item !== "string" || !item.trim()) continue;
|
|
2556
|
+
const id = item.trim();
|
|
2557
|
+
if (!out.includes(id)) out.push(id);
|
|
2558
|
+
}
|
|
2559
|
+
return out;
|
|
2560
|
+
}
|
|
2561
|
+
function accessFromConfig(config2) {
|
|
2562
|
+
const scoped = scopedForm(config2);
|
|
2563
|
+
return {
|
|
2564
|
+
policies: policiesFromConfig(config2),
|
|
2565
|
+
allowedSources: scoped ? allowedSourcesFrom(scoped.allowedSources) : null
|
|
2566
|
+
};
|
|
2567
|
+
}
|
|
2524
2568
|
function policiesFromConfig(config2) {
|
|
2525
|
-
const
|
|
2569
|
+
const raw = scopedForm(config2)?.policies ?? config2;
|
|
2570
|
+
const entries = Array.isArray(raw) ? raw : [raw];
|
|
2526
2571
|
const out = [];
|
|
2527
2572
|
for (const entry of entries) {
|
|
2528
2573
|
if (!entry || typeof entry !== "object") continue;
|
|
@@ -2565,12 +2610,13 @@ function policiesFromConfig(config2) {
|
|
|
2565
2610
|
var warnedUntrusted = false;
|
|
2566
2611
|
var warnedAnonymous = false;
|
|
2567
2612
|
var warnedUnlabelled = false;
|
|
2613
|
+
var warnedBadSources = false;
|
|
2568
2614
|
var announcedVerified = false;
|
|
2569
2615
|
var reportedIdMismatches = /* @__PURE__ */ new Set();
|
|
2570
2616
|
function runWithMessageIdentity(message, fn) {
|
|
2571
2617
|
const verified = message?.authContext;
|
|
2572
2618
|
const requestId = message?.id;
|
|
2573
|
-
const policies = verified ?
|
|
2619
|
+
const { policies, allowedSources } = verified ? accessFromConfig(verified.config) : accessFromConfig(message?.payload?.config);
|
|
2574
2620
|
if (verified?.userId) {
|
|
2575
2621
|
const claimedId = message?.payload?.userId;
|
|
2576
2622
|
if (!announcedVerified) {
|
|
@@ -2595,6 +2641,9 @@ function runWithMessageIdentity(message, fn) {
|
|
|
2595
2641
|
role: verified.role,
|
|
2596
2642
|
requestId,
|
|
2597
2643
|
policies,
|
|
2644
|
+
// `?? undefined` so "no restriction" leaves the key off the context
|
|
2645
|
+
// entirely; `[]` is passed through as the deny-everything it means.
|
|
2646
|
+
allowedSources: allowedSources ?? void 0,
|
|
2598
2647
|
// Only from the verified context: an unverified message has no say in which graph answers.
|
|
2599
2648
|
graphVersion: graphVersionOf(verified.graphVersion)
|
|
2600
2649
|
},
|
|
@@ -2609,7 +2658,7 @@ function runWithMessageIdentity(message, fn) {
|
|
|
2609
2658
|
"[RequestIdentity] Using the client-supplied payload.userId as the principal \u2014 the relay is not stamping a verified authContext yet, so this identity is NOT trustworthy. Fine for plumbing; do not enable policy enforcement until the relay change lands."
|
|
2610
2659
|
);
|
|
2611
2660
|
}
|
|
2612
|
-
return runAsUser({ userId: claimed, requestId, policies }, fn);
|
|
2661
|
+
return runAsUser({ userId: claimed, requestId, policies, allowedSources: allowedSources ?? void 0 }, fn);
|
|
2613
2662
|
}
|
|
2614
2663
|
if (!warnedAnonymous) {
|
|
2615
2664
|
warnedAnonymous = true;
|
|
@@ -18075,7 +18124,8 @@ function storeScriptDatasetQuery(q, ctx) {
|
|
|
18075
18124
|
return queryCache.storeQuery(q.sql, { data, count });
|
|
18076
18125
|
}
|
|
18077
18126
|
function buildUserAccessContext(userConfig) {
|
|
18078
|
-
const
|
|
18127
|
+
const config2 = userConfig && !Array.isArray(userConfig) && typeof userConfig === "object" && ("policies" in userConfig || "allowedSources" in userConfig) ? userConfig.policies : userConfig;
|
|
18128
|
+
const entries = Array.isArray(config2) ? config2 : [config2];
|
|
18079
18129
|
const restrictions = [];
|
|
18080
18130
|
const prompts = [];
|
|
18081
18131
|
let anyRestriction = false;
|
|
@@ -19581,7 +19631,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
19581
19631
|
const parseResult = UserPromptRequestMessageSchema.safeParse(data);
|
|
19582
19632
|
if (!parseResult.success) {
|
|
19583
19633
|
const zodError = parseResult.error;
|
|
19584
|
-
zodError.
|
|
19634
|
+
zodError.issues.forEach((err) => {
|
|
19585
19635
|
errors.push(`${err.path.join(".")}: ${err.message}`);
|
|
19586
19636
|
});
|
|
19587
19637
|
return { success: false, errors };
|
|
@@ -24094,7 +24144,7 @@ var processDashCompRequest = async (data, components, _sendMessage, anthropicApi
|
|
|
24094
24144
|
const parseResult = DashCompRequestMessageSchema.safeParse(data);
|
|
24095
24145
|
if (!parseResult.success) {
|
|
24096
24146
|
const zodError = parseResult.error;
|
|
24097
|
-
zodError.
|
|
24147
|
+
zodError.issues.forEach((err) => {
|
|
24098
24148
|
errors.push(`${err.path.join(".")}: ${err.message}`);
|
|
24099
24149
|
});
|
|
24100
24150
|
return { success: false, errors };
|
|
@@ -24265,7 +24315,7 @@ async function handleDashboardAgentRequest(data, collections, sendMessage) {
|
|
|
24265
24315
|
console.log("[DashboardAgentReq] Handler invoked. Raw message type/id:", data?.type, data?.id);
|
|
24266
24316
|
const parseResult = DashboardAgentRequestMessageSchema.safeParse(data);
|
|
24267
24317
|
if (!parseResult.success) {
|
|
24268
|
-
logger.error("[DashboardAgentReq] Invalid message \u2014 failed schema validation:", JSON.stringify(parseResult.error.
|
|
24318
|
+
logger.error("[DashboardAgentReq] Invalid message \u2014 failed schema validation:", JSON.stringify(parseResult.error.issues));
|
|
24269
24319
|
return;
|
|
24270
24320
|
}
|
|
24271
24321
|
const { id, payload, from } = parseResult.data;
|
|
@@ -25637,6 +25687,11 @@ fetch(BRIDGE + '/run-tool', {
|
|
|
25637
25687
|
// have been shown to you in full, and guessing column names wastes a turn on
|
|
25638
25688
|
// a failed query. Generated per run \u2014 do not edit.
|
|
25639
25689
|
const BRIDGE = ${JSON.stringify(opts.bridgeUrl)};
|
|
25690
|
+
// Sent for the same reason ./query sends it. A schema describes the data, so
|
|
25691
|
+
// WHICH tables may be described is the caller's access, not a free question \u2014
|
|
25692
|
+
// without this the bridge cannot tell whose run this is, and a source the run
|
|
25693
|
+
// may not read would be described to it in full.
|
|
25694
|
+
const CONTEXT_TOKEN = ${JSON.stringify(opts.contextToken ?? null)};
|
|
25640
25695
|
|
|
25641
25696
|
const [toolId, ...keywords] = process.argv.slice(2);
|
|
25642
25697
|
if (!toolId || !keywords.length) {
|
|
@@ -25646,7 +25701,10 @@ if (!toolId || !keywords.length) {
|
|
|
25646
25701
|
|
|
25647
25702
|
fetch(BRIDGE + '/schema-search', {
|
|
25648
25703
|
method: 'POST',
|
|
25649
|
-
headers: {
|
|
25704
|
+
headers: {
|
|
25705
|
+
'content-type': 'application/json',
|
|
25706
|
+
...(CONTEXT_TOKEN ? { 'x-sa-context': CONTEXT_TOKEN } : {}),
|
|
25707
|
+
},
|
|
25650
25708
|
body: JSON.stringify({ toolId, keywords }),
|
|
25651
25709
|
})
|
|
25652
25710
|
.then(async (r) => {
|
|
@@ -26112,7 +26170,7 @@ function handleCodingAgentAbort(data, sendMessage) {
|
|
|
26112
26170
|
async function handleCodingAgentRequest(data, collections, sendMessage) {
|
|
26113
26171
|
const parseResult = CodingAgentRequestMessageSchema.safeParse(data);
|
|
26114
26172
|
if (!parseResult.success) {
|
|
26115
|
-
logger.error("[CodingAgentReq] Invalid message:", JSON.stringify(parseResult.error.
|
|
26173
|
+
logger.error("[CodingAgentReq] Invalid message:", JSON.stringify(parseResult.error.issues));
|
|
26116
26174
|
return;
|
|
26117
26175
|
}
|
|
26118
26176
|
const { id, payload, from } = parseResult.data;
|
|
@@ -26232,7 +26290,7 @@ async function handleDashBuilderRequest(data, collections, sendMessage) {
|
|
|
26232
26290
|
async function handleDashBuilderRequestInner(data, collections, sendMessage) {
|
|
26233
26291
|
const parsed = DashBuilderRequestMessageSchema.safeParse(data);
|
|
26234
26292
|
if (!parsed.success) {
|
|
26235
|
-
logger.error("[DashBuilderReq] Invalid message:", JSON.stringify(parsed.error.
|
|
26293
|
+
logger.error("[DashBuilderReq] Invalid message:", JSON.stringify(parsed.error.issues));
|
|
26236
26294
|
return;
|
|
26237
26295
|
}
|
|
26238
26296
|
const { id, payload, from } = parsed.data;
|
|
@@ -29982,6 +30040,7 @@ export {
|
|
|
29982
30040
|
UIBlock,
|
|
29983
30041
|
UILogCollector,
|
|
29984
30042
|
UserManager,
|
|
30043
|
+
accessFromConfig,
|
|
29985
30044
|
analyticsClient,
|
|
29986
30045
|
answerCatalogForBinding,
|
|
29987
30046
|
answerComponents,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superatomai/sdk-node",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.83-dsp",
|
|
4
4
|
"description": "Node.js TypeScript SDK for Superatom",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"openai": "^4.77.0",
|
|
42
42
|
"typebox": "^1.1.38",
|
|
43
43
|
"ws": "^8.21.0",
|
|
44
|
-
"zod": "^
|
|
44
|
+
"zod": "^4.6.6"
|
|
45
45
|
},
|
|
46
46
|
"optionalDependencies": {
|
|
47
47
|
"@openai/codex-sdk": "0.156.1"
|