@dbx-tools/appkit-mastra 0.9.154 → 0.9.158
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/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 +6 -7
- package/lib/src/config.js +2 -2
- 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.js +6 -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 +48 -50
- 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 +6 -7
- 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 +5 -5
- 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 +75 -61
- 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/model.ts
CHANGED
|
@@ -23,14 +23,14 @@
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
import { createWorkspaceClient, type WorkspaceClient } from "@databricks/appkit";
|
|
26
|
-
import {
|
|
27
|
-
import { classes, policy, resolve } from "@dbx-tools/model";
|
|
26
|
+
import { tryGetExecutionContext } from "@dbx-tools/appkit";
|
|
27
|
+
import { classes, policy, resolve, selection } from "@dbx-tools/model";
|
|
28
28
|
import {
|
|
29
29
|
createDatabricksLanguageModel,
|
|
30
30
|
type DatabricksLanguageModel,
|
|
31
|
-
} from "@dbx-tools/model-protocol
|
|
31
|
+
} from "@dbx-tools/model-protocol";
|
|
32
32
|
import { log } from "@dbx-tools/shared-core";
|
|
33
|
-
import {
|
|
33
|
+
import { contracts, type ServingEndpointSummary } from "@dbx-tools/shared-model";
|
|
34
34
|
import { RequestContext } from "@mastra/core/request-context";
|
|
35
35
|
|
|
36
36
|
import { MASTRA_USER_KEY, type MastraPluginConfig, type User } from "./config.ts";
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
} from "./serving.ts";
|
|
42
42
|
import { recordActiveTraceAuth, recordActiveTraceModel } from "./telemetry.ts";
|
|
43
43
|
|
|
44
|
-
type ModelClass =
|
|
44
|
+
type ModelClass = contracts.ModelClass;
|
|
45
45
|
const { parseModelClass } = classes;
|
|
46
46
|
const { selectModel } = resolve;
|
|
47
47
|
|
|
@@ -89,7 +89,7 @@ function resolveModelWorkspaceContext(
|
|
|
89
89
|
requestContext?: RequestContext,
|
|
90
90
|
): ResolvedModelWorkspaceClient {
|
|
91
91
|
const user = requestContext?.get(MASTRA_USER_KEY) as User | undefined;
|
|
92
|
-
const executionContext = user?.executionContext ??
|
|
92
|
+
const executionContext = user?.executionContext ?? tryGetExecutionContext();
|
|
93
93
|
if (executionContext?.client.config) {
|
|
94
94
|
return {
|
|
95
95
|
client: executionContext.client,
|
|
@@ -137,7 +137,7 @@ export function resolveDefaultModelId(
|
|
|
137
137
|
overrides: BuildModelOverrides = {},
|
|
138
138
|
): string {
|
|
139
139
|
const requested = overrides.modelId ?? process.env.DATABRICKS_SERVING_ENDPOINT_NAME;
|
|
140
|
-
return
|
|
140
|
+
return selection.resolveModel(endpoints, selectionInput(config, requested, overrides.modelClass))
|
|
141
141
|
.modelId;
|
|
142
142
|
}
|
|
143
143
|
|
package/src/monty-sandbox.ts
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { availableParallelism } from "node:os";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import { boolean } from "@dbx-tools/core";
|
|
14
|
+
import { log, toError, errorMessage, memoize } from "@dbx-tools/shared-core";
|
|
15
15
|
import {
|
|
16
16
|
MastraSandbox,
|
|
17
17
|
type CommandResult,
|
|
@@ -45,9 +45,9 @@ export function montyMaxProcesses(parallelism: number = availableParallelism()):
|
|
|
45
45
|
return Math.max(4, Math.floor(parallelism) * 2);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
const montyContext =
|
|
48
|
+
const montyContext = memoize(async (): Promise<MontyContext> => {
|
|
49
49
|
const errors: Error[] = [];
|
|
50
|
-
const targets =
|
|
50
|
+
const targets = boolean(undefined, "MONTY_FORCE_WASM")
|
|
51
51
|
? [WASM_MONTY_TARGET]
|
|
52
52
|
: [NATIVE_MONTY_TARGET, WASM_MONTY_TARGET];
|
|
53
53
|
for (const target of targets) {
|
|
@@ -66,9 +66,9 @@ const montyContext = functionUtils.memoize(async (): Promise<MontyContext> => {
|
|
|
66
66
|
pool,
|
|
67
67
|
};
|
|
68
68
|
} catch (error) {
|
|
69
|
-
errors.push(
|
|
69
|
+
errors.push(toError(error));
|
|
70
70
|
logger.debug(`${target.name} unavailable`, {
|
|
71
|
-
error:
|
|
71
|
+
error: toError(error),
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
74
|
}
|
|
@@ -208,7 +208,7 @@ export class MontySandbox extends MastraSandbox {
|
|
|
208
208
|
if (aborted || options.abortSignal?.aborted) {
|
|
209
209
|
throw abortReason(options.abortSignal);
|
|
210
210
|
}
|
|
211
|
-
const message =
|
|
211
|
+
const message = errorMessage(caught);
|
|
212
212
|
output.emit("stderr", output.stderr.value ? `\n${message}` : message);
|
|
213
213
|
const { crashedError } = await montyContext();
|
|
214
214
|
const timedOut = caught instanceof crashedError && caught.timedOut;
|
package/src/observability.ts
CHANGED
|
@@ -17,10 +17,11 @@
|
|
|
17
17
|
* ambient OTel context, so when Mastra is invoked from inside an
|
|
18
18
|
* AppKit HTTP span the trace stays connected.
|
|
19
19
|
*
|
|
20
|
-
* Net effect: Mastra spans get exactly the treatment AppKit's
|
|
21
|
-
* `agents` plugin gets.
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* Net effect: deployed Mastra spans get exactly the treatment AppKit's
|
|
21
|
+
* `agents` plugin gets. Local direct MLflow tracing uses its own global
|
|
22
|
+
* provider because AppKit has no OTLP processor to start there. No custom
|
|
23
|
+
* OTLP pipeline lives in this package; the OTLP endpoint, headers, and resource
|
|
24
|
+
* attributes are driven by the standard OTel env vars
|
|
24
25
|
* (`OTEL_EXPORTER_OTLP_ENDPOINT`, `OTEL_EXPORTER_OTLP_HEADERS`,
|
|
25
26
|
* `OTEL_SERVICE_NAME`, `OTEL_RESOURCE_ATTRIBUTES`, ...) and consumed
|
|
26
27
|
* by AppKit's `TelemetryManager`. Set those once and both AppKit and
|
|
@@ -92,7 +93,7 @@ export interface BuildObservabilityOptions {
|
|
|
92
93
|
* Supports dot notation for nested values per the Mastra docs.
|
|
93
94
|
*/
|
|
94
95
|
requestContextKeys?: readonly string[];
|
|
95
|
-
/** AppKit-owned
|
|
96
|
+
/** AppKit-owned provider used unless local direct MLflow tracing owns the global provider. */
|
|
96
97
|
tracerProvider?: TracerProvider;
|
|
97
98
|
}
|
|
98
99
|
|
|
@@ -140,6 +141,7 @@ export async function buildObservability(
|
|
|
140
141
|
const directMlflowConfigured =
|
|
141
142
|
options?.enabled === false || otlpConfigured ? false : await initializeDirectMlflowTracing();
|
|
142
143
|
if (directMlflowConfigured) configureOtelPropagation();
|
|
144
|
+
const bridgeTracerProvider = directMlflowConfigured ? undefined : options?.tracerProvider;
|
|
143
145
|
const tracingConfigured = otlpConfigured || directMlflowConfigured;
|
|
144
146
|
|
|
145
147
|
if (options?.enabled === false || (options?.enabled !== true && !tracingConfigured)) {
|
|
@@ -190,7 +192,7 @@ export async function buildObservability(
|
|
|
190
192
|
serviceName: {
|
|
191
193
|
serviceName,
|
|
192
194
|
bridge: new OtelBridge(
|
|
193
|
-
|
|
195
|
+
bridgeTracerProvider ? { tracerProvider: bridgeTracerProvider } : undefined,
|
|
194
196
|
),
|
|
195
197
|
requestContextKeys,
|
|
196
198
|
},
|
package/src/plugin.ts
CHANGED
|
@@ -56,20 +56,41 @@ import {
|
|
|
56
56
|
type PluginManifest,
|
|
57
57
|
type ResourceRequirement,
|
|
58
58
|
} from "@databricks/appkit";
|
|
59
|
-
import {
|
|
60
|
-
|
|
59
|
+
import {
|
|
60
|
+
pluginRegistry,
|
|
61
|
+
type IdentityMode,
|
|
62
|
+
instance,
|
|
63
|
+
require,
|
|
64
|
+
configureNativeHttpTelemetry,
|
|
65
|
+
excludeUnparentedOutgoingHttpTelemetry,
|
|
66
|
+
deferredNativeTracerProvider,
|
|
67
|
+
requestUserId,
|
|
68
|
+
useServicePrincipal,
|
|
69
|
+
} from "@dbx-tools/appkit";
|
|
70
|
+
import { sendGenieMessageFeedback } from "@dbx-tools/genie";
|
|
61
71
|
import { modelCatalog } from "@dbx-tools/model";
|
|
62
|
-
import { asyncUtils, errorUtils, log, object, stringUtils } from "@dbx-tools/shared-core";
|
|
63
72
|
import {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
combineAbortSignals,
|
|
74
|
+
toError,
|
|
75
|
+
errorContext,
|
|
76
|
+
logger,
|
|
77
|
+
toNumber,
|
|
78
|
+
firstNonEmpty,
|
|
79
|
+
} from "@dbx-tools/shared-core";
|
|
80
|
+
import {
|
|
67
81
|
type Chart,
|
|
68
82
|
type GenieChatRequest,
|
|
69
83
|
type MastraClientConfig,
|
|
70
84
|
type StatementData,
|
|
85
|
+
type FeedbackMode,
|
|
86
|
+
MastraFeedbackRequestSchema,
|
|
87
|
+
type MlflowFeedbackRequest,
|
|
88
|
+
type GenieFeedbackRequest,
|
|
89
|
+
MASTRA_ROUTES,
|
|
90
|
+
genieRoutePath,
|
|
91
|
+
GenieChatRequestSchema,
|
|
71
92
|
} from "@dbx-tools/shared-mastra";
|
|
72
|
-
import {
|
|
93
|
+
import { type ServingEndpointSummary, toModelDisplayName } from "@dbx-tools/shared-model";
|
|
73
94
|
import { workflowRoute } from "@mastra/ai-sdk";
|
|
74
95
|
import type { Agent } from "@mastra/core/agent";
|
|
75
96
|
import { Mastra } from "@mastra/core/mastra";
|
|
@@ -112,12 +133,7 @@ import {
|
|
|
112
133
|
type GenieChatSpace,
|
|
113
134
|
} from "./genie-chat.ts";
|
|
114
135
|
import { collectSpaceSuggestions, resolveGenieSpaces, type GenieSpaceConfig } from "./genie.ts";
|
|
115
|
-
import {
|
|
116
|
-
requestUserId,
|
|
117
|
-
resolveIdentityMode,
|
|
118
|
-
useServicePrincipal,
|
|
119
|
-
type MastraIdentityMode,
|
|
120
|
-
} from "./identity.ts";
|
|
136
|
+
import { resolveIdentityMode } from "./identity.ts";
|
|
121
137
|
import { buildMcpServer, type ResolvedMcp } from "./mcp.ts";
|
|
122
138
|
import { createMastraLakebasePool, createMemoryBuilder, needsLakebase } from "./memory.ts";
|
|
123
139
|
import {
|
|
@@ -242,7 +258,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
242
258
|
return resources;
|
|
243
259
|
}
|
|
244
260
|
|
|
245
|
-
private logger =
|
|
261
|
+
private logger = logger(this);
|
|
246
262
|
private built: BuiltAgents | null = null;
|
|
247
263
|
private mastra: Mastra | null = null;
|
|
248
264
|
private mastraApp: express.Express | null = null;
|
|
@@ -259,13 +275,13 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
259
275
|
*/
|
|
260
276
|
private mcp: ResolvedMcp | null = null;
|
|
261
277
|
/** Resolved feedback destination published to server and browser clients. */
|
|
262
|
-
private resolvedFeedbackMode:
|
|
278
|
+
private resolvedFeedbackMode: FeedbackMode = "none";
|
|
263
279
|
/**
|
|
264
|
-
* Resolved
|
|
280
|
+
* Resolved AppKit identity mode: the identity the chat path's Databricks
|
|
265
281
|
* calls run as. Read once at setup so an invalid `genieIdentity` fails the app
|
|
266
282
|
* boot rather than the first request, and so every request agrees.
|
|
267
283
|
*/
|
|
268
|
-
private identityMode:
|
|
284
|
+
private identityMode: IdentityMode = "user";
|
|
269
285
|
override async setup(): Promise<void> {
|
|
270
286
|
// Resolve the identity mode up front so an invalid `genieIdentity` fails the
|
|
271
287
|
// app boot with a clear message rather than 500-ing the first chat request.
|
|
@@ -277,10 +293,10 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
277
293
|
});
|
|
278
294
|
this.config.feedbackMode = this.resolvedFeedbackMode;
|
|
279
295
|
if (this.config.observability !== false) {
|
|
280
|
-
await
|
|
296
|
+
await configureNativeHttpTelemetry({
|
|
281
297
|
// A low-level request without an active semantic span becomes a noisy
|
|
282
298
|
// standalone trace. Requests inside an agent/tool span remain visible.
|
|
283
|
-
outgoingFilter:
|
|
299
|
+
outgoingFilter: excludeUnparentedOutgoingHttpTelemetry,
|
|
284
300
|
});
|
|
285
301
|
await registerAppMlflowTraceInfoProcessor();
|
|
286
302
|
}
|
|
@@ -320,7 +336,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
320
336
|
* already in the registry by the time this fires.
|
|
321
337
|
*/
|
|
322
338
|
private applyLakebaseAutoDefaults(): void {
|
|
323
|
-
const hasLakebase =
|
|
339
|
+
const hasLakebase = instance(this.context, lakebase) !== undefined;
|
|
324
340
|
if (!hasLakebase) return;
|
|
325
341
|
if (this.config.storage === undefined) this.config.storage = true;
|
|
326
342
|
if (this.config.memory === undefined) this.config.memory = true;
|
|
@@ -335,7 +351,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
335
351
|
await flushDirectMlflowTracing();
|
|
336
352
|
} catch (err) {
|
|
337
353
|
this.logger.warn("error flushing direct MLflow traces", {
|
|
338
|
-
error:
|
|
354
|
+
error: toError(err),
|
|
339
355
|
});
|
|
340
356
|
}
|
|
341
357
|
}
|
|
@@ -494,7 +510,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
494
510
|
}
|
|
495
511
|
|
|
496
512
|
/** Resolve the only feedback destination exposed for this plugin mode. */
|
|
497
|
-
private feedbackMode():
|
|
513
|
+
private feedbackMode(): FeedbackMode {
|
|
498
514
|
return this.resolvedFeedbackMode;
|
|
499
515
|
}
|
|
500
516
|
|
|
@@ -542,7 +558,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
542
558
|
this.route(router, {
|
|
543
559
|
name: "models",
|
|
544
560
|
method: "get",
|
|
545
|
-
path:
|
|
561
|
+
path: MASTRA_ROUTES.models,
|
|
546
562
|
handler: async (req, res) => {
|
|
547
563
|
const result = await this.scopedSelf(req).listModelsResult();
|
|
548
564
|
if (!result.ok) {
|
|
@@ -563,7 +579,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
563
579
|
req: express.Request,
|
|
564
580
|
res: express.Response,
|
|
565
581
|
): Promise<void> => {
|
|
566
|
-
const requested =
|
|
582
|
+
const requested = firstNonEmpty(req.params.agentId);
|
|
567
583
|
if (requested !== null && !this.built?.agents[requested]) {
|
|
568
584
|
res.status(404).json({ error: this.unknownAgentMessage(requested) });
|
|
569
585
|
return;
|
|
@@ -586,19 +602,19 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
586
602
|
res.json({
|
|
587
603
|
agentId,
|
|
588
604
|
model,
|
|
589
|
-
displayName: model ?
|
|
605
|
+
displayName: model ? toModelDisplayName(model) : null,
|
|
590
606
|
});
|
|
591
607
|
};
|
|
592
608
|
this.route(router, {
|
|
593
609
|
name: "defaultModel",
|
|
594
610
|
method: "get",
|
|
595
|
-
path:
|
|
611
|
+
path: MASTRA_ROUTES.defaultModel,
|
|
596
612
|
handler: handleDefaultModel,
|
|
597
613
|
});
|
|
598
614
|
this.route(router, {
|
|
599
615
|
name: "defaultModelByAgent",
|
|
600
616
|
method: "get",
|
|
601
|
-
path: `${
|
|
617
|
+
path: `${MASTRA_ROUTES.defaultModel}/:agentId`,
|
|
602
618
|
handler: handleDefaultModel,
|
|
603
619
|
});
|
|
604
620
|
}
|
|
@@ -663,10 +679,10 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
663
679
|
this.route(router, {
|
|
664
680
|
name: "embed",
|
|
665
681
|
method: "get",
|
|
666
|
-
path: `${
|
|
682
|
+
path: `${MASTRA_ROUTES.embed}/:type/:id`,
|
|
667
683
|
handler: async (req, res) => {
|
|
668
|
-
const type =
|
|
669
|
-
const id =
|
|
684
|
+
const type = firstNonEmpty(req.params.type) ?? "";
|
|
685
|
+
const id = firstNonEmpty(req.params.id);
|
|
670
686
|
const resolve = embedResolvers[type];
|
|
671
687
|
if (!resolve) {
|
|
672
688
|
this.logger.warn("embed:unsupported", {
|
|
@@ -747,7 +763,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
747
763
|
// the upstream status. Log and degrade.
|
|
748
764
|
this.logger.warn("suggestions:error", {
|
|
749
765
|
status: result.status,
|
|
750
|
-
error:
|
|
766
|
+
error: toError(result.message),
|
|
751
767
|
});
|
|
752
768
|
res.json({ questions: [] });
|
|
753
769
|
return;
|
|
@@ -757,13 +773,13 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
757
773
|
this.route(router, {
|
|
758
774
|
name: "suggestions",
|
|
759
775
|
method: "get",
|
|
760
|
-
path:
|
|
776
|
+
path: MASTRA_ROUTES.suggestions,
|
|
761
777
|
handler: handleSuggestions,
|
|
762
778
|
});
|
|
763
779
|
this.route(router, {
|
|
764
780
|
name: "suggestionsByAgent",
|
|
765
781
|
method: "get",
|
|
766
|
-
path: `${
|
|
782
|
+
path: `${MASTRA_ROUTES.suggestions}/:agentId`,
|
|
767
783
|
handler: handleSuggestions,
|
|
768
784
|
});
|
|
769
785
|
}
|
|
@@ -776,11 +792,11 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
776
792
|
* written to Mastra Memory.
|
|
777
793
|
*/
|
|
778
794
|
private registerGenieChatRoutes(router: IAppRouter): void {
|
|
779
|
-
const path = (...parts: string[]) =>
|
|
780
|
-
const { chat: chatSegment, messages, suggestions, threads } =
|
|
795
|
+
const path = (...parts: string[]) => genieRoutePath(":alias", ...parts);
|
|
796
|
+
const { chat: chatSegment, messages, suggestions, threads } = MASTRA_ROUTES;
|
|
781
797
|
/** Resolve the route's alias, answering 404 when no such space is configured. */
|
|
782
798
|
const spaceFor = (req: express.Request, res: express.Response): GenieChatSpace | undefined => {
|
|
783
|
-
const alias =
|
|
799
|
+
const alias = firstNonEmpty(req.params.alias) ?? "";
|
|
784
800
|
const configured = resolveGenieSpaces(this.config, this.context)[alias];
|
|
785
801
|
if (configured) return { alias, spaceId: configured.spaceId };
|
|
786
802
|
res.status(404).json({ error: `Unknown Genie space alias "${alias}"` });
|
|
@@ -800,7 +816,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
800
816
|
handler: async (req, res) => {
|
|
801
817
|
const space = spaceFor(req, res);
|
|
802
818
|
if (!space) return;
|
|
803
|
-
const parsed =
|
|
819
|
+
const parsed = GenieChatRequestSchema.safeParse(req.body);
|
|
804
820
|
if (!parsed.success) {
|
|
805
821
|
res
|
|
806
822
|
.status(400)
|
|
@@ -834,7 +850,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
834
850
|
handler: async (req, res) => {
|
|
835
851
|
const space = spaceFor(req, res);
|
|
836
852
|
if (!space) return;
|
|
837
|
-
const threadId =
|
|
853
|
+
const threadId = firstNonEmpty(req.params.threadId) ?? "";
|
|
838
854
|
const result = await this.asUser(req).genieConversationRead((client) =>
|
|
839
855
|
listGenieThreadMessages({
|
|
840
856
|
client,
|
|
@@ -856,7 +872,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
856
872
|
handler: async (req, res) => {
|
|
857
873
|
const space = spaceFor(req, res);
|
|
858
874
|
if (!space) return;
|
|
859
|
-
const threadId =
|
|
875
|
+
const threadId = firstNonEmpty(req.params.threadId) ?? "";
|
|
860
876
|
const result = await this.asUser(req).genieConversationWrite((client) =>
|
|
861
877
|
deleteGenieThread(client, space, threadId),
|
|
862
878
|
);
|
|
@@ -879,8 +895,8 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
879
895
|
handler: async (req, res) => {
|
|
880
896
|
const space = spaceFor(req, res);
|
|
881
897
|
if (!space) return;
|
|
882
|
-
const threadId =
|
|
883
|
-
const messageId =
|
|
898
|
+
const threadId = firstNonEmpty(req.params.threadId) ?? "";
|
|
899
|
+
const messageId = firstNonEmpty(req.params.messageId) ?? "";
|
|
884
900
|
const result = await this.asUser(req).genieConversationWrite((client) =>
|
|
885
901
|
deleteGenieThreadMessage(client, space, threadId, messageId),
|
|
886
902
|
);
|
|
@@ -973,14 +989,14 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
973
989
|
this.route(router, {
|
|
974
990
|
name: "feedback",
|
|
975
991
|
method: "post",
|
|
976
|
-
path:
|
|
992
|
+
path: MASTRA_ROUTES.feedback,
|
|
977
993
|
handler: async (req, res) => {
|
|
978
994
|
const mode = this.feedbackMode();
|
|
979
995
|
if (mode === "none") {
|
|
980
996
|
res.status(404).json({ ok: false });
|
|
981
997
|
return;
|
|
982
998
|
}
|
|
983
|
-
const parsed =
|
|
999
|
+
const parsed = MastraFeedbackRequestSchema.safeParse(req.body);
|
|
984
1000
|
if (!parsed.success) {
|
|
985
1001
|
// A Zod issue string quotes the received body back, so only the
|
|
986
1002
|
// offending field names travel; the full issue list is logged.
|
|
@@ -1024,7 +1040,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
1024
1040
|
this.route(router, {
|
|
1025
1041
|
name: "mlflowExperiment",
|
|
1026
1042
|
method: "get",
|
|
1027
|
-
path:
|
|
1043
|
+
path: MASTRA_ROUTES.mlflowExperiment,
|
|
1028
1044
|
handler: async (req, res) => {
|
|
1029
1045
|
if (this.feedbackMode() !== "mlflow") {
|
|
1030
1046
|
res.json({ url: null });
|
|
@@ -1088,7 +1104,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
1088
1104
|
): void {
|
|
1089
1105
|
this.logger.warn(`${operation}:error`, {
|
|
1090
1106
|
status: result.status,
|
|
1091
|
-
error:
|
|
1107
|
+
error: toError(result.message),
|
|
1092
1108
|
});
|
|
1093
1109
|
if (res.headersSent) return;
|
|
1094
1110
|
res.status(result.status).json({ error: clientMessage });
|
|
@@ -1150,7 +1166,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
1150
1166
|
if (Object.keys(spaces).length === 0) return { ok: true, data: [] };
|
|
1151
1167
|
const client = getExecutionContext().client;
|
|
1152
1168
|
return this.execute((executeSignal) => {
|
|
1153
|
-
const combined =
|
|
1169
|
+
const combined = combineAbortSignals(signal, executeSignal);
|
|
1154
1170
|
return collectSpaceSuggestions({
|
|
1155
1171
|
spaces,
|
|
1156
1172
|
client,
|
|
@@ -1168,7 +1184,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
1168
1184
|
* (see {@link logFeedback} in `./mlflow.js`).
|
|
1169
1185
|
*/
|
|
1170
1186
|
private async logFeedback(
|
|
1171
|
-
feedback:
|
|
1187
|
+
feedback: MlflowFeedbackRequest,
|
|
1172
1188
|
): Promise<ExecutionResult<string | undefined>> {
|
|
1173
1189
|
const ctx = getExecutionContext();
|
|
1174
1190
|
const sourceId =
|
|
@@ -1188,7 +1204,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
1188
1204
|
}
|
|
1189
1205
|
|
|
1190
1206
|
/** Send Agent Mode rating and comment directly to the originating Genie message. */
|
|
1191
|
-
private sendGenieFeedback(input:
|
|
1207
|
+
private sendGenieFeedback(input: GenieFeedbackRequest): Promise<ExecutionResult<void>> {
|
|
1192
1208
|
const client = getExecutionContext().client;
|
|
1193
1209
|
return this.execute(
|
|
1194
1210
|
(signal) =>
|
|
@@ -1238,7 +1254,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
1238
1254
|
const limit = Math.min(options.limit ?? STATEMENT_ROW_CAP, STATEMENT_ROW_CAP);
|
|
1239
1255
|
return this.execute(
|
|
1240
1256
|
async (executeSignal) => {
|
|
1241
|
-
const combined =
|
|
1257
|
+
const combined = combineAbortSignals(options.signal, executeSignal);
|
|
1242
1258
|
try {
|
|
1243
1259
|
const { data, visualization } = await fetchStatementEmbedData(client, statementId, {
|
|
1244
1260
|
limit,
|
|
@@ -1254,7 +1270,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
1254
1270
|
} catch (err) {
|
|
1255
1271
|
// The Databricks SDK throws on 404; surface as `undefined`
|
|
1256
1272
|
// so the route maps to a clean HTTP 404 instead of a 500.
|
|
1257
|
-
if (
|
|
1273
|
+
if (errorContext(err).notAccessible) return undefined;
|
|
1258
1274
|
throw err;
|
|
1259
1275
|
}
|
|
1260
1276
|
},
|
|
@@ -1298,7 +1314,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
1298
1314
|
fetchChart(chartId, {
|
|
1299
1315
|
userKey,
|
|
1300
1316
|
...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),
|
|
1301
|
-
signal:
|
|
1317
|
+
signal: combineAbortSignals(options.signal, executeSignal) ?? options.signal,
|
|
1302
1318
|
}),
|
|
1303
1319
|
chartFetchDefaults,
|
|
1304
1320
|
);
|
|
@@ -1333,7 +1349,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
1333
1349
|
if (result.ok) return result.data;
|
|
1334
1350
|
this.logger.warn("listModels:error", {
|
|
1335
1351
|
status: result.status,
|
|
1336
|
-
error:
|
|
1352
|
+
error: toError(result.message),
|
|
1337
1353
|
});
|
|
1338
1354
|
throw new ExecutionError(MODEL_CATALOGUE_FAILED_MESSAGE);
|
|
1339
1355
|
}
|
|
@@ -1341,7 +1357,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
1341
1357
|
private async buildAgentAndServer(): Promise<void> {
|
|
1342
1358
|
const memoryPool = needsLakebase(this.config)
|
|
1343
1359
|
? createMastraLakebasePool(
|
|
1344
|
-
|
|
1360
|
+
require(this.context, lakebase, this.config).exports().getPgConfig(),
|
|
1345
1361
|
)
|
|
1346
1362
|
: undefined;
|
|
1347
1363
|
const memoryBuilder = createMemoryBuilder(this.config, memoryPool);
|
|
@@ -1398,15 +1414,13 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
1398
1414
|
// `agent.resumeStream()` errors with "could not find a suspended
|
|
1399
1415
|
// run" and the approval UI hangs after the user clicks Approve.
|
|
1400
1416
|
const instanceStorage = memoryBuilder?.instanceStorage();
|
|
1401
|
-
// Wire Mastra's tracer into
|
|
1402
|
-
//
|
|
1403
|
-
//
|
|
1404
|
-
// `createApp`, so the OTLP endpoint / headers / sampling are
|
|
1405
|
-
// env-driven and shared with every other AppKit plugin.
|
|
1417
|
+
// Wire Mastra's tracer into OTel through `@mastra/otel-bridge`. Deployed
|
|
1418
|
+
// Apps use the provider AppKit registered during `createApp`; local direct
|
|
1419
|
+
// MLflow tracing uses its own global provider when no OTLP exporter exists.
|
|
1406
1420
|
const observability = await buildObservability({
|
|
1407
1421
|
serviceName: this.name,
|
|
1408
1422
|
enabled: this.config.observability,
|
|
1409
|
-
tracerProvider: await
|
|
1423
|
+
tracerProvider: await deferredNativeTracerProvider(),
|
|
1410
1424
|
});
|
|
1411
1425
|
// Optional MCP exposure: build a Mastra MCP server from the
|
|
1412
1426
|
// registered agents (and, opt-in, the ambient tools) and register
|
|
@@ -1491,7 +1505,7 @@ type EmbedResolver = (
|
|
|
1491
1505
|
function parseTimeoutMs(raw: unknown): number | undefined {
|
|
1492
1506
|
const v = Array.isArray(raw) ? raw[0] : raw;
|
|
1493
1507
|
if (typeof v !== "string") return undefined;
|
|
1494
|
-
const n =
|
|
1508
|
+
const n = toNumber(v);
|
|
1495
1509
|
if (n === undefined || n <= 0) return undefined;
|
|
1496
1510
|
return Math.min(Math.floor(n), MAX_EMBED_POLL_TIMEOUT_MS);
|
|
1497
1511
|
}
|
|
@@ -1506,7 +1520,7 @@ function parseTimeoutMs(raw: unknown): number | undefined {
|
|
|
1506
1520
|
function parseStatementLimit(raw: unknown): number | undefined {
|
|
1507
1521
|
const v = Array.isArray(raw) ? raw[0] : raw;
|
|
1508
1522
|
if (typeof v !== "string") return undefined;
|
|
1509
|
-
const n =
|
|
1523
|
+
const n = toNumber(v);
|
|
1510
1524
|
if (n === undefined || n < 0) return undefined;
|
|
1511
1525
|
return Math.floor(n);
|
|
1512
1526
|
}
|