@dbx-tools/appkit-mastra 0.9.93 → 0.9.95
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 +85 -40
- package/index.ts +4 -10
- package/lib/index.d.ts +4 -10
- package/lib/index.js +4 -8
- package/lib/src/agents.js +11 -23
- package/lib/src/chat.js +20 -1
- package/lib/src/config.d.ts +9 -11
- package/lib/src/config.js +7 -7
- package/lib/src/filesystems.d.ts +20 -2
- package/lib/src/filesystems.js +29 -2
- package/lib/src/plugin.js +3 -2
- package/lib/src/remote-skills.d.ts +3 -4
- package/lib/src/remote-skills.js +5 -14
- package/lib/src/server.d.ts +7 -0
- package/lib/src/server.js +33 -2
- package/lib/src/skill-paths.d.ts +8 -4
- package/lib/src/skill-paths.js +12 -6
- package/lib/src/workspaces.d.ts +39 -33
- package/lib/src/workspaces.js +208 -168
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -30
- package/src/agents.ts +11 -24
- package/src/chat.ts +24 -0
- package/src/config.ts +15 -17
- package/src/filesystems.ts +43 -0
- package/src/plugin.ts +2 -0
- package/src/remote-skills.ts +5 -15
- package/src/server.ts +33 -1
- package/src/skill-paths.ts +13 -5
- package/src/workspaces.ts +285 -210
- package/lib/src/skill-cache.d.ts +0 -94
- package/lib/src/skill-cache.js +0 -251
- package/lib/src/skill-search.d.ts +0 -30
- package/lib/src/skill-search.js +0 -171
- package/src/skill-cache.ts +0 -347
- package/src/skill-search.ts +0 -203
package/lib/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/agents.ts","../src/chart.ts","../src/chat.ts","../src/config.ts","../src/defaults.ts","../src/evaluation.ts","../src/filesystems.ts","../src/genie.ts","../src/identity.ts","../src/mcp.ts","../src/memory.ts","../src/mlflow.ts","../src/model.ts","../src/monty-sandbox.ts","../src/observability.ts","../src/openapi-tool.ts","../src/plugin.ts","../src/processors.ts","../src/remote-skills.ts","../src/rest.ts","../src/sandbox.ts","../src/server.ts","../src/serving-sanitize.ts","../src/serving.ts","../src/skill-
|
|
1
|
+
{"root":["../src/agents.ts","../src/chart.ts","../src/chat.ts","../src/config.ts","../src/defaults.ts","../src/evaluation.ts","../src/filesystems.ts","../src/genie.ts","../src/identity.ts","../src/mcp.ts","../src/memory.ts","../src/mlflow.ts","../src/model.ts","../src/monty-sandbox.ts","../src/observability.ts","../src/openapi-tool.ts","../src/plugin.ts","../src/processors.ts","../src/remote-skills.ts","../src/rest.ts","../src/sandbox.ts","../src/server.ts","../src/serving-sanitize.ts","../src/serving.ts","../src/skill-paths.ts","../src/statement.ts","../src/storage-schema.ts","../src/style.ts","../src/summarize.ts","../src/telemetry.ts","../src/trace-attributes.ts","../src/validation.ts","../src/workspaces.ts","../src/writer.ts","../index.ts"],"version":"5.9.3"}
|
package/package.json
CHANGED
|
@@ -34,19 +34,19 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@databricks/appkit": "0.81.0",
|
|
37
|
-
"@dbx-tools/appkit": "^0.9.
|
|
38
|
-
"@dbx-tools/core": "^0.9.
|
|
39
|
-
"@dbx-tools/databricks": "^0.9.
|
|
40
|
-
"@dbx-tools/fs": "^0.9.
|
|
41
|
-
"@dbx-tools/genie": "^0.9.
|
|
42
|
-
"@dbx-tools/model": "^0.9.
|
|
43
|
-
"@dbx-tools/path": "^0.9.
|
|
44
|
-
"@dbx-tools/postgres": "^0.9.
|
|
45
|
-
"@dbx-tools/shared-core": "^0.9.
|
|
46
|
-
"@dbx-tools/shared-fs": "^0.9.
|
|
47
|
-
"@dbx-tools/shared-genie": "^0.9.
|
|
48
|
-
"@dbx-tools/shared-mastra": "^0.9.
|
|
49
|
-
"@dbx-tools/shared-model": "^0.9.
|
|
37
|
+
"@dbx-tools/appkit": "^0.9.95",
|
|
38
|
+
"@dbx-tools/core": "^0.9.95",
|
|
39
|
+
"@dbx-tools/databricks": "^0.9.95",
|
|
40
|
+
"@dbx-tools/fs": "^0.9.95",
|
|
41
|
+
"@dbx-tools/genie": "^0.9.95",
|
|
42
|
+
"@dbx-tools/model": "^0.9.95",
|
|
43
|
+
"@dbx-tools/path": "^0.9.95",
|
|
44
|
+
"@dbx-tools/postgres": "^0.9.95",
|
|
45
|
+
"@dbx-tools/shared-core": "^0.9.95",
|
|
46
|
+
"@dbx-tools/shared-fs": "^0.9.95",
|
|
47
|
+
"@dbx-tools/shared-genie": "^0.9.95",
|
|
48
|
+
"@dbx-tools/shared-mastra": "^0.9.95",
|
|
49
|
+
"@dbx-tools/shared-model": "^0.9.95",
|
|
50
50
|
"@mastra/ai-sdk": "1.10.5",
|
|
51
51
|
"@mastra/core": "1.71.0",
|
|
52
52
|
"@mastra/express": "1.5.15",
|
|
@@ -176,18 +176,10 @@
|
|
|
176
176
|
"types": "./lib/src/serving.d.ts",
|
|
177
177
|
"default": "./lib/src/serving.js"
|
|
178
178
|
},
|
|
179
|
-
"./skill-cache": {
|
|
180
|
-
"types": "./lib/src/skill-cache.d.ts",
|
|
181
|
-
"default": "./lib/src/skill-cache.js"
|
|
182
|
-
},
|
|
183
179
|
"./skill-paths": {
|
|
184
180
|
"types": "./lib/src/skill-paths.d.ts",
|
|
185
181
|
"default": "./lib/src/skill-paths.js"
|
|
186
182
|
},
|
|
187
|
-
"./skill-search": {
|
|
188
|
-
"types": "./lib/src/skill-search.d.ts",
|
|
189
|
-
"default": "./lib/src/skill-search.js"
|
|
190
|
-
},
|
|
191
183
|
"./statement": {
|
|
192
184
|
"types": "./lib/src/statement.d.ts",
|
|
193
185
|
"default": "./lib/src/statement.js"
|
|
@@ -227,7 +219,7 @@
|
|
|
227
219
|
"./package.json": "./package.json"
|
|
228
220
|
}
|
|
229
221
|
},
|
|
230
|
-
"version": "0.9.
|
|
222
|
+
"version": "0.9.95",
|
|
231
223
|
"types": "./lib/index.d.ts",
|
|
232
224
|
"dbxToolsConfig": {
|
|
233
225
|
"tags": [
|
|
@@ -336,18 +328,10 @@
|
|
|
336
328
|
"types": "./lib/src/serving.d.ts",
|
|
337
329
|
"default": "./lib/src/serving.js"
|
|
338
330
|
},
|
|
339
|
-
"./skill-cache": {
|
|
340
|
-
"types": "./lib/src/skill-cache.d.ts",
|
|
341
|
-
"default": "./lib/src/skill-cache.js"
|
|
342
|
-
},
|
|
343
331
|
"./skill-paths": {
|
|
344
332
|
"types": "./lib/src/skill-paths.d.ts",
|
|
345
333
|
"default": "./lib/src/skill-paths.js"
|
|
346
334
|
},
|
|
347
|
-
"./skill-search": {
|
|
348
|
-
"types": "./lib/src/skill-search.d.ts",
|
|
349
|
-
"default": "./lib/src/skill-search.js"
|
|
350
|
-
},
|
|
351
335
|
"./statement": {
|
|
352
336
|
"types": "./lib/src/statement.d.ts",
|
|
353
337
|
"default": "./lib/src/statement.js"
|
package/src/agents.ts
CHANGED
|
@@ -49,10 +49,9 @@ import type { MemoryBuilder } from "./memory.ts";
|
|
|
49
49
|
import { buildModel, RESPONSES_PROVIDER_OPTIONS } from "./model.ts";
|
|
50
50
|
import { stripStaleChartsProcessor } from "./processors.ts";
|
|
51
51
|
import { MASTRA_RESOLVED_MODEL_KEY } from "./serving.ts";
|
|
52
|
-
import { CatalogueSkillSearchProcessor } from "./skill-search.ts";
|
|
53
52
|
import { TYPOGRAPHY_RULE } from "./style.ts";
|
|
54
53
|
import { buildSummarizeTool } from "./summarize.ts";
|
|
55
|
-
import { createWorkspace
|
|
54
|
+
import { createWorkspace } from "./workspaces.ts";
|
|
56
55
|
|
|
57
56
|
/**
|
|
58
57
|
* Tool record accepted by every Mastra `Agent.tools` field and by the
|
|
@@ -188,16 +187,16 @@ export function createAgent<
|
|
|
188
187
|
* options, so {@link buildAgents} may rebuild it with startup-provisioned
|
|
189
188
|
* `extraSkillPaths` (a caller-supplied workspace is never touched).
|
|
190
189
|
*/
|
|
191
|
-
const
|
|
190
|
+
const defaultWorkspaces = new WeakSet<Workspace>();
|
|
192
191
|
|
|
193
192
|
/** Brand `workspace` as the auto-created default. */
|
|
194
193
|
function markDefaultWorkspace(workspace: Workspace): void {
|
|
195
|
-
(workspace
|
|
194
|
+
defaultWorkspaces.add(workspace);
|
|
196
195
|
}
|
|
197
196
|
|
|
198
197
|
/** Whether `workspace` was auto-created by {@link createAgent}. */
|
|
199
198
|
function isDefaultWorkspace(workspace: Workspace | undefined): boolean {
|
|
200
|
-
return
|
|
199
|
+
return workspace !== undefined && defaultWorkspaces.has(workspace);
|
|
201
200
|
}
|
|
202
201
|
|
|
203
202
|
/**
|
|
@@ -577,14 +576,14 @@ export async function buildAgents(opts: {
|
|
|
577
576
|
(def.workspace === undefined && !workspace) ||
|
|
578
577
|
((extraSkillPaths?.length ||
|
|
579
578
|
config.sandbox !== undefined ||
|
|
580
|
-
config.
|
|
579
|
+
config.workspaceTools !== undefined ||
|
|
580
|
+
context !== undefined) &&
|
|
581
581
|
isDefaultWorkspace(workspace))
|
|
582
582
|
) {
|
|
583
583
|
workspace = createWorkspace({
|
|
584
584
|
extraSkillPaths,
|
|
585
|
-
...(config.
|
|
586
|
-
|
|
587
|
-
: {}),
|
|
585
|
+
...(config.workspaceTools !== undefined ? { tools: config.workspaceTools } : {}),
|
|
586
|
+
pluginContext: context,
|
|
588
587
|
sandbox: config.sandbox === true ? "databricks" : config.sandbox,
|
|
589
588
|
});
|
|
590
589
|
markDefaultWorkspace(workspace);
|
|
@@ -668,21 +667,9 @@ function toolErrorLoggingProcessor(logger: log.Logger): OutputProcessor {
|
|
|
668
667
|
function workspaceSkillInputProcessors(
|
|
669
668
|
workspace: Workspace | undefined,
|
|
670
669
|
config: MastraPluginConfig,
|
|
671
|
-
):
|
|
672
|
-
if (!workspace || config.
|
|
673
|
-
const options =
|
|
674
|
-
typeof config.workspaceSkillSearch === "object" ? config.workspaceSkillSearch : undefined;
|
|
675
|
-
const catalogue = workspaceSkillCatalogueResolver(workspace);
|
|
676
|
-
if (catalogue) {
|
|
677
|
-
return [
|
|
678
|
-
new CatalogueSkillSearchProcessor({
|
|
679
|
-
resolve: catalogue,
|
|
680
|
-
topK: options?.topK ?? 5,
|
|
681
|
-
minScore: options?.minScore ?? 0.1,
|
|
682
|
-
...(options?.ttlMs !== undefined ? { ttlMs: options.ttlMs } : {}),
|
|
683
|
-
}),
|
|
684
|
-
];
|
|
685
|
-
}
|
|
670
|
+
): SkillSearchProcessor[] {
|
|
671
|
+
if (!workspace || config.workspaceSkills === false) return [];
|
|
672
|
+
const options = typeof config.workspaceSkills === "object" ? config.workspaceSkills : undefined;
|
|
686
673
|
if (!workspace.skills) return [];
|
|
687
674
|
return [
|
|
688
675
|
new SkillSearchProcessor({
|
package/src/chat.ts
CHANGED
|
@@ -4,9 +4,16 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { errorUtils, log } from "@dbx-tools/shared-core";
|
|
7
8
|
import { routes } from "@dbx-tools/shared-mastra";
|
|
9
|
+
import {
|
|
10
|
+
isStaleMastraResumeError,
|
|
11
|
+
STALE_MASTRA_RESUME_STREAM_TEXT,
|
|
12
|
+
} from "@dbx-tools/shared-mastra/resume";
|
|
8
13
|
import { chatRoute } from "@mastra/ai-sdk";
|
|
9
14
|
|
|
15
|
+
const logger = log.logger("mastra/chat");
|
|
16
|
+
|
|
10
17
|
/** Register the official AI SDK chat stream plus its approval continuation. */
|
|
11
18
|
export function agentChatRoutes() {
|
|
12
19
|
const path = `${routes.MASTRA_ROUTES.chat}/:agentId` as `${string}:agentId`;
|
|
@@ -15,6 +22,23 @@ export function agentChatRoutes() {
|
|
|
15
22
|
path,
|
|
16
23
|
sendReasoning: true,
|
|
17
24
|
sendSources: true,
|
|
25
|
+
onError: serializeChatStreamError,
|
|
18
26
|
}),
|
|
19
27
|
];
|
|
20
28
|
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Keep a late or duplicate resume from failing the UI stream. Mastra's
|
|
32
|
+
* `chatRoute` already swallows a couple of resume ids on the v6 approval
|
|
33
|
+
* path; this covers the generic workflow errors `consumeStream` still
|
|
34
|
+
* surfaces on v5.
|
|
35
|
+
*/
|
|
36
|
+
function serializeChatStreamError(error: unknown): string {
|
|
37
|
+
if (isStaleMastraResumeError(error)) {
|
|
38
|
+
logger.warn("ignored stale mastra resume", {
|
|
39
|
+
error: errorUtils.errorMessage(error),
|
|
40
|
+
});
|
|
41
|
+
return STALE_MASTRA_RESUME_STREAM_TEXT;
|
|
42
|
+
}
|
|
43
|
+
return errorUtils.errorMessage(error);
|
|
44
|
+
}
|
package/src/config.ts
CHANGED
|
@@ -20,6 +20,7 @@ import type { BrandContext } from "@dbx-tools/shared-core";
|
|
|
20
20
|
import type { AgentConfig } from "@mastra/core/agent";
|
|
21
21
|
import type { RequestContext } from "@mastra/core/request-context";
|
|
22
22
|
import { MASTRA_RESOURCE_ID_KEY, MASTRA_THREAD_ID_KEY } from "@mastra/core/request-context";
|
|
23
|
+
import type { WorkspaceToolsConfig } from "@mastra/core/workspace";
|
|
23
24
|
import type { PgVectorConfig, PostgresStoreConfig } from "@mastra/pg";
|
|
24
25
|
|
|
25
26
|
import type { AnyMastraAgentDefinition, MastraTools } from "./agents.ts";
|
|
@@ -147,8 +148,8 @@ export type MastraMemoryConfig = PgVectorConfig & {
|
|
|
147
148
|
id?: string;
|
|
148
149
|
};
|
|
149
150
|
|
|
150
|
-
/**
|
|
151
|
-
export interface
|
|
151
|
+
/** Mastra native workspace skill-search configuration. */
|
|
152
|
+
export interface MastraWorkspaceSkillsConfig {
|
|
152
153
|
/** Maximum skill matches returned by one search. Defaults to 5. */
|
|
153
154
|
topK?: number;
|
|
154
155
|
/** Minimum BM25 relevance score. Defaults to 0.1. */
|
|
@@ -217,16 +218,13 @@ export interface MastraPluginConfig extends BasePluginConfig {
|
|
|
217
218
|
* custom `workspace` keeps that workspace and its sandbox.
|
|
218
219
|
*/
|
|
219
220
|
sandbox?: boolean | "databricks" | "monty" | DatabricksWorkspaceSandboxOptions;
|
|
221
|
+
/** Native Mastra workspace tool availability, approval, and hook configuration. */
|
|
222
|
+
workspaceTools?: WorkspaceToolsConfig;
|
|
220
223
|
/**
|
|
221
|
-
*
|
|
222
|
-
*
|
|
224
|
+
* Use Mastra's native workspace skill manager. Defaults to true. Pass an
|
|
225
|
+
* object to tune on-demand discovery and loaded-skill state.
|
|
223
226
|
*/
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Use dbx-tools catalogue-backed on-demand skill search. Defaults to true.
|
|
227
|
-
* Pass an object to tune search.
|
|
228
|
-
*/
|
|
229
|
-
workspaceSkillSearch?: boolean | MastraSkillSearchConfig;
|
|
227
|
+
workspaceSkills?: boolean | MastraWorkspaceSkillsConfig;
|
|
230
228
|
/**
|
|
231
229
|
* Code-defined agents. Accepts three shapes for convenience:
|
|
232
230
|
*
|
|
@@ -613,7 +611,7 @@ export interface MastraPluginConfig extends BasePluginConfig {
|
|
|
613
611
|
* through neither fails startup unless `failOnError: false`.
|
|
614
612
|
*
|
|
615
613
|
* Provisioned skills are written to the Databricks user's Assistant skills
|
|
616
|
-
* folder (`/Users/<email>/.assistant/skills`, the
|
|
614
|
+
* folder (`/Workspace/Users/<email>/.assistant/skills`, the personal skill
|
|
617
615
|
* target) so they persist and are picked up by the built-in Assistant-skills
|
|
618
616
|
* mount. With no writable workspace, they go to a local temp dir instead.
|
|
619
617
|
*
|
|
@@ -667,15 +665,15 @@ export const MASTRA_CONFIG_SCHEMA: ConfigSchema = {
|
|
|
667
665
|
description:
|
|
668
666
|
'Command sandbox for auto-created agent workspaces. Defaults to Monty; false disables command execution, and true, "databricks", or an object selects/configures Databricks Sandbox with optional fallback.',
|
|
669
667
|
},
|
|
670
|
-
|
|
671
|
-
type: "
|
|
668
|
+
workspaceSkills: {
|
|
669
|
+
type: ["boolean", "object"],
|
|
672
670
|
description:
|
|
673
|
-
"
|
|
671
|
+
"Use Mastra's native on-demand workspace skill search and writable skill saves. Defaults to true.",
|
|
674
672
|
},
|
|
675
|
-
|
|
676
|
-
type:
|
|
673
|
+
workspaceTools: {
|
|
674
|
+
type: "object",
|
|
677
675
|
description:
|
|
678
|
-
"
|
|
676
|
+
"Native Mastra workspace tool configuration for availability, approvals, read-before-write, output limits, and hooks.",
|
|
679
677
|
},
|
|
680
678
|
defaultAgent: {
|
|
681
679
|
type: "string",
|
package/src/filesystems.ts
CHANGED
|
@@ -22,12 +22,14 @@ import {
|
|
|
22
22
|
FileExistsError,
|
|
23
23
|
FileNotFoundError,
|
|
24
24
|
IsDirectoryError,
|
|
25
|
+
CompositeFilesystem,
|
|
25
26
|
MastraFilesystem,
|
|
26
27
|
NotDirectoryError,
|
|
27
28
|
PermissionError,
|
|
28
29
|
WorkspaceReadOnlyError,
|
|
29
30
|
} from "@mastra/core/workspace";
|
|
30
31
|
import type {
|
|
32
|
+
CompositeFilesystemConfig,
|
|
31
33
|
CopyOptions,
|
|
32
34
|
FileContent,
|
|
33
35
|
FileEntry,
|
|
@@ -49,6 +51,15 @@ export interface MastraFileSystemAdapterOptions extends MastraFilesystemOptions
|
|
|
49
51
|
/** Override the Mastra display name. Defaults to `MastraFileSystemAdapter`. */
|
|
50
52
|
name?: string;
|
|
51
53
|
|
|
54
|
+
/** Human-friendly mount name surfaced by composite filesystem listings. */
|
|
55
|
+
displayName?: string;
|
|
56
|
+
|
|
57
|
+
/** Mount description surfaced by composite filesystem listings and help. */
|
|
58
|
+
description?: string;
|
|
59
|
+
|
|
60
|
+
/** Replace the generated filesystem usage instructions. */
|
|
61
|
+
instructions?: string;
|
|
62
|
+
|
|
52
63
|
/**
|
|
53
64
|
* Override the Mastra provider id. Defaults to the source
|
|
54
65
|
* {@link FileSystem.backend}.
|
|
@@ -117,6 +128,14 @@ export class MastraFileSystemAdapter extends MastraFilesystem {
|
|
|
117
128
|
return this.options.provider ?? this.fs.backend;
|
|
118
129
|
}
|
|
119
130
|
|
|
131
|
+
get displayName(): string | undefined {
|
|
132
|
+
return this.options.displayName;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
get description(): string | undefined {
|
|
136
|
+
return this.options.description;
|
|
137
|
+
}
|
|
138
|
+
|
|
120
139
|
get readOnly(): boolean {
|
|
121
140
|
return this.options.readOnly === true || this.fs.readOnly;
|
|
122
141
|
}
|
|
@@ -145,7 +164,9 @@ export class MastraFileSystemAdapter extends MastraFilesystem {
|
|
|
145
164
|
}
|
|
146
165
|
|
|
147
166
|
getInstructions(): string {
|
|
167
|
+
if (this.options.instructions !== undefined) return this.options.instructions;
|
|
148
168
|
return [
|
|
169
|
+
...(this.description ? [this.description] : []),
|
|
149
170
|
`Files are served by a ${this.fs.backend} filesystem rooted at ${this.fs.root}.`,
|
|
150
171
|
"Workspace paths are absolute within this mount (for example `/notes/report.md`).",
|
|
151
172
|
].join(" ");
|
|
@@ -298,6 +319,28 @@ export class MastraFileSystemAdapter extends MastraFilesystem {
|
|
|
298
319
|
}
|
|
299
320
|
}
|
|
300
321
|
|
|
322
|
+
/**
|
|
323
|
+
* Composite mount namespace whose virtual root has no repository-level
|
|
324
|
+
* `.gitignore`. Mastra's list tool probes that relative file before walking;
|
|
325
|
+
* an empty result keeps native ignore handling enabled without routing the
|
|
326
|
+
* virtual-root lookup into an unrelated mount.
|
|
327
|
+
*/
|
|
328
|
+
export class MountedCompositeFilesystem extends CompositeFilesystem {
|
|
329
|
+
constructor(config: CompositeFilesystemConfig) {
|
|
330
|
+
super(config);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
override async readFile(inputPath: string, options?: ReadOptions): Promise<string | Buffer> {
|
|
334
|
+
if (
|
|
335
|
+
(inputPath === ".gitignore" || inputPath === "/.gitignore") &&
|
|
336
|
+
!this.getFilesystemForPath(inputPath)
|
|
337
|
+
) {
|
|
338
|
+
return options?.encoding ? "" : Buffer.alloc(0);
|
|
339
|
+
}
|
|
340
|
+
return super.readFile(inputPath, options);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
301
344
|
/** Fresh writable local temp mount on a root unique to this call. */
|
|
302
345
|
export function scratchFilesystem(): MastraFileSystemAdapter {
|
|
303
346
|
return filesystems(localFS.scratchFS("mastra"));
|
package/src/plugin.ts
CHANGED
|
@@ -111,6 +111,7 @@ import { buildObservability, configureOtelPropagation } from "./observability.ts
|
|
|
111
111
|
import { provisionRemoteSkills } from "./remote-skills.ts";
|
|
112
112
|
import {
|
|
113
113
|
attachRoutePatchMiddleware,
|
|
114
|
+
attachStaleResumeRecovery,
|
|
114
115
|
createRequestContext,
|
|
115
116
|
isMastraRequestAllowed,
|
|
116
117
|
MastraServer,
|
|
@@ -1185,6 +1186,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
1185
1186
|
customApiRoutes: agentChatRoutes(),
|
|
1186
1187
|
});
|
|
1187
1188
|
await this.mastraServer.init();
|
|
1189
|
+
attachStaleResumeRecovery(this.mastraApp);
|
|
1188
1190
|
this.logger.info("ready", {
|
|
1189
1191
|
agents: Object.keys(this.built.agents),
|
|
1190
1192
|
defaultAgent: this.built.defaultAgentId,
|
package/src/remote-skills.ts
CHANGED
|
@@ -36,10 +36,9 @@
|
|
|
36
36
|
* Pass `refreshTtlMs: 0` to download on every boot.
|
|
37
37
|
*
|
|
38
38
|
* The default destination is the Databricks workspace Assistant skills tree
|
|
39
|
-
* (`/Workspace/.assistant/skills
|
|
40
|
-
* action writes to), so provisioned skills persist across restarts and are
|
|
39
|
+
* (`/Workspace/.assistant/skills`), so provisioned skills persist across restarts and are
|
|
41
40
|
* discovered by the built-in Assistant-skills mount. Pass `userEmail` (or an
|
|
42
|
-
* explicit `databricksBasePath`) to target `/Users/<email>/.assistant/skills`
|
|
41
|
+
* explicit `databricksBasePath`) to target `/Workspace/Users/<email>/.assistant/skills`
|
|
43
42
|
* instead. When no Databricks client is resolvable at startup - or the resolved
|
|
44
43
|
* identity cannot WRITE the destination, which is the normal case for a
|
|
45
44
|
* Databricks App service principal against the admin-owned shared tree (see
|
|
@@ -73,8 +72,7 @@ import {
|
|
|
73
72
|
import type { OneOrMany } from "@dbx-tools/shared-core";
|
|
74
73
|
import type { FileSystem } from "@dbx-tools/shared-fs";
|
|
75
74
|
|
|
76
|
-
import {
|
|
77
|
-
import { clearWorkspaceSkillCache } from "./skill-cache.ts";
|
|
75
|
+
import { ORGANIZATION_SKILLS_PATH, personalSkillsPath } from "./skill-paths.ts";
|
|
78
76
|
|
|
79
77
|
const logger = log.logger("mastra/remote-skills");
|
|
80
78
|
|
|
@@ -208,7 +206,7 @@ export interface ProvisionRemoteSkillsOptions {
|
|
|
208
206
|
failOnError?: boolean;
|
|
209
207
|
/**
|
|
210
208
|
* Absolute Databricks path that roots the destination Assistant skills tree.
|
|
211
|
-
* Defaults to the OBO user's `/Users/<email>/.assistant/skills`.
|
|
209
|
+
* Defaults to the OBO user's `/Workspace/Users/<email>/.assistant/skills`.
|
|
212
210
|
*/
|
|
213
211
|
databricksBasePath?: string;
|
|
214
212
|
/** Auth-scoped Databricks client. Defaults to the AppKit execution context. */
|
|
@@ -442,7 +440,6 @@ export async function provisionRemoteSkills(
|
|
|
442
440
|
const localSkillPaths: string[] = [];
|
|
443
441
|
const skillNames: string[] = [];
|
|
444
442
|
let staging: LocalFileSystem | undefined;
|
|
445
|
-
let workspaceUpdated = false;
|
|
446
443
|
|
|
447
444
|
try {
|
|
448
445
|
const sources = Array.isArray(options.sources) ? options.sources : [options.sources];
|
|
@@ -491,7 +488,6 @@ export async function provisionRemoteSkills(
|
|
|
491
488
|
// Only after the copy lands: a metadata entry written first would
|
|
492
489
|
// mark a failed provision as fresh and suppress the retry for a day.
|
|
493
490
|
await writeMetadata(destination, key, record);
|
|
494
|
-
workspaceUpdated = true;
|
|
495
491
|
} else {
|
|
496
492
|
localSkillPaths.push(await persistLocally(key, staged, record));
|
|
497
493
|
}
|
|
@@ -520,12 +516,6 @@ export async function provisionRemoteSkills(
|
|
|
520
516
|
}
|
|
521
517
|
}
|
|
522
518
|
|
|
523
|
-
if (workspaceUpdated && client?.config?.getHost) {
|
|
524
|
-
await clearWorkspaceSkillCache({
|
|
525
|
-
host: (await client.config.getHost()).toString(),
|
|
526
|
-
});
|
|
527
|
-
}
|
|
528
|
-
|
|
529
519
|
return { localSkillPaths, databricksBasePath, skillNames };
|
|
530
520
|
}
|
|
531
521
|
|
|
@@ -603,7 +593,7 @@ function resolveDatabricksBasePath(
|
|
|
603
593
|
// A named user targets their personal Assistant tree (the "save a skill"
|
|
604
594
|
// target); otherwise the shared workspace Assistant tree, which the built-in
|
|
605
595
|
// Assistant-skills mount already scans.
|
|
606
|
-
return email ?
|
|
596
|
+
return email ? personalSkillsPath(email) : ORGANIZATION_SKILLS_PATH;
|
|
607
597
|
}
|
|
608
598
|
|
|
609
599
|
/**
|
package/src/server.ts
CHANGED
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { getExecutionContext } from "@databricks/appkit";
|
|
9
|
-
import { hash, http, log, object, stringUtils, token } from "@dbx-tools/shared-core";
|
|
9
|
+
import { errorUtils, hash, http, log, object, stringUtils, token } from "@dbx-tools/shared-core";
|
|
10
10
|
import { feedback, thread } from "@dbx-tools/shared-mastra";
|
|
11
|
+
import { isStaleMastraResumeError } from "@dbx-tools/shared-mastra/resume";
|
|
11
12
|
import {
|
|
12
13
|
MASTRA_RESOURCE_ID_KEY,
|
|
13
14
|
MASTRA_THREAD_ID_KEY,
|
|
@@ -42,6 +43,7 @@ import { recordActiveTraceAuth, recordActiveTraceUser } from "./telemetry.ts";
|
|
|
42
43
|
* when no SDK is registered, which must never be surfaced as a trace to
|
|
43
44
|
* attach feedback to.
|
|
44
45
|
*/
|
|
46
|
+
const logger = log.logger("mastra/server");
|
|
45
47
|
const INVALID_TRACE_ID = "0".repeat(32);
|
|
46
48
|
const TRUSTED_REQUEST_CONTEXT_KEYS = [
|
|
47
49
|
MASTRA_RESOURCE_ID_KEY,
|
|
@@ -460,3 +462,33 @@ export function attachRoutePatchMiddleware(app: express.Express): void {
|
|
|
460
462
|
next();
|
|
461
463
|
});
|
|
462
464
|
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Finish a chat request when Mastra throws because the workflow is no
|
|
468
|
+
* longer suspended. Duplicate approve/resume and late `consumeStream`
|
|
469
|
+
* both hit that path; the client already has (or will reload) the
|
|
470
|
+
* completed turn.
|
|
471
|
+
*/
|
|
472
|
+
export function attachStaleResumeRecovery(app: express.Express): void {
|
|
473
|
+
app.use((error: unknown, req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
474
|
+
if (!isStaleMastraResumeError(error)) {
|
|
475
|
+
next(error);
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
logger.warn("ignored stale mastra resume", {
|
|
479
|
+
path: req.path,
|
|
480
|
+
error: errorUtils.errorMessage(error),
|
|
481
|
+
});
|
|
482
|
+
if (res.headersSent) {
|
|
483
|
+
res.end();
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
res.status(200);
|
|
487
|
+
res.setHeader("content-type", "text/event-stream; charset=utf-8");
|
|
488
|
+
res.setHeader("cache-control", "no-cache");
|
|
489
|
+
res.write(`data: ${JSON.stringify({ type: "start" })}\n\n`);
|
|
490
|
+
res.write(`data: ${JSON.stringify({ type: "finish" })}\n\n`);
|
|
491
|
+
res.write("data: [DONE]\n\n");
|
|
492
|
+
res.end();
|
|
493
|
+
});
|
|
494
|
+
}
|
package/src/skill-paths.ts
CHANGED
|
@@ -10,10 +10,18 @@
|
|
|
10
10
|
* @module
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
/**
|
|
14
|
-
export const
|
|
13
|
+
/** Organization Assistant root, mounted at its actual workspace path. */
|
|
14
|
+
export const ORGANIZATION_ASSISTANT_PATH = "/Workspace/.assistant";
|
|
15
15
|
|
|
16
|
-
/**
|
|
17
|
-
export
|
|
18
|
-
|
|
16
|
+
/** Organization skills tree, readable by everyone in the workspace. */
|
|
17
|
+
export const ORGANIZATION_SKILLS_PATH = `${ORGANIZATION_ASSISTANT_PATH}/skills`;
|
|
18
|
+
|
|
19
|
+
/** Workspace home root for one user. */
|
|
20
|
+
export function personalWorkspacePath(userEmail: string): string {
|
|
21
|
+
return `/Workspace/Users/${userEmail.trim()}`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Personal skills tree owned by one user. */
|
|
25
|
+
export function personalSkillsPath(userEmail: string): string {
|
|
26
|
+
return `${personalWorkspacePath(userEmail)}/.assistant/skills`;
|
|
19
27
|
}
|