@askdb/core 1.0.0-beta.40 → 1.0.0-beta.42
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/README.md +39 -1
- package/dist/ask.d.ts +48 -0
- package/dist/ask.d.ts.map +1 -1
- package/dist/ask.js +176 -10
- package/dist/ask.js.map +1 -1
- package/dist/enrichment/suggest.d.ts +7 -0
- package/dist/enrichment/suggest.d.ts.map +1 -1
- package/dist/enrichment/suggest.js +7 -1
- package/dist/enrichment/suggest.js.map +1 -1
- package/dist/errors.d.ts +49 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +20 -0
- package/dist/errors.js.map +1 -1
- package/dist/exec/postgres.d.ts +6 -0
- package/dist/exec/postgres.d.ts.map +1 -0
- package/dist/exec/postgres.js +30 -0
- package/dist/exec/postgres.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/logging/log-events.d.ts +13 -0
- package/dist/logging/log-events.d.ts.map +1 -1
- package/dist/logging/log-events.js +13 -0
- package/dist/logging/log-events.js.map +1 -1
- package/dist/modes/post-execute-log.d.ts +9 -0
- package/dist/modes/post-execute-log.d.ts.map +1 -0
- package/dist/modes/post-execute-log.js +26 -0
- package/dist/modes/post-execute-log.js.map +1 -0
- package/dist/sql/bind.d.ts +100 -0
- package/dist/sql/bind.d.ts.map +1 -0
- package/dist/sql/bind.js +560 -0
- package/dist/sql/bind.js.map +1 -0
- package/dist/sql/dialect-spec.d.ts +4 -0
- package/dist/sql/dialect-spec.d.ts.map +1 -1
- package/dist/sql/dialect-spec.js +8 -0
- package/dist/sql/dialect-spec.js.map +1 -1
- package/dist/sql/extract-sql.d.ts +8 -1
- package/dist/sql/extract-sql.d.ts.map +1 -1
- package/dist/sql/extract-sql.js +27 -4
- package/dist/sql/extract-sql.js.map +1 -1
- package/dist/sql/generate.d.ts +19 -0
- package/dist/sql/generate.d.ts.map +1 -1
- package/dist/sql/generate.js +79 -5
- package/dist/sql/generate.js.map +1 -1
- package/dist/sql/index.d.ts +4 -2
- package/dist/sql/index.d.ts.map +1 -1
- package/dist/sql/index.js +4 -2
- package/dist/sql/index.js.map +1 -1
- package/dist/sql/parameter-manifest.d.ts +34 -0
- package/dist/sql/parameter-manifest.d.ts.map +1 -0
- package/dist/sql/parameter-manifest.js +150 -0
- package/dist/sql/parameter-manifest.js.map +1 -0
- package/dist/sql/prompt.d.ts +7 -1
- package/dist/sql/prompt.d.ts.map +1 -1
- package/dist/sql/prompt.js +24 -1
- package/dist/sql/prompt.js.map +1 -1
- package/dist/sql/sensitive-guardrail.d.ts +47 -0
- package/dist/sql/sensitive-guardrail.d.ts.map +1 -0
- package/dist/sql/sensitive-guardrail.js +589 -0
- package/dist/sql/sensitive-guardrail.js.map +1 -0
- package/dist/sql/tenant-placeholders.d.ts +3 -2
- package/dist/sql/tenant-placeholders.d.ts.map +1 -1
- package/dist/sql/tenant-placeholders.js +14 -11
- package/dist/sql/tenant-placeholders.js.map +1 -1
- package/dist/sql/validate.d.ts.map +1 -1
- package/dist/sql/validate.js +1 -47
- package/dist/sql/validate.js.map +1 -1
- package/package.json +6 -5
- package/dist/ai/provider.d.ts +0 -116
- package/dist/ai/provider.d.ts.map +0 -1
- package/dist/ai/provider.js +0 -255
- package/dist/ai/provider.js.map +0 -1
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Prefer
|
|
2
|
+
* Prefer an explicitly `sql`-tagged fence; fall back to an untagged fence.
|
|
3
|
+
* Never return a fence tagged with anything else (e.g. `json`, `sql-unbound`).
|
|
4
|
+
* Keep single-block and bare-prose behavior identical to the pre-parameterize path.
|
|
3
5
|
*/
|
|
4
6
|
export declare function extractSqlFromModelText(raw: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Extract the ```sql-unbound fence from model text, if present.
|
|
9
|
+
* Returns undefined when the fence is missing or empty.
|
|
10
|
+
*/
|
|
11
|
+
export declare function extractUnboundSqlFromModelText(raw: string): string | undefined;
|
|
5
12
|
//# sourceMappingURL=extract-sql.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract-sql.d.ts","sourceRoot":"","sources":["../../src/sql/extract-sql.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"extract-sql.d.ts","sourceRoot":"","sources":["../../src/sql/extract-sql.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAe3D;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQ9E"}
|
package/dist/sql/extract-sql.js
CHANGED
|
@@ -1,12 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Prefer
|
|
2
|
+
* Prefer an explicitly `sql`-tagged fence; fall back to an untagged fence.
|
|
3
|
+
* Never return a fence tagged with anything else (e.g. `json`, `sql-unbound`).
|
|
4
|
+
* Keep single-block and bare-prose behavior identical to the pre-parameterize path.
|
|
3
5
|
*/
|
|
4
6
|
export function extractSqlFromModelText(raw) {
|
|
5
7
|
const text = raw.trim();
|
|
6
|
-
const
|
|
7
|
-
if (
|
|
8
|
-
return
|
|
8
|
+
const sqlTagged = /```sql(?![\w-])\s*([\s\S]*?)```/im.exec(text);
|
|
9
|
+
if (sqlTagged?.[1]) {
|
|
10
|
+
return sqlTagged[1].trim();
|
|
11
|
+
}
|
|
12
|
+
const untagged = /```(?![a-zA-Z])\s*([\s\S]*?)```/m.exec(text);
|
|
13
|
+
if (untagged?.[1]) {
|
|
14
|
+
return untagged[1].trim();
|
|
15
|
+
}
|
|
16
|
+
// A reply that only has non-sql tagged fences (json, sql-unbound, …) has no SQL.
|
|
17
|
+
if (/```[a-zA-Z][\w-]*/.test(text)) {
|
|
18
|
+
return "";
|
|
9
19
|
}
|
|
10
20
|
return text.trim();
|
|
11
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Extract the ```sql-unbound fence from model text, if present.
|
|
24
|
+
* Returns undefined when the fence is missing or empty.
|
|
25
|
+
*/
|
|
26
|
+
export function extractUnboundSqlFromModelText(raw) {
|
|
27
|
+
const text = raw.trim();
|
|
28
|
+
const fence = /```sql-unbound\s*([\s\S]*?)```/im.exec(text);
|
|
29
|
+
if (fence?.[1]) {
|
|
30
|
+
const unbound = fence[1].trim();
|
|
31
|
+
return unbound.length > 0 ? unbound : undefined;
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
12
35
|
//# sourceMappingURL=extract-sql.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract-sql.js","sourceRoot":"","sources":["../../src/sql/extract-sql.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"extract-sql.js","sourceRoot":"","sources":["../../src/sql/extract-sql.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAW;IACjD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACxB,MAAM,SAAS,GAAG,mCAAmC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjE,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnB,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IACD,MAAM,QAAQ,GAAG,kCAAkC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/D,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClB,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;IACD,iFAAiF;IACjF,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,8BAA8B,CAAC,GAAW;IACxD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACxB,MAAM,KAAK,GAAG,kCAAkC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5D,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChC,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAClD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/dist/sql/generate.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { AskDbLogger } from "../logging/askdb-logger.js";
|
|
|
4
4
|
import type { AnyNormalizedSchema } from "../schema/types.js";
|
|
5
5
|
import type { NormalizedTenantPolicy, TenantScope } from "../schema/v2/tenant-policy.js";
|
|
6
6
|
import type { DialectSpec } from "./dialect-spec.js";
|
|
7
|
+
import { type ParameterManifest } from "./parameter-manifest.js";
|
|
7
8
|
import { type TenantGuardrailResult } from "./tenant-guardrail.js";
|
|
8
9
|
import { type SelectGuardrailExplain } from "./validate.js";
|
|
9
10
|
export type GenerateSqlDeps = {
|
|
@@ -27,6 +28,20 @@ export type GenerateSqlDeps = {
|
|
|
27
28
|
tenantPolicy?: NormalizedTenantPolicy;
|
|
28
29
|
/** Validated tenant scope from the host. Forwarded from ask(). */
|
|
29
30
|
tenantScope?: TenantScope;
|
|
31
|
+
/**
|
|
32
|
+
* Forwarded verbatim to the underlying `generateText` call's `providerOptions`.
|
|
33
|
+
* Resolve provider-portable reasoning/latency effort (e.g. via `@askdb/ai`'s
|
|
34
|
+
* `resolveProviderOptions`) and pass the result here — core stays BYO-model
|
|
35
|
+
* and does not interpret or validate this bag. Omitted entirely (not sent
|
|
36
|
+
* as an empty object) when unset, so existing `generateText` call shapes
|
|
37
|
+
* are unaffected.
|
|
38
|
+
*/
|
|
39
|
+
providerOptions?: Record<string, unknown>;
|
|
40
|
+
/**
|
|
41
|
+
* When true, ask the model for unbound SQL + parameter manifest and return
|
|
42
|
+
* them as optional extras when valid. Forwarded from ask(); default decided there.
|
|
43
|
+
*/
|
|
44
|
+
parameterize?: boolean;
|
|
30
45
|
};
|
|
31
46
|
/** Result of NL→SQL generation (always includes `sql`; `explain` when {@link GenerateSqlDeps.explain}). */
|
|
32
47
|
export type GenerateSelectSqlResult = {
|
|
@@ -39,6 +54,10 @@ export type GenerateSelectSqlResult = {
|
|
|
39
54
|
completionTokens: number | null;
|
|
40
55
|
totalTokens: number | null;
|
|
41
56
|
};
|
|
57
|
+
/** Named-placeholder SQL from the ```sql-unbound fence, when parameterize succeeded. */
|
|
58
|
+
unboundNamedSql?: string;
|
|
59
|
+
/** Validated parameter manifest, when parameterize succeeded. */
|
|
60
|
+
parameterManifest?: ParameterManifest;
|
|
42
61
|
};
|
|
43
62
|
/**
|
|
44
63
|
* Dialect-parameterized NL→SQL generator. Validates inputs, builds the user/system
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/sql/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,IAAI,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/sql/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,IAAI,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAA4B,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC7F,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,CAAC,EAAE,OAAO,mBAAmB,CAAC;IAC1C,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,qGAAqG;IACrG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,yCAAyC,CAAC,EAAE,OAAO,CAAC;IACpD;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,sBAAsB,CAAC;IACtC,kEAAkE;IAClE,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,2GAA2G;AAC3G,MAAM,MAAM,uBAAuB,GAAG;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,eAAe,CAAC,EAAE,qBAAqB,CAAC;IACxC,iGAAiG;IACjG,KAAK,CAAC,EAAE;QAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACrG,wFAAwF;IACxF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,EAC3B,KAAK,EAAE,kBAAkB,EACzB,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,uBAAuB,CAAC,CAsIlC"}
|
package/dist/sql/generate.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { generateText as defaultGenerateText } from "ai";
|
|
2
2
|
import { SqlGenerationError } from "../errors.js";
|
|
3
3
|
import { AskDbLogEvent } from "../logging/log-events.js";
|
|
4
|
-
import { extractSqlFromModelText } from "./extract-sql.js";
|
|
4
|
+
import { extractSqlFromModelText, extractUnboundSqlFromModelText } from "./extract-sql.js";
|
|
5
|
+
import { crossValidateManifestAgainstSql, parseParameterManifest, } from "./parameter-manifest.js";
|
|
5
6
|
import { buildNlToSqlSystemPrompt, buildNlToSqlUserPrompt } from "./prompt.js";
|
|
6
7
|
import { assertNlToSqlInputs, nlToSqlAmbiguityNotes } from "./schema-question-precheck.js";
|
|
7
8
|
import { validateTenantGuardrails } from "./tenant-guardrail.js";
|
|
@@ -19,6 +20,7 @@ export async function generateSelectSql(dialect, question, schema, model, deps =
|
|
|
19
20
|
const nlToSqlSchemaOptions = deps.omitSensitiveIdentifiersFromNlToSqlPrompt === true
|
|
20
21
|
? { omitSensitiveIdentifiersFromPrompt: true }
|
|
21
22
|
: undefined;
|
|
23
|
+
const parameterize = deps.parameterize === true;
|
|
22
24
|
logger?.info({
|
|
23
25
|
event: AskDbLogEvent.PipelineGenerateStart,
|
|
24
26
|
questionLength: question.length,
|
|
@@ -30,9 +32,15 @@ export async function generateSelectSql(dialect, question, schema, model, deps =
|
|
|
30
32
|
try {
|
|
31
33
|
const result = await generateText({
|
|
32
34
|
model,
|
|
33
|
-
|
|
34
|
-
prompt: buildNlToSqlUserPrompt(dialect, question, schema, ambiguityNotes, logger, nlToSqlSchemaOptions, deps.prebuiltDdl, deps.tenantPolicy, deps.tenantScope),
|
|
35
|
+
instructions: buildNlToSqlSystemPrompt(dialect),
|
|
36
|
+
prompt: buildNlToSqlUserPrompt(dialect, question, schema, ambiguityNotes, logger, nlToSqlSchemaOptions, deps.prebuiltDdl, deps.tenantPolicy, deps.tenantScope, parameterize || undefined),
|
|
35
37
|
temperature: 0,
|
|
38
|
+
// Cast: AskDB's public `providerOptions` type is a plain opaque bag
|
|
39
|
+
// (`Record<string, unknown>`) so callers don't need AI SDK JSON types.
|
|
40
|
+
// We don't interpret or validate it — the AI SDK does that.
|
|
41
|
+
...(deps.providerOptions
|
|
42
|
+
? { providerOptions: deps.providerOptions }
|
|
43
|
+
: {}),
|
|
36
44
|
});
|
|
37
45
|
text = result.text;
|
|
38
46
|
const u = result.usage;
|
|
@@ -53,10 +61,20 @@ export async function generateSelectSql(dialect, question, schema, model, deps =
|
|
|
53
61
|
}
|
|
54
62
|
const extracted = extractSqlFromModelText(text);
|
|
55
63
|
const sql = validateSelectSql(dialect, extracted);
|
|
56
|
-
//
|
|
64
|
+
// Optional parameterized extras — any failure clears them (never throws).
|
|
65
|
+
let unboundNamedSql;
|
|
66
|
+
let parameterManifest;
|
|
67
|
+
if (parameterize) {
|
|
68
|
+
const extras = tryParseParameterizedExtras(text, dialect, logger);
|
|
69
|
+
unboundNamedSql = extras.unboundNamedSql;
|
|
70
|
+
parameterManifest = extras.parameterManifest;
|
|
71
|
+
}
|
|
72
|
+
// Tenant guardrail validation: prefer unbound (named) SQL when available so
|
|
73
|
+
// `:tenant_*` placeholders still match today's guardrail behavior.
|
|
57
74
|
let tenantGuardrail;
|
|
58
75
|
if (deps.tenantPolicy && deps.tenantScope) {
|
|
59
|
-
|
|
76
|
+
const guardrailSql = unboundNamedSql ?? sql;
|
|
77
|
+
tenantGuardrail = validateTenantGuardrails(guardrailSql, deps.tenantPolicy, deps.tenantScope);
|
|
60
78
|
if (tenantGuardrail.passed) {
|
|
61
79
|
logger?.info({ event: AskDbLogEvent.TenantGuardrailPassed }, "tenant guardrail validation passed");
|
|
62
80
|
}
|
|
@@ -80,6 +98,10 @@ export async function generateSelectSql(dialect, question, schema, model, deps =
|
|
|
80
98
|
out.tenantGuardrail = tenantGuardrail;
|
|
81
99
|
if (usage !== undefined)
|
|
82
100
|
out.usage = usage;
|
|
101
|
+
if (unboundNamedSql !== undefined)
|
|
102
|
+
out.unboundNamedSql = unboundNamedSql;
|
|
103
|
+
if (parameterManifest !== undefined)
|
|
104
|
+
out.parameterManifest = parameterManifest;
|
|
83
105
|
return out;
|
|
84
106
|
}
|
|
85
107
|
catch (e) {
|
|
@@ -92,4 +114,56 @@ export async function generateSelectSql(dialect, question, schema, model, deps =
|
|
|
92
114
|
throw e;
|
|
93
115
|
}
|
|
94
116
|
}
|
|
117
|
+
function tryParseParameterizedExtras(text, dialect, logger) {
|
|
118
|
+
const unbound = extractUnboundSqlFromModelText(text);
|
|
119
|
+
if (!unbound) {
|
|
120
|
+
logger?.debug?.({
|
|
121
|
+
event: AskDbLogEvent.PipelineParameterized,
|
|
122
|
+
parameterCount: 0,
|
|
123
|
+
listParameterCount: 0,
|
|
124
|
+
reason: "missing_unbound",
|
|
125
|
+
}, "parameterize extras dropped");
|
|
126
|
+
return {};
|
|
127
|
+
}
|
|
128
|
+
let unboundValidated;
|
|
129
|
+
try {
|
|
130
|
+
unboundValidated = validateSelectSql(dialect, unbound);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
logger?.debug?.({
|
|
134
|
+
event: AskDbLogEvent.PipelineParameterized,
|
|
135
|
+
parameterCount: 0,
|
|
136
|
+
listParameterCount: 0,
|
|
137
|
+
reason: "unbound_invalid",
|
|
138
|
+
}, "parameterize extras dropped");
|
|
139
|
+
return {};
|
|
140
|
+
}
|
|
141
|
+
const parsed = parseParameterManifest(text);
|
|
142
|
+
if (!parsed.ok) {
|
|
143
|
+
logger?.debug?.({
|
|
144
|
+
event: AskDbLogEvent.PipelineParameterized,
|
|
145
|
+
parameterCount: 0,
|
|
146
|
+
listParameterCount: 0,
|
|
147
|
+
reason: parsed.reason.toLowerCase(),
|
|
148
|
+
}, "parameterize extras dropped");
|
|
149
|
+
return {};
|
|
150
|
+
}
|
|
151
|
+
const cross = crossValidateManifestAgainstSql(unboundValidated, parsed.manifest, dialect);
|
|
152
|
+
if (!cross.ok) {
|
|
153
|
+
logger?.debug?.({
|
|
154
|
+
event: AskDbLogEvent.PipelineParameterized,
|
|
155
|
+
parameterCount: 0,
|
|
156
|
+
listParameterCount: 0,
|
|
157
|
+
reason: cross.reason.toLowerCase(),
|
|
158
|
+
}, "parameterize extras dropped");
|
|
159
|
+
return {};
|
|
160
|
+
}
|
|
161
|
+
const listParameterCount = parsed.manifest.parameters.filter((p) => p.cardinality === "many").length;
|
|
162
|
+
logger?.info({
|
|
163
|
+
event: AskDbLogEvent.PipelineParameterized,
|
|
164
|
+
parameterCount: parsed.manifest.parameters.length,
|
|
165
|
+
listParameterCount,
|
|
166
|
+
}, "parameterize extras accepted");
|
|
167
|
+
return { unboundNamedSql: unboundValidated, parameterManifest: parsed.manifest };
|
|
168
|
+
}
|
|
95
169
|
//# sourceMappingURL=generate.js.map
|
package/dist/sql/generate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/sql/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,IAAI,CAAC;AAEzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAMzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/sql/generate.ts"],"names":[],"mappings":"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"}
|
package/dist/sql/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { extractSqlFromModelText, extractUnboundSqlFromModelText } from "./extract-sql.js";
|
|
2
|
+
export { bindPreparedQuery, escapeSqlLiteral, type QueryParameterType, type QueryParameterValue, type QueryParamSlot, type QueryParameterBinding, type PreparedQuery, type BoundQuery, } from "./bind.js";
|
|
3
|
+
export { parseParameterManifest, type ParameterManifest, type ManifestParameter, } from "./parameter-manifest.js";
|
|
2
4
|
export { generateSelectSql, type GenerateSelectSqlResult, type GenerateSqlDeps, } from "./generate.js";
|
|
3
5
|
export { validateSelectSql, buildSelectGuardrailExplanation, type SelectGuardrailExplain, } from "./validate.js";
|
|
4
6
|
export { buildNlToSqlUserPrompt, buildNlToSqlSystemPrompt, } from "./prompt.js";
|
|
5
7
|
export { assertNlToSqlInputs, nlToSqlAmbiguityNotes, } from "./schema-question-precheck.js";
|
|
6
|
-
export {
|
|
8
|
+
export { type DialectId, type DialectSpec, type BuiltInDialectId, POSTGRES_DIALECT, COCKROACHDB_DIALECT, MYSQL_DIALECT, MARIADB_DIALECT, SQLITE_DIALECT, SQLSERVER_DIALECT, BUILT_IN_DIALECTS, SUPPORTED_DIALECT_IDS, isBuiltInDialectId, getDialectSpec, } from "./dialect-spec.js";
|
|
7
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/sql/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sql/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sql/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,8BAA8B,EAAE,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAClB,KAAK,UAAU,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,sBAAsB,EACtB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,iBAAiB,EACjB,KAAK,uBAAuB,EAC5B,KAAK,eAAe,GACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,iBAAiB,EACjB,+BAA+B,EAC/B,KAAK,sBAAsB,GAC5B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,GACf,MAAM,mBAAmB,CAAC"}
|
package/dist/sql/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { extractSqlFromModelText, extractUnboundSqlFromModelText } from "./extract-sql.js";
|
|
2
|
+
export { bindPreparedQuery, escapeSqlLiteral, } from "./bind.js";
|
|
3
|
+
export { parseParameterManifest, } from "./parameter-manifest.js";
|
|
2
4
|
export { generateSelectSql, } from "./generate.js";
|
|
3
5
|
export { validateSelectSql, buildSelectGuardrailExplanation, } from "./validate.js";
|
|
4
6
|
export { buildNlToSqlUserPrompt, buildNlToSqlSystemPrompt, } from "./prompt.js";
|
|
5
7
|
export { assertNlToSqlInputs, nlToSqlAmbiguityNotes, } from "./schema-question-precheck.js";
|
|
6
|
-
export {
|
|
8
|
+
export { POSTGRES_DIALECT, COCKROACHDB_DIALECT, MYSQL_DIALECT, MARIADB_DIALECT, SQLITE_DIALECT, SQLSERVER_DIALECT, BUILT_IN_DIALECTS, SUPPORTED_DIALECT_IDS, isBuiltInDialectId, getDialectSpec, } from "./dialect-spec.js";
|
|
7
9
|
//# sourceMappingURL=index.js.map
|
package/dist/sql/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sql/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sql/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,8BAA8B,EAAE,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EACL,iBAAiB,EACjB,gBAAgB,GAOjB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,sBAAsB,GAGvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,iBAAiB,GAGlB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,iBAAiB,EACjB,+BAA+B,GAEhC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAIL,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,GACf,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { QueryParameterRejectionReason } from "../errors.js";
|
|
2
|
+
import { type QueryParameterType, type QueryParameterValue } from "./bind.js";
|
|
3
|
+
import type { DialectSpec } from "./dialect-spec.js";
|
|
4
|
+
export type ManifestParameter = {
|
|
5
|
+
name: string;
|
|
6
|
+
type: QueryParameterType;
|
|
7
|
+
cardinality: "one" | "many";
|
|
8
|
+
description?: string;
|
|
9
|
+
value: QueryParameterValue | QueryParameterValue[];
|
|
10
|
+
};
|
|
11
|
+
export type ParameterManifest = {
|
|
12
|
+
parameters: ManifestParameter[];
|
|
13
|
+
};
|
|
14
|
+
export type ManifestParseFailure = {
|
|
15
|
+
ok: false;
|
|
16
|
+
reason: QueryParameterRejectionReason | "MALFORMED" | "EMPTY" | "MISSING";
|
|
17
|
+
message: string;
|
|
18
|
+
};
|
|
19
|
+
export type ManifestParseSuccess = {
|
|
20
|
+
ok: true;
|
|
21
|
+
manifest: ParameterManifest;
|
|
22
|
+
};
|
|
23
|
+
export type ManifestParseResult = ManifestParseSuccess | ManifestParseFailure;
|
|
24
|
+
/**
|
|
25
|
+
* Extract and validate the ```json parameter manifest fence from model text.
|
|
26
|
+
* Returns a typed failure the caller can act on — never throws.
|
|
27
|
+
*/
|
|
28
|
+
export declare function parseParameterManifest(modelText: string): ManifestParseResult;
|
|
29
|
+
/**
|
|
30
|
+
* Cross-validate a parsed manifest against unbound SQL.
|
|
31
|
+
* Returns a typed failure — never throws.
|
|
32
|
+
*/
|
|
33
|
+
export declare function crossValidateManifestAgainstSql(unboundSql: string, manifest: ParameterManifest, dialect: Pick<DialectSpec, "listBinding">): ManifestParseResult;
|
|
34
|
+
//# sourceMappingURL=parameter-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parameter-manifest.d.ts","sourceRoot":"","sources":["../../src/sql/parameter-manifest.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACzB,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,kBAAkB,CAAC;IACzB,WAAW,EAAE,KAAK,GAAG,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,mBAAmB,GAAG,mBAAmB,EAAE,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,EAAE,iBAAiB,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,6BAA6B,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS,CAAC;IAC1E,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,IAAI,CAAC;IACT,QAAQ,EAAE,iBAAiB,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,oBAAoB,GAAG,oBAAoB,CAAC;AA0F9E;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,mBAAmB,CA2C7E;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,GACxC,mBAAmB,CAmCrB"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { isValidListContext, scanPlaceholders, } from "./bind.js";
|
|
3
|
+
const NAME_RE = /^[a-z][a-z0-9_]*$/;
|
|
4
|
+
const scalarValueSchema = z.union([z.string(), z.number().finite(), z.boolean()]);
|
|
5
|
+
const parameterSchema = z.object({
|
|
6
|
+
name: z.string(),
|
|
7
|
+
type: z.enum(["string", "number", "boolean", "date", "datetime"]),
|
|
8
|
+
cardinality: z.enum(["one", "many"]),
|
|
9
|
+
description: z.string().optional(),
|
|
10
|
+
value: z.unknown(),
|
|
11
|
+
});
|
|
12
|
+
const manifestSchema = z.object({
|
|
13
|
+
parameters: z.array(parameterSchema),
|
|
14
|
+
});
|
|
15
|
+
function failure(reason, message) {
|
|
16
|
+
return { ok: false, reason, message };
|
|
17
|
+
}
|
|
18
|
+
function validateValue(type, cardinality, value) {
|
|
19
|
+
if (value === null || value === undefined) {
|
|
20
|
+
return failure("INVALID_VALUE", "Parameter value must not be null or undefined.");
|
|
21
|
+
}
|
|
22
|
+
if (cardinality === "many") {
|
|
23
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
24
|
+
return failure("INVALID_VALUE", "List parameter requires a non-empty array value.");
|
|
25
|
+
}
|
|
26
|
+
const items = [];
|
|
27
|
+
for (const item of value) {
|
|
28
|
+
const one = validateScalar(type, item);
|
|
29
|
+
if (!one.ok)
|
|
30
|
+
return one;
|
|
31
|
+
items.push(one.value);
|
|
32
|
+
}
|
|
33
|
+
return { ok: true, value: items };
|
|
34
|
+
}
|
|
35
|
+
if (Array.isArray(value)) {
|
|
36
|
+
return failure("INVALID_VALUE", "Scalar parameter must not be an array.");
|
|
37
|
+
}
|
|
38
|
+
return validateScalar(type, value);
|
|
39
|
+
}
|
|
40
|
+
function validateScalar(type, value) {
|
|
41
|
+
if (typeof value === "object" && value !== null) {
|
|
42
|
+
return failure("INVALID_VALUE", "Parameter value must be a string, number, or boolean.");
|
|
43
|
+
}
|
|
44
|
+
switch (type) {
|
|
45
|
+
case "string":
|
|
46
|
+
if (typeof value !== "string") {
|
|
47
|
+
return failure("INVALID_VALUE", "Parameter of type string requires a string value.");
|
|
48
|
+
}
|
|
49
|
+
return { ok: true, value };
|
|
50
|
+
case "date":
|
|
51
|
+
if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
52
|
+
return failure("INVALID_VALUE", "Date parameter must be an ISO date string (YYYY-MM-DD).");
|
|
53
|
+
}
|
|
54
|
+
return { ok: true, value };
|
|
55
|
+
case "datetime":
|
|
56
|
+
if (typeof value !== "string" ||
|
|
57
|
+
!/^\d{4}-\d{2}-\d{2}([T ]\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:?\d{2})?)?$/.test(value)) {
|
|
58
|
+
return failure("INVALID_VALUE", "Datetime parameter must be an ISO datetime string.");
|
|
59
|
+
}
|
|
60
|
+
return { ok: true, value };
|
|
61
|
+
case "number":
|
|
62
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
63
|
+
return failure("INVALID_VALUE", "Numeric parameter must be a finite number.");
|
|
64
|
+
}
|
|
65
|
+
return { ok: true, value };
|
|
66
|
+
case "boolean":
|
|
67
|
+
if (typeof value !== "boolean") {
|
|
68
|
+
return failure("INVALID_VALUE", "Boolean parameter requires a boolean value.");
|
|
69
|
+
}
|
|
70
|
+
return { ok: true, value };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Extract and validate the ```json parameter manifest fence from model text.
|
|
75
|
+
* Returns a typed failure the caller can act on — never throws.
|
|
76
|
+
*/
|
|
77
|
+
export function parseParameterManifest(modelText) {
|
|
78
|
+
const fence = /```json\s*([\s\S]*?)```/im.exec(modelText.trim());
|
|
79
|
+
if (!fence?.[1]) {
|
|
80
|
+
return failure("MISSING", "No ```json parameter manifest fence found.");
|
|
81
|
+
}
|
|
82
|
+
let parsed;
|
|
83
|
+
try {
|
|
84
|
+
parsed = JSON.parse(fence[1].trim());
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return failure("MALFORMED", "Parameter manifest JSON is malformed.");
|
|
88
|
+
}
|
|
89
|
+
const result = manifestSchema.safeParse(parsed);
|
|
90
|
+
if (!result.success) {
|
|
91
|
+
return failure("MALFORMED", "Parameter manifest does not match the expected shape.");
|
|
92
|
+
}
|
|
93
|
+
if (result.data.parameters.length === 0) {
|
|
94
|
+
return failure("EMPTY", "Parameter manifest has an empty parameters array.");
|
|
95
|
+
}
|
|
96
|
+
const parameters = [];
|
|
97
|
+
for (const p of result.data.parameters) {
|
|
98
|
+
if (!NAME_RE.test(p.name)) {
|
|
99
|
+
return failure("INVALID_NAME", "Parameter name must match ^[a-z][a-z0-9_]*$.");
|
|
100
|
+
}
|
|
101
|
+
if (p.name.startsWith("tenant_") || p.name.startsWith("askdb_")) {
|
|
102
|
+
return failure("RESERVED_NAME", "Parameter name uses a reserved prefix.");
|
|
103
|
+
}
|
|
104
|
+
const valueCheck = validateValue(p.type, p.cardinality, p.value);
|
|
105
|
+
if (!valueCheck.ok)
|
|
106
|
+
return valueCheck;
|
|
107
|
+
// Reject mixed-type arrays already handled by per-item type checks.
|
|
108
|
+
void scalarValueSchema; // keep import used for documentation of accepted scalars
|
|
109
|
+
parameters.push({
|
|
110
|
+
name: p.name,
|
|
111
|
+
type: p.type,
|
|
112
|
+
cardinality: p.cardinality,
|
|
113
|
+
description: p.description,
|
|
114
|
+
value: valueCheck.value,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
return { ok: true, manifest: { parameters } };
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Cross-validate a parsed manifest against unbound SQL.
|
|
121
|
+
* Returns a typed failure — never throws.
|
|
122
|
+
*/
|
|
123
|
+
export function crossValidateManifestAgainstSql(unboundSql, manifest, dialect) {
|
|
124
|
+
const listBinding = dialect.listBinding ?? "expand";
|
|
125
|
+
const occurrences = scanPlaceholders(unboundSql);
|
|
126
|
+
const nonTenant = occurrences.filter((o) => !o.name.startsWith("tenant_"));
|
|
127
|
+
const byName = new Map(manifest.parameters.map((p) => [p.name, p]));
|
|
128
|
+
for (const p of manifest.parameters) {
|
|
129
|
+
if (!nonTenant.some((o) => o.name === p.name) && !occurrences.some((o) => o.name === p.name)) {
|
|
130
|
+
return failure("UNRESOLVED_PLACEHOLDER", "Manifest parameter does not appear in unbound SQL.");
|
|
131
|
+
}
|
|
132
|
+
// Tenant placeholders must not appear in the manifest (already rejected by RESERVED_NAME
|
|
133
|
+
// for tenant_ prefix). Double-check appearance of tenant_* in unbound is OK without manifest entry.
|
|
134
|
+
}
|
|
135
|
+
for (const occ of nonTenant) {
|
|
136
|
+
if (!byName.has(occ.name)) {
|
|
137
|
+
return failure("UNRESOLVED_PLACEHOLDER", "Unbound SQL contains a non-tenant placeholder absent from the manifest.");
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
for (const occ of occurrences) {
|
|
141
|
+
const p = byName.get(occ.name);
|
|
142
|
+
if (!p)
|
|
143
|
+
continue; // tenant placeholders have no manifest entry
|
|
144
|
+
if (p.cardinality === "many" && !isValidListContext(unboundSql, occ, listBinding)) {
|
|
145
|
+
return failure("INVALID_LIST_CONTEXT", "List parameter is not in a valid IN (...) or = ANY(...) context.");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return { ok: true, manifest };
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=parameter-manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parameter-manifest.js","sourceRoot":"","sources":["../../src/sql/parameter-manifest.ts"],"names":[],"mappings":"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"}
|
package/dist/sql/prompt.d.ts
CHANGED
|
@@ -16,7 +16,13 @@ export declare function buildNlToSqlUserPrompt(dialect: DialectSpec, question: s
|
|
|
16
16
|
* still fires using the consumer-supplied `nlToSqlSchemaOptions` to keep
|
|
17
17
|
* observability consistent.
|
|
18
18
|
*/
|
|
19
|
-
prebuiltDdl?: string, tenantPolicy?: NormalizedTenantPolicy, tenantScope?: TenantScope
|
|
19
|
+
prebuiltDdl?: string, tenantPolicy?: NormalizedTenantPolicy, tenantScope?: TenantScope,
|
|
20
|
+
/**
|
|
21
|
+
* When true, append the unbound-SQL + parameter-manifest output-format
|
|
22
|
+
* instructions. When false/undefined, the prompt is unchanged from the
|
|
23
|
+
* pre-parameterize path (byte-identical).
|
|
24
|
+
*/
|
|
25
|
+
parameterize?: boolean): string;
|
|
20
26
|
/** Dialect-parameterized system prompt for the NL→SQL generator. */
|
|
21
27
|
export declare function buildNlToSqlSystemPrompt(dialect: DialectSpec): string;
|
|
22
28
|
//# sourceMappingURL=prompt.d.ts.map
|
package/dist/sql/prompt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/sql/prompt.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAK9D,OAAO,KAAK,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAOrD;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,EAC3B,cAAc,GAAE,SAAS,MAAM,EAAO,EACtC,MAAM,CAAC,EAAE,WAAW,EACpB,oBAAoB,CAAC,EAAE,oBAAoB;AAC3C;;;;;;GAMG;AACH,WAAW,CAAC,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,sBAAsB,EACrC,WAAW,CAAC,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/sql/prompt.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAK9D,OAAO,KAAK,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAOrD;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,EAC3B,cAAc,GAAE,SAAS,MAAM,EAAO,EACtC,MAAM,CAAC,EAAE,WAAW,EACpB,oBAAoB,CAAC,EAAE,oBAAoB;AAC3C;;;;;;GAMG;AACH,WAAW,CAAC,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,sBAAsB,EACrC,WAAW,CAAC,EAAE,WAAW;AACzB;;;;GAIG;AACH,YAAY,CAAC,EAAE,OAAO,GACrB,MAAM,CAkGR;AAED,oEAAoE;AACpE,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAErE"}
|
package/dist/sql/prompt.js
CHANGED
|
@@ -18,7 +18,13 @@ export function buildNlToSqlUserPrompt(dialect, question, schema, ambiguityNotes
|
|
|
18
18
|
* still fires using the consumer-supplied `nlToSqlSchemaOptions` to keep
|
|
19
19
|
* observability consistent.
|
|
20
20
|
*/
|
|
21
|
-
prebuiltDdl, tenantPolicy, tenantScope
|
|
21
|
+
prebuiltDdl, tenantPolicy, tenantScope,
|
|
22
|
+
/**
|
|
23
|
+
* When true, append the unbound-SQL + parameter-manifest output-format
|
|
24
|
+
* instructions. When false/undefined, the prompt is unchanged from the
|
|
25
|
+
* pre-parameterize path (byte-identical).
|
|
26
|
+
*/
|
|
27
|
+
parameterize) {
|
|
22
28
|
const formatted = isV2(schema)
|
|
23
29
|
? formatSchemaV2ForNlToSql(schema, nlToSqlSchemaOptions)
|
|
24
30
|
: formatSchemaForNlToSql(schema, nlToSqlSchemaOptions);
|
|
@@ -66,6 +72,23 @@ prebuiltDdl, tenantPolicy, tenantScope) {
|
|
|
66
72
|
lines.push("");
|
|
67
73
|
}
|
|
68
74
|
lines.push(`Question: ${question}`);
|
|
75
|
+
if (parameterize === true) {
|
|
76
|
+
const listBinding = dialect.listBinding ?? "expand";
|
|
77
|
+
const listForm = listBinding === "array"
|
|
78
|
+
? "For multi-value parameters use `= ANY(:name)` (array dialects)."
|
|
79
|
+
: "For multi-value parameters use `IN (:name)`.";
|
|
80
|
+
lines.push("");
|
|
81
|
+
lines.push("Parameterized output format (required):");
|
|
82
|
+
lines.push("1. Emit the complete bound SQL (values inlined as literals) in a ```sql fence — exactly as you would without this instruction.");
|
|
83
|
+
lines.push("2. Emit the same statement in a ```sql-unbound fence, replacing values taken from the user's question with `:name` placeholders.");
|
|
84
|
+
lines.push("3. Emit a ```json fence with `{\"parameters\":[{\"name\",\"type\",\"cardinality\",\"description\",\"value\"}, ...]}` describing each placeholder.");
|
|
85
|
+
lines.push("- Placeholder names match `^[a-z][a-z0-9_]*$`. Never quote placeholders (`state = :state_name`, never `state = ':state_name'`).");
|
|
86
|
+
lines.push("- Never write `$1`, `?`, or `@p0` markers — only `:name` placeholders. AskDB derives driver markers.");
|
|
87
|
+
lines.push(`- ${listForm}`);
|
|
88
|
+
lines.push("- Types are `string` | `number` | `boolean` | `date` | `datetime`. Use `cardinality` `one` or `many`. Dates/datetimes are ISO strings.");
|
|
89
|
+
lines.push("- Keep `:tenant_*` placeholders exactly as the tenant policy block instructs; do not put them in the manifest.");
|
|
90
|
+
lines.push("- Only parameterize values that came from the user's question — not structural constants you chose (e.g. status enums you invented).");
|
|
91
|
+
}
|
|
69
92
|
return lines.join("\n");
|
|
70
93
|
}
|
|
71
94
|
/** Dialect-parameterized system prompt for the NL→SQL generator. */
|
package/dist/sql/prompt.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/sql/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,OAAO,EACL,sBAAsB,GAEvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,wBAAwB,GAEzB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,SAAS,IAAI,CAAC,MAA2B;IACvC,OAAO,UAAU,IAAI,MAAM,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAAoB,EACpB,QAAgB,EAChB,MAA2B,EAC3B,iBAAoC,EAAE,EACtC,MAAoB,EACpB,oBAA2C;AAC3C;;;;;;GAMG;AACH,WAAoB,EACpB,YAAqC,EACrC,WAAyB;
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/sql/prompt.ts"],"names":[],"mappings":"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"}
|