@vericto/sdk 0.0.0-stage → 0.2.0
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/CHANGELOG.md +83 -0
- package/LICENSE +93 -0
- package/README.md +377 -2
- package/SECURITY.md +58 -0
- package/dist/better-sqlite3.cjs +62 -0
- package/dist/better-sqlite3.cjs.map +1 -0
- package/dist/better-sqlite3.d.cts +64 -0
- package/dist/better-sqlite3.d.ts +64 -0
- package/dist/better-sqlite3.js +58 -0
- package/dist/better-sqlite3.js.map +1 -0
- package/dist/chunk-HFL7W4WC.cjs +600 -0
- package/dist/chunk-HFL7W4WC.cjs.map +1 -0
- package/dist/chunk-I4I35HUY.js +582 -0
- package/dist/chunk-I4I35HUY.js.map +1 -0
- package/dist/guard-BVpq8ytG.d.cts +175 -0
- package/dist/guard-BVpq8ytG.d.ts +175 -0
- package/dist/index.cjs +76 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +76 -0
- package/dist/index.d.ts +76 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/langchain.cjs +195 -0
- package/dist/langchain.cjs.map +1 -0
- package/dist/langchain.d.cts +126 -0
- package/dist/langchain.d.ts +126 -0
- package/dist/langchain.js +186 -0
- package/dist/langchain.js.map +1 -0
- package/dist/snowflake.cjs +51 -0
- package/dist/snowflake.cjs.map +1 -0
- package/dist/snowflake.d.cts +47 -0
- package/dist/snowflake.d.ts +47 -0
- package/dist/snowflake.js +47 -0
- package/dist/snowflake.js.map +1 -0
- package/package.json +83 -4
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { a as Verdict, F as Finding } from './guard-BVpq8ytG.js';
|
|
2
|
+
export { C as CONFIG_PATH, D as DEFAULT_API_URL, b as Decision, E as EVALUATE_PATH, c as Evaluator, d as FailMode, R as RuntimeApiEvaluator, e as RuntimeApiOptions, V as Vericto, f as VerictoLogger, g as VerictoOptions, i as isMasked, s as sqlToExecute, v as verdictFromResponse } from './guard-BVpq8ytG.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Dialects the Vericto engine evaluates (`sqlite` since vericto-engine 4.1.0). The
|
|
6
|
+
* wrappers still ask the server (`GET /api/v1/meta/config`) and refuse a dialect it
|
|
7
|
+
* does not list.
|
|
8
|
+
*/
|
|
9
|
+
declare const KNOWN_DIALECTS: readonly ["postgres", "mysql", "oracle", "mssql", "snowflake", "sqlite"];
|
|
10
|
+
/**
|
|
11
|
+
* Map a driver name to the Vericto dialect id. Unknown names pass through
|
|
12
|
+
* lower-cased: the server decides, and answers with a clear error.
|
|
13
|
+
*/
|
|
14
|
+
declare function normalizeDialect(name: string): string;
|
|
15
|
+
|
|
16
|
+
/** Base class of every error this package throws. */
|
|
17
|
+
declare class VerictoError extends Error {
|
|
18
|
+
constructor(message: string);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The client is misconfigured: missing or rejected API key, bad database id, a key
|
|
22
|
+
* without the `proxy:evaluate` scope, or a malformed request. Thrown whatever the
|
|
23
|
+
* fail mode is: failing open on a revoked key would switch the firewall off silently.
|
|
24
|
+
*/
|
|
25
|
+
declare class VerictoConfigError extends VerictoError {
|
|
26
|
+
readonly status: number | undefined;
|
|
27
|
+
readonly code: string | undefined;
|
|
28
|
+
constructor(message: string, options?: {
|
|
29
|
+
status?: number;
|
|
30
|
+
code?: string;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The Vericto server does not evaluate this dialect (it is missing from
|
|
35
|
+
* `GET /api/v1/meta/config`, e.g. `sqlite` on a server older than vericto-engine
|
|
36
|
+
* 4.1.0). No SQL was executed.
|
|
37
|
+
*/
|
|
38
|
+
declare class VerictoUnsupportedDialectError extends VerictoConfigError {
|
|
39
|
+
readonly dialect: string;
|
|
40
|
+
readonly supported: readonly string[];
|
|
41
|
+
constructor(dialect: string, supported: readonly string[], apiUrl: string);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Vericto could not return a verdict after the configured retries. With
|
|
45
|
+
* `failMode: 'closed'` (the default) the statement is not executed and this is thrown.
|
|
46
|
+
*/
|
|
47
|
+
declare class VerictoUnavailableError extends VerictoError {
|
|
48
|
+
readonly status: number | undefined;
|
|
49
|
+
readonly code: string | undefined;
|
|
50
|
+
constructor(message: string, options?: {
|
|
51
|
+
status?: number;
|
|
52
|
+
code?: string;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/** The workspace used its monthly query quota (HTTP 429 `QUOTA_EXCEEDED`). Not retried. */
|
|
56
|
+
declare class VerictoQuotaExceededError extends VerictoUnavailableError {
|
|
57
|
+
readonly resetsAt: string | undefined;
|
|
58
|
+
readonly upgradeUrl: string | undefined;
|
|
59
|
+
constructor(message: string, options?: {
|
|
60
|
+
resetsAt?: string;
|
|
61
|
+
upgradeUrl?: string;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/** Vericto blocked the statement. It was not executed. */
|
|
65
|
+
declare class VerictoBlockedError extends VerictoError {
|
|
66
|
+
readonly verdict: Verdict;
|
|
67
|
+
readonly sql: string;
|
|
68
|
+
constructor(verdict: Verdict, sql: string);
|
|
69
|
+
get findings(): readonly Finding[];
|
|
70
|
+
get suggestedFix(): string | undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** The package version (kept in sync with package.json by a test). */
|
|
74
|
+
declare const VERSION = "0.2.0";
|
|
75
|
+
|
|
76
|
+
export { Finding, KNOWN_DIALECTS, VERSION, Verdict, VerictoBlockedError, VerictoConfigError, VerictoError, VerictoQuotaExceededError, VerictoUnavailableError, VerictoUnsupportedDialectError, normalizeDialect };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { CONFIG_PATH, DEFAULT_API_URL, EVALUATE_PATH, KNOWN_DIALECTS, RuntimeApiEvaluator, VERSION, Vericto, VerictoBlockedError, VerictoConfigError, VerictoError, VerictoQuotaExceededError, VerictoUnavailableError, VerictoUnsupportedDialectError, isMasked, normalizeDialect, sqlToExecute, verdictFromResponse } from './chunk-I4I35HUY.js';
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkHFL7W4WC_cjs = require('./chunk-HFL7W4WC.cjs');
|
|
4
|
+
var sql$1 = require('@langchain/classic/agents/toolkits/sql');
|
|
5
|
+
var sql_db = require('@langchain/classic/sql_db');
|
|
6
|
+
var sql = require('@langchain/classic/tools/sql');
|
|
7
|
+
var tools = require('@langchain/core/tools');
|
|
8
|
+
|
|
9
|
+
var TYPEORM_DIALECTS = {
|
|
10
|
+
postgres: "postgres",
|
|
11
|
+
"aurora-postgres": "postgres",
|
|
12
|
+
mysql: "mysql",
|
|
13
|
+
mariadb: "mysql",
|
|
14
|
+
"aurora-mysql": "mysql",
|
|
15
|
+
mssql: "mssql",
|
|
16
|
+
oracle: "oracle",
|
|
17
|
+
sqlite: "sqlite",
|
|
18
|
+
"better-sqlite3": "sqlite",
|
|
19
|
+
sqljs: "sqlite"
|
|
20
|
+
};
|
|
21
|
+
function dialectFromDataSource(dataSource) {
|
|
22
|
+
const type = dataSource.options.type;
|
|
23
|
+
const dialect = TYPEORM_DIALECTS[type];
|
|
24
|
+
if (!dialect) {
|
|
25
|
+
throw new chunkHFL7W4WC_cjs.VerictoConfigError(
|
|
26
|
+
`vericto: no Vericto dialect for the TypeORM type '${type}'. Supported: ${Object.keys(TYPEORM_DIALECTS).join(", ")}; or pass { dialect }.`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return dialect;
|
|
30
|
+
}
|
|
31
|
+
function guardDataSource(dataSource, vericto, dialect) {
|
|
32
|
+
const name = chunkHFL7W4WC_cjs.normalizeDialect(dialect);
|
|
33
|
+
const query = async (sql, parameters, ...rest) => {
|
|
34
|
+
const final = await vericto.prepare(sql, name);
|
|
35
|
+
return dataSource.query.call(dataSource, final, parameters, ...rest);
|
|
36
|
+
};
|
|
37
|
+
return new Proxy(dataSource, {
|
|
38
|
+
get(target, prop) {
|
|
39
|
+
if (prop === "query") return query;
|
|
40
|
+
const value = Reflect.get(target, prop, target);
|
|
41
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function blockedMessage(verdict) {
|
|
46
|
+
const lines = ["Vericto blocked this SQL query; it was NOT executed."];
|
|
47
|
+
const rule = verdict.ruleCode ?? "a Vericto rule";
|
|
48
|
+
lines.push(`Rule: ${rule}${verdict.severity ? ` (severity ${verdict.severity})` : ""}`);
|
|
49
|
+
if (verdict.message) lines.push(`Reason: ${verdict.message}`);
|
|
50
|
+
const denied = verdict.accessDenied.length ? JSON.stringify(verdict.accessDenied) : void 0;
|
|
51
|
+
if (denied) lines.push(`Access denied: ${denied}`);
|
|
52
|
+
if (verdict.suggestedFix) {
|
|
53
|
+
lines.push(`Suggested fix: ${verdict.suggestedFix}`);
|
|
54
|
+
lines.push("Use the suggested fix, or rewrite the query so that it complies with the rule, and try again.");
|
|
55
|
+
} else {
|
|
56
|
+
lines.push("Rewrite the query so that it complies with the rule, and try again. Do not retry the same query.");
|
|
57
|
+
}
|
|
58
|
+
return lines.join("\n");
|
|
59
|
+
}
|
|
60
|
+
function describeVerdict(verdict) {
|
|
61
|
+
if (verdict.decision === "BLOCKED") return blockedMessage(verdict).replace("; it was NOT executed.", ".");
|
|
62
|
+
const rule = verdict.ruleCode ? ` by ${verdict.ruleCode}${verdict.severity ? ` (severity ${verdict.severity})` : ""}` : "";
|
|
63
|
+
let text;
|
|
64
|
+
switch (verdict.decision) {
|
|
65
|
+
case "FLAGGED":
|
|
66
|
+
text = `Vericto: FLAGGED${rule}. The query is allowed to run, but it was reported.`;
|
|
67
|
+
break;
|
|
68
|
+
case "MONITORED":
|
|
69
|
+
text = `Vericto: MONITORED${rule}. The query is allowed to run.`;
|
|
70
|
+
break;
|
|
71
|
+
case "PARSE_ERROR":
|
|
72
|
+
text = `Vericto could not parse the query${verdict.parseError ? ` (${verdict.parseError})` : ""}; the workspace policy allows it to run.`;
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
text = "Vericto: ALLOWED. The query can run.";
|
|
76
|
+
}
|
|
77
|
+
if (chunkHFL7W4WC_cjs.isMasked(verdict)) {
|
|
78
|
+
text += `
|
|
79
|
+
It reads sensitive columns, so it will run masked, as: ${chunkHFL7W4WC_cjs.sqlToExecute(verdict)}`;
|
|
80
|
+
}
|
|
81
|
+
return text;
|
|
82
|
+
}
|
|
83
|
+
function checkOnBlock(onBlock) {
|
|
84
|
+
const value = onBlock ?? "return";
|
|
85
|
+
if (value !== "return" && value !== "raise") {
|
|
86
|
+
throw new chunkHFL7W4WC_cjs.VerictoConfigError(`onBlock must be 'return' or 'raise', got ${JSON.stringify(value)}.`);
|
|
87
|
+
}
|
|
88
|
+
return value;
|
|
89
|
+
}
|
|
90
|
+
var VerictoSqlDatabase = class _VerictoSqlDatabase extends sql_db.SqlDatabase {
|
|
91
|
+
vericto;
|
|
92
|
+
dialect;
|
|
93
|
+
onBlock;
|
|
94
|
+
/** The unguarded data source: SQL run through it directly is not checked. */
|
|
95
|
+
rawDataSource;
|
|
96
|
+
constructor(fields) {
|
|
97
|
+
super(fields);
|
|
98
|
+
this.vericto = fields.vericto;
|
|
99
|
+
this.dialect = fields.dialect;
|
|
100
|
+
this.onBlock = checkOnBlock(fields.onBlock);
|
|
101
|
+
this.rawDataSource = fields.appDataSource;
|
|
102
|
+
this.appDataSource = guardDataSource(fields.appDataSource, this.vericto, this.dialect);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Same as `SqlDatabase.fromDataSourceParams`, plus the Vericto options. Fails fast
|
|
106
|
+
* when the server does not evaluate the dialect. LangChain's own schema
|
|
107
|
+
* introspection (the column catalogue read here) runs on the raw data source.
|
|
108
|
+
*/
|
|
109
|
+
static async fromDataSourceParams(fields) {
|
|
110
|
+
const vericto = fields.vericto ?? new chunkHFL7W4WC_cjs.Vericto();
|
|
111
|
+
const dialect = await vericto.requireDialect(fields.dialect ?? dialectFromDataSource(fields.appDataSource));
|
|
112
|
+
checkOnBlock(fields.onBlock);
|
|
113
|
+
const base = await sql_db.SqlDatabase.fromDataSourceParams(fields);
|
|
114
|
+
const db = new _VerictoSqlDatabase({ ...fields, vericto, dialect });
|
|
115
|
+
db.allTables = base.allTables;
|
|
116
|
+
db.customDescription = base.customDescription;
|
|
117
|
+
return db;
|
|
118
|
+
}
|
|
119
|
+
/** Same as `SqlDatabase.fromOptionsParams`, plus the Vericto options. */
|
|
120
|
+
static async fromOptionsParams(fields) {
|
|
121
|
+
const { DataSource } = await sql_db.SqlDatabase.imports();
|
|
122
|
+
const { appDataSourceOptions, ...rest } = fields;
|
|
123
|
+
return _VerictoSqlDatabase.fromDataSourceParams({ ...rest, appDataSource: new DataSource(appDataSourceOptions) });
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Run `command` after Vericto checks it. Blocked: returns {@link blockedMessage}
|
|
127
|
+
* (or throws `VerictoBlockedError` with `onBlock: 'raise'`). Masked: runs the
|
|
128
|
+
* rewrite. Vericto unavailable or misconfigured: throws.
|
|
129
|
+
*/
|
|
130
|
+
async run(command, fetch = "all") {
|
|
131
|
+
try {
|
|
132
|
+
return await super.run(command, fetch);
|
|
133
|
+
} catch (err) {
|
|
134
|
+
if (err instanceof chunkHFL7W4WC_cjs.VerictoBlockedError && this.onBlock === "return") return blockedMessage(err.verdict);
|
|
135
|
+
throw err;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
var VerictoQuerySqlTool = class extends sql.QuerySqlTool {
|
|
140
|
+
static lc_name() {
|
|
141
|
+
return "VerictoQuerySqlTool";
|
|
142
|
+
}
|
|
143
|
+
/** @ignore */
|
|
144
|
+
async _call(input) {
|
|
145
|
+
try {
|
|
146
|
+
return await this.db.run(input);
|
|
147
|
+
} catch (err) {
|
|
148
|
+
if (err instanceof chunkHFL7W4WC_cjs.VerictoError) throw err;
|
|
149
|
+
return String(err);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
var VerictoSqlToolkit = class extends sql$1.SqlToolkit {
|
|
154
|
+
constructor(db, llm) {
|
|
155
|
+
super(db, llm);
|
|
156
|
+
this.tools = this.tools.map((tool) => tool instanceof sql.QuerySqlTool ? new VerictoQuerySqlTool(db) : tool);
|
|
157
|
+
this.dialect = db.dialect;
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
var VerictoCheckSqlTool = class extends tools.Tool {
|
|
161
|
+
static lc_name() {
|
|
162
|
+
return "VerictoCheckSqlTool";
|
|
163
|
+
}
|
|
164
|
+
name = "vericto-check-sql";
|
|
165
|
+
description = "Input is one SQL query. Checks it with the Vericto SQL firewall without running it and returns the verdict: ALLOWED, FLAGGED, MONITORED, or BLOCKED with the rule and a suggested fix. Use it before running a query; if it is blocked, fix the query and check again.";
|
|
166
|
+
vericto;
|
|
167
|
+
dialect;
|
|
168
|
+
onBlock;
|
|
169
|
+
constructor(options = {}) {
|
|
170
|
+
super();
|
|
171
|
+
const vericto = options.vericto ?? options.db?.vericto;
|
|
172
|
+
const dialect = options.dialect ?? options.db?.dialect;
|
|
173
|
+
if (!dialect) throw new chunkHFL7W4WC_cjs.VerictoConfigError("VerictoCheckSqlTool needs { dialect } or { db }.");
|
|
174
|
+
this.vericto = vericto ?? new chunkHFL7W4WC_cjs.Vericto();
|
|
175
|
+
this.dialect = chunkHFL7W4WC_cjs.normalizeDialect(dialect);
|
|
176
|
+
this.onBlock = checkOnBlock(options.onBlock ?? options.db?.onBlock);
|
|
177
|
+
}
|
|
178
|
+
/** @ignore */
|
|
179
|
+
async _call(input) {
|
|
180
|
+
const verdict = await this.vericto.check(input, this.dialect);
|
|
181
|
+
if (verdict.decision === "BLOCKED" && this.onBlock === "raise") throw new chunkHFL7W4WC_cjs.VerictoBlockedError(verdict, input);
|
|
182
|
+
return describeVerdict(verdict);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
exports.VerictoCheckSqlTool = VerictoCheckSqlTool;
|
|
187
|
+
exports.VerictoQuerySqlTool = VerictoQuerySqlTool;
|
|
188
|
+
exports.VerictoSqlDatabase = VerictoSqlDatabase;
|
|
189
|
+
exports.VerictoSqlToolkit = VerictoSqlToolkit;
|
|
190
|
+
exports.blockedMessage = blockedMessage;
|
|
191
|
+
exports.describeVerdict = describeVerdict;
|
|
192
|
+
exports.dialectFromDataSource = dialectFromDataSource;
|
|
193
|
+
exports.guardDataSource = guardDataSource;
|
|
194
|
+
//# sourceMappingURL=langchain.cjs.map
|
|
195
|
+
//# sourceMappingURL=langchain.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/langchain.ts"],"names":["VerictoConfigError","normalizeDialect","isMasked","sqlToExecute","SqlDatabase","Vericto","VerictoBlockedError","QuerySqlTool","VerictoError","SqlToolkit","Tool"],"mappings":";;;;;;;;AAkDA,IAAM,gBAAA,GAAqD;AAAA,EACzD,QAAA,EAAU,UAAA;AAAA,EACV,iBAAA,EAAmB,UAAA;AAAA,EACnB,KAAA,EAAO,OAAA;AAAA,EACP,OAAA,EAAS,OAAA;AAAA,EACT,cAAA,EAAgB,OAAA;AAAA,EAChB,KAAA,EAAO,OAAA;AAAA,EACP,MAAA,EAAQ,QAAA;AAAA,EACR,MAAA,EAAQ,QAAA;AAAA,EACR,gBAAA,EAAkB,QAAA;AAAA,EAClB,KAAA,EAAO;AACT,CAAA;AAOO,SAAS,sBAAsB,UAAA,EAAiD;AACrF,EAAA,MAAM,IAAA,GAAe,WAAW,OAAA,CAAQ,IAAA;AACxC,EAAA,MAAM,OAAA,GAAU,iBAAiB,IAAI,CAAA;AACrC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAIA,oCAAA;AAAA,MACR,CAAA,kDAAA,EAAqD,IAAI,CAAA,cAAA,EACzC,MAAA,CAAO,KAAK,gBAAgB,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,sBAAA;AAAA,KAC1D;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AAMO,SAAS,eAAA,CAAgB,UAAA,EAAwB,OAAA,EAAkB,OAAA,EAA6B;AACrG,EAAA,MAAM,IAAA,GAAOC,mCAAiB,OAAO,CAAA;AACrC,EAAA,MAAM,KAAA,GAAQ,OAAO,GAAA,EAAa,UAAA,EAAA,GAA2B,IAAA,KAAsC;AACjG,IAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,OAAA,CAAQ,KAAK,IAAI,CAAA;AAC7C,IAAA,OAAQ,WAAW,KAAA,CAAmD,IAAA,CAAK,YAAY,KAAA,EAAO,UAAA,EAAY,GAAG,IAAI,CAAA;AAAA,EACnH,CAAA;AACA,EAAA,OAAO,IAAI,MAAM,UAAA,EAAY;AAAA,IAC3B,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,SAAS,OAAO,KAAA;AAC7B,MAAA,MAAM,KAAA,GAAiB,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,MAAM,MAAM,CAAA;AACvD,MAAA,OAAO,OAAO,KAAA,KAAU,UAAA,GAAc,KAAA,CAAuC,IAAA,CAAK,MAAM,CAAA,GAAI,KAAA;AAAA,IAC9F;AAAA,GACD,CAAA;AACH;AAGO,SAAS,eAAe,OAAA,EAA0B;AACvD,EAAA,MAAM,KAAA,GAAQ,CAAC,sDAAsD,CAAA;AACrE,EAAA,MAAM,IAAA,GAAO,QAAQ,QAAA,IAAY,gBAAA;AACjC,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,MAAA,EAAS,IAAI,CAAA,EAAG,OAAA,CAAQ,QAAA,GAAW,CAAA,WAAA,EAAc,OAAA,CAAQ,QAAQ,CAAA,CAAA,CAAA,GAAM,EAAE,CAAA,CAAE,CAAA;AACtF,EAAA,IAAI,QAAQ,OAAA,EAAS,KAAA,CAAM,KAAK,CAAA,QAAA,EAAW,OAAA,CAAQ,OAAO,CAAA,CAAE,CAAA;AAC5D,EAAA,MAAM,MAAA,GAAS,QAAQ,YAAA,CAAa,MAAA,GAAS,KAAK,SAAA,CAAU,OAAA,CAAQ,YAAY,CAAA,GAAI,MAAA;AACpF,EAAA,IAAI,MAAA,EAAQ,KAAA,CAAM,IAAA,CAAK,CAAA,eAAA,EAAkB,MAAM,CAAA,CAAE,CAAA;AACjD,EAAA,IAAI,QAAQ,YAAA,EAAc;AACxB,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,eAAA,EAAkB,OAAA,CAAQ,YAAY,CAAA,CAAE,CAAA;AACnD,IAAA,KAAA,CAAM,KAAK,+FAA+F,CAAA;AAAA,EAC5G,CAAA,MAAO;AACL,IAAA,KAAA,CAAM,KAAK,kGAAkG,CAAA;AAAA,EAC/G;AACA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;AAGO,SAAS,gBAAgB,OAAA,EAA0B;AACxD,EAAA,IAAI,OAAA,CAAQ,aAAa,SAAA,EAAW,OAAO,eAAe,OAAO,CAAA,CAAE,OAAA,CAAQ,wBAAA,EAA0B,GAAG,CAAA;AACxG,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,QAAA,GAAW,CAAA,IAAA,EAAO,QAAQ,QAAQ,CAAA,EAAG,OAAA,CAAQ,QAAA,GAAW,CAAA,WAAA,EAAc,OAAA,CAAQ,QAAQ,CAAA,CAAA,CAAA,GAAM,EAAE,CAAA,CAAA,GAAK,EAAA;AACxH,EAAA,IAAI,IAAA;AACJ,EAAA,QAAQ,QAAQ,QAAA;AAAU,IACxB,KAAK,SAAA;AACH,MAAA,IAAA,GAAO,mBAAmB,IAAI,CAAA,mDAAA,CAAA;AAC9B,MAAA;AAAA,IACF,KAAK,WAAA;AACH,MAAA,IAAA,GAAO,qBAAqB,IAAI,CAAA,8BAAA,CAAA;AAChC,MAAA;AAAA,IACF,KAAK,aAAA;AACH,MAAA,IAAA,GAAO,oCAAoC,OAAA,CAAQ,UAAA,GAAa,KAAK,OAAA,CAAQ,UAAU,MAAM,EAAE,CAAA,wCAAA,CAAA;AAC/F,MAAA;AAAA,IACF;AACE,MAAA,IAAA,GAAO,sCAAA;AAAA;AAEX,EAAA,IAAIC,0BAAA,CAAS,OAAO,CAAA,EAAG;AACrB,IAAA,IAAA,IAAQ;AAAA,uDAAA,EAA4DC,8BAAA,CAAa,OAAO,CAAC,CAAA,CAAA;AAAA,EAC3F;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,aAAa,OAAA,EAAuC;AAE3D,EAAA,MAAM,QAAgB,OAAA,IAAW,QAAA;AACjC,EAAA,IAAI,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,OAAA,EAAS;AAC3C,IAAA,MAAM,IAAIH,oCAAA,CAAmB,CAAA,yCAAA,EAA4C,KAAK,SAAA,CAAU,KAAK,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,EACnG;AACA,EAAA,OAAO,KAAA;AACT;AAOO,IAAM,kBAAA,GAAN,MAAM,mBAAA,SAA2BI,kBAAA,CAAY;AAAA,EACzC,OAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA;AAAA,EAEA,aAAA;AAAA,EAEC,YAAY,MAAA,EAA0E;AAC9F,IAAA,KAAA,CAAM,MAAM,CAAA;AACZ,IAAA,IAAA,CAAK,UAAU,MAAA,CAAO,OAAA;AACtB,IAAA,IAAA,CAAK,UAAU,MAAA,CAAO,OAAA;AACtB,IAAA,IAAA,CAAK,OAAA,GAAU,YAAA,CAAa,MAAA,CAAO,OAAO,CAAA;AAC1C,IAAA,IAAA,CAAK,gBAAgB,MAAA,CAAO,aAAA;AAC5B,IAAA,IAAA,CAAK,gBAAgB,eAAA,CAAgB,MAAA,CAAO,eAAe,IAAA,CAAK,OAAA,EAAS,KAAK,OAAO,CAAA;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAsB,qBAAqB,MAAA,EAA+D;AACxG,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,IAAW,IAAIC,yBAAA,EAAQ;AAC9C,IAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,cAAA,CAAe,OAAO,OAAA,IAAW,qBAAA,CAAsB,MAAA,CAAO,aAAa,CAAC,CAAA;AAC1G,IAAA,YAAA,CAAa,OAAO,OAAO,CAAA;AAC3B,IAAA,MAAM,IAAA,GAAO,MAAMD,kBAAA,CAAY,oBAAA,CAAqB,MAAM,CAAA;AAC1D,IAAA,MAAM,EAAA,GAAK,IAAI,mBAAA,CAAmB,EAAE,GAAG,MAAA,EAAQ,OAAA,EAAS,SAAS,CAAA;AACjE,IAAA,EAAA,CAAG,YAAY,IAAA,CAAK,SAAA;AACpB,IAAA,EAAA,CAAG,oBAAoB,IAAA,CAAK,iBAAA;AAC5B,IAAA,OAAO,EAAA;AAAA,EACT;AAAA;AAAA,EAGA,aAAsB,kBACpB,MAAA,EAC6B;AAC7B,IAAA,MAAM,EAAE,UAAA,EAAW,GAAI,MAAMA,mBAAY,OAAA,EAAQ;AACjD,IAAA,MAAM,EAAE,oBAAA,EAAsB,GAAG,IAAA,EAAK,GAAI,MAAA;AAC1C,IAAA,OAAO,mBAAA,CAAmB,oBAAA,CAAqB,EAAE,GAAG,IAAA,EAAM,eAAe,IAAI,UAAA,CAAW,oBAAoB,CAAA,EAAG,CAAA;AAAA,EACjH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAe,GAAA,CAAI,OAAA,EAAiB,KAAA,GAAuB,KAAA,EAAwB;AACjF,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,KAAA,CAAM,GAAA,CAAI,OAAA,EAAS,KAAK,CAAA;AAAA,IACvC,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,GAAA,YAAeE,yCAAuB,IAAA,CAAK,OAAA,KAAY,UAAU,OAAO,cAAA,CAAe,IAAI,OAAO,CAAA;AACtG,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AACF;AAOO,IAAM,mBAAA,GAAN,cAAkCC,gBAAA,CAAa;AAAA,EACpD,OAAgB,OAAA,GAAkB;AAChC,IAAA,OAAO,qBAAA;AAAA,EACT;AAAA;AAAA,EAGA,MAAe,MAAM,KAAA,EAAgC;AACnD,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,CAAK,EAAA,CAAG,GAAA,CAAI,KAAK,CAAA;AAAA,IAChC,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,GAAA,YAAeC,gCAAc,MAAM,GAAA;AACvC,MAAA,OAAO,OAAO,GAAG,CAAA;AAAA,IACnB;AAAA,EACF;AACF;AAGO,IAAM,iBAAA,GAAN,cAAgCC,gBAAA,CAAW;AAAA,EAChD,WAAA,CAAY,IAAwB,GAAA,EAAiC;AACnE,IAAA,KAAA,CAAM,IAAI,GAAG,CAAA;AACb,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAU,IAAA,YAAgBF,gBAAA,GAAe,IAAI,mBAAA,CAAoB,EAAE,CAAA,GAAI,IAAK,CAAA;AACzG,IAAA,IAAA,CAAK,UAAU,EAAA,CAAG,OAAA;AAAA,EACpB;AACF;AAYO,IAAM,mBAAA,GAAN,cAAkCG,UAAA,CAAK;AAAA,EAC5C,OAAgB,OAAA,GAAkB;AAChC,IAAA,OAAO,qBAAA;AAAA,EACT;AAAA,EAEA,IAAA,GAAO,mBAAA;AAAA,EACP,WAAA,GACE,wQAAA;AAAA,EAIO,OAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EAET,WAAA,CAAY,OAAA,GAAsC,EAAC,EAAG;AACpD,IAAA,KAAA,EAAM;AACN,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,IAAW,OAAA,CAAQ,EAAA,EAAI,OAAA;AAC/C,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,IAAW,OAAA,CAAQ,EAAA,EAAI,OAAA;AAC/C,IAAA,IAAI,CAAC,OAAA,EAAS,MAAM,IAAIV,qCAAmB,kDAAkD,CAAA;AAC7F,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA,IAAW,IAAIK,yBAAA,EAAQ;AACtC,IAAA,IAAA,CAAK,OAAA,GAAUJ,mCAAiB,OAAO,CAAA;AACvC,IAAA,IAAA,CAAK,UAAU,YAAA,CAAa,OAAA,CAAQ,OAAA,IAAW,OAAA,CAAQ,IAAI,OAAO,CAAA;AAAA,EACpE;AAAA;AAAA,EAGA,MAAM,MAAM,KAAA,EAAgC;AAC1C,IAAA,MAAM,UAAU,MAAM,IAAA,CAAK,QAAQ,KAAA,CAAM,KAAA,EAAO,KAAK,OAAO,CAAA;AAC5D,IAAA,IAAI,OAAA,CAAQ,QAAA,KAAa,SAAA,IAAa,IAAA,CAAK,OAAA,KAAY,SAAS,MAAM,IAAIK,qCAAA,CAAoB,OAAA,EAAS,KAAK,CAAA;AAC5G,IAAA,OAAO,gBAAgB,OAAO,CAAA;AAAA,EAChC;AACF","file":"langchain.cjs","sourcesContent":["/**\n * Vericto for LangChain.js SQL agents and chains (`@langchain/classic`).\n *\n * ```ts\n * import { DataSource } from 'typeorm';\n * import { VerictoSqlDatabase, VerictoSqlToolkit } from '@vericto/sdk/langchain';\n * import { createSqlAgent } from '@langchain/classic/agents/toolkits/sql';\n *\n * const db = await VerictoSqlDatabase.fromDataSourceParams({\n * appDataSource: new DataSource({ type: 'postgres', url: process.env.DATABASE_URL }),\n * });\n * const agent = createSqlAgent(llm, new VerictoSqlToolkit(db, llm));\n * ```\n *\n * Every statement LangChain sends through the database's TypeORM `DataSource` is\n * checked: the agent's queries (`run`, `QuerySqlTool`), the sample rows of\n * `getTableInfo`, and `SqlDatabaseChain`'s generated SQL. A blocked query is\n * answered with a message the model can act on (rule, reason, suggested fix)\n * instead of an exception, unless `onBlock: 'raise'`. Masked queries run as the\n * rewrite. Vericto being unavailable or misconfigured is never turned into a message\n * for the model: it propagates, so the fail mode stays in charge.\n *\n * Requires the optional peers `@langchain/classic`, `@langchain/core` and `typeorm`.\n */\nimport { SqlToolkit } from '@langchain/classic/agents/toolkits/sql';\nimport { SqlDatabase, type SqlDatabaseDataSourceParams } from '@langchain/classic/sql_db';\nimport { QuerySqlTool } from '@langchain/classic/tools/sql';\nimport type { BaseLanguageModelInterface } from '@langchain/core/language_models/base';\nimport { Tool } from '@langchain/core/tools';\nimport type { DataSource } from 'typeorm';\n\nimport { normalizeDialect } from './dialects.js';\nimport { VerictoBlockedError, VerictoConfigError, VerictoError } from './errors.js';\nimport { Vericto } from './guard.js';\nimport { isMasked, sqlToExecute, type Verdict } from './verdict.js';\n\n/** What a blocked query does: `return` a message for the model (default), or `raise`. */\nexport type OnBlock = 'return' | 'raise';\n\nexport interface VerictoLangChainOptions {\n /** The guard. Default: one built from the `VERICTO_*` environment variables. */\n vericto?: Vericto;\n /** The Vericto dialect. Default: read from the TypeORM `DataSource` type. */\n dialect?: string;\n /** Default `return`. */\n onBlock?: OnBlock;\n}\n\nexport type VerictoSqlDatabaseParams = SqlDatabaseDataSourceParams & VerictoLangChainOptions;\n\nconst TYPEORM_DIALECTS: Readonly<Record<string, string>> = {\n postgres: 'postgres',\n 'aurora-postgres': 'postgres',\n mysql: 'mysql',\n mariadb: 'mysql',\n 'aurora-mysql': 'mysql',\n mssql: 'mssql',\n oracle: 'oracle',\n sqlite: 'sqlite',\n 'better-sqlite3': 'sqlite',\n sqljs: 'sqlite',\n};\n\n/**\n * The Vericto dialect of a TypeORM `DataSource` type. Types Vericto does not\n * evaluate (cockroachdb, sap, spanner, mongodb...) throw `VerictoConfigError`: pass\n * `dialect` explicitly if you know what you are doing.\n */\nexport function dialectFromDataSource(dataSource: Pick<DataSource, 'options'>): string {\n const type: string = dataSource.options.type;\n const dialect = TYPEORM_DIALECTS[type];\n if (!dialect) {\n throw new VerictoConfigError(\n `vericto: no Vericto dialect for the TypeORM type '${type}'. ` +\n `Supported: ${Object.keys(TYPEORM_DIALECTS).join(', ')}; or pass { dialect }.`,\n );\n }\n return dialect;\n}\n\n/**\n * A `DataSource` whose `query()` is checked by Vericto first (and runs the masked\n * rewrite). Everything else is the original data source's.\n */\nexport function guardDataSource(dataSource: DataSource, vericto: Vericto, dialect: string): DataSource {\n const name = normalizeDialect(dialect);\n const query = async (sql: string, parameters?: unknown[], ...rest: unknown[]): Promise<unknown> => {\n const final = await vericto.prepare(sql, name);\n return (dataSource.query as (...args: unknown[]) => Promise<unknown>).call(dataSource, final, parameters, ...rest);\n };\n return new Proxy(dataSource, {\n get(target, prop) {\n if (prop === 'query') return query;\n const value: unknown = Reflect.get(target, prop, target);\n return typeof value === 'function' ? (value as (...a: unknown[]) => unknown).bind(target) : value;\n },\n });\n}\n\n/** The message a model gets for a blocked query: what was blocked, why, and the fix. */\nexport function blockedMessage(verdict: Verdict): string {\n const lines = ['Vericto blocked this SQL query; it was NOT executed.'];\n const rule = verdict.ruleCode ?? 'a Vericto rule';\n lines.push(`Rule: ${rule}${verdict.severity ? ` (severity ${verdict.severity})` : ''}`);\n if (verdict.message) lines.push(`Reason: ${verdict.message}`);\n const denied = verdict.accessDenied.length ? JSON.stringify(verdict.accessDenied) : undefined;\n if (denied) lines.push(`Access denied: ${denied}`);\n if (verdict.suggestedFix) {\n lines.push(`Suggested fix: ${verdict.suggestedFix}`);\n lines.push('Use the suggested fix, or rewrite the query so that it complies with the rule, and try again.');\n } else {\n lines.push('Rewrite the query so that it complies with the rule, and try again. Do not retry the same query.');\n }\n return lines.join('\\n');\n}\n\n/** A readable verdict for the check tool. */\nexport function describeVerdict(verdict: Verdict): string {\n if (verdict.decision === 'BLOCKED') return blockedMessage(verdict).replace('; it was NOT executed.', '.');\n const rule = verdict.ruleCode ? ` by ${verdict.ruleCode}${verdict.severity ? ` (severity ${verdict.severity})` : ''}` : '';\n let text: string;\n switch (verdict.decision) {\n case 'FLAGGED':\n text = `Vericto: FLAGGED${rule}. The query is allowed to run, but it was reported.`;\n break;\n case 'MONITORED':\n text = `Vericto: MONITORED${rule}. The query is allowed to run.`;\n break;\n case 'PARSE_ERROR':\n text = `Vericto could not parse the query${verdict.parseError ? ` (${verdict.parseError})` : ''}; the workspace policy allows it to run.`;\n break;\n default:\n text = 'Vericto: ALLOWED. The query can run.';\n }\n if (isMasked(verdict)) {\n text += `\\nIt reads sensitive columns, so it will run masked, as: ${sqlToExecute(verdict)}`;\n }\n return text;\n}\n\nfunction checkOnBlock(onBlock: OnBlock | undefined): OnBlock {\n // Checked at run time too: plain-JS callers get no type error.\n const value: string = onBlock ?? 'return';\n if (value !== 'return' && value !== 'raise') {\n throw new VerictoConfigError(`onBlock must be 'return' or 'raise', got ${JSON.stringify(value)}.`);\n }\n return value;\n}\n\n/**\n * A LangChain `SqlDatabase` whose statements are checked by Vericto. Accepted\n * wherever a `SqlDatabase` is: `QuerySqlTool`, `SqlToolkit`/`createSqlAgent`,\n * `SqlDatabaseChain`.\n */\nexport class VerictoSqlDatabase extends SqlDatabase {\n readonly vericto: Vericto;\n readonly dialect: string;\n readonly onBlock: OnBlock;\n /** The unguarded data source: SQL run through it directly is not checked. */\n readonly rawDataSource: DataSource;\n\n protected constructor(fields: VerictoSqlDatabaseParams & { vericto: Vericto; dialect: string }) {\n super(fields);\n this.vericto = fields.vericto;\n this.dialect = fields.dialect;\n this.onBlock = checkOnBlock(fields.onBlock);\n this.rawDataSource = fields.appDataSource;\n this.appDataSource = guardDataSource(fields.appDataSource, this.vericto, this.dialect);\n }\n\n /**\n * Same as `SqlDatabase.fromDataSourceParams`, plus the Vericto options. Fails fast\n * when the server does not evaluate the dialect. LangChain's own schema\n * introspection (the column catalogue read here) runs on the raw data source.\n */\n static override async fromDataSourceParams(fields: VerictoSqlDatabaseParams): Promise<VerictoSqlDatabase> {\n const vericto = fields.vericto ?? new Vericto();\n const dialect = await vericto.requireDialect(fields.dialect ?? dialectFromDataSource(fields.appDataSource));\n checkOnBlock(fields.onBlock);\n const base = await SqlDatabase.fromDataSourceParams(fields);\n const db = new VerictoSqlDatabase({ ...fields, vericto, dialect });\n db.allTables = base.allTables;\n db.customDescription = base.customDescription;\n return db;\n }\n\n /** Same as `SqlDatabase.fromOptionsParams`, plus the Vericto options. */\n static override async fromOptionsParams(\n fields: Parameters<typeof SqlDatabase.fromOptionsParams>[0] & VerictoLangChainOptions,\n ): Promise<VerictoSqlDatabase> {\n const { DataSource } = await SqlDatabase.imports();\n const { appDataSourceOptions, ...rest } = fields;\n return VerictoSqlDatabase.fromDataSourceParams({ ...rest, appDataSource: new DataSource(appDataSourceOptions) });\n }\n\n /**\n * Run `command` after Vericto checks it. Blocked: returns {@link blockedMessage}\n * (or throws `VerictoBlockedError` with `onBlock: 'raise'`). Masked: runs the\n * rewrite. Vericto unavailable or misconfigured: throws.\n */\n override async run(command: string, fetch: 'all' | 'one' = 'all'): Promise<string> {\n try {\n return await super.run(command, fetch);\n } catch (err) {\n if (err instanceof VerictoBlockedError && this.onBlock === 'return') return blockedMessage(err.verdict);\n throw err;\n }\n }\n}\n\n/**\n * `QuerySqlTool` that lets Vericto errors through. The stock tool turns every error\n * into text for the model, which would also hide \"Vericto unavailable\" (and, with\n * `onBlock: 'raise'`, the block) from your code.\n */\nexport class VerictoQuerySqlTool extends QuerySqlTool {\n static override lc_name(): string {\n return 'VerictoQuerySqlTool';\n }\n\n /** @ignore */\n override async _call(input: string): Promise<string> {\n try {\n return await this.db.run(input);\n } catch (err) {\n if (err instanceof VerictoError) throw err;\n return String(err);\n }\n }\n}\n\n/** `SqlToolkit` with {@link VerictoQuerySqlTool} and the Vericto dialect in the prompt. */\nexport class VerictoSqlToolkit extends SqlToolkit {\n constructor(db: VerictoSqlDatabase, llm: BaseLanguageModelInterface) {\n super(db, llm);\n this.tools = this.tools.map((tool) => (tool instanceof QuerySqlTool ? new VerictoQuerySqlTool(db) : tool));\n this.dialect = db.dialect;\n }\n}\n\nexport interface VerictoCheckSqlToolOptions extends VerictoLangChainOptions {\n /** Take the guard, dialect and onBlock from this database. */\n db?: VerictoSqlDatabase;\n}\n\n/**\n * A tool that only checks a query (nothing is executed) and answers with Vericto's\n * verdict, so an agent can validate SQL before it proposes or runs it. Each check is\n * a Runtime API evaluation (it counts against the runtime quota and is audited).\n */\nexport class VerictoCheckSqlTool extends Tool {\n static override lc_name(): string {\n return 'VerictoCheckSqlTool';\n }\n\n name = 'vericto-check-sql';\n description =\n 'Input is one SQL query. Checks it with the Vericto SQL firewall without running it and returns the ' +\n 'verdict: ALLOWED, FLAGGED, MONITORED, or BLOCKED with the rule and a suggested fix. ' +\n 'Use it before running a query; if it is blocked, fix the query and check again.';\n\n readonly vericto: Vericto;\n readonly dialect: string;\n readonly onBlock: OnBlock;\n\n constructor(options: VerictoCheckSqlToolOptions = {}) {\n super();\n const vericto = options.vericto ?? options.db?.vericto;\n const dialect = options.dialect ?? options.db?.dialect;\n if (!dialect) throw new VerictoConfigError('VerictoCheckSqlTool needs { dialect } or { db }.');\n this.vericto = vericto ?? new Vericto();\n this.dialect = normalizeDialect(dialect);\n this.onBlock = checkOnBlock(options.onBlock ?? options.db?.onBlock);\n }\n\n /** @ignore */\n async _call(input: string): Promise<string> {\n const verdict = await this.vericto.check(input, this.dialect);\n if (verdict.decision === 'BLOCKED' && this.onBlock === 'raise') throw new VerictoBlockedError(verdict, input);\n return describeVerdict(verdict);\n }\n}\n"]}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { SqlToolkit } from '@langchain/classic/agents/toolkits/sql';
|
|
2
|
+
import { SqlDatabase, SqlDatabaseDataSourceParams } from '@langchain/classic/sql_db';
|
|
3
|
+
import { QuerySqlTool } from '@langchain/classic/tools/sql';
|
|
4
|
+
import { BaseLanguageModelInterface } from '@langchain/core/language_models/base';
|
|
5
|
+
import { Tool } from '@langchain/core/tools';
|
|
6
|
+
import { DataSource } from 'typeorm';
|
|
7
|
+
import { Vericto, Verdict } from './index.cjs';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Vericto for LangChain.js SQL agents and chains (`@langchain/classic`).
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { DataSource } from 'typeorm';
|
|
14
|
+
* import { VerictoSqlDatabase, VerictoSqlToolkit } from '@vericto/sdk/langchain';
|
|
15
|
+
* import { createSqlAgent } from '@langchain/classic/agents/toolkits/sql';
|
|
16
|
+
*
|
|
17
|
+
* const db = await VerictoSqlDatabase.fromDataSourceParams({
|
|
18
|
+
* appDataSource: new DataSource({ type: 'postgres', url: process.env.DATABASE_URL }),
|
|
19
|
+
* });
|
|
20
|
+
* const agent = createSqlAgent(llm, new VerictoSqlToolkit(db, llm));
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* Every statement LangChain sends through the database's TypeORM `DataSource` is
|
|
24
|
+
* checked: the agent's queries (`run`, `QuerySqlTool`), the sample rows of
|
|
25
|
+
* `getTableInfo`, and `SqlDatabaseChain`'s generated SQL. A blocked query is
|
|
26
|
+
* answered with a message the model can act on (rule, reason, suggested fix)
|
|
27
|
+
* instead of an exception, unless `onBlock: 'raise'`. Masked queries run as the
|
|
28
|
+
* rewrite. Vericto being unavailable or misconfigured is never turned into a message
|
|
29
|
+
* for the model: it propagates, so the fail mode stays in charge.
|
|
30
|
+
*
|
|
31
|
+
* Requires the optional peers `@langchain/classic`, `@langchain/core` and `typeorm`.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/** What a blocked query does: `return` a message for the model (default), or `raise`. */
|
|
35
|
+
type OnBlock = 'return' | 'raise';
|
|
36
|
+
interface VerictoLangChainOptions {
|
|
37
|
+
/** The guard. Default: one built from the `VERICTO_*` environment variables. */
|
|
38
|
+
vericto?: Vericto;
|
|
39
|
+
/** The Vericto dialect. Default: read from the TypeORM `DataSource` type. */
|
|
40
|
+
dialect?: string;
|
|
41
|
+
/** Default `return`. */
|
|
42
|
+
onBlock?: OnBlock;
|
|
43
|
+
}
|
|
44
|
+
type VerictoSqlDatabaseParams = SqlDatabaseDataSourceParams & VerictoLangChainOptions;
|
|
45
|
+
/**
|
|
46
|
+
* The Vericto dialect of a TypeORM `DataSource` type. Types Vericto does not
|
|
47
|
+
* evaluate (cockroachdb, sap, spanner, mongodb...) throw `VerictoConfigError`: pass
|
|
48
|
+
* `dialect` explicitly if you know what you are doing.
|
|
49
|
+
*/
|
|
50
|
+
declare function dialectFromDataSource(dataSource: Pick<DataSource, 'options'>): string;
|
|
51
|
+
/**
|
|
52
|
+
* A `DataSource` whose `query()` is checked by Vericto first (and runs the masked
|
|
53
|
+
* rewrite). Everything else is the original data source's.
|
|
54
|
+
*/
|
|
55
|
+
declare function guardDataSource(dataSource: DataSource, vericto: Vericto, dialect: string): DataSource;
|
|
56
|
+
/** The message a model gets for a blocked query: what was blocked, why, and the fix. */
|
|
57
|
+
declare function blockedMessage(verdict: Verdict): string;
|
|
58
|
+
/** A readable verdict for the check tool. */
|
|
59
|
+
declare function describeVerdict(verdict: Verdict): string;
|
|
60
|
+
/**
|
|
61
|
+
* A LangChain `SqlDatabase` whose statements are checked by Vericto. Accepted
|
|
62
|
+
* wherever a `SqlDatabase` is: `QuerySqlTool`, `SqlToolkit`/`createSqlAgent`,
|
|
63
|
+
* `SqlDatabaseChain`.
|
|
64
|
+
*/
|
|
65
|
+
declare class VerictoSqlDatabase extends SqlDatabase {
|
|
66
|
+
readonly vericto: Vericto;
|
|
67
|
+
readonly dialect: string;
|
|
68
|
+
readonly onBlock: OnBlock;
|
|
69
|
+
/** The unguarded data source: SQL run through it directly is not checked. */
|
|
70
|
+
readonly rawDataSource: DataSource;
|
|
71
|
+
protected constructor(fields: VerictoSqlDatabaseParams & {
|
|
72
|
+
vericto: Vericto;
|
|
73
|
+
dialect: string;
|
|
74
|
+
});
|
|
75
|
+
/**
|
|
76
|
+
* Same as `SqlDatabase.fromDataSourceParams`, plus the Vericto options. Fails fast
|
|
77
|
+
* when the server does not evaluate the dialect. LangChain's own schema
|
|
78
|
+
* introspection (the column catalogue read here) runs on the raw data source.
|
|
79
|
+
*/
|
|
80
|
+
static fromDataSourceParams(fields: VerictoSqlDatabaseParams): Promise<VerictoSqlDatabase>;
|
|
81
|
+
/** Same as `SqlDatabase.fromOptionsParams`, plus the Vericto options. */
|
|
82
|
+
static fromOptionsParams(fields: Parameters<typeof SqlDatabase.fromOptionsParams>[0] & VerictoLangChainOptions): Promise<VerictoSqlDatabase>;
|
|
83
|
+
/**
|
|
84
|
+
* Run `command` after Vericto checks it. Blocked: returns {@link blockedMessage}
|
|
85
|
+
* (or throws `VerictoBlockedError` with `onBlock: 'raise'`). Masked: runs the
|
|
86
|
+
* rewrite. Vericto unavailable or misconfigured: throws.
|
|
87
|
+
*/
|
|
88
|
+
run(command: string, fetch?: 'all' | 'one'): Promise<string>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* `QuerySqlTool` that lets Vericto errors through. The stock tool turns every error
|
|
92
|
+
* into text for the model, which would also hide "Vericto unavailable" (and, with
|
|
93
|
+
* `onBlock: 'raise'`, the block) from your code.
|
|
94
|
+
*/
|
|
95
|
+
declare class VerictoQuerySqlTool extends QuerySqlTool {
|
|
96
|
+
static lc_name(): string;
|
|
97
|
+
/** @ignore */
|
|
98
|
+
_call(input: string): Promise<string>;
|
|
99
|
+
}
|
|
100
|
+
/** `SqlToolkit` with {@link VerictoQuerySqlTool} and the Vericto dialect in the prompt. */
|
|
101
|
+
declare class VerictoSqlToolkit extends SqlToolkit {
|
|
102
|
+
constructor(db: VerictoSqlDatabase, llm: BaseLanguageModelInterface);
|
|
103
|
+
}
|
|
104
|
+
interface VerictoCheckSqlToolOptions extends VerictoLangChainOptions {
|
|
105
|
+
/** Take the guard, dialect and onBlock from this database. */
|
|
106
|
+
db?: VerictoSqlDatabase;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* A tool that only checks a query (nothing is executed) and answers with Vericto's
|
|
110
|
+
* verdict, so an agent can validate SQL before it proposes or runs it. Each check is
|
|
111
|
+
* a Runtime API evaluation (it counts against the runtime quota and is audited).
|
|
112
|
+
*/
|
|
113
|
+
declare class VerictoCheckSqlTool extends Tool {
|
|
114
|
+
static lc_name(): string;
|
|
115
|
+
name: string;
|
|
116
|
+
description: string;
|
|
117
|
+
readonly vericto: Vericto;
|
|
118
|
+
readonly dialect: string;
|
|
119
|
+
readonly onBlock: OnBlock;
|
|
120
|
+
constructor(options?: VerictoCheckSqlToolOptions);
|
|
121
|
+
/** @ignore */
|
|
122
|
+
_call(input: string): Promise<string>;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export { VerictoCheckSqlTool, VerictoQuerySqlTool, VerictoSqlDatabase, VerictoSqlToolkit, blockedMessage, describeVerdict, dialectFromDataSource, guardDataSource };
|
|
126
|
+
export type { OnBlock, VerictoCheckSqlToolOptions, VerictoLangChainOptions, VerictoSqlDatabaseParams };
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { SqlToolkit } from '@langchain/classic/agents/toolkits/sql';
|
|
2
|
+
import { SqlDatabase, SqlDatabaseDataSourceParams } from '@langchain/classic/sql_db';
|
|
3
|
+
import { QuerySqlTool } from '@langchain/classic/tools/sql';
|
|
4
|
+
import { BaseLanguageModelInterface } from '@langchain/core/language_models/base';
|
|
5
|
+
import { Tool } from '@langchain/core/tools';
|
|
6
|
+
import { DataSource } from 'typeorm';
|
|
7
|
+
import { Vericto, Verdict } from './index.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Vericto for LangChain.js SQL agents and chains (`@langchain/classic`).
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { DataSource } from 'typeorm';
|
|
14
|
+
* import { VerictoSqlDatabase, VerictoSqlToolkit } from '@vericto/sdk/langchain';
|
|
15
|
+
* import { createSqlAgent } from '@langchain/classic/agents/toolkits/sql';
|
|
16
|
+
*
|
|
17
|
+
* const db = await VerictoSqlDatabase.fromDataSourceParams({
|
|
18
|
+
* appDataSource: new DataSource({ type: 'postgres', url: process.env.DATABASE_URL }),
|
|
19
|
+
* });
|
|
20
|
+
* const agent = createSqlAgent(llm, new VerictoSqlToolkit(db, llm));
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* Every statement LangChain sends through the database's TypeORM `DataSource` is
|
|
24
|
+
* checked: the agent's queries (`run`, `QuerySqlTool`), the sample rows of
|
|
25
|
+
* `getTableInfo`, and `SqlDatabaseChain`'s generated SQL. A blocked query is
|
|
26
|
+
* answered with a message the model can act on (rule, reason, suggested fix)
|
|
27
|
+
* instead of an exception, unless `onBlock: 'raise'`. Masked queries run as the
|
|
28
|
+
* rewrite. Vericto being unavailable or misconfigured is never turned into a message
|
|
29
|
+
* for the model: it propagates, so the fail mode stays in charge.
|
|
30
|
+
*
|
|
31
|
+
* Requires the optional peers `@langchain/classic`, `@langchain/core` and `typeorm`.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/** What a blocked query does: `return` a message for the model (default), or `raise`. */
|
|
35
|
+
type OnBlock = 'return' | 'raise';
|
|
36
|
+
interface VerictoLangChainOptions {
|
|
37
|
+
/** The guard. Default: one built from the `VERICTO_*` environment variables. */
|
|
38
|
+
vericto?: Vericto;
|
|
39
|
+
/** The Vericto dialect. Default: read from the TypeORM `DataSource` type. */
|
|
40
|
+
dialect?: string;
|
|
41
|
+
/** Default `return`. */
|
|
42
|
+
onBlock?: OnBlock;
|
|
43
|
+
}
|
|
44
|
+
type VerictoSqlDatabaseParams = SqlDatabaseDataSourceParams & VerictoLangChainOptions;
|
|
45
|
+
/**
|
|
46
|
+
* The Vericto dialect of a TypeORM `DataSource` type. Types Vericto does not
|
|
47
|
+
* evaluate (cockroachdb, sap, spanner, mongodb...) throw `VerictoConfigError`: pass
|
|
48
|
+
* `dialect` explicitly if you know what you are doing.
|
|
49
|
+
*/
|
|
50
|
+
declare function dialectFromDataSource(dataSource: Pick<DataSource, 'options'>): string;
|
|
51
|
+
/**
|
|
52
|
+
* A `DataSource` whose `query()` is checked by Vericto first (and runs the masked
|
|
53
|
+
* rewrite). Everything else is the original data source's.
|
|
54
|
+
*/
|
|
55
|
+
declare function guardDataSource(dataSource: DataSource, vericto: Vericto, dialect: string): DataSource;
|
|
56
|
+
/** The message a model gets for a blocked query: what was blocked, why, and the fix. */
|
|
57
|
+
declare function blockedMessage(verdict: Verdict): string;
|
|
58
|
+
/** A readable verdict for the check tool. */
|
|
59
|
+
declare function describeVerdict(verdict: Verdict): string;
|
|
60
|
+
/**
|
|
61
|
+
* A LangChain `SqlDatabase` whose statements are checked by Vericto. Accepted
|
|
62
|
+
* wherever a `SqlDatabase` is: `QuerySqlTool`, `SqlToolkit`/`createSqlAgent`,
|
|
63
|
+
* `SqlDatabaseChain`.
|
|
64
|
+
*/
|
|
65
|
+
declare class VerictoSqlDatabase extends SqlDatabase {
|
|
66
|
+
readonly vericto: Vericto;
|
|
67
|
+
readonly dialect: string;
|
|
68
|
+
readonly onBlock: OnBlock;
|
|
69
|
+
/** The unguarded data source: SQL run through it directly is not checked. */
|
|
70
|
+
readonly rawDataSource: DataSource;
|
|
71
|
+
protected constructor(fields: VerictoSqlDatabaseParams & {
|
|
72
|
+
vericto: Vericto;
|
|
73
|
+
dialect: string;
|
|
74
|
+
});
|
|
75
|
+
/**
|
|
76
|
+
* Same as `SqlDatabase.fromDataSourceParams`, plus the Vericto options. Fails fast
|
|
77
|
+
* when the server does not evaluate the dialect. LangChain's own schema
|
|
78
|
+
* introspection (the column catalogue read here) runs on the raw data source.
|
|
79
|
+
*/
|
|
80
|
+
static fromDataSourceParams(fields: VerictoSqlDatabaseParams): Promise<VerictoSqlDatabase>;
|
|
81
|
+
/** Same as `SqlDatabase.fromOptionsParams`, plus the Vericto options. */
|
|
82
|
+
static fromOptionsParams(fields: Parameters<typeof SqlDatabase.fromOptionsParams>[0] & VerictoLangChainOptions): Promise<VerictoSqlDatabase>;
|
|
83
|
+
/**
|
|
84
|
+
* Run `command` after Vericto checks it. Blocked: returns {@link blockedMessage}
|
|
85
|
+
* (or throws `VerictoBlockedError` with `onBlock: 'raise'`). Masked: runs the
|
|
86
|
+
* rewrite. Vericto unavailable or misconfigured: throws.
|
|
87
|
+
*/
|
|
88
|
+
run(command: string, fetch?: 'all' | 'one'): Promise<string>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* `QuerySqlTool` that lets Vericto errors through. The stock tool turns every error
|
|
92
|
+
* into text for the model, which would also hide "Vericto unavailable" (and, with
|
|
93
|
+
* `onBlock: 'raise'`, the block) from your code.
|
|
94
|
+
*/
|
|
95
|
+
declare class VerictoQuerySqlTool extends QuerySqlTool {
|
|
96
|
+
static lc_name(): string;
|
|
97
|
+
/** @ignore */
|
|
98
|
+
_call(input: string): Promise<string>;
|
|
99
|
+
}
|
|
100
|
+
/** `SqlToolkit` with {@link VerictoQuerySqlTool} and the Vericto dialect in the prompt. */
|
|
101
|
+
declare class VerictoSqlToolkit extends SqlToolkit {
|
|
102
|
+
constructor(db: VerictoSqlDatabase, llm: BaseLanguageModelInterface);
|
|
103
|
+
}
|
|
104
|
+
interface VerictoCheckSqlToolOptions extends VerictoLangChainOptions {
|
|
105
|
+
/** Take the guard, dialect and onBlock from this database. */
|
|
106
|
+
db?: VerictoSqlDatabase;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* A tool that only checks a query (nothing is executed) and answers with Vericto's
|
|
110
|
+
* verdict, so an agent can validate SQL before it proposes or runs it. Each check is
|
|
111
|
+
* a Runtime API evaluation (it counts against the runtime quota and is audited).
|
|
112
|
+
*/
|
|
113
|
+
declare class VerictoCheckSqlTool extends Tool {
|
|
114
|
+
static lc_name(): string;
|
|
115
|
+
name: string;
|
|
116
|
+
description: string;
|
|
117
|
+
readonly vericto: Vericto;
|
|
118
|
+
readonly dialect: string;
|
|
119
|
+
readonly onBlock: OnBlock;
|
|
120
|
+
constructor(options?: VerictoCheckSqlToolOptions);
|
|
121
|
+
/** @ignore */
|
|
122
|
+
_call(input: string): Promise<string>;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export { VerictoCheckSqlTool, VerictoQuerySqlTool, VerictoSqlDatabase, VerictoSqlToolkit, blockedMessage, describeVerdict, dialectFromDataSource, guardDataSource };
|
|
126
|
+
export type { OnBlock, VerictoCheckSqlToolOptions, VerictoLangChainOptions, VerictoSqlDatabaseParams };
|