@deepagents/text2sql 0.37.1 → 0.38.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.
Files changed (37) hide show
  1. package/dist/index.js +159 -40
  2. package/dist/index.js.map +2 -2
  3. package/dist/lib/adapters/adapter.d.ts +4 -4
  4. package/dist/lib/adapters/adapter.d.ts.map +1 -1
  5. package/dist/lib/adapters/bigquery/constraint.bigquery.grounding.d.ts.map +1 -1
  6. package/dist/lib/adapters/bigquery/index.js +160 -31
  7. package/dist/lib/adapters/bigquery/index.js.map +3 -3
  8. package/dist/lib/adapters/bigquery/indexes.bigquery.grounding.d.ts.map +1 -1
  9. package/dist/lib/adapters/bigquery/row-count.bigquery.grounding.d.ts.map +1 -1
  10. package/dist/lib/adapters/groundings/abstract.grounding.d.ts +3 -1
  11. package/dist/lib/adapters/groundings/abstract.grounding.d.ts.map +1 -1
  12. package/dist/lib/adapters/groundings/column-stats.grounding.d.ts.map +1 -1
  13. package/dist/lib/adapters/groundings/column-values.grounding.d.ts.map +1 -1
  14. package/dist/lib/adapters/groundings/constraint.grounding.d.ts.map +1 -1
  15. package/dist/lib/adapters/groundings/context.d.ts +6 -2
  16. package/dist/lib/adapters/groundings/context.d.ts.map +1 -1
  17. package/dist/lib/adapters/groundings/index.js +96 -20
  18. package/dist/lib/adapters/groundings/index.js.map +2 -2
  19. package/dist/lib/adapters/groundings/indexes.grounding.d.ts.map +1 -1
  20. package/dist/lib/adapters/groundings/row-count.grounding.d.ts.map +1 -1
  21. package/dist/lib/adapters/groundings/table.grounding.d.ts.map +1 -1
  22. package/dist/lib/adapters/groundings/view.grounding.d.ts.map +1 -1
  23. package/dist/lib/adapters/mysql/index.js +145 -35
  24. package/dist/lib/adapters/mysql/index.js.map +3 -3
  25. package/dist/lib/adapters/postgres/index.js +151 -35
  26. package/dist/lib/adapters/postgres/index.js.map +3 -3
  27. package/dist/lib/adapters/postgres/postgres.d.ts.map +1 -1
  28. package/dist/lib/adapters/spreadsheet/index.js +109 -27
  29. package/dist/lib/adapters/spreadsheet/index.js.map +3 -3
  30. package/dist/lib/adapters/sqlite/index.js +145 -35
  31. package/dist/lib/adapters/sqlite/index.js.map +3 -3
  32. package/dist/lib/adapters/sqlserver/index.js +151 -35
  33. package/dist/lib/adapters/sqlserver/index.js.map +3 -3
  34. package/dist/lib/adapters/sqlserver/sqlserver.d.ts.map +1 -1
  35. package/dist/lib/sql.d.ts +14 -2
  36. package/dist/lib/sql.d.ts.map +1 -1
  37. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -163,13 +163,14 @@ function relationship(input) {
163
163
  }
164
164
 
165
165
  // packages/text2sql/src/lib/adapters/groundings/context.ts
