@mindstudio-ai/agent 0.1.18 → 0.1.19

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.
@@ -2201,10 +2201,11 @@ var init_query = __esm({
2201
2201
  limit: this._limit,
2202
2202
  offset: this._offset
2203
2203
  });
2204
- return { query, fallbackQuery: null, config: this._config };
2204
+ return { type: "query", query, fallbackQuery: null, config: this._config };
2205
2205
  }
2206
2206
  const fallbackQuery = buildSelect(this._config.tableName);
2207
2207
  return {
2208
+ type: "query",
2208
2209
  query: null,
2209
2210
  fallbackQuery,
2210
2211
  config: this._config,
@@ -2329,12 +2330,96 @@ var init_query = __esm({
2329
2330
  }
2330
2331
  });
2331
2332
 
2333
+ // src/db/mutation.ts
2334
+ var Mutation;
2335
+ var init_mutation = __esm({
2336
+ "src/db/mutation.ts"() {
2337
+ "use strict";
2338
+ Mutation = class _Mutation {
2339
+ /** @internal */
2340
+ _config;
2341
+ /** @internal */
2342
+ _queries;
2343
+ /** @internal */
2344
+ _processResult;
2345
+ /** @internal Non-batchable executor for complex mutations (e.g. removeAll JS fallback). */
2346
+ _executor;
2347
+ constructor(config, queries, processResult) {
2348
+ this._config = config;
2349
+ this._queries = queries;
2350
+ this._processResult = processResult;
2351
+ this._executor = void 0;
2352
+ }
2353
+ /**
2354
+ * Create a non-batchable mutation that wraps an async executor.
2355
+ * Used for operations that require multi-step execution (e.g. removeAll
2356
+ * with a JS-fallback predicate: fetch all rows → filter → delete).
2357
+ *
2358
+ * Works fine when awaited standalone. Throws if passed to db.batch().
2359
+ *
2360
+ * @internal
2361
+ */
2362
+ static fromExecutor(config, executor) {
2363
+ const m = new _Mutation(config, [], () => void 0);
2364
+ Object.defineProperty(m, "_executor", { value: executor });
2365
+ return m;
2366
+ }
2367
+ // -------------------------------------------------------------------------
2368
+ // PromiseLike — executes on await
2369
+ // -------------------------------------------------------------------------
2370
+ then(onfulfilled, onrejected) {
2371
+ return this._execute().then(onfulfilled, onrejected);
2372
+ }
2373
+ // -------------------------------------------------------------------------
2374
+ // Batch compilation — used by db.batch()
2375
+ // -------------------------------------------------------------------------
2376
+ /**
2377
+ * @internal Compile this mutation into SQL for batch execution.
2378
+ * Returns the queries and a result processor.
2379
+ *
2380
+ * Throws if this is a non-batchable mutation (created via fromExecutor).
2381
+ */
2382
+ _compile() {
2383
+ if (this._executor) {
2384
+ throw new Error(
2385
+ "This operation cannot be batched (e.g. removeAll with a predicate that cannot compile to SQL). Await it separately."
2386
+ );
2387
+ }
2388
+ return {
2389
+ type: "mutation",
2390
+ queries: this._queries,
2391
+ config: this._config,
2392
+ processResult: this._processResult
2393
+ };
2394
+ }
2395
+ /**
2396
+ * @internal Process raw SQL results into the typed result.
2397
+ * Used by db.batch() after executing the compiled queries.
2398
+ */
2399
+ static _processResults(results, compiled) {
2400
+ return compiled.processResult(results);
2401
+ }
2402
+ // -------------------------------------------------------------------------
2403
+ // Execution
2404
+ // -------------------------------------------------------------------------
2405
+ async _execute() {
2406
+ if (this._executor) {
2407
+ return this._executor();
2408
+ }
2409
+ const results = await this._config.executeBatch(this._queries);
2410
+ return this._processResult(results);
2411
+ }
2412
+ };
2413
+ }
2414
+ });
2415
+
2332
2416
  // src/db/table.ts
2333
2417
  var Table;
2334
2418
  var init_table = __esm({
2335
2419
  "src/db/table.ts"() {
2336
2420
  "use strict";
2337
2421
  init_query();
2422
+ init_mutation();
2338
2423
  init_predicate();
2339
2424
  init_sql();
2340
2425
  Table = class {
@@ -2399,7 +2484,7 @@ var init_table = __esm({
2399
2484
  sortBy(accessor) {
2400
2485
  return new Query(this._config).sortBy(accessor);
2401
2486
  }
2402
- async push(data) {
2487
+ push(data) {
2403
2488
  const isArray = Array.isArray(data);
2404
2489
  const items = isArray ? data : [data];
2405
2490
  const queries = items.map(
@@ -2409,71 +2494,76 @@ var init_table = __esm({
2409
2494
  this._config.columns
2410
2495
  )
2411
2496
  );
2412
- const results = await this._config.executeBatch(queries);
2413
- const rows = results.map((r) => {
2414
- if (r.rows.length > 0) {
2415
- return deserializeRow(
2416
- r.rows[0],
2417
- this._config.columns
2418
- );
2419
- }
2420
- return void 0;
2497
+ return new Mutation(this._config, queries, (results) => {
2498
+ const rows = results.map((r) => {
2499
+ if (r.rows.length > 0) {
2500
+ return deserializeRow(
2501
+ r.rows[0],
2502
+ this._config.columns
2503
+ );
2504
+ }
2505
+ return void 0;
2506
+ });
2507
+ return isArray ? rows : rows[0];
2421
2508
  });
2422
- return isArray ? rows : rows[0];
2423
2509
  }
2424
2510
  /**
2425
2511
  * Update a row by ID. Only the provided fields are changed.
2426
2512
  * Returns the updated row via `UPDATE ... RETURNING *`.
2427
2513
  */
2428
- async update(id, data) {
2514
+ update(id, data) {
2429
2515
  const query = buildUpdate(
2430
2516
  this._config.tableName,
2431
2517
  id,
2432
2518
  data,
2433
2519
  this._config.columns
2434
2520
  );
2435
- const results = await this._config.executeBatch([query]);
2436
- return deserializeRow(
2437
- results[0].rows[0],
2438
- this._config.columns
2521
+ return new Mutation(
2522
+ this._config,
2523
+ [query],
2524
+ (results) => deserializeRow(
2525
+ results[0].rows[0],
2526
+ this._config.columns
2527
+ )
2439
2528
  );
2440
2529
  }
2441
- async remove(id) {
2530
+ remove(id) {
2442
2531
  const query = buildDelete(this._config.tableName, `id = ?`, [id]);
2443
- await this._config.executeBatch([query]);
2532
+ return new Mutation(this._config, [query], () => void 0);
2444
2533
  }
2445
2534
  /**
2446
2535
  * Remove all rows matching a predicate. Returns the count removed.
2447
2536
  */
2448
- async removeAll(predicate) {
2537
+ removeAll(predicate) {
2449
2538
  const compiled = compilePredicate(predicate);
2450
2539
  if (compiled.type === "sql") {
2451
2540
  const query = buildDelete(this._config.tableName, compiled.where);
2452
- const results = await this._config.executeBatch([query]);
2453
- return results[0].changes;
2454
- }
2455
- console.warn(
2456
- `[mindstudio] removeAll predicate on ${this._config.tableName} could not be compiled to SQL \u2014 fetching all rows first`
2457
- );
2458
- const allQuery = buildSelect(this._config.tableName);
2459
- const allResults = await this._config.executeBatch([allQuery]);
2460
- const allRows = allResults[0].rows.map(
2461
- (r) => deserializeRow(
2462
- r,
2463
- this._config.columns
2464
- )
2465
- );
2466
- const matching = allRows.filter((row) => predicate(row));
2467
- if (matching.length === 0) return 0;
2468
- const deleteQueries = matching.filter((row) => row.id).map((row) => buildDelete(this._config.tableName, `id = ?`, [row.id]));
2469
- if (deleteQueries.length > 0) {
2470
- await this._config.executeBatch(deleteQueries);
2541
+ return new Mutation(this._config, [query], (results) => results[0].changes);
2471
2542
  }
2472
- return matching.length;
2543
+ return Mutation.fromExecutor(this._config, async () => {
2544
+ console.warn(
2545
+ `[mindstudio] removeAll predicate on ${this._config.tableName} could not be compiled to SQL \u2014 fetching all rows first`
2546
+ );
2547
+ const allQuery = buildSelect(this._config.tableName);
2548
+ const allResults = await this._config.executeBatch([allQuery]);
2549
+ const allRows = allResults[0].rows.map(
2550
+ (r) => deserializeRow(
2551
+ r,
2552
+ this._config.columns
2553
+ )
2554
+ );
2555
+ const matching = allRows.filter((row) => predicate(row));
2556
+ if (matching.length === 0) return 0;
2557
+ const deleteQueries = matching.filter((row) => row.id).map((row) => buildDelete(this._config.tableName, `id = ?`, [row.id]));
2558
+ if (deleteQueries.length > 0) {
2559
+ await this._config.executeBatch(deleteQueries);
2560
+ }
2561
+ return matching.length;
2562
+ });
2473
2563
  }
2474
- async clear() {
2564
+ clear() {
2475
2565
  const query = buildDelete(this._config.tableName);
2476
- await this._config.executeBatch([query]);
2566
+ return new Mutation(this._config, [query], () => void 0);
2477
2567
  }
2478
2568
  };
2479
2569
  }
@@ -2501,44 +2591,64 @@ function createDb(databases, executeBatch) {
2501
2591
  ago: (ms) => Date.now() - ms,
2502
2592
  fromNow: (ms) => Date.now() + ms,
2503
2593
  // --- Batch execution ---
2504
- batch: ((...queries) => {
2594
+ batch: ((...operations) => {
2505
2595
  return (async () => {
2506
- const compiled = queries.map((q) => {
2507
- if (!(q instanceof Query)) {
2508
- throw new MindStudioError(
2509
- "db.batch() only accepts Query objects (from .filter(), .sortBy(), etc.)",
2510
- "invalid_batch_query",
2511
- 400
2512
- );
2596
+ const compiled = operations.map((op) => {
2597
+ if (op instanceof Query) {
2598
+ return op._compile();
2599
+ }
2600
+ if (op instanceof Mutation) {
2601
+ return op._compile();
2513
2602
  }
2514
- return q._compile();
2603
+ throw new MindStudioError(
2604
+ "db.batch() only accepts Query and Mutation objects (from .filter(), .update(), .push(), etc.)",
2605
+ "invalid_batch_operation",
2606
+ 400
2607
+ );
2515
2608
  });
2516
2609
  const groups = /* @__PURE__ */ new Map();
2517
2610
  for (let i = 0; i < compiled.length; i++) {
2518
2611
  const c = compiled[i];
2519
2612
  const dbId = c.config.databaseId;
2520
- const sqlQuery = c.query ?? c.fallbackQuery;
2521
2613
  if (!groups.has(dbId)) groups.set(dbId, []);
2522
- groups.get(dbId).push({ index: i, sqlQuery });
2614
+ if (c.type === "query") {
2615
+ const sqlQuery = c.query ?? c.fallbackQuery;
2616
+ groups.get(dbId).push({ opIndex: i, sqlQueries: [sqlQuery] });
2617
+ } else {
2618
+ groups.get(dbId).push({ opIndex: i, sqlQueries: c.queries });
2619
+ }
2523
2620
  }
2524
- const allResults = new Array(compiled.length);
2621
+ const opResults = /* @__PURE__ */ new Map();
2525
2622
  await Promise.all(
2526
2623
  Array.from(groups.entries()).map(async ([dbId, entries]) => {
2527
- const sqlQueries = entries.map((e) => e.sqlQuery);
2528
- const results = await executeBatch(dbId, sqlQueries);
2529
- for (let i = 0; i < entries.length; i++) {
2530
- allResults[entries[i].index] = results[i];
2624
+ const flatQueries = [];
2625
+ const slices = [];
2626
+ for (const entry of entries) {
2627
+ slices.push({
2628
+ opIndex: entry.opIndex,
2629
+ start: flatQueries.length,
2630
+ count: entry.sqlQueries.length
2631
+ });
2632
+ flatQueries.push(...entry.sqlQueries);
2633
+ }
2634
+ const results = await executeBatch(dbId, flatQueries);
2635
+ for (const { opIndex, start, count } of slices) {
2636
+ opResults.set(opIndex, results.slice(start, start + count));
2531
2637
  }
2532
2638
  })
2533
2639
  );
2534
2640
  return compiled.map((c, i) => {
2535
- const result = allResults[i];
2536
- if (!c.query && c.predicates?.length) {
2537
- console.warn(
2538
- `[mindstudio] db.batch(): filter on ${c.config.tableName} could not be compiled to SQL \u2014 processing in JS`
2539
- );
2641
+ const results = opResults.get(i);
2642
+ if (c.type === "query") {
2643
+ if (!c.query && c.predicates?.length) {
2644
+ console.warn(
2645
+ `[mindstudio] db.batch(): filter on ${c.config.tableName} could not be compiled to SQL \u2014 processing in JS`
2646
+ );
2647
+ }
2648
+ return Query._processResults(results[0], c);
2649
+ } else {
2650
+ return Mutation._processResults(results, c);
2540
2651
  }
2541
- return Query._processResults(result, c);
2542
2652
  });
2543
2653
  })();
2544
2654
  })
@@ -2597,6 +2707,7 @@ var init_db = __esm({
2597
2707
  init_errors();
2598
2708
  init_table();
2599
2709
  init_query();
2710
+ init_mutation();
2600
2711
  init_table();
2601
2712
  }
2602
2713
  });
@@ -4282,15 +4393,24 @@ function summarizeInput(input) {
4282
4393
  }
4283
4394
  async function cmdAsk(question, options) {
4284
4395
  try {
4396
+ let lineBuffer = "";
4285
4397
  const response = await runAsk(question, options, (event) => {
4286
4398
  switch (event.type) {
4287
4399
  case "text":
4288
- process.stderr.write(event.text);
4400
+ lineBuffer += event.text;
4401
+ while (lineBuffer.includes("\n")) {
4402
+ const idx = lineBuffer.indexOf("\n");
4403
+ process.stderr.write(lineBuffer.slice(0, idx + 1));
4404
+ lineBuffer = lineBuffer.slice(idx + 1);
4405
+ }
4289
4406
  break;
4290
4407
  case "tool_start":
4408
+ if (lineBuffer) {
4409
+ process.stderr.write(lineBuffer + "\n");
4410
+ lineBuffer = "";
4411
+ }
4291
4412
  process.stderr.write(
4292
- `
4293
- ${ansi.cyan("\u27E1")} ${ansi.bold(event.name)} ${ansi.dim(summarizeInput(event.input))}
4413
+ ` ${ansi.cyan("\u27E1")} ${ansi.bold(event.name)} ${ansi.dim(summarizeInput(event.input))}
4294
4414
  `
4295
4415
  );
4296
4416
  break;
@@ -4298,6 +4418,9 @@ async function cmdAsk(question, options) {
4298
4418
  break;
4299
4419
  }
4300
4420
  });
4421
+ if (lineBuffer) {
4422
+ process.stderr.write(lineBuffer);
4423
+ }
4301
4424
  if (process.stdout.isTTY) {
4302
4425
  process.stderr.write("\n");
4303
4426
  } else {
@@ -4389,7 +4512,7 @@ async function startMcpServer(options) {
4389
4512
  capabilities: { tools: {} },
4390
4513
  serverInfo: {
4391
4514
  name: "mindstudio-agent",
4392
- version: "0.1.18"
4515
+ version: "0.1.19"
4393
4516
  },
4394
4517
  instructions: 'Welcome to MindStudio \u2014 a platform with 200+ AI models, 850+ third-party integrations, and pre-built agents.\n\nGetting started:\n1. Call `ask` with any question about the SDK \u2014 it knows every action, model, and connector and returns working code with real model IDs and config options. Examples: ask("generate an image with FLUX"), ask("what models support vision?"), ask("how do I send a Slack message?").\n2. Call `changeName` to set your display name \u2014 use your name or whatever your user calls you. This is how you\'ll appear in MindStudio request logs.\n3. If you have a profile picture or icon, call `uploadFile` to upload it, then `changeProfilePicture` with the returned URL.\n4. For manual browsing, call `listActions` to discover all available actions.\n\nThen use the tools to generate text, images, video, audio, search the web, work with data sources, run agents, and more.\n\nImportant:\n- AI-powered actions (text generation, image generation, video, audio, etc.) cost money. Before running these, call `estimateActionCost` and confirm with the user before proceeding \u2014 unless they\'ve explicitly told you to go ahead.\n- Not all agents from `listAgents` are configured for API use. Do not try to run an agent just because it appears in the list \u2014 it will likely fail. Only run agents the user specifically asks you to run.'
4395
4518
  });
@@ -5229,7 +5352,7 @@ function isNewerVersion(current, latest) {
5229
5352
  return false;
5230
5353
  }
5231
5354
  async function checkForUpdate() {
5232
- const currentVersion = "0.1.18";
5355
+ const currentVersion = "0.1.19";
5233
5356
  if (!currentVersion) return null;
5234
5357
  try {
5235
5358
  const { loadConfig: loadConfig2, saveConfig: saveConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
@@ -5258,7 +5381,7 @@ async function checkForUpdate() {
5258
5381
  }
5259
5382
  }
5260
5383
  function printUpdateNotice(latestVersion) {
5261
- const currentVersion = "0.1.18";
5384
+ const currentVersion = "0.1.19";
5262
5385
  process.stderr.write(
5263
5386
  `
5264
5387
  ${ansi2.cyanBright("Update available")} ${ansi2.gray(currentVersion + " \u2192")} ${ansi2.cyanBold(latestVersion)}
@@ -5313,7 +5436,7 @@ async function cmdLogin(options) {
5313
5436
  process.stderr.write("\n");
5314
5437
  printLogo();
5315
5438
  process.stderr.write("\n");
5316
- const ver = "0.1.18";
5439
+ const ver = "0.1.19";
5317
5440
  process.stderr.write(
5318
5441
  ` ${ansi2.bold("MindStudio Agent")} ${ver ? " " + ansi2.gray("v" + ver) : ""}
5319
5442
  `
@@ -5399,6 +5522,9 @@ async function cmdLogin(options) {
5399
5522
  ${ansi2.bold("Using with Claude Code?")} Run once to enable the MCP server:
5400
5523
  ${ansi2.cyan("claude mcp add mindstudio -- mindstudio mcp")}
5401
5524
 
5525
+ ${ansi2.bold("Need help?")} Ask the SDK anything:
5526
+ ${ansi2.cyan('mindstudio ask "how do I generate an image?"')}
5527
+
5402
5528
  `
5403
5529
  );
5404
5530
  return;
@@ -5612,6 +5738,12 @@ async function main() {
5612
5738
  const command = positionals[0];
5613
5739
  const updatePromise = command !== "mcp" && command !== "login" ? checkForUpdate() : Promise.resolve(null);
5614
5740
  try {
5741
+ if (command === "version" || command === "-v") {
5742
+ process.stdout.write(
5743
+ "0.1.19\n"
5744
+ );
5745
+ return;
5746
+ }
5615
5747
  if (command === "login") {
5616
5748
  await cmdLogin({
5617
5749
  baseUrl: values["base-url"]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindstudio-ai/agent",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "TypeScript SDK for MindStudio direct step execution",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",