@deepagents/text2sql 0.12.0 → 0.12.1
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.js +146 -23
- package/dist/index.js.map +3 -3
- package/dist/lib/adapters/groundings/index.js +106 -9
- package/dist/lib/adapters/groundings/index.js.map +3 -3
- package/dist/lib/adapters/mysql/index.js +106 -9
- package/dist/lib/adapters/mysql/index.js.map +3 -3
- package/dist/lib/adapters/postgres/index.js +106 -9
- package/dist/lib/adapters/postgres/index.js.map +3 -3
- package/dist/lib/adapters/spreadsheet/index.js +1 -0
- package/dist/lib/adapters/spreadsheet/index.js.map +2 -2
- package/dist/lib/adapters/sqlite/index.js +106 -9
- package/dist/lib/adapters/sqlite/index.js.map +3 -3
- package/dist/lib/adapters/sqlserver/column-stats.sqlserver.grounding.d.ts.map +1 -1
- package/dist/lib/adapters/sqlserver/index.js +107 -12
- package/dist/lib/adapters/sqlserver/index.js.map +3 -3
- package/dist/lib/agents/result-tools.d.ts +3 -0
- package/dist/lib/agents/result-tools.d.ts.map +1 -1
- package/dist/lib/agents/sql.agent.d.ts +1 -1
- package/dist/lib/agents/sql.agent.d.ts.map +1 -1
- package/dist/lib/sql.d.ts.map +1 -1
- package/dist/lib/synthesis/index.js +115 -8
- package/dist/lib/synthesis/index.js.map +3 -3
- package/dist/lib/synthesis/synthesizers/depth-evolver.d.ts +3 -3
- package/dist/lib/synthesis/synthesizers/depth-evolver.d.ts.map +1 -1
- package/dist/lib/synthesis/synthesizers/schema-synthesizer.d.ts +1 -1
- package/dist/lib/synthesis/synthesizers/schema-synthesizer.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -603,7 +603,7 @@ function message(content) {
|
|
|
603
603
|
} : content;
|
|
604
604
|
return {
|
|
605
605
|
id: message2.id,
|
|
606
|
-
name:
|
|
606
|
+
name: message2.role,
|
|
607
607
|
data: "content",
|
|
608
608
|
type: "message",
|
|
609
609
|
persist: true,
|
|
@@ -625,6 +625,22 @@ function assistantText(content, options) {
|
|
|
625
625
|
parts: [{ type: "text", text: content }]
|
|
626
626
|
});
|
|
627
627
|
}
|
|
628
|
+
var LAZY_ID = Symbol("lazy-id");
|
|
629
|
+
function isLazyFragment(fragment2) {
|
|
630
|
+
return LAZY_ID in fragment2;
|
|
631
|
+
}
|
|
632
|
+
function lastAssistantMessage(content) {
|
|
633
|
+
return {
|
|
634
|
+
name: "assistant",
|
|
635
|
+
type: "message",
|
|
636
|
+
persist: true,
|
|
637
|
+
data: "content",
|
|
638
|
+
[LAZY_ID]: {
|
|
639
|
+
type: "last-assistant",
|
|
640
|
+
content
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
}
|
|
628
644
|
var ContextRenderer = class {
|
|
629
645
|
options;
|
|
630
646
|
constructor(options = {}) {
|
|
@@ -1121,6 +1137,12 @@ var ContextEngine = class {
|
|
|
1121
1137
|
if (this.#pendingMessages.length === 0) {
|
|
1122
1138
|
return;
|
|
1123
1139
|
}
|
|
1140
|
+
for (let i = 0; i < this.#pendingMessages.length; i++) {
|
|
1141
|
+
const fragment2 = this.#pendingMessages[i];
|
|
1142
|
+
if (isLazyFragment(fragment2)) {
|
|
1143
|
+
this.#pendingMessages[i] = await this.#resolveLazyFragment(fragment2);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1124
1146
|
let parentId = this.#branch.headMessageId;
|
|
1125
1147
|
const now = Date.now();
|
|
1126
1148
|
for (const fragment2 of this.#pendingMessages) {
|
|
@@ -1140,6 +1162,39 @@ var ContextEngine = class {
|
|
|
1140
1162
|
this.#branch.headMessageId = parentId;
|
|
1141
1163
|
this.#pendingMessages = [];
|
|
1142
1164
|
}
|
|
1165
|
+
/**
|
|
1166
|
+
* Resolve a lazy fragment by finding the appropriate ID.
|
|
1167
|
+
*/
|
|
1168
|
+
async #resolveLazyFragment(fragment2) {
|
|
1169
|
+
const lazy = fragment2[LAZY_ID];
|
|
1170
|
+
if (lazy.type === "last-assistant") {
|
|
1171
|
+
const lastId = await this.#getLastAssistantId();
|
|
1172
|
+
return assistantText(lazy.content, { id: lastId ?? crypto.randomUUID() });
|
|
1173
|
+
}
|
|
1174
|
+
throw new Error(`Unknown lazy fragment type: ${lazy.type}`);
|
|
1175
|
+
}
|
|
1176
|
+
/**
|
|
1177
|
+
* Find the most recent assistant message ID (pending or persisted).
|
|
1178
|
+
*/
|
|
1179
|
+
async #getLastAssistantId() {
|
|
1180
|
+
for (let i = this.#pendingMessages.length - 1; i >= 0; i--) {
|
|
1181
|
+
const msg = this.#pendingMessages[i];
|
|
1182
|
+
if (msg.name === "assistant" && !isLazyFragment(msg)) {
|
|
1183
|
+
return msg.id;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
if (this.#branch?.headMessageId) {
|
|
1187
|
+
const chain = await this.#store.getMessageChain(
|
|
1188
|
+
this.#branch.headMessageId
|
|
1189
|
+
);
|
|
1190
|
+
for (let i = chain.length - 1; i >= 0; i--) {
|
|
1191
|
+
if (chain[i].name === "assistant") {
|
|
1192
|
+
return chain[i].id;
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
return void 0;
|
|
1197
|
+
}
|
|
1143
1198
|
/**
|
|
1144
1199
|
* Estimate token count and cost for the full context.
|
|
1145
1200
|
*
|
|
@@ -1419,6 +1474,35 @@ var ContextEngine = class {
|
|
|
1419
1474
|
consolidate() {
|
|
1420
1475
|
return void 0;
|
|
1421
1476
|
}
|
|
1477
|
+
/**
|
|
1478
|
+
* Extract skill path mappings from available_skills fragments.
|
|
1479
|
+
* Returns array of { host, sandbox } for mounting in sandbox filesystem.
|
|
1480
|
+
*
|
|
1481
|
+
* Reads the original `paths` configuration stored in fragment metadata
|
|
1482
|
+
* by the skills() fragment helper.
|
|
1483
|
+
*
|
|
1484
|
+
* @example
|
|
1485
|
+
* ```ts
|
|
1486
|
+
* const context = new ContextEngine({ store, chatId, userId })
|
|
1487
|
+
* .set(skills({ paths: [{ host: './skills', sandbox: '/skills' }] }));
|
|
1488
|
+
*
|
|
1489
|
+
* const mounts = context.getSkillMounts();
|
|
1490
|
+
* // [{ host: './skills', sandbox: '/skills' }]
|
|
1491
|
+
* ```
|
|
1492
|
+
*/
|
|
1493
|
+
getSkillMounts() {
|
|
1494
|
+
const mounts = [];
|
|
1495
|
+
for (const fragment2 of this.#fragments) {
|
|
1496
|
+
if (fragment2.name === "available_skills" && fragment2.metadata && Array.isArray(fragment2.metadata.paths)) {
|
|
1497
|
+
for (const mapping of fragment2.metadata.paths) {
|
|
1498
|
+
if (typeof mapping === "object" && mapping !== null && typeof mapping.host === "string" && typeof mapping.sandbox === "string") {
|
|
1499
|
+
mounts.push({ host: mapping.host, sandbox: mapping.sandbox });
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
return mounts;
|
|
1505
|
+
}
|
|
1422
1506
|
/**
|
|
1423
1507
|
* Inspect the full context state for debugging.
|
|
1424
1508
|
* Returns a JSON-serializable object with context information.
|
|
@@ -1660,7 +1744,7 @@ var errorRecoveryGuardrail = {
|
|
|
1660
1744
|
}
|
|
1661
1745
|
return logAndFail(
|
|
1662
1746
|
"Unknown error",
|
|
1663
|
-
`An error occurred: ${errorText
|
|
1747
|
+
`An error occurred: ${errorText}. Let me try a different approach.`
|
|
1664
1748
|
);
|
|
1665
1749
|
}
|
|
1666
1750
|
};
|
|
@@ -1908,18 +1992,19 @@ var SqliteContextStore = class extends ContextStore {
|
|
|
1908
1992
|
// Message Operations (Graph Nodes)
|
|
1909
1993
|
// ==========================================================================
|
|
1910
1994
|
async addMessage(message2) {
|
|
1995
|
+
const existingParent = message2.parentId === message2.id ? this.#db.prepare("SELECT parentId FROM messages WHERE id = ?").get(message2.id) : void 0;
|
|
1996
|
+
const parentId = message2.parentId === message2.id ? existingParent?.parentId ?? null : message2.parentId;
|
|
1911
1997
|
this.#db.prepare(
|
|
1912
1998
|
`INSERT INTO messages (id, chatId, parentId, name, type, data, createdAt)
|
|
1913
1999
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
1914
2000
|
ON CONFLICT(id) DO UPDATE SET
|
|
1915
|
-
parentId = excluded.parentId,
|
|
1916
2001
|
name = excluded.name,
|
|
1917
2002
|
type = excluded.type,
|
|
1918
2003
|
data = excluded.data`
|
|
1919
2004
|
).run(
|
|
1920
2005
|
message2.id,
|
|
1921
2006
|
message2.chatId,
|
|
1922
|
-
|
|
2007
|
+
parentId,
|
|
1923
2008
|
message2.name,
|
|
1924
2009
|
message2.type ?? null,
|
|
1925
2010
|
JSON.stringify(message2.data),
|
|
@@ -2387,13 +2472,9 @@ var Agent = class _Agent {
|
|
|
2387
2472
|
writer.write({ type: "finish" });
|
|
2388
2473
|
return;
|
|
2389
2474
|
}
|
|
2390
|
-
writer
|
|
2391
|
-
type: "text-delta",
|
|
2392
|
-
id: generateId2(),
|
|
2393
|
-
delta: ` ${failureFeedback}`
|
|
2394
|
-
});
|
|
2475
|
+
writeText(writer, failureFeedback);
|
|
2395
2476
|
const selfCorrectionText = accumulatedText + " " + failureFeedback;
|
|
2396
|
-
context.set(
|
|
2477
|
+
context.set(lastAssistantMessage(selfCorrectionText));
|
|
2397
2478
|
await context.save();
|
|
2398
2479
|
currentResult = await this.#createRawStream(
|
|
2399
2480
|
contextVariables,
|
|
@@ -2498,6 +2579,22 @@ var repairToolCall = async ({
|
|
|
2498
2579
|
});
|
|
2499
2580
|
return { ...toolCall, input: JSON.stringify(output) };
|
|
2500
2581
|
};
|
|
2582
|
+
function writeText(writer, text) {
|
|
2583
|
+
const feedbackPartId = generateId2();
|
|
2584
|
+
writer.write({
|
|
2585
|
+
id: feedbackPartId,
|
|
2586
|
+
type: "text-start"
|
|
2587
|
+
});
|
|
2588
|
+
writer.write({
|
|
2589
|
+
id: feedbackPartId,
|
|
2590
|
+
type: "text-delta",
|
|
2591
|
+
delta: ` ${text}`
|
|
2592
|
+
});
|
|
2593
|
+
writer.write({
|
|
2594
|
+
id: feedbackPartId,
|
|
2595
|
+
type: "text-end"
|
|
2596
|
+
});
|
|
2597
|
+
}
|
|
2501
2598
|
|
|
2502
2599
|
// packages/text2sql/src/lib/agents/explainer.agent.ts
|
|
2503
2600
|
import { groq as groq2 } from "@ai-sdk/groq";
|
|
@@ -2606,6 +2703,7 @@ import { createBashTool as createBashTool2 } from "bash-tool";
|
|
|
2606
2703
|
import chalk3 from "chalk";
|
|
2607
2704
|
import {
|
|
2608
2705
|
Bash,
|
|
2706
|
+
InMemoryFs,
|
|
2609
2707
|
MountableFs,
|
|
2610
2708
|
OverlayFs,
|
|
2611
2709
|
ReadWriteFs,
|
|
@@ -2613,6 +2711,7 @@ import {
|
|
|
2613
2711
|
} from "just-bash";
|
|
2614
2712
|
import * as fs from "node:fs/promises";
|
|
2615
2713
|
import * as path from "node:path";
|
|
2714
|
+
import { v7 } from "uuid";
|
|
2616
2715
|
function createCommand(name, subcommands) {
|
|
2617
2716
|
const usageLines = Object.entries(subcommands).map(([, def]) => ` ${name} ${def.usage.padEnd(30)} ${def.description}`).join("\n");
|
|
2618
2717
|
return defineCommand2(name, async (args, ctx) => {
|
|
@@ -2663,7 +2762,7 @@ function createSqlCommand(adapter) {
|
|
|
2663
2762
|
try {
|
|
2664
2763
|
const rows = await adapter.execute(query);
|
|
2665
2764
|
const rowsArray = Array.isArray(rows) ? rows : [];
|
|
2666
|
-
const filePath = `/results/${
|
|
2765
|
+
const filePath = `/results/${v7()}.json`;
|
|
2667
2766
|
await ctx.fs.writeFile(filePath, JSON.stringify(rowsArray, null, 2));
|
|
2668
2767
|
const columns = rowsArray.length > 0 ? Object.keys(rowsArray[0]) : [];
|
|
2669
2768
|
return {
|
|
@@ -2714,14 +2813,24 @@ function createSqlCommand(adapter) {
|
|
|
2714
2813
|
});
|
|
2715
2814
|
}
|
|
2716
2815
|
async function createResultTools(options) {
|
|
2717
|
-
const { adapter, chatId, messageId } = options;
|
|
2816
|
+
const { adapter, chatId, messageId, skillMounts = [] } = options;
|
|
2718
2817
|
const sqlCommand = createSqlCommand(adapter);
|
|
2719
|
-
const
|
|
2818
|
+
const root = process.env.TEXT2SQL_FS_ROOT || process.cwd();
|
|
2819
|
+
const chatDir = path.join(root, "artifacts", chatId);
|
|
2720
2820
|
const resultsDir = path.join(chatDir, messageId, "results");
|
|
2721
2821
|
await fs.mkdir(resultsDir, { recursive: true });
|
|
2822
|
+
const fsMounts = skillMounts.map(({ host, sandbox: sandbox2 }) => ({
|
|
2823
|
+
mountPoint: sandbox2,
|
|
2824
|
+
filesystem: new OverlayFs({
|
|
2825
|
+
root: host,
|
|
2826
|
+
mountPoint: "/",
|
|
2827
|
+
readOnly: true
|
|
2828
|
+
})
|
|
2829
|
+
}));
|
|
2722
2830
|
const filesystem = new MountableFs({
|
|
2723
|
-
base: new
|
|
2831
|
+
base: new InMemoryFs(),
|
|
2724
2832
|
mounts: [
|
|
2833
|
+
...fsMounts,
|
|
2725
2834
|
{
|
|
2726
2835
|
mountPoint: "/results",
|
|
2727
2836
|
filesystem: new ReadWriteFs({ root: resultsDir })
|
|
@@ -2739,10 +2848,6 @@ async function createResultTools(options) {
|
|
|
2739
2848
|
const { bash, sandbox } = await createBashTool2({
|
|
2740
2849
|
sandbox: bashInstance,
|
|
2741
2850
|
destination: "/",
|
|
2742
|
-
uploadDirectory: {
|
|
2743
|
-
source: process.cwd(),
|
|
2744
|
-
include: "packages/text2sql/src/skills/**/*.md"
|
|
2745
|
-
},
|
|
2746
2851
|
onBeforeBashCall: ({ command }) => {
|
|
2747
2852
|
console.log(chalk3.cyan(`[onBeforeBashCall]: ${command}`));
|
|
2748
2853
|
return { command };
|
|
@@ -2765,7 +2870,9 @@ import {
|
|
|
2765
2870
|
NoContentGeneratedError,
|
|
2766
2871
|
NoObjectGeneratedError,
|
|
2767
2872
|
NoOutputGeneratedError,
|
|
2768
|
-
TypeValidationError
|
|
2873
|
+
TypeValidationError,
|
|
2874
|
+
defaultSettingsMiddleware,
|
|
2875
|
+
wrapLanguageModel
|
|
2769
2876
|
} from "ai";
|
|
2770
2877
|
import { Console } from "node:console";
|
|
2771
2878
|
import { createWriteStream } from "node:fs";
|
|
@@ -2777,6 +2884,7 @@ var logger = new Console({
|
|
|
2777
2884
|
stderr: createWriteStream("./sql-agent-error.log", { flags: "a" }),
|
|
2778
2885
|
inspectOptions: { depth: null }
|
|
2779
2886
|
});
|
|
2887
|
+
var RETRY_TEMPERATURES = [0, 0.2, 0.3];
|
|
2780
2888
|
function extractSql(output) {
|
|
2781
2889
|
const match = output.match(/```sql\n?([\s\S]*?)```/);
|
|
2782
2890
|
return match ? match[1].trim() : output.trim();
|
|
@@ -2830,8 +2938,14 @@ async function toSql(options) {
|
|
|
2830
2938
|
} else {
|
|
2831
2939
|
context.set(user(options.input));
|
|
2832
2940
|
}
|
|
2941
|
+
const temperature = RETRY_TEMPERATURES[attemptNumber - 1] ?? RETRY_TEMPERATURES[RETRY_TEMPERATURES.length - 1];
|
|
2942
|
+
const baseModel = options.model ?? groq3("openai/gpt-oss-20b");
|
|
2943
|
+
const model = wrapLanguageModel({
|
|
2944
|
+
model: baseModel,
|
|
2945
|
+
middleware: defaultSettingsMiddleware({ settings: { temperature } })
|
|
2946
|
+
});
|
|
2833
2947
|
const sqlOutput = structuredOutput({
|
|
2834
|
-
model
|
|
2948
|
+
model,
|
|
2835
2949
|
context,
|
|
2836
2950
|
schema: z3.union([
|
|
2837
2951
|
z3.object({
|
|
@@ -3672,9 +3786,15 @@ var Text2Sql = class {
|
|
|
3672
3786
|
"For large results, slice first: cat <path> | jq '.[:10]'"
|
|
3673
3787
|
]
|
|
3674
3788
|
}),
|
|
3789
|
+
hint(
|
|
3790
|
+
`You cannot access sql through a tool, it'll fail so the proper way to access it is through the bash tool using "sql run" and "sql validate" commands.`
|
|
3791
|
+
),
|
|
3675
3792
|
hint(
|
|
3676
3793
|
"The sql command outputs: file path, column names (comma-separated), and row count. Use column names to construct precise jq queries."
|
|
3677
3794
|
),
|
|
3795
|
+
hint(
|
|
3796
|
+
'This is virtual bash environment and "sql" commands proxy to the database hence you cannot access sql files directly.'
|
|
3797
|
+
),
|
|
3678
3798
|
hint(
|
|
3679
3799
|
"If a query fails, the sql command returns an error message in stderr."
|
|
3680
3800
|
)
|
|
@@ -3683,14 +3803,16 @@ var Text2Sql = class {
|
|
|
3683
3803
|
);
|
|
3684
3804
|
const userMsg = messages.at(-1);
|
|
3685
3805
|
if (userMsg) {
|
|
3686
|
-
context.set(
|
|
3806
|
+
context.set(message(userMsg));
|
|
3687
3807
|
await context.save();
|
|
3688
3808
|
}
|
|
3689
3809
|
const messageId = userMsg?.id ?? generateId3();
|
|
3810
|
+
const skillMounts = context.getSkillMounts();
|
|
3690
3811
|
const { bash } = await createResultTools({
|
|
3691
3812
|
adapter: this.#config.adapter,
|
|
3692
3813
|
chatId: params.chatId,
|
|
3693
|
-
messageId
|
|
3814
|
+
messageId,
|
|
3815
|
+
skillMounts
|
|
3694
3816
|
});
|
|
3695
3817
|
const chatAgent = agent({
|
|
3696
3818
|
name: "text2sql",
|
|
@@ -3710,6 +3832,7 @@ var Text2Sql = class {
|
|
|
3710
3832
|
sendFinish: true,
|
|
3711
3833
|
sendReasoning: true,
|
|
3712
3834
|
sendSources: true,
|
|
3835
|
+
originalMessages: messages,
|
|
3713
3836
|
generateMessageId: generateId3,
|
|
3714
3837
|
onFinish: async ({ responseMessage }) => {
|
|
3715
3838
|
context.set(assistant(responseMessage));
|
|
@@ -3734,7 +3857,7 @@ var Text2Sql = class {
|
|
|
3734
3857
|
);
|
|
3735
3858
|
const userMsg = messages.at(-1);
|
|
3736
3859
|
if (userMsg) {
|
|
3737
|
-
context.set(
|
|
3860
|
+
context.set(message(userMsg));
|
|
3738
3861
|
await context.save();
|
|
3739
3862
|
}
|
|
3740
3863
|
const developerAgent = agent({
|