166
- function createGroundingContext() {
166
+ function createGroundingContext(options = {}) {
167
167
  return {
168
168
  tables: [],
169
169
  views: [],
170
170
  relationships: [],
171
171
  info: void 0,
172
- cache: /* @__PURE__ */ new Map()
172
+ cache: /* @__PURE__ */ new Map(),
173
+ onProgress: options.onProgress
173
174
  };
174
175
  }
175
176
 
@@ -315,7 +316,24 @@ var Adapter = class {
315
316
  async introspect(ctx = createGroundingContext()) {
316
317
  for (const fn of this.grounding) {
317
318
  const grounding = fn(this);
318
- await grounding.execute(ctx);
319
+ if (grounding.phase) {
320
+ ctx.onProgress?.({
321
+ type: "phase:start",
322
+ phase: grounding.phase,
323
+ message: `Starting ${grounding.name} introspection...`
324
+ });
325
+ }
326
+ try {
327
+ await grounding.execute(ctx);
328
+ } finally {
329
+ if (grounding.phase) {
330
+ ctx.onProgress?.({
331
+ type: "phase:end",
332
+ phase: grounding.phase,
333
+ message: `Finished ${grounding.name} introspection.`
334
+ });
335
+ }
336
+ }
319
337
  }
320
338
  return this.#toSchemaFragments(ctx);
321
339
  }
@@ -521,26 +539,33 @@ var Adapter = class {
521
539
  async #checkScope(sql, allowedEntities) {
522
540
  const dialect = this.formatterLanguage;
523
541
  const scopeDialects = {
524
- sqlite: "mysql",
525
- postgresql: "postgresql",
526
- bigquery: "bigquery",
527
- transactsql: "transactsql",
528
- mysql: "mysql"
542
+ sqlite: ["sqlite", "mysql"],
543
+ postgresql: ["postgresql"],
544
+ bigquery: ["bigquery"],
545
+ transactsql: ["transactsql"],
546
+ mysql: ["mysql"]
529
547
  };
530
- const scopeDialect = scopeDialects[dialect];
531
- if (!scopeDialect) {
548
+ const candidates = scopeDialects[dialect];
549
+ if (!candidates) {
532
550
  throw new TypeError(
533
551
  `No scope dialect mapping for formatter language "${dialect}". Add it to the scopeDialects map in Adapter.#checkScope.`
534
552
  );
535
553
  }
536
- let references;
537
- try {
538
- references = extractBaseEntityReferences(sql, scopeDialect);
539
- } catch (error) {
554
+ let references = null;
555
+ let lastError;
556
+ for (const candidate of candidates) {
557
+ try {
558
+ references = extractBaseEntityReferences(sql, candidate);
559
+ break;
560
+ } catch (error) {
561
+ lastError = error;
562
+ }
563
+ }
564
+ if (references === null) {
540
565
  return buildScopeParseErrorPayload(
541
566
  sql,
542
567
  dialect,
543
- error
568
+ lastError
544
569
  );
545
570
  }
546
571
  if (references.length === 0) return null;
@@ -5202,6 +5227,9 @@ function sqlSandboxExtension(adapters, options = {}) {
5202
5227
  }
5203
5228
 
5204
5229
  // packages/text2sql/src/lib/sql.ts
5230
+ import {
5231
+ createUIMessageStream
5232
+ } from "ai";
5205
5233
  import "@deepagents/agent";
5206
5234
  import {
5207
5235
  agent as agent2,
@@ -5209,6 +5237,7 @@ import {
5209
5237
  errorRecoveryGuardrail,
5210
5238
  fragment as fragment3
5211
5239
  } from "@deepagents/context";
5240
+ var TEXT2SQL_INDEX_PROGRESS_CHUNK = "data-text2sql-index-progress";
5212
5241
  var Text2Sql = class {
5213
5242
  #config;
5214
5243
  #introspection;
@@ -5251,35 +5280,113 @@ var Text2Sql = class {
5251
5280
  return result.sql;
5252
5281
  }
5253
5282
  async index() {
5283
+ return this.#index();
5284
+ }
5285
+ async #index(onProgress) {
5254
5286
  const entries = Object.entries(this.#config.adapters);
5255
- const wrapped = await Promise.all(
5287
+ onProgress?.({
5288
+ type: "index:start",
5289
+ message: `Indexing ${entries.length} adapter${entries.length === 1 ? "" : "s"}...`,
5290
+ current: 0,
5291
+ total: entries.length
5292
+ });
5293
+ const settled = await Promise.allSettled(
5256
5294
  entries.map(async ([name, adapter]) => {
5257
- const schema = await this.#indexAdapter(name, adapter);
5295
+ const schema = await this.#indexAdapter(name, adapter, onProgress);
5258
5296
  return fragment3(name, ...schema);
5259
5297
  })
5260
5298
  );
5299
+ const failed = settled.find((result) => result.status === "rejected");
5300
+ if (failed) {
5301
+ onProgress?.({
5302
+ type: "index:error",
5303
+ message: failed.reason instanceof Error ? failed.reason.message : String(failed.reason)
5304
+ });
5305
+ throw failed.reason;
5306
+ }
5307
+ const wrapped = settled.map((result) => {
5308
+ if (result.status === "rejected") {
5309
+ throw result.reason;
5310
+ }
5311
+ return result.value;
5312
+ });
5313
+ onProgress?.({
5314
+ type: "index:end",
5315
+ message: "Finished indexing adapters.",
5316
+ current: entries.length,
5317
+ total: entries.length
5318
+ });
5261
5319
  return wrapped;
5262
5320
  }
5263
- async #indexAdapter(name, adapter) {
5321
+ async #indexAdapter(name, adapter, onProgress) {
5322
+ onProgress?.({
5323
+ type: "adapter:start",
5324
+ adapter: name,
5325
+ message: `Indexing adapter "${name}"...`
5326
+ });
5264
5327
  const cache = this.#introspection.get(name);
5265
5328
  if (!cache) {
5266
5329
  throw new Error(`no introspection cache registered for "${name}"`);
5267
5330
  }
5268
- const cached = await cache.read();
5269
- if (cached) {
5270
- return cached;
5271
- }
5272
5331
  try {
5273
- const fragments = await adapter.introspect();
5332
+ const cached = await cache.read();
5333
+ if (cached) {
5334
+ onProgress?.({
5335
+ type: "adapter:cache-hit",
5336
+ adapter: name,
5337
+ message: `Using cached index for adapter "${name}".`,
5338
+ cached: true
5339
+ });
5340
+ onProgress?.({
5341
+ type: "adapter:end",
5342
+ adapter: name,
5343
+ message: `Finished indexing adapter "${name}".`,
5344
+ cached: true
5345
+ });
5346
+ return cached;
5347
+ }
5348
+ onProgress?.({
5349
+ type: "adapter:cache-miss",
5350
+ adapter: name,
5351
+ message: `No cached index for adapter "${name}".`,
5352
+ cached: false
5353
+ });
5354
+ const ctx = createGroundingContext({
5355
+ onProgress: (progress) => onProgress?.(this.#adapterProgressEvent(name, progress))
5356
+ });
5357
+ const fragments = await adapter.introspect(ctx);
5274
5358
  await cache.write(fragments);
5359
+ onProgress?.({
5360
+ type: "adapter:end",
5361
+ adapter: name,
5362
+ message: `Finished indexing adapter "${name}".`,
5363
+ cached: false
5364
+ });
5275
5365
  return fragments;
5276
5366
  } catch (error) {
5277
5367
  const reason = error instanceof Error ? error.message : String(error);
5368
+ onProgress?.({
5369
+ type: "adapter:error",
5370
+ adapter: name,
5371
+ message: `Failed indexing adapter "${name}": ${reason}`
5372
+ });
5278
5373
  throw new Error(`introspecting adapter "${name}": ${reason}`, {
5279
5374
  cause: error
5280
5375
  });
5281
5376
  }
5282
5377
  }
5378
+ #adapterProgressEvent(adapter, progress) {
5379
+ return {
5380
+ type: progress.type,
5381
+ adapter,
5382
+ phase: progress.phase,
5383
+ table: progress.table,
5384
+ message: progress.message,
5385
+ current: progress.current,
5386
+ total: progress.total,
5387
+ cached: false
5388
+ };
5389
+ }
5283
5390
  async toPairs(adapterName, factory) {
5284
5391
  const adapter = this.#requireAdapter(adapterName);
5285
5392
  const producer = factory(adapter);
@@ -5289,23 +5396,34 @@ var Text2Sql = class {
5289
5396
  if (messages.length === 0) {
5290
5397
  throw new Error("messages must not be empty");
5291
5398
  }
5292
- const context = this.#config.context(
5293
- ...guidelines(),
5294
- ...await this.index()
5295
- );
5296
- const chatAgent = agent2({
5297
- name: "text2sql",
5298
- sandbox: this.#config.sandbox,
5299
- model: this.#config.model,
5300
- context,
5301
- tools: this.#config.tools,
5302
- guardrails: [errorRecoveryGuardrail],
5303
- maxGuardrailRetries: 3
5304
- });
5305
- return chat(chatAgent, messages, {
5306
- abortSignal: options?.abortSignal,
5307
- generateTitle: options?.generateTitle,
5308
- transform: this.#config.transform
5399
+ return createUIMessageStream({
5400
+ execute: async ({ writer }) => {
5401
+ const progress = (event) => {
5402
+ writer.write({
5403
+ type: TEXT2SQL_INDEX_PROGRESS_CHUNK,
5404
+ data: event
5405
+ });
5406
+ };
5407
+ const context = this.#config.context(
5408
+ ...guidelines(),
5409
+ ...await this.#index(progress)
5410
+ );
5411
+ const chatAgent = agent2({
5412
+ name: "text2sql",
5413
+ sandbox: this.#config.sandbox,
5414
+ model: this.#config.model,
5415
+ context,
5416
+ tools: this.#config.tools,
5417
+ guardrails: [errorRecoveryGuardrail],
5418
+ maxGuardrailRetries: 3
5419
+ });
5420
+ const chatStream = await chat(chatAgent, messages, {
5421
+ abortSignal: options?.abortSignal,
5422
+ generateTitle: options?.generateTitle,
5423
+ transform: this.#config.transform
5424
+ });
5425
+ writer.merge(chatStream);
5426
+ }
5309
5427
  });
5310
5428
  }
5311
5429
  };
@@ -5325,6 +5443,7 @@ export {
5325
5443
  SqlProxyEnforcementPlugin,
5326
5444
  SqlProxyViolationError,
5327
5445
  SqliteFs,
5446
+ TEXT2SQL_INDEX_PROGRESS_CHUNK,
5328
5447
  Text2Sql,
5329
5448
  UnanswerableSQLError,
5330
5449
  applyTablesFilter,