@deepagents/text2sql 0.13.1 → 0.14.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/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1060 -218
- package/dist/index.js.map +4 -4
- package/dist/lib/adapters/groundings/index.js +166 -154
- package/dist/lib/adapters/groundings/index.js.map +4 -4
- package/dist/lib/adapters/mysql/index.js +166 -154
- package/dist/lib/adapters/mysql/index.js.map +4 -4
- package/dist/lib/adapters/postgres/index.js +168 -155
- package/dist/lib/adapters/postgres/index.js.map +4 -4
- package/dist/lib/adapters/postgres/info.postgres.grounding.d.ts.map +1 -1
- package/dist/lib/adapters/spreadsheet/index.js +22 -2
- package/dist/lib/adapters/spreadsheet/index.js.map +4 -4
- package/dist/lib/adapters/sqlite/index.js +166 -154
- package/dist/lib/adapters/sqlite/index.js.map +4 -4
- package/dist/lib/adapters/sqlserver/index.js +166 -154
- package/dist/lib/adapters/sqlserver/index.js.map +4 -4
- package/dist/lib/agents/result-tools.d.ts +20 -23
- package/dist/lib/agents/result-tools.d.ts.map +1 -1
- package/dist/lib/fs/index.d.ts +4 -0
- package/dist/lib/fs/index.d.ts.map +1 -0
- package/dist/lib/fs/scoped-fs.d.ts +53 -0
- package/dist/lib/fs/scoped-fs.d.ts.map +1 -0
- package/dist/lib/fs/sqlite-fs.d.ts +66 -0
- package/dist/lib/fs/sqlite-fs.d.ts.map +1 -0
- package/dist/lib/fs/tracked-fs.d.ts +40 -0
- package/dist/lib/fs/tracked-fs.d.ts.map +1 -0
- package/dist/lib/sql.d.ts +3 -4
- package/dist/lib/sql.d.ts.map +1 -1
- package/dist/lib/synthesis/index.js +181 -181
- package/dist/lib/synthesis/index.js.map +4 -4
- package/package.json +5 -5
|
@@ -554,7 +554,7 @@ var ColumnValuesGrounding = class extends AbstractGrounding {
|
|
|
554
554
|
// packages/text2sql/src/lib/adapters/groundings/report.grounding.ts
|
|
555
555
|
import { groq as groq2 } from "@ai-sdk/groq";
|
|
556
556
|
import { tool } from "ai";
|
|
557
|
-
import
|
|
557
|
+
import dedent2 from "dedent";
|
|
558
558
|
import z from "zod";
|
|
559
559
|
import "@deepagents/agent";
|
|
560
560
|
|
|
@@ -572,6 +572,7 @@ import spawn2 from "nano-spawn";
|
|
|
572
572
|
import {
|
|
573
573
|
createBashTool
|
|
574
574
|
} from "bash-tool";
|
|
575
|
+
import dedent from "dedent";
|
|
575
576
|
import YAML from "yaml";
|
|
576
577
|
import { DatabaseSync } from "node:sqlite";
|
|
577
578
|
import { groq } from "@ai-sdk/groq";
|
|
@@ -793,7 +794,7 @@ function assistantText(content, options) {
|
|
|
793
794
|
parts: [{ type: "text", text: content }]
|
|
794
795
|
});
|
|
795
796
|
}
|
|
796
|
-
var LAZY_ID = Symbol("lazy-id");
|
|
797
|
+
var LAZY_ID = Symbol.for("@deepagents/context:lazy-id");
|
|
797
798
|
function isLazyFragment(fragment2) {
|
|
798
799
|
return LAZY_ID in fragment2;
|
|
799
800
|
}
|
|
@@ -1180,7 +1181,7 @@ var ContextEngine = class {
|
|
|
1180
1181
|
async #createBranchFrom(messageId, switchTo) {
|
|
1181
1182
|
const branches = await this.#store.listBranches(this.#chatId);
|
|
1182
1183
|
const samePrefix = branches.filter(
|
|
1183
|
-
(
|
|
1184
|
+
(it) => it.name === this.#branchName || it.name.startsWith(`${this.#branchName}-v`)
|
|
1184
1185
|
);
|
|
1185
1186
|
const newBranchName = `${this.#branchName}-v${samePrefix.length + 1}`;
|
|
1186
1187
|
const newBranch = {
|
|
@@ -1208,6 +1209,15 @@ var ContextEngine = class {
|
|
|
1208
1209
|
createdAt: newBranch.createdAt
|
|
1209
1210
|
};
|
|
1210
1211
|
}
|
|
1212
|
+
/**
|
|
1213
|
+
* Rewind to a message without clearing pending messages.
|
|
1214
|
+
* Used internally when saving an update to an existing message.
|
|
1215
|
+
*/
|
|
1216
|
+
async #rewindForUpdate(messageId) {
|
|
1217
|
+
const pendingBackup = [...this.#pendingMessages];
|
|
1218
|
+
await this.rewind(messageId);
|
|
1219
|
+
this.#pendingMessages = pendingBackup;
|
|
1220
|
+
}
|
|
1211
1221
|
/**
|
|
1212
1222
|
* Get the current chat ID.
|
|
1213
1223
|
*/
|
|
@@ -1292,7 +1302,18 @@ var ContextEngine = class {
|
|
|
1292
1302
|
messages.push(message(msg.data).codec?.decode());
|
|
1293
1303
|
}
|
|
1294
1304
|
}
|
|
1305
|
+
for (let i = 0; i < this.#pendingMessages.length; i++) {
|
|
1306
|
+
const fragment2 = this.#pendingMessages[i];
|
|
1307
|
+
if (isLazyFragment(fragment2)) {
|
|
1308
|
+
this.#pendingMessages[i] = await this.#resolveLazyFragment(fragment2);
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1295
1311
|
for (const fragment2 of this.#pendingMessages) {
|
|
1312
|
+
if (!fragment2.codec) {
|
|
1313
|
+
throw new Error(
|
|
1314
|
+
`Fragment "${fragment2.name}" is missing codec. Lazy fragments must be resolved before decode.`
|
|
1315
|
+
);
|
|
1316
|
+
}
|
|
1296
1317
|
const decoded = fragment2.codec.decode();
|
|
1297
1318
|
messages.push(decoded);
|
|
1298
1319
|
}
|
|
@@ -1323,9 +1344,24 @@ var ContextEngine = class {
|
|
|
1323
1344
|
this.#pendingMessages[i] = await this.#resolveLazyFragment(fragment2);
|
|
1324
1345
|
}
|
|
1325
1346
|
}
|
|
1347
|
+
for (const fragment2 of this.#pendingMessages) {
|
|
1348
|
+
if (fragment2.id) {
|
|
1349
|
+
const existing = await this.#store.getMessage(fragment2.id);
|
|
1350
|
+
if (existing && existing.parentId) {
|
|
1351
|
+
await this.#rewindForUpdate(existing.parentId);
|
|
1352
|
+
fragment2.id = crypto.randomUUID();
|
|
1353
|
+
break;
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1326
1357
|
let parentId = this.#branch.headMessageId;
|
|
1327
1358
|
const now = Date.now();
|
|
1328
1359
|
for (const fragment2 of this.#pendingMessages) {
|
|
1360
|
+
if (!fragment2.codec) {
|
|
1361
|
+
throw new Error(
|
|
1362
|
+
`Fragment "${fragment2.name}" is missing codec. Lazy fragments must be resolved before encode.`
|
|
1363
|
+
);
|
|
1364
|
+
}
|
|
1329
1365
|
const messageData = {
|
|
1330
1366
|
id: fragment2.id ?? crypto.randomUUID(),
|
|
1331
1367
|
chatId: this.#chatId,
|
|
@@ -1685,33 +1721,28 @@ var ContextEngine = class {
|
|
|
1685
1721
|
return void 0;
|
|
1686
1722
|
}
|
|
1687
1723
|
/**
|
|
1688
|
-
* Extract skill
|
|
1689
|
-
* Returns
|
|
1690
|
-
*
|
|
1691
|
-
* Reads the original `paths` configuration stored in fragment metadata
|
|
1692
|
-
* by the skills() fragment helper.
|
|
1724
|
+
* Extract skill mounts from available_skills fragments.
|
|
1725
|
+
* Returns unified mount array where entries with `name` are individual skills.
|
|
1693
1726
|
*
|
|
1694
1727
|
* @example
|
|
1695
1728
|
* ```ts
|
|
1696
1729
|
* const context = new ContextEngine({ store, chatId, userId })
|
|
1697
1730
|
* .set(skills({ paths: [{ host: './skills', sandbox: '/skills' }] }));
|
|
1698
1731
|
*
|
|
1699
|
-
* const mounts = context.getSkillMounts();
|
|
1700
|
-
* // [{ host: './skills', sandbox: '/skills' }]
|
|
1732
|
+
* const { mounts } = context.getSkillMounts();
|
|
1733
|
+
* // mounts: [{ name: 'bi-dashboards', host: './skills/bi-dashboards/SKILL.md', sandbox: '/skills/bi-dashboards/SKILL.md' }]
|
|
1734
|
+
*
|
|
1735
|
+
* // Extract skills only (entries with name)
|
|
1736
|
+
* const skills = mounts.filter(m => m.name);
|
|
1701
1737
|
* ```
|
|
1702
1738
|
*/
|
|
1703
1739
|
getSkillMounts() {
|
|
1704
|
-
const mounts = [];
|
|
1705
1740
|
for (const fragment2 of this.#fragments) {
|
|
1706
|
-
if (fragment2.name === "available_skills" && fragment2.metadata
|
|
1707
|
-
|
|
1708
|
-
if (typeof mapping === "object" && mapping !== null && typeof mapping.host === "string" && typeof mapping.sandbox === "string") {
|
|
1709
|
-
mounts.push({ host: mapping.host, sandbox: mapping.sandbox });
|
|
1710
|
-
}
|
|
1711
|
-
}
|
|
1741
|
+
if (fragment2.name === "available_skills" && fragment2.metadata?.mounts) {
|
|
1742
|
+
return { mounts: fragment2.metadata.mounts };
|
|
1712
1743
|
}
|
|
1713
1744
|
}
|
|
1714
|
-
return mounts;
|
|
1745
|
+
return { mounts: [] };
|
|
1715
1746
|
}
|
|
1716
1747
|
/**
|
|
1717
1748
|
* Inspect the full context state for debugging.
|
|
@@ -1780,91 +1811,53 @@ function runGuardrailChain(part, guardrails, context) {
|
|
|
1780
1811
|
let currentPart = part;
|
|
1781
1812
|
for (const guardrail2 of guardrails) {
|
|
1782
1813
|
const result = guardrail2.handle(currentPart, context);
|
|
1783
|
-
if (result.type === "fail") {
|
|
1814
|
+
if (result.type === "fail" || result.type === "stop") {
|
|
1784
1815
|
return result;
|
|
1785
1816
|
}
|
|
1786
1817
|
currentPart = result.part;
|
|
1787
1818
|
}
|
|
1788
1819
|
return pass(currentPart);
|
|
1789
1820
|
}
|
|
1790
|
-
var
|
|
1791
|
-
-- Chats table
|
|
1792
|
-
-- createdAt/updatedAt: DEFAULT for insert, inline SET for updates
|
|
1793
|
-
CREATE TABLE IF NOT EXISTS chats (
|
|
1794
|
-
id TEXT PRIMARY KEY,
|
|
1795
|
-
userId TEXT NOT NULL,
|
|
1796
|
-
title TEXT,
|
|
1797
|
-
metadata TEXT,
|
|
1798
|
-
createdAt INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),
|
|
1799
|
-
updatedAt INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)
|
|
1800
|
-
);
|
|
1801
|
-
|
|
1802
|
-
CREATE INDEX IF NOT EXISTS idx_chats_updatedAt ON chats(updatedAt);
|
|
1803
|
-
CREATE INDEX IF NOT EXISTS idx_chats_userId ON chats(userId);
|
|
1804
|
-
|
|
1805
|
-
-- Messages table (nodes in the DAG)
|
|
1806
|
-
CREATE TABLE IF NOT EXISTS messages (
|
|
1807
|
-
id TEXT PRIMARY KEY,
|
|
1808
|
-
chatId TEXT NOT NULL,
|
|
1809
|
-
parentId TEXT,
|
|
1810
|
-
name TEXT NOT NULL,
|
|
1811
|
-
type TEXT,
|
|
1812
|
-
data TEXT NOT NULL,
|
|
1813
|
-
createdAt INTEGER NOT NULL,
|
|
1814
|
-
FOREIGN KEY (chatId) REFERENCES chats(id) ON DELETE CASCADE,
|
|
1815
|
-
FOREIGN KEY (parentId) REFERENCES messages(id)
|
|
1816
|
-
);
|
|
1817
|
-
|
|
1818
|
-
CREATE INDEX IF NOT EXISTS idx_messages_chatId ON messages(chatId);
|
|
1819
|
-
CREATE INDEX IF NOT EXISTS idx_messages_parentId ON messages(parentId);
|
|
1820
|
-
|
|
1821
|
-
-- Branches table (pointers to head messages)
|
|
1822
|
-
CREATE TABLE IF NOT EXISTS branches (
|
|
1823
|
-
id TEXT PRIMARY KEY,
|
|
1824
|
-
chatId TEXT NOT NULL,
|
|
1825
|
-
name TEXT NOT NULL,
|
|
1826
|
-
headMessageId TEXT,
|
|
1827
|
-
isActive INTEGER NOT NULL DEFAULT 0,
|
|
1828
|
-
createdAt INTEGER NOT NULL,
|
|
1829
|
-
FOREIGN KEY (chatId) REFERENCES chats(id) ON DELETE CASCADE,
|
|
1830
|
-
FOREIGN KEY (headMessageId) REFERENCES messages(id),
|
|
1831
|
-
UNIQUE(chatId, name)
|
|
1832
|
-
);
|
|
1833
|
-
|
|
1834
|
-
CREATE INDEX IF NOT EXISTS idx_branches_chatId ON branches(chatId);
|
|
1821
|
+
var SKILLS_INSTRUCTIONS = dedent`A skill is a set of local instructions to follow that is stored in a \`SKILL.md\` file. Below is the list of skills that can be used. Each entry includes a name, description, and file path so you can open the source for full instructions when using a specific skill.
|
|
1835
1822
|
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
messageId UNINDEXED,
|
|
1855
|
-
chatId UNINDEXED,
|
|
1856
|
-
name UNINDEXED,
|
|
1857
|
-
content,
|
|
1858
|
-
tokenize='porter unicode61'
|
|
1859
|
-
);
|
|
1860
|
-
`;
|
|
1823
|
+
### How to use skills
|
|
1824
|
+
- Discovery: The list below shows the skills available in this session (name + description + file path). Skill bodies live on disk at the listed paths.
|
|
1825
|
+
- Trigger rules: If the user names a skill (with \`$SkillName\` or plain text) OR the task clearly matches a skill's description shown below, you must use that skill for that turn before doing anything else. Multiple mentions mean use them all. Do not carry skills across turns unless re-mentioned.
|
|
1826
|
+
- Missing/blocked: If a named skill isn't in the list or the path can't be read, say so briefly and continue with the best fallback.
|
|
1827
|
+
- How to use a skill (progressive disclosure):
|
|
1828
|
+
1) After deciding to use a skill, open its \`SKILL.md\`. Read only enough to follow the workflow.
|
|
1829
|
+
2) If \`SKILL.md\` points to extra folders such as \`references/\`, load only the specific files needed for the request; don't bulk-load everything.
|
|
1830
|
+
3) If \`scripts/\` exist, prefer running or patching them instead of retyping large code blocks.
|
|
1831
|
+
4) If \`assets/\` or templates exist, reuse them instead of recreating from scratch.
|
|
1832
|
+
- Coordination and sequencing:
|
|
1833
|
+
- If multiple skills apply, choose the minimal set that covers the request and state the order you'll use them.
|
|
1834
|
+
- Announce which skill(s) you're using and why (one short line). If you skip an obvious skill, say why.
|
|
1835
|
+
- Context hygiene:
|
|
1836
|
+
- Keep context small: summarize long sections instead of pasting them; only load extra files when needed.
|
|
1837
|
+
- Avoid deep reference-chasing: prefer opening only files directly linked from \`SKILL.md\` unless you're blocked.
|
|
1838
|
+
- When variants exist (frameworks, providers, domains), pick only the relevant reference file(s) and note that choice.
|
|
1839
|
+
- Safety and fallback: If a skill can't be applied cleanly (missing files, unclear instructions), state the issue, pick the next-best approach, and continue.`;
|
|
1840
|
+
var ddl_sqlite_default = "-- Context Store DDL for SQLite\n-- This schema implements a DAG-based message history with branching and checkpoints.\n\n-- Performance PRAGMAs (session-level, run on each connection)\nPRAGMA journal_mode = WAL;\nPRAGMA synchronous = NORMAL;\nPRAGMA cache_size = -64000;\nPRAGMA temp_store = MEMORY;\nPRAGMA mmap_size = 268435456;\n\n-- Integrity\nPRAGMA foreign_keys = ON;\n\n-- Chats table\n-- createdAt/updatedAt: DEFAULT for insert, inline SET for updates\nCREATE TABLE IF NOT EXISTS chats (\n id TEXT PRIMARY KEY,\n userId TEXT NOT NULL,\n title TEXT,\n metadata TEXT,\n createdAt INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000),\n updatedAt INTEGER NOT NULL DEFAULT (strftime('%s', 'now') * 1000)\n);\n\nCREATE INDEX IF NOT EXISTS idx_chats_updatedAt ON chats(updatedAt);\nCREATE INDEX IF NOT EXISTS idx_chats_userId ON chats(userId);\n-- Composite index for listChats(): WHERE userId = ? ORDER BY updatedAt DESC\nCREATE INDEX IF NOT EXISTS idx_chats_userId_updatedAt ON chats(userId, updatedAt DESC);\n\n-- Messages table (nodes in the DAG)\nCREATE TABLE IF NOT EXISTS messages (\n id TEXT PRIMARY KEY,\n chatId TEXT NOT NULL,\n parentId TEXT,\n name TEXT NOT NULL,\n type TEXT,\n data TEXT NOT NULL,\n createdAt INTEGER NOT NULL,\n FOREIGN KEY (chatId) REFERENCES chats(id) ON DELETE CASCADE,\n FOREIGN KEY (parentId) REFERENCES messages(id)\n);\n\nCREATE INDEX IF NOT EXISTS idx_messages_chatId ON messages(chatId);\nCREATE INDEX IF NOT EXISTS idx_messages_parentId ON messages(parentId);\n-- Composite index for recursive CTE parent traversal in getMessageChain()\nCREATE INDEX IF NOT EXISTS idx_messages_chatId_parentId ON messages(chatId, parentId);\n\n-- Branches table (pointers to head messages)\nCREATE TABLE IF NOT EXISTS branches (\n id TEXT PRIMARY KEY,\n chatId TEXT NOT NULL,\n name TEXT NOT NULL,\n headMessageId TEXT,\n isActive INTEGER NOT NULL DEFAULT 0,\n createdAt INTEGER NOT NULL,\n FOREIGN KEY (chatId) REFERENCES chats(id) ON DELETE CASCADE,\n FOREIGN KEY (headMessageId) REFERENCES messages(id),\n UNIQUE(chatId, name)\n);\n\nCREATE INDEX IF NOT EXISTS idx_branches_chatId ON branches(chatId);\n-- Composite index for getActiveBranch(): WHERE chatId = ? AND isActive = 1\nCREATE INDEX IF NOT EXISTS idx_branches_chatId_isActive ON branches(chatId, isActive);\n\n-- Checkpoints table (pointers to message nodes)\nCREATE TABLE IF NOT EXISTS checkpoints (\n id TEXT PRIMARY KEY,\n chatId TEXT NOT NULL,\n name TEXT NOT NULL,\n messageId TEXT NOT NULL,\n createdAt INTEGER NOT NULL,\n FOREIGN KEY (chatId) REFERENCES chats(id) ON DELETE CASCADE,\n FOREIGN KEY (messageId) REFERENCES messages(id),\n UNIQUE(chatId, name)\n);\n\nCREATE INDEX IF NOT EXISTS idx_checkpoints_chatId ON checkpoints(chatId);\n\n-- FTS5 virtual table for full-text search\n-- messageId/chatId/name are UNINDEXED (stored but not searchable, used for filtering/joining)\n-- Only 'content' is indexed for full-text search\nCREATE VIRTUAL TABLE IF NOT EXISTS messages_fts USING fts5(\n messageId UNINDEXED,\n chatId UNINDEXED,\n name UNINDEXED,\n content,\n tokenize='porter unicode61'\n);\n";
|
|
1861
1841
|
var SqliteContextStore = class extends ContextStore {
|
|
1862
1842
|
#db;
|
|
1843
|
+
#statements = /* @__PURE__ */ new Map();
|
|
1844
|
+
/**
|
|
1845
|
+
* Get or create a prepared statement.
|
|
1846
|
+
* Statements are cached for the lifetime of the store to avoid
|
|
1847
|
+
* repeated SQL parsing and compilation overhead.
|
|
1848
|
+
*/
|
|
1849
|
+
#stmt(sql) {
|
|
1850
|
+
let stmt = this.#statements.get(sql);
|
|
1851
|
+
if (!stmt) {
|
|
1852
|
+
stmt = this.#db.prepare(sql);
|
|
1853
|
+
this.#statements.set(sql, stmt);
|
|
1854
|
+
}
|
|
1855
|
+
return stmt;
|
|
1856
|
+
}
|
|
1863
1857
|
constructor(path3) {
|
|
1864
1858
|
super();
|
|
1865
1859
|
this.#db = new DatabaseSync(path3);
|
|
1866
|
-
this.#db.exec(
|
|
1867
|
-
this.#db.exec(STORE_DDL);
|
|
1860
|
+
this.#db.exec(ddl_sqlite_default);
|
|
1868
1861
|
}
|
|
1869
1862
|
/**
|
|
1870
1863
|
* Execute a function within a transaction.
|
|
@@ -1885,11 +1878,12 @@ var SqliteContextStore = class extends ContextStore {
|
|
|
1885
1878
|
// Chat Operations
|
|
1886
1879
|
// ==========================================================================
|
|
1887
1880
|
async createChat(chat) {
|
|
1888
|
-
this.#useTransaction(() => {
|
|
1889
|
-
this.#db.prepare(
|
|
1881
|
+
return this.#useTransaction(() => {
|
|
1882
|
+
const row = this.#db.prepare(
|
|
1890
1883
|
`INSERT INTO chats (id, userId, title, metadata)
|
|
1891
|
-
VALUES (?, ?, ?, ?)
|
|
1892
|
-
|
|
1884
|
+
VALUES (?, ?, ?, ?)
|
|
1885
|
+
RETURNING *`
|
|
1886
|
+
).get(
|
|
1893
1887
|
chat.id,
|
|
1894
1888
|
chat.userId,
|
|
1895
1889
|
chat.title ?? null,
|
|
@@ -1899,6 +1893,14 @@ var SqliteContextStore = class extends ContextStore {
|
|
|
1899
1893
|
`INSERT INTO branches (id, chatId, name, headMessageId, isActive, createdAt)
|
|
1900
1894
|
VALUES (?, ?, 'main', NULL, 1, ?)`
|
|
1901
1895
|
).run(crypto.randomUUID(), chat.id, Date.now());
|
|
1896
|
+
return {
|
|
1897
|
+
id: row.id,
|
|
1898
|
+
userId: row.userId,
|
|
1899
|
+
title: row.title ?? void 0,
|
|
1900
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : void 0,
|
|
1901
|
+
createdAt: row.createdAt,
|
|
1902
|
+
updatedAt: row.updatedAt
|
|
1903
|
+
};
|
|
1902
1904
|
});
|
|
1903
1905
|
}
|
|
1904
1906
|
async upsertChat(chat) {
|
|
@@ -2041,21 +2043,16 @@ var SqliteContextStore = class extends ContextStore {
|
|
|
2041
2043
|
// Message Operations (Graph Nodes)
|
|
2042
2044
|
// ==========================================================================
|
|
2043
2045
|
async addMessage(message2) {
|
|
2044
|
-
|
|
2046
|
+
if (message2.parentId === message2.id) {
|
|
2047
|
+
throw new Error(`Message ${message2.id} cannot be its own parent`);
|
|
2048
|
+
}
|
|
2049
|
+
this.#stmt(
|
|
2045
2050
|
`INSERT INTO messages (id, chatId, parentId, name, type, data, createdAt)
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
?5,
|
|
2052
|
-
?6,
|
|
2053
|
-
?7
|
|
2054
|
-
)
|
|
2055
|
-
ON CONFLICT(id) DO UPDATE SET
|
|
2056
|
-
name = excluded.name,
|
|
2057
|
-
type = excluded.type,
|
|
2058
|
-
data = excluded.data`
|
|
2051
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
2052
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
2053
|
+
name = excluded.name,
|
|
2054
|
+
type = excluded.type,
|
|
2055
|
+
data = excluded.data`
|
|
2059
2056
|
).run(
|
|
2060
2057
|
message2.id,
|
|
2061
2058
|
message2.chatId,
|
|
@@ -2066,14 +2063,16 @@ var SqliteContextStore = class extends ContextStore {
|
|
|
2066
2063
|
message2.createdAt
|
|
2067
2064
|
);
|
|
2068
2065
|
const content = typeof message2.data === "string" ? message2.data : JSON.stringify(message2.data);
|
|
2069
|
-
this.#
|
|
2070
|
-
this.#
|
|
2066
|
+
this.#stmt(`DELETE FROM messages_fts WHERE messageId = ?`).run(message2.id);
|
|
2067
|
+
this.#stmt(
|
|
2071
2068
|
`INSERT INTO messages_fts(messageId, chatId, name, content)
|
|
2072
|
-
|
|
2069
|
+
VALUES (?, ?, ?, ?)`
|
|
2073
2070
|
).run(message2.id, message2.chatId, message2.name, content);
|
|
2074
2071
|
}
|
|
2075
2072
|
async getMessage(messageId) {
|
|
2076
|
-
const row = this.#
|
|
2073
|
+
const row = this.#stmt("SELECT * FROM messages WHERE id = ?").get(
|
|
2074
|
+
messageId
|
|
2075
|
+
);
|
|
2077
2076
|
if (!row) {
|
|
2078
2077
|
return void 0;
|
|
2079
2078
|
}
|
|
@@ -2088,15 +2087,16 @@ var SqliteContextStore = class extends ContextStore {
|
|
|
2088
2087
|
};
|
|
2089
2088
|
}
|
|
2090
2089
|
async getMessageChain(headId) {
|
|
2091
|
-
const rows = this.#
|
|
2090
|
+
const rows = this.#stmt(
|
|
2092
2091
|
`WITH RECURSIVE chain AS (
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2092
|
+
SELECT *, 0 as depth FROM messages WHERE id = ?
|
|
2093
|
+
UNION ALL
|
|
2094
|
+
SELECT m.*, c.depth + 1 FROM messages m
|
|
2095
|
+
INNER JOIN chain c ON m.id = c.parentId
|
|
2096
|
+
WHERE c.depth < 100000
|
|
2097
|
+
)
|
|
2098
|
+
SELECT * FROM chain
|
|
2099
|
+
ORDER BY depth DESC`
|
|
2100
2100
|
).all(headId);
|
|
2101
2101
|
return rows.map((row) => ({
|
|
2102
2102
|
id: row.id,
|
|
@@ -2109,7 +2109,7 @@ var SqliteContextStore = class extends ContextStore {
|
|
|
2109
2109
|
}));
|
|
2110
2110
|
}
|
|
2111
2111
|
async hasChildren(messageId) {
|
|
2112
|
-
const row = this.#
|
|
2112
|
+
const row = this.#stmt(
|
|
2113
2113
|
"SELECT EXISTS(SELECT 1 FROM messages WHERE parentId = ?) as hasChildren"
|
|
2114
2114
|
).get(messageId);
|
|
2115
2115
|
return row.hasChildren === 1;
|
|
@@ -2156,7 +2156,9 @@ var SqliteContextStore = class extends ContextStore {
|
|
|
2156
2156
|
};
|
|
2157
2157
|
}
|
|
2158
2158
|
async getActiveBranch(chatId) {
|
|
2159
|
-
const row = this.#
|
|
2159
|
+
const row = this.#stmt(
|
|
2160
|
+
"SELECT * FROM branches WHERE chatId = ? AND isActive = 1"
|
|
2161
|
+
).get(chatId);
|
|
2160
2162
|
if (!row) {
|
|
2161
2163
|
return void 0;
|
|
2162
2164
|
}
|
|
@@ -2174,45 +2176,43 @@ var SqliteContextStore = class extends ContextStore {
|
|
|
2174
2176
|
this.#db.prepare("UPDATE branches SET isActive = 1 WHERE id = ?").run(branchId);
|
|
2175
2177
|
}
|
|
2176
2178
|
async updateBranchHead(branchId, messageId) {
|
|
2177
|
-
this.#
|
|
2179
|
+
this.#stmt("UPDATE branches SET headMessageId = ? WHERE id = ?").run(
|
|
2180
|
+
messageId,
|
|
2181
|
+
branchId
|
|
2182
|
+
);
|
|
2178
2183
|
}
|
|
2179
2184
|
async listBranches(chatId) {
|
|
2180
|
-
const
|
|
2185
|
+
const rows = this.#db.prepare(
|
|
2181
2186
|
`SELECT
|
|
2182
2187
|
b.id,
|
|
2183
2188
|
b.name,
|
|
2184
2189
|
b.headMessageId,
|
|
2185
2190
|
b.isActive,
|
|
2186
|
-
b.createdAt
|
|
2191
|
+
b.createdAt,
|
|
2192
|
+
COALESCE(
|
|
2193
|
+
(
|
|
2194
|
+
WITH RECURSIVE chain AS (
|
|
2195
|
+
SELECT id, parentId FROM messages WHERE id = b.headMessageId
|
|
2196
|
+
UNION ALL
|
|
2197
|
+
SELECT m.id, m.parentId FROM messages m
|
|
2198
|
+
INNER JOIN chain c ON m.id = c.parentId
|
|
2199
|
+
)
|
|
2200
|
+
SELECT COUNT(*) FROM chain
|
|
2201
|
+
),
|
|
2202
|
+
0
|
|
2203
|
+
) as messageCount
|
|
2187
2204
|
FROM branches b
|
|
2188
2205
|
WHERE b.chatId = ?
|
|
2189
2206
|
ORDER BY b.createdAt ASC`
|
|
2190
2207
|
).all(chatId);
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
SELECT m.id, m.parentId FROM messages m
|
|
2200
|
-
INNER JOIN chain c ON m.id = c.parentId
|
|
2201
|
-
)
|
|
2202
|
-
SELECT COUNT(*) as count FROM chain`
|
|
2203
|
-
).get(branch.headMessageId);
|
|
2204
|
-
messageCount = countRow.count;
|
|
2205
|
-
}
|
|
2206
|
-
result.push({
|
|
2207
|
-
id: branch.id,
|
|
2208
|
-
name: branch.name,
|
|
2209
|
-
headMessageId: branch.headMessageId,
|
|
2210
|
-
isActive: branch.isActive === 1,
|
|
2211
|
-
messageCount,
|
|
2212
|
-
createdAt: branch.createdAt
|
|
2213
|
-
});
|
|
2214
|
-
}
|
|
2215
|
-
return result;
|
|
2208
|
+
return rows.map((row) => ({
|
|
2209
|
+
id: row.id,
|
|
2210
|
+
name: row.name,
|
|
2211
|
+
headMessageId: row.headMessageId,
|
|
2212
|
+
isActive: row.isActive === 1,
|
|
2213
|
+
messageCount: row.messageCount,
|
|
2214
|
+
createdAt: row.createdAt
|
|
2215
|
+
}));
|
|
2216
2216
|
}
|
|
2217
2217
|
// ==========================================================================
|
|
2218
2218
|
// Checkpoint Operations
|
|
@@ -2480,8 +2480,10 @@ var Agent = class _Agent {
|
|
|
2480
2480
|
execute: async ({ writer }) => {
|
|
2481
2481
|
let currentResult = result;
|
|
2482
2482
|
let attempt = 0;
|
|
2483
|
+
const { mounts } = context.getSkillMounts();
|
|
2483
2484
|
const guardrailContext = {
|
|
2484
|
-
availableTools: Object.keys(this.tools)
|
|
2485
|
+
availableTools: Object.keys(this.tools),
|
|
2486
|
+
availableSkills: mounts
|
|
2485
2487
|
};
|
|
2486
2488
|
while (attempt < maxRetries) {
|
|
2487
2489
|
if (config?.abortSignal?.aborted) {
|
|
@@ -2509,10 +2511,20 @@ var Agent = class _Agent {
|
|
|
2509
2511
|
);
|
|
2510
2512
|
break;
|
|
2511
2513
|
}
|
|
2514
|
+
if (checkResult.type === "stop") {
|
|
2515
|
+
console.log(
|
|
2516
|
+
chalk2.red(
|
|
2517
|
+
`[${this.#options.name}] Guardrail stopped - unrecoverable error, no retry`
|
|
2518
|
+
)
|
|
2519
|
+
);
|
|
2520
|
+
writer.write(part);
|
|
2521
|
+
writer.write({ type: "finish" });
|
|
2522
|
+
return;
|
|
2523
|
+
}
|
|
2512
2524
|
if (checkResult.part.type === "text-delta") {
|
|
2513
2525
|
accumulatedText += checkResult.part.delta;
|
|
2514
2526
|
}
|
|
2515
|
-
writer.write(
|
|
2527
|
+
writer.write(part);
|
|
2516
2528
|
}
|
|
2517
2529
|
if (!guardrailFailed) {
|
|
2518
2530
|
writer.write({ type: "finish" });
|
|
@@ -2640,7 +2652,7 @@ var ReportGrounding = class extends AbstractGrounding {
|
|
|
2640
2652
|
}),
|
|
2641
2653
|
fragment(
|
|
2642
2654
|
"instructions",
|
|
2643
|
-
|
|
2655
|
+
dedent2`
|
|
2644
2656
|
Write a business context that helps another agent answer questions accurately.
|
|
2645
2657
|
|
|
2646
2658
|
For EACH table, do queries ONE AT A TIME:
|