@dbx-tools/appkit-mastra 0.6.218 → 0.6.220

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.
Files changed (46) hide show
  1. package/README.md +72 -25
  2. package/index.ts +4 -7
  3. package/lib/index.d.ts +4 -7
  4. package/lib/index.js +4 -5
  5. package/lib/src/agents.d.ts +15 -6
  6. package/lib/src/agents.js +30 -12
  7. package/lib/src/chat.d.ts +7 -0
  8. package/lib/src/chat.js +19 -0
  9. package/lib/src/config.d.ts +2 -2
  10. package/lib/src/config.js +1 -1
  11. package/lib/src/genie.js +5 -4
  12. package/lib/src/memory.d.ts +2 -2
  13. package/lib/src/memory.js +2 -2
  14. package/lib/src/model.d.ts +2 -0
  15. package/lib/src/model.js +7 -1
  16. package/lib/src/plugin.d.ts +1 -1
  17. package/lib/src/plugin.js +3 -31
  18. package/lib/src/processors.d.ts +4 -28
  19. package/lib/src/processors.js +4 -61
  20. package/lib/src/server.d.ts +10 -21
  21. package/lib/src/server.js +52 -28
  22. package/lib/src/serving-sanitize.d.ts +8 -5
  23. package/lib/src/serving-sanitize.js +16 -11
  24. package/lib/src/trace-io.js +7 -3
  25. package/lib/src/writer.d.ts +7 -7
  26. package/lib/src/writer.js +12 -9
  27. package/lib/tsconfig.tsbuildinfo +1 -1
  28. package/package.json +23 -22
  29. package/src/agents.ts +92 -27
  30. package/src/chat.ts +20 -0
  31. package/src/config.ts +5 -2
  32. package/src/genie.ts +7 -11
  33. package/src/memory.ts +8 -8
  34. package/src/model.ts +7 -0
  35. package/src/plugin.ts +2 -30
  36. package/src/processors.ts +4 -66
  37. package/src/server.ts +49 -27
  38. package/src/serving-sanitize.ts +14 -10
  39. package/src/trace-io.ts +7 -2
  40. package/src/writer.ts +15 -11
  41. package/lib/src/history.d.ts +0 -93
  42. package/lib/src/history.js +0 -231
  43. package/lib/src/threads.d.ts +0 -104
  44. package/lib/src/threads.js +0 -264
  45. package/src/history.ts +0 -270
  46. package/src/threads.ts +0 -309
package/src/agents.ts CHANGED
@@ -19,7 +19,12 @@ import { ConfigurationError } from "@databricks/appkit";
19
19
  import { plugin } from "@dbx-tools/appkit";
20
20
  import { fallback } from "@dbx-tools/model";
21
21
  import { log, object, string } from "@dbx-tools/shared-core";
22
- import type { AgentConfig, ToolsInput } from "@mastra/core/agent";
22
+ import type {
23
+ AgentConfig,
24
+ AgentExecutionOptions,
25
+ AgentInstructions,
26
+ ToolsInput,
27
+ } from "@mastra/core/agent";
23
28
  import { Agent } from "@mastra/core/agent";
24
29
  import { MASTRA_RESOURCE_ID_KEY } from "@mastra/core/request-context";
25
30
  import type { Tool } from "@mastra/core/tools";
@@ -32,7 +37,7 @@ import type { MastraPluginConfig } from "./config.ts";
32
37
  import { buildGenieToolkitProvider, resolveGenieSpaces } from "./genie.ts";
33
38
  import type { MemoryBuilder } from "./memory.ts";
34
39
  import { buildModel } from "./model.ts";
35
- import { ResultProcessor, stripStaleChartsProcessor } from "./processors.ts";
40
+ import { stripStaleChartsProcessor } from "./processors.ts";
36
41
  import { TYPOGRAPHY_RULE } from "./style.ts";
37
42
  import { buildSummarizeTool } from "./summarize.ts";
38
43
  import { createWorkspace } from "./workspaces.ts";
