@dbx-tools/appkit-mastra 0.6.223 → 0.6.225

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/pagination.ts CHANGED
@@ -9,7 +9,11 @@
9
9
 
10
10
  import { object } from "@dbx-tools/shared-core";
11
11
 
12
- /** Bounds for {@link clampPerPage}. */
12
+ /**
13
+ * Bounds for {@link clampPerPage}.
14
+ *
15
+ * @deprecated Use the native `@mastra/client-js` memory API pagination inputs.
16
+ */
13
17
  export interface PerPageBounds {
14
18
  /** Page size used for empty / non-positive / non-numeric inputs. */
15
19
  fallback: number;
@@ -17,7 +21,11 @@ export interface PerPageBounds {
17
21
  max: number;
18
22
  }
19
23
 
20
- /** Coerce / clamp a `perPage` value, falling back to `bounds.fallback`. */
24
+ /**
25
+ * Coerce / clamp a `perPage` value, falling back to `bounds.fallback`.
26
+ *
27
+ * @deprecated Use the native `@mastra/client-js` memory API pagination inputs.
28
+ */
21
29
  export function clampPerPage(value: number | undefined, bounds: PerPageBounds): number {
22
30
  if (value === undefined || Number.isNaN(value)) return bounds.fallback;
23
31
  const n = Math.trunc(value);
@@ -29,6 +37,8 @@ export function clampPerPage(value: number | undefined, bounds: PerPageBounds):
29
37
  * Coerce a Hono query value into a non-negative integer. Returns
30
38
  * `undefined` for empty / non-numeric / negative inputs so the caller
31
39
  * can apply its built-in defaults.
40
+ *
41
+ * @deprecated Use the native `@mastra/client-js` memory API pagination inputs.
32
42
  */
33
43
  export function parseIntParam(value: string | undefined): number | undefined {
34
44
  const n = object.toNumber(value);
package/src/plugin.ts CHANGED
@@ -95,6 +95,7 @@ import {
95
95
  import { buildMcpServer, type ResolvedMcp } from "./mcp.ts";
96
96
  import { createMemoryBuilder, createServicePrincipalPool, needsLakebase } from "./memory.ts";
97
97
  import { logFeedback, resolveFeedbackEnabled } from "./mlflow.ts";
98
+ import { resolveDefaultModelId } from "./model.ts";
98
99
  import { buildObservability } from "./observability.ts";
99
100
  import { provisionRemoteSkills } from "./remote-skills.ts";
100
101
  import {
@@ -149,8 +150,8 @@ const STATEMENT_CACHE_NAMESPACE = "mastra:statement";
149
150
  * agents: createAgent({
150
151
  * name: "analyst",
151
152
  * instructions: "You answer questions about revenue and returns.",
152
- * tools(plugins) {
153
- * return { ...plugins.genie?.toolkit() };
153
+ * async tools(plugins) {
154
+ * return { ...(await plugins.genie?.toolkit()) };
154
155
  * },
155
156
  * }),
156
157
  * }),
@@ -506,16 +507,12 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
506
507
  },
507
508
  });
508
509
 
509
- // `GET /default-model` (and `/default-model/:agentId`) reports the static
510
- // serving-endpoint an agent falls back to when the client pins no model,
511
- // so the picker can label its default option with the model's humanized
512
- // name. Agent-scoped via the optional `/:agentId` suffix (URL symmetry
513
- // with the history / threads / suggestions routes), defaulting to the
514
- // default agent. `model` / `displayName` are null when the agent has no
515
- // static default (a dynamic, call-time model); an unknown agent id is a
516
- // 404, matching the history / threads routes. Reads only in-memory build
517
- // state, so it needs no OBO scoping. Registered before the catch-all,
518
- // same as `/models`.
510
+ // `GET /default-model` (and `/default-model/:agentId`) reports what an
511
+ // unpinned turn will use. A configured string is returned directly; an
512
+ // automatic default resolves the highest-ranked currently available GPT
513
+ // (or general chat fallback) from the same OBO-scoped live catalogue as
514
+ // `/models`; a custom dynamic resolver remains null because it is call-time
515
+ // application code.
519
516
  const handleDefaultModel = async (
520
517
  req: express.Request,
521
518
  res: express.Response,
@@ -526,11 +523,20 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
526
523
  return;
527
524
  }
528
525
  const agentId = requested ?? this.built?.defaultAgentId ?? FALLBACK_AGENT_ID;
529
- const raw = this.built?.defaultModels[agentId];
530
- // `"<dynamic>"` (a call-time function) has no fixed id to advertise.
531
- const model = raw && raw !== "<dynamic>" ? raw : null;
532
- // Return the humanized label too, so the picker shows a friendly name on
533
- // load without waiting on the `/models` catalogue (no raw-id flash).
526
+ const intent = this.built?.defaultModels[agentId];
527
+ let model: string | null = null;
528
+ if (intent?.kind === "configured") {
529
+ model = intent.model;
530
+ } else if (intent?.kind === "auto") {
531
+ const result = await this.scopedSelf(req).listModelsResult();
532
+ if (!result.ok) {
533
+ this.sendFailure(res, result, "default-model", MODEL_CATALOGUE_FAILED_MESSAGE);
534
+ return;
535
+ }
536
+ if (result.data.length > 0) {
537
+ model = resolveDefaultModelId(this.config, result.data);
538
+ }
539
+ }
534
540
  res.json({
535
541
  agentId,
536
542
  model,
@@ -1210,8 +1216,8 @@ function parseStatementLimit(raw: unknown): number | undefined {
1210
1216
  * agents: {
1211
1217
  * analyst: createAgent({
1212
1218
  * instructions: "You answer questions about sales.",
1213
- * tools(plugins) {
1214
- * return { ...plugins.genie?.toolkit() };
1219
+ * async tools(plugins) {
1220
+ * return { ...(await plugins.genie?.toolkit()) };
1215
1221
  * },
1216
1222
  * }),
1217
1223
  * helper: createAgent({ instructions: "You explain the analyst's answers." }),
@@ -21,8 +21,8 @@
21
21
  * @module
22
22
  */
23
23
 
24
- import { json, string } from "@dbx-tools/shared-core";
25
24
  import { chatToolReasoningEffort, ReasoningEffort } from "@dbx-tools/model-rs";
25
+ import { json, string } from "@dbx-tools/shared-core";
26
26
  import {
27
27
  type ChatMessage,
28
28
  type ChatRole,
@@ -1,46 +0,0 @@
1
- /**
2
- * Shared agent binding and request-context resolution for Mastra custom routes.
3
- *
4
- * @module
5
- */
6
- import type { Agent } from "@mastra/core/agent";
7
- import { type RequestContext } from "@mastra/core/request-context";
8
- import type { ContextWithMastra } from "@mastra/core/server";
9
- /** Fixed-agent or dynamic `:agentId` binding accepted by custom agent routes. */
10
- export type AgentRouteOptions = {
11
- path: `${string}:agentId${string}`;
12
- agent?: never;
13
- } | {
14
- path: string;
15
- agent: string;
16
- };
17
- /** Validated route path and optional fixed agent binding. */
18
- export interface ResolvedAgentRouteOptions {
19
- path: string;
20
- fixedAgent: string | undefined;
21
- }
22
- /** Resolve and validate a fixed or dynamic agent route declaration. */
23
- export declare function resolveAgentRouteOptions(options: AgentRouteOptions, field: string): ResolvedAgentRouteOptions;
24
- interface ResolvedAgentRequestContext {
25
- agentId: string;
26
- agent: Agent;
27
- requestContext: RequestContext;
28
- resourceId: string;
29
- }
30
- interface AgentRequestContextError {
31
- error: Response;
32
- }
33
- interface ResolveAgentRequestContextOptions {
34
- fixedAgent?: string;
35
- threadId?: "optional" | "required";
36
- }
37
- /** Resolve an agent plus the caller-scoped Mastra request context. */
38
- export declare function resolveAgentRequestContext(context: ContextWithMastra, options: ResolveAgentRequestContextOptions & {
39
- threadId: "required";
40
- }): (ResolvedAgentRequestContext & {
41
- threadId: string;
42
- }) | AgentRequestContextError;
43
- export declare function resolveAgentRequestContext(context: ContextWithMastra, options?: ResolveAgentRequestContextOptions): (ResolvedAgentRequestContext & {
44
- threadId?: string;
45
- }) | AgentRequestContextError;
46
- export {};
@@ -1,47 +0,0 @@
1
- /**
2
- * Shared agent binding and request-context resolution for Mastra custom routes.
3
- *
4
- * @module
5
- */
6
- import { ValidationError } from "@databricks/appkit";
7
- import { MASTRA_RESOURCE_ID_KEY, MASTRA_THREAD_ID_KEY, } from "@mastra/core/request-context";
8
- /** Resolve and validate a fixed or dynamic agent route declaration. */
9
- export function resolveAgentRouteOptions(options, field) {
10
- const fixedAgent = "agent" in options ? options.agent : undefined;
11
- if (!fixedAgent && !options.path.includes(":agentId")) {
12
- throw ValidationError.invalidValue(field, options.path, "a path containing `:agentId`, or an explicit `agent`");
13
- }
14
- return { path: options.path, fixedAgent };
15
- }
16
- export function resolveAgentRequestContext(context, options = {}) {
17
- const mastra = context.get("mastra");
18
- const requestContext = context.get("requestContext");
19
- const agentId = options.fixedAgent ?? context.req.param("agentId");
20
- if (!agentId) {
21
- return { error: context.json({ error: "agentId is required" }, 400) };
22
- }
23
- const agent = mastra.getAgentById(agentId);
24
- if (!agent) {
25
- return { error: context.json({ error: `Unknown agent "${agentId}"` }, 404) };
26
- }
27
- const resourceId = requestContext.get(MASTRA_RESOURCE_ID_KEY);
28
- if (!resourceId) {
29
- return {
30
- error: context.json({ error: "resource id missing from request context" }, 400),
31
- };
32
- }
33
- const threadId = requestContext.get(MASTRA_THREAD_ID_KEY);
34
- if (options.threadId === "required" && !threadId) {
35
- return {
36
- error: context.json({ error: "thread id missing from request context" }, 400),
37
- };
38
- }
39
- return {
40
- agentId,
41
- agent,
42
- requestContext,
43
- resourceId,
44
- ...(threadId ? { threadId } : {}),
45
- };
46
- }
47
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2FnZW50LXJvdXRlLWNvbnRleHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvX2FnZW50LXJvdXRlLWNvbnRleHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUVILE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVyRCxPQUFPLEVBQ0wsc0JBQXNCLEVBQ3RCLG9CQUFvQixHQUVyQixNQUFNLDhCQUE4QixDQUFDO0FBYXRDLHVFQUF1RTtBQUN2RSxNQUFNLFVBQVUsd0JBQXdCLENBQ3RDLE9BQTBCLEVBQzFCLEtBQWE7SUFFYixNQUFNLFVBQVUsR0FBRyxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDbEUsSUFBSSxDQUFDLFVBQVUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7UUFDdEQsTUFBTSxlQUFlLENBQUMsWUFBWSxDQUNoQyxLQUFLLEVBQ0wsT0FBTyxDQUFDLElBQUksRUFDWixzREFBc0QsQ0FDdkQsQ0FBQztJQUNKLENBQUM7SUFDRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLENBQUM7QUFDNUMsQ0FBQztBQTJCRCxNQUFNLFVBQVUsMEJBQTBCLENBQ3hDLE9BQTBCLEVBQzFCLFVBQTZDLEVBQUU7SUFFL0MsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNyQyxNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDckQsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFVBQVUsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNuRSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDYixPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUscUJBQXFCLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDO0lBQ3hFLENBQUM7SUFDRCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzNDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNYLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxrQkFBa0IsT0FBTyxHQUFHLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDO0lBQy9FLENBQUM7SUFDRCxNQUFNLFVBQVUsR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDLHNCQUFzQixDQUF1QixDQUFDO0lBQ3BGLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNoQixPQUFPO1lBQ0wsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsMENBQTBDLEVBQUUsRUFBRSxHQUFHLENBQUM7U0FDaEYsQ0FBQztJQUNKLENBQUM7SUFDRCxNQUFNLFFBQVEsR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDLG9CQUFvQixDQUF1QixDQUFDO0lBQ2hGLElBQUksT0FBTyxDQUFDLFFBQVEsS0FBSyxVQUFVLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNqRCxPQUFPO1lBQ0wsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsd0NBQXdDLEVBQUUsRUFBRSxHQUFHLENBQUM7U0FDOUUsQ0FBQztJQUNKLENBQUM7SUFDRCxPQUFPO1FBQ0wsT0FBTztRQUNQLEtBQUs7UUFDTCxjQUFjO1FBQ2QsVUFBVTtRQUNWLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztLQUNsQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU2hhcmVkIGFnZW50IGJpbmRpbmcgYW5kIHJlcXVlc3QtY29udGV4dCByZXNvbHV0aW9uIGZvciBNYXN0cmEgY3VzdG9tIHJvdXRlcy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgVmFsaWRhdGlvbkVycm9yIH0gZnJvbSBcIkBkYXRhYnJpY2tzL2FwcGtpdFwiO1xuaW1wb3J0IHR5cGUgeyBBZ2VudCB9IGZyb20gXCJAbWFzdHJhL2NvcmUvYWdlbnRcIjtcbmltcG9ydCB7XG4gIE1BU1RSQV9SRVNPVVJDRV9JRF9LRVksXG4gIE1BU1RSQV9USFJFQURfSURfS0VZLFxuICB0eXBlIFJlcXVlc3RDb250ZXh0LFxufSBmcm9tIFwiQG1hc3RyYS9jb3JlL3JlcXVlc3QtY29udGV4dFwiO1xuaW1wb3J0IHR5cGUgeyBDb250ZXh0V2l0aE1hc3RyYSB9IGZyb20gXCJAbWFzdHJhL2NvcmUvc2VydmVyXCI7XG5cbi8qKiBGaXhlZC1hZ2VudCBvciBkeW5hbWljIGA6YWdlbnRJZGAgYmluZGluZyBhY2NlcHRlZCBieSBjdXN0b20gYWdlbnQgcm91dGVzLiAqL1xuZXhwb3J0IHR5cGUgQWdlbnRSb3V0ZU9wdGlvbnMgPVxuICB7IHBhdGg6IGAke3N0cmluZ306YWdlbnRJZCR7c3RyaW5nfWA7IGFnZW50PzogbmV2ZXIgfSB8IHsgcGF0aDogc3RyaW5nOyBhZ2VudDogc3RyaW5nIH07XG5cbi8qKiBWYWxpZGF0ZWQgcm91dGUgcGF0aCBhbmQgb3B0aW9uYWwgZml4ZWQgYWdlbnQgYmluZGluZy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRBZ2VudFJvdXRlT3B0aW9ucyB7XG4gIHBhdGg6IHN0cmluZztcbiAgZml4ZWRBZ2VudDogc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuXG4vKiogUmVzb2x2ZSBhbmQgdmFsaWRhdGUgYSBmaXhlZCBvciBkeW5hbWljIGFnZW50IHJvdXRlIGRlY2xhcmF0aW9uLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVBZ2VudFJvdXRlT3B0aW9ucyhcbiAgb3B0aW9uczogQWdlbnRSb3V0ZU9wdGlvbnMsXG4gIGZpZWxkOiBzdHJpbmcsXG4pOiBSZXNvbHZlZEFnZW50Um91dGVPcHRpb25zIHtcbiAgY29uc3QgZml4ZWRBZ2VudCA9IFwiYWdlbnRcIiBpbiBvcHRpb25zID8gb3B0aW9ucy5hZ2VudCA6IHVuZGVmaW5lZDtcbiAgaWYgKCFmaXhlZEFnZW50ICYmICFvcHRpb25zLnBhdGguaW5jbHVkZXMoXCI6YWdlbnRJZFwiKSkge1xuICAgIHRocm93IFZhbGlkYXRpb25FcnJvci5pbnZhbGlkVmFsdWUoXG4gICAgICBmaWVsZCxcbiAgICAgIG9wdGlvbnMucGF0aCxcbiAgICAgIFwiYSBwYXRoIGNvbnRhaW5pbmcgYDphZ2VudElkYCwgb3IgYW4gZXhwbGljaXQgYGFnZW50YFwiLFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIHsgcGF0aDogb3B0aW9ucy5wYXRoLCBmaXhlZEFnZW50IH07XG59XG5cbmludGVyZmFjZSBSZXNvbHZlZEFnZW50UmVxdWVzdENvbnRleHQge1xuICBhZ2VudElkOiBzdHJpbmc7XG4gIGFnZW50OiBBZ2VudDtcbiAgcmVxdWVzdENvbnRleHQ6IFJlcXVlc3RDb250ZXh0O1xuICByZXNvdXJjZUlkOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBBZ2VudFJlcXVlc3RDb250ZXh0RXJyb3Ige1xuICBlcnJvcjogUmVzcG9uc2U7XG59XG5cbmludGVyZmFjZSBSZXNvbHZlQWdlbnRSZXF1ZXN0Q29udGV4dE9wdGlvbnMge1xuICBmaXhlZEFnZW50Pzogc3RyaW5nO1xuICB0aHJlYWRJZD86IFwib3B0aW9uYWxcIiB8IFwicmVxdWlyZWRcIjtcbn1cblxuLyoqIFJlc29sdmUgYW4gYWdlbnQgcGx1cyB0aGUgY2FsbGVyLXNjb3BlZCBNYXN0cmEgcmVxdWVzdCBjb250ZXh0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVBZ2VudFJlcXVlc3RDb250ZXh0KFxuICBjb250ZXh0OiBDb250ZXh0V2l0aE1hc3RyYSxcbiAgb3B0aW9uczogUmVzb2x2ZUFnZW50UmVxdWVzdENvbnRleHRPcHRpb25zICYgeyB0aHJlYWRJZDogXCJyZXF1aXJlZFwiIH0sXG4pOiAoUmVzb2x2ZWRBZ2VudFJlcXVlc3RDb250ZXh0ICYgeyB0aHJlYWRJZDogc3RyaW5nIH0pIHwgQWdlbnRSZXF1ZXN0Q29udGV4dEVycm9yO1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVBZ2VudFJlcXVlc3RDb250ZXh0KFxuICBjb250ZXh0OiBDb250ZXh0V2l0aE1hc3RyYSxcbiAgb3B0aW9ucz86IFJlc29sdmVBZ2VudFJlcXVlc3RDb250ZXh0T3B0aW9ucyxcbik6IChSZXNvbHZlZEFnZW50UmVxdWVzdENvbnRleHQgJiB7IHRocmVhZElkPzogc3RyaW5nIH0pIHwgQWdlbnRSZXF1ZXN0Q29udGV4dEVycm9yO1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVBZ2VudFJlcXVlc3RDb250ZXh0KFxuICBjb250ZXh0OiBDb250ZXh0V2l0aE1hc3RyYSxcbiAgb3B0aW9uczogUmVzb2x2ZUFnZW50UmVxdWVzdENvbnRleHRPcHRpb25zID0ge30sXG4pOiAoUmVzb2x2ZWRBZ2VudFJlcXVlc3RDb250ZXh0ICYgeyB0aHJlYWRJZD86IHN0cmluZyB9KSB8IEFnZW50UmVxdWVzdENvbnRleHRFcnJvciB7XG4gIGNvbnN0IG1hc3RyYSA9IGNvbnRleHQuZ2V0KFwibWFzdHJhXCIpO1xuICBjb25zdCByZXF1ZXN0Q29udGV4dCA9IGNvbnRleHQuZ2V0KFwicmVxdWVzdENvbnRleHRcIik7XG4gIGNvbnN0IGFnZW50SWQgPSBvcHRpb25zLmZpeGVkQWdlbnQgPz8gY29udGV4dC5yZXEucGFyYW0oXCJhZ2VudElkXCIpO1xuICBpZiAoIWFnZW50SWQpIHtcbiAgICByZXR1cm4geyBlcnJvcjogY29udGV4dC5qc29uKHsgZXJyb3I6IFwiYWdlbnRJZCBpcyByZXF1aXJlZFwiIH0sIDQwMCkgfTtcbiAgfVxuICBjb25zdCBhZ2VudCA9IG1hc3RyYS5nZXRBZ2VudEJ5SWQoYWdlbnRJZCk7XG4gIGlmICghYWdlbnQpIHtcbiAgICByZXR1cm4geyBlcnJvcjogY29udGV4dC5qc29uKHsgZXJyb3I6IGBVbmtub3duIGFnZW50IFwiJHthZ2VudElkfVwiYCB9LCA0MDQpIH07XG4gIH1cbiAgY29uc3QgcmVzb3VyY2VJZCA9IHJlcXVlc3RDb250ZXh0LmdldChNQVNUUkFfUkVTT1VSQ0VfSURfS0VZKSBhcyBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGlmICghcmVzb3VyY2VJZCkge1xuICAgIHJldHVybiB7XG4gICAgICBlcnJvcjogY29udGV4dC5qc29uKHsgZXJyb3I6IFwicmVzb3VyY2UgaWQgbWlzc2luZyBmcm9tIHJlcXVlc3QgY29udGV4dFwiIH0sIDQwMCksXG4gICAgfTtcbiAgfVxuICBjb25zdCB0aHJlYWRJZCA9IHJlcXVlc3RDb250ZXh0LmdldChNQVNUUkFfVEhSRUFEX0lEX0tFWSkgYXMgc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBpZiAob3B0aW9ucy50aHJlYWRJZCA9PT0gXCJyZXF1aXJlZFwiICYmICF0aHJlYWRJZCkge1xuICAgIHJldHVybiB7XG4gICAgICBlcnJvcjogY29udGV4dC5qc29uKHsgZXJyb3I6IFwidGhyZWFkIGlkIG1pc3NpbmcgZnJvbSByZXF1ZXN0IGNvbnRleHRcIiB9LCA0MDApLFxuICAgIH07XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBhZ2VudElkLFxuICAgIGFnZW50LFxuICAgIHJlcXVlc3RDb250ZXh0LFxuICAgIHJlc291cmNlSWQsXG4gICAgLi4uKHRocmVhZElkID8geyB0aHJlYWRJZCB9IDoge30pLFxuICB9O1xufVxuIl19
@@ -1,100 +0,0 @@
1
- /**
2
- * Shared agent binding and request-context resolution for Mastra custom routes.
3
- *
4
- * @module
5
- */
6
-
7
- import { ValidationError } from "@databricks/appkit";
8
- import type { Agent } from "@mastra/core/agent";
9
- import {
10
- MASTRA_RESOURCE_ID_KEY,
11
- MASTRA_THREAD_ID_KEY,
12
- type RequestContext,
13
- } from "@mastra/core/request-context";
14
- import type { ContextWithMastra } from "@mastra/core/server";
15
-
16
- /** Fixed-agent or dynamic `:agentId` binding accepted by custom agent routes. */
17
- export type AgentRouteOptions =
18
- { path: `${string}:agentId${string}`; agent?: never } | { path: string; agent: string };
19
-
20
- /** Validated route path and optional fixed agent binding. */
21
- export interface ResolvedAgentRouteOptions {
22
- path: string;
23
- fixedAgent: string | undefined;
24
- }
25
-
26
- /** Resolve and validate a fixed or dynamic agent route declaration. */
27
- export function resolveAgentRouteOptions(
28
- options: AgentRouteOptions,
29
- field: string,
30
- ): ResolvedAgentRouteOptions {
31
- const fixedAgent = "agent" in options ? options.agent : undefined;
32
- if (!fixedAgent && !options.path.includes(":agentId")) {
33
- throw ValidationError.invalidValue(
34
- field,
35
- options.path,
36
- "a path containing `:agentId`, or an explicit `agent`",
37
- );
38
- }
39
- return { path: options.path, fixedAgent };
40
- }
41
-
42
- interface ResolvedAgentRequestContext {
43
- agentId: string;
44
- agent: Agent;
45
- requestContext: RequestContext;
46
- resourceId: string;
47
- }
48
-
49
- interface AgentRequestContextError {
50
- error: Response;
51
- }
52
-
53
- interface ResolveAgentRequestContextOptions {
54
- fixedAgent?: string;
55
- threadId?: "optional" | "required";
56
- }
57
-
58
- /** Resolve an agent plus the caller-scoped Mastra request context. */
59
- export function resolveAgentRequestContext(
60
- context: ContextWithMastra,
61
- options: ResolveAgentRequestContextOptions & { threadId: "required" },
62
- ): (ResolvedAgentRequestContext & { threadId: string }) | AgentRequestContextError;
63
- export function resolveAgentRequestContext(
64
- context: ContextWithMastra,
65
- options?: ResolveAgentRequestContextOptions,
66
- ): (ResolvedAgentRequestContext & { threadId?: string }) | AgentRequestContextError;
67
- export function resolveAgentRequestContext(
68
- context: ContextWithMastra,
69
- options: ResolveAgentRequestContextOptions = {},
70
- ): (ResolvedAgentRequestContext & { threadId?: string }) | AgentRequestContextError {
71
- const mastra = context.get("mastra");
72
- const requestContext = context.get("requestContext");
73
- const agentId = options.fixedAgent ?? context.req.param("agentId");
74
- if (!agentId) {
75
- return { error: context.json({ error: "agentId is required" }, 400) };
76
- }
77
- const agent = mastra.getAgentById(agentId);
78
- if (!agent) {
79
- return { error: context.json({ error: `Unknown agent "${agentId}"` }, 404) };
80
- }
81
- const resourceId = requestContext.get(MASTRA_RESOURCE_ID_KEY) as string | undefined;
82
- if (!resourceId) {
83
- return {
84
- error: context.json({ error: "resource id missing from request context" }, 400),
85
- };
86
- }
87
- const threadId = requestContext.get(MASTRA_THREAD_ID_KEY) as string | undefined;
88
- if (options.threadId === "required" && !threadId) {
89
- return {
90
- error: context.json({ error: "thread id missing from request context" }, 400),
91
- };
92
- }
93
- return {
94
- agentId,
95
- agent,
96
- requestContext,
97
- resourceId,
98
- ...(threadId ? { threadId } : {}),
99
- };
100
- }