@mastra/client-js 1.31.2-alpha.6 → 1.32.0-alpha.10

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/CHANGELOG.md CHANGED
@@ -1,5 +1,73 @@
1
1
  # @mastra/client-js
2
2
 
3
+ ## 1.32.0-alpha.10
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`4adc391`](https://github.com/mastra-ai/mastra/commit/4adc3911075249c352bb4832d2471922826344de), [`171c3a2`](https://github.com/mastra-ai/mastra/commit/171c3a23f36199ad1354166fb515b22b57f310c2), [`b486abf`](https://github.com/mastra-ai/mastra/commit/b486abfa2a7528c6f527e4015c819ea9fa54aaad)]:
8
+ - @mastra/core@1.51.0-alpha.10
9
+ - @mastra/schema-compat@1.3.4-alpha.2
10
+
11
+ ## 1.32.0-alpha.9
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies [[`edce8d2`](https://github.com/mastra-ai/mastra/commit/edce8d2769f19e27a05737c627af2d765472a4f8)]:
16
+ - @mastra/core@1.51.0-alpha.9
17
+
18
+ ## 1.32.0-alpha.8
19
+
20
+ ### Minor Changes
21
+
22
+ - Added image attachment support to agent controller chat. You can now send images (and other files) with a message, and the Mastra Code web chat lets you attach, paste, or drag-and-drop images which render inline in the transcript. ([#19368](https://github.com/mastra-ai/mastra/pull/19368))
23
+
24
+ ```ts
25
+ await session.sendMessage({
26
+ content: 'What is in this screenshot?',
27
+ files: [{ data: base64Png, mediaType: 'image/png', filename: 'screenshot.png' }],
28
+ });
29
+ ```
30
+
31
+ ### Patch Changes
32
+
33
+ - Updated dependencies [[`bd6d240`](https://github.com/mastra-ai/mastra/commit/bd6d2402db93dddaef0721667e7e8a030e7c6e16), [`0111486`](https://github.com/mastra-ai/mastra/commit/01114867612593eef5cfa2fda6a1194dfedda841), [`96a3749`](https://github.com/mastra-ai/mastra/commit/96a37492235f5b8076b3e3177d83ed5a5e44a640), [`3e26c87`](https://github.com/mastra-ai/mastra/commit/3e26c87de0c5bc2583b795ce6ca5889b6b161acb), [`a5008f2`](https://github.com/mastra-ai/mastra/commit/a5008f22ae710ad9402ea9f2547d8c02f74d384b)]:
34
+ - @mastra/core@1.51.0-alpha.8
35
+
36
+ ## 1.32.0-alpha.7
37
+
38
+ ### Minor Changes
39
+
40
+ - Added an optional session scope to the agent controller API so clients can address independent sessions that share one resource (for example one session per git worktree). ([#19357](https://github.com/mastra-ai/mastra/pull/19357))
41
+
42
+ Session routes now accept a `sessionScope` query parameter, and `AgentController.session()` in the client accepts a scope that travels on every request:
43
+
44
+ ```ts
45
+ const controller = client.getAgentController('code');
46
+
47
+ // Address the worktree's own session instead of the shared one:
48
+ const session = controller.session('repo-123', '/worktrees/feature-a');
49
+ await session.create({ tags: { projectPath: '/worktrees/feature-a' } });
50
+ await session.sendMessage('hello');
51
+ ```
52
+
53
+ Requests without a scope behave exactly as before.
54
+
55
+ - Added run activity reporting to agent controller sessions. `session.state()` responses include a `running` flag so UIs can show a working indicator immediately when attaching to a session that is already mid-run, and each thread returned by `session.listThreads()` carries a `state` of `'active'` or `'idle'` (backed by the same per-thread run tracking that signal `ifIdle` delivery uses), so one listing can power activity indicators across every worktree or scope sharing a resource instead of polling each session: ([#19357](https://github.com/mastra-ai/mastra/pull/19357))
56
+
57
+ ```ts
58
+ const session = client.getAgentController('code').session(resourceId);
59
+
60
+ const { running } = await session.state(); // is the session mid-run?
61
+
62
+ const threads = await session.listThreads({ tags: { projectPath } });
63
+ const busy = threads.filter(thread => thread.state === 'active');
64
+ ```
65
+
66
+ ### Patch Changes
67
+
68
+ - Updated dependencies [[`25e7c12`](https://github.com/mastra-ai/mastra/commit/25e7c126a770069ae7fb7ecf1d2adb40e017b009), [`1ce5121`](https://github.com/mastra-ai/mastra/commit/1ce512155d122bb21f47d98383e82ffbf84b39e8), [`3cfc47a`](https://github.com/mastra-ai/mastra/commit/3cfc47a6b89940aadd0f46fb01ae9624a73a865d), [`2bb7817`](https://github.com/mastra-ai/mastra/commit/2bb78176112fde628483de2830528f7eee911e56), [`51d9870`](https://github.com/mastra-ai/mastra/commit/51d987032c689c2855374d0f244f5d654da809d1), [`5cab274`](https://github.com/mastra-ai/mastra/commit/5cab2744250e22d12fefa7b32637dce224233cee), [`7fa27d3`](https://github.com/mastra-ai/mastra/commit/7fa27d3b6f5ed68cd34e454a4d3ad9c482a0cfbc), [`a58dcbb`](https://github.com/mastra-ai/mastra/commit/a58dcbb546d7e1d65ebdc1f39e55f0908fcd9391), [`153bd3b`](https://github.com/mastra-ai/mastra/commit/153bd3b396bdfed6b74cf43de12db8fd2d83c04a), [`07bb863`](https://github.com/mastra-ai/mastra/commit/07bb8631919c6f7cf377dccd45b096e0f17fbed0), [`8a586ec`](https://github.com/mastra-ai/mastra/commit/8a586eca9a4914f31dff6140d0d45ac375b00669), [`3927473`](https://github.com/mastra-ai/mastra/commit/392747323ddb10c643d12be7b9ae913159dfaeed), [`dce50dc`](https://github.com/mastra-ai/mastra/commit/dce50dc9a1c1fcd0f427bb5f6250ec74910cb04b), [`634caff`](https://github.com/mastra-ai/mastra/commit/634caff29a9200ad058b67d53f96d9e5832fb8a2)]:
69
+ - @mastra/core@1.51.0-alpha.7
70
+
3
71
  ## 1.31.2-alpha.6
4
72
 
5
73
  ### Patch Changes
@@ -3,7 +3,7 @@ name: mastra-client-js
3
3
  description: Documentation for @mastra/client-js. Use when working with @mastra/client-js APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/client-js"
6
- version: "1.31.2-alpha.6"
6
+ version: "1.32.0-alpha.10"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.31.2-alpha.6",
2
+ "version": "1.32.0-alpha.10",
3
3
  "package": "@mastra/client-js",
4
4
  "exports": {
5
5
  "RequestContext": {
package/dist/index.cjs CHANGED
@@ -6145,16 +6145,24 @@ var Channels = class extends BaseResource {
6145
6145
 
6146
6146
  // src/resources/agent-controller.ts
6147
6147
  var AgentControllerSession = class extends BaseResource {
6148
- constructor(options, controllerId, resourceId) {
6148
+ constructor(options, controllerId, resourceId, scope) {
6149
6149
  super(options);
6150
6150
  this.controllerId = controllerId;
6151
6151
  this.resourceId = resourceId;
6152
+ this.scope = scope;
6152
6153
  }
6153
6154
  controllerId;
6154
6155
  resourceId;
6156
+ scope;
6155
6157
  base() {
6156
6158
  return `/agent-controller/${encodeURIComponent(this.controllerId)}/sessions/${encodeURIComponent(this.resourceId)}`;
6157
6159
  }
6160
+ /** Append this session's scope (if any) as a `sessionScope` query param. */
6161
+ url(path) {
6162
+ if (this.scope === void 0) return path;
6163
+ const sep = path.includes("?") ? "&" : "?";
6164
+ return `${path}${sep}sessionScope=${encodeURIComponent(this.scope)}`;
6165
+ }
6158
6166
  /**
6159
6167
  * Create or resume this session. Pass `tags` to scope initial thread
6160
6168
  * selection — a thread is a resume candidate only when its metadata matches
@@ -6165,7 +6173,7 @@ var AgentControllerSession = class extends BaseResource {
6165
6173
  create(options) {
6166
6174
  return this.request(`/agent-controller/${encodeURIComponent(this.controllerId)}/sessions`, {
6167
6175
  method: "POST",
6168
- body: { resourceId: this.resourceId, tags: options?.tags }
6176
+ body: { resourceId: this.resourceId, tags: options?.tags, sessionScope: this.scope }
6169
6177
  });
6170
6178
  }
6171
6179
  /**
@@ -6173,7 +6181,7 @@ var AgentControllerSession = class extends BaseResource {
6173
6181
  * message arrives here as `message_*` events, not on the sendMessage call.
6174
6182
  */
6175
6183
  async subscribe(options) {
6176
- const response = await this.request(`${this.base()}/stream`, { stream: true });
6184
+ const response = await this.request(this.url(`${this.base()}/stream`), { stream: true });
6177
6185
  if (!response.body) {
6178
6186
  throw new Error("No response body for agent controller session stream");
6179
6187
  }
@@ -6215,17 +6223,25 @@ var AgentControllerSession = class extends BaseResource {
6215
6223
  }
6216
6224
  };
6217
6225
  }
6218
- /** Send a user message. The reply streams over `subscribe()`. */
6226
+ /**
6227
+ * Send a user message. The reply streams over `subscribe()`.
6228
+ * Pass a structured message to attach files (e.g. pasted images) as base64-encoded data:
6229
+ * `sendMessage({ content: 'What is in this image?', files })`.
6230
+ */
6219
6231
  async sendMessage(message) {
6220
- await this.request(`${this.base()}/messages`, { method: "POST", body: { message } });
6232
+ const { content, files } = typeof message === "string" ? { content: message, files: void 0 } : message;
6233
+ await this.request(this.url(`${this.base()}/messages`), {
6234
+ method: "POST",
6235
+ body: { message: content, ...files?.length ? { files } : {} }
6236
+ });
6221
6237
  }
6222
6238
  /** Abort the in-flight run for this session. */
6223
6239
  async abort() {
6224
- await this.request(`${this.base()}/abort`, { method: "POST" });
6240
+ await this.request(this.url(`${this.base()}/abort`), { method: "POST" });
6225
6241
  }
6226
6242
  /** Approve or decline a pending tool call (`tool_approval_required`). */
6227
6243
  async approveTool(toolCallId, approved) {
6228
- await this.request(`${this.base()}/tool-approval`, {
6244
+ await this.request(this.url(`${this.base()}/tool-approval`), {
6229
6245
  method: "POST",
6230
6246
  body: { toolCallId, approved }
6231
6247
  });
@@ -6236,35 +6252,34 @@ var AgentControllerSession = class extends BaseResource {
6236
6252
  * `request_access`, and a {@link PlanResume} for `submit_plan`.
6237
6253
  */
6238
6254
  async respondToToolSuspension(toolCallId, resumeData) {
6239
- await this.request(`${this.base()}/tool-suspension`, {
6255
+ await this.request(this.url(`${this.base()}/tool-suspension`), {
6240
6256
  method: "POST",
6241
6257
  body: { toolCallId, resumeData }
6242
6258
  });
6243
6259
  }
6244
6260
  /** Inject a message into the in-flight run without starting a new turn. */
6245
6261
  async steer(message) {
6246
- await this.request(`${this.base()}/steer`, { method: "POST", body: { message } });
6262
+ await this.request(this.url(`${this.base()}/steer`), { method: "POST", body: { message } });
6247
6263
  }
6248
6264
  /** Get the current mode, model, and thread (for initial UI hydration). */
6249
6265
  state() {
6250
- return this.request(this.base());
6266
+ return this.request(this.url(this.base()));
6251
6267
  }
6252
6268
  /** Merge key-value pairs into the session state. Existing keys not in the payload are preserved. */
6253
6269
  async setState(updates) {
6254
- await this.request(`${this.base()}/state`, { method: "PUT", body: { state: updates } });
6270
+ await this.request(this.url(`${this.base()}/state`), { method: "PUT", body: { state: updates } });
6255
6271
  }
6256
6272
  /** Switch the active mode (e.g. `build`, `plan`). */
6257
6273
  async switchMode(modeId) {
6258
- await this.request(`${this.base()}/mode`, { method: "POST", body: { modeId } });
6274
+ await this.request(this.url(`${this.base()}/mode`), { method: "POST", body: { modeId } });
6259
6275
  }
6260
6276
  /** Switch the model. Defaults to thread scope. */
6261
6277
  async switchModel(modelId, options) {
6262
- await this.request(`${this.base()}/model`, {
6278
+ await this.request(this.url(`${this.base()}/model`), {
6263
6279
  method: "POST",
6264
6280
  body: { modelId, scope: options?.scope, modeId: options?.modeId }
6265
6281
  });
6266
6282
  }
6267
- /** List the threads for this session's resource, most-recently-updated first. Pass `limit` for just the newest N. */
6268
6283
  /**
6269
6284
  * List the session's threads, newest first. Pass `limit` to cap the count
6270
6285
  * (e.g. for a sidebar) and `tags` to scope to threads matching every tag —
@@ -6278,36 +6293,38 @@ var AgentControllerSession = class extends BaseResource {
6278
6293
  if (opts.limit != null) params.set("limit", String(opts.limit));
6279
6294
  if (opts.tags && Object.keys(opts.tags).length > 0) params.set("tags", JSON.stringify(opts.tags));
6280
6295
  const query = params.toString() ? `?${params.toString()}` : "";
6281
- const body = await this.request(`${this.base()}/threads${query}`);
6296
+ const body = await this.request(
6297
+ this.url(`${this.base()}/threads${query}`)
6298
+ );
6282
6299
  return body.threads;
6283
6300
  }
6284
6301
  /** Switch the session to an existing thread (rebinds stream + state). */
6285
6302
  async switchThread(threadId) {
6286
- await this.request(`${this.base()}/thread`, { method: "POST", body: { threadId } });
6303
+ await this.request(this.url(`${this.base()}/thread`), { method: "POST", body: { threadId } });
6287
6304
  }
6288
6305
  /** Create a new thread (unbinds previous, binds the new one). */
6289
6306
  async createThread(title) {
6290
- return this.request(`${this.base()}/threads`, {
6307
+ return this.request(this.url(`${this.base()}/threads`), {
6291
6308
  method: "POST",
6292
6309
  body: { title }
6293
6310
  });
6294
6311
  }
6295
6312
  /** Delete a thread. If it's the active thread the session unbinds. */
6296
6313
  async deleteThread(threadId) {
6297
- await this.request(`${this.base()}/threads/${encodeURIComponent(threadId)}`, {
6314
+ await this.request(this.url(`${this.base()}/threads/${encodeURIComponent(threadId)}`), {
6298
6315
  method: "DELETE"
6299
6316
  });
6300
6317
  }
6301
6318
  /** Rename a thread. */
6302
6319
  async renameThread(threadId, title) {
6303
- await this.request(`${this.base()}/threads/${encodeURIComponent(threadId)}`, {
6320
+ await this.request(this.url(`${this.base()}/threads/${encodeURIComponent(threadId)}`), {
6304
6321
  method: "PUT",
6305
6322
  body: { title }
6306
6323
  });
6307
6324
  }
6308
6325
  /** Clone a thread (and its messages). The session binds to the clone. */
6309
6326
  async cloneThread(options) {
6310
- return this.request(`${this.base()}/threads/clone`, {
6327
+ return this.request(this.url(`${this.base()}/threads/clone`), {
6311
6328
  method: "POST",
6312
6329
  body: options ?? {}
6313
6330
  });
@@ -6316,7 +6333,7 @@ var AgentControllerSession = class extends BaseResource {
6316
6333
  async listMessages(threadId, limit) {
6317
6334
  const params = limit != null ? `?limit=${limit}` : "";
6318
6335
  const body = await this.request(
6319
- `${this.base()}/threads/${encodeURIComponent(threadId)}/messages${params}`
6336
+ this.url(`${this.base()}/threads/${encodeURIComponent(threadId)}/messages${params}`)
6320
6337
  );
6321
6338
  return body.messages;
6322
6339
  }
@@ -6325,33 +6342,33 @@ var AgentControllerSession = class extends BaseResource {
6325
6342
  * if a run is active it queues for after completion.
6326
6343
  */
6327
6344
  async followUp(message) {
6328
- await this.request(`${this.base()}/follow-up`, { method: "POST", body: { message } });
6345
+ await this.request(this.url(`${this.base()}/follow-up`), { method: "POST", body: { message } });
6329
6346
  }
6330
6347
  /** Get the observational memory record for this session's thread. */
6331
6348
  async getOMRecord() {
6332
- const body = await this.request(`${this.base()}/om`);
6349
+ const body = await this.request(this.url(`${this.base()}/om`));
6333
6350
  return body.record;
6334
6351
  }
6335
6352
  /** Change the session's resource identity. */
6336
6353
  async setResourceId(newResourceId) {
6337
- await this.request(`${this.base()}/resource`, {
6354
+ await this.request(this.url(`${this.base()}/resource`), {
6338
6355
  method: "POST",
6339
6356
  body: { newResourceId }
6340
6357
  });
6341
6358
  }
6342
6359
  /** Get known resource IDs for this session. */
6343
6360
  async getResourceIds() {
6344
- const body = await this.request(`${this.base()}/resources`);
6361
+ const body = await this.request(this.url(`${this.base()}/resources`));
6345
6362
  return body.resourceIds;
6346
6363
  }
6347
6364
  /** Get the current goal for this session's thread. */
6348
6365
  async getGoal() {
6349
- const body = await this.request(`${this.base()}/goal`);
6366
+ const body = await this.request(this.url(`${this.base()}/goal`));
6350
6367
  return body.goal;
6351
6368
  }
6352
6369
  /** Set a new goal objective. The agent's in-loop judge evaluates progress after each turn. */
6353
6370
  async setGoal(objective, options) {
6354
- const body = await this.request(`${this.base()}/goal`, {
6371
+ const body = await this.request(this.url(`${this.base()}/goal`), {
6355
6372
  method: "POST",
6356
6373
  body: { objective, ...options }
6357
6374
  });
@@ -6359,7 +6376,7 @@ var AgentControllerSession = class extends BaseResource {
6359
6376
  }
6360
6377
  /** Update goal options (judge model, max runs, status). */
6361
6378
  async updateGoal(options) {
6362
- const body = await this.request(`${this.base()}/goal`, {
6379
+ const body = await this.request(this.url(`${this.base()}/goal`), {
6363
6380
  method: "PUT",
6364
6381
  body: options
6365
6382
  });
@@ -6367,25 +6384,25 @@ var AgentControllerSession = class extends BaseResource {
6367
6384
  }
6368
6385
  /** Clear the current goal. */
6369
6386
  async clearGoal() {
6370
- await this.request(`${this.base()}/goal`, { method: "DELETE" });
6387
+ await this.request(this.url(`${this.base()}/goal`), { method: "DELETE" });
6371
6388
  }
6372
6389
  // ---------------------------------------------------------------------------
6373
6390
  // Permissions
6374
6391
  // ---------------------------------------------------------------------------
6375
6392
  /** Get the current permission rules (per-category and per-tool policies). */
6376
6393
  async getPermissions() {
6377
- return this.request(`${this.base()}/permissions`);
6394
+ return this.request(this.url(`${this.base()}/permissions`));
6378
6395
  }
6379
6396
  /** Set the approval policy for a tool category. */
6380
6397
  async setPermissionForCategory(category, policy) {
6381
- await this.request(`${this.base()}/permissions/category`, {
6398
+ await this.request(this.url(`${this.base()}/permissions/category`), {
6382
6399
  method: "PUT",
6383
6400
  body: { category, policy }
6384
6401
  });
6385
6402
  }
6386
6403
  /** Set the approval policy for a specific tool. */
6387
6404
  async setPermissionForTool(toolName, policy) {
6388
- await this.request(`${this.base()}/permissions/tool`, {
6405
+ await this.request(this.url(`${this.base()}/permissions/tool`), {
6389
6406
  method: "PUT",
6390
6407
  body: { toolName, policy }
6391
6408
  });
@@ -6396,7 +6413,7 @@ var AgentControllerSession = class extends BaseResource {
6396
6413
  * or is persisted for later.
6397
6414
  */
6398
6415
  async sendNotification(input) {
6399
- return this.request(`${this.base()}/notifications`, {
6416
+ return this.request(this.url(`${this.base()}/notifications`), {
6400
6417
  method: "POST",
6401
6418
  body: input
6402
6419
  });
@@ -6425,9 +6442,13 @@ var AgentController = class extends BaseResource {
6425
6442
  async workspaceStatus() {
6426
6443
  return this.request(`${this.basePath()}/workspace`);
6427
6444
  }
6428
- /** Scope to a session bound to `resourceId` (e.g. a user or conversation id). */
6429
- session(resourceId) {
6430
- return new AgentControllerSession(this.options, this.controllerId, resourceId);
6445
+ /**
6446
+ * Scope to a session bound to `resourceId` (e.g. a user or conversation id).
6447
+ * Pass `scope` to address an independent session over the same resourceId
6448
+ * (e.g. one session per git worktree, with the worktree path as the scope).
6449
+ */
6450
+ session(resourceId, scope) {
6451
+ return new AgentControllerSession(this.options, this.controllerId, resourceId, scope);
6431
6452
  }
6432
6453
  };
6433
6454
  function agentControllerMessageText(message) {