@dbx-tools/appkit-mastra 0.6.8 → 0.6.10
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 +49 -2
- package/index.ts +14 -26
- package/lib/index.d.ts +14 -26
- package/lib/index.js +13 -26
- package/lib/src/config.d.ts +21 -0
- package/lib/src/config.js +5 -1
- package/lib/src/databricks-aitools.d.ts +73 -0
- package/lib/src/databricks-aitools.js +152 -0
- package/lib/src/filesystems.d.ts +52 -170
- package/lib/src/filesystems.js +168 -888
- package/lib/src/plugin.js +14 -2
- package/lib/src/remote-skills.d.ts +4 -4
- package/lib/src/remote-skills.js +63 -35
- package/lib/src/workspaces.d.ts +4 -0
- package/lib/src/workspaces.js +37 -13
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +13 -10
- package/src/config.ts +27 -0
- package/src/databricks-aitools.ts +216 -0
- package/src/filesystems.ts +225 -970
- package/src/plugin.ts +14 -1
- package/src/remote-skills.ts +69 -38
- package/src/workspaces.ts +41 -16
package/package.json
CHANGED
|
@@ -32,22 +32,25 @@
|
|
|
32
32
|
"express": "^5.1.0",
|
|
33
33
|
"pg": "^8.22.0",
|
|
34
34
|
"zod": "4.3.6",
|
|
35
|
-
"@dbx-tools/
|
|
36
|
-
"@dbx-tools/
|
|
37
|
-
"@dbx-tools/genie": "0.6.
|
|
38
|
-
"@dbx-tools/
|
|
39
|
-
"@dbx-tools/
|
|
40
|
-
"@dbx-tools/
|
|
41
|
-
"@dbx-tools/
|
|
42
|
-
"@dbx-tools/shared-
|
|
43
|
-
"@dbx-tools/shared-
|
|
35
|
+
"@dbx-tools/appkit": "0.6.10",
|
|
36
|
+
"@dbx-tools/databricks": "0.6.10",
|
|
37
|
+
"@dbx-tools/genie": "0.6.10",
|
|
38
|
+
"@dbx-tools/fs": "0.6.10",
|
|
39
|
+
"@dbx-tools/model": "0.6.10",
|
|
40
|
+
"@dbx-tools/core": "0.6.10",
|
|
41
|
+
"@dbx-tools/path": "0.6.10",
|
|
42
|
+
"@dbx-tools/shared-core": "0.6.10",
|
|
43
|
+
"@dbx-tools/shared-fs": "0.6.10",
|
|
44
|
+
"@dbx-tools/shared-model": "0.6.10",
|
|
45
|
+
"@dbx-tools/shared-genie": "0.6.10",
|
|
46
|
+
"@dbx-tools/shared-mastra": "0.6.10"
|
|
44
47
|
},
|
|
45
48
|
"main": "./lib/index.js",
|
|
46
49
|
"license": "UNLICENSED",
|
|
47
50
|
"publishConfig": {
|
|
48
51
|
"access": "public"
|
|
49
52
|
},
|
|
50
|
-
"version": "0.6.
|
|
53
|
+
"version": "0.6.10",
|
|
51
54
|
"types": "./lib/index.d.ts",
|
|
52
55
|
"type": "module",
|
|
53
56
|
"exports": {
|
package/src/config.ts
CHANGED
|
@@ -23,6 +23,7 @@ import { MASTRA_RESOURCE_ID_KEY, MASTRA_THREAD_ID_KEY } from "@mastra/core/reque
|
|
|
23
23
|
import type { PgVectorConfig, PostgresStoreConfig } from "@mastra/pg";
|
|
24
24
|
|
|
25
25
|
import type { MastraAgentDefinition, MastraTools } from "./agents.ts";
|
|
26
|
+
import type { DatabricksAIToolsOption } from "./databricks-aitools.ts";
|
|
26
27
|
import type { GenieSpacesConfig } from "./genie.ts";
|
|
27
28
|
import type { MastraIdentityMode } from "./identity.ts";
|
|
28
29
|
import type { RemoteSkillsOption } from "./remote-skills.ts";
|
|
@@ -580,6 +581,27 @@ export interface MastraPluginConfig extends BasePluginConfig {
|
|
|
580
581
|
* ```
|
|
581
582
|
*/
|
|
582
583
|
remoteSkills?: RemoteSkillsOption;
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Fold Databricks AI Tools skills (`databricks aitools`) into every
|
|
587
|
+
* default-workspace agent as extra local skill scan paths.
|
|
588
|
+
*
|
|
589
|
+
* `false` (default) off; `"auto"` runs the `databricks` CLI when it's
|
|
590
|
+
* installed and logs-and-continues when it isn't (never fails startup);
|
|
591
|
+
* `true` requires the CLI and fails startup otherwise. Pass an options bag to
|
|
592
|
+
* select `skills`, include `experimental` skills, or set an explicit `path`.
|
|
593
|
+
*
|
|
594
|
+
* Runs `databricks aitools install --path <dir>` to materialize a resolved,
|
|
595
|
+
* agent-agnostic set (`<name>/SKILL.md` trees) into a temp dir the agents
|
|
596
|
+
* then scan. The CLI is the source of truth.
|
|
597
|
+
*
|
|
598
|
+
* @example
|
|
599
|
+
* ```ts
|
|
600
|
+
* mastra({ databricksAITools: "auto" });
|
|
601
|
+
* mastra({ databricksAITools: { skills: ["databricks-core", "databricks-jobs"] } });
|
|
602
|
+
* ```
|
|
603
|
+
*/
|
|
604
|
+
databricksAITools?: DatabricksAIToolsOption;
|
|
583
605
|
}
|
|
584
606
|
|
|
585
607
|
/**
|
|
@@ -603,6 +625,11 @@ export const MASTRA_CONFIG_SCHEMA: ConfigSchema = {
|
|
|
603
625
|
description:
|
|
604
626
|
"Remote Agent-Skill sources provisioned at startup (GitHub owner/repo, git/GitLab URL, or a direct SKILL.md/archive URL). Prefers the optional `skills` npm CLI, else a direct fetch; fails startup on error unless failOnError:false. Written to the Databricks user Assistant skills folder, or a local temp dir when no workspace is writable.",
|
|
605
627
|
},
|
|
628
|
+
databricksAITools: {
|
|
629
|
+
type: ["boolean", "string", "object"],
|
|
630
|
+
description:
|
|
631
|
+
'Fold Databricks AI Tools skills (databricks aitools) into agents as extra local skill paths. false (default) off; "auto" runs the databricks CLI when installed and logs-and-continues otherwise; true requires the CLI and fails startup otherwise. An object selects skills, experimental, or path.',
|
|
632
|
+
},
|
|
606
633
|
storage: {
|
|
607
634
|
type: ["boolean", "object"],
|
|
608
635
|
description:
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Startup provisioning of Databricks AI Tools skills for a Mastra workspace.
|
|
3
|
+
*
|
|
4
|
+
* Databricks AI Tools (`databricks aitools`) are Databricks-owned Agent-Skill
|
|
5
|
+
* (`SKILL.md`) trees installed and kept up to date through the Databricks CLI.
|
|
6
|
+
* {@link provisionDatabricksAITools} shells out to the CLI
|
|
7
|
+
* (`databricks aitools install --path <dir>`) to materialize a resolved,
|
|
8
|
+
* agent-agnostic skill set into a directory, then hands it to Mastra as an
|
|
9
|
+
* extra LOCAL skill scan path - so an agent gets first-class Databricks skills
|
|
10
|
+
* without anyone hand-copying `SKILL.md` files. It never reimplements the CLI's
|
|
11
|
+
* sourcing; the CLI is the source of truth.
|
|
12
|
+
*
|
|
13
|
+
* The option is `false | true | "auto" | DatabricksAIToolsOptions`:
|
|
14
|
+
*
|
|
15
|
+
* - `false` (default) - off.
|
|
16
|
+
* - `"auto"` - run the CLI when it's installed; if the `databricks` CLI isn't
|
|
17
|
+
* available, log and move on (never fails startup). The "on if the CLI is
|
|
18
|
+
* around" default.
|
|
19
|
+
* - `true` (`"require"`) - require the CLI: fail startup (subject to
|
|
20
|
+
* `failOnError`) when it isn't available or produces nothing.
|
|
21
|
+
* - an options bag for a specific `skills` subset, `experimental` skills, an
|
|
22
|
+
* explicit output `path`, or a custom `cli` path.
|
|
23
|
+
*
|
|
24
|
+
* @module
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { existsSync } from "node:fs";
|
|
28
|
+
import { exec } from "@dbx-tools/core";
|
|
29
|
+
import { localFS } from "@dbx-tools/fs";
|
|
30
|
+
import { error, log, string } from "@dbx-tools/shared-core";
|
|
31
|
+
|
|
32
|
+
const logger = log.logger("mastra/databricks-aitools");
|
|
33
|
+
|
|
34
|
+
/** The Databricks CLI binary name; resolved on `PATH`. */
|
|
35
|
+
const DATABRICKS_CLI = "databricks";
|
|
36
|
+
|
|
37
|
+
/** Stable temp directory the CLI's skill tree is rebuilt into each boot. */
|
|
38
|
+
const SKILLS_CACHE_DIR = "databricks-aitools";
|
|
39
|
+
|
|
40
|
+
/* -------------------------------- types -------------------------------- */
|
|
41
|
+
|
|
42
|
+
/** How aggressively to enable Databricks AI Tools skills. */
|
|
43
|
+
export type DatabricksAIToolsMode = "auto" | "require";
|
|
44
|
+
|
|
45
|
+
/** Options for {@link provisionDatabricksAITools}. */
|
|
46
|
+
export interface DatabricksAIToolsOptions {
|
|
47
|
+
/**
|
|
48
|
+
* `"auto"` (default) runs the CLI when installed and logs-and-continues when
|
|
49
|
+
* it isn't; `"require"` fails startup when the CLI can't supply skills.
|
|
50
|
+
*/
|
|
51
|
+
mode?: DatabricksAIToolsMode;
|
|
52
|
+
/** Install only these skill names (comma/space list or array). */
|
|
53
|
+
skills?: string | string[];
|
|
54
|
+
/** Include experimental skills when the CLI has to fetch. */
|
|
55
|
+
experimental?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Explicit directory to materialize skills into with the CLI. Defaults to a
|
|
58
|
+
* fresh {@link localFS.tmpFS} root.
|
|
59
|
+
*/
|
|
60
|
+
path?: string;
|
|
61
|
+
/** Absolute path to the `databricks` CLI. Defaults to `databricks` on PATH. */
|
|
62
|
+
cli?: string;
|
|
63
|
+
/**
|
|
64
|
+
* Fail app startup when required skills can't be provisioned. Defaults to
|
|
65
|
+
* `true` for `mode: "require"` and `false` for `"auto"`.
|
|
66
|
+
*/
|
|
67
|
+
failOnError?: boolean;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** The `databricksAITools` config option: a toggle, `"auto"`, or an options bag. */
|
|
71
|
+
export type DatabricksAIToolsOption = boolean | "auto" | DatabricksAIToolsOptions;
|
|
72
|
+
|
|
73
|
+
/** What {@link provisionDatabricksAITools} resolved. */
|
|
74
|
+
export interface ProvisionedDatabricksAITools {
|
|
75
|
+
/** Extra LOCAL skill scan paths to hand Mastra. Empty when disabled/unresolved. */
|
|
76
|
+
localSkillPaths: string[];
|
|
77
|
+
/** How the skills were sourced, for logging. */
|
|
78
|
+
source?: "cli";
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* ------------------------------- helpers ------------------------------- */
|
|
82
|
+
|
|
83
|
+
/** Normalize the `databricksAITools` option into a flat options bag, or `undefined` when off. */
|
|
84
|
+
export function normalizeDatabricksAIToolsOption(
|
|
85
|
+
option: DatabricksAIToolsOption | undefined,
|
|
86
|
+
): DatabricksAIToolsOptions | undefined {
|
|
87
|
+
if (option === undefined || option === false) return undefined;
|
|
88
|
+
if (option === true) return { mode: "require" };
|
|
89
|
+
if (option === "auto") return { mode: "auto" };
|
|
90
|
+
return { mode: option.mode ?? "auto", ...option };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Materialize Databricks AI Tools skills at app startup and return them as
|
|
95
|
+
* extra local skill scan paths.
|
|
96
|
+
*
|
|
97
|
+
* Resolution: reuse the installed global tree when present (no CLI call) unless
|
|
98
|
+
* `refresh`/`skills`/`path` ask for a fresh CLI materialization; otherwise run
|
|
99
|
+
* `databricks aitools install --path <dir> --skills-only` when the CLI resolves.
|
|
100
|
+
* A `"require"` provision that yields nothing fails startup unless
|
|
101
|
+
* `failOnError: false`.
|
|
102
|
+
*/
|
|
103
|
+
export async function provisionDatabricksAITools(
|
|
104
|
+
option: DatabricksAIToolsOption | undefined,
|
|
105
|
+
): Promise<ProvisionedDatabricksAITools> {
|
|
106
|
+
const options = normalizeDatabricksAIToolsOption(option);
|
|
107
|
+
const empty: ProvisionedDatabricksAITools = { localSkillPaths: [] };
|
|
108
|
+
if (!options) return empty;
|
|
109
|
+
|
|
110
|
+
const mode = options.mode ?? "auto";
|
|
111
|
+
const failOnError = options.failOnError ?? mode === "require";
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
// The `databricks` CLI is the source of truth. When it's resolvable, run
|
|
115
|
+
// `databricks aitools install --path <dir>` to materialize a fresh,
|
|
116
|
+
// agent-agnostic skill set into a dir Mastra can scan.
|
|
117
|
+
const cliPath = await resolveCli(options.cli);
|
|
118
|
+
if (cliPath) {
|
|
119
|
+
const dir = await materializeViaCli(cliPath, options);
|
|
120
|
+
if (dir) return { localSkillPaths: [dir], source: "cli" };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// CLI not installed (or produced nothing). "auto" logs and moves on;
|
|
124
|
+
// "require" fails startup unless `failOnError: false`.
|
|
125
|
+
if (failOnError) {
|
|
126
|
+
throw new Error(
|
|
127
|
+
`Databricks AI Tools required but the "${DATABRICKS_CLI}" CLI is not available. Install the Databricks CLI (\`databricks aitools install\`), or set databricksAITools: "auto".`,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
logger.info("databricks CLI not available; skipping AI Tools skills");
|
|
131
|
+
return empty;
|
|
132
|
+
} catch (err) {
|
|
133
|
+
if (failOnError) {
|
|
134
|
+
throw new Error(
|
|
135
|
+
`failed to provision Databricks AI Tools skills: ${error.errorMessage(err)}`,
|
|
136
|
+
{ cause: error.toError(err) },
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
logger.warn("skipped", { error: error.errorMessage(err) });
|
|
140
|
+
return empty;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Resolve the `databricks` CLI, returning its invocation path or `undefined`. */
|
|
145
|
+
async function resolveCli(cli: string | undefined): Promise<string | undefined> {
|
|
146
|
+
const command = string.trimToNull(cli) ?? DATABRICKS_CLI;
|
|
147
|
+
try {
|
|
148
|
+
const result = await exec.spawn(command, ["aitools", "version"], {
|
|
149
|
+
stdout: "capture",
|
|
150
|
+
stderr: "capture",
|
|
151
|
+
check: false,
|
|
152
|
+
});
|
|
153
|
+
if (result.exitCode === 0) return command;
|
|
154
|
+
} catch {
|
|
155
|
+
// CLI absent or `aitools` unsupported - caller falls back / fails.
|
|
156
|
+
}
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Run `databricks aitools install --path <dir>` to materialize a resolved,
|
|
162
|
+
* agent-agnostic skill set into a directory (writes `<name>/SKILL.md` trees,
|
|
163
|
+
* no agents, no state) Mastra can then scan.
|
|
164
|
+
*/
|
|
165
|
+
async function materializeViaCli(
|
|
166
|
+
cli: string,
|
|
167
|
+
options: DatabricksAIToolsOptions,
|
|
168
|
+
): Promise<string | undefined> {
|
|
169
|
+
const explicit = string.trimToNull(options.path);
|
|
170
|
+
let dir: string;
|
|
171
|
+
|
|
172
|
+
if (explicit) {
|
|
173
|
+
// An explicit path is the caller's to own - install straight into it.
|
|
174
|
+
await installSkills(cli, options, explicit);
|
|
175
|
+
dir = explicit;
|
|
176
|
+
} else {
|
|
177
|
+
// The resolved skill set is the same on almost every boot, so rebuild ONE
|
|
178
|
+
// stable temp tree rather than leaving a fresh scratch dir behind each
|
|
179
|
+
// time. The CLI writes into a throwaway root that only replaces the stable
|
|
180
|
+
// one on success, so a failed install keeps the previous skills usable.
|
|
181
|
+
const stable = await localFS.rebuildFS(SKILLS_CACHE_DIR, (scratch) =>
|
|
182
|
+
installSkills(cli, options, scratch.root),
|
|
183
|
+
);
|
|
184
|
+
dir = stable.root;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (!existsSync(dir)) return undefined;
|
|
188
|
+
logger.debug("materialized aitools skills via CLI", {
|
|
189
|
+
path: dir,
|
|
190
|
+
skills: string.parseList(options.skills),
|
|
191
|
+
});
|
|
192
|
+
return dir;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** Run `databricks aitools install --path <dir>`, failing loudly on a non-zero exit. */
|
|
196
|
+
async function installSkills(
|
|
197
|
+
cli: string,
|
|
198
|
+
options: DatabricksAIToolsOptions,
|
|
199
|
+
dir: string,
|
|
200
|
+
): Promise<void> {
|
|
201
|
+
const args = ["aitools", "install", "--path", dir];
|
|
202
|
+
const skills = string.parseList(options.skills);
|
|
203
|
+
if (skills.length > 0) args.push("--skills", skills.join(","));
|
|
204
|
+
if (options.experimental) args.push("--experimental");
|
|
205
|
+
|
|
206
|
+
const result = await exec.spawn(cli, args, {
|
|
207
|
+
stdout: "capture",
|
|
208
|
+
stderr: "capture",
|
|
209
|
+
check: false,
|
|
210
|
+
});
|
|
211
|
+
if (result.exitCode !== 0) {
|
|
212
|
+
throw new Error(
|
|
213
|
+
`databricks aitools install failed (exit ${result.exitCode}): ${result.stderr || result.stdout}`,
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
}
|