@dbx-tools/appkit-mastra 0.1.4 → 0.1.12

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/index.ts CHANGED
@@ -13,7 +13,9 @@ export * from "./src/plugin.js";
13
13
  export * from "@dbx-tools/appkit-mastra-shared";
14
14
  export * from "./src/config.js";
15
15
  export * from "./src/agents.js";
16
+ export * from "./src/chart.js";
16
17
  export * from "./src/genie.js";
18
+ export * from "./src/tools/email.js";
17
19
  export {
18
20
  clearServingEndpointsCache,
19
21
  extractModelOverride,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
- "main": "dist/index.js",
3
- "types": "dist/index.d.ts",
2
+ "main": "./dist/index.js",
3
+ "types": "./dist/index.d.ts",
4
4
  "exports": {
5
5
  ".": {
6
6
  "source": "./index.ts",
@@ -8,32 +8,13 @@
8
8
  "default": "./dist/index.js"
9
9
  }
10
10
  },
11
- "files": [
12
- "dist",
13
- "index.ts",
14
- "src"
15
- ],
16
- "license": "Apache-2.0",
17
- "homepage": "https://github.com/reggie-db/dbx-tools-appkit#readme",
18
- "bugs": {
19
- "url": "https://github.com/reggie-db/dbx-tools-appkit/issues"
20
- },
21
- "publishConfig": {
22
- "registry": "https://registry.npmjs.org/",
23
- "access": "public"
24
- },
25
- "repository": {
26
- "type": "git",
27
- "url": "git+https://github.com/reggie-db/dbx-tools-appkit.git",
28
- "directory": "packages/mastra"
29
- },
30
11
  "name": "@dbx-tools/appkit-mastra",
31
- "version": "0.1.4",
32
- "module": "index.ts",
12
+ "version": "0.1.12",
33
13
  "type": "module",
14
+ "module": "index.ts",
34
15
  "dependencies": {
35
- "@dbx-tools/appkit-shared": "0.1.3",
36
- "@dbx-tools/appkit-mastra-shared": "0.1.3",
16
+ "@dbx-tools/appkit-mastra-shared": "0.1.12",
17
+ "@dbx-tools/appkit-shared": "0.1.12",
37
18
  "@mastra/ai-sdk": "^1.3",
38
19
  "@mastra/core": "^1.32",
39
20
  "@mastra/express": "^1.3",
@@ -51,5 +32,20 @@
51
32
  "@types/express": "^5",
52
33
  "@types/pg": "^8",
53
34
  "express": "^5"
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "index*.ts",
39
+ "src"
40
+ ],
41
+ "license": "Apache-2.0",
42
+ "homepage": "https://github.com/reggie-db/dbx-tools-appkit#readme",
43
+ "bugs": {
44
+ "url": "https://github.com/reggie-db/dbx-tools-appkit/issues"
45
+ },
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "git+https://github.com/reggie-db/dbx-tools-appkit.git",
49
+ "directory": "packages/mastra"
54
50
  }
55
51
  }
package/src/agents.ts CHANGED
@@ -21,10 +21,12 @@ import { createTool } from "@mastra/core/tools";
21
21
  import type { Tool } from "@mastra/core/tools";
22
22
  import type { PgVectorConfig, PostgresStoreConfig } from "@mastra/pg";
23
23
 
24
+ import { buildRenderDataTool } from "./chart.js";
24
25
  import type { MastraPluginConfig } from "./config.js";
25
26
  import { buildGenieProvider } from "./genie.js";
26
27
  import type { MemoryBuilder } from "./memory.js";
27
28
  import { buildModel } from "./model.js";
29
+ import { stripStaleChartsProcessor } from "./processors/strip-stale-charts.js";
28
30
 
29
31
  /**
30
32
  * Tool record accepted by every Mastra `Agent.tools` field and by the
@@ -121,8 +123,8 @@ export interface AppKitToolOptions {
121
123
  /**
122
124
  * Build a deterministic Mastra tool id from a description.
123
125
  * Delegates to {@link stringUtils.toUniqueSlug}: slug + always-on
124
- * SHA-1 suffix so two tools with the same leading words don't
125
- * collide in traces. Stable across runs.
126
+ * 6-char FNV-1a base-32 suffix so two tools with the same leading
127
+ * words don't collide in traces. Stable across runs.
126
128
  */
