@dbx-tools/appkit-mastra 0.9.117 → 0.9.119

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/package.json CHANGED
@@ -34,20 +34,21 @@
34
34
  },
35
35
  "dependencies": {
36
36
  "@databricks/appkit": "0.81.0",
37
- "@dbx-tools/appkit": "^0.9.117",
38
- "@dbx-tools/core": "^0.9.117",
39
- "@dbx-tools/databricks": "^0.9.117",
40
- "@dbx-tools/fs": "^0.9.117",
41
- "@dbx-tools/genie": "^0.9.117",
42
- "@dbx-tools/model": "^0.9.117",
43
- "@dbx-tools/model-protocol": "^0.9.117",
44
- "@dbx-tools/path": "^0.9.117",
45
- "@dbx-tools/postgres": "^0.9.117",
46
- "@dbx-tools/shared-core": "^0.9.117",
47
- "@dbx-tools/shared-fs": "^0.9.117",
48
- "@dbx-tools/shared-genie": "^0.9.117",
49
- "@dbx-tools/shared-mastra": "^0.9.117",
50
- "@dbx-tools/shared-model": "^0.9.117",
37
+ "@dbx-tools/appkit": "^0.9.119",
38
+ "@dbx-tools/cache": "^0.9.119",
39
+ "@dbx-tools/core": "^0.9.119",
40
+ "@dbx-tools/databricks": "^0.9.119",
41
+ "@dbx-tools/fs": "^0.9.119",
42
+ "@dbx-tools/genie": "^0.9.119",
43
+ "@dbx-tools/model": "^0.9.119",
44
+ "@dbx-tools/model-protocol": "^0.9.119",
45
+ "@dbx-tools/path": "^0.9.119",
46
+ "@dbx-tools/postgres": "^0.9.119",
47
+ "@dbx-tools/shared-core": "^0.9.119",
48
+ "@dbx-tools/shared-fs": "^0.9.119",
49
+ "@dbx-tools/shared-genie": "^0.9.119",
50
+ "@dbx-tools/shared-mastra": "^0.9.119",
51
+ "@dbx-tools/shared-model": "^0.9.119",
51
52
  "@mastra/ai-sdk": "1.10.5",
52
53
  "@mastra/core": "1.71.0",
53
54
  "@mastra/express": "1.5.15",
@@ -68,7 +69,6 @@
68
69
  "ai": "^7.0.0",
69
70
  "express": "^5.1.0",
70
71
  "fuse.js": "^7.4.2",
71
- "lru-cache": "11.5.3",
72
72
  "pg": "^8.22.0",
73
73
  "yaml": "^2.9.0",
74
74
  "zod": "4.3.6"
@@ -164,10 +164,6 @@
164
164
  "types": "./lib/src/rest.d.ts",
165
165
  "default": "./lib/src/rest.js"
166
166
  },
167
- "./sandbox": {
168
- "types": "./lib/src/sandbox.d.ts",
169
- "default": "./lib/src/sandbox.js"
170
- },
171
167
  "./server": {
172
168
  "types": "./lib/src/server.d.ts",
173
169
  "default": "./lib/src/server.js"
@@ -223,7 +219,7 @@
223
219
  "./package.json": "./package.json"
224
220
  }
225
221
  },
226
- "version": "0.9.117",
222
+ "version": "0.9.119",
227
223
  "types": "./lib/index.d.ts",
