@agentproto/adapter-mastra 0.1.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jeremy (agentik.net)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # @agentproto/adapter-mastra
2
+
3
+ Generic Mastra adapter for [AIP-14](https://agentik.net/docs/aip-14)
4
+ `ToolHandle`s. Wraps any tool authored via
5
+ [`@agentproto/tool`](../tool-runtime) into a Mastra `createTool({...})`
6
+ handle.
7
+
8
+ ```ts
9
+ import { defineTool } from "@agentproto/tool"
10
+ import { toMastraTool } from "@agentproto/adapter-mastra"
11
+ import { z } from "zod"
12
+
13
+ const echo = defineTool({
14
+ id: "echo",
15
+ description: "Returns its input.",
16
+ inputSchema: z.object({ message: z.string() }),
17
+ outputSchema: z.object({ echo: z.string() }),
18
+ execute: ({ input }) => ({ echo: input.message }),
19
+ })
20
+
21
+ const mastraEcho = toMastraTool(echo, {
22
+ // Optional: static context fields merged into every invocation.
23
+ contextProvider: () => ({ governanceConfig: getGovernanceConfig() }),
24
+ })
25
+ ```
26
+
27
+ `toMastraTool` produces a Mastra-native handle whose `execute` calls
28
+ `handle.invoke(...)` from the runtime — so input/output validation,
29
+ schema-defined errors, and AIP-14 conformance happen once, regardless of which
30
+ framework consumes the tool.
31
+
32
+ ## Mapping
33
+
34
+ | AIP-14 ToolHandle | Mastra createTool |
35
+ | ---------------------------------- | -------------------------------------------------------- |
36
+ | `id` | `id` |
37
+ | `description` | `description` |
38
+ | `inputSchema` (zod) | `inputSchema` |
39
+ | `outputSchema` (zod) | `outputSchema` |
40
+ | `invoke({input, context})` | `execute(inputData, mastraContext) → handle.invoke(...)` |
41
+ | `mutates`, `approval`, `riskLevel` | `metadata` (Mastra has no first-class fields for these) |
42
+
43
+ ## Spec
44
+
45
+ See [AIP-14](https://agentik.net/docs/aip-14).
@@ -0,0 +1,85 @@
1
+ import { createTool } from '@mastra/core/tools';
2
+ import { ToolContext } from '@agentproto/tool';
3
+ export { ToolError } from '@agentproto/tool';
4
+ import { DriverContext, ToolImplementation } from '@agentproto/driver';
5
+ export { ToolImplementation } from '@agentproto/driver';
6
+
7
+ /**
8
+ * @agentproto/adapter-mastra — Mastra adapter for AIP-30
9
+ * `ToolImplementation`s.
10
+ *
11
+ * One function: {@link toMastraTool} takes a typed `ToolImplementation`
12
+ * (an `(contract, body)` pair produced by
13
+ * {@link "@agentproto/driver".implementTool}) and returns a Mastra
14
+ * `createTool({...})` result. Same role as the AI SDK / LangChain
15
+ * adapters — re-express the canonical typed binding in a host
16
+ * framework's tool shape, without re-declaring the contract metadata.
17
+ *
18
+ * Why `ToolImplementation` (not `(handle, execute)`) is the input:
19
+ * the typed binding flows the contract's `inputSchema`, `outputSchema`,
20
+ * and `contextSchema` generics into the body, so the compiler enforces
21
+ * shape match between body and contract — Solidity's `is IERC20`
22
+ * pattern in TS. An adapter that consumed handle + execute separately
23
+ * would defeat that guarantee.
24
+ *
25
+ * Resolver / multi-provider dispatch: when the body should pick a
26
+ * provider per call instead of being statically bound, the caller
27
+ * wraps `runTool` in `implementTool` once — the adapter is unchanged.
28
+ *
29
+ * ```ts
30
+ * import { implementTool, runTool } from "@agentproto/driver"
31
+ *
32
+ * // Static body:
33
+ * const impl = implementTool(handle, async ({ input, context }) => …)
34
+ *
35
+ * // Resolver-driven body:
36
+ * const dispatchImpl = implementTool(handle, async args =>
37
+ * runTool({ tool: handle, candidates: [...], ...args })
38
+ * )
39
+ * ```
40
+ *
41
+ * Spec: https://agentproto.sh/docs/aip-14, https://agentproto.sh/docs/aip-30
42
+ */
43
+
44
+ /**
45
+ * Per-call context source. Two modes:
46
+ *
47
+ * - **Static** (`{ context }`) — bind a fixed `TContext` once at
48
+ * adapter time. Same value for every invocation. Use for tools
49
+ * whose context is process-scoped (e.g. `governanceConfig` from
50
+ * a single workspace).
51
+ *
52
+ * - **Dynamic** (`{ fromMastraContext }`) — resolve `TContext`
53
+ * per-call from Mastra's native execution context (agent,
54
+ * workflow, requestContext, observability). Use when context
55
+ * depends on per-request state (multi-tenant `guildId`, scoped
56
+ * DB connections, …).
57
+ */
58
+ type MastraContextSource<TContext extends ToolContext> = {
59
+ context: TContext;
60
+ } | {
61
+ fromMastraContext: (mastraContext: unknown) => TContext;
62
+ };
63
+ interface ToMastraToolOptions<TContext extends ToolContext> {
64
+ /** Where the body's `context` arg comes from per call. */
65
+ source: MastraContextSource<TContext>;
66
+ /** Optional provider context (for non-builtin bodies). */
67
+ driverCtx?: DriverContext;
68
+ }
69
+ /**
70
+ * Adapt a {@link ToolImplementation} into a Mastra tool.
71
+ *
72
+ * Type inference: `TContext` is inferred from `impl` only —
73
+ * `options.source` is wrapped in `NoInfer<>` so a literal context
74
+ * doesn't narrow the contract's `TContext` and reject an impl whose
75
+ * body accepts a broader set (TS contravariant-position bug otherwise).
76
+ *
77
+ * Drop the result into `agent.stream({ tools: { [id]: adapted } })`
78
+ * or pass to Mastra's tool registry directly — same shape as
79
+ * authoring with `createTool` by hand, minus the duplication of
80
+ * contract metadata and minus the type drift risk between contract
81
+ * and body.
82
+ */
83
+ declare function toMastraTool<TInput, TOutput, TContext extends ToolContext = ToolContext>(impl: ToolImplementation<TInput, TOutput, TContext>, options: ToMastraToolOptions<NoInfer<TContext>>): ReturnType<typeof createTool>;
84
+
85
+ export { type MastraContextSource, type ToMastraToolOptions, toMastraTool };
package/dist/index.mjs ADDED
@@ -0,0 +1,42 @@
1
+ import { createTool } from '@mastra/core/tools';
2
+ import { toToolError } from '@agentproto/tool';
3
+ export { ToolError } from '@agentproto/tool';
4
+
5
+ /**
6
+ * @agentproto/adapter-mastra v0.1.0-alpha
7
+ * Mastra adapter for AIP-30 ToolImplementations.
8
+ */
9
+
10
+ var DEFAULT_PROVIDER_CTX = Object.freeze({
11
+ secrets: {},
12
+ authState: "authed",
13
+ providerId: "mastra-adapter",
14
+ driverKind: "builtin",
15
+ implementsEntry: { tool: "mastra-adapter", version: "0.0.0" }
16
+ });
17
+ function toMastraTool(impl, options) {
18
+ return createTool({
19
+ id: impl.tool.id,
20
+ description: impl.tool.description,
21
+ inputSchema: impl.tool.inputSchema,
22
+ outputSchema: impl.tool.outputSchema,
23
+ execute: async (inputData, mastraContext) => {
24
+ const context = "context" in options.source ? options.source.context : options.source.fromMastraContext(mastraContext);
25
+ const typedInput = inputData;
26
+ try {
27
+ return await impl.body({
28
+ input: typedInput,
29
+ context,
30
+ driverCtx: options.driverCtx ?? DEFAULT_PROVIDER_CTX,
31
+ signal: mastraContext?.abortSignal ?? new AbortController().signal
32
+ });
33
+ } catch (thrown) {
34
+ throw toToolError(thrown);
35
+ }
36
+ }
37
+ });
38
+ }
39
+
40
+ export { toMastraTool };
41
+ //# sourceMappingURL=index.mjs.map
42
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;AAkDA,IAAM,oBAAA,GAAsC,OAAO,MAAA,CAAO;AAAA,EACxD,SAAS,EAAC;AAAA,EACV,SAAA,EAAW,QAAA;AAAA,EACX,UAAA,EAAY,gBAAA;AAAA,EACZ,UAAA,EAAY,SAAA;AAAA,EACZ,eAAA,EAAiB,EAAE,IAAA,EAAM,gBAAA,EAAkB,SAAS,OAAA;AACtD,CAAC,CAAA;AAyCM,SAAS,YAAA,CAKd,MACA,OAAA,EAC+B;AAC/B,EAAA,OAAO,UAAA,CAAW;AAAA,IAChB,EAAA,EAAI,KAAK,IAAA,CAAK,EAAA;AAAA,IACd,WAAA,EAAa,KAAK,IAAA,CAAK,WAAA;AAAA,IACvB,WAAA,EAAa,KAAK,IAAA,CAAK,WAAA;AAAA,IACvB,YAAA,EAAc,KAAK,IAAA,CAAK,YAAA;AAAA,IACxB,OAAA,EAAS,OAAO,SAAA,EAAW,aAAA,KAAkB;AAG3C,MAAA,MAAM,OAAA,GACJ,SAAA,IAAa,OAAA,CAAQ,MAAA,GACjB,OAAA,CAAQ,OAAO,OAAA,GACf,OAAA,CAAQ,MAAA,CAAO,iBAAA,CAAkB,aAAa,CAAA;AAMpD,MAAA,MAAM,UAAA,GAAqB,SAAA;AAE3B,MAAA,IAAI;AACF,QAAA,OAAO,MAAM,KAAK,IAAA,CAAK;AAAA,UACrB,KAAA,EAAO,UAAA;AAAA,UACP,OAAA;AAAA,UACA,SAAA,EAAW,QAAQ,SAAA,IAAa,oBAAA;AAAA,UAChC,MAAA,EACG,aAAA,EACG,WAAA,IAAe,IAAI,iBAAgB,CAAE;AAAA,SAC5C,CAAA;AAAA,MACH,SAAS,MAAA,EAAQ;AAEf,QAAA,MAAM,YAAY,MAAM,CAAA;AAAA,MAC1B;AAAA,IACF;AAAA,GACD,CAAA;AACH","file":"index.mjs","sourcesContent":["/**\n * @agentproto/adapter-mastra — Mastra adapter for AIP-30\n * `ToolImplementation`s.\n *\n * One function: {@link toMastraTool} takes a typed `ToolImplementation`\n * (an `(contract, body)` pair produced by\n * {@link \"@agentproto/driver\".implementTool}) and returns a Mastra\n * `createTool({...})` result. Same role as the AI SDK / LangChain\n * adapters — re-express the canonical typed binding in a host\n * framework's tool shape, without re-declaring the contract metadata.\n *\n * Why `ToolImplementation` (not `(handle, execute)`) is the input:\n * the typed binding flows the contract's `inputSchema`, `outputSchema`,\n * and `contextSchema` generics into the body, so the compiler enforces\n * shape match between body and contract — Solidity's `is IERC20`\n * pattern in TS. An adapter that consumed handle + execute separately\n * would defeat that guarantee.\n *\n * Resolver / multi-provider dispatch: when the body should pick a\n * provider per call instead of being statically bound, the caller\n * wraps `runTool` in `implementTool` once — the adapter is unchanged.\n *\n * ```ts\n * import { implementTool, runTool } from \"@agentproto/driver\"\n *\n * // Static body:\n * const impl = implementTool(handle, async ({ input, context }) => …)\n *\n * // Resolver-driven body:\n * const dispatchImpl = implementTool(handle, async args =>\n * runTool({ tool: handle, candidates: [...], ...args })\n * )\n * ```\n *\n * Spec: https://agentproto.sh/docs/aip-14, https://agentproto.sh/docs/aip-30\n */\n\nimport { createTool } from \"@mastra/core/tools\"\nimport { toToolError, type ToolContext } from \"@agentproto/tool\"\nimport type {\n DriverContext,\n ToolImplementation,\n} from \"@agentproto/driver\"\n\n/**\n * Default {@link DriverContext} used when the caller doesn't pass\n * one. `kind: \"builtin\"` reflects the typical adapter use-case\n * (in-process bodies that don't read provider secrets / sandbox\n * handles). Override via `bind.driverCtx` for non-builtin bodies.\n */\nconst DEFAULT_PROVIDER_CTX: DriverContext = Object.freeze({\n secrets: {},\n authState: \"authed\",\n providerId: \"mastra-adapter\",\n driverKind: \"builtin\",\n implementsEntry: { tool: \"mastra-adapter\", version: \"0.0.0\" },\n})\n\n/**\n * Per-call context source. Two modes:\n *\n * - **Static** (`{ context }`) — bind a fixed `TContext` once at\n * adapter time. Same value for every invocation. Use for tools\n * whose context is process-scoped (e.g. `governanceConfig` from\n * a single workspace).\n *\n * - **Dynamic** (`{ fromMastraContext }`) — resolve `TContext`\n * per-call from Mastra's native execution context (agent,\n * workflow, requestContext, observability). Use when context\n * depends on per-request state (multi-tenant `guildId`, scoped\n * DB connections, …).\n */\nexport type MastraContextSource<TContext extends ToolContext> =\n | { context: TContext }\n | { fromMastraContext: (mastraContext: unknown) => TContext }\n\nexport interface ToMastraToolOptions<TContext extends ToolContext> {\n /** Where the body's `context` arg comes from per call. */\n source: MastraContextSource<TContext>\n /** Optional provider context (for non-builtin bodies). */\n driverCtx?: DriverContext\n}\n\n/**\n * Adapt a {@link ToolImplementation} into a Mastra tool.\n *\n * Type inference: `TContext` is inferred from `impl` only —\n * `options.source` is wrapped in `NoInfer<>` so a literal context\n * doesn't narrow the contract's `TContext` and reject an impl whose\n * body accepts a broader set (TS contravariant-position bug otherwise).\n *\n * Drop the result into `agent.stream({ tools: { [id]: adapted } })`\n * or pass to Mastra's tool registry directly — same shape as\n * authoring with `createTool` by hand, minus the duplication of\n * contract metadata and minus the type drift risk between contract\n * and body.\n */\nexport function toMastraTool<\n TInput,\n TOutput,\n TContext extends ToolContext = ToolContext,\n>(\n impl: ToolImplementation<TInput, TOutput, TContext>,\n options: ToMastraToolOptions<NoInfer<TContext>>\n): ReturnType<typeof createTool> {\n return createTool({\n id: impl.tool.id,\n description: impl.tool.description,\n inputSchema: impl.tool.inputSchema,\n outputSchema: impl.tool.outputSchema,\n execute: async (inputData, mastraContext) => {\n // Pull context per-call: static binding closes over `options.source.context`;\n // dynamic binding reads from Mastra's native context.\n const context: TContext =\n \"context\" in options.source\n ? options.source.context\n : options.source.fromMastraContext(mastraContext)\n\n // Mastra validates `inputData` against `inputSchema` BEFORE\n // calling execute, so the structural shape matches `TInput` at\n // this point. The local typed binding documents the post-\n // validation contract.\n const typedInput: TInput = inputData as TInput\n\n try {\n return await impl.body({\n input: typedInput,\n context,\n driverCtx: options.driverCtx ?? DEFAULT_PROVIDER_CTX,\n signal:\n (mastraContext as { abortSignal?: AbortSignal } | undefined)\n ?.abortSignal ?? new AbortController().signal,\n })\n } catch (thrown) {\n // Re-throw as a structured error; Mastra catches and surfaces.\n throw toToolError(thrown)\n }\n },\n })\n}\n\nexport { ToolError } from \"@agentproto/tool\"\nexport type { ToolImplementation } from \"@agentproto/driver\"\n"]}
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@agentproto/adapter-mastra",
3
+ "version": "0.1.1",
4
+ "description": "Generic Mastra adapter for AIP-14 ToolHandles. Wraps any `@agentproto/tool` ToolHandle into a Mastra createTool() handle so apps drop in tools authored once and used by any framework.",
5
+ "keywords": [
6
+ "agentproto",
7
+ "aip-14",
8
+ "tool",
9
+ "mastra",
10
+ "adapter",
11
+ "open-standard"
12
+ ],
13
+ "homepage": "https://agentik.net/docs/aip-14",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/agentproto/ts"
17
+ },
18
+ "bugs": {
19
+ "url": "https://github.com/agentproto/ts/issues"
20
+ },
21
+ "license": "MIT",
22
+ "type": "module",
23
+ "main": "dist/index.mjs",
24
+ "module": "dist/index.mjs",
25
+ "types": "dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.mjs",
30
+ "default": "./dist/index.mjs"
31
+ },
32
+ "./package.json": "./package.json"
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "README.md",
37
+ "LICENSE"
38
+ ],
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "dependencies": {
43
+ "@agentproto/driver": "0.1.1",
44
+ "@agentproto/tool": "0.1.1"
45
+ },
46
+ "peerDependencies": {
47
+ "@mastra/core": "*",
48
+ "zod": "^4.0.0"
49
+ },
50
+ "devDependencies": {
51
+ "@mastra/core": "1.32.1",
52
+ "@types/node": "^25.6.2",
53
+ "tsup": "^8.5.1",
54
+ "typescript": "^5.9.3",
55
+ "vitest": "^3.2.4",
56
+ "zod": "^4.4.3",
57
+ "@agentproto/tooling": "0.1.0-alpha.0"
58
+ },
59
+ "scripts": {
60
+ "dev": "tsup --watch",
61
+ "build": "tsup",
62
+ "clean": "rm -rf dist",
63
+ "check-types": "tsc --noEmit",
64
+ "test": "vitest run",
65
+ "test:watch": "vitest"
66
+ }
67
+ }