@dbx-tools/appkit-mastra 0.1.13 → 0.1.14

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.
Files changed (59) hide show
  1. package/README.md +304 -645
  2. package/index.ts +46 -38
  3. package/package.json +58 -45
  4. package/src/agents.ts +224 -66
  5. package/src/chart.ts +531 -429
  6. package/src/config.ts +270 -19
  7. package/src/filesystems.ts +1090 -0
  8. package/src/genie.ts +1000 -660
  9. package/src/history.ts +166 -79
  10. package/src/mcp.ts +105 -0
  11. package/src/memory.ts +94 -92
  12. package/src/mlflow.ts +149 -0
  13. package/src/model.ts +75 -408
  14. package/src/observability.ts +121 -69
  15. package/src/pagination.ts +34 -0
  16. package/src/plugin.ts +552 -67
  17. package/src/processors.ts +168 -0
  18. package/src/rest.ts +67 -0
  19. package/src/server.ts +232 -45
  20. package/src/serving-sanitize.ts +167 -0
  21. package/src/serving.ts +27 -243
  22. package/src/statement.ts +89 -0
  23. package/src/storage-schema.ts +41 -0
  24. package/src/summarize.ts +176 -0
  25. package/src/threads.ts +338 -0
  26. package/src/workspaces.ts +346 -0
  27. package/src/writer.ts +44 -0
  28. package/tsconfig.json +41 -0
  29. package/dist/index.d.ts +0 -20
  30. package/dist/index.js +0 -20
  31. package/dist/src/agents.d.ts +0 -306
  32. package/dist/src/agents.js +0 -403
  33. package/dist/src/chart.d.ts +0 -170
  34. package/dist/src/chart.js +0 -491
  35. package/dist/src/config.d.ts +0 -183
  36. package/dist/src/config.js +0 -12
  37. package/dist/src/genie.d.ts +0 -131
  38. package/dist/src/genie.js +0 -630
  39. package/dist/src/history.d.ts +0 -67
  40. package/dist/src/history.js +0 -172
  41. package/dist/src/memory.d.ts +0 -100
  42. package/dist/src/memory.js +0 -242
  43. package/dist/src/model.d.ts +0 -159
  44. package/dist/src/model.js +0 -427
  45. package/dist/src/observability.d.ts +0 -33
  46. package/dist/src/observability.js +0 -71
  47. package/dist/src/plugin.d.ts +0 -130
  48. package/dist/src/plugin.js +0 -283
  49. package/dist/src/processors/strip-stale-charts.d.ts +0 -29
  50. package/dist/src/processors/strip-stale-charts.js +0 -96
  51. package/dist/src/server.d.ts +0 -46
  52. package/dist/src/server.js +0 -123
  53. package/dist/src/serving.d.ts +0 -156
  54. package/dist/src/serving.js +0 -231
  55. package/dist/src/tools/email.d.ts +0 -74
  56. package/dist/src/tools/email.js +0 -122
  57. package/dist/tsconfig.build.tsbuildinfo +0 -1
  58. package/src/processors/strip-stale-charts.ts +0 -105
  59. package/src/tools/email.ts +0 -147