228
224
  "dbxToolsConfig": {
229
225
  "tags": [
@@ -316,10 +312,6 @@
316
312
  "types": "./lib/src/rest.d.ts",
317
313
  "default": "./lib/src/rest.js"
318
314
  },
319
- "./sandbox": {
320
- "types": "./lib/src/sandbox.d.ts",
321
- "default": "./lib/src/sandbox.js"
322
- },
323
315
  "./server": {
324
316
  "types": "./lib/src/server.d.ts",
325
317
  "default": "./lib/src/server.js"
package/src/agents.ts CHANGED
@@ -35,7 +35,7 @@ import type {
35
35
  } from "@mastra/core/agent";
36
36
  import { Agent } from "@mastra/core/agent";
37
37
  import { createEventedAgent } from "@mastra/core/agent/durable";
38
- import { SkillSearchProcessor } from "@mastra/core/processors";
38
+ import { SkillSearchProcessor, ToolCallFilter } from "@mastra/core/processors";
39
39
  import type { OutputProcessor } from "@mastra/core/processors";
40
40
  import { MASTRA_RESOURCE_ID_KEY } from "@mastra/core/request-context";
41
41
  import type { RequestContext } from "@mastra/core/request-context";
@@ -738,6 +738,11 @@ export async function buildAgents(opts: {
738
738
  // turn's `[chart:<id>]` markers. Opt out per-plugin via
739
739
  // `config.stripStaleCharts: false`.
740
740
  const inputProcessors = [
741
+ // `render_data` can carry hundreds of inline rows. Keep the complete call
742
+ // in Memory and the UI transcript, but use Mastra's native prompt-stage
743
+ // filter to omit prior calls/results from later model requests. Current
744
+ // turn calls remain available to the agent loop.
745
+ new ToolCallFilter({ exclude: ["render_data"] }),
741
746
  ...(config.stripStaleCharts === false ? [] : [stripStaleChartsProcessor]),
742
747
  ];
743
748
  const agents: Record<string, Agent> = {};
@@ -762,7 +767,7 @@ export async function buildAgents(opts: {
762
767
  fallbackToTmp: config.workspaceFallbackToTmp,
763
768
  ...(config.workspaceTools !== undefined ? { tools: config.workspaceTools } : {}),
764
769
  pluginContext: context,
765
- sandbox: config.sandbox === true ? "databricks" : config.sandbox,
770
+ sandbox: config.sandbox,
766
771
  });
767
772
  markDefaultWorkspace(workspace);
768
773
  } else if (workspace) {
package/src/config.ts CHANGED
@@ -20,14 +20,17 @@ import type { BrandContext } from "@dbx-tools/shared-core";
20
20
  import type { AgentConfig } from "@mastra/core/agent";
21
21
  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
- import type { WorkspaceToolsConfig } from "@mastra/core/workspace";
23
+ import type {
24
+ WorkspaceSandbox,
25
+ WorkspaceSandboxResolver,
26
+ WorkspaceToolsConfig,
27
+ } from "@mastra/core/workspace";
24
28
  import type { PgVectorConfig, PostgresStoreConfig } from "@mastra/pg";
25
29
 
26
30
  import type { AnyMastraAgentDefinition, MastraTools } from "./agents.ts";
27
31
  import type { GenieSpacesConfig } from "./genie.ts";
28
32
  import { IDENTITY_MODES, type MastraIdentityMode } from "./identity.ts";
29
- import type { RemoteSkillsOption } from "./remote-skills.ts";
30
- import type { DatabricksWorkspaceSandboxOptions } from "./sandbox.ts";
33
+ import type { LocalSkillMount, RemoteSkillsOption } from "./remote-skills.ts";
31
34
 
32
35
  /**
33
36
  * `RequestContext` key under which {@link MastraServer} stores the
@@ -226,20 +229,22 @@ export interface MastraPluginConfig extends BasePluginConfig {
226
229
  */
227
230
  memory?: boolean | MastraMemoryConfig;
228
231
  /**
229
- * Expose executable tools from each agent definition through native Mastra
230
- * Code Mode. Defaults on whenever the agent has executable tools. The plugin
231
- * selects Mastra's isolated-vm transport once during startup and falls back
232
- * to Mastra QuickJS when the native transport is unavailable. Set `false` to
232
+ * Expose executable tools available to the current request through native
233
+ * Mastra Code Mode. Defaults on whenever the request has executable tools.
234
+ * The plugin selects Mastra's isolated-vm transport once during startup and
235
+ * falls back to Mastra QuickJS when the native transport is unavailable.
236
+ * These transports do not execute through the workspace command sandbox;
237
+ * SSH is used only when an exposed SSH-backed tool is called. Set `false` to
233
238
  * opt out.
234
239
  */
235
240
  codeMode?: boolean | MastraCodeModeConfig;
236
241
  /**
237
242
  * Sandbox for auto-created agent workspaces. Defaults to Monty. `false`
238
- * disables command execution; `true`, `"databricks"`, or an object
239
- * selects/configures Databricks Sandbox. An agent with an explicit custom
240
- * `workspace` keeps that workspace and its sandbox.
243
+ * disables command execution; `true` or `"monty"` selects Monty; an explicit
244
+ * Mastra sandbox or resolver supplies a remote transport. An agent with an
245
+ * explicit custom `workspace` keeps that workspace and its sandbox.
241
246
  */
242
- sandbox?: boolean | "databricks" | "monty" | DatabricksWorkspaceSandboxOptions;
247
+ sandbox?: boolean | "monty" | WorkspaceSandbox | WorkspaceSandboxResolver;
243
248
  /** Add user-scoped `/tmp` only when no configured workspace path mounts writable. */
244
249
  workspaceFallbackToTmp?: boolean;
245
250
  /** Native Mastra workspace tool availability, approval, and hook configuration. */
@@ -634,10 +639,10 @@ export interface MastraPluginConfig extends BasePluginConfig {
634
639
  * without it, a URL source is fetched directly. A source that resolves
635
640
  * through neither fails startup unless `failOnError: false`.
636
641
  *
637
- * Provisioned skills are written to the Databricks user's Assistant skills
638
- * folder (`/Workspace/Users/<email>/.assistant/skills`, the personal skill
639
- * target) so they persist and are picked up by the built-in Assistant-skills
640
- * mount. With no writable workspace, they go to a local temp dir instead.
642
+ * AI Tools is cached daily with `@dbx-tools/cache` and served to every
643
+ * auto-created workspace from the shared `/.databricks/skills` memory mount.
644
+ * Other sources are written to the Databricks user's Assistant skills folder
645
+ * when writable, with a read-only local-memory fallback.
641
646
  *
642
647
  * @example
643
648
  * ```ts
@@ -651,6 +656,8 @@ export interface MastraPluginConfig extends BasePluginConfig {
651
656
  * ```
652
657
  */
653
658
  remoteSkills?: RemoteSkillsOption;
659
+ /** Read-only local skill trees mounted into every default agent workspace. */
660
+ localSkillMounts?: LocalSkillMount[];
654
661
  }
655
662
 
656
663
  /**
@@ -677,7 +684,7 @@ export const MASTRA_CONFIG_SCHEMA: ConfigSchema = {
677
684
  remoteSkills: {
678
685
  type: ["string", "array", "object"],
679
686
  description:
680
- 'Remote Agent-Skill sources provisioned at startup: "aitools" for Databricks\' own skill set (read from the public databricks/databricks-agent-skills repo, no CLI needed), a GitHub owner/repo, a git/GitLab URL, or a direct SKILL.md/archive URL. Non-aitools sources prefer the optional `skills` npm CLI, else a direct fetch; fails startup on error unless failOnError:false. Written to the Databricks user Assistant skills folder, or read-only local backing storage exposed at stable virtual workspace mounts.',
687
+ 'Remote Agent-Skill sources provisioned at startup: "aitools" for Databricks\' own skill set (daily @dbx-tools/cache snapshot served from the shared in-memory /.databricks/skills mount), a GitHub owner/repo, a git/GitLab URL, or a direct SKILL.md/archive URL. Non-aitools sources prefer the optional `skills` npm CLI, else a direct fetch; fails startup on error unless failOnError:false. Other sources write to the Databricks user Assistant skills folder or a read-only local-memory fallback.',
681
688
  },
682
689
  storage: {
683
690
  type: ["boolean", "object"],
@@ -692,12 +699,12 @@ export const MASTRA_CONFIG_SCHEMA: ConfigSchema = {
692
699
  codeMode: {
693
700
  type: ["boolean", "object"],
694
701
  description:
695
- "Expose all executable tools available to the current request, including native workspace tools, through dynamically generated Mastra Code Mode for sandboxed TypeScript batching, aggregation, and arithmetic. The plugin selects Mastra isolated-vm once during startup and falls back to Mastra QuickJS when native initialization is unavailable. False disables it.",
702
+ "Expose all executable tools available to the current request through native Mastra Code Mode for TypeScript batching, aggregation, and arithmetic. The plugin uses Mastra isolated-vm with the existing QuickJS fallback; neither transport runs through the workspace command sandbox, so SSH is used only when an SSH-backed tool is called. False disables it.",
696
703
  },
697
704
  sandbox: {
698
705
  type: ["boolean", "string", "object"],
699
706
  description:
700
- 'Command sandbox for auto-created agent workspaces. Defaults to Monty. False disables command execution; true, "databricks", or an object selects/configures Databricks Sandbox.',
707
+ 'Command sandbox for auto-created agent workspaces. Defaults to Monty. False disables command execution; true or "monty" selects Monty; an explicit sandbox or resolver supplies another transport.',
701
708
  },
702
709
  workspaceFallbackToTmp: {
703
710
  type: "boolean",
package/src/defaults.ts CHANGED
@@ -53,9 +53,9 @@ const STATEMENT_CACHE_TTL_SEC = 5 * 60;
53
53
  export const modelCatalogueDefaults: ExecuteSettings = {
54
54
  default: {
55
55
  // Cache disabled here because `listServingEndpoints` already memoizes the
56
- // catalogue through the same `CacheManager`, keyed by workspace host with
57
- // `config.modelCacheTtlMs`. That entry is shared across identities; a
58
- // second interceptor cache would duplicate it once per user.
56
+ // catalogue in the shared model cache, keyed by workspace host and trusted
57
+ // credential identity with `config.modelCacheTtlMs`. A second interceptor
58
+ // cache would duplicate it once per user.
59
59
  cache: { enabled: false },
60
60
  // Retry enabled: listing endpoints is an idempotent GET, and the listing
61
61
  // is on the chat UI's load path, so a transient 5xx should not blank the
package/src/genie.ts CHANGED
@@ -45,6 +45,7 @@ import {
45
45
  } from "@databricks/appkit";
46
46
  import type { WorkspaceClient } from "@databricks/appkit";
47
47
  import { pluginRegistry } from "@dbx-tools/appkit";
48
+ import { createCache } from "@dbx-tools/cache/cache";
48
49
  import { chat, space as genieSpace } from "@dbx-tools/genie";
49
50
  import { errorUtils, log, stringUtils } from "@dbx-tools/shared-core";
50
51
  import { genieModel, type GenieMessage } from "@dbx-tools/shared-genie";
@@ -52,7 +53,6 @@ import type { StartedEvent } from "@dbx-tools/shared-mastra";
52
53
  import type { RequestContext } from "@mastra/core/request-context";
53
54
  import { MASTRA_THREAD_ID_KEY } from "@mastra/core/request-context";
54
55
  import { createTool, type ToolExecutionContext } from "@mastra/core/tools";
55
- import { LRUCache } from "lru-cache";
56
56
  import { z } from "zod";
57
57
 
58
58
  import type { MastraTools } from "./agents.ts";
@@ -1091,19 +1091,19 @@ const SUGGESTION_LIMIT = 6;
1091
1091
  const SUGGESTION_CACHE_TTL_MS = 10 * 60_000;
1092
1092
 
1093
1093
  /** Bounded process-local cache of parsed sample questions by Genie space id. */
1094
- const _suggestionCache = new LRUCache<string, string[]>({
1095
- max: 128,
1094
+ const _suggestionCache = createCache({
1095
+ maxEntries: 128,
1096
1096
  ttl: SUGGESTION_CACHE_TTL_MS,
1097
1097
  });
1098
1098
 
1099
1099
  /** Read a space's cached questions, or `undefined` on miss / expiry. */
1100
- function readSuggestionCache(spaceId: string): string[] | undefined {
1101
- return _suggestionCache.get(spaceId);
1100
+ function readSuggestionCache(spaceId: string): Promise<string[] | undefined> {
1101
+ return _suggestionCache.get<string[]>(spaceId);
1102
1102
  }
1103
1103
 
1104
1104
  /** Cache a space's parsed questions for {@link SUGGESTION_CACHE_TTL_MS}. */
1105
- function writeSuggestionCache(spaceId: string, questions: string[]): void {
1106
- _suggestionCache.set(spaceId, questions);
1105
+ async function writeSuggestionCache(spaceId: string, questions: string[]): Promise<void> {
1106
+ await _suggestionCache.set(spaceId, questions);
1107
1107
  }
1108
1108
 
1109
1109
  /**
@@ -1128,7 +1128,7 @@ export async function collectSpaceSuggestions(opts: {
1128
1128
  const seen = new Set<string>();
1129
1129
 
1130
1130
  for (const { spaceId } of Object.values(opts.spaces)) {
1131
- let questions = readSuggestionCache(spaceId);
1131
+ let questions = await readSuggestionCache(spaceId);
1132
1132
  if (!questions) {
1133
1133
  try {
1134
1134
  const space = await genieSpace.getGenieSpace(spaceId, {
@@ -1136,7 +1136,7 @@ export async function collectSpaceSuggestions(opts: {
1136
1136
  ...(opts.signal ? { context: opts.signal } : {}),
1137
1137
  });
1138
1138
  questions = genieSpace.genieSampleQuestions(space);
1139
- writeSuggestionCache(spaceId, questions);
1139
+ await writeSuggestionCache(spaceId, questions);
1140
1140
  } catch (err) {
1141
1141
  logger.warn("suggestions:fetch-error", {
1142
1142
  spaceId,
package/src/model.ts CHANGED
@@ -22,13 +22,14 @@
22
22
  * @module
23
23
  */
24
24
 
25
- import { getExecutionContext } from "@databricks/appkit";
25
+ import { createWorkspaceClient, type WorkspaceClient } from "@databricks/appkit";
26
+ import { appkit } from "@dbx-tools/appkit";
26
27
  import { classes, policy, resolve } from "@dbx-tools/model";
27
28
  import { createDatabricksLanguageModel } from "@dbx-tools/model-protocol/provider";
28
29
  import { log } from "@dbx-tools/shared-core";
29
30
  import { model, type ServingEndpointSummary } from "@dbx-tools/shared-model";
30
31
  import type { MastraModelConfig } from "@mastra/core/llm";
31
- import type { RequestContext } from "@mastra/core/request-context";
32
+ import { RequestContext } from "@mastra/core/request-context";
32
33
 
33
34
  import { MASTRA_USER_KEY, type MastraPluginConfig, type User } from "./config.ts";
34
35
  import {
@@ -73,6 +74,32 @@ export interface BuildModelOverrides {
73
74
  modelClass?: ModelClass;
74
75
  }
75
76
 
77
+ /** Resolved workspace client and the authentication mode backing it. */
78
+ interface ResolvedModelWorkspaceClient {
79
+ client: WorkspaceClient;
80
+ auth: "obo" | "service-principal";
81
+ }
82
+
83
+ /** Resolve an OBO workspace client when present, else a service-principal client. */
84
+ function resolveModelWorkspaceContext(
85
+ requestContext?: RequestContext,
86
+ ): ResolvedModelWorkspaceClient {
87
+ const user = requestContext?.get(MASTRA_USER_KEY) as User | undefined;
88
+ const executionContext = user?.executionContext ?? appkit.tryGetExecutionContext();
89
+ if (executionContext?.client.config) {
90
+ return {
91
+ client: executionContext.client,
92
+ auth: "isUserContext" in executionContext ? "obo" : "service-principal",
93
+ };
94
+ }
95
+ return { client: createWorkspaceClient(), auth: "service-principal" };
96
+ }
97
+
98
+ /** Resolve the workspace client used for model discovery and inference. */
99
+ export function resolveModelWorkspaceClient(requestContext?: RequestContext): WorkspaceClient {
100
+ return resolveModelWorkspaceContext(requestContext).client;
101
+ }
102
+
76
103
  function selectionInput(
77
104
  config: MastraPluginConfig,
78
105
  requested: string | undefined,
@@ -125,24 +152,24 @@ export function resolveDefaultModelId(
125
152
  */
126
153
  export async function buildModel(
127
154
  config: MastraPluginConfig,
128
- requestContext: RequestContext,
155
+ requestContext?: RequestContext,
129
156
  overrides: BuildModelOverrides = {},
130
157
  ): Promise<MastraModelConfig> {
158
+ const context = requestContext ?? new RequestContext();
131
159
  // The chat path stamps the AppKit user on the request context via
132
160
  // `MastraServer`. The MCP transport routes don't thread that context
133
161
  // into tool execution, so fall back to the ambient execution context
134
162
  // (the active OBO scope, or the service principal) when it's absent.
135
- const user = requestContext.get(MASTRA_USER_KEY) as User | undefined;
136
- const executionContext = user?.executionContext ?? getExecutionContext();
137
- recordActiveTraceAuth("isUserContext" in executionContext ? "obo" : "service-principal");
138
- const clientConfig = executionContext.client.config;
163
+ const { client, auth } = resolveModelWorkspaceContext(context);
164
+ recordActiveTraceAuth(auth);
165
+ const clientConfig = client.config;
139
166
  const host = (await clientConfig.getHost()).toString();
140
167
  const headers = new Headers();
141
168
  await clientConfig.authenticate(headers);
142
169
  const logger = log.logger(config);
143
170
  const serving = resolveServingConfig(config);
144
171
  const override = serving.allowOverride
145
- ? (requestContext.get(MASTRA_MODEL_OVERRIDE_KEY) as string | undefined)
172
+ ? (context.get(MASTRA_MODEL_OVERRIDE_KEY) as string | undefined)
146
173
  : undefined;
147
174
 
148
175
  // The override / agent default / env value can be either a concrete
@@ -155,12 +182,12 @@ export async function buildModel(
155
182
  const requested = override ?? overrides.modelId ?? process.env.DATABRICKS_SERVING_ENDPOINT_NAME;
156
183
 
157
184
  const { modelId, source } = await selectModel(
158
- executionContext.client,
185
+ client,
159
186
  host,
160
187
  selectionInput(config, requested, overrides.modelClass, serving),
161
188
  );
162
189
  logger.debug("model selected", { modelId, source, requested });
163
- requestContext.set(MASTRA_RESOLVED_MODEL_KEY, modelId);
190
+ context.set(MASTRA_RESOLVED_MODEL_KEY, modelId);
164
191
  recordActiveTraceModel(modelId);
165
192
 
166
193
  return createDatabricksLanguageModel({
package/src/plugin.ts CHANGED
@@ -1126,7 +1126,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
1126
1126
  context: this.context,
1127
1127
  memoryBuilder,
1128
1128
  log: this.logger,
1129
- extraSkillMounts: provisioned.localSkillMounts,
1129
+ extraSkillMounts: [...(this.config.localSkillMounts ?? []), ...provisioned.localSkillMounts],
1130
1130
  });
1131
1131
 
1132
1132
  // `mastra.server.apiRoutes` is only honored by Mastra's standalone