@dbx-tools/appkit-mastra 0.6.211 → 0.6.212

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/src/threads.ts CHANGED
@@ -21,7 +21,6 @@
21
21
  * @module
22
22
  */
23
23
 
24
- import { ValidationError } from "@databricks/appkit";
25
24
  import { log } from "@dbx-tools/shared-core";
26
25
  import {
27
26
  wire,
@@ -32,10 +31,14 @@ import {
32
31
  } from "@dbx-tools/shared-mastra";
33
32
  import type { Agent } from "@mastra/core/agent";
34
33
  import type { StorageThreadType } from "@mastra/core/memory";
35
- import { MASTRA_RESOURCE_ID_KEY, MASTRA_THREAD_ID_KEY } from "@mastra/core/request-context";
36
34
  import type { ContextWithMastra } from "@mastra/core/server";
37
35
  import { registerApiRoute } from "@mastra/core/server";
38
36
 
37
+ import {
38
+ resolveAgentRequestContext,
39
+ resolveAgentRouteOptions,
40
+ type AgentRouteOptions,
41
+ } from "./_agent-route-context.ts";
39
42
  import { clampPerPage, parseIntParam } from "./pagination.ts";
40
43
  import { invalidFields } from "./validation.ts";
41
44
 
@@ -196,8 +199,7 @@ export async function renameThread(opts: RenameThreadOptions): Promise<MastraThr
196
199
  }
197
200
 
198
201
  /** Options accepted by {@link threadsRoute}. */
199
- export type ThreadsRouteOptions =
200
- { path: `${string}:agentId${string}`; agent?: never } | { path: string; agent: string };
202
+ export type ThreadsRouteOptions = AgentRouteOptions;
201
203
 
202
204
  /**
203
205
  * Register the `<path>` Mastra custom API route. Handles three methods
@@ -221,45 +223,13 @@ export type ThreadsRouteOptions =
221
223
  * agent) and `/route/threads/:agentId`.
222
224
  */
223
225
  export function threadsRoute(options: ThreadsRouteOptions) {
224
- const { path } = options;
225
- const fixedAgent = "agent" in options ? options.agent : undefined;
226
- if (!fixedAgent && !path.includes(":agentId")) {
227
- throw ValidationError.invalidValue(
228
- "threadsRoute.path",
229
- path,
230
- "a path containing `:agentId`, or an explicit `agent`",
231
- );
232
- }
233
- // Shared by GET / DELETE: resolve the active agent and the caller's
234
- // resource id, returning a JSON error response when either is
235
- // missing. Keeps both handlers thin with identical validation.
236
- const resolveContext = (c: ContextWithMastra) => {
237
- const mastra = c.get("mastra");
238
- const requestContext = c.get("requestContext");
239
- const agentId = fixedAgent ?? c.req.param("agentId");
240
- if (!agentId) {
241
- return { error: c.json({ error: "agentId is required" }, 400) } as const;
242
- }
243
- const agent = mastra.getAgentById(agentId);
244
- if (!agent) {
245
- return {
246
- error: c.json({ error: `Unknown agent "${agentId}"` }, 404),
247
- } as const;
248
- }
249
- const resourceId = requestContext.get(MASTRA_RESOURCE_ID_KEY) as string | undefined;
250
- if (!resourceId) {
251
- return {
252
- error: c.json({ error: "resource id missing from request context" }, 400),
253
- } as const;
254
- }
255
- return { agentId, agent, requestContext, resourceId } as const;
256
- };
226
+ const { path, fixedAgent } = resolveAgentRouteOptions(options, "threadsRoute.path");
257
227
 
258
228
  return [
259
229
  registerApiRoute(path, {
260
230
  method: "GET",
261
231
  handler: async (c: ContextWithMastra) => {
262
- const ctx = resolveContext(c);
232
+ const ctx = resolveAgentRequestContext(c, { fixedAgent });
263
233
  if ("error" in ctx) return ctx.error;
264
234
  const payload = await listThreads({
265
235
  agent: ctx.agent,
@@ -273,21 +243,17 @@ export function threadsRoute(options: ThreadsRouteOptions) {
273
243
  registerApiRoute(path, {
274
244
  method: "DELETE",
275
245
  handler: async (c: ContextWithMastra) => {
276
- const ctx = resolveContext(c);
246
+ const ctx = resolveAgentRequestContext(c, { fixedAgent, threadId: "required" });
277
247
  if ("error" in ctx) return ctx.error;
278
- const threadId = ctx.requestContext.get(MASTRA_THREAD_ID_KEY) as string | undefined;
279
- if (!threadId) {
280
- return c.json({ error: "thread id missing from request context" }, 400);
281
- }
282
248
  const { deleted } = await deleteThread({
283
249
  agent: ctx.agent,
284
- threadId,
250
+ threadId: ctx.threadId,
285
251
  resourceId: ctx.resourceId,
286
252
  });
287
253
  const payload: MastraDeleteThreadResponse = {
288
254
  ok: true,
289
255
  agentId: ctx.agentId,
290
- threadId,
256
+ threadId: ctx.threadId,
291
257
  deleted,
292
258
  };
293
259
  return c.json(payload);
@@ -296,12 +262,8 @@ export function threadsRoute(options: ThreadsRouteOptions) {
296
262
  registerApiRoute(path, {
297
263
  method: "PATCH",
298
264
  handler: async (c: ContextWithMastra) => {
299
- const ctx = resolveContext(c);
265
+ const ctx = resolveAgentRequestContext(c, { fixedAgent, threadId: "required" });
300
266
  if ("error" in ctx) return ctx.error;
301
- const threadId = ctx.requestContext.get(MASTRA_THREAD_ID_KEY) as string | undefined;
302
- if (!threadId) {
303
- return c.json({ error: "thread id missing from request context" }, 400);
304
- }
305
267
  const body = wire.MastraUpdateThreadRequestSchema.safeParse(await c.req.json());
306
268
  if (!body.success) {
307
269
  logger.warn("rename:invalid", { error: body.error.message });
@@ -309,12 +271,12 @@ export function threadsRoute(options: ThreadsRouteOptions) {
309
271
  }
310
272
  const thread = await renameThread({
311
273
  agent: ctx.agent,
312
- threadId,
274
+ threadId: ctx.threadId,
313
275
  resourceId: ctx.resourceId,
314
276
  title: body.data.title,
315
277
  });
316
278
  if (!thread) {
317
- return c.json({ error: `Unknown thread "${threadId}"` }, 404);
279
+ return c.json({ error: `Unknown thread "${ctx.threadId}"` }, 404);
318
280
  }
319
281
  const payload: MastraUpdateThreadResponse = {
320
282
  ok: true,