@mindstudio-ai/agent 0.1.5 → 0.1.6

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.
@@ -682,8 +682,8 @@ var init_metadata = __esm({
682
682
  "postToX": {
683
683
  stepType: "postToX",
684
684
  description: "Create a post on X (Twitter) from the connected account.",
685
- usageNotes: "- Requires an X OAuth connection (connectionId).\n- Posts are plain text. Maximum 280 characters.",
686
- inputSchema: { "type": "object", "properties": { "text": { "type": "string", "description": "The text content of the post (max 280 characters)" }, "connectionId": { "type": "string", "description": "X (Twitter) OAuth connection ID" } }, "required": ["text"] },
685
+ usageNotes: "- Requires an X OAuth connection (connectionId).\n- Maximum 280 characters of text.\n- Optionally attach up to 4 media items (images, GIFs, or videos) via mediaUrls.\n- Media URLs must be publicly accessible. The service fetches and uploads them to X.\n- Supported formats: JPEG, PNG, GIF, WEBP, MP4. Images up to 5MB, videos up to 512MB.",
686
+ inputSchema: { "type": "object", "properties": { "text": { "type": "string", "description": "The text content of the post (max 280 characters)" }, "connectionId": { "type": "string", "description": "X (Twitter) OAuth connection ID" }, "mediaUrls": { "type": "array", "items": { "type": "string" }, "description": "Up to 4 URLs of images, GIFs, or videos to attach to the post" } }, "required": ["text"] },
687
687
  outputSchema: { "description": "This step does not produce output data." }
688
688
  },
689
689
  "postToZapier": {
@@ -1907,6 +1907,69 @@ var init_client = __esm({
1907
1907
  $billingEvents: billingEvents != null ? JSON.parse(billingEvents) : void 0
1908
1908
  };
1909
1909
  }
1910
+ /**
1911
+ * Execute multiple steps in parallel in a single request.
1912
+ *
1913
+ * All steps run in parallel on the server. Results are returned in the same
1914
+ * order as the input. Individual step failures do not affect other steps —
1915
+ * partial success is possible.
1916
+ *
1917
+ * ```ts
1918
+ * const { results } = await agent.executeStepBatch([
1919
+ * { stepType: 'generateImage', step: { prompt: 'a sunset' } },
1920
+ * { stepType: 'textToSpeech', step: { text: 'Hello world' } },
1921
+ * ]);
1922
+ * ```
1923
+ */
1924
+ async executeStepBatch(steps, options) {
1925
+ const threadId = options?.threadId ?? (this._reuseThreadId ? this._threadId : void 0);
1926
+ const { data } = await request(this._httpConfig, "POST", "/steps/execute-batch", {
1927
+ steps,
1928
+ ...options?.appId != null && { appId: options.appId },
1929
+ ...threadId != null && { threadId }
1930
+ });
1931
+ const results = await Promise.all(
1932
+ data.results.map(async (r) => {
1933
+ if (r.output != null) {
1934
+ return {
1935
+ stepType: r.stepType,
1936
+ output: r.output,
1937
+ billingCost: r.billingCost,
1938
+ error: r.error
1939
+ };
1940
+ }
1941
+ if (r.outputUrl) {
1942
+ const res = await fetch(r.outputUrl);
1943
+ if (!res.ok) {
1944
+ return {
1945
+ stepType: r.stepType,
1946
+ error: `Failed to fetch output from S3: ${res.status} ${res.statusText}`
1947
+ };
1948
+ }
1949
+ const envelope = await res.json();
1950
+ return {
1951
+ stepType: r.stepType,
1952
+ output: envelope.value,
1953
+ billingCost: r.billingCost
1954
+ };
1955
+ }
1956
+ return {
1957
+ stepType: r.stepType,
1958
+ billingCost: r.billingCost,
1959
+ error: r.error
1960
+ };
1961
+ })
1962
+ );
1963
+ if (this._reuseThreadId && data.threadId) {
1964
+ this._threadId = data.threadId;
1965
+ }
1966
+ return {
1967
+ results,
1968
+ totalBillingCost: data.totalBillingCost,
1969
+ appId: data.appId,
1970
+ threadId: data.threadId
1971
+ };
1972
+ }
1910
1973
  /**
1911
1974
  * Get the authenticated user's identity and organization info.
1912
1975
  *
@@ -2211,7 +2274,7 @@ async function startMcpServer(options) {
2211
2274
  capabilities: { tools: {} },
2212
2275
  serverInfo: {
2213
2276
  name: "mindstudio-agent",
2214
- version: "0.1.5"
2277
+ version: "0.1.6"
2215
2278
  },
2216
2279
  instructions: "Welcome to MindStudio \u2014 a platform with 200+ AI models, 850+ third-party integrations, and pre-built agents.\n\nGetting started:\n1. Call `listAgents` to verify your connection and see available agents.\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. This helps users identify your requests in their logs.\n4. 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."
2217
2280
  });
@@ -2292,6 +2355,10 @@ async function startMcpServer(options) {
2292
2355
  extension: ext,
2293
2356
  ...mimeType && { type: mimeType }
2294
2357
  });
2358
+ } else if (toolName === "executeBatch") {
2359
+ result = await getAgent().executeStepBatch(
2360
+ args.steps
2361
+ );
2295
2362
  } else if (toolName === "listAgents") {
2296
2363
  result = await getAgent().listAgents();
2297
2364
  } else if (toolName === "runAgent") {
@@ -2382,7 +2449,8 @@ var init_mcp = __esm({
2382
2449
  changeProfilePicture: "Update the profile picture of the authenticated agent.",
2383
2450
  uploadFile: "Upload a file to the MindStudio CDN.",
2384
2451
  listAgents: "List all pre-built agents in the organization.",
2385
- runAgent: "Run a pre-built agent and wait for the result."
2452
+ runAgent: "Run a pre-built agent and wait for the result.",
2453
+ executeBatch: "Execute multiple actions in parallel in a single request."
2386
2454
  };
2387
2455
  HELPER_TOOLS = [
2388
2456
  {
@@ -2550,6 +2618,37 @@ var init_mcp = __esm({
2550
2618
  required: ["filePath"]
2551
2619
  }
2552
2620
  },
2621
+ {
2622
+ name: "executeBatch",
2623
+ description: "Execute multiple actions in parallel in a single request. All steps run in parallel on the server. Results are returned in the same order as the input. Individual step failures do not affect other steps \u2014 partial success is possible. Maximum 50 steps per batch.",
2624
+ inputSchema: {
2625
+ type: "object",
2626
+ properties: {
2627
+ steps: {
2628
+ type: "array",
2629
+ description: "Array of steps to execute.",
2630
+ minItems: 1,
2631
+ maxItems: 50,
2632
+ items: {
2633
+ type: "object",
2634
+ properties: {
2635
+ stepType: {
2636
+ type: "string",
2637
+ description: 'The action type name (e.g. "generateImage", "textToSpeech").'
2638
+ },
2639
+ step: {
2640
+ type: "object",
2641
+ description: "Action input parameters.",
2642
+ additionalProperties: true
2643
+ }
2644
+ },
2645
+ required: ["stepType", "step"]
2646
+ }
2647
+ }
2648
+ },
2649
+ required: ["steps"]
2650
+ }
2651
+ },
2553
2652
  {
2554
2653
  name: "listAgents",
2555
2654
  description: "List all pre-built agents in the organization along with org metadata.",
@@ -2643,6 +2742,10 @@ function fatal(message) {
2643
2742
  process.stderr.write(JSON.stringify({ error: { message } }) + "\n");
2644
2743
  process.exit(1);
2645
2744
  }
2745
+ function usageBlock(lines) {
2746
+ process.stderr.write("\n" + lines.map((l) => " " + l).join("\n") + "\n\n");
2747
+ process.exit(1);
2748
+ }
2646
2749
  async function readStdin() {
2647
2750
  const chunks = [];
2648
2751
  for await (const chunk of process.stdin) {
@@ -2914,6 +3017,52 @@ async function cmdRun(appId, variables, options) {
2914
3017
  process.stdout.write(JSON.stringify(result, null, 2) + "\n");
2915
3018
  }
2916
3019
  }
3020
+ async function cmdBatch(input, options) {
3021
+ if (!Array.isArray(input)) {
3022
+ fatal(
3023
+ `Batch input must be a JSON array of { stepType, step } objects.
3024
+ Example: mindstudio batch '[{"stepType":"generateImage","step":{"prompt":"a cat"}}]'`
3025
+ );
3026
+ }
3027
+ for (let i = 0; i < input.length; i++) {
3028
+ const item = input[i];
3029
+ if (!item || typeof item !== "object" || !item.stepType || !item.step) {
3030
+ fatal(
3031
+ `Invalid step at index ${i}: each entry must have "stepType" and "step" fields.`
3032
+ );
3033
+ }
3034
+ }
3035
+ const { stepMetadata: stepMetadata2 } = await Promise.resolve().then(() => (init_metadata(), metadata_exports));
3036
+ const metaByName = new Map(
3037
+ Object.entries(stepMetadata2).map(([name, m]) => [name, m])
3038
+ );
3039
+ const steps = input.map(
3040
+ (item, i) => {
3041
+ let meta = metaByName.get(item.stepType);
3042
+ if (!meta) {
3043
+ const camel = item.stepType.replace(
3044
+ /-([a-z])/g,
3045
+ (_, c) => c.toUpperCase()
3046
+ );
3047
+ meta = metaByName.get(camel);
3048
+ }
3049
+ if (meta) {
3050
+ return { stepType: meta.stepType, step: item.step };
3051
+ }
3052
+ return { stepType: item.stepType, step: item.step };
3053
+ }
3054
+ );
3055
+ const agent = await createAgent(options);
3056
+ const result = await agent.executeStepBatch(steps, {
3057
+ appId: options.appId,
3058
+ threadId: options.threadId
3059
+ });
3060
+ if (options.noMeta) {
3061
+ process.stdout.write(JSON.stringify(result.results, null, 2) + "\n");
3062
+ } else {
3063
+ process.stdout.write(JSON.stringify(result, null, 2) + "\n");
3064
+ }
3065
+ }
2917
3066
  async function cmdUpload(filePath, options) {
2918
3067
  const ext = extname2(filePath).slice(1).toLowerCase();
2919
3068
  if (!ext) fatal("Cannot determine file extension. Please provide a file with an extension.");
@@ -2942,7 +3091,7 @@ function isNewerVersion(current, latest) {
2942
3091
  return false;
2943
3092
  }
2944
3093
  async function checkForUpdate() {
2945
- const currentVersion = "0.1.5";
3094
+ const currentVersion = "0.1.6";
2946
3095
  if (!currentVersion) return null;
2947
3096
  try {
2948
3097
  const { loadConfig: loadConfig2, saveConfig: saveConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
@@ -2971,7 +3120,7 @@ async function checkForUpdate() {
2971
3120
  }
2972
3121
  }
2973
3122
  function printUpdateNotice(latestVersion) {
2974
- const currentVersion = "0.1.5";
3123
+ const currentVersion = "0.1.6";
2975
3124
  process.stderr.write(
2976
3125
  `
2977
3126
  ${ansi.cyanBright("Update available")} ${ansi.gray(currentVersion + " \u2192")} ${ansi.cyanBold(latestVersion)}
@@ -3026,7 +3175,7 @@ async function cmdLogin(options) {
3026
3175
  process.stderr.write("\n");
3027
3176
  printLogo();
3028
3177
  process.stderr.write("\n");
3029
- const ver = "0.1.5";
3178
+ const ver = "0.1.6";
3030
3179
  process.stderr.write(
3031
3180
  ` ${ansi.bold("MindStudio Agent")} ${ver ? " " + ansi.gray("v" + ver) : ""}
3032
3181
  `
@@ -3350,10 +3499,82 @@ async function main() {
3350
3499
  });
3351
3500
  return;
3352
3501
  }
3502
+ if (command === "batch") {
3503
+ let input2;
3504
+ const firstArg = positionals[1];
3505
+ if (firstArg && firstArg.startsWith("[")) {
3506
+ try {
3507
+ input2 = parseJson5(firstArg);
3508
+ } catch {
3509
+ fatal(`Invalid JSON input: ${firstArg}`);
3510
+ }
3511
+ } else if (!process.stdin.isTTY) {
3512
+ const raw = (await readStdin()).trim();
3513
+ if (raw) {
3514
+ try {
3515
+ input2 = parseJson5(raw);
3516
+ } catch {
3517
+ fatal(`Invalid JSON on stdin: ${raw}`);
3518
+ }
3519
+ }
3520
+ }
3521
+ if (input2 === void 0) {
3522
+ usageBlock([
3523
+ "batch \u2014 Execute multiple actions in parallel",
3524
+ "",
3525
+ "Usage:",
3526
+ ` mindstudio batch '[{ "stepType": "<action>", "step": { ... } }, ...]'`,
3527
+ " cat steps.json | mindstudio batch",
3528
+ "",
3529
+ 'Each entry needs "stepType" (action name) and "step" (input object).',
3530
+ "Maximum 50 steps per batch. Results come back in the same order.",
3531
+ "Individual failures don't affect other steps.",
3532
+ "",
3533
+ "Options:",
3534
+ " --app-id <id> App ID for thread context",
3535
+ " --thread-id <id> Thread ID for state persistence",
3536
+ " --no-meta Strip top-level metadata from output",
3537
+ "",
3538
+ "Examples:",
3539
+ " mindstudio batch '[",
3540
+ ' { "stepType": "generateImage", "step": { "prompt": "a sunset" } },',
3541
+ ' { "stepType": "textToSpeech", "step": { "text": "hello world" } }',
3542
+ " ]'",
3543
+ "",
3544
+ ` echo '[{"stepType":"searchGoogle","step":{"query":"cats"}}]' | mindstudio batch`
3545
+ ]);
3546
+ }
3547
+ await cmdBatch(input2, {
3548
+ apiKey: values["api-key"],
3549
+ baseUrl: values["base-url"],
3550
+ appId: values["app-id"],
3551
+ threadId: values["thread-id"],
3552
+ noMeta: values["no-meta"]
3553
+ });
3554
+ return;
3555
+ }
3353
3556
  if (command === "run-agent") {
3354
3557
  const appId = positionals[1];
3355
3558
  if (!appId)
3356
- fatal("Missing app ID. Usage: mindstudio run-agent <appId> [json | --flags]");
3559
+ usageBlock([
3560
+ "run-agent \u2014 Run a pre-built agent and wait for the result",
3561
+ "",
3562
+ "Usage:",
3563
+ " mindstudio run-agent <appId> [json | --flags]",
3564
+ "",
3565
+ "Options:",
3566
+ " --workflow <name> Workflow to execute (default: app default)",
3567
+ ' --version <ver> App version, e.g. "draft" (default: "live")',
3568
+ " --output-key <key> Extract a single field from the result",
3569
+ " --no-meta Strip metadata from output",
3570
+ "",
3571
+ "Examples:",
3572
+ ' mindstudio run-agent abc123 --query "hello"',
3573
+ ` mindstudio run-agent abc123 '{"query": "hello"}'`,
3574
+ " mindstudio run-agent abc123 --workflow summarize --version draft",
3575
+ "",
3576
+ 'Tip: run "mindstudio agents" to list available agent IDs.'
3577
+ ]);
3357
3578
  const runArgv = process.argv.slice(process.argv.indexOf("run-agent") + 2);
3358
3579
  const stepArgs = [];
3359
3580
  for (let i = 0; i < runArgv.length; i++) {
@@ -3402,7 +3623,18 @@ async function main() {
3402
3623
  if (command === "upload") {
3403
3624
  const filePath = positionals[1];
3404
3625
  if (!filePath)
3405
- fatal("Missing file path. Usage: mindstudio upload <filepath>");
3626
+ usageBlock([
3627
+ "upload \u2014 Upload a file to the MindStudio CDN",
3628
+ "",
3629
+ "Usage:",
3630
+ " mindstudio upload <filepath>",
3631
+ "",
3632
+ "Returns the permanent public URL for the uploaded file.",
3633
+ "",
3634
+ "Examples:",
3635
+ " mindstudio upload photo.png",
3636
+ " mindstudio upload /path/to/document.pdf"
3637
+ ]);
3406
3638
  await cmdUpload(filePath, {
3407
3639
  apiKey: values["api-key"],
3408
3640
  baseUrl: values["base-url"]
@@ -3419,7 +3651,20 @@ async function main() {
3419
3651
  if (command === "list-models-by-type" || command === "list-models-summary-by-type") {
3420
3652
  type = positionals[1];
3421
3653
  if (!type)
3422
- fatal(`Missing model type. Usage: mindstudio ${command} <type>`);
3654
+ usageBlock([
3655
+ `${command} \u2014 List AI models filtered by type`,
3656
+ "",
3657
+ "Usage:",
3658
+ ` mindstudio ${command} <type>`,
3659
+ "",
3660
+ "Types:",
3661
+ " llm_chat, image_generation, video_generation,",
3662
+ " video_analysis, text_to_speech, vision, transcription",
3663
+ "",
3664
+ "Examples:",
3665
+ ` mindstudio ${command} image_generation`,
3666
+ ` mindstudio ${command} llm_chat`
3667
+ ]);
3423
3668
  }
3424
3669
  if (command === "list-models-summary" || command === "list-models-summary-by-type") {
3425
3670
  summary = true;
@@ -3449,9 +3694,18 @@ async function main() {
3449
3694
  if (command === "estimate-cost") {
3450
3695
  const stepMethod = positionals[1];
3451
3696
  if (!stepMethod)
3452
- fatal(
3453
- "Missing action name. Usage: mindstudio estimate-cost <action> [json | --flags]"
3454
- );
3697
+ usageBlock([
3698
+ "estimate-cost \u2014 Estimate the cost of an action before running it",
3699
+ "",
3700
+ "Usage:",
3701
+ " mindstudio estimate-cost <action> [json | --flags]",
3702
+ "",
3703
+ "Examples:",
3704
+ ' mindstudio estimate-cost generate-image --prompt "a sunset"',
3705
+ ` mindstudio estimate-cost generate-text '{"message": "hello"}'`,
3706
+ "",
3707
+ 'Tip: run "mindstudio list-actions" to see available actions.'
3708
+ ]);
3455
3709
  const costArgv = positionals.slice(2);
3456
3710
  let costInput;
3457
3711
  const firstArg = costArgv[0];
@@ -3473,7 +3727,15 @@ async function main() {
3473
3727
  if (command === "change-name") {
3474
3728
  const name = positionals[1];
3475
3729
  if (!name)
3476
- fatal("Missing name. Usage: mindstudio change-name <name>");
3730
+ usageBlock([
3731
+ "change-name \u2014 Update your display name",
3732
+ "",
3733
+ "Usage:",
3734
+ " mindstudio change-name <name>",
3735
+ "",
3736
+ "Examples:",
3737
+ ' mindstudio change-name "My Agent"'
3738
+ ]);
3477
3739
  await cmdChangeName(name, {
3478
3740
  apiKey: values["api-key"],
3479
3741
  baseUrl: values["base-url"]
@@ -3483,9 +3745,17 @@ async function main() {
3483
3745
  if (command === "change-profile-picture") {
3484
3746
  const url = positionals[1];
3485
3747
  if (!url)
3486
- fatal(
3487
- "Missing URL. Usage: mindstudio change-profile-picture <url>"
3488
- );
3748
+ usageBlock([
3749
+ "change-profile-picture \u2014 Update your profile picture",
3750
+ "",
3751
+ "Usage:",
3752
+ " mindstudio change-profile-picture <url>",
3753
+ "",
3754
+ "Examples:",
3755
+ " mindstudio change-profile-picture https://example.com/avatar.png",
3756
+ "",
3757
+ 'Tip: use "mindstudio upload" to host an image first.'
3758
+ ]);
3489
3759
  await cmdChangeProfilePicture(url, {
3490
3760
  apiKey: values["api-key"],
3491
3761
  baseUrl: values["base-url"]
@@ -3503,13 +3773,48 @@ async function main() {
3503
3773
  if (command === "info") {
3504
3774
  const rawMethod2 = positionals[1];
3505
3775
  if (!rawMethod2)
3506
- fatal("Missing action name. Usage: mindstudio info <action>");
3776
+ usageBlock([
3777
+ "info \u2014 Show action details and parameters",
3778
+ "",
3779
+ "Usage:",
3780
+ " mindstudio info <action>",
3781
+ "",
3782
+ "Shows the description, input parameters (with types and",
3783
+ "defaults), and output fields for an action.",
3784
+ "",
3785
+ "Examples:",
3786
+ " mindstudio info generate-image",
3787
+ " mindstudio info search-google",
3788
+ "",
3789
+ 'Tip: run "mindstudio list-actions" to see available actions.'
3790
+ ]);
3507
3791
  await cmdInfo(rawMethod2);
3508
3792
  return;
3509
3793
  }
3510
3794
  const split = findMethodSplit(process.argv.slice(2));
3511
3795
  if (!split)
3512
- fatal("Missing action name. Usage: mindstudio <action> [json | --flags]");
3796
+ usageBlock([
3797
+ "Run an action directly",
3798
+ "",
3799
+ "Usage:",
3800
+ " mindstudio <action> [json | --flags]",
3801
+ " mindstudio run <action> [json | --flags]",
3802
+ "",
3803
+ "Input can be inline JSON, --flags, or piped via stdin.",
3804
+ "",
3805
+ "Options:",
3806
+ " --app-id <id> App ID for thread context",
3807
+ " --thread-id <id> Thread ID for state persistence",
3808
+ " --output-key <key> Extract a single field from the result",
3809
+ " --no-meta Strip $-prefixed metadata from output",
3810
+ "",
3811
+ "Examples:",
3812
+ ' mindstudio generate-image --prompt "a sunset"',
3813
+ ` mindstudio search-google '{"query": "cats"}'`,
3814
+ ` echo '{"message":"hello"}' | mindstudio generate-text`,
3815
+ "",
3816
+ 'Tip: run "mindstudio list-actions" to see available actions.'
3817
+ ]);
3513
3818
  const { rawMethod, stepArgv } = split;
3514
3819
  const allKeys = await getAllMethodKeys();
3515
3820
  const method = resolveMethodOrFail(rawMethod, allKeys);
@@ -3568,6 +3873,9 @@ Discover:
3568
3873
  info <action> Show action details and parameters
3569
3874
  list-models [--type <t>] [--summary] List available AI models
3570
3875
 
3876
+ Batch:
3877
+ batch [json] Execute multiple actions in parallel
3878
+
3571
3879
  Pre-built agents:
3572
3880
  agents [--json] List agents in your organization
3573
3881
  run-agent <appId> [json | --flags] Run an agent and wait for result
@@ -3610,6 +3918,7 @@ Examples:
3610
3918
  mindstudio list-actions --summary
3611
3919
  mindstudio info generate-image
3612
3920
  mindstudio list-models --type image_generation
3921
+ mindstudio batch '[{"stepType":"generateImage","step":{"prompt":"a cat"}}]'
3613
3922
  mindstudio run-agent <appId> --query "hello"
3614
3923
  mindstudio agents
3615
3924
  mindstudio mcp
package/llms.txt CHANGED
@@ -205,6 +205,34 @@ For action types not covered by generated methods:
205
205
  const result = await agent.executeStep('stepType', { ...params });
206
206
  ```
207
207
 
208
+ ## Batch execution
209
+
210
+ Execute multiple steps in parallel in a single request. Maximum 50 steps per batch.
211
+ Individual step failures do not affect other steps — partial success is possible.
212
+
213
+ ```typescript
214
+ const result = await agent.executeStepBatch([
215
+ { stepType: 'generateImage', step: { prompt: 'a sunset' } },
216
+ { stepType: 'textToSpeech', step: { text: 'hello world' } },
217
+ ], { appId?, threadId? });
218
+
219
+ // Result:
220
+ result.results; // BatchStepResult[] — same order as input
221
+ result.results[0].stepType; // string
222
+ result.results[0].output; // object | undefined (step output on success)
223
+ result.results[0].error; // string | undefined (error message on failure)
224
+ result.results[0].billingCost; // number | undefined (cost on success)
225
+ result.totalBillingCost; // number | undefined
226
+ result.appId; // string
227
+ result.threadId; // string
228
+ ```
229
+
230
+ CLI:
231
+ ```bash
232
+ mindstudio batch '[{"stepType":"generateImage","step":{"prompt":"a cat"}}]'
233
+ cat steps.json | mindstudio batch
234
+ ```
235
+
208
236
  ## Methods
209
237
 
210
238
  All methods below are called on a `MindStudioAgent` instance (`agent.methodName(...)`).
@@ -1320,8 +1348,11 @@ Update the content of an existing Notion page.
1320
1348
  #### postToX
1321
1349
  Create a post on X (Twitter) from the connected account.
1322
1350
  - Requires an X OAuth connection (connectionId).
1323
- - Posts are plain text. Maximum 280 characters.
1324
- - Input: `{ text: string, connectionId?: string }`
1351
+ - Maximum 280 characters of text.
1352
+ - Optionally attach up to 4 media items (images, GIFs, or videos) via mediaUrls.
1353
+ - Media URLs must be publicly accessible. The service fetches and uploads them to X.
1354
+ - Supported formats: JPEG, PNG, GIF, WEBP, MP4. Images up to 5MB, videos up to 512MB.
1355
+ - Input: `{ text: string, connectionId?: string, mediaUrls?: string[] }`
1325
1356
  - Output: `unknown`
1326
1357
 
1327
1358
  #### searchXPosts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindstudio-ai/agent",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "TypeScript SDK for MindStudio direct step execution",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",