@dbx-tools/appkit-mastra 0.9.95 → 0.9.99
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 +134 -103
- package/index.ts +3 -3
- package/lib/index.d.ts +3 -3
- package/lib/index.js +3 -3
- package/lib/src/agents.d.ts +3 -3
- package/lib/src/agents.js +9 -6
- package/lib/src/monty-sandbox.d.ts +4 -7
- package/lib/src/monty-sandbox.js +17 -28
- package/lib/src/openapi-tool.js +3 -12
- package/lib/src/server.js +1 -1
- package/lib/src/skill-paths.d.ts +1 -1
- package/lib/src/skill-paths.js +2 -2
- package/lib/src/workspaces.d.ts +53 -92
- package/lib/src/workspaces.js +303 -144
- package/package.json +14 -14
- package/src/agents.ts +8 -6
- package/src/monty-sandbox.ts +18 -29
- package/src/openapi-tool.ts +2 -11
- package/src/server.ts +22 -20
- package/src/skill-paths.ts +1 -1
- package/src/workspaces.ts +476 -215
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.99",
|
|
38
|
+
"@dbx-tools/core": "^0.9.99",
|
|
39
|
+
"@dbx-tools/databricks": "^0.9.99",
|
|
40
|
+
"@dbx-tools/fs": "^0.9.99",
|
|
41
|
+
"@dbx-tools/genie": "^0.9.99",
|
|
42
|
+
"@dbx-tools/model": "^0.9.99",
|
|
43
|
+
"@dbx-tools/path": "^0.9.99",
|
|
44
|
+
"@dbx-tools/postgres": "^0.9.99",
|
|
45
|
+
"@dbx-tools/shared-core": "^0.9.99",
|
|
46
|
+
"@dbx-tools/shared-fs": "^0.9.99",
|
|
47
|
+
"@dbx-tools/shared-genie": "^0.9.99",
|
|
48
|
+
"@dbx-tools/shared-mastra": "^0.9.99",
|
|
49
|
+
"@dbx-tools/shared-model": "^0.9.99",
|
|
50
50
|
"@mastra/ai-sdk": "1.10.5",
|
|
51
51
|
"@mastra/core": "1.71.0",
|
|
52
52
|
"@mastra/express": "1.5.15",
|
|
@@ -219,7 +219,7 @@
|
|
|
219
219
|
"./package.json": "./package.json"
|
|
220
220
|
}
|
|
221
221
|
},
|
|
222
|
-
"version": "0.9.
|
|
222
|
+
"version": "0.9.99",
|
|
223
223
|
"types": "./lib/index.d.ts",
|
|
224
224
|
"dbxToolsConfig": {
|
|
225
225
|
"tags": [
|
package/src/agents.ts
CHANGED
|
@@ -51,7 +51,7 @@ import { stripStaleChartsProcessor } from "./processors.ts";
|
|
|
51
51
|
import { MASTRA_RESOLVED_MODEL_KEY } from "./serving.ts";
|
|
52
52
|
import { TYPOGRAPHY_RULE } from "./style.ts";
|
|
53
53
|
import { buildSummarizeTool } from "./summarize.ts";
|
|
54
|
-
import {
|
|
54
|
+
import { bindDatabricksWorkspaceContext, databricksWorkspace } from "./workspaces.ts";
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
57
|
* Tool record accepted by every Mastra `Agent.tools` field and by the
|
|
@@ -168,8 +168,8 @@ function deriveToolId(description: string): string {
|
|
|
168
168
|
* ```
|
|
169
169
|
*
|
|
170
170
|
* Adds the package's default workspace when the definition omits one. That
|
|
171
|
-
* workspace carries Databricks skill mounts and
|
|
172
|
-
*
|
|
171
|
+
* workspace carries Databricks skill mounts and Monty command execution. An
|
|
172
|
+
* explicit workspace remains the caller's complete override.
|
|
173
173
|
*/
|
|
174
174
|
export function createAgent<
|
|
175
175
|
TRequestContext extends Record<string, unknown> | unknown = unknown,
|
|
@@ -177,7 +177,7 @@ export function createAgent<
|
|
|
177
177
|
MastraAgentDefinition<TRequestContext>,
|
|
178
178
|
>(def: TDefinition): TDefinition {
|
|
179
179
|
if (def.workspace) return { ...def };
|
|
180
|
-
const workspace =
|
|
180
|
+
const workspace = databricksWorkspace();
|
|
181
181
|
markDefaultWorkspace(workspace);
|
|
182
182
|
return { ...def, workspace };
|
|
183
183
|
}
|
|
@@ -338,7 +338,7 @@ export interface MastraAgentDefinition<
|
|
|
338
338
|
/**
|
|
339
339
|
* Mastra {@link Workspace} for this agent (filesystem, sandbox, or other
|
|
340
340
|
* providers). Assistant skills from Databricks workspace paths are wired
|
|
341
|
-
* via {@link
|
|
341
|
+
* via {@link databricksWorkspace}.
|
|
342
342
|
*/
|
|
343
343
|
workspace?: Workspace | MastraAgentWorkspaceResolver;
|
|
344
344
|
}
|
|
@@ -580,13 +580,15 @@ export async function buildAgents(opts: {
|
|
|
580
580
|
context !== undefined) &&
|
|
581
581
|
isDefaultWorkspace(workspace))
|
|
582
582
|
) {
|
|
583
|
-
workspace =
|
|
583
|
+
workspace = databricksWorkspace({
|
|
584
584
|
extraSkillPaths,
|
|
585
585
|
...(config.workspaceTools !== undefined ? { tools: config.workspaceTools } : {}),
|
|
586
586
|
pluginContext: context,
|
|
587
587
|
sandbox: config.sandbox === true ? "databricks" : config.sandbox,
|
|
588
588
|
});
|
|
589
589
|
markDefaultWorkspace(workspace);
|
|
590
|
+
} else if (workspace) {
|
|
591
|
+
workspace = bindDatabricksWorkspaceContext(workspace, context);
|
|
590
592
|
}
|
|
591
593
|
const gated = approvalGatedToolIds(tools);
|
|
592
594
|
if (gated.length > 0) approvalGatedByAgent.push({ agentId: id, toolIds: gated });
|
package/src/monty-sandbox.ts
CHANGED
|
@@ -11,12 +11,13 @@
|
|
|
11
11
|
|
|
12
12
|
import { configUtils } from "@dbx-tools/core";
|
|
13
13
|
import { errorUtils, functionUtils, log } from "@dbx-tools/shared-core";
|
|
14
|
+
import { availableParallelism } from "node:os";
|
|
14
15
|
import type {
|
|
15
16
|
CommandResult,
|
|
16
17
|
ExecuteCommandOptions,
|
|
17
18
|
SandboxInfo,
|
|
18
|
-
WorkspaceSandbox,
|
|
19
19
|
} from "@mastra/core/workspace";
|
|
20
|
+
import { MastraSandbox, type ProviderStatus } from "@mastra/core/workspace";
|
|
20
21
|
import type { CheckoutOptions, Monty, MontyCrashedError, MontySession } from "@pydantic/monty";
|
|
21
22
|
|
|
22
23
|
const DEFAULT_COMMAND_TIMEOUT_MS = 30_000;
|
|
@@ -38,6 +39,11 @@ interface MontyContext {
|
|
|
38
39
|
pool: MontyPool;
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
/** @internal Size the shared worker pool from the host's available processors. */
|
|
43
|
+
export function montyMaxProcesses(parallelism: number = availableParallelism()): number {
|
|
44
|
+
return Math.max(4, Math.floor(parallelism) * 2);
|
|
45
|
+
}
|
|
46
|
+
|
|
41
47
|
const montyContext = functionUtils.memoize(async (): Promise<MontyContext> => {
|
|
42
48
|
const errors: Error[] = [];
|
|
43
49
|
const targets = configUtils.boolean(undefined, "MONTY_FORCE_WASM")
|
|
@@ -47,12 +53,13 @@ const montyContext = functionUtils.memoize(async (): Promise<MontyContext> => {
|
|
|
47
53
|
try {
|
|
48
54
|
const module = await target.load();
|
|
49
55
|
logger.debug(`${target.name} module available`);
|
|
56
|
+
const maxProcesses = montyMaxProcesses();
|
|
50
57
|
const pool = await module.Monty.create({
|
|
51
58
|
minProcesses: 1,
|
|
52
|
-
maxProcesses
|
|
59
|
+
maxProcesses,
|
|
53
60
|
requestTimeout: 35,
|
|
54
61
|
});
|
|
55
|
-
logger.debug(`${target.name} pool created
|
|
62
|
+
logger.debug(`${target.name} pool created`, { maxProcesses });
|
|
56
63
|
return {
|
|
57
64
|
crashedError: module.MontyCrashedError,
|
|
58
65
|
pool,
|
|
@@ -82,12 +89,11 @@ export interface MontySandboxOptions {
|
|
|
82
89
|
}
|
|
83
90
|
|
|
84
91
|
/** Python-only, deny-by-default sandbox backed by Monty's selected worker pool. */
|
|
85
|
-
export class MontySandbox
|
|
92
|
+
export class MontySandbox extends MastraSandbox {
|
|
86
93
|
readonly id: string;
|
|
87
94
|
readonly name: string;
|
|
88
95
|
readonly provider = "monty";
|
|
89
|
-
status:
|
|
90
|
-
error?: string;
|
|
96
|
+
status: ProviderStatus = "pending";
|
|
91
97
|
|
|
92
98
|
private readonly commandTimeoutMs: number;
|
|
93
99
|
private readonly maxMemoryBytes: number;
|
|
@@ -96,8 +102,10 @@ export class MontySandbox implements WorkspaceSandbox {
|
|
|
96
102
|
private lastUsedAt?: Date;
|
|
97
103
|
|
|
98
104
|
constructor(options: MontySandboxOptions = {}) {
|
|
105
|
+
const name = options.name ?? "Pydantic Monty";
|
|
106
|
+
super({ name });
|
|
99
107
|
this.id = options.id ?? "monty";
|
|
100
|
-
this.name =
|
|
108
|
+
this.name = name;
|
|
101
109
|
this.commandTimeoutMs = options.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;
|
|
102
110
|
this.maxMemoryBytes = options.maxMemoryBytes ?? DEFAULT_MAX_MEMORY_BYTES;
|
|
103
111
|
this.typeCheck = options.typeCheck ?? false;
|
|
@@ -105,33 +113,14 @@ export class MontySandbox implements WorkspaceSandbox {
|
|
|
105
113
|
|
|
106
114
|
/** Warm the shared crash-isolated worker pool. */
|
|
107
115
|
async start(): Promise<void> {
|
|
108
|
-
|
|
109
|
-
this.status = "starting";
|
|
110
|
-
this.error = undefined;
|
|
111
|
-
try {
|
|
112
|
-
await montyContext();
|
|
113
|
-
this.status = "running";
|
|
114
|
-
} catch (caught) {
|
|
115
|
-
this.status = "error";
|
|
116
|
-
this.error = errorUtils.errorMessage(caught);
|
|
117
|
-
throw caught;
|
|
118
|
-
}
|
|
116
|
+
await montyContext();
|
|
119
117
|
}
|
|
120
118
|
|
|
121
119
|
/** The process-wide pool stays warm; this instance carries no open session. */
|
|
122
|
-
async stop(): Promise<void> {
|
|
123
|
-
this.status = "stopped";
|
|
124
|
-
}
|
|
120
|
+
async stop(): Promise<void> {}
|
|
125
121
|
|
|
126
122
|
/** The process-wide pool stays warm; each command closes its own checkout. */
|
|
127
|
-
async destroy(): Promise<void> {
|
|
128
|
-
this.status = "destroyed";
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/** Monty sessions are ephemeral and do not provide persistent checkpoints. */
|
|
132
|
-
async snapshot(): Promise<void> {}
|
|
133
|
-
|
|
134
|
-
readonly supportsCheckpoints = false;
|
|
123
|
+
async destroy(): Promise<void> {}
|
|
135
124
|
|
|
136
125
|
/** Execute Python source and map Monty output to Mastra's command result. */
|
|
137
126
|
async executeCommand(
|
package/src/openapi-tool.ts
CHANGED
|
@@ -9,16 +9,7 @@ import { urlBuilder, type UrlBuilder } from "@dbx-tools/shared-core/net";
|
|
|
9
9
|
import type { JSONSchema7 } from "json-schema";
|
|
10
10
|
import { z } from "zod";
|
|
11
11
|
|
|
12
|
-
const HTTP_METHODS = [
|
|
13
|
-
"GET",
|
|
14
|
-
"POST",
|
|
15
|
-
"PUT",
|
|
16
|
-
"PATCH",
|
|
17
|
-
"DELETE",
|
|
18
|
-
"OPTIONS",
|
|
19
|
-
"HEAD",
|
|
20
|
-
"TRACE",
|
|
21
|
-
] as const;
|
|
12
|
+
const HTTP_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD", "TRACE"] as const;
|
|
22
13
|
|
|
23
14
|
const JsonObjectSchema = z
|
|
24
15
|
.record(z.string(), z.unknown())
|
|
@@ -208,7 +199,7 @@ function operationUrl(document: OpenApiDocument, sourceUrl: URL | undefined, pat
|
|
|
208
199
|
? base.withPathAppend(path).toString()
|
|
209
200
|
: `${server.replace(/\/$/, "")}/${path.replace(/^\//, "")}`;
|
|
210
201
|
}
|
|
211
|
-
return sourceUrl ? urlBuilder(sourceUrl)?.withPathReplace(path).toString() ?? path : path;
|
|
202
|
+
return sourceUrl ? (urlBuilder(sourceUrl)?.withPathReplace(path).toString() ?? path) : path;
|
|
212
203
|
}
|
|
213
204
|
|
|
214
205
|
function resolveReferences(
|
package/src/server.ts
CHANGED
|
@@ -470,25 +470,27 @@ export function attachRoutePatchMiddleware(app: express.Express): void {
|
|
|
470
470
|
* completed turn.
|
|
471
471
|
*/
|
|
472
472
|
export function attachStaleResumeRecovery(app: express.Express): void {
|
|
473
|
-
app.use(
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
473
|
+
app.use(
|
|
474
|
+
(error: unknown, req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
475
|
+
if (!isStaleMastraResumeError(error)) {
|
|
476
|
+
next(error);
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
logger.warn("ignored stale mastra resume", {
|
|
480
|
+
path: req.path,
|
|
481
|
+
error: errorUtils.errorMessage(error),
|
|
482
|
+
});
|
|
483
|
+
if (res.headersSent) {
|
|
484
|
+
res.end();
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
res.status(200);
|
|
488
|
+
res.setHeader("content-type", "text/event-stream; charset=utf-8");
|
|
489
|
+
res.setHeader("cache-control", "no-cache");
|
|
490
|
+
res.write(`data: ${JSON.stringify({ type: "start" })}\n\n`);
|
|
491
|
+
res.write(`data: ${JSON.stringify({ type: "finish" })}\n\n`);
|
|
492
|
+
res.write("data: [DONE]\n\n");
|
|
483
493
|
res.end();
|
|
484
|
-
|
|
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
|
+
},
|
|
495
|
+
);
|
|
494
496
|
}
|
package/src/skill-paths.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Where Databricks Assistant `SKILL.md` trees live.
|
|
3
3
|
*
|
|
4
4
|
* Two modules need these paths and must agree on them: `workspaces.ts` MOUNTS
|
|
5
|
-
* them per request (see `
|
|
5
|
+
* them per request (see `DEFAULT_DATABRICKS_WORKSPACE_PATHS`), and `remote-skills.ts`
|
|
6
6
|
* WRITES provisioned skills into them at startup. They live here rather than being
|
|
7
7
|
* spelled out in both, where a change to one would silently provision skills into a
|
|
8
8
|
* tree the other never scanned.
|