@@ -155,7 +160,11 @@ function deriveToolId(description: string): string {
155
160
  * workspace carries Databricks skill mounts and Databricks Sandbox command
156
161
  * execution. An explicit workspace remains the caller's complete override.
157
162
  */
158
- export function createAgent<T extends MastraAgentDefinition>(def: T): T {
163
+ export function createAgent<
164
+ TRequestContext extends Record<string, unknown> | unknown = unknown,
165
+ TDefinition extends MastraAgentDefinition<TRequestContext> =
166
+ MastraAgentDefinition<TRequestContext>,
167
+ >(def: TDefinition): TDefinition {
159
168
  if (def.workspace) return { ...def };
160
169
  const workspace = createWorkspace();
161
170
  markDefaultWorkspace(workspace);
@@ -260,13 +269,27 @@ export type MastraAgentWorkspaceResolver = () => Workspace | undefined;
260
269
  * `config.agents` is the `agentId` the client streams against; `name`
261
270
  * is purely informational (defaults to the key).
262
271
  */
263
- export interface MastraAgentDefinition {
272
+ export interface MastraAgentDefinition<
273
+ TRequestContext extends Record<string, unknown> | unknown = unknown,
274
+ > {
264
275
  /** Display name used as `Agent.name`. Defaults to the registry key. */
265
276
  name?: string;
266
277
  /** Optional long-form description; surfaced as `Agent.description`. */
267
278
  description?: string;
268
- /** System prompt body. */
269
- instructions: string;
279
+ /** Static or request-context-aware system instructions. */
280
+ instructions: AgentConfig<string, ToolsInput, undefined, TRequestContext>["instructions"];
281
+ /** Native Mastra schema that validates and types application request context. */
282
+ requestContextSchema?: AgentConfig<
283
+ string,
284
+ ToolsInput,
285
+ undefined,
286
+ TRequestContext
287
+ >["requestContextSchema"];
288
+ /**
289
+ * Mastra-native per-call approval gate for this agent's tools. Supports an
290
+ * async Classifier-backed function; tool-level approval remains authoritative.
291
+ */
292
+ requireToolApproval?: AgentExecutionOptions["requireToolApproval"];
270
293
  /**
271
294
  * Per-agent model override.
272
295
  *
@@ -279,7 +302,7 @@ export interface MastraAgentDefinition {
279
302
  * straight through to `Agent.model`. Use this when you need full
280
303
  * control over auth or providerId.
281
304
  */
282
- model?: AgentConfig["model"] | string;
305
+ model?: AgentConfig<string, ToolsInput, undefined, TRequestContext>["model"] | string;
283
306
  /**
284
307
  * Per-agent tool record. Either a plain map or a callback that
285
308
  * receives the typed {@link MastraPlugins} sibling-plugin index and
@@ -323,6 +346,9 @@ export interface MastraAgentDefinition {
323
346
  workspace?: Workspace | MastraAgentWorkspaceResolver;
324
347
  }
325
348
 
349
+ /** Type-erased registry member; each definition retains typing at `createAgent`. */
350
+ export type AnyMastraAgentDefinition = MastraAgentDefinition<any>;
351
+
326
352
  /**
327
353
  * Distributive `Omit` so unions in `PostgresStoreConfig` /
328
354
  * `PgVectorConfig` keep their discriminants after the override types
@@ -433,13 +459,47 @@ function resolveStyleInstructions(config: MastraPluginConfig): string | null {
433
459
  return DEFAULT_STYLE_INSTRUCTIONS;
434
460
  }
435
461
 
462
+ /** Append the style block without narrowing Mastra's native instruction shapes. */
463
+ function appendStyleInstructions(
464
+ instructions: AgentInstructions,
465
+ style: string | null,
466
+ ): AgentInstructions {
467
+ if (!style) return instructions;
468
+ if (typeof instructions === "string") {
469
+ return `${instructions.trimEnd()}\n\n${style}`;
470
+ }
471
+ if (Array.isArray(instructions)) {
472
+ if (instructions.every((instruction) => typeof instruction === "string")) {
473
+ return [...instructions, style] as AgentInstructions;
474
+ }
475
+ return [...instructions, { role: "system", content: style }] as AgentInstructions;
476
+ }
477
+ return [instructions, { role: "system", content: style }] as AgentInstructions;
478
+ }
479
+
436
480
  /**
437
- * Join an agent's bespoke instructions with the resolved style block.
438
- * Returns the bespoke text unchanged when the style block is disabled.
481
+ * Compose static or request-context-aware instructions with the shared style
482
+ * policy while preserving Mastra's native generic inference.
439
483
  */
440
- function composeInstructions(agentInstructions: string, style: string | null): string {
441
- if (!style) return agentInstructions;
442
- return `${agentInstructions.trimEnd()}\n\n${style}`;
484
+ function composeInstructions<TRequestContext extends Record<string, unknown> | unknown>(
485
+ agentInstructions: AgentConfig<string, ToolsInput, undefined, TRequestContext>["instructions"],
486
+ style: string | null,
487
+ ): AgentConfig<string, ToolsInput, undefined, TRequestContext>["instructions"] {
488
+ if (typeof agentInstructions !== "function") {
489
+ return appendStyleInstructions(agentInstructions, style) as AgentConfig<
490
+ string,
491
+ ToolsInput,
492
+ undefined,
493
+ TRequestContext
494
+ >["instructions"];
495
+ }
496
+ return (async (args) =>
497
+ appendStyleInstructions(await agentInstructions(args), style)) as AgentConfig<
498
+ string,
499
+ ToolsInput,
500
+ undefined,
501
+ TRequestContext
502
+ >["instructions"];
443
503
  }
444
504
 
445
505
  /**
@@ -502,7 +562,6 @@ export async function buildAgents(opts: {
502
562
  // chartIds from prior assistant tool results into the new
503
563
  // turn's `[chart:<id>]` markers. Opt out per-plugin via
504
564
  // `config.stripStaleCharts: false`.
505
- const outputProcessors = [new ResultProcessor()];
506
565
  const inputProcessors = [
507
566
  ...(config.stripStaleCharts === false ? [] : [stripStaleChartsProcessor]),
508
567
  ];
@@ -536,15 +595,18 @@ export async function buildAgents(opts: {
536
595
  // omits it.
537
596
  description: def.description?.trim() || defaultAgentDescription(def.name ?? id),
538
597
  instructions: composeInstructions(def.instructions, style),
598
+ ...(def.requestContextSchema ? { requestContextSchema: def.requestContextSchema } : {}),
539
599
  model: resolveModel(config, def.model),
540
600
  defaultOptions: {
541
601
  maxSteps: config.agentMaxSteps ?? DEFAULT_AGENT_MAX_STEPS,
602
+ ...(def.requireToolApproval !== undefined
603
+ ? { requireToolApproval: def.requireToolApproval }
604
+ : {}),
542
605
  },
543
606
  tools,
544
607
  ...(memory ? { memory } : {}),
545
608
  ...(workspace ? { workspace } : {}),
546
609
  inputProcessors,
547
- outputProcessors,
548
610
  });
549
611
  // Surface the effective default model per agent so operators can
550
612
  // see at a glance which endpoint each agent points at without
@@ -642,7 +704,10 @@ function assertApprovalGatedToolsHaveStorage(
642
704
  * overrides (`X-Mastra-Model` etc.) and the workspace-catalogue
643
705
  * fuzzy match are still applied at runtime.
644
706
  */
645
- function describeAgentDefaultModel(config: MastraPluginConfig, def: MastraAgentDefinition): string {
707
+ function describeAgentDefaultModel(
708
+ config: MastraPluginConfig,
709
+ def: AnyMastraAgentDefinition,
710
+ ): string {
646
711
  const effective = def.model ?? config.defaultModel;
647
712
  if (typeof effective === "string") return effective;
648
713
  if (effective !== undefined) return "<dynamic>";
@@ -667,13 +732,13 @@ function describeAgentDefaultModel(config: MastraPluginConfig, def: MastraAgentD
667
732
  * Omitted or empty inputs fall back to a single built-in analyst so
668
733
  * the bare `mastra()` call still mounts a working chat route.
669
734
  */
670
- function resolveDefinitions(config: MastraPluginConfig): Record<string, MastraAgentDefinition> {
735
+ function resolveDefinitions(config: MastraPluginConfig): Record<string, AnyMastraAgentDefinition> {
671
736
  const input = config.agents;
672
737
  if (!input) return fallbackDefinitions();
673
738
 
674
739
  if (Array.isArray(input)) {
675
740
  if (input.length === 0) return fallbackDefinitions();
676
- const out: Record<string, MastraAgentDefinition> = {};
741
+ const out: Record<string, AnyMastraAgentDefinition> = {};
677
742
  input.forEach((def, i) => {
678
743
  const key = deriveAgentKey(def, i);
679
744
  if (out[key]) {
@@ -687,21 +752,21 @@ function resolveDefinitions(config: MastraPluginConfig): Record<string, MastraAg
687
752
  return out;
688
753
  }
689
754
 
690
- // Single-definition shorthand: an agent always has `instructions: string`,
691
- // a record-of-agents never has that field directly.
692
- if (typeof (input as MastraAgentDefinition).instructions === "string") {
693
- const def = input as MastraAgentDefinition;
755
+ // Single-definition shorthand: an agent owns the required `instructions`
756
+ // field (static or dynamic); a record-of-agents never owns it directly.
757
+ if ("instructions" in input) {
758
+ const def = input as AnyMastraAgentDefinition;
694
759
  const key = deriveAgentKey(def);
695
760
  return { [key]: def };
696
761
  }
697
762
 
698
- const record = input as Record<string, MastraAgentDefinition>;
763
+ const record = input as Record<string, AnyMastraAgentDefinition>;
699
764
  if (Object.keys(record).length === 0) return fallbackDefinitions();
700
765
  return record;
701
766
  }
702
767
 
703
768
  /** Derive a registry id from a definition's `name`, with a fallback. */
704
- function deriveAgentKey(def: MastraAgentDefinition, index?: number): string {
769
+ function deriveAgentKey(def: AnyMastraAgentDefinition, index?: number): string {
705
770
  if (def.name) {
706
771
  const slug = string.toIdentifier(def.name);
707
772
  if (slug) return slug;
@@ -710,7 +775,7 @@ function deriveAgentKey(def: MastraAgentDefinition, index?: number): string {
710
775
  }
711
776
 
712
777
  /** Built-in fallback registry used when `agents` is omitted / empty. */
713
- function fallbackDefinitions(): Record<string, MastraAgentDefinition> {
778
+ function fallbackDefinitions(): Record<string, AnyMastraAgentDefinition> {
714
779
  return {
715
780
  [FALLBACK_AGENT_ID]: {
716
781
  name: "Default Agent",
@@ -738,7 +803,7 @@ function fallbackDefinitions(): Record<string, MastraAgentDefinition> {
738
803
  */
739
804
  function resolveModel(
740
805
  config: MastraPluginConfig,
741
- override: MastraAgentDefinition["model"],
806
+ override: AnyMastraAgentDefinition["model"],
742
807
  ): AgentConfig["model"] {
743
808
  const effective = override ?? config.defaultModel;
744
809
  if (effective === undefined) {
@@ -758,7 +823,7 @@ function resolveModel(
758
823
  * survives - the caller already knows which agent was registering.
759
824
  */
760
825
  async function resolveTools(
761
- defTools: MastraAgentDefinition["tools"],
826
+ defTools: AnyMastraAgentDefinition["tools"],
762
827
  plugins: MastraPlugins,
763
828
  ambientTools: MastraTools,
764
829
  ): Promise<MastraTools> {
@@ -768,7 +833,7 @@ async function resolveTools(
768
833
  }
769
834
 
770
835
  function resolveAgentWorkspace(
771
- workspace: MastraAgentDefinition["workspace"],
836
+ workspace: AnyMastraAgentDefinition["workspace"],
772
837
  ): Workspace | undefined {
773
838
  if (!workspace) return undefined;
774
839
  return typeof workspace === "function" ? workspace() : workspace;
package/src/chat.ts ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Official Mastra AI SDK chat routes for browser-compatible UI streams.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ import { routes } from "@dbx-tools/shared-mastra";
8
+ import { chatRoute } from "@mastra/ai-sdk";
9
+
10
+ /** Register the official AI SDK chat stream plus its approval continuation. */
11
+ export function agentChatRoutes() {
12
+ const path = `${routes.MASTRA_ROUTES.chat}/:agentId` as `${string}:agentId`;
13
+ return [
14
+ chatRoute({
15
+ path,
16
+ sendReasoning: true,
17
+ sendSources: true,
18
+ }),
19
+ ];
20
+ }
package/src/config.ts CHANGED
@@ -22,7 +22,7 @@ import type { RequestContext } from "@mastra/core/request-context";
22
22
  import { MASTRA_RESOURCE_ID_KEY, MASTRA_THREAD_ID_KEY } from "@mastra/core/request-context";
23
23
  import type { PgVectorConfig, PostgresStoreConfig } from "@mastra/pg";
24
24
 
25
- import type { MastraAgentDefinition, MastraTools } from "./agents.ts";
25
+ import type { AnyMastraAgentDefinition, MastraTools } from "./agents.ts";
26
26
  import type { GenieSpacesConfig } from "./genie.ts";
27
27
  import { IDENTITY_MODES, type MastraIdentityMode } from "./identity.ts";
28
28
  import type { RemoteSkillsOption } from "./remote-skills.ts";
@@ -252,7 +252,10 @@ export interface MastraPluginConfig extends BasePluginConfig {
252
252
  * });
253
253
  * ```
254
254
  */
255
- agents?: Record<string, MastraAgentDefinition> | MastraAgentDefinition | MastraAgentDefinition[];
255
+ agents?:
256
+ | Record<string, AnyMastraAgentDefinition>
257
+ | AnyMastraAgentDefinition
258
+ | AnyMastraAgentDefinition[];
256
259
  /**
257
260
  * Ambient tools spread into every registered agent's tools record;
258
261
  * per-agent tools win on key collision. Use for a small shared
package/src/genie.ts CHANGED
@@ -48,10 +48,10 @@ import { plugin } from "@dbx-tools/appkit";
48
48
  import { chat, space as genieSpace } from "@dbx-tools/genie";
49
49
  import { error, log, string } from "@dbx-tools/shared-core";
50
50
  import { genieModel, type GenieMessage } from "@dbx-tools/shared-genie";
51
- import type { MastraWriter, StartedEvent } from "@dbx-tools/shared-mastra";
51
+ import type { StartedEvent } from "@dbx-tools/shared-mastra";
52
52
  import type { RequestContext } from "@mastra/core/request-context";
53
53
  import { MASTRA_THREAD_ID_KEY } from "@mastra/core/request-context";
54
- import { createTool } from "@mastra/core/tools";
54
+ import { createTool, type ToolExecutionContext } from "@mastra/core/tools";
55
55
  import { z } from "zod";
56
56
 
57
57
  import type { MastraTools } from "./agents.ts";
@@ -59,7 +59,7 @@ import { chartPlannerRequestSchema, chartToolOutputSchema, prepareChart } from "
59
59
  import { MASTRA_USER_KEY, resolveUserKey } from "./config.ts";
60
60
  import type { MastraPluginConfig, User } from "./config.ts";
61
61
  import { fetchStatementData } from "./statement.ts";
62
- import { safeWrite } from "./writer.ts";
62
+ import { safeWriteProgress } from "./writer.ts";
63
63
 
64
64
  const logger = log.logger("mastra/genie");
65
65
 
@@ -96,12 +96,7 @@ export type GenieSpacesConfig = Record<string, GenieSpaceConfig | string>;
96
96
  * `abortSignal` (for per-call cancellation).
97
97
  */
98
98
  type ToolExecuteCtx =
99
- | {
100
- requestContext?: RequestContext;
101
- writer?: MastraWriter;
102
- abortSignal?: AbortSignal;
103
- }
104
- | undefined;
99
+ Pick<ToolExecutionContext, "requestContext" | "writer" | "abortSignal" | "agent"> | undefined;
105
100
 
106
101
  /**
107
102
  * Pull the per-request {@link WorkspaceClient} off the active
@@ -435,6 +430,7 @@ function buildAskGenieTool(opts: {
435
430
  const ctx = ctxRaw as ToolExecuteCtx;
436
431
  const { client, requestContext } = requireClient(ctx, toolId);
437
432
  const writer = ctx?.writer;
433
+ const toolCallId = ctx?.agent?.toolCallId;
438
434
  const signal = ctx?.abortSignal;
439
435
  const threadId = requestContext.get(MASTRA_THREAD_ID_KEY) as string | undefined;
440
436
 
@@ -475,7 +471,7 @@ function buildAskGenieTool(opts: {
475
471
  spaceId,
476
472
  content: question,
477
473
  };
478
- await safeWrite(logger, writer, startedEvent);
474
+ await safeWriteProgress(logger, writer, toolCallId, startedEvent);
479
475
 
480
476
  const runTurn = async (): Promise<GenieMessage> => {
481
477
  const seedConversationId = conversationId;
@@ -487,7 +483,7 @@ function buildAskGenieTool(opts: {
487
483
  ...(signal ? { context: signal } : {}),
488
484
  })) {
489
485
  if (event.type !== "message") {
490
- await safeWrite(logger, writer, event);
486
+ await safeWriteProgress(logger, writer, toolCallId, event);
491
487
  }
492
488
  const eventConversationId = event.conversation_id;
493
489
  if (eventConversationId) {
package/src/memory.ts CHANGED
@@ -39,7 +39,7 @@ import { Memory } from "@mastra/memory";
39
39
  import { PgVector, PostgresStore } from "@mastra/pg";
40
40
  import { Pool, type PoolConfig } from "pg";
41
41
 
42
- import type { MastraAgentDefinition, MastraMemoryConfigOverride } from "./agents.ts";
42
+ import type { AnyMastraAgentDefinition, MastraMemoryConfigOverride } from "./agents.ts";
43
43
  import type { MastraPluginConfig } from "./config.ts";
44
44
  import { agentStorageSchemaName } from "./storage-schema.ts";
45
45
  import { summaryModel, TITLE_INSTRUCTIONS } from "./summarize.ts";
@@ -143,8 +143,8 @@ export async function createServicePrincipalPool(pgConfig: PoolConfig): Promise<
143
143
  }
144
144
 
145
145
  /** Effective per-knob setting after the plugin/agent cascade. */
146
- type StorageSetting = MastraAgentDefinition["storage"];
147
- type MemorySetting = MastraAgentDefinition["memory"];
146
+ type StorageSetting = AnyMastraAgentDefinition["storage"];
147
+ type MemorySetting = AnyMastraAgentDefinition["memory"];
148
148
 
149
149
  /**
150
150
  * True when any plugin-level or per-agent setting could need the
@@ -223,7 +223,7 @@ export class MemoryBuilder {
223
223
  * vector store enabled - Mastra accepts a missing `memory` field
224
224
  * and treats the agent as stateless.
225
225
  */
226
- forAgent(agentId: string, def: MastraAgentDefinition): Memory | undefined {
226
+ forAgent(agentId: string, def: AnyMastraAgentDefinition): Memory | undefined {
227
227
  const storageSetting = def.storage ?? this.config.storage;
228
228
  const memorySetting = def.memory ?? this.config.memory;
229
229
 
@@ -368,14 +368,14 @@ function settingNeedsSharedPool(setting: StorageSetting | MemorySetting | undefi
368
368
  }
369
369
 
370
370
  /** Walk the three shapes of `config.agents` into a flat list. */
371
- function collectAgentDefinitions(config: MastraPluginConfig): MastraAgentDefinition[] {
371
+ function collectAgentDefinitions(config: MastraPluginConfig): AnyMastraAgentDefinition[] {
372
372
  const agents = config.agents;
373
373
  if (!agents) return [];
374
374
  if (Array.isArray(agents)) return agents;
375
- if (typeof (agents as MastraAgentDefinition).instructions === "string") {
376
- return [agents as MastraAgentDefinition];
375
+ if ("instructions" in agents) {
376
+ return [agents as AnyMastraAgentDefinition];
377
377
  }
378
- return Object.values(agents as Record<string, MastraAgentDefinition>);
378
+ return Object.values(agents);
379
379
  }
380
380
 
381
381
  /** Fill in a default `id` when the caller didn't supply one. */
package/src/model.ts CHANGED
@@ -25,6 +25,7 @@
25
25
 
26
26
  import { getExecutionContext } from "@databricks/appkit";
27
27
  import { classes, invoke, resolve } from "@dbx-tools/model";
28
+ import { ModelServingApi, modelServingApi } from "@dbx-tools/model-rs";
28
29
  import { functionModule, json, log, net } from "@dbx-tools/shared-core";
29
30
  import { model } from "@dbx-tools/shared-model";
30
31
  import type { MastraModelConfig } from "@mastra/core/llm";
@@ -42,6 +43,11 @@ type ModelClass = model.ModelClass;
42
43
  const { parseModelClass } = classes;
43
44
  const { selectModel } = resolve;
44
45
 
46
+ /** Pick the native Databricks inference surface required by a resolved model. */
47
+ export function servingApi(modelId: string): "chat" | "responses" {
48
+ return modelServingApi(modelId) === ModelServingApi.Responses ? "responses" : "chat";
49
+ }
50
+
45
51
  /** Optional overrides accepted by {@link buildModel}. */
46
52
  export interface BuildModelOverrides {
47
53
  /**
@@ -128,6 +134,7 @@ export async function buildModel(
128
134
  modelId,
129
135
  url,
130
136
  headers: Object.fromEntries(headers.entries()),
137
+ api: servingApi(modelId),
131
138
  };
132
139
  }
133
140
 
package/src/plugin.ts CHANGED
@@ -76,6 +76,7 @@ import type { Pool } from "pg";
76
76
 
77
77
  import { buildAgents, FALLBACK_AGENT_ID, type BuiltAgents } from "./agents.ts";
78
78
  import { fetchChart } from "./chart.ts";
79
+ import { agentChatRoutes } from "./chat.ts";
79
80
  import { attributedUserId, MASTRA_CONFIG_SCHEMA, type MastraPluginConfig } from "./config.ts";
80
81
  import {
81
82
  chartFetchDefaults,
@@ -85,7 +86,6 @@ import {
85
86
  statementDataDefaults,
86
87
  } from "./defaults.ts";
87
88
  import { collectSpaceSuggestions, resolveGenieSpaces } from "./genie.ts";
88
- import { historyRoute } from "./history.ts";
89
89
  import {
90
90
  requestUserId,
91
91
  resolveIdentityMode,
@@ -105,7 +105,6 @@ import {
105
105
  } from "./server.ts";
106
106
  import { resolveServingConfig } from "./serving.ts";
107
107
  import { fetchStatementData, STATEMENT_ROW_CAP } from "./statement.ts";
108
- import { threadsRoute } from "./threads.ts";
109
108
  import { attachChatTurnTraceIo } from "./trace-io.ts";
110
109
  import { invalidFields } from "./validation.ts";
111
110
 
@@ -1122,34 +1121,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
1122
1121
  app: this.mastraApp,
1123
1122
  mastra: this.mastra,
1124
1123
  prefix: "",
1125
- customApiRoutes: [
1126
- // `historyRoute` registers both GET (load) and DELETE
1127
- // (clear) on the same path, so it returns an array we
1128
- // splice in.
1129
- ...historyRoute({
1130
- path: routes.MASTRA_ROUTES.history,
1131
- agent: this.built.defaultAgentId,
1132
- }),
1133
- // Assert the `:agentId` template type: the per-package build's
1134
- // NodeNext resolution widens the imported `routes.MASTRA_ROUTES.history`
1135
- // to `string` (the source/bundler typecheck keeps it a literal),
1136
- // which would otherwise drop this out of the dynamic-agent
1137
- // overload and demand a fixed `agent`.
1138
- ...historyRoute({
1139
- path: `${routes.MASTRA_ROUTES.history}/:agentId` as `${string}:agentId`,
1140
- }),
1141
- // `threadsRoute` registers GET (list the caller's conversation
1142
- // threads) and DELETE (remove the targeted thread) on the same
1143
- // path; both the default-agent and dynamic-agent mounts are
1144
- // spliced in, mirroring the history routes above.
1145
- ...threadsRoute({
1146
- path: routes.MASTRA_ROUTES.threads,
1147
- agent: this.built.defaultAgentId,
1148
- }),
1149
- ...threadsRoute({
1150
- path: `${routes.MASTRA_ROUTES.threads}/:agentId` as `${string}:agentId`,
1151
- }),
1152
- ],
1124
+ customApiRoutes: agentChatRoutes(),
1153
1125
  });
1154
1126
  await this.mastraServer.init();
1155
1127
  this.logger.info("ready", {
package/src/processors.ts CHANGED
@@ -1,21 +1,15 @@
1
1
  /**
2
2
  * Mastra stream processors wired onto the plugin's agents.
3
3
  *
4
- * Two complementary processors live here:
5
- *
6
- * - An **input** processor ({@link stripStaleChartsProcessor}) that
7
- * scrubs turn-scoped `chartId` fields out of prior tool results
8
- * replayed from Memory, so the model can't copy a stale id into the
9
- * new turn's `[chart:<id>]` markers.
10
- * - An **output** processor ({@link ResultProcessor}) that trims the
11
- * bulky, redundant payload fields off targeted outbound stream frames
12
- * before they're serialized to the SSE client.
4
+ * The input processor ({@link stripStaleChartsProcessor}) scrubs turn-scoped
5
+ * `chartId` fields out of prior tool results replayed from Memory, so the model
6
+ * cannot copy a stale id into the new turn's `[chart:<id>]` markers.
13
7
  *
14
8
  * @module
15
9
  */
16
10
 
17
11
  import { log } from "@dbx-tools/shared-core";
18
- import type { InputProcessor, ProcessInputArgs, Processor } from "@mastra/core/processors";
12
+ import type { InputProcessor, ProcessInputArgs } from "@mastra/core/processors";
19
13
 
20
14
  const logger = log.logger("mastra/processors");
21
15
 
@@ -112,59 +106,3 @@ export const stripStaleChartsProcessor: InputProcessor = {
112
106
  return args.messages;
113
107
  },
114
108
  };
115
-
116
- /**
117
- * Mastra output processor that trims the bulky, redundant payload
118
- * fields off targeted outbound stream frames.
119
- *
120
- * Mastra emits step / finish / tool-result frames whose payloads
121
- * echo the full tool `output` / `result` / assistant `messages` /
122
- * `response` - data the chat client already received inline and
123
- * doesn't need re-sent. This processor empties those keys on the
124
- * targeted frame types so the outbound SSE stream stays lean;
125
- * every other frame passes through untouched.
126
- */
127
- export class ResultProcessor implements Processor {
128
- id = "result-processor";
129
-
130
- // Tell Mastra to also route tool/data parts to this processor method
131
- processDataParts = true;
132
-
133
- async processOutputStream({ part }: { part: any }): Promise<any | null> {
134
- // 1. Guard clause: Ensure the chunk is a valid object
135
- if (!part || typeof part !== "object") {
136
- return part;
137
- }
138
-
139
- // 2. Filter for the targeted frame types
140
- const targetedTypes = ["step-finish", "finish", "tool-result", "data-tool-agent"];
141
- if (!targetedTypes.includes(part.type)) {
142
- return part; // Return unchanged to pass-through
143
- }
144
-
145
- // 3. Check for the presence of a payload object
146
- const payload = part.payload;
147
- if (!payload || typeof payload !== "object") {
148
- return part;
149
- }
150
-
151
- // 4. Safely delete the unwanted keys from the payload reference
152
- const keysToDelete = ["output", "messages", "response", "result"];
153
- for (const key of keysToDelete) {
154
- if (key in payload) {
155
- const value = payload[key];
156
- if (typeof value === "object") {
157
- payload[key] = {};
158
- } else if (Array.isArray(value)) {
159
- payload[key] = [];
160
- } else {
161
- delete payload[key];
162
- }
163
- }
164
- }
165
-
166
- // 5. Return the modified part object. Mastra handles re-serialization
167
- // for the outbound SSE client stream automatically.
168
- return part;
169
- }
170
- }