@dbx-tools/appkit-mastra 0.9.95 → 0.9.105
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 +238 -285
- package/index.ts +4 -5
- package/lib/index.d.ts +4 -5
- package/lib/index.js +4 -5
- package/lib/src/agents.d.ts +5 -3
- package/lib/src/agents.js +70 -19
- package/lib/src/chat.d.ts +3 -1
- package/lib/src/chat.js +98 -12
- package/lib/src/config.d.ts +7 -1
- package/lib/src/config.js +6 -2
- package/lib/src/model.d.ts +3 -6
- package/lib/src/model.js +11 -94
- package/lib/src/monty-sandbox.d.ts +3 -7
- package/lib/src/monty-sandbox.js +17 -28
- package/lib/src/openapi-tool.js +3 -12
- package/lib/src/plugin.js +3 -1
- 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 +319 -192
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +16 -22
- package/src/agents.ts +69 -18
- package/src/chat.ts +103 -11
- package/src/config.ts +13 -2
- package/src/model.ts +10 -108
- package/src/monty-sandbox.ts +23 -33
- package/src/openapi-tool.ts +2 -11
- package/src/plugin.ts +2 -0
- package/src/server.ts +22 -20
- package/src/skill-paths.ts +1 -1
- package/src/workspaces.ts +485 -266
- package/lib/src/serving-sanitize.d.ts +0 -6
- package/lib/src/serving-sanitize.js +0 -7
- package/src/serving-sanitize.ts +0 -19
package/src/monty-sandbox.ts
CHANGED
|
@@ -9,13 +9,15 @@
|
|
|
9
9
|
* @module
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import { availableParallelism } from "node:os";
|
|
12
13
|
import { configUtils } from "@dbx-tools/core";
|
|
13
14
|
import { errorUtils, functionUtils, log } from "@dbx-tools/shared-core";
|
|
14
|
-
import
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
import {
|
|
16
|
+
MastraSandbox,
|
|
17
|
+
type CommandResult,
|
|
18
|
+
type ExecuteCommandOptions,
|
|
19
|
+
type ProviderStatus,
|
|
20
|
+
type SandboxInfo,
|
|
19
21
|
} from "@mastra/core/workspace";
|
|
20
22
|
import type { CheckoutOptions, Monty, MontyCrashedError, MontySession } from "@pydantic/monty";
|
|
21
23
|
|
|
@@ -38,6 +40,11 @@ interface MontyContext {
|
|
|
38
40
|
pool: MontyPool;
|
|
39
41
|
}
|
|
40
42
|
|
|
43
|
+
/** @internal Size the shared worker pool from the host's available processors. */
|
|
44
|
+
export function montyMaxProcesses(parallelism: number = availableParallelism()): number {
|
|
45
|
+
return Math.max(4, Math.floor(parallelism) * 2);
|
|
46
|
+
}
|
|
47
|
+
|
|
41
48
|
const montyContext = functionUtils.memoize(async (): Promise<MontyContext> => {
|
|
42
49
|
const errors: Error[] = [];
|
|
43
50
|
const targets = configUtils.boolean(undefined, "MONTY_FORCE_WASM")
|
|
@@ -47,12 +54,13 @@ const montyContext = functionUtils.memoize(async (): Promise<MontyContext> => {
|
|
|
47
54
|
try {
|
|
48
55
|
const module = await target.load();
|
|
49
56
|
logger.debug(`${target.name} module available`);
|
|
57
|
+
const maxProcesses = montyMaxProcesses();
|
|
50
58
|
const pool = await module.Monty.create({
|
|
51
59
|
minProcesses: 1,
|
|
52
|
-
maxProcesses
|
|
60
|
+
maxProcesses,
|
|
53
61
|
requestTimeout: 35,
|
|
54
62
|
});
|
|
55
|
-
logger.debug(`${target.name} pool created
|
|
63
|
+
logger.debug(`${target.name} pool created`, { maxProcesses });
|
|
56
64
|
return {
|
|
57
65
|
crashedError: module.MontyCrashedError,
|
|
58
66
|
pool,
|
|
@@ -82,12 +90,11 @@ export interface MontySandboxOptions {
|
|
|
82
90
|
}
|
|
83
91
|
|
|
84
92
|
/** Python-only, deny-by-default sandbox backed by Monty's selected worker pool. */
|
|
85
|
-
export class MontySandbox
|
|
93
|
+
export class MontySandbox extends MastraSandbox {
|
|
86
94
|
readonly id: string;
|
|
87
95
|
readonly name: string;
|
|
88
96
|
readonly provider = "monty";
|
|
89
|
-
status:
|
|
90
|
-
error?: string;
|
|
97
|
+
status: ProviderStatus = "pending";
|
|
91
98
|
|
|
92
99
|
private readonly commandTimeoutMs: number;
|
|
93
100
|
private readonly maxMemoryBytes: number;
|
|
@@ -96,8 +103,10 @@ export class MontySandbox implements WorkspaceSandbox {
|
|
|
96
103
|
private lastUsedAt?: Date;
|
|
97
104
|
|
|
98
105
|
constructor(options: MontySandboxOptions = {}) {
|
|
106
|
+
const name = options.name ?? "Pydantic Monty";
|
|
107
|
+
super({ name });
|
|
99
108
|
this.id = options.id ?? "monty";
|
|
100
|
-
this.name =
|
|
109
|
+
this.name = name;
|
|
101
110
|
this.commandTimeoutMs = options.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;
|
|
102
111
|
this.maxMemoryBytes = options.maxMemoryBytes ?? DEFAULT_MAX_MEMORY_BYTES;
|
|
103
112
|
this.typeCheck = options.typeCheck ?? false;
|
|
@@ -105,33 +114,14 @@ export class MontySandbox implements WorkspaceSandbox {
|
|
|
105
114
|
|
|
106
115
|
/** Warm the shared crash-isolated worker pool. */
|
|
107
116
|
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
|
-
}
|
|
117
|
+
await montyContext();
|
|
119
118
|
}
|
|
120
119
|
|
|
121
120
|
/** The process-wide pool stays warm; this instance carries no open session. */
|
|
122
|
-
async stop(): Promise<void> {
|
|
123
|
-
this.status = "stopped";
|
|
124
|
-
}
|
|
121
|
+
async stop(): Promise<void> {}
|
|
125
122
|
|
|
126
123
|
/** 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;
|
|
124
|
+
async destroy(): Promise<void> {}
|
|
135
125
|
|
|
136
126
|
/** Execute Python source and map Monty output to Mastra's command result. */
|
|
137
127
|
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/plugin.ts
CHANGED
|
@@ -458,6 +458,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
458
458
|
defaultAgent: this.built?.defaultAgentId ?? FALLBACK_AGENT_ID,
|
|
459
459
|
agents: Object.keys(this.built?.agents ?? {}),
|
|
460
460
|
feedbackEnabled: this.feedbackEnabled(),
|
|
461
|
+
backgroundTurns: this.config.backgroundTurns !== false,
|
|
461
462
|
// In `service-principal` mode the chat works for any caller who can open
|
|
462
463
|
// the app, so a UI that hides chat behind an OBO-token probe should show
|
|
463
464
|
// it regardless. `"user"` mode keeps the OBO-gated behavior.
|
|
@@ -1190,6 +1191,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
1190
1191
|
this.logger.info("ready", {
|
|
1191
1192
|
agents: Object.keys(this.built.agents),
|
|
1192
1193
|
defaultAgent: this.built.defaultAgentId,
|
|
1194
|
+
backgroundTurns: this.config.backgroundTurns !== false,
|
|
1193
1195
|
apiAccess: this.config.apiAccess ?? "scoped",
|
|
1194
1196
|
mcp: this.mcp ? `${this.basePath}${this.mcp.httpPath}` : "off",
|
|
1195
1197
|
lakebase: memoryBuilder !== undefined,
|
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.
|