@@ -1,105 +0,0 @@
1
- /**
2
- * Mastra input processor that strips `chartId` fields from every
3
- * tool-invocation result in prior assistant messages before they
4
- * reach the model.
5
- *
6
- * Why: chartIds are only meaningful within the assistant turn that
7
- * minted them - the writer events backing them are gone after the
8
- * stream closes. When the model sees old chartIds in memory recall
9
- * (Mastra Memory persists tool results), it's tempted to type
10
- * those ids into the new turn's `[[chart:<id>]]` markers, leaving
11
- * the chat client's chart slots stuck with no matching event. This
12
- * processor removes the temptation by deleting `chartId` keys from
13
- * every assistant message's tool results before the prompt is
14
- * built. The current turn's tool results don't exist yet at
15
- * `processInput` time, so they pass through unmodified.
16
- *
17
- * The strip is recursive - any nested `chartId` field is removed,
18
- * regardless of which tool produced the result. This covers Genie's
19
- * `datasets[].chartId` and `render_data`'s top-level `chartId`
20
- * uniformly without coupling to specific tool ids.
21
- */
22
-
23
- import { logUtils } from "@dbx-tools/appkit-shared";
24
- import type {
25
- InputProcessor,
26
- ProcessInputArgs,
27
- } from "@mastra/core/processors";
28
-
29
- const log = logUtils.logger("mastra/processor/strip-stale-charts");
30
-
31
- /**
32
- * Recursively clone `value`, omitting any property whose key is
33
- * `chartId`. Arrays are mapped element-wise; primitives are
34
- * returned as-is. The result is structurally identical to the
35
- * input minus chartIds, so downstream message-shape consumers
36
- * keep working.
37
- */
38
- function stripChartIds(value: unknown): unknown {
39
- if (Array.isArray(value)) {
40
- return value.map(stripChartIds);
41
- }
42
- if (value && typeof value === "object") {
43
- const obj = value as Record<string, unknown>;
44
- const out: Record<string, unknown> = {};
45
- for (const [key, val] of Object.entries(obj)) {
46
- if (key === "chartId") continue;
47
- out[key] = stripChartIds(val);
48
- }
49
- return out;
50
- }
51
- return value;
52
- }
53
-
54
- /**
55
- * Input processor that scrubs `chartId` from every tool-invocation
56
- * result in the message list. Wired onto every agent by default
57
- * via {@link buildAgents}; opt out with
58
- * `MastraPluginConfig.stripStaleCharts: false`.
59
- */
60
- export const stripStaleChartsProcessor: InputProcessor = {
61
- id: "strip-stale-charts",
62
- description:
63
- "Removes chartId fields from prior tool-invocation results so the model can't reuse turn-scoped ids from memory.",
64
- processInput(args: ProcessInputArgs) {
65
- let stripped = 0;
66
- for (const message of args.messages) {
67
- if (message.role !== "assistant") continue;
68
- const parts = message.content?.parts;
69
- if (!Array.isArray(parts)) continue;
70
- for (const part of parts) {
71
- // Tool-invocation parts hold the persisted tool result.
72
- // We don't scrub the input args (`rawInput` / `args`) because
73
- // the chartId there is the model's outgoing claim, not
74
- // anything it could re-reference; only `result` carries
75
- // ids that subsequent turns might copy.
76
- if (
77
- (part as { type?: unknown }).type !== "tool-invocation"
78
- ) {
79
- continue;
80
- }
81
- const inv = (part as { toolInvocation?: { result?: unknown } })
82
- .toolInvocation;
83
- if (!inv || inv.result === undefined) continue;
84
- const before = inv.result;
85
- const after = stripChartIds(before);
86
- // Cheap structural check via JSON length - the actual
87
- // strip writes a fresh object only when chartId keys
88
- // existed, so different stringification length is a
89
- // reliable signal that something was removed.
90
- if (
91
- typeof before === "object" &&
92
- before !== null &&
93
- JSON.stringify(before).length !== JSON.stringify(after).length
94
- ) {
95
- inv.result = after;
96
- stripped += 1;
97
- }
98
- }
99
- }
100
- if (stripped > 0) {
101
- log.debug("stripped", { results: stripped });
102
- }
103
- return args.messages;
104
- },
105
- };
@@ -1,147 +0,0 @@
1
- /**
2
- * Mastra tool: `send_email`. Gated behind {@link requireApproval}
3
- * so the model can call it freely but execution is paused until a
4
- * human approves via the chat UI.
5
- *
6
- * The execute body is a stub - it logs the would-be email to the
7
- * server console (via `logUtils.logger`) and returns success. Swap
8
- * in a real SMTP / SES / Resend / Workspace Mail call later by
9
- * editing the `execute` body; the tool surface and approval gate
10
- * stay the same.
11
- *
12
- * Approval flow (Mastra + AI SDK V5):
13
- *
14
- * 1. Model calls the tool with `{ to, subject, body, ... }`.
15
- * 2. Mastra evaluates `requireApproval` (here always `true`),
16
- * pauses the agent loop, and emits a `tool-call-approval`
17
- * chunk on the response stream.
18
- * 3. The chat client renders an approve/deny prompt against the
19
- * `state: 'approval-requested'` tool part. On approve, it sends
20
- * a `MastraToolApproval` response back; on deny, the tool call
21
- * is rejected and the model sees an error.
22
- * 4. On approve, this `execute` runs and logs the email.
23
- *
24
- * The tool is intentionally NOT auto-installed on every agent -
25
- * email is domain-specific, not infrastructure. Spread it into the
26
- * specific agents that should be able to draft emails.
27
- */
28
-
29
- import { logUtils, stringUtils } from "@dbx-tools/appkit-shared";
30
- import { createTool } from "@mastra/core/tools";
31
- import { z } from "zod";
32
-
33
- const log = logUtils.logger("mastra/tool/send-email");
34
-
35
- const emailInputSchema = z.object({
36
- to: z.string().describe(stringUtils.toDescription`
37
- Single recipient email address (e.g. "alice@example.com"). For
38
- multiple recipients, comma-separate them yourself.
39
- `),
40
- subject: z.string().describe(stringUtils.toDescription`
41
- Subject line.
42
- `),
43
- body: z.string().describe(stringUtils.toDescription`
44
- Email body. Plain text or markdown; the renderer downstream
45
- decides which to honour. Be specific - the recipient may not
46
- have any context the model has from prior chat turns.
47
- `),
48
- cc: z
49
- .array(z.string())
50
- .optional()
51
- .describe(stringUtils.toDescription`
52
- Optional CC recipients.
53
- `),
54
- bcc: z
55
- .array(z.string())
56
- .optional()
57
- .describe(stringUtils.toDescription`
58
- Optional BCC recipients.
59
- `),
60
- });
61
-
62
- const emailOutputSchema = z.object({
63
- sent: z.boolean().describe(stringUtils.toDescription`
64
- True when the email was dispatched. The current implementation
65
- always returns true after console-logging the would-be email;
66
- swap in a real provider to make this meaningful.
67
- `),
68
- recipient: z.string().describe(stringUtils.toDescription`
69
- Echo of the \`to\` field for confirmation.
70
- `),
71
- });
72
-
73
- /** Options accepted by {@link buildEmailTool}. */
74
- export interface BuildEmailToolOptions {
75
- /**
76
- * Override the tool id. Defaults to `"send_email"`. Useful if a
77
- * caller wants `send_internal_email` / `send_external_email`
78
- * variants.
79
- */
80
- id?: string;
81
- /**
82
- * Replace the default execute body with a real provider call.
83
- * Receives the validated input and must return `{sent, recipient}`.
84
- * The console-log default is meant for demos / dev; production
85
- * deployments should wire SMTP / SES / Resend / Workspace Mail
86
- * here.
87
- */
88
- send?: (input: z.infer<typeof emailInputSchema>) => Promise<void> | void;
89
- }
90
-
91
- /**
92
- * Build the `send_email` tool. Approval-gated by default; the
93
- * execute body either calls the supplied {@link send} hook or
94
- * logs the email to the server console as a demo stub.
95
- *
96
- * @example
97
- * ```ts
98
- * import { buildEmailTool, createAgent, mastra } from "@dbx-tools/appkit-mastra";
99
- *
100
- * const support = createAgent({
101
- * instructions: "...",
102
- * tools(plugins) {
103
- * return {
104
- * ...(plugins.genie?.toolkit() ?? {}),
105
- * send_email: buildEmailTool(),
106
- * };
107
- * },
108
- * });
109
- * ```
110
- */
111
- export function buildEmailTool(opts: BuildEmailToolOptions = {}) {
112
- return createTool({
113
- id: opts.id ?? "send_email",
114
- description: stringUtils.toDescription`
115
- Send an email on the user's behalf. Pass a recipient
116
- address, subject, and body; the user will be prompted to
117
- approve the send before it goes out (the tool is
118
- approval-gated). Use this when the user explicitly asks
119
- to send / forward / share something via email - never
120
- autonomously. Keep subjects short and bodies focused; the
121
- recipient may not have any of the chat context.
122
- `,
123
- inputSchema: emailInputSchema,
124
- outputSchema: emailOutputSchema,
125
- requireApproval: true,
126
- execute: async (input) => {
127
- const { to, subject, body, cc, bcc } = input as z.infer<
128
- typeof emailInputSchema
129
- >;
130
- // Default behaviour: dump the email to the server console so
131
- // demos can see the gate fire end-to-end without a real
132
- // provider. Replace by passing `opts.send`.
133
- log.info("send", {
134
- to,
135
- ...(cc && cc.length > 0 ? { cc } : {}),
136
- ...(bcc && bcc.length > 0 ? { bcc } : {}),
137
- subject,
138
- bodyLength: body.length,
139
- body,
140
- });
141
- if (opts.send) {
142
- await opts.send(input as z.infer<typeof emailInputSchema>);
143
- }
144
- return { sent: true, recipient: to };
145
- },
146
- });
147
- }