@dbx-tools/appkit-mastra 0.9.153 → 0.9.157
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 +4 -3
- package/index.ts +32 -24
- package/lib/index.d.ts +32 -24
- package/lib/index.js +32 -23
- package/lib/src/agents.d.ts +5 -6
- package/lib/src/agents.js +12 -15
- package/lib/src/chart.js +33 -33
- package/lib/src/chat.js +10 -13
- package/lib/src/config.d.ts +12 -13
- package/lib/src/config.js +4 -4
- package/lib/src/evaluation.js +7 -9
- package/lib/src/feedback-mode.d.ts +1 -1
- package/lib/src/feedback-mode.js +1 -1
- package/lib/src/filesystems.js +6 -6
- package/lib/src/follow-up-suggestions.js +10 -10
- package/lib/src/genie-chat.js +27 -29
- package/lib/src/genie.d.ts +2 -2
- package/lib/src/genie.js +29 -29
- package/lib/src/identity.d.ts +3 -30
- package/lib/src/identity.js +2 -27
- package/lib/src/memory.d.ts +1 -1
- package/lib/src/memory.js +24 -6
- package/lib/src/mlflow.d.ts +4 -4
- package/lib/src/mlflow.js +15 -18
- package/lib/src/model.d.ts +3 -3
- package/lib/src/model.js +6 -6
- package/lib/src/monty-sandbox.js +8 -8
- package/lib/src/observability.d.ts +6 -5
- package/lib/src/observability.js +8 -6
- package/lib/src/plugin.d.ts +1 -1
- package/lib/src/plugin.js +49 -51
- package/lib/src/remote-skills.d.ts +3 -4
- package/lib/src/remote-skills.js +46 -46
- package/lib/src/rest.d.ts +2 -2
- package/lib/src/rest.js +3 -3
- package/lib/src/server.js +17 -20
- package/lib/src/serving.js +10 -11
- package/lib/src/statement.js +7 -7
- package/lib/src/storage-schema.js +4 -4
- package/lib/src/summarize.js +5 -5
- package/lib/src/telemetry.d.ts +0 -6
- package/lib/src/telemetry.js +34 -41
- package/lib/src/validation.js +3 -4
- package/lib/src/workspaces.d.ts +2 -2
- package/lib/src/workspaces.js +34 -36
- package/lib/src/writer.d.ts +2 -2
- package/lib/src/writer.js +3 -3
- package/package.json +17 -305
- package/src/agents.ts +27 -21
- package/src/chart.ts +43 -37
- package/src/chat.ts +10 -12
- package/src/config.ts +14 -15
- package/src/evaluation.ts +6 -8
- package/src/feedback-mode.ts +1 -1
- package/src/filesystems.ts +5 -5
- package/src/follow-up-suggestions.ts +9 -9
- package/src/genie-chat.ts +32 -31
- package/src/genie.ts +29 -29
- package/src/identity.ts +3 -38
- package/src/memory.ts +24 -6
- package/src/mlflow.ts +21 -21
- package/src/model.ts +7 -7
- package/src/monty-sandbox.ts +7 -7
- package/src/observability.ts +8 -6
- package/src/plugin.ts +78 -65
- package/src/remote-skills.ts +63 -55
- package/src/rest.ts +4 -4
- package/src/server.ts +32 -20
- package/src/serving.ts +14 -11
- package/src/statement.ts +10 -6
- package/src/storage-schema.ts +3 -3
- package/src/summarize.ts +4 -4
- package/src/telemetry.ts +49 -55
- package/src/validation.ts +2 -3
- package/src/workspaces.ts +52 -42
- package/src/writer.ts +3 -3
package/src/chart.ts
CHANGED
|
@@ -29,17 +29,23 @@
|
|
|
29
29
|
|
|
30
30
|
import { AppKitError, CacheManager, ExecutionError } from "@databricks/appkit";
|
|
31
31
|
import {
|
|
32
|
-
asyncUtils,
|
|
33
|
-
errorUtils,
|
|
34
|
-
hash,
|
|
35
|
-
json,
|
|
36
32
|
log,
|
|
37
|
-
object,
|
|
38
|
-
stringUtils,
|
|
39
33
|
type BrandContext,
|
|
34
|
+
sleep,
|
|
35
|
+
toError,
|
|
36
|
+
id,
|
|
37
|
+
parseRecord,
|
|
38
|
+
toNumber,
|
|
39
|
+
toDescription,
|
|
40
40
|
} from "@dbx-tools/shared-core";
|
|
41
|
-
import {
|
|
42
|
-
|
|
41
|
+
import {
|
|
42
|
+
type Chart,
|
|
43
|
+
type ChartResult,
|
|
44
|
+
formatMarker,
|
|
45
|
+
ChartTypeSchema,
|
|
46
|
+
ChartSchema,
|
|
47
|
+
} from "@dbx-tools/shared-mastra";
|
|
48
|
+
import { ModelClass } from "@dbx-tools/shared-model";
|
|
43
49
|
import { Agent } from "@mastra/core/agent";
|
|
44
50
|
import type { RequestContext } from "@mastra/core/request-context";
|
|
45
51
|
import { createTool } from "@mastra/core/tools";
|
|
@@ -108,17 +114,17 @@ const chartDataPointSchema = z
|
|
|
108
114
|
if (v === null || v === undefined) return null;
|
|
109
115
|
if (typeof v === "number") return Number.isFinite(v) ? v : null;
|
|
110
116
|
if (typeof v === "string") {
|
|
111
|
-
return
|
|
117
|
+
return toNumber(v) ?? null;
|
|
112
118
|
}
|
|
113
119
|
// Scatter `[x, y]` or heatmap `[xIndex, yIndex, value]`. Coerce
|
|
114
120
|
// stringified components; reject if any component is non-finite.
|
|
115
121
|
if (Array.isArray(v) && (v.length === 2 || v.length === 3)) {
|
|
116
|
-
const nums = v.map((c) =>
|
|
122
|
+
const nums = v.map((c) => toNumber(c));
|
|
117
123
|
return nums.every((n) => n !== undefined) ? nums : null;
|
|
118
124
|
}
|
|
119
125
|
if (typeof v === "object" && v !== null && "value" in v) {
|
|
120
126
|
const obj = v as { name?: unknown; value: unknown };
|
|
121
|
-
const val =
|
|
127
|
+
const val = toNumber(obj.value);
|
|
122
128
|
if (val === undefined) return null;
|
|
123
129
|
// Coerce numeric / boolean / nullish names to strings so a
|
|
124
130
|
// pie slice keyed on a year (`2024`) or category id is
|
|
@@ -163,13 +169,13 @@ const seriesMarkTypeSchema = z
|
|
|
163
169
|
* across charts.
|
|
164
170
|
*/
|
|
165
171
|
export const chartPlanSchema = z.object({
|
|
166
|
-
chartType:
|
|
172
|
+
chartType: ChartTypeSchema,
|
|
167
173
|
title: z
|
|
168
174
|
.string()
|
|
169
175
|
.nullable()
|
|
170
176
|
.default(null)
|
|
171
177
|
.describe(
|
|
172
|
-
|
|
178
|
+
toDescription(`
|
|
173
179
|
Short title shown above the chart. Use null to fall back to the
|
|
174
180
|
\`title\` argument the caller passed in.
|
|
175
181
|
`),
|
|
@@ -179,7 +185,7 @@ export const chartPlanSchema = z.object({
|
|
|
179
185
|
.nullable()
|
|
180
186
|
.default(null)
|
|
181
187
|
.describe(
|
|
182
|
-
|
|
188
|
+
toDescription(`
|
|
183
189
|
Axis label for the primary (usually bottom / value) axis.
|
|
184
190
|
Used for bar / horizontalBar / line / area / combo / waterfall
|
|
185
191
|
/ scatter / heatmap; use null for pie / funnel / treemap / radar.
|
|
@@ -190,7 +196,7 @@ export const chartPlanSchema = z.object({
|
|
|
190
196
|
.nullable()
|
|
191
197
|
.default(null)
|
|
192
198
|
.describe(
|
|
193
|
-
|
|
199
|
+
toDescription(`
|
|
194
200
|
Axis label for the secondary (usually left) axis. Used for
|
|
195
201
|
bar / horizontalBar / line / area / combo / waterfall /
|
|
196
202
|
scatter / heatmap; use null for pie / funnel / treemap / radar.
|
|
@@ -201,7 +207,7 @@ export const chartPlanSchema = z.object({
|
|
|
201
207
|
.nullable()
|
|
202
208
|
.default(null)
|
|
203
209
|
.describe(
|
|
204
|
-
|
|
210
|
+
toDescription(`
|
|
205
211
|
Primary category labels. For \`bar\` / \`horizontalBar\` /
|
|
206
212
|
\`line\` / \`area\` / \`combo\` / \`waterfall\`: one label per
|
|
207
213
|
data point. For \`heatmap\`: x-axis categories. For \`radar\`:
|
|
@@ -215,7 +221,7 @@ export const chartPlanSchema = z.object({
|
|
|
215
221
|
.nullable()
|
|
216
222
|
.default(null)
|
|
217
223
|
.describe(
|
|
218
|
-
|
|
224
|
+
toDescription(`
|
|
219
225
|
Y-axis (row) labels for \`heatmap\`. Use null when the
|
|
220
226
|
row labels come from the series names, which is the preferred
|
|
221
227
|
way to build a heatmap. Use null for every other chart type.
|
|
@@ -225,7 +231,7 @@ export const chartPlanSchema = z.object({
|
|
|
225
231
|
.array(
|
|
226
232
|
z.object({
|
|
227
233
|
name: z.string().describe(
|
|
228
|
-
|
|
234
|
+
toDescription(`
|
|
229
235
|
Legend name for this series.
|
|
230
236
|
`),
|
|
231
237
|
),
|
|
@@ -238,7 +244,7 @@ export const chartPlanSchema = z.object({
|
|
|
238
244
|
"Which y-axis to bind (0 = left, 1 = right). Use on `combo` when series have different units or scales; use null otherwise.",
|
|
239
245
|
),
|
|
240
246
|
data: z.array(chartDataPointSchema).describe(
|
|
241
|
-
|
|
247
|
+
toDescription(`
|
|
242
248
|
Data points. For category charts (\`bar\` / \`horizontalBar\`
|
|
243
249
|
/ \`line\` / \`area\` / \`combo\` / \`waterfall\` / \`radar\`),
|
|
244
250
|
an array of numbers aligned to \`categories\`; for
|
|
@@ -254,7 +260,7 @@ export const chartPlanSchema = z.object({
|
|
|
254
260
|
)
|
|
255
261
|
.default([])
|
|
256
262
|
.describe(
|
|
257
|
-
|
|
263
|
+
toDescription(`
|
|
258
264
|
One or more series to plot. Required for every chart type
|
|
259
265
|
except \`custom\`, which carries its series inside \`option\`.
|
|
260
266
|
Slice charts (\`pie\` / \`funnel\` / \`treemap\`) and
|
|
@@ -268,7 +274,7 @@ export const chartPlanSchema = z.object({
|
|
|
268
274
|
.nullable()
|
|
269
275
|
.default(null)
|
|
270
276
|
.describe(
|
|
271
|
-
|
|
277
|
+
toDescription(`
|
|
272
278
|
Required for \`custom\`; use null for every other chart type. A
|
|
273
279
|
COMPLETE Echarts option, as a JSON object encoded in a string:
|
|
274
280
|
\`series\` (each with its own \`type\` and that series' own data
|
|
@@ -294,7 +300,7 @@ type ChartPlanInput = z.input<typeof chartPlanSchema>;
|
|
|
294
300
|
*/
|
|
295
301
|
export const chartPlannerRequestSchema = z.object({
|
|
296
302
|
title: z.string().describe(
|
|
297
|
-
|
|
303
|
+
toDescription(`
|
|
298
304
|
Concise title shown above the chart (e.g. "Top 10 SKUs by Revenue").
|
|
299
305
|
`),
|
|
300
306
|
),
|
|
@@ -302,7 +308,7 @@ export const chartPlannerRequestSchema = z.object({
|
|
|
302
308
|
.string()
|
|
303
309
|
.optional()
|
|
304
310
|
.describe(
|
|
305
|
-
|
|
311
|
+
toDescription(`
|
|
306
312
|
One-line intent the chart-planner uses when picking a chart type
|
|
307
313
|
and axis encodings (e.g. "compare quarterly revenue across
|
|
308
314
|
regions", "highlight the steep drop after position 5"). Not shown
|
|
@@ -314,7 +320,7 @@ export const chartPlannerRequestSchema = z.object({
|
|
|
314
320
|
.nonempty("Data must contain at least one row")
|
|
315
321
|
.readonly()
|
|
316
322
|
.describe(
|
|
317
|
-
|
|
323
|
+
toDescription(`
|
|
318
324
|
Tabular dataset to chart. One object per row, keyed by column
|
|
319
325
|
name. Values may be strings, numbers, booleans, or null. The
|
|
320
326
|
chart-planner decides which columns are categories vs. numeric
|
|
@@ -334,7 +340,7 @@ export type ChartPlannerRequest = z.infer<typeof chartPlannerRequestSchema>;
|
|
|
334
340
|
* cache by id, while the model gets the exact opaque token to copy into prose
|
|
335
341
|
* and has no reason to invent or retype a UUID.
|
|
336
342
|
*/
|
|
337
|
-
export const chartToolOutputSchema =
|
|
343
|
+
export const chartToolOutputSchema = ChartSchema.pick({ chartId: true }).extend({
|
|
338
344
|
marker: z
|
|
339
345
|
.string()
|
|
340
346
|
.describe(
|
|
@@ -355,7 +361,7 @@ export type ChartToolOutput = z.infer<typeof chartToolOutputSchema>;
|
|
|
355
361
|
* the schema by construction.
|
|
356
362
|
*/
|
|
357
363
|
function formatChartTypePicker(): string {
|
|
358
|
-
return
|
|
364
|
+
return ChartTypeSchema.options
|
|
359
365
|
.map((opt) => `\`${opt.value}\` for ${opt.description ?? ""}`)
|
|
360
366
|
.join("; ");
|
|
361
367
|
}
|
|
@@ -364,7 +370,7 @@ function formatChartTypePicker(): string {
|
|
|
364
370
|
* System prompt for the inner chart-planning agent. Tuned for a
|
|
365
371
|
* fast-tier model (Haiku, GPT-5-mini, Gemini Flash Lite).
|
|
366
372
|
*/
|
|
367
|
-
const CHART_PLANNER_INSTRUCTIONS =
|
|
373
|
+
const CHART_PLANNER_INSTRUCTIONS = toDescription(`
|
|
368
374
|
You design Apache Echarts visualizations. The user gives you a
|
|
369
375
|
tabular dataset (rows of objects) plus a title and an optional
|
|
370
376
|
description of the intent. You produce a small chart plan (chart
|
|
@@ -453,7 +459,7 @@ function getPlannerAgent(config: MastraPluginConfig): Agent {
|
|
|
453
459
|
description: "Picks chart type and axis encodings for a dataset.",
|
|
454
460
|
instructions: CHART_PLANNER_INSTRUCTIONS,
|
|
455
461
|
model: ({ requestContext }) =>
|
|
456
|
-
buildModel(config, requestContext, { modelClass:
|
|
462
|
+
buildModel(config, requestContext, { modelClass: ModelClass.ChatFast }),
|
|
457
463
|
});
|
|
458
464
|
plannerAgents.set(config, agent);
|
|
459
465
|
}
|
|
@@ -472,7 +478,7 @@ async function runChartPlanner(
|
|
|
472
478
|
): Promise<ChartResult> {
|
|
473
479
|
const { title, description, data } = request;
|
|
474
480
|
const { requestContext, abortSignal } = options;
|
|
475
|
-
const prompt =
|
|
481
|
+
const prompt = toDescription({
|
|
476
482
|
Title: title,
|
|
477
483
|
...(description ? { Description: description } : {}),
|
|
478
484
|
"Dataset (JSON, one row per object)": JSON.stringify(data, null, 2),
|
|
@@ -516,7 +522,7 @@ async function writeChart(entry: Chart, userKey: string): Promise<void> {
|
|
|
516
522
|
} catch (err) {
|
|
517
523
|
logger.warn("write-error", {
|
|
518
524
|
chartId: entry.chartId,
|
|
519
|
-
error:
|
|
525
|
+
error: toError(err),
|
|
520
526
|
});
|
|
521
527
|
}
|
|
522
528
|
}
|
|
@@ -534,7 +540,7 @@ async function readChart(chartId: string, userKey: string): Promise<Chart | unde
|
|
|
534
540
|
} catch (err) {
|
|
535
541
|
logger.warn("read-error", {
|
|
536
542
|
chartId,
|
|
537
|
-
error:
|
|
543
|
+
error: toError(err),
|
|
538
544
|
});
|
|
539
545
|
return undefined;
|
|
540
546
|
}
|
|
@@ -594,13 +600,13 @@ export interface PrepareChartOptions {
|
|
|
594
600
|
* - on data / planner failure: `{ chartId, error }`
|
|
595
601
|
*/
|
|
596
602
|
export async function prepareChart(opts: PrepareChartOptions): Promise<ChartToolOutput> {
|
|
597
|
-
const chartId =
|
|
603
|
+
const chartId = id();
|
|
598
604
|
await writeChart({ chartId }, opts.userKey);
|
|
599
605
|
logger.debug("queued", { chartId });
|
|
600
606
|
// Fire-and-forget. Failures land in the cache as `error` entries;
|
|
601
607
|
// never escape into an unhandled rejection.
|
|
602
608
|
void runPrepareChart(chartId, opts);
|
|
603
|
-
return { chartId, marker:
|
|
609
|
+
return { chartId, marker: formatMarker("chart", chartId) };
|
|
604
610
|
}
|
|
605
611
|
|
|
606
612
|
async function runPrepareChart(chartId: string, opts: PrepareChartOptions): Promise<void> {
|
|
@@ -629,7 +635,7 @@ async function runPrepareChart(chartId: string, opts: PrepareChartOptions): Prom
|
|
|
629
635
|
elapsedMs: Date.now() - startedAt,
|
|
630
636
|
});
|
|
631
637
|
} catch (err) {
|
|
632
|
-
logger.warn("error", { chartId, error:
|
|
638
|
+
logger.warn("error", { chartId, error: toError(err) });
|
|
633
639
|
// The entry's `error` is rendered in the chat, so only an AppKitError's
|
|
634
640
|
// own message travels; anything else could carry upstream provider detail.
|
|
635
641
|
const errText = err instanceof AppKitError ? err.message : CHART_FAILED_MESSAGE;
|
|
@@ -694,7 +700,7 @@ export async function fetchChart(
|
|
|
694
700
|
if (last.result !== undefined || last.error !== undefined) return last;
|
|
695
701
|
const remaining = deadline - Date.now();
|
|
696
702
|
if (remaining <= 0) return last;
|
|
697
|
-
await
|
|
703
|
+
await sleep(Math.min(intervalMs, remaining), options.signal);
|
|
698
704
|
}
|
|
699
705
|
}
|
|
700
706
|
|
|
@@ -958,7 +964,7 @@ export function planToEchartsOption(
|
|
|
958
964
|
// note on `chartDataPointSchema`). A malformed string costs one chart.
|
|
959
965
|
// Nothing here is eval'd; a string-valued Echarts formatter is a
|
|
960
966
|
// template, not code.
|
|
961
|
-
const option =
|
|
967
|
+
const option = parseRecord(plan.option);
|
|
962
968
|
if (!option) {
|
|
963
969
|
throw new Error('chartType "custom" needs an `option` holding a JSON object');
|
|
964
970
|
}
|
|
@@ -1199,7 +1205,7 @@ export function planToEchartsOption(
|
|
|
1199
1205
|
export function buildRenderDataTool(config: MastraPluginConfig) {
|
|
1200
1206
|
return createTool({
|
|
1201
1207
|
id: "render_data",
|
|
1202
|
-
description:
|
|
1208
|
+
description: toDescription([
|
|
1203
1209
|
`
|
|
1204
1210
|
Submit a tabular dataset for inline rendering as a chart in
|
|
1205
1211
|
the user's view. Pass a title, the raw rows (array of objects
|
package/src/chat.ts
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import { routes } from "@dbx-tools/shared-mastra";
|
|
7
|
+
import { log, toError, errorMessage, isRecord } from "@dbx-tools/shared-core";
|
|
9
8
|
import {
|
|
9
|
+
MASTRA_ROUTES,
|
|
10
10
|
isStaleMastraResumeError,
|
|
11
11
|
STALE_MASTRA_RESUME_STREAM_TEXT,
|
|
12
|
-
} from "@dbx-tools/shared-mastra
|
|
12
|
+
} from "@dbx-tools/shared-mastra";
|
|
13
13
|
import { handleChatStream, toAISdkStream } from "@mastra/ai-sdk";
|
|
14
14
|
import { isEventedAgent } from "@mastra/core/agent/durable";
|
|
15
15
|
import { registerApiRoute } from "@mastra/core/server";
|
|
@@ -37,16 +37,14 @@ function latestUserText(value: unknown): string | undefined {
|
|
|
37
37
|
if (!Array.isArray(value)) return undefined;
|
|
38
38
|
for (let index = value.length - 1; index >= 0; index -= 1) {
|
|
39
39
|
const message = value[index];
|
|
40
|
-
if (!
|
|
40
|
+
if (!isRecord(message) || message.role !== "user") continue;
|
|
41
41
|
if (typeof message.content === "string" && message.content.trim()) {
|
|
42
42
|
return message.content.trim();
|
|
43
43
|
}
|
|
44
44
|
if (!Array.isArray(message.parts)) continue;
|
|
45
45
|
const text = message.parts
|
|
46
46
|
.flatMap((part) =>
|
|
47
|
-
|
|
48
|
-
? [part.text]
|
|
49
|
-
: [],
|
|
47
|
+
isRecord(part) && part.type === "text" && typeof part.text === "string" ? [part.text] : [],
|
|
50
48
|
)
|
|
51
49
|
.join("\n")
|
|
52
50
|
.trim();
|
|
@@ -58,11 +56,11 @@ function latestUserText(value: unknown): string | undefined {
|
|
|
58
56
|
/** Register detached chat, durable observation, and explicit abort routes. */
|
|
59
57
|
export function agentChatRoutes(config: MastraPluginConfig = {}) {
|
|
60
58
|
const followUps = resolveFollowUpSuggestionsConfig(config.followUpSuggestions);
|
|
61
|
-
const chatPath = `${
|
|
59
|
+
const chatPath = `${MASTRA_ROUTES.chat}/:agentId` as `${string}:agentId`;
|
|
62
60
|
const runPath =
|
|
63
|
-
`${
|
|
61
|
+
`${MASTRA_ROUTES.chat}/:agentId${MASTRA_ROUTES.runs}/:runId` as `${string}:agentId${string}:runId`;
|
|
64
62
|
const abortPath =
|
|
65
|
-
`${runPath}${
|
|
63
|
+
`${runPath}${MASTRA_ROUTES.abort}` as `${string}:agentId${string}:runId${string}`;
|
|
66
64
|
return [
|
|
67
65
|
registerApiRoute(chatPath, {
|
|
68
66
|
method: "POST",
|
|
@@ -180,9 +178,9 @@ export function agentChatRoutes(config: MastraPluginConfig = {}) {
|
|
|
180
178
|
function serializeChatStreamError(error: unknown): string {
|
|
181
179
|
if (isStaleMastraResumeError(error)) {
|
|
182
180
|
logger.warn("ignored stale mastra resume", {
|
|
183
|
-
error:
|
|
181
|
+
error: toError(error),
|
|
184
182
|
});
|
|
185
183
|
return STALE_MASTRA_RESUME_STREAM_TEXT;
|
|
186
184
|
}
|
|
187
|
-
return
|
|
185
|
+
return errorMessage(error);
|
|
188
186
|
}
|
package/src/config.ts
CHANGED
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { getExecutionContext, type BasePluginConfig, type ConfigSchema } from "@databricks/appkit";
|
|
18
|
-
import {
|
|
18
|
+
import { type ExecutionContextLike, type IdentityMode, IDENTITY_MODES } from "@dbx-tools/appkit";
|
|
19
19
|
import type { BrandContext } from "@dbx-tools/shared-core";
|
|
20
|
-
import type { FeedbackModeOption } from "@dbx-tools/shared-mastra
|
|
20
|
+
import type { FeedbackModeOption } from "@dbx-tools/shared-mastra";
|
|
21
21
|
import type { AgentConfig } from "@mastra/core/agent";
|
|
22
22
|
import type { RequestContext } from "@mastra/core/request-context";
|
|
23
23
|
import { MASTRA_RESOURCE_ID_KEY, MASTRA_THREAD_ID_KEY } from "@mastra/core/request-context";
|
|
@@ -31,7 +31,6 @@ import type { PgVectorConfig, PostgresStoreConfig } from "@mastra/pg";
|
|
|
31
31
|
|
|
32
32
|
import type { AnyMastraAgentDefinition, MastraTools } from "./agents.ts";
|
|
33
33
|
import type { GenieSpacesConfig } from "./genie.ts";
|
|
34
|
-
import { IDENTITY_MODES, type MastraIdentityMode } from "./identity.ts";
|
|
35
34
|
import type { LocalSkillMount, RemoteSkillsOption } from "./remote-skills.ts";
|
|
36
35
|
|
|
37
36
|
/**
|
|
@@ -101,14 +100,14 @@ export const TRACE_REQUEST_CONTEXT_KEYS: readonly string[] = [
|
|
|
101
100
|
/** AppKit execution context plus the canonical user id. */
|
|
102
101
|
export interface User {
|
|
103
102
|
id: string;
|
|
104
|
-
executionContext:
|
|
103
|
+
executionContext: ExecutionContextLike;
|
|
105
104
|
}
|
|
106
105
|
|
|
107
106
|
/**
|
|
108
107
|
* Canonical identity for an AppKit execution context: the OBO user id on a
|
|
109
108
|
* user-scoped call, the service principal id otherwise.
|
|
110
109
|
*/
|
|
111
|
-
export function executionContextUserId(context:
|
|
110
|
+
export function executionContextUserId(context: ExecutionContextLike): string {
|
|
112
111
|
return "userId" in context ? context.userId : context.serviceUserId;
|
|
113
112
|
}
|
|
114
113
|
|
|
@@ -128,7 +127,7 @@ export function executionContextUserId(context: appkit.ExecutionContextLike): st
|
|
|
128
127
|
* renders as an expired chart.
|
|
129
128
|
*/
|
|
130
129
|
export function attributedUserId(
|
|
131
|
-
executionContext:
|
|
130
|
+
executionContext: ExecutionContextLike,
|
|
132
131
|
forwardedUserId?: string,
|
|
133
132
|
): string {
|
|
134
133
|
if ("isUserContext" in executionContext) return executionContextUserId(executionContext);
|
|
@@ -241,15 +240,15 @@ export interface MastraPluginConfig extends BasePluginConfig {
|
|
|
241
240
|
/** AI SDK provider-options namespace. Defaults to `"openai"`; no env fallback. */
|
|
242
241
|
providerId?: string;
|
|
243
242
|
/**
|
|
244
|
-
* PostgresStore for Mastra threads/messages. `true`
|
|
245
|
-
*
|
|
246
|
-
* separately configured store.
|
|
243
|
+
* PostgresStore for Mastra threads/messages. `true` derives a dedicated,
|
|
244
|
+
* lifecycle-isolated service-principal pool from the `lakebase` plugin; an
|
|
245
|
+
* object opens a separately configured store.
|
|
247
246
|
*/
|
|
248
247
|
storage?: boolean | PostgresStoreConfig;
|
|
249
248
|
/**
|
|
250
|
-
* PgVector store for Mastra memory recall. `true`
|
|
251
|
-
*
|
|
252
|
-
* separately configured store.
|
|
249
|
+
* PgVector store for Mastra memory recall. `true` derives a dedicated,
|
|
250
|
+
* lifecycle-isolated service-principal pool from the `lakebase` plugin; an
|
|
251
|
+
* object opens a separately configured store.
|
|
253
252
|
*/
|
|
254
253
|
memory?: boolean | MastraMemoryConfig;
|
|
255
254
|
/**
|
|
@@ -640,7 +639,7 @@ export interface MastraPluginConfig extends BasePluginConfig {
|
|
|
640
639
|
* mastra({ genieIdentity: "auto", genieSpaces: { default: spaceId } });
|
|
641
640
|
* ```
|
|
642
641
|
*/
|
|
643
|
-
genieIdentity?:
|
|
642
|
+
genieIdentity?: IdentityMode;
|
|
644
643
|
/**
|
|
645
644
|
* Optional brand context applied to charts produced by the built-in
|
|
646
645
|
* `render_data` / `prepare_chart` tools. When set, the chart planner's
|
|
@@ -716,12 +715,12 @@ export const MASTRA_CONFIG_SCHEMA: ConfigSchema = {
|
|
|
716
715
|
storage: {
|
|
717
716
|
type: ["boolean", "object"],
|
|
718
717
|
description:
|
|
719
|
-
"PostgresStore for Mastra threads / messages. `true`
|
|
718
|
+
"PostgresStore for Mastra threads / messages. `true` derives a dedicated lifecycle-isolated service-principal pool from the `lakebase` plugin; an object opens a separately configured store. Auto-enabled when the `lakebase` plugin is registered.",
|
|
720
719
|
},
|
|
721
720
|
memory: {
|
|
722
721
|
type: ["boolean", "object"],
|
|
723
722
|
description:
|
|
724
|
-
"PgVector store for Mastra semantic recall. `true`
|
|
723
|
+
"PgVector store for Mastra semantic recall. `true` derives a dedicated lifecycle-isolated service-principal pool from the `lakebase` plugin; an object opens a separately configured store. Auto-enabled when the `lakebase` plugin is registered.",
|
|
725
724
|
},
|
|
726
725
|
codeMode: {
|
|
727
726
|
type: ["boolean", "string", "object"],
|
package/src/evaluation.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { DriveResult, EvalDriver } from "@databricks/appkit/beta";
|
|
8
|
-
import {
|
|
8
|
+
import { errorMessage, id, isRecord } from "@dbx-tools/shared-core";
|
|
9
9
|
import type { Agent } from "@mastra/core/agent";
|
|
10
10
|
import type { RequestContext } from "@mastra/core/request-context";
|
|
11
11
|
|
|
@@ -29,7 +29,7 @@ export function createMastraEvalDriver(
|
|
|
29
29
|
): EvalDriver {
|
|
30
30
|
const resourceId = options.resourceId ?? `eval:${agent.id}`;
|
|
31
31
|
const requestContextFactory = options.createRequestContext ?? createRequestContext;
|
|
32
|
-
let threadId =
|
|
32
|
+
let threadId = id();
|
|
33
33
|
|
|
34
34
|
return {
|
|
35
35
|
async send(message, sendOptions): Promise<DriveResult> {
|
|
@@ -41,13 +41,11 @@ export function createMastraEvalDriver(
|
|
|
41
41
|
...(sendOptions?.signal ? { abortSignal: sendOptions.signal } : {}),
|
|
42
42
|
});
|
|
43
43
|
const toolCallDetails = result.toolCalls.map((call) => {
|
|
44
|
-
const payload: Record<string, unknown> =
|
|
45
|
-
? call.payload
|
|
46
|
-
: {};
|
|
44
|
+
const payload: Record<string, unknown> = isRecord(call.payload) ? call.payload : {};
|
|
47
45
|
const args = payload.args;
|
|
48
46
|
return {
|
|
49
47
|
name: String(payload.toolName ?? ""),
|
|
50
|
-
args:
|
|
48
|
+
args: isRecord(args) ? args : {},
|
|
51
49
|
};
|
|
52
50
|
});
|
|
53
51
|
return {
|
|
@@ -60,7 +58,7 @@ export function createMastraEvalDriver(
|
|
|
60
58
|
};
|
|
61
59
|
} catch (caught) {
|
|
62
60
|
return {
|
|
63
|
-
reply:
|
|
61
|
+
reply: errorMessage(caught),
|
|
64
62
|
toolCalls: [],
|
|
65
63
|
toolCallDetails: [],
|
|
66
64
|
succeeded: false,
|
|
@@ -69,7 +67,7 @@ export function createMastraEvalDriver(
|
|
|
69
67
|
}
|
|
70
68
|
},
|
|
71
69
|
reset() {
|
|
72
|
-
threadId =
|
|
70
|
+
threadId = id();
|
|
73
71
|
},
|
|
74
72
|
};
|
|
75
73
|
}
|
package/src/feedback-mode.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { ConfigurationError } from "@databricks/appkit";
|
|
8
|
-
import type { FeedbackMode, FeedbackModeOption } from "@dbx-tools/shared-mastra
|
|
8
|
+
import type { FeedbackMode, FeedbackModeOption } from "@dbx-tools/shared-mastra";
|
|
9
9
|
|
|
10
10
|
/** Runtime availability used by automatic feedback selection. */
|
|
11
11
|
export interface FeedbackAvailability {
|
package/src/filesystems.ts
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* @module
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import {
|
|
13
|
-
import { FileSystemError,
|
|
12
|
+
import { scratchFS } from "@dbx-tools/fs";
|
|
13
|
+
import { FileSystemError, dirname, normalize } from "@dbx-tools/shared-fs";
|
|
14
14
|
import type {
|
|
15
15
|
FileEntry as SharedFileEntry,
|
|
16
16
|
FileStat as SharedFileStat,
|
|
@@ -292,7 +292,7 @@ export class MastraFileSystemAdapter extends MastraFilesystem {
|
|
|
292
292
|
|
|
293
293
|
/** When Mastra asks for non-recursive writes, require the parent directory. */
|
|
294
294
|
private async assertParentExists(inputPath: string): Promise<void> {
|
|
295
|
-
const parent =
|
|
295
|
+
const parent = dirname(normalizeWorkspacePath(inputPath));
|
|
296
296
|
if (parent === "/" || (await this.fs.exists(parent))) return;
|
|
297
297
|
throw new DirectoryNotFoundError(parent);
|
|
298
298
|
}
|
|
@@ -343,7 +343,7 @@ export class MountedCompositeFilesystem extends CompositeFilesystem {
|
|
|
343
343
|
|
|
344
344
|
/** Fresh writable local temp mount on a root unique to this call. */
|
|
345
345
|
export function scratchFilesystem(): MastraFileSystemAdapter {
|
|
346
|
-
return filesystems(
|
|
346
|
+
return filesystems(scratchFS("mastra"));
|
|
347
347
|
}
|
|
348
348
|
|
|
349
349
|
/** Map a shared-fs error code onto the matching Mastra filesystem error. */
|
|
@@ -397,6 +397,6 @@ function toMastraStat(stat: SharedFileStat, inputPath: string): FileStat {
|
|
|
397
397
|
* and a mount should not fail a listing over a stray segment.
|
|
398
398
|
*/
|
|
399
399
|
function normalizeWorkspacePath(inputPath: string): string {
|
|
400
|
-
const result =
|
|
400
|
+
const result = normalize(inputPath);
|
|
401
401
|
return result.ok ? result.path : "/";
|
|
402
402
|
}
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { log, combineAbortSignals, isRecord, toError, toDescription } from "@dbx-tools/shared-core";
|
|
8
8
|
import {
|
|
9
9
|
FOLLOW_UP_SUGGESTIONS_PART_TYPE,
|
|
10
10
|
type FollowUpSuggestionsPartData,
|
|
11
11
|
FollowUpSuggestionsPartDataSchema,
|
|
12
|
-
} from "@dbx-tools/shared-mastra
|
|
13
|
-
import {
|
|
12
|
+
} from "@dbx-tools/shared-mastra";
|
|
13
|
+
import { ModelClass } from "@dbx-tools/shared-model";
|
|
14
14
|
import { Agent } from "@mastra/core/agent";
|
|
15
15
|
import type { MessageList } from "@mastra/core/agent/message-list";
|
|
16
16
|
import type { MastraModelConfig } from "@mastra/core/llm";
|
|
@@ -25,7 +25,7 @@ import { buildModel } from "./model.ts";
|
|
|
25
25
|
import { TYPOGRAPHY_RULE } from "./style.ts";
|
|
26
26
|
|
|
27
27
|
const logger = log.logger("mastra/follow-up-suggestions");
|
|
28
|
-
const FOLLOW_UP_MODEL_CLASS =
|
|
28
|
+
const FOLLOW_UP_MODEL_CLASS = ModelClass.ChatFast;
|
|
29
29
|
const DEFAULT_QUESTION_LIMIT = 3;
|
|
30
30
|
const MAX_QUESTION_LIMIT = 10;
|
|
31
31
|
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
@@ -195,8 +195,8 @@ function acceptedQuestions(
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
function toolActivityValue(value: unknown): Record<string, unknown> | undefined {
|
|
198
|
-
if (!
|
|
199
|
-
return
|
|
198
|
+
if (!isRecord(value)) return undefined;
|
|
199
|
+
return isRecord(value.payload) ? value.payload : value;
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
function toolActivityName(value: Record<string, unknown>): string | undefined {
|
|
@@ -244,8 +244,8 @@ export async function suggestFollowUps(
|
|
|
244
244
|
const settings = resolveFollowUpSuggestionsConfig(config.followUpSuggestions);
|
|
245
245
|
if (!settings || settings.mode === "genie") return [];
|
|
246
246
|
const timeout = AbortSignal.timeout(settings.timeoutMs);
|
|
247
|
-
const abortSignal =
|
|
248
|
-
const prompt =
|
|
247
|
+
const abortSignal = combineAbortSignals(options.abortSignal, timeout);
|
|
248
|
+
const prompt = toDescription({
|
|
249
249
|
"User message": options.userText,
|
|
250
250
|
"Assistant answer": options.answer,
|
|
251
251
|
...(options.turnContext ? { "Turn tool data": options.turnContext } : {}),
|
|
@@ -264,7 +264,7 @@ export async function suggestFollowUps(
|
|
|
264
264
|
return acceptedQuestions(parsed.questions, options, settings.limit);
|
|
265
265
|
} catch (error) {
|
|
266
266
|
if (!options.abortSignal?.aborted) {
|
|
267
|
-
logger.warn("generation-failed", { error:
|
|
267
|
+
logger.warn("generation-failed", { error: toError(error) });
|
|
268
268
|
}
|
|
269
269
|
return [];
|
|
270
270
|
}
|