@dbx-tools/appkit-mastra 0.1.13 → 0.1.19
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/README.md +109 -102
- package/dist/src/agents.d.ts +2 -2
- package/dist/src/agents.js +65 -14
- package/dist/src/chart.d.ts +39 -105
- package/dist/src/chart.js +177 -194
- package/dist/src/config.d.ts +104 -0
- package/dist/src/config.js +43 -0
- package/dist/src/genie.d.ts +169 -107
- package/dist/src/genie.js +983 -577
- package/dist/src/history.d.ts +31 -3
- package/dist/src/history.js +137 -31
- package/dist/src/memory.d.ts +4 -4
- package/dist/src/memory.js +2 -2
- package/dist/src/model.js +2 -2
- package/dist/src/observability.d.ts +56 -25
- package/dist/src/observability.js +70 -56
- package/dist/src/plugin.js +25 -15
- package/dist/src/processors/strip-stale-charts.js +1 -1
- package/dist/src/server.d.ts +12 -0
- package/dist/src/server.js +38 -2
- package/dist/src/serving.js +1 -1
- package/dist/src/tools/email.js +1 -1
- package/dist/src/writer.d.ts +23 -0
- package/dist/src/writer.js +37 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +21 -18
- package/src/agents.ts +72 -17
- package/src/chart.ts +205 -251
- package/src/config.ts +120 -0
- package/src/genie.ts +1183 -658
- package/src/history.ts +147 -33
- package/src/memory.ts +5 -5
- package/src/model.ts +3 -3
- package/src/observability.ts +94 -70
- package/src/plugin.ts +25 -15
- package/src/processors/strip-stale-charts.ts +1 -1
- package/src/server.ts +49 -2
- package/src/serving.ts +1 -1
- package/src/tools/email.ts +1 -1
- package/src/writer.ts +44 -0
package/dist/src/genie.d.ts
CHANGED
|
@@ -1,131 +1,193 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Genie agent for Mastra.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* parameter.
|
|
4
|
+
* Each configured Genie space exposes a single Mastra tool to the
|
|
5
|
+
* calling agent (`genie` for the `"default"` alias, `genie_<alias>`
|
|
6
|
+
* otherwise). When invoked, the tool runs end-to-end:
|
|
8
7
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* 1. Pulls the per-request {@link WorkspaceClient} off
|
|
9
|
+
* `ctx.requestContext` (stamped by `MastraServer`) and emits a
|
|
10
|
+
* `started` writer event so the host UI can show progress
|
|
11
|
+
* immediately, before any LLM round-trip.
|
|
12
|
+
* 2. Spins up a per-call inner Mastra `Agent` with three tools:
|
|
13
|
+
* - `ask_genie`: drives one `genieEventChat` turn, fetches
|
|
14
|
+
* the matching statement's rows when the turn ran SQL,
|
|
15
|
+
* and forwards every wire event (status, thinking, sql,
|
|
16
|
+
* rows) through `ctx.writer` for streaming UI updates.
|
|
17
|
+
* - `get_space_description`: cheap title / description /
|
|
18
|
+
* warehouse id lookup for grounding.
|
|
19
|
+
* - `get_space_serialized`: full `GenieSpace` JSON for
|
|
20
|
+
* column-level grounding when the description isn't
|
|
21
|
+
* enough.
|
|
22
|
+
* 3. Runs the inner agent with `structuredOutput` (Mastra's
|
|
23
|
+
* two-pass mode + `jsonPromptInjection`) to coerce the
|
|
24
|
+
* agent's final answer into a tagged
|
|
25
|
+
* `[{type:"text"|"data", ...}]` array. The two-pass design
|
|
26
|
+
* avoids Databricks Model Serving's `response_format` +
|
|
27
|
+
* `tools` collision; prompt injection sidesteps the
|
|
28
|
+
* separate `response_format` + streaming collision in the
|
|
29
|
+
* structuring agent.
|
|
30
|
+
* 4. Charts every `data` item in parallel via
|
|
31
|
+
* {@link runChartPlanner}, maps `text` items to the shared
|
|
32
|
+
* {@link GenieSummaryItem} `string` variant, and returns the
|
|
33
|
+
* hydrated {@link GenieAgentResult}.
|
|
12
34
|
*
|
|
13
|
-
*
|
|
14
|
-
* `
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* Row payloads from `query_result` are intentionally discarded - the
|
|
19
|
-
* LLM never sees rows, and charts come from the separate
|
|
20
|
-
* `render_data` tool when the model decides one is useful.
|
|
35
|
+
* The inner agent talks to Genie directly via
|
|
36
|
+
* `@dbx-tools/genie` (`genieEventChat`) and the workspace
|
|
37
|
+
* `statementExecution.getStatement` API. AppKit's stock `genie`
|
|
38
|
+
* plugin is honored only for its `spaces` config so existing
|
|
39
|
+
* AppKit-style wiring keeps working without change.
|
|
21
40
|
*/
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
41
|
+
import { type ChartEvent } from "@dbx-tools/appkit-mastra-shared";
|
|
42
|
+
import { appkitUtils } from "@dbx-tools/shared";
|
|
43
|
+
import type { RequestContext } from "@mastra/core/request-context";
|
|
44
|
+
import type { MastraTools } from "./agents.js";
|
|
24
45
|
import type { MastraPluginConfig } from "./config.js";
|
|
25
|
-
/**
|
|
26
|
-
export
|
|
27
|
-
/**
|
|
28
|
-
export
|
|
46
|
+
/** Default alias used when a single unnamed Genie space is wired up. */
|
|
47
|
+
export declare const DEFAULT_GENIE_ALIAS = "default";
|
|
48
|
+
/** Per-space Genie agent configuration. */
|
|
49
|
+
export interface GenieSpaceConfig {
|
|
50
|
+
/** Genie `space_id`. Required; resolves via `client.genie.getSpace`. */
|
|
51
|
+
spaceId: string;
|
|
52
|
+
/**
|
|
53
|
+
* Optional human-readable description appended to the Genie
|
|
54
|
+
* tool's description so the calling LLM has hints about
|
|
55
|
+
* *what data* this space covers (e.g. "orders, returns,
|
|
56
|
+
* fulfillment"). When omitted, only the space's own
|
|
57
|
+
* `description` (fetched on first use) is shown.
|
|
58
|
+
*/
|
|
59
|
+
hint?: string;
|
|
60
|
+
}
|
|
61
|
+
/** Map of alias -> space config. Accepts either explicit objects or bare space ids. */
|
|
62
|
+
export type GenieSpacesConfig = Record<string, GenieSpaceConfig | string>;
|
|
29
63
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
64
|
+
* Get the chart inventory map for this request, creating it on
|
|
65
|
+
* first access. Subsequent reads return the same map so callers
|
|
66
|
+
* mutate in place. The map is request-scoped (collected with the
|
|
67
|
+
* `RequestContext` at end of request), so there's no per-process
|
|
68
|
+
* leak.
|
|
33
69
|
*/
|
|
34
|
-
export
|
|
35
|
-
/** Conversation history returned by `genie.exports().getConversation`. */
|
|
36
|
-
export type GenieConversation = Awaited<ReturnType<GenieExports["getConversation"]>>;
|
|
70
|
+
export declare function chartInventoryFromContext(requestContext: RequestContext): Map<string, ChartEvent>;
|
|
37
71
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* `
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* The `chart` variant is the wire shape emitted by
|
|
44
|
-
* {@link emitChartWithPlanning} (used by both this Genie
|
|
45
|
-
* draining loop and the system-level `render_data` tool). All
|
|
46
|
-
* fields except `chartId` are optional because two events per
|
|
47
|
-
* chartId arrive on the wire: the first carries the rows
|
|
48
|
-
* (`title` + `description?` + `data`); the second, on planner
|
|
49
|
-
* success, carries just the resolved Echarts spec (`option`).
|
|
50
|
-
* The host UI's `<ChartSlot>` merges them by `chartId`.
|
|
72
|
+
* Options for {@link createGenieTool}. Only carries config that
|
|
73
|
+
* doesn't vary per request - the per-request {@link WorkspaceClient},
|
|
74
|
+
* `RequestContext`, writer, and abort signal flow through the
|
|
75
|
+
* tool's `execute(_, ctx)` and are not captured here.
|
|
51
76
|
*/
|
|
52
|
-
export
|
|
53
|
-
|
|
54
|
-
conversationId: string;
|
|
55
|
-
messageId: string;
|
|
77
|
+
export interface CreateGenieToolOptions {
|
|
78
|
+
/** Genie space id this tool targets. */
|
|
56
79
|
spaceId: string;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
chartId: string;
|
|
70
|
-
title?: string;
|
|
71
|
-
description?: string;
|
|
72
|
-
data?: Array<Record<string, unknown>>;
|
|
73
|
-
option?: Record<string, unknown>;
|
|
74
|
-
} | {
|
|
75
|
-
kind: "text";
|
|
76
|
-
content: string;
|
|
77
|
-
} | {
|
|
78
|
-
kind: "suggested";
|
|
79
|
-
questions: string[];
|
|
80
|
-
} | {
|
|
81
|
-
kind: "error";
|
|
82
|
-
error: string;
|
|
83
|
-
};
|
|
80
|
+
/** Plugin config; resolves the LLM and chart planner agent. */
|
|
81
|
+
config: MastraPluginConfig;
|
|
82
|
+
/** Override the registered tool id. Defaults to `"genie"`. */
|
|
83
|
+
toolId?: string;
|
|
84
|
+
/** Override the tool description shown to the calling LLM. */
|
|
85
|
+
toolDescription?: string;
|
|
86
|
+
/**
|
|
87
|
+
* Override the inner agent's max tool-loop steps. Defaults to
|
|
88
|
+
* {@link DEFAULT_MAX_STEPS}.
|
|
89
|
+
*/
|
|
90
|
+
maxSteps?: number;
|
|
91
|
+
}
|
|
84
92
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
93
|
+
* Build the calling agent's Genie tool. The returned Mastra tool
|
|
94
|
+
* runs end-to-end on each invocation:
|
|
95
|
+
*
|
|
96
|
+
* 1. Pull the per-request `WorkspaceClient` off
|
|
97
|
+
* `ctx.requestContext` (stamped by `MastraServer` under
|
|
98
|
+
* {@link MASTRA_USER_KEY}) and emit a `started` writer
|
|
99
|
+
* event so the host UI shows progress immediately.
|
|
100
|
+
* 2. Spin up the inner Mastra agent + three tools, fresh per
|
|
101
|
+
* call so the row cache stays invocation-scoped.
|
|
102
|
+
* 3. Run the agent with `structuredOutput` against
|
|
103
|
+
* {@link agentSummarySchema}. Mastra's two-pass design keeps
|
|
104
|
+
* the inner loop tools-only (no `response_format`), so the
|
|
105
|
+
* Databricks Model Serving `response_format`+`tools`
|
|
106
|
+
* collision never fires.
|
|
107
|
+
* 4. Walk the returned `[text|data][]`, map `text` items to
|
|
108
|
+
* shared `GenieSummaryItem.string`, and chart every `data`
|
|
109
|
+
* item in parallel via {@link runChartPlanner} to a
|
|
110
|
+
* `GenieSummaryItem.visualize`. Items referencing a missing
|
|
111
|
+
* `statementId` are dropped with a warn log; chart-planner
|
|
112
|
+
* failures leave `dataset.chart` unset so the host UI falls
|
|
113
|
+
* back to a table.
|
|
114
|
+
*/
|
|
115
|
+
export declare function createGenieTool(opts: CreateGenieToolOptions): import("@mastra/core/tools").Tool<any, any, any, any, import("@mastra/core/tools").ToolExecutionContext<any, any, unknown>, string, unknown>;
|
|
116
|
+
/**
|
|
117
|
+
* Default tool id for a wired Genie alias. The well-known
|
|
118
|
+
* `default` alias collapses to `genie`; every other alias gets a
|
|
119
|
+
* `genie_` prefix so multi-space registrations stay
|
|
120
|
+
* disambiguated.
|
|
90
121
|
*/
|
|
91
122
|
export declare function defaultGenieToolName(alias: string): string;
|
|
92
123
|
/**
|
|
93
|
-
*
|
|
94
|
-
* `
|
|
95
|
-
*
|
|
124
|
+
* Normalize the {@link GenieSpacesConfig} record. Bare-string
|
|
125
|
+
* entries (`{ default: "01ef..." }`) get wrapped as
|
|
126
|
+
* `{ spaceId: "01ef..." }`; object entries pass through unchanged.
|
|
127
|
+
* `undefined` and empty-string values are dropped so callers can
|
|
128
|
+
* pass `process.env.X` directly (matches AppKit `genie()`'s
|
|
129
|
+
* defensive treatment of unset env vars).
|
|
130
|
+
*/
|
|
131
|
+
export declare function normalizeGenieSpaces(spaces: GenieSpacesConfig | Record<string, string | GenieSpaceConfig | undefined> | undefined): Record<string, GenieSpaceConfig>;
|
|
132
|
+
/**
|
|
133
|
+
* Discover Genie space aliases from every supported source and
|
|
134
|
+
* merge them into a single record. Precedence (highest first):
|
|
96
135
|
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
136
|
+
* 1. {@link MastraPluginConfig.genieSpaces} on the `mastra(...)`
|
|
137
|
+
* call. Explicit Mastra wiring always wins so users can
|
|
138
|
+
* override AppKit's defaults per-agent.
|
|
139
|
+
* 2. AppKit `genie({ spaces: { ... } })` plugin instance. Lets
|
|
140
|
+
* users keep using the existing AppKit config format
|
|
141
|
+
* (`genie({ spaces: { sales: "...", ops: "..." } })`)
|
|
142
|
+
* without restating the same record on the Mastra plugin.
|
|
143
|
+
* Read off the live plugin instance via a structural cast
|
|
144
|
+
* since `Plugin.config` is TS-protected (not runtime-private).
|
|
145
|
+
* 3. `DATABRICKS_GENIE_SPACE_ID` env var (registered under the
|
|
146
|
+
* well-known `default` alias). Matches the AppKit `genie()`
|
|
147
|
+
* plugin's fallback behavior so a bare `mastra()` + `genie()`
|
|
148
|
+
* pair just works.
|
|
149
|
+
*
|
|
150
|
+
* Aliases collide cleanly: a higher-precedence source's value
|
|
151
|
+
* replaces a lower one's wholesale. Sources that contribute zero
|
|
152
|
+
* aliases (or contribute only `undefined` / empty entries) are
|
|
153
|
+
* silently ignored.
|
|
154
|
+
*/
|
|
155
|
+
export declare function resolveGenieSpaces(config: MastraPluginConfig, context: appkitUtils.PluginContextLike | undefined): Record<string, GenieSpaceConfig>;
|
|
156
|
+
/**
|
|
157
|
+
* Build one Mastra tool per configured Genie space. Each tool is
|
|
158
|
+
* a thin {@link createGenieTool} wrapper with the alias-derived
|
|
159
|
+
* id and a hint-flavored description so the calling LLM knows
|
|
160
|
+
* which space covers what data.
|
|
161
|
+
*
|
|
162
|
+
* Returns a record keyed by tool id, ready to spread into an
|
|
163
|
+
* `Agent`'s `tools` map (or surfaced via
|
|
164
|
+
* `plugins.genie?.toolkit()`).
|
|
101
165
|
*/
|
|
102
166
|
export declare function buildGenieTools(opts: {
|
|
103
|
-
|
|
104
|
-
exports: GenieExports;
|
|
167
|
+
spaces: GenieSpacesConfig | Record<string, GenieSpaceConfig>;
|
|
105
168
|
config: MastraPluginConfig;
|
|
106
|
-
|
|
107
|
-
}): Record<string, ReturnType<typeof createTool>>;
|
|
169
|
+
}): MastraTools;
|
|
108
170
|
/**
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* of the AppKit default (which does one blocking call per tool with no
|
|
114
|
-
* mid-flight events).
|
|
115
|
-
*
|
|
116
|
-
* The returned `toolkit()` reads alias names off the plugin's
|
|
117
|
-
* `getAgentTools()` registry (each entry is `${alias}.sendMessage` or
|
|
118
|
-
* `${alias}.getConversation`), then mints one `sendMessage` tool per
|
|
119
|
-
* alias plus a shared `getConversation`. `sendMessage` / `getConversation`
|
|
120
|
-
* are bound back to the plugin instance so they keep their `this`
|
|
121
|
-
* (they are class methods, not free functions).
|
|
122
|
-
*
|
|
123
|
-
* `_opts` is accepted but unused for now - the streaming tools are an
|
|
124
|
-
* all-or-nothing bundle. Wire `only` / `except` / `prefix` / `rename`
|
|
125
|
-
* later if a caller needs them.
|
|
171
|
+
* Plugin-toolkit adapter so the `plugins.genie?.toolkit()` lookup
|
|
172
|
+
* inside an agent's `tools(plugins)` callback returns the
|
|
173
|
+
* Genie agent-backed tools instead of throwing on missing plugin.
|
|
174
|
+
* Mirrors AppKit's `PluginToolkitProvider` shape.
|
|
126
175
|
*/
|
|
127
|
-
export declare function
|
|
176
|
+
export declare function buildGenieToolkitProvider(opts: {
|
|
177
|
+
spaces: GenieSpacesConfig | Record<string, GenieSpaceConfig>;
|
|
128
178
|
config: MastraPluginConfig;
|
|
129
179
|
}): {
|
|
130
|
-
toolkit(opts?: unknown):
|
|
180
|
+
toolkit(opts?: unknown): MastraTools;
|
|
131
181
|
};
|
|
182
|
+
/**
|
|
183
|
+
* Returns `true` when at least one Genie space is reachable
|
|
184
|
+
* through {@link resolveGenieSpaces} - either via
|
|
185
|
+
* {@link MastraPluginConfig.genieSpaces}, the AppKit `genie()`
|
|
186
|
+
* plugin instance, or the `DATABRICKS_GENIE_SPACE_ID` env var.
|
|
187
|
+
*
|
|
188
|
+
* Cheap to call from `resolveProvider` to short-circuit `genie`
|
|
189
|
+
* lookups when nothing is wired, so the `plugins.genie` lookup
|
|
190
|
+
* still resolves to `undefined` (matching AppKit's
|
|
191
|
+
* absent-plugin semantics) when neither source is configured.
|
|
192
|
+
*/
|
|
193
|
+
export declare function hasAnyGenieSpaces(config: MastraPluginConfig, context: appkitUtils.PluginContextLike | undefined): boolean;
|