@mastra/client-js 1.47.0-alpha.5 → 1.47.0-alpha.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.
@@ -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.47.0-alpha.5"
6
+ version: "1.47.0-alpha.6"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.47.0-alpha.5",
2
+ "version": "1.47.0-alpha.6",
3
3
  "package": "@mastra/client-js",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -74,8 +74,8 @@ const session = await controller.createSession({
74
74
  })
75
75
 
76
76
  const unsubscribe = session.subscribe(event => {
77
- if (event.type === 'message_update') {
78
- console.log(event.message)
77
+ if (event.type === 'message_update' && event.event.type === 'text-delta') {
78
+ process.stdout.write(event.event.delta)
79
79
  }
80
80
  })
81
81
 
@@ -83,6 +83,8 @@ await session.sendMessage({ content: 'Plan a small TypeScript CLI.' })
83
83
  unsubscribe()
84
84
  ```
85
85
 
86
+ Each message emits a `message_start` event with the initial message, zero or more `message_update` events with compact deltas, and a `message_end` event containing the message ID. Apply updates by ID when you need to reconstruct the complete message.
87
+
86
88
  Use the same controller for many Sessions. Don't store a current Session on the controller or route work through controller-level message methods.
87
89
 
88
90
  ## Understand the runtime model
@@ -219,31 +219,92 @@ Returns: `Promise<SendNotificationResult>`
219
219
 
220
220
  `onEvent` receives every event the session emits, discriminated by `event.type`:
221
221
 
222
- | Group | Events |
223
- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
224
- | Run | `agent_start`, `agent_end`, `usage_update`, `goal_evaluation`, `follow_up_queued` |
225
- | Messages | `message_start`, `message_update`, `message_end` |
226
- | Tools | `tool_input_start`, `tool_input_delta`, `tool_input_end`, `tool_start`, `tool_update`, `tool_end`, `shell_output`, `command_exit`, `tool_approval_required`, `tool_suspended`, `tool_suspension_cancelled`, `task_updated` |
227
- | Session | `state_changed`, `display_state_changed`, `mode_changed`, `model_changed`, `thread_changed`, `thread_created`, `thread_deleted`, `thread_title_updated` |
228
- | Subagents | `subagent_start`, `subagent_text_delta`, `subagent_tool_start`, `subagent_tool_end`, `subagent_end`, `subagent_model_changed` |
229
- | Memory | `om_observation_start`, `om_observation_end`, `om_observation_failed`, `om_reflection_start`, `om_reflection_end`, `om_reflection_failed`, `om_buffering_start`, `om_buffering_end`, `om_buffering_failed`, `om_model_changed`, `om_activation`, `om_status`, `om_thread_title_updated` |
230
- | Workspace | `workspace_ready`, `workspace_error`, `workspace_status_changed` |
231
- | Notification | `notification`, `notification_summary`, `info`, `error` |
222
+ | Group | Events |
223
+ | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
224
+ | Run | `agent_start`, `agent_end`, `usage_update`, `goal_evaluation`, `follow_up_queued` |
225
+ | Messages | `message_start`, `message_update`, `message_end` |
226
+ | Tools | `tool_input_start`, `tool_input_delta`, `tool_input_end`, `tool_start`, `tool_update`, `tool_end`, `shell_output`, `command_exit`, `tool_approval_required`, `tool_suspended`, `tool_suspension_cancelled`, `task_updated` |
227
+ | Session | `state_changed`, `display_state_changed`, `mode_changed`, `model_changed`, `thread_changed`, `thread_created`, `thread_deleted`, `thread_title_updated` |
228
+ | Subagents | `subagent_start`, `subagent_text_delta`, `subagent_tool_start`, `subagent_tool_end`, `subagent_end`, `subagent_model_changed` |
229
+ | Memory | `om_observation_start`, `om_observation_end`, `om_observation_failed`, `om_reflection_start`, `om_reflection_end`, `om_reflection_failed`, `om_buffering_start`, `om_buffering_end`, `om_buffering_failed`, `om_model_changed`, `om_activation`, `om_status`, `om_thread_title_updated` |
230
+ | Workspace | `workspace_ready`, `workspace_error`, `workspace_status_changed` |
231
+ | Diagnostics | `info`, `error` |
232
232
 
233
- `message_*` events carry a `MastraDBMessage` and `thread_created` carries a thread, with timestamps hydrated to `Date`.
233
+ Notifications are delivered as agent signals carried on messages rather than as `notification` or `notification_summary` controller events.
234
234
 
235
- A controller can also emit events the SDK doesn't type. `AgentControllerEvent` is the union of `KnownAgentControllerEvent` and `OtherAgentControllerEvent`. Because `OtherAgentControllerEvent.type` is `string`, comparing `event.type` to a literal doesn't narrow the union. Narrow with `isKnownAgentControllerEvent(event)` first:
235
+ A message lifecycle uses three event shapes:
236
+
237
+ - `message_start` carries the initial `MastraDBMessage`, with `createdAt` hydrated to `Date`.
238
+ - `message_update` carries the message `id` and a compact text, reasoning, or part update.
239
+ - `message_end` carries the `id` of the completed message.
240
+
241
+ `thread_created` also carries a thread with timestamps hydrated to `Date`.
242
+
243
+ A controller can emit events the SDK doesn't type. `AgentControllerEvent` is the union of `KnownAgentControllerEvent` and `OtherAgentControllerEvent`. Because `OtherAgentControllerEvent.type` is `string`, comparing `event.type` to a literal doesn't narrow the union. Narrow with `isKnownAgentControllerEvent(event)` first, then reconstruct messages by ID:
236
244
 
237
245
  ```typescript
238
- import { isKnownAgentControllerEvent } from '@mastra/client-js'
246
+ import {
247
+ isKnownAgentControllerEvent,
248
+ type AgentControllerEvent,
249
+ type KnownAgentControllerEvent,
250
+ type MastraDBMessage,
251
+ } from '@mastra/client-js'
252
+
253
+ type MessageUpdate = Extract<KnownAgentControllerEvent, { type: 'message_update' }>['event']
254
+
255
+ const activeMessages = new Map<string, MastraDBMessage>()
256
+
257
+ function applyUpdate(message: MastraDBMessage, update: MessageUpdate): MastraDBMessage {
258
+ const parts = [...message.content.parts]
259
+
260
+ if (update.type === 'text-delta') {
261
+ const index = parts.findLastIndex(part => part.type === 'text')
262
+ const part = parts[index]
263
+
264
+ if (part?.type === 'text') {
265
+ parts[index] = { ...part, text: part.text + update.delta }
266
+ } else {
267
+ parts.push({ type: 'text', text: update.delta })
268
+ }
269
+ } else if (update.type === 'reasoning-delta') {
270
+ const part = parts[update.index]
271
+ const reasoning = part?.type === 'reasoning' ? part.reasoning + update.delta : update.delta
272
+ parts[update.index] = {
273
+ ...(part?.type === 'reasoning' ? part : { type: 'reasoning' as const }),
274
+ reasoning,
275
+ details: [{ type: 'text', text: reasoning }],
276
+ }
277
+ } else {
278
+ parts[update.index] = update.part
279
+ }
280
+
281
+ return { ...message, content: { ...message.content, parts } }
282
+ }
239
283
 
240
284
  function handleEvent(event: AgentControllerEvent) {
241
285
  if (!isKnownAgentControllerEvent(event)) return
242
286
 
243
287
  switch (event.type) {
244
- case 'message_update':
245
- render(event.message)
288
+ case 'message_start':
289
+ activeMessages.set(event.message.id, structuredClone(event.message))
290
+ break
291
+ case 'message_update': {
292
+ const message = activeMessages.get(event.id)
293
+ if (!message) break
294
+
295
+ const updated = applyUpdate(message, event.event)
296
+ activeMessages.set(event.id, updated)
297
+ render(updated)
298
+ break
299
+ }
300
+ case 'message_end': {
301
+ const message = activeMessages.get(event.id)
302
+ if (!message) break
303
+
304
+ renderComplete(message)
305
+ activeMessages.delete(event.id)
246
306
  break
307
+ }
247
308
  case 'tool_approval_required':
248
309
  showApproval(event.toolCallId)
249
310
  break
@@ -251,7 +312,7 @@ function handleEvent(event: AgentControllerEvent) {
251
312
  }
252
313
  ```
253
314
 
254
- Use `agentControllerMessageText(message)` to pull the plain text out of a message's nested content parts.
315
+ Use `agentControllerMessageText(message)` to pull the plain text out of a reconstructed message's nested content parts.
255
316
 
256
317
  ## Related
257
318
 
@@ -233,7 +233,7 @@ const scores = await mastraClient.listScoresBySpan({
233
233
 
234
234
  ## Feedback
235
235
 
236
- Feedback methods create, list, and query human-in-the-loop signals such as ratings, thumbs, comments, and corrections through the target Mastra runtime and its configured observability storage. They don't call the hosted Mastra Platform feedback query API. See the [feedback guide](https://mastra.ai/docs/observability/feedback) for examples and the [feedback reference](https://mastra.ai/reference/observability/feedback) for full schemas.
236
+ Feedback methods create, list, and query human-in-the-loop signals such as ratings, thumbs, comments, and corrections through the target Mastra runtime and its configured observability storage. They don't call the hosted Mastra Platform Feedback API. See the [feedback guide](https://mastra.ai/docs/observability/feedback) for examples and the [feedback reference](https://mastra.ai/reference/observability/feedback) for full schemas.
237
237
 
238
238
  ### Creating feedback
239
239
 
@@ -285,6 +285,8 @@ const feedback = await mastraClient.listFeedback({
285
285
  })
286
286
  ```
287
287
 
288
+ `filters` accepts every [`FeedbackFilter`](https://mastra.ai/reference/observability/feedback) field. The client sends them as query parameters on `GET /api/observability/feedback`. See [list query parameters](https://mastra.ai/reference/observability/feedback).
289
+
288
290
  ### Aggregating feedback
289
291
 
290
292
  Aggregate numeric feedback values, such as ratings or thumbs encoded as `1` and `-1`: