@dbx-tools/appkit-mastra 0.9.129 → 0.9.132

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 (51) hide show
  1. package/README.md +182 -117
  2. package/index.ts +10 -8
  3. package/lib/index.d.ts +10 -8
  4. package/lib/index.js +8 -7
  5. package/lib/src/agents.d.ts +4 -0
  6. package/lib/src/agents.js +12 -3
  7. package/lib/src/config.d.ts +7 -2
  8. package/lib/src/config.js +6 -3
  9. package/lib/src/defaults.d.ts +9 -0
  10. package/lib/src/defaults.js +29 -1
  11. package/lib/src/genie-chat.d.ts +71 -0
  12. package/lib/src/genie-chat.js +272 -0
  13. package/lib/src/genie.d.ts +2 -0
  14. package/lib/src/genie.js +11 -8
  15. package/lib/src/memory.d.ts +5 -5
  16. package/lib/src/memory.js +10 -3
  17. package/lib/src/observability.d.ts +3 -0
  18. package/lib/src/observability.js +2 -2
  19. package/lib/src/plugin.d.ts +36 -7
  20. package/lib/src/plugin.js +220 -33
  21. package/lib/src/request-context.d.ts +2 -0
  22. package/lib/src/request-context.js +3 -0
  23. package/lib/src/server.d.ts +4 -0
  24. package/lib/src/server.js +40 -2
  25. package/lib/src/statement.d.ts +16 -1
  26. package/lib/src/statement.js +50 -18
  27. package/lib/src/telemetry.d.ts +22 -1
  28. package/lib/src/telemetry.js +174 -18
  29. package/lib/src/workspaces.d.ts +2 -2
  30. package/lib/src/workspaces.js +3 -2
  31. package/lib/tsconfig.tsbuildinfo +1 -1
  32. package/package.json +32 -25
  33. package/src/agents.ts +15 -1
  34. package/src/config.ts +10 -4
  35. package/src/defaults.ts +30 -0
  36. package/src/genie-chat.ts +341 -0
  37. package/src/genie.ts +11 -7
  38. package/src/memory.ts +9 -4
  39. package/src/observability.ts +6 -2
  40. package/src/plugin.ts +262 -31
  41. package/src/request-context.ts +2 -0
  42. package/src/server.ts +35 -0
  43. package/src/statement.ts +71 -19
  44. package/src/telemetry.ts +206 -16
  45. package/src/workspaces.ts +4 -3
  46. package/exports.ts +0 -7
  47. package/lib/exports.d.ts +0 -1
  48. package/lib/exports.js +0 -2
  49. package/lib/src/openapi-tool.d.ts +0 -29
  50. package/lib/src/openapi-tool.js +0 -175
  51. package/src/openapi-tool.ts +0 -245
package/README.md CHANGED
@@ -1,13 +1,10 @@
1
1
  # @dbx-tools/appkit-mastra
2
2
 
3
- AppKit plugin and server-side toolkit for hosting Mastra agents inside a
4
- Databricks App.
3
+ Host Mastra agents in a Databricks App with AppKit authentication, streaming
4
+ routes, Lakebase-backed memory, Genie tools, model selection, chart and table
5
+ embeds, MLflow feedback, and MCP exposure.
5
6
 
6
- The plugin mounts Mastra's streaming routes in an AppKit server and adds
7
- Databricks authentication, Lakebase-backed memory, Genie tools, model selection,
8
- chart and table embeds, MLflow feedback, and MCP exposure.
9
-
10
- ## Quick Start
7
+ ## Quick start
11
8
 
12
9
  Add an agent and run its command tools in the default Monty runtime:
13
10
 
@@ -25,7 +22,7 @@ await createApp({ plugins: [server(), mastra({ agents: { analyst } })] });
25
22
  Add Lakebase, Genie, Analytics, or other AppKit plugins when the agent needs
26
23
  durable threads or workspace tools.
27
24
 
28
- ## Choose Mastra Or AppKit Agents
25
+ ## Choose Mastra, AppKit Agents, or direct Genie
29
26
 
30
27
  Native AppKit Agents is the shorter path for AppKit-native agent definitions,
31
28
  streaming chat, threads, cancellation, and approvals. Choose this package when
@@ -37,13 +34,18 @@ the application already uses Mastra or needs Mastra-specific capabilities:
37
34
  ToolProvider plugins stay available without rewriting them.
38
35
  - Genie as an agent tool that emits typed progress events, result metadata, and
39
36
  delayed chart/data markers into the same assistant turn.
40
- - A paired React client in [`@dbx-tools/ui-mastra`](../../ui/mastra) with model
37
+ - A paired React client in [@dbx-tools/ui-mastra](../../ui/mastra) with model
41
38
  picking, thread sidebar, approvals, feedback, exports, and inline embeds.
42
39
  - Per-request model override and fuzzy endpoint resolution through
43
- [`@dbx-tools/model`](../model), instead of binding every agent to a fixed
40
+ [@dbx-tools/model](../model), instead of binding every agent to a fixed
44
41
  endpoint name.
45
42
 
46
- ## Full App Example
43
+ Use direct Genie chat when one Genie space owns the conversation and users don't
44
+ need a supervising agent. Choose Mastra when one turn must combine Genie with
45
+ other tools, memory, approvals, or workflows. Direct Genie keeps conversation
46
+ history in Genie and doesn't write Mastra memory.
47
+
48
+ ## Full app example
47
49
 
