@mindstudio-ai/agent 0.1.147 → 0.1.149

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 CHANGED
@@ -789,7 +789,7 @@ function stripSystemColumns(data) {
789
789
  }
790
790
 
791
791
  // src/db/predicate.ts
792
- function compilePredicate(fn, bindings) {
792
+ function compilePredicate(fn, bindings, columns = []) {
793
793
  try {
794
794
  const source = fn.toString();
795
795
  const names = extractParamNames(source);
@@ -812,7 +812,7 @@ function compilePredicate(fn, bindings) {
812
812
  if (parser.pos < tokens.length) {
813
813
  return { type: "js", fn, reason: "unexpected tokens after expression" };
814
814
  }
815
- const where = compileNode(ast);
815
+ const where = compileNode(ast, columns);
816
816
  if (!where) {
817
817
  return { type: "js", fn, reason: "could not compile to SQL" };
818
818
  }
@@ -1471,17 +1471,18 @@ var Parser = class {
1471
1471
  return this.tokens[this.pos]?.type === "dot" && this.tokens[this.pos + 1]?.type === "identifier" && this.tokens[this.pos + 1]?.value === "includes" && this.tokens[this.pos + 2]?.type === "lparen";
1472
1472
  }
1473
1473
  };
1474
- function compileNode(node) {
1474
+ function compileNode(node, columns) {
1475
+ const stored = (field, value) => escapeValue(serializeColumnParam(value, field, columns));
1475
1476
  switch (node.kind) {
1476
1477
  case "comparison":
1477
- return `${node.field} ${node.operator} ${escapeValue(node.value)}`;
1478
+ return `${node.field} ${node.operator} ${stored(node.field, node.value)}`;
1478
1479
  case "nullCheck":
1479
1480
  return `${node.field} ${node.isNull ? "IS NULL" : "IS NOT NULL"}`;
1480
1481
  case "in": {
1481
1482
  if (node.values.length === 0) {
1482
1483
  return "0";
1483
1484
  }
1484
- const vals = node.values.map(escapeValue).join(", ");
1485
+ const vals = node.values.map((v) => stored(node.field, v)).join(", ");
1485
1486
  return `${node.field} IN (${vals})`;
1486
1487
  }
1487
1488
  case "like":
@@ -1489,15 +1490,15 @@ function compileNode(node) {
1489
1490
  case "booleanField":
1490
1491
  return node.negated ? `${node.field} = 0` : `${node.field} = 1`;
1491
1492
  case "logical": {
1492
- const left = compileNode(node.left);
1493
- const right = compileNode(node.right);
1493
+ const left = compileNode(node.left, columns);
1494
+ const right = compileNode(node.right, columns);
1494
1495
  if (!left || !right) {
1495
1496
  return null;
1496
1497
  }
1497
1498
  return `(${left} ${node.operator} ${right})`;
1498
1499
  }
1499
1500
  case "not": {
1500
- const inner = compileNode(node.operand);
1501
+ const inner = compileNode(node.operand, columns);
1501
1502
  if (!inner) {
1502
1503
  return null;
1503
1504
  }
@@ -1857,6 +1858,7 @@ var Query = class _Query {
1857
1858
  });
1858
1859
  }
1859
1860
  async every() {
1861
+ await this._config.ready?.();
1860
1862
  const compiled = this._compilePredicates();
1861
1863
  if (compiled.allSql && compiled.sqlWhere) {
1862
1864
  const query = buildExists(
@@ -2022,6 +2024,7 @@ var Query = class _Query {
2022
2024
  return this._run().then(onfulfilled, onrejected);
2023
2025
  }
2024
2026
  async _run() {
2027
+ await this._config.ready?.();
2025
2028
  if (this._aggregate && !this._rawWhere) {
2026
2029
  const compiled = this._compilePredicates();
2027
2030
  if (compiled.allSql) {
@@ -2162,7 +2165,7 @@ var Query = class _Query {
2162
2165
  return { allSql: true, sqlWhere: "", compiled: [] };
2163
2166
  }
2164
2167
  const compiled = this._predicates.map(
2165
- (p) => compilePredicate(p.fn, p.bindings)
2168
+ (p) => compilePredicate(p.fn, p.bindings, this._config.columns)
2166
2169
  );
2167
2170
  const allSql = compiled.every((c) => c.type === "sql");
2168
2171
  let sqlWhere = "";
@@ -2206,14 +2209,14 @@ var Mutation = class _Mutation {
2206
2209
  /** @internal */
2207
2210
  _config;
2208
2211
  /** @internal */
2209
- _queries;
2212
+ _build;
2210
2213
  /** @internal */
2211
2214
  _processResult;
2212
2215
  /** @internal Non-batchable executor for complex mutations (e.g. removeAll JS fallback). */
2213
2216
  _executor;
2214
- constructor(config, queries, processResult) {
2217
+ constructor(config, build, processResult) {
2215
2218
  this._config = config;
2216
- this._queries = queries;
2219
+ this._build = build;
2217
2220
  this._processResult = processResult;
2218
2221
  this._executor = void 0;
2219
2222
  }
@@ -2227,7 +2230,11 @@ var Mutation = class _Mutation {
2227
2230
  * @internal
2228
2231
  */
2229
2232
  static fromExecutor(config, executor) {
2230
- const m = new _Mutation(config, [], () => void 0);
2233
+ const m = new _Mutation(
2234
+ config,
2235
+ () => [],
2236
+ () => void 0
2237
+ );
2231
2238
  Object.defineProperty(m, "_executor", { value: executor });
2232
2239
  return m;
2233
2240
  }
@@ -2259,7 +2266,7 @@ var Mutation = class _Mutation {
2259
2266
  }
2260
2267
  return {
2261
2268
  type: "mutation",
2262
- queries: this._queries,
2269
+ queries: this._build(),
2263
2270
  config: this._config,
2264
2271
  processResult: this._processResult
2265
2272
  };
@@ -2275,10 +2282,11 @@ var Mutation = class _Mutation {
2275
2282
  // Execution
2276
2283
  // -------------------------------------------------------------------------
2277
2284
  async _execute() {
2285
+ await this._config.ready?.();
2278
2286
  if (this._executor) {
2279
2287
  return this._executor();
2280
2288
  }
2281
- const results = await this._config.executeBatch(this._queries);
2289
+ const results = await this._config.executeBatch(this._build());
2282
2290
  return this._processResult(results);
2283
2291
  }
2284
2292
  };
@@ -2387,17 +2395,15 @@ var Table = class {
2387
2395
  const items = (isArray ? data : [data]).map(
2388
2396
  (item) => this._config.defaults ? { ...this._config.defaults, ...item } : item
2389
2397
  );
2390
- for (const item of items) {
2398
+ const build = () => items.map((item) => {
2391
2399
  this._checkManagedColumns(item);
2392
- }
2393
- const queries = items.map(
2394
- (item) => buildInsert(
2400
+ return buildInsert(
2395
2401
  this._config.tableName,
2396
2402
  item,
2397
2403
  this._config.columns
2398
- )
2399
- );
2400
- return new Mutation(this._config, queries, (results) => {
2404
+ );
2405
+ });
2406
+ return new Mutation(this._config, build, (results) => {
2401
2407
  const rows = results.map((r) => {
2402
2408
  if (r.rows.length > 0) {
2403
2409
  return deserializeRow(
@@ -2421,14 +2427,13 @@ var Table = class {
2421
2427
  * Returns the updated row via `UPDATE ... RETURNING *`.
2422
2428
  */
2423
2429
  update(id, data) {
2424
- this._checkManagedColumns(data);
2425
- const query = buildUpdate(
2426
- this._config.tableName,
2427
- id,
2428
- data,
2429
- this._config.columns
2430
- );
2431
- return new Mutation(this._config, [query], (results) => {
2430
+ const build = () => {
2431
+ this._checkManagedColumns(data);
2432
+ return [
2433
+ buildUpdate(this._config.tableName, id, data, this._config.columns)
2434
+ ];
2435
+ };
2436
+ return new Mutation(this._config, build, (results) => {
2432
2437
  if (!results[0]?.rows[0]) {
2433
2438
  throw new MindStudioError(
2434
2439
  `Row not found: no row with ID '${id}' in table '${this._config.tableName}'`,
@@ -2448,19 +2453,25 @@ var Table = class {
2448
2453
  const query = buildDelete(this._config.tableName, `id = ?`, [id]);
2449
2454
  return new Mutation(
2450
2455
  this._config,
2451
- [query],
2456
+ () => [query],
2452
2457
  (results) => ({
2453
2458
  deleted: results[0].changes > 0
2454
2459
  })
2455
2460
  );
2456
2461
  }
2457
2462
  removeAll(predicate, bindings) {
2458
- const compiled = compilePredicate(predicate, bindings);
2459
- if (compiled.type === "sql") {
2460
- const query = buildDelete(this._config.tableName, compiled.where);
2463
+ const sqlWhere = () => {
2464
+ const compiled = compilePredicate(
2465
+ predicate,
2466
+ bindings,
2467
+ this._config.columns
2468
+ );
2469
+ return compiled.type === "sql" ? compiled.where : null;
2470
+ };
2471
+ if (sqlWhere() !== null) {
2461
2472
  return new Mutation(
2462
2473
  this._config,
2463
- [query],
2474
+ () => [buildDelete(this._config.tableName, sqlWhere())],
2464
2475
  (results) => results[0].changes
2465
2476
  );
2466
2477
  }
@@ -2490,7 +2501,7 @@ var Table = class {
2490
2501
  const query = buildDelete(this._config.tableName);
2491
2502
  return new Mutation(
2492
2503
  this._config,
2493
- [query],
2504
+ () => [query],
2494
2505
  (results) => results[0].changes
2495
2506
  );
2496
2507
  }
@@ -2509,7 +2520,6 @@ var Table = class {
2509
2520
  const conflictColumns = Array.isArray(conflictKey) ? conflictKey : [conflictKey];
2510
2521
  this._validateUniqueConstraint(conflictColumns);
2511
2522
  const withDefaults = this._config.defaults ? { ...this._config.defaults, ...data } : data;
2512
- this._checkManagedColumns(withDefaults);
2513
2523
  for (const col of conflictColumns) {
2514
2524
  if (!(col in withDefaults)) {
2515
2525
  throw new MindStudioError(
@@ -2519,13 +2529,18 @@ var Table = class {
2519
2529
  );
2520
2530
  }
2521
2531
  }
2522
- const query = buildUpsert(
2523
- this._config.tableName,
2524
- withDefaults,
2525
- conflictColumns,
2526
- this._config.columns
2527
- );
2528
- return new Mutation(this._config, [query], (results) => {
2532
+ const build = () => {
2533
+ this._checkManagedColumns(withDefaults);
2534
+ return [
2535
+ buildUpsert(
2536
+ this._config.tableName,
2537
+ withDefaults,
2538
+ conflictColumns,
2539
+ this._config.columns
2540
+ )
2541
+ ];
2542
+ };
2543
+ return new Mutation(this._config, build, (results) => {
2529
2544
  if (!results[0]?.rows[0]) {
2530
2545
  throw new MindStudioError(
2531
2546
  `Upsert into ${this._config.tableName} returned no row`,
@@ -2616,6 +2631,7 @@ var Table = class {
2616
2631
 
2617
2632
  // src/db/raw.ts
2618
2633
  var RawQuery = class _RawQuery {
2634
+ /** Read when it's compiled: the lazy db's database is known only once its context is. */
2619
2635
  _databaseId;
2620
2636
  _executeBatch;
2621
2637
  _query;
@@ -2641,7 +2657,7 @@ var RawQuery = class _RawQuery {
2641
2657
  return {
2642
2658
  type: "raw",
2643
2659
  query: this._query,
2644
- config: { databaseId: this._databaseId },
2660
+ config: { databaseId: this._databaseId() },
2645
2661
  processResult: (result) => _RawQuery._process(result)
2646
2662
  };
2647
2663
  }
@@ -2697,7 +2713,7 @@ function createDb(databases, executeBatch, authConfig, syncRoles) {
2697
2713
  validateRawSql(query);
2698
2714
  const database = resolveDatabase(databases, options?.database);
2699
2715
  return new RawQuery(
2700
- database.id,
2716
+ () => database.id,
2701
2717
  (queries) => executeBatch(database.id, queries),
2702
2718
  { sql: query, params: params?.map(serializeParam) }
2703
2719
  );
@@ -4218,7 +4234,7 @@ var stepMetadata = {
4218
4234
  description: "Legacy v1 data sources. v2 apps should use `dataSources.defineDataSource()` from @mindstudio-ai/agent instead, which owns parsing, chunking, embedding and citations. Create a new empty vector data source for the current app.",
4219
4235
  usageNotes: '- Creates a new data source (vector database) associated with the current app version.\n- The data source is created empty \u2014 use the "Upload Data Source Document" block to add documents.\n- Returns the new data source ID which can be used in subsequent blocks.',
4220
4236
  inputSchema: { "type": "object", "properties": { "name": { "type": "string", "description": "Name for the new data source (supports variable interpolation)" } }, "required": ["name"] },
4221
- outputSchema: { "description": "This step does not produce output data." }
4237
+ outputSchema: { "type": "object", "properties": { "dataSourceId": { "type": "string", "description": "ID of the newly created data source" }, "name": { "type": "string", "description": "Resolved name of the data source" } }, "required": ["dataSourceId", "name"] }
4222
4238
  },
4223
4239
  "createGmailDraft": {
4224
4240
  stepType: "createGmailDraft",
@@ -4262,14 +4278,14 @@ var stepMetadata = {
4262
4278
  description: "Legacy v1 data sources. v2 apps should use `dataSources.defineDataSource()` from @mindstudio-ai/agent instead, which owns parsing, chunking, embedding and citations. Delete a vector data source from the current app.",
4263
4279
  usageNotes: "- Soft-deletes a data source (vector database) by marking it as deleted.\n- The Milvus partition is cleaned up asynchronously by a background cron job.\n- The data source must belong to the current app version.",
4264
4280
  inputSchema: { "type": "object", "properties": { "dataSourceId": { "type": "string", "description": "ID of the data source to delete (supports variable interpolation)" } }, "required": ["dataSourceId"] },
4265
- outputSchema: { "description": "This step does not produce output data." }
4281
+ outputSchema: { "type": "object", "properties": { "dataSourceId": { "type": "string", "description": "ID of the deleted data source" } }, "required": ["dataSourceId"] }
4266
4282
  },
4267
4283
  "deleteDataSourceDocument": {
4268
4284
  stepType: "deleteDataSourceDocument",
4269
4285
  description: "Legacy v1 data sources. v2 apps should use `dataSources.defineDataSource()` from @mindstudio-ai/agent instead, which owns parsing, chunking, embedding and citations. Delete a single document from a data source.",
4270
4286
  usageNotes: "- Soft-deletes a document by marking it as deleted.\n- Requires both the data source ID and document ID.\n- After deletion, reloads vectors into Milvus so the data source reflects the change immediately.",
4271
4287
  inputSchema: { "type": "object", "properties": { "dataSourceId": { "type": "string", "description": "ID of the data source containing the document (supports variable interpolation)" }, "documentId": { "type": "string", "description": "ID of the document to delete (supports variable interpolation)" } }, "required": ["dataSourceId", "documentId"] },
4272
- outputSchema: { "description": "This step does not produce output data." }
4288
+ outputSchema: { "type": "object", "properties": { "dataSourceId": { "type": "string", "description": "ID of the data source" }, "documentId": { "type": "string", "description": "ID of the deleted document" } }, "required": ["dataSourceId", "documentId"] }
4273
4289
  },
4274
4290
  "deleteGmailEmail": {
4275
4291
  stepType: "deleteGmailEmail",
@@ -4353,7 +4369,7 @@ var stepMetadata = {
4353
4369
  description: "Legacy v1 data sources. v2 apps should use `dataSources.defineDataSource()` from @mindstudio-ai/agent instead, which owns parsing, chunking, embedding and citations. Fetch the full extracted text contents of a document in a data source.",
4354
4370
  usageNotes: '- Loads a document by ID and returns its full extracted text content.\n- The document must have been successfully processed (status "done").\n- Also returns document metadata (name, summary, word count).',
4355
4371
  inputSchema: { "type": "object", "properties": { "dataSourceId": { "type": "string", "description": "ID of the data source containing the document (supports variable interpolation)" }, "documentId": { "type": "string", "description": "ID of the document to fetch (supports variable interpolation)" } }, "required": ["dataSourceId", "documentId"] },
4356
- outputSchema: { "description": "This step does not produce output data." }
4372
+ outputSchema: { "type": "object", "properties": { "documentId": { "type": "string", "description": "ID of the document" }, "name": { "type": "string", "description": "Document name" }, "content": { "type": "string", "description": "Full extracted text content" }, "summary": { "type": "string", "description": "Document summary" }, "numWords": { "type": "number", "description": "Word count" } }, "required": ["documentId", "name", "content", "summary", "numWords"] }
4357
4373
  },
4358
4374
  "fetchGoogleDoc": {
4359
4375
  stepType: "fetchGoogleDoc",
@@ -4427,17 +4443,17 @@ var stepMetadata = {
4427
4443
  },
4428
4444
  "generateLipsync": {
4429
4445
  stepType: "generateLipsync",
4430
- description: "Generate a lip sync video from provided audio and image.",
4446
+ description: "Generate a lip sync video from audio and an image or video.",
4431
4447
  usageNotes: "- In foreground mode, the video is displayed to the user. In background mode, the URL is saved to a variable.",
4432
- inputSchema: { "type": "object", "properties": { "intermediateAsset": { "type": "boolean", "description": "When true, the asset is created but hidden from the user's gallery (tagged as intermediate)" }, "addWatermark": { "type": "boolean", "description": "Whether to add a MindStudio watermark to the generated video.\n\nThe watermark is a product mark on assets generated in the MindStudio UI. A step run directly via the SDK or API is producing the app's own asset, so it is never watermarked and this flag has no effect there." }, "lipsyncModelOverride": { "type": "object", "properties": { "model": { "type": "string" }, "config": { "type": "object", "properties": {}, "required": [] } }, "required": ["model"], "description": "Optional model configuration override. Uses the workflow's default lipsync model if not specified" } } },
4433
- outputSchema: { "description": "This step does not produce output data." }
4448
+ inputSchema: { "type": "object", "properties": { "intermediateAsset": { "type": "boolean", "description": "When true, the asset is created but hidden from the user's gallery (tagged as intermediate)" }, "addWatermark": { "type": "boolean", "description": "Whether to add a MindStudio watermark to the generated video.\n\nThe watermark is a product mark on assets generated in the MindStudio UI. A step run directly via the SDK or API is producing the app's own asset, so it is never watermarked and this flag has no effect there." }, "lipsyncModelOverride": { "type": "object", "properties": { "model": { "type": "string" }, "config": { "type": "object", "properties": {}, "required": [] } }, "required": ["model"], "description": "The lip sync model to run and its config, whose keys come from the model: the media (`image` or `video`, and `audio`) and the model's options" } } },
4449
+ outputSchema: { "type": "object", "properties": { "videoUrl": { "type": "string", "description": "URL of the generated lip sync video" } }, "required": ["videoUrl"] }
4434
4450
  },
4435
4451
  "generateMusic": {
4436
4452
  stepType: "generateMusic",
4437
4453
  description: "Generate an audio file from provided instructions (text) using a music model.",
4438
4454
  usageNotes: "- The text field contains the instructions (prompt) for the music generation.\n- In foreground mode, the audio is displayed to the user. In background mode, the URL is saved to a variable.",
4439
4455
  inputSchema: { "type": "object", "properties": { "text": { "type": "string", "description": "The instructions (prompt) for the music generation" }, "intermediateAsset": { "type": "boolean", "description": "When true, the asset is created but hidden from the user's gallery (tagged as intermediate)" }, "musicModelOverride": { "type": "object", "properties": { "model": { "type": "string" }, "config": { "type": "object", "properties": {}, "required": [] } }, "required": ["model"], "description": "Optional model configuration override. Uses the workflow's default music model if not specified" } }, "required": ["text"] },
4440
- outputSchema: { "description": "This step does not produce output data." }
4456
+ outputSchema: { "type": "object", "properties": { "audioUrl": { "type": "string", "description": "URL of the generated audio file" } }, "required": ["audioUrl"] }
4441
4457
  },
4442
4458
  "generatePdf": {
4443
4459
  stepType: "generatePdf",
@@ -4490,7 +4506,7 @@ var stepMetadata = {
4490
4506
  description: "Download attachments from a Gmail email and store them on the app's own storage.",
4491
4507
  usageNotes: "- Requires a Google OAuth connection with Gmail readonly scope.\n- Attachments are stored and returned as URLs \u2014 on the public CDN by default, or in one of the app's own file stores when the call passes `store`. Use a private store for anything confidential; a public CDN URL is readable by anyone who has it.\n- Attachments larger than 25MB are skipped.\n- Use the message ID from Search Gmail Emails, List Recent Gmail Emails, or Get Gmail Email steps.",
4492
4508
  inputSchema: { "type": "object", "properties": { "messageId": { "type": "string", "description": "Gmail message ID" }, "connectionId": { "type": "string", "description": "Google OAuth connection ID" } }, "required": ["messageId"] },
4493
- outputSchema: { "description": "This step does not produce output data." }
4509
+ outputSchema: { "type": "object", "properties": { "attachments": { "type": "array", "items": { "type": "object", "properties": { "filename": { "type": "string" }, "mimeType": { "type": "string" }, "size": { "type": "number" }, "url": { "type": "string" } }, "required": ["filename", "mimeType", "size", "url"] }, "description": "List of attachments with CDN URLs" } }, "required": ["attachments"] }
4494
4510
  },
4495
4511
  "getGmailDraft": {
4496
4512
  stepType: "getGmailDraft",
@@ -4511,7 +4527,7 @@ var stepMetadata = {
4511
4527
  description: "Get the number of unread emails in the connected Gmail inbox.",
4512
4528
  usageNotes: "- Requires a Google OAuth connection with Gmail readonly scope.\n- Returns the unread message count for the inbox label.\n- This is a lightweight call that does not fetch any email content.",
4513
4529
  inputSchema: { "type": "object", "properties": { "connectionId": { "type": "string", "description": "Google OAuth connection ID" } } },
4514
- outputSchema: { "description": "This step does not produce output data." }
4530
+ outputSchema: { "type": "object", "properties": { "unreadCount": { "type": "number", "description": "Number of unread messages in the inbox" } }, "required": ["unreadCount"] }
4515
4531
  },
4516
4532
  "getGoogleCalendarEvent": {
4517
4533
  stepType: "getGoogleCalendarEvent",
@@ -4637,7 +4653,7 @@ var stepMetadata = {
4637
4653
  description: "Legacy v1 data sources. v2 apps should use `dataSources.defineDataSource()` from @mindstudio-ai/agent instead, which owns parsing, chunking, embedding and citations. List all data sources for the current app.",
4638
4654
  usageNotes: "- Returns metadata for every data source associated with the current app version.\n- Each entry includes the data source ID, name, description, status, and document list.",
4639
4655
  inputSchema: { "type": "object", "properties": {}, "required": [] },
4640
- outputSchema: { "description": "This step does not produce output data." }
4656
+ outputSchema: { "type": "object", "properties": { "dataSources": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "description": { "type": "string" }, "status": { "enum": ["loaded", "hibernating"], "type": "string" }, "dateCreated": { "type": "string" }, "documents": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "status": { "enum": ["processing", "done", "error"], "type": "string" }, "numWords": { "type": "number" }, "dateUploaded": { "type": "string" } }, "required": ["id", "name", "status", "dateUploaded"] } } }, "required": ["id", "name", "description", "status", "dateCreated", "documents"] }, "description": "All data sources for the current app version" } }, "required": ["dataSources"] }
4641
4657
  },
4642
4658
  "listGmailDrafts": {
4643
4659
  stepType: "listGmailDrafts",
@@ -4651,7 +4667,7 @@ var stepMetadata = {
4651
4667
  description: "List all labels in the connected Gmail account. Use these label IDs or names with the Update Gmail Labels step.",
4652
4668
  usageNotes: '- Requires a Google OAuth connection with Gmail readonly scope.\n- Returns both system labels (INBOX, SENT, TRASH, etc.) and user-created labels.\n- Label type is "system" for built-in labels or "user" for custom labels.',
4653
4669
  inputSchema: { "type": "object", "properties": { "connectionId": { "type": "string", "description": "Google OAuth connection ID" } } },
4654
- outputSchema: { "description": "This step does not produce output data." }
4670
+ outputSchema: { "type": "object", "properties": { "labels": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "type": { "type": "string" } }, "required": ["id", "name", "type"] }, "description": "List of Gmail labels" } }, "required": ["labels"] }
4655
4671
  },
4656
4672
  "listGoogleCalendarEvents": {
4657
4673
  stepType: "listGoogleCalendarEvents",
@@ -4672,7 +4688,7 @@ var stepMetadata = {
4672
4688
  description: "List recent emails from the connected Gmail inbox.",
4673
4689
  usageNotes: '- Requires a Google OAuth connection with Gmail readonly scope.\n- Returns up to 100 emails (default 5), ordered by most recent first.\n- Functionally equivalent to Search Gmail Emails with an "in:inbox" query.',
4674
4690
  inputSchema: { "type": "object", "properties": { "connectionId": { "type": "string", "description": "Google OAuth connection ID" }, "exportType": { "enum": ["json", "text"], "type": "string", "description": 'Format for the variable output: "json" or "text"' }, "limit": { "type": "string", "description": "Maximum number of emails to return (1-100, default: 5)" } }, "required": ["exportType", "limit"] },
4675
- outputSchema: { "description": "This step does not produce output data." }
4691
+ outputSchema: { "type": "object", "properties": { "emails": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Gmail message ID" }, "subject": { "type": "string", "description": "Email subject line" }, "from": { "type": "string", "description": "Sender email address" }, "to": { "type": "string", "description": "Recipient email address" }, "date": { "type": "string", "description": "Email date" }, "plainBody": { "type": "string", "description": "Plain text body content" }, "htmlBody": { "type": "string", "description": "HTML body content (if available)" }, "labels": { "type": "string", "description": "Comma-separated label IDs applied to the email" } }, "required": ["id", "subject", "from", "to", "date", "plainBody", "htmlBody", "labels"] }, "description": "List of recent email messages" } }, "required": ["emails"] }
4676
4692
  },
4677
4693
  "logic": {
4678
4694
  stepType: "logic",
@@ -4787,7 +4803,7 @@ var stepMetadata = {
4787
4803
  stepType: "peopleSearch",
4788
4804
  description: "Search for people matching specific criteria using Apollo.io. Supports natural language queries and advanced filters.",
4789
4805
  usageNotes: '- Can use a natural language "smartQuery" which is converted to Apollo search parameters by an AI model.\n- Advanced params can override or supplement the smart query results.\n- Optionally enriches returned people and/or their organizations for additional detail.\n- Results are paginated. Use limit and page to control the result window.',
4790
- inputSchema: { "type": "object", "properties": { "smartQuery": { "type": "string", "description": 'Natural language search query (e.g. "marketing directors at SaaS companies in NYC")' }, "enrichPeople": { "type": "boolean", "description": "Whether to enrich each result with full contact details" }, "enrichOrganizations": { "type": "boolean", "description": "Whether to enrich each result with full company details" }, "limit": { "type": "string", "description": "Maximum number of results to return" }, "page": { "type": "string", "description": "Page number for pagination" }, "params": { "type": "object", "properties": { "personTitles": { "type": "string", "description": "Job titles to search for (comma-separated)" }, "includeSimilarTitles": { "type": "string", "description": "Whether to include similar/related job titles" }, "qKeywords": { "type": "string", "description": "Keywords to search for in person profiles" }, "personLocations": { "type": "string", "description": "Geographic locations of people (comma-separated)" }, "personSeniorities": { "type": "string", "description": "Seniority levels to filter by (comma-separated)" }, "organizationLocations": { "type": "string", "description": "Geographic locations of organizations (comma-separated)" }, "qOrganizationDomainsList": { "type": "string", "description": "Organization domains to filter by (comma-separated)" }, "contactEmailStatus": { "type": "string", "description": "Email verification status filter" }, "organizationNumEmployeesRanges": { "type": "string", "description": 'Employee count ranges as semicolon-separated pairs (e.g. "1,10; 250,500")' }, "revenueRangeMin": { "type": "string", "description": "Minimum annual revenue filter" }, "revenueRangeMax": { "type": "string", "description": "Maximum annual revenue filter" }, "currentlyUsingAllOfTechnologyUids": { "type": "string", "description": "Technology UIDs the organization must use (all required)" }, "currentlyUsingAnyOfTechnologyUids": { "type": "string", "description": "Technology UIDs the organization uses (any match)" }, "currentlyNotUsingAnyOfTechnologyUids": { "type": "string", "description": "Technology UIDs the organization must not use" } }, "required": ["personTitles", "includeSimilarTitles", "qKeywords", "personLocations", "personSeniorities", "organizationLocations", "qOrganizationDomainsList", "contactEmailStatus", "organizationNumEmployeesRanges", "revenueRangeMin", "revenueRangeMax", "currentlyUsingAllOfTechnologyUids", "currentlyUsingAnyOfTechnologyUids", "currentlyNotUsingAnyOfTechnologyUids"], "description": "Advanced search filter parameters" } }, "required": ["smartQuery", "enrichPeople", "enrichOrganizations", "limit", "page", "params"] },
4806
+ inputSchema: { "type": "object", "properties": { "smartQuery": { "type": "string", "description": 'Natural language search query (e.g. "marketing directors at SaaS companies in NYC")' }, "enrichPeople": { "type": "boolean", "description": "Whether to enrich each result with full contact details" }, "enrichOrganizations": { "type": "boolean", "description": "Whether to enrich each result with full company details" }, "limit": { "type": "string", "description": "Maximum number of results to return" }, "page": { "type": "string", "description": "Page number for pagination" }, "params": { "type": "object", "properties": { "personTitles": { "type": "string", "description": "Job titles to search for (comma-separated)" }, "includeSimilarTitles": { "type": "string", "description": "Whether to include similar/related job titles" }, "qKeywords": { "type": "string", "description": "Keywords to search for in person profiles" }, "personLocations": { "type": "string", "description": "Geographic locations of people (comma-separated)" }, "personSeniorities": { "type": "string", "description": "Seniority levels to filter by (comma-separated)" }, "organizationLocations": { "type": "string", "description": "Geographic locations of organizations (comma-separated)" }, "qOrganizationDomainsList": { "type": "string", "description": "Organization domains to filter by (comma-separated)" }, "contactEmailStatus": { "type": "string", "description": "Email verification status filter" }, "organizationNumEmployeesRanges": { "type": "string", "description": 'Employee count ranges as semicolon-separated pairs (e.g. "1,10; 250,500")' }, "revenueRangeMin": { "type": "string", "description": "Minimum annual revenue filter" }, "revenueRangeMax": { "type": "string", "description": "Maximum annual revenue filter" }, "currentlyUsingAllOfTechnologyUids": { "type": "string", "description": "Technology UIDs the organization must use (all required)" }, "currentlyUsingAnyOfTechnologyUids": { "type": "string", "description": "Technology UIDs the organization uses (any match)" }, "currentlyNotUsingAnyOfTechnologyUids": { "type": "string", "description": "Technology UIDs the organization must not use" } }, "required": ["personTitles", "includeSimilarTitles", "qKeywords", "personLocations", "personSeniorities", "organizationLocations", "qOrganizationDomainsList", "contactEmailStatus", "organizationNumEmployeesRanges", "revenueRangeMin", "revenueRangeMax", "currentlyUsingAllOfTechnologyUids", "currentlyUsingAnyOfTechnologyUids", "currentlyNotUsingAnyOfTechnologyUids"], "description": "Advanced search filter parameters" } }, "required": ["smartQuery", "enrichPeople", "enrichOrganizations", "limit", "page", "params"], "description": "Search parameters including natural language query, filters, pagination, and enrichment options" },
4791
4807
  outputSchema: { "type": "object", "properties": { "results": { "description": "Apollo search results with matched people and optionally enriched data" } }, "required": ["results"] }
4792
4808
  },
4793
4809
  "postToLinkedIn": {
@@ -4856,7 +4872,7 @@ var stepMetadata = {
4856
4872
  "renderVideoFromHtmlComposition": {
4857
4873
  stepType: "renderVideoFromHtmlComposition",
4858
4874
  description: "Render an HTML composition (HTML, CSS, media and seekable animation on a timeline) to a video file",
4859
- usageNotes: "- Renders an HTML composition in HyperFrames' format (https://hyperframes.heygen.com) with HyperFrames 0.8.97, in Chrome off the app's own sandbox; author for that version\n- Pass the composition as `html`, the page itself (up to 10 MB), or as `project`, the URL of a zip of a project's folder (`index.html` at its root, or the file `entryFile` names) or of one HTML file, up to 2 GiB: an app file or any public URL\n- `variables` overrides the composition's `data-composition-variables` defaults, which it reads with `window.__hyperframes.getVariables()`\n- Whatever the composition loads itself (fonts, scripts, images, video) is fetched as it renders, so each is in the project or at a public URL; a private app file needs a signed URL\n- fps 24, 30 or 60 (default 30); quality draft, standard or high (default standard); format mp4 (default), webm or mov (both keep transparency), or gif\n- One render per call, finishing within 15 minutes\n- A composition HyperFrames can't render fails with HyperFrames' own reason",
4875
+ usageNotes: "- Renders an HTML composition in HyperFrames' format (https://hyperframes.heygen.com) with HyperFrames 0.8.97, in Chrome off the app's own sandbox; author for that version\n- Pass the composition as `html`, the page itself (up to 10 MB), or as `project`, the URL of a zip of a project's folder (`index.html` at its root, or the file `entryFile` names) or of one HTML file, up to 2 GiB: an app file or any public URL\n- `variables` overrides the composition's `data-composition-variables` defaults, which it reads with `window.__hyperframes.getVariables()`\n- Whatever the composition loads itself (fonts, scripts, images, video) is fetched as it renders, so each is in the project or at a public URL; a private app file needs a signed URL\n- fps 24, 30 or 60 (default 30); quality draft, standard or high (default standard); format mp4 (default), webm or mov (both keep transparency), or gif\n- An mp4, webm or mov renders in chunks of about 10 seconds side by side, so a long video takes little longer than a short one; a call finishes within about 30 minutes, and reports its progress as it goes. A gif renders whole, within 15 minutes\n- A composition HyperFrames can't render fails with HyperFrames' own reason",
4860
4876
  inputSchema: { "type": "object", "properties": { "html": { "type": "string", "description": "The composition's HTML, up to 10 MB; give this or project" }, "project": { "type": "string", "description": "URL of a zip of the project's folder, or of one self-contained HTML file; give this or html" }, "entryFile": { "type": "string", "description": "The entry HTML inside the zip, relative to its root; index.html when omitted" }, "variables": { "type": "object", "properties": {}, "required": [], "description": "Values over the composition's declared variables" }, "fps": { "enum": [24, 30, 60], "type": "number", "description": "Frames per second: 24, 30 (default) or 60" }, "quality": { "enum": ["draft", "standard", "high"], "type": "string", "description": "Encode quality: draft, standard (default) or high" }, "format": { "enum": ["mp4", "webm", "mov", "gif"], "type": "string", "description": "mp4 (default), webm or mov (both keep transparency), or gif" }, "intermediateAsset": { "type": "boolean", "description": "When true, the asset is created but hidden from the user's gallery (tagged as intermediate)" } } },
4861
4877
  outputSchema: { "type": "object", "properties": { "videoUrl": { "type": "string", "description": "URL of the rendered video" }, "durationSec": { "type": "number", "description": "Its length in seconds" }, "frames": { "type": "number", "description": "How many frames it has" } }, "required": ["videoUrl", "durationSec", "frames"] }
4862
4878
  },
@@ -5044,7 +5060,7 @@ var stepMetadata = {
5044
5060
  description: "Send an existing draft from the connected Gmail account.",
5045
5061
  usageNotes: "- Requires a Google OAuth connection with Gmail compose scope.\n- The draft is sent and removed from the Drafts folder.\n- Use the draft ID returned by the Create Gmail Draft or List Gmail Drafts steps.",
5046
5062
  inputSchema: { "type": "object", "properties": { "draftId": { "type": "string", "description": "Gmail draft ID to send" }, "connectionId": { "type": "string", "description": "Google OAuth connection ID" } }, "required": ["draftId"] },
5047
- outputSchema: { "description": "This step does not produce output data." }
5063
+ outputSchema: { "type": "object", "properties": { "messageId": { "type": "string", "description": "Gmail message ID of the sent email" } }, "required": ["messageId"] }
5048
5064
  },
5049
5065
  "sendGmailMessage": {
5050
5066
  stepType: "sendGmailMessage",
@@ -5072,7 +5088,7 @@ var stepMetadata = {
5072
5088
  description: "Mark one or more Gmail emails as read or unread.",
5073
5089
  usageNotes: "- Requires a Google OAuth connection with Gmail modify scope.\n- Accepts one or more message IDs as a comma-separated string or array.\n- Set markAsRead to true to mark as read, false to mark as unread.",
5074
5090
  inputSchema: { "type": "object", "properties": { "messageIds": { "type": "string", "description": "Gmail message ID(s), comma-separated" }, "markAsRead": { "type": "boolean", "description": "true = mark as read, false = mark as unread" }, "connectionId": { "type": "string", "description": "Google OAuth connection ID" } }, "required": ["messageIds", "markAsRead"] },
5075
- outputSchema: { "description": "This step does not produce output data." }
5091
+ outputSchema: { "type": "object", "properties": { "messageIds": { "type": "array", "items": { "type": "string" }, "description": "IDs of the updated messages" } }, "required": ["messageIds"] }
5076
5092
  },
5077
5093
  "setRunTitle": {
5078
5094
  stepType: "setRunTitle",
@@ -5111,10 +5127,10 @@ var stepMetadata = {
5111
5127
  },
5112
5128
  "typesafeEvaluate": {
5113
5129
  stepType: "typesafeEvaluate",
5114
- description: "Ask TypeSafe structured questions about text or JSON and get calibrated answers. The model returns a probability, a selected option, or a score. It does not write a reply. Each question is a noul (yes or no, as a probability from 0 to 1), a choice (one option from a set you define, with a probability for each), or a score (a rating against ordered levels). Put every question in the same call. The question id is yours: answers come back under the same ids. The model defaults to Jev (jev-latest).",
5115
- usageNotes: "- state is the content to judge: a string, or a JSON object or array (a record, a chat log, application state). Text only. Turn images, audio, and video into text first.\n- questions is a map. The key is an id you choose. It is not shown to the model. The answer comes back under the same id.\n- A noul asks a yes/no question and returns noul, a probability from 0 (no) to 1 (yes). Optional criteria.true and criteria.false say what a yes and a no mean.\n- A choice picks one option. criteria is a map of option id to a short description (or null). At most 255 options. The answer includes the winning choice, a probability for every option, and confidence.\n- A score rates the state on an ordered rubric. criteria is 2 to 10 level descriptions, low to high. The answer's score can land between levels, and includes a probability per level plus confidence.\n- instructions may be a string, or an object that keeps the question in one field and reference data in the others. Refer to those fields by name in backticks.\n- Send every question you need in one call. The model reads the state once and answers them together.\n- model defaults to jev-latest, the current stable release. jev-preview tracks the newest release. Pin a version such as jev-1.13.0 when a threshold was tuned against that version. The response model field is the version that answered.\n- Billed per input token. Output tokens are free.",
5116
- inputSchema: { "type": "object", "properties": { "state": { "anyOf": [{ "type": "string" }, { "type": "object", "properties": {}, "required": [] }, { "type": "array", "items": {} }] }, "questions": { "type": "object", "properties": {}, "required": [], "description": "Questions to ask about the state, keyed by an id you choose." }, "model": { "type": "string", "description": "Model id or alias. Defaults to jev-latest. jev-preview tracks the newest release. Pin a version such as jev-1.13.0 when a threshold was tuned against that version." } }, "required": ["state", "questions"] },
5117
- outputSchema: { "type": "object", "properties": { "model": { "type": "string", "description": "Versioned model id that answered, such as jev-1.13.0." }, "answers": { "type": "object", "properties": {}, "required": [], "description": "One answer per question, under the same ids." }, "usage": { "type": "object", "properties": { "input_tokens": { "type": "number" }, "output_tokens": { "type": "number" } }, "required": ["input_tokens", "output_tokens"], "description": "Token counts for the call. Input tokens are what the step bills." } }, "required": ["model", "answers", "usage"] }
5130
+ description: "Ask structured questions about text, JSON, or images and get calibrated answers. The model returns a probability, a selected option, or a score. It does not write a reply. Each question is a noul (yes or no, as a probability from 0 to 1), a choice (one option from a set you define, with a probability for each), or a score (a rating against ordered levels). Put every question in the same call. The question id is yours: answers come back under the same ids. The model defaults to Jev (jev-latest). Pass clef or clef-flash to run Cloudflare Clef with the same questions and answers. Clef and Clef Flash can also read up to 4 images.",
5131
+ usageNotes: "- state is the content to judge: a string, or a JSON object or array (a record, a chat log, application state).\n- images is for Clef and Clef Flash. Pass up to 4 PNG, JPEG, or WebP images as URLs. Each file is at most 4 MiB, and 8 MiB together. A call on Jev that includes images is rejected.\n- questions is a map. The key is an id you choose. It is not shown to the model. The answer comes back under the same id.\n- A noul asks a yes/no question and returns noul, a probability from 0 (no) to 1 (yes). Optional criteria.true and criteria.false say what a yes and a no mean.\n- A choice picks one option. criteria is a map of option id to a short description (or null). At most 255 options. The answer includes the winning choice, a probability for every option, and confidence.\n- A score rates the state on an ordered rubric. criteria is 2 to 10 level descriptions, low to high. The answer's score can land between levels, and includes a probability per level plus confidence.\n- instructions may be a string, or an object that keeps the question in one field and reference data in the others. Refer to those fields by name in backticks.\n- Send every question you need in one call. The model reads the state once and answers them together.\n- model defaults to jev-latest, the current stable TypeSafe release. jev-preview tracks the newest TypeSafe release. Pin a version such as jev-1.13.0 when a threshold was tuned against that version. clef and clef-flash run Cloudflare Clef on the same questions and answers. clef is the larger model. clef-flash is the faster one. @cf/cloudflare/clef and @cf/cloudflare/clef-flash name the same two. Clef accepts at most 64 questions, and a question id may use only letters, digits, underscore, dot, and hyphen, up to 100 characters. The response model field is the version that answered.\n- Billed per input token. Output tokens are free. Clef and Clef-flash have their own rates.",
5132
+ inputSchema: { "type": "object", "properties": { "state": { "anyOf": [{ "type": "string" }, { "type": "object", "properties": {}, "required": [] }, { "type": "array", "items": {} }] }, "questions": { "type": "object", "properties": {}, "required": [], "description": "Questions to ask about the state, keyed by an id you choose." }, "model": { "type": "string", "description": "Model id or alias. Defaults to jev-latest. jev-preview tracks the newest TypeSafe release. Pin a version such as jev-1.13.0 when a threshold was tuned against that version. clef and clef-flash run Cloudflare Clef, with the same questions and answers." }, "images": { "type": "array", "items": { "type": "string" }, "description": "Images for Clef to read, up to 4. Each entry is a URL or a data URL (PNG, JPEG, or WebP). A Jev call that includes images is rejected." } }, "required": ["state", "questions"] },
5133
+ outputSchema: { "type": "object", "properties": { "model": { "type": "string", "description": "Versioned model id that answered, such as jev-1.13.0." }, "answers": { "type": "object", "properties": {}, "required": [], "description": "One answer per question, under the same ids." }, "usage": { "type": "object", "properties": { "input_tokens": { "type": "number" }, "output_tokens": { "type": "number" } }, "required": ["input_tokens", "output_tokens"], "description": "Token counts for the call. Input tokens are what the model bills." } }, "required": ["model", "answers", "usage"] }
5118
5134
  },
5119
5135
  "updateGmailLabels": {
5120
5136
  stepType: "updateGmailLabels",
@@ -5149,7 +5165,7 @@ var stepMetadata = {
5149
5165
  description: "Legacy v1 data sources. v2 apps should use `dataSources.defineDataSource()` from @mindstudio-ai/agent instead, which owns parsing, chunking, embedding and citations. Upload a file into an existing data source from a URL or raw text content.",
5150
5166
  usageNotes: '- If "file" is a single URL, the file is downloaded from that URL and uploaded.\n- If "file" is any other string, a .txt document is created from that content and uploaded.\n- The block waits (polls) for processing to complete before transitioning, up to 5 minutes.\n- Once processing finishes, vectors are loaded into Milvus so the data source is immediately queryable.\n- Supported file types (when using a URL) are the same as the data source upload UI (PDF, DOCX, TXT, etc.).',
5151
5167
  inputSchema: { "type": "object", "properties": { "dataSourceId": { "type": "string", "description": "ID of the target data source (supports variable interpolation)" }, "file": { "type": "string", "description": "A URL to download, or raw text content to create a .txt document from (supports variable interpolation)" }, "fileName": { "type": "string", "description": "Display name for the document (supports variable interpolation)" } }, "required": ["dataSourceId", "file", "fileName"] },
5152
- outputSchema: { "description": "This step does not produce output data." }
5168
+ outputSchema: { "type": "object", "properties": { "documentId": { "type": "string", "description": "ID of the uploaded document" }, "dataSourceId": { "type": "string", "description": "ID of the data source it was uploaded to" }, "fileName": { "type": "string", "description": "Resolved file name" } }, "required": ["documentId", "dataSourceId", "fileName"] }
5153
5169
  },
5154
5170
  "upscaleImage": {
5155
5171
  stepType: "upscaleImage",
@@ -6495,6 +6511,12 @@ var toStepLogEvent = (event) => ({
6495
6511
  ...event.ephemeral === true ? { ephemeral: true } : {},
6496
6512
  ...typeof event.progress === "number" ? { progress: event.progress } : {}
6497
6513
  });
6514
+ var stepFailure = (stepType, failure) => new MindStudioError(
6515
+ `[${stepType}] ${typeof failure.error === "string" && failure.error || "Step execution failed."}`,
6516
+ errorCodeFrom(failure, "step_error"),
6517
+ typeof failure.code === "number" ? failure.code : 500,
6518
+ failure
6519
+ );
6498
6520
  var MindStudioAgent = class {
6499
6521
  /** @internal */
6500
6522
  _httpConfig;
@@ -6685,11 +6707,7 @@ var MindStudioAgent = class {
6685
6707
  continue;
6686
6708
  }
6687
6709
  if (poll.status === "error") {
6688
- throw new MindStudioError(
6689
- `[${stepType}] ${poll.error ?? "Step execution failed."}`,
6690
- "step_error",
6691
- 500
6692
- );
6710
+ throw stepFailure(stepType, poll);
6693
6711
  }
6694
6712
  let output;
6695
6713
  if (poll.output != null) {
@@ -6817,11 +6835,7 @@ var MindStudioAgent = class {
6817
6835
  billingEvents: event.billingEvents
6818
6836
  };
6819
6837
  } else if (event.type === "error") {
6820
- throw new MindStudioError(
6821
- `[${stepType}] ${event.error || "Step execution failed"}`,
6822
- "step_error",
6823
- 500
6824
- );
6838
+ throw stepFailure(stepType, event);
6825
6839
  }
6826
6840
  } catch (err) {
6827
6841
  if (err instanceof MindStudioError) {
@@ -6841,11 +6855,7 @@ var MindStudioAgent = class {
6841
6855
  billingEvents: event.billingEvents
6842
6856
  };
6843
6857
  } else if (event.type === "error") {
6844
- throw new MindStudioError(
6845
- event.error || "Step execution failed",
6846
- "step_error",
6847
- 500
6848
- );
6858
+ throw stepFailure(stepType, event);
6849
6859
  } else if (event.type === "log") {
6850
6860
  options.onLog(toStepLogEvent(event));
6851
6861
  }
@@ -6975,8 +6985,9 @@ var MindStudioAgent = class {
6975
6985
  if (poll.status === "error") {
6976
6986
  throw new MindStudioError(
6977
6987
  poll.error ?? "Batch execution failed.",
6978
- "batch_execution_error",
6979
- 500
6988
+ errorCodeFrom(poll, "batch_execution_error"),
6989
+ typeof poll.code === "number" ? poll.code : 500,
6990
+ poll
6980
6991
  );
6981
6992
  }
6982
6993
  const results = await Promise.all(
@@ -7973,41 +7984,40 @@ var MindStudioAgent = class {
7973
7984
  return {
7974
7985
  defineTable(name, options) {
7975
7986
  const databaseHint = options?.database;
7987
+ const target = () => {
7988
+ const databases = agent._getContext()?.databases ?? [];
7989
+ const database = databaseHint ? databases.find(
7990
+ (d) => d.id === databaseHint || d.name === databaseHint
7991
+ ) : databases.find((d) => d.tables.some((t) => t.name === name));
7992
+ return {
7993
+ databaseId: database?.id ?? databases[0]?.id ?? "",
7994
+ columns: database?.tables.find((t) => t.name === name)?.schema ?? []
7995
+ };
7996
+ };
7997
+ const authTable = () => {
7998
+ const ac = agent._getContext()?.authConfig;
7999
+ return ac?.table === name ? ac : void 0;
8000
+ };
7976
8001
  const tableConfig = {
7977
- databaseId: "",
8002
+ get databaseId() {
8003
+ return target().databaseId;
8004
+ },
7978
8005
  tableName: name,
7979
- columns: [],
8006
+ get columns() {
8007
+ return target().columns;
8008
+ },
7980
8009
  unique: options?.unique,
7981
8010
  defaults: options?.defaults,
8011
+ get managedColumns() {
8012
+ return authTable()?.columns;
8013
+ },
8014
+ get syncRoles() {
8015
+ return authTable()?.columns.roles ? agent._syncRoles.bind(agent) : void 0;
8016
+ },
8017
+ ready: () => agent.ensureContext(),
7982
8018
  executeBatch: async (queries) => {
7983
8019
  await agent.ensureContext();
7984
- const ctx = agent._getContext();
7985
- const ac = ctx.authConfig;
7986
- if (ac && ac.table === name && !tableConfig.managedColumns) {
7987
- tableConfig.managedColumns = ac.columns;
7988
- if (ac.columns.roles) {
7989
- tableConfig.syncRoles = agent._syncRoles.bind(agent);
7990
- }
7991
- }
7992
- const databases = ctx.databases;
7993
- let targetDb;
7994
- if (databaseHint) {
7995
- targetDb = databases.find(
7996
- (d) => d.id === databaseHint || d.name === databaseHint
7997
- );
7998
- } else {
7999
- targetDb = databases.find(
8000
- (d) => d.tables.some((t) => t.name === name)
8001
- );
8002
- }
8003
- if (tableConfig.columns.length === 0 && targetDb) {
8004
- const tableSchema = targetDb.tables.find((t) => t.name === name);
8005
- if (tableSchema) {
8006
- tableConfig.columns = tableSchema.schema;
8007
- }
8008
- }
8009
- const databaseId = targetDb?.id ?? databases[0]?.id ?? "";
8010
- return agent._executeDbBatch(databaseId, queries);
8020
+ return agent._executeDbBatch(tableConfig.databaseId, queries);
8011
8021
  }
8012
8022
  };
8013
8023
  return new Table(tableConfig);
@@ -8025,15 +8035,12 @@ var MindStudioAgent = class {
8025
8035
  // (the same deferral lazy defineTable uses).
8026
8036
  sql: (query, params, options) => {
8027
8037
  validateRawSql(query);
8038
+ const databaseId = () => resolveDatabase(agent._getContext().databases, options?.database).id;
8028
8039
  return new RawQuery(
8029
- "",
8040
+ databaseId,
8030
8041
  async (queries) => {
8031
8042
  await agent.ensureContext();
8032
- const database = resolveDatabase(
8033
- agent._getContext().databases,
8034
- options?.database
8035
- );
8036
- return agent._executeDbBatch(database.id, queries);
8043
+ return agent._executeDbBatch(databaseId(), queries);
8037
8044
  },
8038
8045
  { sql: query, params: params?.map(serializeParam) }
8039
8046
  );
@@ -8963,14 +8970,14 @@ var monacoSnippets = {
8963
8970
  "codaGetPage": { fields: [["docId", "string"], ["pageId", "string"]], outputKeys: ["content"] },
8964
8971
  "codaGetTableRows": { fields: [["docId", "string"], ["tableId", "string"]], outputKeys: ["rows"] },
8965
8972
  "convertPdfToImages": { fields: [["pdfUrl", "string"]], outputKeys: ["imageUrls"] },
8966
- "createDataSource": { fields: [["name", "string"]], outputKeys: [] },
8973
+ "createDataSource": { fields: [["name", "string"]], outputKeys: ["dataSourceId", "name"] },
8967
8974
  "createGmailDraft": { fields: [["to", "string"], ["subject", "string"], ["message", "string"], ["messageType", ["plain", "html", "markdown"]]], outputKeys: ["draftId"] },
8968
8975
  "createGoogleCalendarEvent": { fields: [["summary", "string"], ["startDateTime", "string"], ["endDateTime", "string"]], outputKeys: ["eventId", "htmlLink"] },
8969
8976
  "createGoogleDoc": { fields: [["title", "string"], ["text", "string"], ["textType", ["plain", "html", "markdown"]]], outputKeys: ["documentUrl"] },
8970
8977
  "createGoogleSheet": { fields: [["title", "string"], ["text", "string"]], outputKeys: ["spreadsheetUrl"] },
8971
8978
  "decomposeImage": { fields: [["image", "string"]], outputKeys: ["imageUrls"] },
8972
- "deleteDataSource": { fields: [["dataSourceId", "string"]], outputKeys: [] },
8973
- "deleteDataSourceDocument": { fields: [["dataSourceId", "string"], ["documentId", "string"]], outputKeys: [] },
8979
+ "deleteDataSource": { fields: [["dataSourceId", "string"]], outputKeys: ["dataSourceId"] },
8980
+ "deleteDataSourceDocument": { fields: [["dataSourceId", "string"], ["documentId", "string"]], outputKeys: ["dataSourceId", "documentId"] },
8974
8981
  "deleteGmailEmail": { fields: [["messageId", "string"]], outputKeys: [] },
8975
8982
  "deleteGoogleCalendarEvent": { fields: [["eventId", "string"]], outputKeys: [] },
8976
8983
  "deleteGoogleSheetRows": { fields: [["documentId", "string"], ["startRow", "string"], ["endRow", "string"]], outputKeys: [] },
@@ -8982,7 +8989,7 @@ var monacoSnippets = {
8982
8989
  "enrichPerson": { fields: [["params", "object"]], outputKeys: ["data"] },
8983
8990
  "extractAudioFromVideo": { fields: [["videoUrl", "string"]], outputKeys: ["audioUrl"] },
8984
8991
  "extractText": { fields: [["url", "string"]], outputKeys: ["text"] },
8985
- "fetchDataSourceDocument": { fields: [["dataSourceId", "string"], ["documentId", "string"]], outputKeys: [] },
8992
+ "fetchDataSourceDocument": { fields: [["dataSourceId", "string"], ["documentId", "string"]], outputKeys: ["documentId", "name", "content", "summary", "numWords"] },
8986
8993
  "fetchGoogleDoc": { fields: [["documentId", "string"], ["exportType", ["html", "markdown", "json", "plain"]]], outputKeys: ["content"] },
8987
8994
  "fetchGoogleSheet": { fields: [["spreadsheetId", "string"], ["range", "string"], ["exportType", ["csv", "json"]]], outputKeys: ["content"] },
8988
8995
  "fetchSlackChannelHistory": { fields: [["channelId", "string"]], outputKeys: ["messages"] },
@@ -8993,17 +9000,17 @@ var monacoSnippets = {
8993
9000
  "generate3dModel": { fields: [], outputKeys: ["glbUrl"] },
8994
9001
  "generateAsset": { fields: [["source", "string"], ["sourceType", ["html", "markdown", "spa", "raw", "dynamic", "customInterface"]], ["outputFormat", ["pdf", "png", "html", "mp4", "openGraph"]], ["pageSize", ["full", "letter", "A4", "custom"]], ["testData", "object"]], outputKeys: ["url"] },
8995
9002
  "generateImage": { fields: [["prompt", "string"]], outputKeys: ["imageUrl"] },
8996
- "generateLipsync": { fields: [], outputKeys: [] },
8997
- "generateMusic": { fields: [["text", "string"]], outputKeys: [] },
9003
+ "generateLipsync": { fields: [], outputKeys: ["videoUrl"] },
9004
+ "generateMusic": { fields: [["text", "string"]], outputKeys: ["audioUrl"] },
8998
9005
  "generatePdf": { fields: [["source", "string"], ["sourceType", ["html", "markdown", "spa", "raw", "dynamic", "customInterface"]], ["outputFormat", ["pdf", "png", "html", "mp4", "openGraph"]], ["pageSize", ["full", "letter", "A4", "custom"]], ["testData", "object"]], outputKeys: ["url"] },
8999
9006
  "generateSound": { fields: [["text", "string"]], outputKeys: ["audioUrl"] },
9000
9007
  "generateStaticVideoFromImage": { fields: [["imageUrl", "string"], ["duration", "string"]], outputKeys: ["videoUrl"] },
9001
9008
  "generateText": { fields: [["message", "string"]], outputKeys: ["content"] },
9002
9009
  "generateVideo": { fields: [["prompt", "string"]], outputKeys: ["videoUrl"] },
9003
- "getGmailAttachments": { fields: [["messageId", "string"]], outputKeys: [] },
9010
+ "getGmailAttachments": { fields: [["messageId", "string"]], outputKeys: ["attachments"] },
9004
9011
  "getGmailDraft": { fields: [["draftId", "string"]], outputKeys: ["draftId", "messageId", "subject", "to", "from", "body"] },
9005
9012
  "getGmailEmail": { fields: [["messageId", "string"]], outputKeys: ["messageId", "subject", "from", "to", "date", "body", "labels"] },
9006
- "getGmailUnreadCount": { fields: [], outputKeys: [] },
9013
+ "getGmailUnreadCount": { fields: [], outputKeys: ["unreadCount"] },
9007
9014
  "getGoogleCalendarEvent": { fields: [["eventId", "string"], ["exportType", ["json", "text"]]], outputKeys: ["event"] },
9008
9015
  "getGoogleDriveFile": { fields: [["fileId", "string"]], outputKeys: ["url", "name", "mimeType", "size"] },
9009
9016
  "getGoogleSheetInfo": { fields: [["documentId", "string"]], outputKeys: ["title", "sheets"] },
@@ -9021,12 +9028,12 @@ var monacoSnippets = {
9021
9028
  "imageRemoveWatermark": { fields: [["imageUrl", "string"], ["engine", "string"]], outputKeys: ["imageUrl"] },
9022
9029
  "importFromUrl": { fields: [["url", "string"]], outputKeys: ["fileUrl", "key", "size", "contentType"] },
9023
9030
  "insertVideoClips": { fields: [["baseVideoUrl", "string"], ["overlayVideos", "array"]], outputKeys: ["videoUrl"] },
9024
- "listDataSources": { fields: [], outputKeys: [] },
9031
+ "listDataSources": { fields: [], outputKeys: ["dataSources"] },
9025
9032
  "listGmailDrafts": { fields: [["exportType", ["json", "text"]]], outputKeys: ["drafts"] },
9026
- "listGmailLabels": { fields: [], outputKeys: [] },
9033
+ "listGmailLabels": { fields: [], outputKeys: ["labels"] },
9027
9034
  "listGoogleCalendarEvents": { fields: [["limit", "number"], ["exportType", ["json", "text"]]], outputKeys: ["events"] },
9028
9035
  "listGoogleDriveFiles": { fields: [["exportType", ["json", "text"]]], outputKeys: ["files"] },
9029
- "listRecentGmailEmails": { fields: [["exportType", ["json", "text"]], ["limit", "string"]], outputKeys: [] },
9036
+ "listRecentGmailEmails": { fields: [["exportType", ["json", "text"]], ["limit", "string"]], outputKeys: ["emails"] },
9030
9037
  "logic": { fields: [["context", "string"], ["cases", "array"]], outputKeys: ["selectedCase"] },
9031
9038
  "makeDotComRunScenario": { fields: [["webhookUrl", "string"], ["input", "object"]], outputKeys: ["data"] },
9032
9039
  "mergeAudio": { fields: [["mp3Urls", "array"]], outputKeys: ["audioUrl"] },
@@ -9075,11 +9082,11 @@ var monacoSnippets = {
9075
9082
  "searchYoutube": { fields: [["query", "string"], ["limitPages", "string"], ["filter", "string"], ["filterType", "string"]], outputKeys: ["results"] },
9076
9083
  "searchYoutubeTrends": { fields: [["bp", ["now", "music", "gaming", "films"]], ["hl", "string"], ["gl", "string"]], outputKeys: [] },
9077
9084
  "sendEmail": { fields: [["subject", "string"], ["body", "string"]], outputKeys: ["recipients", "cc", "bcc", "from", "suppressed", "batchId"] },
9078
- "sendGmailDraft": { fields: [["draftId", "string"]], outputKeys: [] },
9085
+ "sendGmailDraft": { fields: [["draftId", "string"]], outputKeys: ["messageId"] },
9079
9086
  "sendGmailMessage": { fields: [["to", "string"], ["subject", "string"], ["message", "string"], ["messageType", ["plain", "html", "markdown"]]], outputKeys: ["messageId"] },
9080
9087
  "sendSlackDirectMessage": { fields: [["slackUserId", "string"], ["messageType", ["string", "blocks"]], ["message", "string"]], outputKeys: [] },
9081
9088
  "sendSMS": { fields: [["body", "string"]], outputKeys: [] },
9082
- "setGmailReadStatus": { fields: [["messageIds", "string"], ["markAsRead", "boolean"]], outputKeys: [] },
9089
+ "setGmailReadStatus": { fields: [["messageIds", "string"], ["markAsRead", "boolean"]], outputKeys: ["messageIds"] },
9083
9090
  "setRunTitle": { fields: [["title", "string"]], outputKeys: [] },
9084
9091
  "setVariable": { fields: [["value", "string"]], outputKeys: [] },
9085
9092
  "textToSpeech": { fields: [["text", "string"]], outputKeys: ["audioUrl"] },
@@ -9090,7 +9097,7 @@ var monacoSnippets = {
9090
9097
  "updateGoogleCalendarEvent": { fields: [["eventId", "string"]], outputKeys: ["eventId", "htmlLink"] },
9091
9098
  "updateGoogleDoc": { fields: [["documentId", "string"], ["text", "string"], ["textType", ["plain", "html", "markdown"]], ["operationType", ["addToTop", "addToBottom", "overwrite"]]], outputKeys: ["documentUrl"] },
9092
9099
  "updateGoogleSheet": { fields: [["text", "string"], ["spreadsheetId", "string"], ["range", "string"], ["operationType", ["addToBottom", "overwrite", "range"]]], outputKeys: ["spreadsheetUrl"] },
9093
- "uploadDataSourceDocument": { fields: [["dataSourceId", "string"], ["file", "string"], ["fileName", "string"]], outputKeys: [] },
9100
+ "uploadDataSourceDocument": { fields: [["dataSourceId", "string"], ["file", "string"], ["fileName", "string"]], outputKeys: ["documentId", "dataSourceId", "fileName"] },
9094
9101
  "upscaleImage": { fields: [["imageUrl", "string"], ["targetResolution", ["2k", "4k", "8k"]], ["engine", ["standard", "pro"]]], outputKeys: ["imageUrl"] },
9095
9102
  "upscaleVideo": { fields: [["videoUrl", "string"], ["targetResolution", ["720p", "1080p", "2K", "4K"]], ["engine", ["standard", "pro", "ultimate", "flashvsr", "seedance", "seedvr2", "runwayml/upscale-v1"]]], outputKeys: ["videoUrl"] },
9096
9103
  "userMessage": { fields: [["message", "string"]], outputKeys: ["content"] },