127
129
  function deriveToolId(description: string): string {
128
130
  return stringUtils.toUniqueSlug(description, { fallbackPrefix: "tool" });
@@ -344,16 +346,21 @@ Rules:
344
346
  * Override globally via {@link MastraPluginConfig.styleInstructions}
345
347
  * (pass `false` to disable entirely, or a string to replace).
346
348
  */
347
- export const DEFAULT_STYLE_INSTRUCTIONS = `Output style:
348
-
349
- - Plain prose. Use hyphens (-) only. Never use em dashes (—) or en dashes (–).
350
- - Never use emojis.
351
- - Skip openers like "Great question", "Absolutely", "I'd be happy to help".
352
- - Skip closers like "Let me know if you have any questions".
353
- - Skip self-disclaimers ("I should mention", "It's important to note").
354
- - Answer directly. No preamble before the actual answer.
355
- - Use lists and headers only when they clarify a multi-part answer; not for short replies.
356
- - Quote numbers, code, identifiers, and tool output verbatim. Never paraphrase them.`;
349
+ export const DEFAULT_STYLE_INSTRUCTIONS = [
350
+ "Output style:",
351
+ "",
352
+ "Use markdown formatting, including headings, lists, and code blocks.",
353
+ "Avoid lists and headers for short replies.",
354
+ "Plain prose.",
355
+ "Use hyphens (-) only. Never use em dashes or en dashes.",
356
+ "Never use emojis.",
357
+ "Skip openers like 'Great question', 'Absolutely', and 'I'd be happy to help'.",
358
+ "Skip closers like 'Let me know if you have any questions'.",
359
+ "Skip self-disclaimers like 'I should mention' and 'It's important to note'.",
360
+ "Answer directly.",
361
+ "Do not include a preamble before the actual answer.",
362
+ "Use lists and headers only when they clarify a multi-part answer.",
363
+ ].join("\n");
357
364
 
358
365
  /**
359
366
  * Resolve the style block to append to every agent's instructions.
@@ -364,6 +371,7 @@ function resolveStyleInstructions(config: MastraPluginConfig): string | null {
364
371
  if (typeof config.styleInstructions === "string") {
365
372
  return config.styleInstructions;
366
373
  }
374
+
367
375
  return DEFAULT_STYLE_INSTRUCTIONS;
368
376
  }
369
377
 
@@ -371,10 +379,7 @@ function resolveStyleInstructions(config: MastraPluginConfig): string | null {
371
379
  * Join an agent's bespoke instructions with the resolved style block.
372
380
  * Returns the bespoke text unchanged when the style block is disabled.
373
381
  */
374
- function composeInstructions(
375
- agentInstructions: string,
376
- style: string | null,
377
- ): string {
382
+ function composeInstructions(agentInstructions: string, style: string | null): string {
378
383
  if (!style) return agentInstructions;
379
384
  return `${agentInstructions.trimEnd()}\n\n${style}`;
380
385
  }
@@ -403,9 +408,23 @@ export async function buildAgents(opts: {
403
408
  const ids = Object.keys(definitions);
404
409
  const defaultAgentId = config.defaultAgent ?? ids[0] ?? FALLBACK_AGENT_ID;
405
410
 
406
- const plugins = buildPluginsMap(context);
407
- const ambientTools = config.tools ?? {};
411
+ const plugins = buildPluginsMap(config, context);
412
+ // System-default ambient tools every agent gets out of the box.
413
+ // Currently just `render_data` for inline visualizations; the
414
+ // user can shadow it by including a same-named tool in their own
415
+ // `config.tools` or per-agent `tools`. Order in {@link resolveTools}
416
+ // is `system -> user-ambient -> per-agent`, last write wins.
417
+ const systemTools: MastraTools = {
418
+ render_data: buildRenderDataTool(config),
419
+ };
420
+ const ambientTools = { ...systemTools, ...(config.tools ?? {}) };
408
421
  const style = resolveStyleInstructions(config);
422
+ // Default-on protection against the model copying turn-scoped
423
+ // chartIds from prior assistant tool results into the new
424
+ // turn's `[[chart:<id>]]` markers. Opt out per-plugin via
425
+ // `config.stripStaleCharts: false`.
426
+ const inputProcessors =
427
+ config.stripStaleCharts === false ? [] : [stripStaleChartsProcessor];
409
428
  const agents: Record<string, Agent> = {};
410
429
 
411
430
  for (const [id, def] of Object.entries(definitions)) {
@@ -419,6 +438,7 @@ export async function buildAgents(opts: {
419
438
  model: resolveModel(config, def.model),
420
439
  tools,
421
440
  ...(memory ? { memory } : {}),
441
+ ...(inputProcessors.length > 0 ? { inputProcessors } : {}),
422
442
  });
423
443
  }
424
444
 
@@ -569,6 +589,7 @@ async function resolveTools(
569
589
  * time instead of staring at a spinner for the full Genie round-trip.
570
590
  */
571
591
  function buildPluginsMap(
592
+ config: MastraPluginConfig,
572
593
  context: pluginUtils.PluginContextLike | undefined,
573
594
  ): MastraPlugins {
574
595
  const cache = new Map<string, MastraPluginToolkitProvider | null>();
@@ -576,7 +597,7 @@ function buildPluginsMap(
576
597
  get(_target, propName) {
577
598
  if (typeof propName !== "string") return undefined;
578
599
  if (cache.has(propName)) return cache.get(propName) ?? undefined;
579
- const provider = resolveProvider(context, propName);
600
+ const provider = resolveProvider(config, context, propName);
580
601
  cache.set(propName, provider);
581
602
  return provider ?? undefined;
582
603
  },
@@ -587,16 +608,20 @@ function buildPluginsMap(
587
608
  * Pick the right {@link MastraPluginToolkitProvider} for a sibling
588
609
  * plugin lookup. Returns the streaming-aware Genie adapter when the
589
610
  * caller asks for `genie`; falls back to the generic AppKit
590
- * `ToolProvider` adapter for every other plugin name.
611
+ * `ToolProvider` adapter for every other plugin name. `config` is
612
+ * threaded through so Genie's tool can run the chart planner
613
+ * inline against the same model resolver / fallback ladder the
614
+ * agents use.
591
615
  */
592
616
  function resolveProvider(
617
+ config: MastraPluginConfig,
593
618
  context: pluginUtils.PluginContextLike | undefined,
594
619
  propName: string,
595
620
  ): MastraPluginToolkitProvider | null {
596
621
  if (propName === "genie") {
597
622
  const geniePlugin = pluginUtils.instance(context, genie);
598
623
  if (!geniePlugin) return null;
599
- return buildGenieProvider(geniePlugin) as MastraPluginToolkitProvider;
624
+ return buildGenieProvider(geniePlugin, { config }) as MastraPluginToolkitProvider;
600
625
  }
601
626
  const plugin = context?.getPlugins().get(propName);
602
627
  return adaptPluginToolkit(plugin);