48
50
  ```ts
49
51
  import { analytics, createApp, lakebase, server } from "@databricks/appkit";
@@ -98,7 +100,7 @@ This example provides:
98
100
  - Lakebase registration automatically enables durable thread storage and vector
99
101
  memory unless you opt out.
100
102
 
101
- ## Agent Registration
103
+ ## Agent registration
102
104
 
103
105
  `mastra({ agents })` accepts a single definition, an array, or a record.
104
106
  Records are best when clients need stable agent ids:
@@ -135,7 +137,7 @@ Agents are also told to issue independent tool calls together in one turn and
135
137
  to keep dependent or conflicting calls sequential. Models that do not support
136
138
  parallel tool calls continue through the normal multi-step agent loop.
137
139
 
138
- ## Typed Application Request Context
140
+ ## Typed application request context
139
141
 
140
142
  Use Mastra's native `requestContextSchema` for UI selections that should shape a
141
143
  turn, such as a store, workflow, route, or selected entity:
@@ -174,12 +176,12 @@ so application context cannot change conversation ownership or credentials.
174
176
  `createAgent({ requireToolApproval })` forwards Mastra's native request-level
175
177
  approval gate. It may be an async Classifier-backed function that returns `true`
176
178
  for calls still needing human review. A tool's own `requireApproval` remains
177
- authoritative; configure that native function on the tool when policy should
179
+ authoritative. Configure that native function on the tool when policy should
178
180
  allow some calls. Regular agents do not include Agent Controller's durable
179
181
  allow/ask/deny permission store, so remembered decisions remain a caller-owned,
180
182
  server-side durable policy rather than browser state.
181
183
 
182
- ## AppKit Toolkits
184
+ ## AppKit toolkits
183
185
 
184
186
  The `tools(plugins)` callback receives a dynamic index of registered AppKit
185
187
  tool-provider plugins. Each entry exposes `.toolkit(opts)` with AppKit's public
@@ -208,11 +210,11 @@ const agent = agents.createAgent({
208
210
  });
209
211
  ```
210
212
 
211
- Tool calls dispatch back through the owning AppKit plugin, preserving OBO auth
212
- and AppKit telemetry behavior. Optional plugins should be guarded with `?.` when
213
- you spread their tools.
213
+ Tool calls dispatch back through the owning AppKit plugin, preserving
214
+ on-behalf-of-user (OBO) authentication and AppKit telemetry behavior. Optional
215
+ plugins should be guarded with `?.` when you spread their tools.
214
216
 
215
- ### Tools Flow In, Not Out
217
+ ### Tools flow in, not out
216
218
 
217
219
  The plugin is a tool _consumer_, not an AppKit `ToolProvider`: it deliberately
218
220
  implements neither `getAgentTools()` nor `executeAgentTool()`, so its built-in
@@ -237,7 +239,7 @@ unless `mcp: { tools: true }` names them explicitly. Approval-gated tools you
237
239
  register yourself are enforced separately: boot fails if one is registered
238
240
  without Mastra storage to persist the suspended run.
239
241
 
240
- ## Memory And Storage
242
+ ## Memory and storage
241
243
 
242
244
  The `memory` and `storage` config fields can be `false`, `true`, or a concrete
243
245
  Mastra Postgres/PgVector config.
