@dbx-tools/appkit-mastra 0.3.21 → 0.3.23
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/package.json +10 -10
- package/src/agents.ts +3 -3
- package/src/chart.ts +2 -2
- package/src/config.ts +1 -1
- package/src/filesystems.ts +3 -5
- package/src/genie.ts +5 -6
- package/src/history.ts +1 -1
- package/src/memory.ts +2 -2
- package/src/mlflow.ts +2 -2
- package/src/model.ts +2 -2
- package/src/observability.ts +2 -2
- package/src/plugin.ts +13 -13
- package/src/server.ts +5 -8
- package/src/serving-sanitize.ts +35 -27
- package/src/serving.ts +2 -2
- package/src/statement.ts +1 -1
- package/src/summarize.ts +1 -1
- package/src/threads.ts +1 -1
- package/src/workspaces.ts +1 -1
- package/src/writer.ts +1 -1
- package/test/tsconfig.json +14 -0
package/package.json
CHANGED
|
@@ -28,22 +28,22 @@
|
|
|
28
28
|
"express": "^5.1.0",
|
|
29
29
|
"pg": "^8.22.0",
|
|
30
30
|
"zod": "^4.3.6",
|
|
31
|
-
"@dbx-tools/
|
|
32
|
-
"@dbx-tools/
|
|
33
|
-
"@dbx-tools/databricks": "0.3.
|
|
34
|
-
"@dbx-tools/
|
|
35
|
-
"@dbx-tools/model": "0.3.
|
|
36
|
-
"@dbx-tools/shared-core": "0.3.
|
|
37
|
-
"@dbx-tools/
|
|
38
|
-
"@dbx-tools/shared-
|
|
39
|
-
"@dbx-tools/shared-model": "0.3.
|
|
31
|
+
"@dbx-tools/appkit": "0.3.23",
|
|
32
|
+
"@dbx-tools/genie": "0.3.23",
|
|
33
|
+
"@dbx-tools/databricks": "0.3.23",
|
|
34
|
+
"@dbx-tools/core": "0.3.23",
|
|
35
|
+
"@dbx-tools/model": "0.3.23",
|
|
36
|
+
"@dbx-tools/shared-core": "0.3.23",
|
|
37
|
+
"@dbx-tools/shared-mastra": "0.3.23",
|
|
38
|
+
"@dbx-tools/shared-genie": "0.3.23",
|
|
39
|
+
"@dbx-tools/shared-model": "0.3.23"
|
|
40
40
|
},
|
|
41
41
|
"main": "index.ts",
|
|
42
42
|
"license": "UNLICENSED",
|
|
43
43
|
"publishConfig": {
|
|
44
44
|
"access": "public"
|
|
45
45
|
},
|
|
46
|
-
"version": "0.3.
|
|
46
|
+
"version": "0.3.23",
|
|
47
47
|
"types": "index.ts",
|
|
48
48
|
"type": "module",
|
|
49
49
|
"exports": {
|
package/src/agents.ts
CHANGED
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
* @module
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
import { plugin } from "@dbx-tools/appkit";
|
|
19
|
+
import { fallback } from "@dbx-tools/model";
|
|
20
|
+
import { log, object, string } from "@dbx-tools/shared-core";
|
|
18
21
|
import type { AgentConfig, ToolsInput } from "@mastra/core/agent";
|
|
19
22
|
import { Agent } from "@mastra/core/agent";
|
|
20
23
|
import type { Tool } from "@mastra/core/tools";
|
|
@@ -27,12 +30,9 @@ import type { MastraPluginConfig } from "./config";
|
|
|
27
30
|
import { buildGenieToolkitProvider, resolveGenieSpaces } from "./genie";
|
|
28
31
|
import type { MemoryBuilder } from "./memory";
|
|
29
32
|
import { buildModel } from "./model";
|
|
30
|
-
import { fallback } from "@dbx-tools/model";
|
|
31
33
|
import { ResultProcessor, stripStaleChartsProcessor } from "./processors";
|
|
32
34
|
import { buildSummarizeTool } from "./summarize";
|
|
33
35
|
import { createWorkspace } from "./workspaces";
|
|
34
|
-
import { log, object, string } from "@dbx-tools/shared-core";
|
|
35
|
-
import { plugin } from "@dbx-tools/appkit";
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* Tool record accepted by every Mastra `Agent.tools` field and by the
|
package/src/chart.ts
CHANGED
|
@@ -28,7 +28,9 @@
|
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
30
|
import { CacheManager } from "@databricks/appkit";
|
|
31
|
+
import { async, error, hash, log, string, type BrandContext } from "@dbx-tools/shared-core";
|
|
31
32
|
import { wire, type Chart, type ChartResult } from "@dbx-tools/shared-mastra";
|
|
33
|
+
import { model } from "@dbx-tools/shared-model";
|
|
32
34
|
import { Agent } from "@mastra/core/agent";
|
|
33
35
|
import type { RequestContext } from "@mastra/core/request-context";
|
|
34
36
|
import { createTool } from "@mastra/core/tools";
|
|
@@ -36,8 +38,6 @@ import { z } from "zod";
|
|
|
36
38
|
|
|
37
39
|
import type { MastraPluginConfig } from "./config";
|
|
38
40
|
import { buildModel } from "./model";
|
|
39
|
-
import { model } from "@dbx-tools/shared-model";
|
|
40
|
-
import { async, error, hash, log, string, type BrandContext } from "@dbx-tools/shared-core";
|
|
41
41
|
|
|
42
42
|
const logger = log.logger("mastra/chart");
|
|
43
43
|
|
package/src/config.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import type { BasePluginConfig } from "@databricks/appkit";
|
|
11
|
+
import { appkit } from "@dbx-tools/appkit";
|
|
11
12
|
import type { BrandContext } from "@dbx-tools/shared-core";
|
|
12
13
|
import type { AgentConfig } from "@mastra/core/agent";
|
|
13
14
|
import { MASTRA_RESOURCE_ID_KEY, MASTRA_THREAD_ID_KEY } from "@mastra/core/request-context";
|
|
@@ -15,7 +16,6 @@ import type { PgVectorConfig, PostgresStoreConfig } from "@mastra/pg";
|
|
|
15
16
|
|
|
16
17
|
import type { MastraAgentDefinition, MastraTools } from "./agents";
|
|
17
18
|
import type { GenieSpacesConfig } from "./genie";
|
|
18
|
-
import { appkit } from "@dbx-tools/appkit";
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* `RequestContext` key under which {@link MastraServer} stores the
|
package/src/filesystems.ts
CHANGED
|
@@ -13,8 +13,10 @@
|
|
|
13
13
|
* @module
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
+
import { posix as path } from "node:path";
|
|
16
17
|
import { getExecutionContext } from "@databricks/appkit";
|
|
17
18
|
import { WorkspaceClient } from "@databricks/sdk-experimental";
|
|
19
|
+
import { error, functionModule, hash, log } from "@dbx-tools/shared-core";
|
|
18
20
|
import type {
|
|
19
21
|
CopyOptions,
|
|
20
22
|
FileContent,
|
|
@@ -26,8 +28,6 @@ import type {
|
|
|
26
28
|
ReadOptions,
|
|
27
29
|
RemoveOptions,
|
|
28
30
|
WriteOptions,
|
|
29
|
-
} from "@mastra/core/workspace";
|
|
30
|
-
import {
|
|
31
31
|
DirectoryNotEmptyError,
|
|
32
32
|
DirectoryNotFoundError,
|
|
33
33
|
FileExistsError,
|
|
@@ -39,8 +39,6 @@ import {
|
|
|
39
39
|
WorkspaceReadOnlyError,
|
|
40
40
|
type MastraFilesystemOptions,
|
|
41
41
|
} from "@mastra/core/workspace";
|
|
42
|
-
import { posix as path } from "node:path";
|
|
43
|
-
import { error, functionModule, hash, log } from "@dbx-tools/shared-core";
|
|
44
42
|
|
|
45
43
|
/* ------------------------------ constants ------------------------------ */
|
|
46
44
|
|
|
@@ -764,7 +762,7 @@ export class DatabricksWorkspaceFilesystem extends MastraFilesystem {
|
|
|
764
762
|
const entries = await this.listAbsoluteDirectory(absolutePath);
|
|
765
763
|
const filtered = this.filterEntries(entries, options);
|
|
766
764
|
if (!options?.recursive) return filtered;
|
|
767
|
-
return this.readDirectoryRecursive(absolutePath, options, 0);
|
|
765
|
+
return await this.readDirectoryRecursive(absolutePath, options, 0);
|
|
768
766
|
} catch (err) {
|
|
769
767
|
this.rethrow(err, inputPath);
|
|
770
768
|
}
|
package/src/genie.ts
CHANGED
|
@@ -38,11 +38,11 @@
|
|
|
38
38
|
|
|
39
39
|
import { CacheManager, genie } from "@databricks/appkit";
|
|
40
40
|
import { WorkspaceClient } from "@databricks/sdk-experimental";
|
|
41
|
-
import {
|
|
41
|
+
import { plugin } from "@dbx-tools/appkit";
|
|
42
42
|
import { chat, space as genieSpace } from "@dbx-tools/genie";
|
|
43
|
-
import { genieModel, type GenieMessage } from "@dbx-tools/shared-genie";
|
|
44
43
|
import { error, log, string } from "@dbx-tools/shared-core";
|
|
45
|
-
import {
|
|
44
|
+
import { genieModel, type GenieMessage } from "@dbx-tools/shared-genie";
|
|
45
|
+
import { wire, type MastraWriter, type StartedEvent } from "@dbx-tools/shared-mastra";
|
|
46
46
|
import type { RequestContext } from "@mastra/core/request-context";
|
|
47
47
|
import { MASTRA_THREAD_ID_KEY } from "@mastra/core/request-context";
|
|
48
48
|
import { createTool } from "@mastra/core/tools";
|
|
@@ -50,8 +50,7 @@ import { z } from "zod";
|
|
|
50
50
|
|
|
51
51
|
import type { MastraTools } from "./agents";
|
|
52
52
|
import { chartPlannerRequestSchema, prepareChart } from "./chart";
|
|
53
|
-
import type { MastraPluginConfig } from "./config";
|
|
54
|
-
import { MASTRA_USER_KEY, type User } from "./config";
|
|
53
|
+
import type { MastraPluginConfig, MASTRA_USER_KEY, type User } from "./config";
|
|
55
54
|
import { fetchStatementData } from "./statement";
|
|
56
55
|
import { safeWrite } from "./writer";
|
|
57
56
|
|
|
@@ -918,7 +917,7 @@ export function resolveGenieSpaces(
|
|
|
918
917
|
const merged: Record<string, GenieSpaceConfig> = {};
|
|
919
918
|
|
|
920
919
|
// Source 3 (lowest precedence): env var.
|
|
921
|
-
const envSpaceId = process.env
|
|
920
|
+
const envSpaceId = process.env.DATABRICKS_GENIE_SPACE_ID;
|
|
922
921
|
if (envSpaceId) {
|
|
923
922
|
merged[DEFAULT_GENIE_ALIAS] = { spaceId: envSpaceId };
|
|
924
923
|
}
|
package/src/history.ts
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* @module
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
import { error, log } from "@dbx-tools/shared-core";
|
|
21
22
|
import type {
|
|
22
23
|
MastraClearHistoryResponse,
|
|
23
24
|
MastraHistoryResponse,
|
|
@@ -31,7 +32,6 @@ import type { ContextWithMastra } from "@mastra/core/server";
|
|
|
31
32
|
import { registerApiRoute } from "@mastra/core/server";
|
|
32
33
|
|
|
33
34
|
import { clampPerPage, parseIntParam } from "./pagination";
|
|
34
|
-
import { error, log } from "@dbx-tools/shared-core";
|
|
35
35
|
|
|
36
36
|
const logger = log.logger("mastra/history");
|
|
37
37
|
|
package/src/memory.ts
CHANGED
|
@@ -29,18 +29,18 @@
|
|
|
29
29
|
* @module
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
|
+
import { randomUUID } from "node:crypto";
|
|
32
33
|
import { getUsernameWithApiLookup } from "@databricks/appkit";
|
|
34
|
+
import { log } from "@dbx-tools/shared-core";
|
|
33
35
|
import { fastembed } from "@mastra/fastembed";
|
|
34
36
|
import { Memory } from "@mastra/memory";
|
|
35
37
|
import { PgVector, PostgresStore } from "@mastra/pg";
|
|
36
|
-
import { randomUUID } from "node:crypto";
|
|
37
38
|
import { Pool, type PoolConfig } from "pg";
|
|
38
39
|
|
|
39
40
|
import type { MastraAgentDefinition, MastraMemoryConfigOverride } from "./agents";
|
|
40
41
|
import type { MastraPluginConfig } from "./config";
|
|
41
42
|
import { agentStorageSchemaName } from "./storage-schema";
|
|
42
43
|
import { summaryModel, TITLE_INSTRUCTIONS } from "./summarize";
|
|
43
|
-
import { log } from "@dbx-tools/shared-core";
|
|
44
44
|
|
|
45
45
|
const logger = log.logger("mastra/memory");
|
|
46
46
|
|
package/src/mlflow.ts
CHANGED
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
* @module
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
+
import { appkit } from "@dbx-tools/appkit";
|
|
23
|
+
import { async, error, log } from "@dbx-tools/shared-core";
|
|
22
24
|
import { feedback } from "@dbx-tools/shared-mastra";
|
|
23
25
|
import { databricksFetch, readResponseJson, readResponseText } from "./rest";
|
|
24
|
-
import { async, error, log } from "@dbx-tools/shared-core";
|
|
25
|
-
import { appkit } from "@dbx-tools/appkit";
|
|
26
26
|
|
|
27
27
|
const logger = log.logger("mastra/mlflow");
|
|
28
28
|
|
package/src/model.ts
CHANGED
|
@@ -25,14 +25,14 @@
|
|
|
25
25
|
|
|
26
26
|
import { getExecutionContext } from "@databricks/appkit";
|
|
27
27
|
import { classes, resolve } from "@dbx-tools/model";
|
|
28
|
+
import { functionModule, log, net } from "@dbx-tools/shared-core";
|
|
28
29
|
import { model } from "@dbx-tools/shared-model";
|
|
29
30
|
import type { MastraModelConfig } from "@mastra/core/llm";
|
|
30
31
|
import type { RequestContext } from "@mastra/core/request-context";
|
|
31
32
|
|
|
32
33
|
import { MASTRA_USER_KEY, type MastraPluginConfig, type User } from "./config";
|
|
33
|
-
import { rewriteServingBody } from "./serving-sanitize";
|
|
34
34
|
import { MASTRA_MODEL_OVERRIDE_KEY, resolveServingConfig } from "./serving";
|
|
35
|
-
import {
|
|
35
|
+
import { rewriteServingBody } from "./serving-sanitize";
|
|
36
36
|
|
|
37
37
|
type ModelClass = model.ModelClass;
|
|
38
38
|
const { parseModelClass } = classes;
|
package/src/observability.ts
CHANGED
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
* @module
|
|
34
34
|
*/
|
|
35
35
|
|
|
36
|
+
import { project } from "@dbx-tools/core";
|
|
37
|
+
import { log } from "@dbx-tools/shared-core";
|
|
36
38
|
import { Observability } from "@mastra/observability";
|
|
37
39
|
import { OtelBridge } from "@mastra/otel-bridge";
|
|
38
40
|
|
|
39
41
|
import { TRACE_REQUEST_CONTEXT_KEYS } from "./config";
|
|
40
|
-
import { log } from "@dbx-tools/shared-core";
|
|
41
|
-
import { project } from "@dbx-tools/core";
|
|
42
42
|
|
|
43
43
|
const logger = log.logger("mastra/observability");
|
|
44
44
|
|
package/src/plugin.ts
CHANGED
|
@@ -51,11 +51,9 @@ import {
|
|
|
51
51
|
type PluginManifest,
|
|
52
52
|
type ResourceRequirement,
|
|
53
53
|
} from "@databricks/appkit";
|
|
54
|
-
import
|
|
55
|
-
import {
|
|
56
|
-
import
|
|
57
|
-
import type { Pool } from "pg";
|
|
58
|
-
|
|
54
|
+
import { plugin } from "@dbx-tools/appkit";
|
|
55
|
+
import { serving as nodeServing } from "@dbx-tools/model";
|
|
56
|
+
import { error, log, string } from "@dbx-tools/shared-core";
|
|
59
57
|
import {
|
|
60
58
|
feedback,
|
|
61
59
|
routes,
|
|
@@ -63,8 +61,12 @@ import {
|
|
|
63
61
|
type MastraFeedbackRequest,
|
|
64
62
|
type StatementData,
|
|
65
63
|
} from "@dbx-tools/shared-mastra";
|
|
66
|
-
import { serving as nodeServing } from "@dbx-tools/model";
|
|
67
64
|
import { display, type ServingEndpointSummary } from "@dbx-tools/shared-model";
|
|
65
|
+
import type { Agent } from "@mastra/core/agent";
|
|
66
|
+
import { Mastra } from "@mastra/core/mastra";
|
|
67
|
+
import express from "express";
|
|
68
|
+
import type { Pool } from "pg";
|
|
69
|
+
|
|
68
70
|
import { buildAgents, FALLBACK_AGENT_ID, type BuiltAgents } from "./agents";
|
|
69
71
|
import { fetchChart } from "./chart";
|
|
70
72
|
import type { MastraPluginConfig } from "./config";
|
|
@@ -78,8 +80,6 @@ import { attachRoutePatchMiddleware, isMastraRequestAllowed, MastraServer } from
|
|
|
78
80
|
import { resolveServingConfig } from "./serving";
|
|
79
81
|
import { fetchStatementData, STATEMENT_ROW_CAP } from "./statement";
|
|
80
82
|
import { threadsRoute } from "./threads";
|
|
81
|
-
import { error, log, string } from "@dbx-tools/shared-core";
|
|
82
|
-
import { plugin } from "@dbx-tools/appkit";
|
|
83
83
|
|
|
84
84
|
const GENIE_MANIFEST = plugin.data(genie).plugin.manifest;
|
|
85
85
|
const LAKEBASE_MANIFEST = plugin.data(lakebase).plugin.manifest;
|
|
@@ -330,7 +330,7 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
330
330
|
// Reads only in-memory build state, so it's synchronous and needs no OBO
|
|
331
331
|
// scoping. Registered before the catch-all, same as `/models`.
|
|
332
332
|
const handleDefaultModel = (req: express.Request, res: express.Response): void => {
|
|
333
|
-
const requested = string.firstNonEmpty(req.params
|
|
333
|
+
const requested = string.firstNonEmpty(req.params.agentId);
|
|
334
334
|
const agentId = requested ?? this.built?.defaultAgentId ?? FALLBACK_AGENT_ID;
|
|
335
335
|
const raw = this.built?.defaultModels[agentId];
|
|
336
336
|
// `"<dynamic>"` (a call-time function) has no fixed id to advertise.
|
|
@@ -378,14 +378,14 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
378
378
|
// clean 404; thrown errors bubble through `next(err)`.
|
|
379
379
|
const embedResolvers: Record<string, EmbedResolver> = {
|
|
380
380
|
chart: (req, id, signal) => {
|
|
381
|
-
const timeoutMs = parseTimeoutMs(req.query
|
|
381
|
+
const timeoutMs = parseTimeoutMs(req.query.timeoutMs);
|
|
382
382
|
return fetchChart(id, {
|
|
383
383
|
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
384
384
|
signal,
|
|
385
385
|
});
|
|
386
386
|
},
|
|
387
387
|
data: (req, id, signal) => {
|
|
388
|
-
const limit = parseStatementLimit(req.query
|
|
388
|
+
const limit = parseStatementLimit(req.query.limit);
|
|
389
389
|
return this.userScopedSelf(req).fetchStatement(id, {
|
|
390
390
|
...(limit !== undefined ? { limit } : {}),
|
|
391
391
|
signal,
|
|
@@ -394,8 +394,8 @@ export class MastraPlugin extends Plugin<MastraPluginConfig> {
|
|
|
394
394
|
};
|
|
395
395
|
|
|
396
396
|
router.get(`${routes.MASTRA_ROUTES.embed}/:type/:id`, (req, res, next) => {
|
|
397
|
-
const type = req.params
|
|
398
|
-
const id = req.params
|
|
397
|
+
const type = req.params.type ?? "";
|
|
398
|
+
const id = req.params.id;
|
|
399
399
|
const resolve = embedResolvers[type];
|
|
400
400
|
if (!resolve) {
|
|
401
401
|
res.status(404).json({ error: `unsupported embed type: ${type}` });
|
package/src/server.ts
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { randomUUID } from "node:crypto";
|
|
10
11
|
import { getExecutionContext } from "@databricks/appkit";
|
|
12
|
+
import { http, log, object, string, token } from "@dbx-tools/shared-core";
|
|
11
13
|
import { feedback, thread } from "@dbx-tools/shared-mastra";
|
|
12
14
|
import {
|
|
13
15
|
MASTRA_RESOURCE_ID_KEY,
|
|
@@ -17,9 +19,6 @@ import {
|
|
|
17
19
|
import { MastraServer as MastraServerExpress } from "@mastra/express";
|
|
18
20
|
import { trace } from "@opentelemetry/api";
|
|
19
21
|
import type express from "express";
|
|
20
|
-
import { randomUUID } from "node:crypto";
|
|
21
|
-
|
|
22
|
-
import { resolveFeedbackEnabled } from "./mlflow";
|
|
23
22
|
|
|
24
23
|
import {
|
|
25
24
|
MASTRA_REQUEST_ID_KEY,
|
|
@@ -30,7 +29,8 @@ import {
|
|
|
30
29
|
type MastraPluginConfig,
|
|
31
30
|
type User,
|
|
32
31
|
} from "./config";
|
|
33
|
-
import {
|
|
32
|
+
import { resolveFeedbackEnabled } from "./mlflow";
|
|
33
|
+
|
|
34
34
|
import { extractModelOverride, MASTRA_MODEL_OVERRIDE_KEY, resolveServingConfig } from "./serving";
|
|
35
35
|
/**
|
|
36
36
|
* OpenTelemetry's sentinel for "no valid trace" - 32 zero hex chars.
|
|
@@ -154,10 +154,7 @@ export class MastraServer extends MastraServerExpress {
|
|
|
154
154
|
configureRequestContextScopes(req: express.Request, requestContext: RequestContext) {
|
|
155
155
|
const scopes = [
|
|
156
156
|
...object
|
|
157
|
-
.sequence(
|
|
158
|
-
token.getAccessTokenScopes(req),
|
|
159
|
-
token.getAccessTokenScopes(req, "authorization"),
|
|
160
|
-
)
|
|
157
|
+
.sequence(token.getAccessTokenScopes(req), token.getAccessTokenScopes(req, "authorization"))
|
|
161
158
|
.distinct(),
|
|
162
159
|
];
|
|
163
160
|
requestContext.set(MASTRA_SCOPES_KEY, scopes);
|
package/src/serving-sanitize.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { string } from "@dbx-tools/shared-core";
|
|
2
|
+
import { type ChatMessage, type ChatRole, openaiChat } from "@dbx-tools/shared-model";
|
|
2
3
|
/**
|
|
3
4
|
* Repairs Mastra / AI SDK message replays sent to Databricks Model
|
|
4
5
|
* Serving before they hit the OpenAI-compatible `/chat/completions`
|
|
@@ -6,43 +7,46 @@ import { string } from "@dbx-tools/shared-core";
|
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* A chat message as it arrives on the serving wire, plus the extended-thinking
|
|
11
|
+
* fields Databricks-hosted Claude adds. The OpenAI-standard part of the shape
|
|
12
|
+
* is {@link ChatMessage} from `@dbx-tools/shared-model`; only the provider
|
|
13
|
+
* extensions this module strips are declared here.
|
|
13
14
|
*/
|
|
14
|
-
export interface ServingChatMessage {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
tool_calls?: Array<{ id: string; type: string; function: unknown }>;
|
|
18
|
-
tool_call_id?: string;
|
|
15
|
+
export interface ServingChatMessage extends ChatMessage {
|
|
16
|
+
/** Narrowed to the roles this repair pass reasons about, plus Claude's `reasoning` turn. */
|
|
17
|
+
role: ChatRole | "reasoning";
|
|
19
18
|
reasoning?: unknown;
|
|
20
19
|
reasoning_content?: unknown;
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
type ServingContentPart = {
|
|
24
|
-
type?: string;
|
|
25
|
-
text?: string;
|
|
26
|
-
[key: string]: unknown;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
22
|
const REASONING_PART_TYPES = new Set(["reasoning", "thinking", "redacted_thinking"]);
|
|
30
23
|
|
|
31
24
|
/**
|
|
32
25
|
* Parse, sanitize, and re-serialize a `/serving-endpoints/...` POST
|
|
33
26
|
* body. Returns the original string verbatim when the body is not
|
|
34
|
-
* JSON
|
|
27
|
+
* JSON or no rewrite was needed.
|
|
35
28
|
*/
|
|
36
29
|
export function rewriteServingBody(body: string): string {
|
|
37
|
-
let parsed:
|
|
30
|
+
let parsed: Record<string, unknown>;
|
|
38
31
|
try {
|
|
39
|
-
parsed = JSON.parse(body)
|
|
32
|
+
parsed = JSON.parse(body) as Record<string, unknown>;
|
|
40
33
|
} catch {
|
|
41
34
|
return body;
|
|
42
35
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
36
|
+
|
|
37
|
+
// Runs regardless of `messages`: Databricks refuses to parse a body carrying
|
|
38
|
+
// an unknown top-level field, so this failure is not specific to a transcript.
|
|
39
|
+
let changed = openaiChat.stripUnsupportedChatFields(parsed).length > 0;
|
|
40
|
+
|
|
41
|
+
if (Array.isArray(parsed.messages)) {
|
|
42
|
+
const messages = parsed.messages as ServingChatMessage[];
|
|
43
|
+
// Evaluated eagerly, not short-circuited: one transcript can need both
|
|
44
|
+
// reasoning blocks stripped AND a trailing assistant prefill folded back.
|
|
45
|
+
const stripped = stripReasoningFromServingMessages(messages);
|
|
46
|
+
const repaired = repairAssistantPrefill(messages);
|
|
47
|
+
changed = changed || stripped || repaired;
|
|
48
|
+
}
|
|
49
|
+
|
|
46
50
|
return changed ? JSON.stringify(parsed) : body;
|
|
47
51
|
}
|
|
48
52
|
|
|
@@ -145,15 +149,19 @@ export function repairAssistantPrefill(messages: ServingChatMessage[]): boolean
|
|
|
145
149
|
return true;
|
|
146
150
|
}
|
|
147
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Flatten content to the prose a human would read: text parts only, separated
|
|
154
|
+
* by blank lines, since the result is spliced into another turn's message body.
|
|
155
|
+
*/
|
|
148
156
|
function textFromServingContent(content: ServingChatMessage["content"]): string {
|
|
149
|
-
|
|
150
|
-
if (!Array.isArray(content)) return "";
|
|
151
|
-
return content
|
|
152
|
-
.filter((part) => part?.type === "text" && typeof part.text === "string")
|
|
153
|
-
.map((part) => part.text as string)
|
|
154
|
-
.join("\n\n");
|
|
157
|
+
return openaiChat.chatContentToText(content, { separator: "\n\n", types: ["text"] });
|
|
155
158
|
}
|
|
156
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Whether a turn carries nothing worth replaying. Deliberately stricter than
|
|
162
|
+
* "has no text": a part of any other type (an image, a cache marker) counts as
|
|
163
|
+
* content, so a message holding one is kept even though it has no prose.
|
|
164
|
+
*/
|
|
157
165
|
function isEmptyServingContent(content: ServingChatMessage["content"]): boolean {
|
|
158
166
|
if (content === undefined) return true;
|
|
159
167
|
if (typeof content === "string") return content.trim().length === 0;
|
package/src/serving.ts
CHANGED
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
* @module
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import { override } from "@dbx-tools/shared-mastra";
|
|
15
14
|
import { serving as nodeServing } from "@dbx-tools/model";
|
|
15
|
+
import { string } from "@dbx-tools/shared-core";
|
|
16
|
+
import { override } from "@dbx-tools/shared-mastra";
|
|
16
17
|
|
|
17
18
|
import type { MastraPluginConfig } from "./config";
|
|
18
|
-
import { string } from "@dbx-tools/shared-core";
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* `RequestContext` key under which {@link MastraServer} stores the
|
package/src/statement.ts
CHANGED
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
import { WorkspaceClient } from "@databricks/sdk-experimental";
|
|
23
|
-
import type { GenieDatasetData } from "@dbx-tools/shared-mastra";
|
|
24
23
|
import { databricks } from "@dbx-tools/appkit";
|
|
24
|
+
import type { GenieDatasetData } from "@dbx-tools/shared-mastra";
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Hard server-side cap on rows returned by the
|
package/src/summarize.ts
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
* @module
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
+
import { string } from "@dbx-tools/shared-core";
|
|
22
23
|
import { model } from "@dbx-tools/shared-model";
|
|
23
24
|
import { Agent } from "@mastra/core/agent";
|
|
24
25
|
import type { MastraModelConfig } from "@mastra/core/llm";
|
|
@@ -28,7 +29,6 @@ import { z } from "zod";
|
|
|
28
29
|
|
|
29
30
|
import type { MastraPluginConfig } from "./config";
|
|
30
31
|
import { buildModel } from "./model";
|
|
31
|
-
import { string } from "@dbx-tools/shared-core";
|
|
32
32
|
|
|
33
33
|
/** Fast / small chat tier used for both titling and summaries. */
|
|
34
34
|
const SUMMARY_MODEL_CLASS = model.ModelClass.ChatFast;
|
package/src/threads.ts
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
* @module
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
+
import { log } from "@dbx-tools/shared-core";
|
|
24
25
|
import {
|
|
25
26
|
wire,
|
|
26
27
|
type MastraDeleteThreadResponse,
|
|
@@ -35,7 +36,6 @@ import type { ContextWithMastra } from "@mastra/core/server";
|
|
|
35
36
|
import { registerApiRoute } from "@mastra/core/server";
|
|
36
37
|
|
|
37
38
|
import { clampPerPage, parseIntParam } from "./pagination";
|
|
38
|
-
import { log } from "@dbx-tools/shared-core";
|
|
39
39
|
|
|
40
40
|
const logger = log.logger("mastra/threads");
|
|
41
41
|
|
package/src/workspaces.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import type { WorkspaceClient } from "@databricks/sdk-experimental";
|
|
14
|
+
import { log, string, token } from "@dbx-tools/shared-core";
|
|
14
15
|
import type { RequestContext } from "@mastra/core/request-context";
|
|
15
16
|
import {
|
|
16
17
|
CompositeFilesystem,
|
|
@@ -22,7 +23,6 @@ import {
|
|
|
22
23
|
|
|
23
24
|
import { MASTRA_SCOPES_KEY, MASTRA_USER_EMAIL_KEY, MASTRA_USER_KEY, type User } from "./config";
|
|
24
25
|
import { DatabricksWorkspaceFilesystem, emptyFilesystem } from "./filesystems";
|
|
25
|
-
import { log, string, token } from "@dbx-tools/shared-core";
|
|
26
26
|
|
|
27
27
|
/* ------------------------------ constants ------------------------------ */
|
|
28
28
|
|
package/src/writer.ts
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
* @module
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import type { MastraWriter } from "@dbx-tools/shared-mastra";
|
|
16
15
|
import { error, log } from "@dbx-tools/shared-core";
|
|
16
|
+
import type { MastraWriter } from "@dbx-tools/shared-mastra";
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Best-effort `writer.write`. No-op when `writer` is undefined;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// ~~ Generated by projen. To modify, edit .projenrc.js and run "pnpm exec projen".
|
|
2
|
+
{
|
|
3
|
+
"extends": "../tsconfig.json",
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"noEmit": true,
|
|
6
|
+
"rootDir": ".."
|
|
7
|
+
},
|
|
8
|
+
"include": [
|
|
9
|
+
"**/*.ts"
|
|
10
|
+
],
|
|
11
|
+
"exclude": [
|
|
12
|
+
"node_modules"
|
|
13
|
+
]
|
|
14
|
+
}
|