@dbx-tools/appkit-mastra 0.1.5 → 0.1.13
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 +735 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/src/agents.js +18 -8
- package/dist/src/chart.d.ts +101 -35
- package/dist/src/chart.js +178 -62
- package/dist/src/config.d.ts +13 -0
- package/dist/src/genie.d.ts +23 -8
- package/dist/src/genie.js +137 -101
- package/dist/src/history.js +14 -0
- package/dist/src/memory.d.ts +21 -0
- package/dist/src/memory.js +47 -2
- package/dist/src/model.js +18 -14
- package/dist/src/observability.d.ts +33 -0
- package/dist/src/observability.js +71 -0
- package/dist/src/plugin.d.ts +1 -1
- package/dist/src/plugin.js +32 -4
- package/dist/src/processors/strip-stale-charts.d.ts +29 -0
- package/dist/src/processors/strip-stale-charts.js +96 -0
- package/dist/src/server.js +10 -0
- package/dist/src/serving.js +19 -2
- package/dist/src/tools/email.d.ts +74 -0
- package/dist/src/tools/email.js +122 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/index.ts +1 -0
- package/package.json +23 -25
- package/src/agents.ts +19 -6
- package/src/chart.ts +232 -64
- package/src/config.ts +13 -0
- package/src/genie.ts +179 -116
- package/src/history.ts +19 -7
- package/src/memory.ts +55 -2
- package/src/model.ts +18 -13
- package/src/observability.ts +92 -0
- package/src/plugin.ts +33 -4
- package/src/processors/strip-stale-charts.ts +105 -0
- package/src/server.ts +11 -0
- package/src/serving.ts +21 -2
- package/src/tools/email.ts +147 -0
- package/dist/src/render-chart-route.d.ts +0 -33
- package/dist/src/render-chart-route.js +0 -120
- package/src/render-chart-route.ts +0 -141
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Chart-render HTTP endpoint for the Mastra plugin.
|
|
3
|
-
*
|
|
4
|
-
* The `render_data` tool returns immediately with a `chartId` and
|
|
5
|
-
* emits the dataset over `ctx.writer`; the client then POSTs that
|
|
6
|
-
* dataset to this endpoint to actually run the chart-planner
|
|
7
|
-
* agent and get back an Echarts `EChartsOption` JSON. Planning
|
|
8
|
-
* happens out-of-band so the calling agent's response stream
|
|
9
|
-
* doesn't sit idle waiting for it - the model can finish the
|
|
10
|
-
* report while the client is still rendering charts.
|
|
11
|
-
*
|
|
12
|
-
* Auth flows through the standard Mastra middleware: the route
|
|
13
|
-
* sits in the same dispatcher pipeline as `chatRoute` /
|
|
14
|
-
* `historyRoute`, so by the time the handler runs the
|
|
15
|
-
* `RequestContext` is populated with the workspace user and
|
|
16
|
-
* the chart-planner's model resolver has the OBO token it
|
|
17
|
-
* needs.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
import type {
|
|
21
|
-
RenderChartRequest,
|
|
22
|
-
RenderChartResponse,
|
|
23
|
-
} from "@dbx-tools/appkit-mastra-shared";
|
|
24
|
-
import { registerApiRoute } from "@mastra/core/server";
|
|
25
|
-
|
|
26
|
-
import { runChartPlanner } from "./chart.js";
|
|
27
|
-
import type { MastraPluginConfig } from "./config.js";
|
|
28
|
-
|
|
29
|
-
/** Hard cap so a misbehaving client can't hand us a million-row payload. */
|
|
30
|
-
const MAX_ROWS = 5_000;
|
|
31
|
-
/**
|
|
32
|
-
* Hard cap on the JSON body the route accepts (in bytes). Mirrors
|
|
33
|
-
* the same intent as {@link MAX_ROWS}: bound the chart-planner's
|
|
34
|
-
* prompt size and protect against accidental denial-of-service
|
|
35
|
-
* from a runaway tool that ships an enormous payload.
|
|
36
|
-
*/
|
|
37
|
-
const MAX_BODY_BYTES = 2 * 1024 * 1024;
|
|
38
|
-
|
|
39
|
-
/** Options accepted by {@link renderChartRoute}. */
|
|
40
|
-
export interface RenderChartRouteOptions {
|
|
41
|
-
path: string;
|
|
42
|
-
config: MastraPluginConfig;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Register a `POST <path>` Mastra custom API route that runs the
|
|
47
|
-
* chart-planner agent against a dataset and returns an Echarts
|
|
48
|
-
* `EChartsOption` JSON.
|
|
49
|
-
*
|
|
50
|
-
* Body shape: {@link RenderChartRequest}; response:
|
|
51
|
-
* {@link RenderChartResponse}.
|
|
52
|
-
*/
|
|
53
|
-
export function renderChartRoute(options: RenderChartRouteOptions) {
|
|
54
|
-
const { path, config } = options;
|
|
55
|
-
return registerApiRoute(path, {
|
|
56
|
-
method: "POST",
|
|
57
|
-
handler: async (c) => {
|
|
58
|
-
const requestContext = c.get("requestContext");
|
|
59
|
-
|
|
60
|
-
// Hono parses the body as JSON; we still validate shape /
|
|
61
|
-
// size since the tool's structured output is a contract,
|
|
62
|
-
// not a guarantee, and the route is publicly mountable.
|
|
63
|
-
const raw = (await c.req.json().catch(() => null)) as unknown;
|
|
64
|
-
const validation = validateBody(raw);
|
|
65
|
-
if ("error" in validation) {
|
|
66
|
-
return c.json({ error: validation.error }, 400);
|
|
67
|
-
}
|
|
68
|
-
const { title, description, data } = validation.body;
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
const result = await runChartPlanner({
|
|
72
|
-
config,
|
|
73
|
-
...(requestContext ? { requestContext } : {}),
|
|
74
|
-
title,
|
|
75
|
-
...(description ? { description } : {}),
|
|
76
|
-
data,
|
|
77
|
-
});
|
|
78
|
-
const payload: RenderChartResponse = {
|
|
79
|
-
option: result.option,
|
|
80
|
-
chartType: result.chartType,
|
|
81
|
-
};
|
|
82
|
-
return c.json(payload);
|
|
83
|
-
} catch (err) {
|
|
84
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
85
|
-
return c.json({ error: message }, 500);
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
type ValidationResult =
|
|
92
|
-
| { body: RenderChartRequest }
|
|
93
|
-
| { error: string };
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Best-effort body validation. Surfaces a 400 for malformed input
|
|
97
|
-
* instead of letting a downstream `.map` / `.length` blow up
|
|
98
|
-
* inside the planner agent. Field-level shape mirrors
|
|
99
|
-
* {@link RenderChartRequest}.
|
|
100
|
-
*/
|
|
101
|
-
function validateBody(raw: unknown): ValidationResult {
|
|
102
|
-
if (!raw || typeof raw !== "object") {
|
|
103
|
-
return { error: "request body must be a JSON object" };
|
|
104
|
-
}
|
|
105
|
-
const r = raw as Record<string, unknown>;
|
|
106
|
-
const title = r.title;
|
|
107
|
-
if (typeof title !== "string" || title.length === 0) {
|
|
108
|
-
return { error: "`title` must be a non-empty string" };
|
|
109
|
-
}
|
|
110
|
-
if (r.description !== undefined && typeof r.description !== "string") {
|
|
111
|
-
return { error: "`description` must be a string when provided" };
|
|
112
|
-
}
|
|
113
|
-
if (!Array.isArray(r.data)) {
|
|
114
|
-
return { error: "`data` must be an array of row objects" };
|
|
115
|
-
}
|
|
116
|
-
if (r.data.length === 0) {
|
|
117
|
-
return { error: "`data` must contain at least one row" };
|
|
118
|
-
}
|
|
119
|
-
if (r.data.length > MAX_ROWS) {
|
|
120
|
-
return { error: `\`data\` exceeds the per-request limit of ${MAX_ROWS} rows` };
|
|
121
|
-
}
|
|
122
|
-
for (const [i, row] of r.data.entries()) {
|
|
123
|
-
if (!row || typeof row !== "object" || Array.isArray(row)) {
|
|
124
|
-
return { error: `data[${i}] must be a plain object` };
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
// Approximate body-size check; spares us pulling Buffer in.
|
|
128
|
-
const approximateBytes = JSON.stringify(r.data).length;
|
|
129
|
-
if (approximateBytes > MAX_BODY_BYTES) {
|
|
130
|
-
return {
|
|
131
|
-
error: `\`data\` exceeds the per-request size limit of ${MAX_BODY_BYTES} bytes`,
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
return {
|
|
135
|
-
body: {
|
|
136
|
-
title,
|
|
137
|
-
...(typeof r.description === "string" ? { description: r.description } : {}),
|
|
138
|
-
data: r.data as Array<Record<string, unknown>>,
|
|
139
|
-
},
|
|
140
|
-
};
|
|
141
|
-
}
|