@@ -252,16 +254,23 @@ mastra({
252
254
 
253
255
  With `lakebase()` registered, both default to enabled:
254
256
 
255
- - storage uses a per-agent schema for durable threads and messages;
256
- - memory uses a shared vector index for semantic recall;
257
- - the existing service-principal pool is captured from `lakebase()` during
257
+ - Storage uses a per-agent schema for durable threads and messages.
258
+ - Memory uses a shared vector index for semantic recall.
259
+ - The existing service-principal pool is captured from `lakebase()` during
258
260
  startup, so request-scoped OBO credentials never reach storage work and no
259
261
  additional PostgreSQL pool is created.
260
262
 
261
263
  Without `lakebase()`, agents are stateless unless you provide explicit storage
262
264
  and memory configs.
263
265
 
264
- ## Workspace Capabilities
266
+ ### Add external durable memory tools
267
+
268
+ Register `@dbx-tools/appkit-memory` as a sibling plugin and request
269
+ `plugins.memory?.toolkit()` from the agents that need its `remember` and
270
+ `recall_memory` tools. The memory plugin owns Databricks and Graphiti selection.
271
+ Mastra continues to own only its configured PostgresStore and PgVector.
272
+
273
+ ## Workspace capabilities
265
274
 
266
275
  Every `agents.createAgent()` gets a default Mastra `Workspace` from
267
276
  `workspaces.databricksWorkspace()`. A workspace can provide file access, skill
@@ -270,6 +279,13 @@ discovery, a command sandbox, or any combination. The default mounts
270
279
  configured Assistant skill paths, and provides Monty for isolated Python
271
280
  command execution.
272
281
 
282
+ Use AppKit's Files plugin when application routes and UI components need
283
+ governed upload, download, or volume access. Use a Mastra workspace when the
284
+ agent itself needs files, skills, or command execution during a turn. A
285
+ `FileSystem` from [@dbx-tools/databricks](../databricks) or
286
+ [@dbx-tools/fs](../fs) can be mounted into that workspace with
287
+ `filesystems(fs)`.
288
+
273
289
  Pass paths directly when an agent needs a different filesystem scope:
274
290
 
275
291
  ```ts
@@ -311,7 +327,7 @@ const workspace = workspaces.databricksWorkspace({
311
327
  Paths are file-only unless `skills` lists relative Mastra skill paths within
312
328
  that included path. At workspace level, `skills` uses Mastra's native path list
313
329
  or resolver. An empty list retains configured mounts without exposing skills.
314
- `writable` controls whether the filesystem attempts mutations; Databricks
330
+ `writable` controls whether the filesystem attempts mutations. Databricks
315
331
  permissions still decide whether an operation succeeds. `mount` can expose the
316
332
  path at a different Mastra path when required.
317
333
 
@@ -361,17 +377,17 @@ export const workspace = new Workspace({
361
377
  });
362
378
  ```
363
379
 
364
- Mastra discovers Databricks Workspace skills only from explicit `skills` paths,
365
- including the paths declared under the default Assistant paths. Those
366
- potentially slow remote directory listings use the skill-search processor. Set
367
- `workspaceSkills: false` to omit that processor, or pass `{ topK, minScore,
368
- ttlMs }` to tune it. Process-memory `localSkillMounts`, AI Tools, and other
369
- startup-provisioned remote skills are passed as native agent-level skills, so
370
- Mastra exposes its standard `skill`, `skill_search`, and `skill_read` tools
371
- without scanning their virtual workspace mounts. Set the workspace's `skills`
372
- to an empty list when the workspace should expose no Databricks skills.
380
+ Mastra discovers skills from explicit `skills` paths, including the paths
381
+ declared under the default Assistant paths and read-only `localSkillMounts`.
382
+ Those paths use the skill-search processor. Set `workspaceSkills: false` to
383
+ omit that processor, or pass `{ topK, minScore, ttlMs }` to tune it. Local
384
+ mounts are also passed as native agent-level skills, so the standard `skill`,
385
+ `skill_search`, and `skill_read` tools remain available. Startup-provisioned
386
+ remote skills use their native tools without duplicating their virtual mounts
387
+ in workspace search. Set the workspace's `skills` to an empty list when the
388
+ workspace should expose no skills.
373
389
 
374
- ### Cache Workspace Metadata
390
+ ### Cache workspace metadata
375
391
 
376
392
  Register `filesCache()` to reuse Databricks directory metadata across page
377
393
  refreshes and later turns:
@@ -398,7 +414,7 @@ const workspace = workspaces.databricksWorkspace({
398
414
  });
399
415
  ```
400
416
 
401
- ### Configure File Approvals
417
+ ### Configure file approvals
402
418
 
403
419
  Workspace tools are enabled and run without approval by default. This applies to
404
420
  file mutations and command execution with either Monty or a supplied sandbox
@@ -427,7 +443,7 @@ are separate, so gate or disable
427
443
  `WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND` when commands must not bypass file
428
444
  policies. Cached metadata never grants Databricks access.
429
445
 
430
- ## Workspace Sandbox
446
+ ## Workspace sandbox
431
447
 
432
448
  Auto-created workspaces use Monty by default. Supply any native Mastra
433
449
  `WorkspaceSandbox` or request-scoped resolver to use a remote transport:
@@ -441,13 +457,13 @@ mastra({
441
457
  });
442
458
  ```
443
459
 
444
- For Databricks Sandbox over SSH, use `sshWorkspaceSandbox(runtime)` from
445
- `@dbx-tools/appkit-sandbox/workspace`. Share that runtime with the
446
- Databricks Sandbox AppKit plugin so agent commands, terminal and health routes
447
- use the same transport and machine assignments. That package owns Sandbox
448
- lifecycle, SSH keys, authentication fallback, and route forwarding. Its Mastra
449
- adapter forwards command output to `onStdout` and `onStderr` while the command
450
- runs, then returns Mastra's completed `CommandResult`.
460
+ For a Databricks Lakebox, use `lakeboxWorkspaceSandbox(runtime)` from
461
+ `@dbx-tools/appkit-lakebox/workspace`. Share that runtime with the Lakebox
462
+ AppKit plugin so agent commands, terminals, desktops, and service routes use the
463
+ same Lakebox and per-user account. That package owns Lakebox lifecycle, SSH
464
+ keys, user accounts, and route forwarding. Its Mastra adapter forwards command
465
+ output to `onStdout` and `onStderr` while the command runs, then returns
466
+ Mastra's completed `CommandResult`.
451
467
 
452
468
  The default local Monty Python runtime accepts Python source or `python3 -c` and
453
469
  has no host filesystem, network, environment variables, shell, or third-party
@@ -479,7 +495,7 @@ const localAgent = agents.createAgent({
479
495
  An agent-level workspace overrides the plugin-level sandbox setting. Returning
480
496
  `undefined` from a workspace resolver disables the workspace for that agent.
481
497
 
482
- ### Batch Tools With Code Mode
498
+ ### Batch tools with Code Mode
483
499
 
484
500
  Mastra Code Mode is enabled by default when an agent has executable tools. It
485
501
  adds an `execute_typescript` tool so the model can batch independent calls,
@@ -494,14 +510,14 @@ filesystem, network, process, timer, or module access beyond the explicitly
494
510
  supplied tools. QuickJS supports concurrent external calls, so generated code
495
511
  can use `Promise.all` for independent operations.
496
512
 
497
- The automatic Code Mode remains available when the workspace uses Databricks
498
- Sandbox because QuickJS or isolated-vm executes the orchestration program
513
+ The automatic Code Mode remains available when the workspace uses a Databricks
514
+ Lakebox because QuickJS or isolated-vm executes the orchestration program
499
515
  independently of the workspace command sandbox. SSH is used only if the program
500
- calls an exposed SSH-backed tool.
516
+ calls an exposed Lakebox-backed tool.
501
517
 
502
518
  Callers may also use native Mastra `createCodeMode` directly when they want
503
519
  multiple explicitly scoped orchestration tools, or when the TypeScript program
504
- itself must execute in a supplied Sandbox:
520
+ itself must run in a supplied Sandbox:
505
521
 
506
522
  ```ts
507
523
  const sales = createCodeMode({
@@ -524,11 +540,11 @@ const agent = new Agent({
524
540
  });
525
541
  ```
526
542
 
527
- This is native Mastra `createCodeMode`; the plugin does not wrap or re-export it.
543
+ This is native Mastra `createCodeMode`. The plugin does not wrap or re-export it.
528
544
  Set plugin `codeMode: false` to disable the automatic Code Mode, or pass
529
545
  `{ id, timeout }` to tune its generated tool.
530
546
 
531
- ## Remote Skills
547
+ ## Remote skills
532
548
 
533
549
  Use `remoteSkills` to install a curated skill set when the files are not already
534
550
  in the Databricks workspace. Sources can be a GitHub `owner/repo`, a git URL, a
@@ -608,13 +624,10 @@ mastra({
608
624
  });
609
625
  ```
610
626
 
611
- **No CLI required.** `databricks aitools install` resolves its skills from the
612
- PUBLIC `databricks/databricks-agent-skills` repo, so this reads the same repo
613
- directly: it fetches the repo's generated `manifest.json` (which names each
614
- skill's files and whether it lives under `skills/` or `experimental/`) and
615
- downloads them. That matters because a deployed Databricks App container has no
616
- `databricks` CLI - the old CLI shell-out simply never produced skills there.
617
- No Databricks auth is involved either, since the repo is public.
627
+ The source reads the public
628
+ [databricks/databricks-agent-skills](https://github.com/databricks/databricks-agent-skills)
629
+ repository's generated `manifest.json` and downloads the selected skill files.
630
+ It doesn't require the Databricks CLI or Databricks authentication.
618
631
 
619
632
  Per-source options for `"aitools"`:
620
633
 
@@ -629,18 +642,18 @@ destination. These trees are supplied to every agent as standard agent-level
629
642
  skills rather than workspace-search roots. Local filesystem mounts remain
630
643
  available below `/.skills` when a Databricks destination is unavailable.
631
644
 
632
- ## Genie Tools
645
+ ## Genie tools
633
646
 
634
647
  `genie.buildGenieTools()` and `plugins.genie.toolkit()` expose tools for:
635
648
 
636
- - asking a configured Genie space;
637
- - reading space descriptions and serialized space metadata;
638
- - fetching statement rows by `statement_id`;
639
- - preparing charts from Genie result sets.
649
+ - Asking a configured Genie space.
650
+ - Reading space descriptions and serialized space metadata.
651
+ - Fetching statement rows by `statement_id`.
652
+ - Preparing charts from Genie result sets.
640
653
 
641
654
  The central agent drives those tools directly. Genie events stream through the
642
655
  Mastra writer using the shared contract from
643
- [`@dbx-tools/shared-mastra`](../../shared/mastra), so clients can show thinking,
656
+ [@dbx-tools/shared-mastra](../../shared/mastra), so clients can show thinking,
644
657
  SQL, row counts, summaries, chart markers, and data markers as the turn runs.
645
658
  Independent `ask_genie` calls can run in parallel. One invocation owns the
646
659
  thread's reusable Genie conversation while overlapping invocations use isolated
@@ -652,11 +665,10 @@ SQL function calls, query output, and the synthesized answer into the existing
652
665
  writer events and terminal `GenieMessage`. Set `genieAgentMode: false` on
653
666
  `mastra(...)` to force the Conversation API polling flow. A pre-stream
654
667
  `FEATURE_DISABLED` or preview-toggle error falls back to polling automatically.
655
- Agent Mode carries query results inline as Markdown; use polling when a workflow
656
- specifically requires `statement_id`-backed chart or data embeds. For
657
- Agent Mode charts, pass the inline Markdown or structured metadata rows to the
658
- auto-wired `render_data` tool; never pass response, conversation, or function
659
- call ids to `prepare_chart`.
668
+ Agent Mode carries query results inline as Markdown and projects the
669
+ `statement_id` from each query output onto its query attachment when Databricks
670
+ supplies one. Use that id with `get_statement`, `prepare_chart`, or a data
671
+ marker. Use `render_data` only when rows are available without a statement id.
660
672
 
661
673
  ```ts
662
674
  const agent = agents.createAgent({
@@ -667,7 +679,56 @@ const agent = agents.createAgent({
667
679
  });
668
680
  ```
669
681
 
670
- ## Charts And Data Embeds
682
+ ### Direct Genie chat
683
+
684
+ The plugin also exposes a Genie-only transport for the paired Mastra UI. It
685
+ keeps the standard AI SDK `UIMessage` stream and the same tool, thought, table,
686
+ and thread presentation without running a Mastra agent:
687
+
688
+ ```tsx
689
+ import { MastraChat } from "@dbx-tools/ui-mastra/react";
690
+
691
+ <MastraChat genieSpace="sales" />;
692
+ ```
693
+
694
+ The alias must exist in `genieSpaces`. Genie owns the state in this mode:
695
+ conversations are thread IDs and Genie messages are projected into the
696
+ transcript. The plugin does not write Mastra Memory or create a supervisor
697
+ agent.
698
+
699
+ Direct Genie chat always uses AppKit's OBO user context, matching the native
700
+ AppKit Genie plugin. Service-principal conversations cannot safely back a
701
+ multi-user thread list because every viewer would share the same Databricks
702
+ conversation owner. Users therefore need workspace access to the configured
703
+ space even when agent-backed calls use `genieIdentity: "service-principal"` or
704
+ `"auto"`.
705
+
706
+ Direct turns require the
707
+ [Genie Agent API](https://docs.databricks.com/aws/en/genie-agents/api). They
708
+ never fall back to the classic start/create/get-message polling flow, and
709
+ history comes only from the Agent API conversation-items endpoint. The GA
710
+ space conversation-list endpoint is used only to discover conversations marked
711
+ `GENIE_CONVERSATION_TYPE_AGENT`. The GA delete endpoints provide the management
712
+ operations that the Agent API does not expose.
713
+
714
+ Agent Mode receives Genie's visualization tool. When Genie emits a
715
+ visualization attachment, the answer contains a
716
+ `[visualization:<statement_id>]` marker and the client renders the result with
717
+ AppKit UI's native Genie Chart/Table component. This path does not use a
718
+ supervisor or Model Serving chart planner. Queries Genie does not mark for
719
+ visualization remain sortable data tables.
720
+
721
+ Operational limits:
722
+
723
+ - The thread list contains the newest 100 Agent Mode conversations.
724
+ - Conversation history is Genie-owned and loaded as one UI history page.
725
+ - Genie conversations cannot be renamed.
726
+ - File attachments, MLflow feedback, approval continuations, background runs,
727
+ and stream reconnection are unavailable.
728
+ - Aborting the browser stream cancels that request instead of leaving a durable
729
+ Mastra run to reconnect.
730
+
731
+ ## Charts and data embeds
671
732
 
672
733
  `chart.prepareChart()` mints a chart id immediately, caches an in-progress
673
734
  record, resolves the data in the background, and stores a terminal chart or
@@ -702,14 +763,11 @@ const resolved = await chart.fetchChart(chartId, { userKey });
702
763
  Agents can return `[chart:<id>]` and `[data:<statement_id>]` markers in prose.
703
764
  The embed route resolves them later, which avoids forcing the language model to
704
765
  inline large tables or wait for chart planning before continuing its answer.
705
- Genie supplies those statement ids through the Conversation API polling
706
- transport; Agent Mode returns inline Markdown and structured table metadata
707
- instead. The
708
- `GENIE_INSTRUCTIONS` prompt directs Agent Mode turns to call `render_data` with
709
- those inline rows, while polling turns call `prepare_chart` only with a real
710
- statement id.
766
+ Agent Mode and polling query attachments carry statement ids when Databricks
767
+ returns them. Direct Genie chat also uses
768
+ `[visualization:<statement_id>]` for AppKit UI's native Genie visualization.
711
769
 
712
- ### Chart Types And Hand-Written Charts
770
+ ### Chart types and hand-written charts
713
771
 
714
772
  The planner does not emit a raw Echarts option. It fills a small plan (chart
715
773
  type, categories, series) that `planToEchartsOption` expands, so tooltip,
@@ -744,10 +802,10 @@ Prefer a listed type whenever one fits. `custom` trades the shared defaults for
744
802
  reach, so it is the answer for an unsupported chart shape, not a way to restyle
745
803
  a supported one.
746
804
 
747
- ### Brand The Charts
805
+ ### Brand the charts
748
806
 
749
807
  Pass a `brand` to the plugin to theme every generated chart with your brand's
750
- palette and font; omit it for the default Echarts look.
808
+ palette and font. Omit it for the default Echarts look.
751
809
 
752
810
  ```ts
753
811
  import { brandUtils } from "@dbx-tools/shared-core";
@@ -768,24 +826,24 @@ read later in a browser whose light/dark theme the server cannot know, so the
768
826
  brand's single (light) foreground would produce near-black labels on a dark chat
769
827
  surface. The renderer resolves tick labels, axis names, grid lines, and the
770
828
  tooltip from AppKit's live CSS tokens instead - see
771
- [`@dbx-tools/ui-mastra`](../../ui/mastra)'s chart theming. Brand identity is the
772
- same in either mode; chrome is not.
829
+ [@dbx-tools/ui-mastra](../../ui/mastra)'s chart theming. Brand identity is the
830
+ same in either mode. Chrome is not.
773
831
 
774
- ## Model Selection
832
+ ## Model selection
775
833
 
776
834
  `model.buildModel()` adapts the generic resolver from
777
- [`@dbx-tools/model`](../model) to Mastra, then constructs a request-scoped
835
+ [@dbx-tools/model](../model) to Mastra, then constructs a request-scoped
778
836
  Vercel AI SDK ProviderV4 model through
779
- [`@dbx-tools/model-protocol`](../model-protocol). It resolves the model per
837
+ [@dbx-tools/model-protocol](../model-protocol). It resolves the model per
780
838
  request, so OBO identity and request-specific overrides stay isolated.
781
839
 
782
840
  Model priority is:
783
841
 
784
- 1. request override (`X-Mastra-Model`, `?model=`, body `model` / `modelId`);
785
- 2. per-agent `model`;
786
- 3. plugin `defaultModel`;
787
- 4. `DATABRICKS_SERVING_ENDPOINT_NAME`;
788
- 5. highest-ranked currently available GPT from the live workspace catalogue,
842
+ 1. Request override (`X-Mastra-Model`, `?model=`, body `model` / `modelId`).
843
+ 1. Per-agent `model`.
844
+ 1. Plugin `defaultModel`.
845
+ 1. `DATABRICKS_SERVING_ENDPOINT_NAME`.
846
+ 1. Highest-ranked available GPT from the live workspace catalogue,
789
847
  then the highest-ranked live chat model when no GPT is deployed.
790
848
 
791
849
  The unconfigured default is live-only and fails clearly when the workspace has
@@ -807,7 +865,7 @@ building custom routes that should behave like the plugin's `/models` and stream
807
865
  routes.
808
866
 
809
867
  The Chat provider uses a provider-local fetch from
810
- `@dbx-tools/model-protocol`; Mastra does not patch `globalThis.fetch`. The
868
+ `@dbx-tools/model-protocol`. Mastra does not patch `globalThis.fetch`. The
811
869
  shared fetch repairs provider-specific wire requirements for both
812
870
  `fetch(url, { body })` and `fetch(new Request(...))`. In particular,
813
871
  Databricks-hosted GPT 5.6 Chat Completions with function tools receives
@@ -831,14 +889,14 @@ without waiting on the `/models` catalogue (so it never flashes a raw id). A
831
889
  `:agentId` that is not registered returns `404` with the registered ids, the
832
890
  same as the history and threads routes.
833
891
 
834
- ## Threads, History, And Suggestions
892
+ ## Threads, history, and suggestions
835
893
 
836
894
  When storage is enabled, the plugin provides route helpers and in-process
837
895
  functions for conversation management:
838
896
 
839
- - `history.loadHistory()` and `history.clearHistory()` read or clear one thread;
897
+ - `history.loadHistory()` and `history.clearHistory()` read or clear one thread.
840
898
  - `threads.listThreads()`, `threads.renameThread()`, and
841
- `threads.deleteThread()` operate on the caller's scoped conversations;
899
+ `threads.deleteThread()` operate on the caller's scoped conversations.
842
900
  - `genie.collectSpaceSuggestions()` reads starter questions from the configured
843
901
  Genie space.
844
902
 
@@ -846,7 +904,7 @@ The plugin resolves the active thread from `x-mastra-thread-id`, `?threadId=`,
846
904
  or a per-session fallback cookie. That keeps streaming, history, and clear
847
905
  operations aligned around the same conversation id.
848
906
 
849
- ## Evaluate In Process
907
+ ## Evaluate in process
850
908
 
851
909
  `eval.createMastraEvalDriver()` adapts a Mastra agent's native `generate()`
852
910
  result to AppKit 0.81's `EvalDriver` contract without reducing a chat stream:
@@ -918,7 +976,7 @@ On Apps UC traces it reads the experiment's
918
976
  `mlflow.experiment.databricksTraceDestinationPath` tag (or the spans-table tag)
919
977
  so the assessment URI matches the row the experiment UI shows. The response
920
978
  header name and request/response schemas live in
921
- [`@dbx-tools/shared-mastra`](../../shared/mastra).
979
+ [@dbx-tools/shared-mastra](../../shared/mastra).
922
980
 
923
981
  Outside a Databricks App, an experiment id automatically enables direct MLflow
924
982
  tracing. The plugin initializes the MLflow Node SDK, injects
@@ -982,7 +1040,7 @@ the global provider AppKit already owns and writes to a different store.
982
1040
 
983
1041
  Success in the boot log looks like:
984
1042
 
985
- ```
1043
+ ```text
986
1044
  [observability] Mastra observability wired through OTel bridge {
987
1045
  otelBase: 'http://localhost:4314', feedback: true, observability: 'mlflow'
988
1046
  }
@@ -990,10 +1048,10 @@ Success in the boot log looks like:
990
1048
 
991
1049
  Verify with SQL against the UC `*_trace_unified` view (the REST
992
1050
  `traces/search` API only covers the experiment store, not UC-backed traces).
993
- Schema names with hyphens need backticks; `attributes` is a `VARIANT`, so use
1051
+ Schema names with hyphens need backticks. `attributes` is a `VARIANT`, so use
994
1052
  `attributes:['key']::string` rather than `map_keys()`.
995
1053
 
996
- ## MCP Exposure
1054
+ ## MCP exposure
997
1055
 
998
1056
  `mcp.buildMcpServer()` exposes registered agents as MCP tools by default. The
999
1057
  AppKit plugin publishes clean aliases under its base path:
@@ -1012,7 +1070,7 @@ mastra({
1012
1070
  Use `mcp: false` to disable MCP. Turn on `tools: true` only for ambient tools
1013
1071
  that are safe outside an in-process chat turn.
1014
1072
 
1015
- ## Driving A Turn From Outside The Routes
1073
+ ## Drive a turn outside the routes
1016
1074
 
1017
1075
  Another plugin (or a scheduled job) can run an agent turn directly, but a raw
1018
1076
  `agent.generate(prompt)` loses everything the HTTP middleware stamps - most
@@ -1035,11 +1093,11 @@ const result = await mastra.getDefault().generate(prompt, { requestContext });
1035
1093
  The AppKit user, the memory thread / resource pair, and a request id (so the
1036
1094
  turn's spans join up in traces) are stamped exactly as the request middleware
1037
1095
  stamps them. Call it inside an `asUser(req)` scope to inherit the caller's OBO
1038
- identity; outside one it resolves to the service principal.
1039
- [`@dbx-tools/teams`](../teams) uses this so a Teams card turn has the same tool
1096
+ identity. Outside one it resolves to the service principal.
1097
+ [@dbx-tools/teams](../teams) uses this so a Teams card turn has the same tool
1040
1098
  reach - and therefore the same answer - as a chat turn.
1041
1099
 
1042
- ## API Gate
1100
+ ## API gate
1043
1101
 
1044
1102
  The stock `@mastra/express` app has broad management routes. The plugin's
1045
1103
  default `apiAccess: "scoped"` allows only the chat, read-only metadata,
@@ -1052,7 +1110,7 @@ logic that need the same allowlist.
1052
1110
  ## Routes
1053
1111
 
1054
1112
  Mounted under the plugin base path, which is `/api/mastra` unless you override
1055
- `name`. Product-specific routes use AppKit's `route()` helper; chat and memory
1113
+ `name`. Product-specific routes use AppKit's `route()` helper. Chat and memory
1056
1114
  use Mastra's native route surfaces behind the same scoped request-context gate.
1057
1115
 
1058
1116
  | Method | Path | Purpose |
@@ -1062,17 +1120,21 @@ use Mastra's native route surfaces behind the same scoped request-context gate.
1062
1120
  | `GET` | `/suggestions[/:agentId]` | Starter questions from the configured Genie spaces. Degrades to `[]`. |
1063
1121
  | `GET` | `/embed/chart/:id` | Long-polls a `[chart:<id>]` marker's cached spec. `?timeoutMs=` up to 5 minutes. |
1064
1122
  | `GET` | `/embed/data/:id` | Rows behind a `[data:<statement_id>]` marker. `?limit=` clamped server-side. |
1123
+ | `GET` | `/embed/visualization/:id` | OBO-only statement payload for a `[visualization:<statement_id>]` AppKit UI embed. |
1065
1124
  | `POST` | `/chat/:agentId` | Official Mastra AI SDK UI stream, including native `resumeData` continuations. |
1125
+ | `POST` | `/genie/:alias/chat` | Direct Genie turn projected onto the AI SDK UI stream. |
1126
+ | `GET` / `DELETE` | `/genie/:alias/threads[...]` | OBO-only Genie conversation list, history, and deletion. |
1127
+ | `GET` | `/genie/:alias/suggestions` | Starter questions for one direct Genie space. |
1066
1128
  | `GET` / `PATCH` / `DELETE` | `/memory/threads[...]` | Native Mastra resource-scoped conversation history and thread management. |
1067
1129
  | `POST` | `/memory/messages/delete` | Native message deletion used before regenerating a response. |
1068
1130
  | `GET` | `/agents/:agentId/suspended-runs` | Native persisted approval discovery after a reload or restart. |
1069
1131
  | `POST` | `/route/feedback` | Log a thumbs / comment assessment to the turn's MLflow trace. `404` when feedback is off. |
1070
- | `GET` | `/route/mlflow-experiment` | Return the experiment URL only when the active viewer has effective `CAN_MANAGE`; otherwise `{ "url": null }`. |
1132
+ | `GET` | `/route/mlflow-experiment` | Return the experiment URL only when the active viewer has effective `CAN_MANAGE`. Otherwise, return `{ "url": null }`. |
1071
1133
  | `POST` / `GET` | `/mcp`, `/sse`, `/messages` | MCP transports, when `mcp` is enabled. |
1072
1134
 
1073
1135
  The UI consumes `/chat/:agentId` with the AI SDK's `DefaultChatTransport`.
1074
1136
 
1075
- ## Environment Variables
1137
+ ## Environment variables
1076
1138
 
1077
1139
  Every value can also be set through plugin config, which wins. These are the
1078
1140
  fallbacks, so a deployment that already follows AppKit's Databricks env naming
@@ -1080,7 +1142,7 @@ needs no extra wiring.
1080
1142
 
1081
1143
  | Variable | Effect |
1082
1144
  | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
1083
- | `DATABRICKS_SERVING_ENDPOINT_NAME` | Optional model override used when neither the agent nor `defaultModel` names one; omit for live highest-rank selection. |
1145
+ | `DATABRICKS_SERVING_ENDPOINT_NAME` | Optional model override used when neither the agent nor `defaultModel` names one. Omit for live highest-rank selection. |
1084
1146
  | `DATABRICKS_GENIE_SPACE_ID` | Genie space registered under the `default` alias. |
1085
1147
  | `MASTRA_GENIE_IDENTITY` | `user` (default, OBO), `service-principal`, or `auto` for the agents' Databricks calls. |
1086
1148
  | `OTEL_EXPORTER_OTLP_ENDPOINT`, `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | Presence of either turns Mastra tracing on when `observability` is unset. On Apps, the telemetry sidecar injects these. |
@@ -1088,7 +1150,7 @@ needs no extra wiring.
1088
1150
  | `MLFLOW_EXPERIMENT_ID`, `MLFLOW_EXPERIMENT_NAME` | With an OTLP endpoint, turns MLflow feedback on when `feedback` is unset. Assessments read the experiment's UC trace destination tag. |
1089
1151
  | `MLFLOW_UC_TRACE_PREFIX` | Optional override for the UC table prefix. Omit to use the experiment tag. |
1090
1152
 
1091
- ## Configuration Reference
1153
+ ## Configuration reference
1092
1154
 
1093
1155
  The main plugin options are:
1094
1156
 
@@ -1099,13 +1161,13 @@ The main plugin options are:
1099
1161
  - `storage` and `memory` accept `true`, `false`, or concrete Mastra Postgres /
1100
1162
  PgVector options. `true` resolves from `lakebase()` when present.
1101
1163
  - `sandbox` defaults to Monty for auto-created workspaces. `false` disables
1102
- command execution; `true` or `"monty"` selects Monty; a native Mastra
1164
+ command execution. `true` or `"monty"` selects Monty. A native Mastra
1103
1165
  sandbox or resolver supplies another transport.
1104
1166
  - `codeMode` exposes all executable tools available to the current request,
1105
1167
  including enabled native workspace tools, through native Mastra Code Mode. It
1106
1168
  defaults on when such tools exist, selecting isolated-vm once at startup and
1107
1169
  falling back to QuickJS only when unavailable. Both transports support
1108
- concurrent external calls without SSH; an SSH connection is needed only when
1170
+ concurrent external calls without SSH. An SSH connection is needed only when
1109
1171
  an exposed SSH-backed tool is called. Pass `false` to disable it.
1110
1172
  - `workspaceSkills` enables Mastra's native on-demand skill search by default.
1111
1173
  Pass `false` to disable it or an object with `topK`, `minScore`, and `ttlMs`
@@ -1141,12 +1203,13 @@ The main plugin options are:
1141
1203
  membership. `"auto"` uses OBO when the request includes it and otherwise uses
1142
1204
  the service principal. Memory threads, cache namespaces, and trace metadata
1143
1205
  remain user-scoped in all three modes. The environment fallback is
1144
- `MASTRA_GENIE_IDENTITY`.
1206
+ `MASTRA_GENIE_IDENTITY`. Direct Genie chat routes always require OBO and do
1207
+ not use this fallback.
1145
1208
  - `apiAccess` chooses the route allowlist. Keep the default scoped mode for
1146
1209
  deployed apps.
1147
1210
 
1148
1211
  Clients that call these routes can import the browser-safe schemas from
1149
- [`@dbx-tools/shared-mastra`](../../shared/mastra).
1212
+ [@dbx-tools/shared-mastra](../../shared/mastra).
1150
1213
 
1151
1214
  ## Modules
1152
1215
 
@@ -1161,6 +1224,8 @@ Clients that call these routes can import the browser-safe schemas from
1161
1224
  reasoning, Claude's replayed thinking blocks, Gemini/Claude content-parts
1162
1225
  responses) from failing a turn.
1163
1226
  - `genie` - Genie prompt, space normalization, Genie toolkits, and suggestions.
1227
+ - `genieChat` - direct Genie AI SDK stream, conversation history projection,
1228
+ and OBO-only thread operations.
1164
1229
  - `chart` / `statement` / `writer` - chart cache, statement row fetches, and
1165
1230
  safe writer events.
1166
1231
  - `validation` - request-body validation for the plugin's custom routes.
@@ -1173,14 +1238,14 @@ Clients that call these routes can import the browser-safe schemas from
1173
1238
  - `montySandbox` - Python-only Pydantic Monty fallback using Node subprocess
1174
1239
  workers.
1175
1240
  - `workspaces` / `filesystems` - native Mastra workspace configuration from
1176
- Databricks paths, opt-in user-scoped temp paths, and caller-supplied mounts;
1241
+ Databricks paths, opt-in user-scoped temp paths, and caller-supplied mounts.
1177
1242
  `filesystems(fs)` wraps any `@dbx-tools/shared-fs` `FileSystem` (including
1178
1243
  `@dbx-tools/databricks` / `@dbx-tools/fs`) as a Mastra mount.
1179
1244
  - `remote-skills` - startup provisioning of remote `SKILL.md` sources. The
1180
1245
  `"aitools"` constant reads Databricks' public skill repo through a daily
1181
1246
  `@dbx-tools/cache` snapshot and serves one shared in-memory
1182
1247
  `/.databricks/skills` tree. Other sources go through the optional `skills` CLI
1183
- or a direct fetch. Every source keeps a process-memory standard-skill copy;
1248
+ or a direct fetch. Every source keeps a process-memory standard-skill copy.
1184
1249
  Databricks persistence and read-only local mounts are storage options, not
1185
1250
  runtime search roots. `refreshTtlMs` overrides the source default.
1186
1251
  - `mcp` - MCP server construction.
@@ -1190,7 +1255,7 @@ Clients that call these routes can import the browser-safe schemas from
1190
1255
  and stale chart-id input cleanup.
1191
1256
 
1192
1257
  Browser-facing wire types are in
1193
- [`@dbx-tools/shared-mastra`](../../shared/mastra). Genie event contracts are in
1194
- [`@dbx-tools/shared-genie`](../../shared/genie). Model request/result contracts
1195
- are in [`@dbx-tools/shared-model`](../../shared/model). The matching React chat
1196
- surface is [`@dbx-tools/ui-mastra`](../../ui/mastra).
1258
+ [@dbx-tools/shared-mastra](../../shared/mastra). Genie event contracts are in
1259
+ [@dbx-tools/shared-genie](../../shared/genie). Model request/result contracts
1260
+ are in [@dbx-tools/shared-model](../../shared/model). The matching React chat
1261
+ surface is [@dbx-tools/ui-mastra](../../ui/mastra).