@agent-native/dispatch 0.10.4 → 0.11.0

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Agent-Native
2
2
 
3
- ### Agentic applications you own.
3
+ ### Open-source framework for agentic applications you own.
4
4
 
5
5
  Don't choose between rich user interfaces and autonomous agents. Every Agent-Native app is both.
6
6
 
@@ -18,17 +18,42 @@ The agent and the UI are equal citizens of the same system. Every action works b
18
18
  - **Reusable integrations** — Connect a provider once in Dispatch, keep secret values in the vault, then grant apps like Brain, Analytics, Mail, and Dispatch access to the shared account metadata and credential refs.
19
19
  - **Apps that improve themselves** — Your apps get better on their own. The agent can add features, fix bugs, and refine the UI over time.
20
20
  - **Any database, any host** — Any SQL database Drizzle supports. Any hosting target Nitro supports. No lock-in.
21
- - **Any AI agent** — Claude Code, Codex, Gemini CLI, OpenCode, or Builder.io. Use whichever agent you prefer.
21
+ - **Any AI agent** — Claude Code, Codex, Cursor, Pi, OpenCode, GitHub Copilot / VS Code, or Builder.io. Use whichever agent you prefer.
22
+
23
+ ## The framework for agent-native apps
24
+
25
+ Agent-Native is an open-source framework for building robust agents that can act inside real apps, not just chat next to them.
26
+
27
+ It gives you primitives for product-grade agentic software: shared actions, SQL-backed state, identity, tools, skills, jobs, observability, and UI surfaces that all work together.
28
+
29
+ Backend agnostic: bring your own database, hosting provider, model stack, and app code.
30
+
31
+ ```ts
32
+ // One action powers UI, agent, HTTP, MCP, A2A, and CLI.
33
+ export default defineAction({
34
+ schema: z.object({
35
+ emailId: z.string(),
36
+ body: z.string(),
37
+ }),
38
+ run: async ({ emailId, body }) => {
39
+ await db.insert(replies).values({ emailId, body });
40
+ },
41
+ });
42
+ ```
43
+
44
+ - **Actions** — Define work once. Use it from UI, agent, API, MCP, A2A, and CLI.
45
+ - **Agent runtime** — Chat, tools, skills, memory, jobs, observability, and handoffs ship together.
46
+ - **Backend agnostic** — Plug in any Drizzle-supported SQL database and Nitro-compatible host.
22
47
 
23
48
  ## Try it with a skill
24
49
 
25
- Don't want to scaffold a whole app yet? Add agent-native superpowers to a coding agent you already use Claude Code, Codex, or Cursor with one command:
50
+ Don't want to scaffold a whole app yet? Add visual planning and PR recaps to Claude Code, Codex, Cursor, Pi, OpenCode, GitHub Copilot / VS Code, and similar agents with one command:
26
51
 
27
52
  ```bash
28
53
  npx @agent-native/core@latest skills add visual-plan
29
54
  ```
30
55
 
31
- It installs the skills, registers the hosted MCP connector, and signs in the selected local client(s) in one step. You get two slash commands that upgrade how your agent plans and reports its work:
56
+ You get two slash commands that upgrade how your agent plans and reports its work:
32
57
 
33
58
  - **`/visual-plan`** — before the agent writes code, it opens a structured, reviewable plan document instead of a wall of text: inline diagrams, UI wireframes and prototypes, file-by-file implementation maps, and annotations you can comment on and approve.
34
59
  - **`/visual-recap`** — after changes land, it turns a PR or git diff into a high-altitude visual recap: schema, API, and file changes rendered as grounded before/after blocks with a shareable review link, instead of scrolling a raw diff.
@@ -37,30 +62,30 @@ See the **[Skills Guide](https://agent-native.com/docs/skills-guide#app-backed-s
37
62
 
38
63
  ## Templates
39
64
 
40
- Start from a complete, production-grade SaaS app — cloneable, not scaffolded. Each one replaces tools you're paying for, except you own everything and can customize it however you want. Not demos; products.
65
+ Start with a full featured template. Each one is a complete, 100% free and open-source SaaS app — cloneable, not scaffolded except you own the code and can customize everything.
41
66
 
42
67
  <table>
43
68
  <tr>
44
69
  <td width="33%" align="center" valign="top">
45
70
 
46
- **Mail**
71
+ **Calendar**
47
72
 
48
- <a href="https://agent-native.com/templates/mail"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F6f49a81c404d4242b33317491eac7575?format=webp&width=800" alt="Mail template" width="100%" /></a>
73
+ <a href="https://agent-native.com/templates/calendar"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2Ffb6c3b483ca24ab3b6c3a758aeceef4c?format=webp&width=800" alt="Calendar template" width="100%" /></a>
49
74
 
50
- **Agent-Native Mail, Superhuman**
75
+ **Agent-Native Google Calendar, Calendly**
51
76
 
52
- Superhuman-style email client with keyboard shortcuts, AI triage, and a fully customizable inbox you own.
77
+ Manage events, sync with Google Calendar, and share a public booking page with AI scheduling.
53
78
 
54
79
  </td>
55
80
  <td width="33%" align="center" valign="top">
56
81
 
57
- **Calendar**
82
+ **Content**
58
83
 
59
- <a href="https://agent-native.com/templates/calendar"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2Ffb6c3b483ca24ab3b6c3a758aeceef4c?format=webp&width=800" alt="Calendar template" width="100%" /></a>
84
+ <a href="https://agent-native.com/templates/content"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F89bcfc6106304bfbaf8ec8a7ccd721eb?format=webp&width=800" alt="Content template" width="100%" /></a>
60
85
 
61
- **Agent-Native Google Calendar, Calendly**
86
+ **Open-source Obsidian for MDX**
62
87
 
63
- Manage events, sync with Google Calendar, and share a public booking page with AI scheduling.
88
+ Edit local Markdown/MDX files, generate rich interactive custom blocks, and draft, rewrite, or publish with an agent.
64
89
 
65
90
  </td>
66
91
  <td width="33%" align="center" valign="top">
@@ -78,17 +103,6 @@ Install `/visual-plan` and `/visual-recap` so your coding agent can plan before
78
103
  <tr>
79
104
  <td width="33%" align="center" valign="top">
80
105
 
81
- **Content**
82
-
83
- <a href="https://agent-native.com/templates/content"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F89bcfc6106304bfbaf8ec8a7ccd721eb?format=webp&width=800" alt="Content template" width="100%" /></a>
84
-
85
- **Agent-Native Notion, Google Docs**
86
-
87
- Write and organize content with an agent that knows your brand and publishing workflow.
88
-
89
- </td>
90
- <td width="33%" align="center" valign="top">
91
-
92
106
  **Slides**
93
107
 
94
108
  <a href="https://agent-native.com/templates/slides"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F2c09b451d40c4a74a89a38d69170c2d8?format=webp&width=800" alt="Slides template" width="100%" /></a>
@@ -100,19 +114,6 @@ Generate and edit React-based presentations via prompt or point-and-click.
100
114
  </td>
101
115
  <td width="33%" align="center" valign="top">
102
116
 
103
- **Video**
104
-
105
- <a href="https://agent-native.com/templates/video"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F6b8bfcc18a1d4c47a491da3b2d4148a4?format=webp&width=800" alt="Video template" width="100%" /></a>
106
-
107
- **Agent-Native video editing**
108
-
109
- Create and edit Remotion video compositions with agent assistance.
110
-
111
- </td>
112
- </tr>
113
- <tr>
114
- <td width="33%" align="center" valign="top">
115
-
116
117
  **Analytics**
117
118
 
118
119
  <a href="https://agent-native.com/templates/analytics"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F4933a80cc3134d7e874631f688be828a?format=webp&width=800" alt="Analytics template" width="100%" /></a>
@@ -132,73 +133,18 @@ Connect analytics data sources, prompt for real charts, and build reusable dashb
132
133
 
133
134
  Record your screen with auto-transcripts, shareable links, and an agent that summarizes, captions, and edits clips on demand.
134
135
 
135
- </td>
136
- <td width="33%" align="center" valign="top">
137
-
138
- **Design**
139
-
140
- <a href="https://agent-native.com/templates/design"><img src="https://cdn.builder.io/api/v1/image/assets%2F348da13fcd8b414c87de9066196f7266%2F961bedb713a94463b834c1f2f4643bcf?format=webp&width=800" alt="Design template" width="100%" /></a>
141
-
142
- **Agent-Native Figma, Canva**
143
-
144
- Create and edit visual designs by prompt or by hand, with the agent as your co-designer.
145
-
146
- </td>
147
- </tr>
148
- <tr>
149
- <td width="33%" align="center" valign="top">
150
-
151
- **Dispatch**
152
-
153
- <a href="https://agent-native.com/templates/dispatch"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F104b3ad8d1dc461aa33ab9bff37a4482?format=webp&width=800" alt="Dispatch template" width="100%" /></a>
154
-
155
- **Mission control for agent-native apps**
156
-
157
- Message, manage, and delegate to agents from Slack, Telegram, or the web. Dispatch is also the control plane for vault secrets, reusable provider connections, app grants, routing, memory, and approvals.
158
-
159
- </td>
160
- <td width="33%" align="center" valign="top">
161
-
162
- **Forms**
163
-
164
- <a href="https://agent-native.com/templates/forms"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F190c3fabd51f4c1bba5aa4e091ad4e9b?format=webp&width=800" alt="Forms template" width="100%" /></a>
165
-
166
- **Agent-Native Typeform**
167
-
168
- Generate forms from a prompt, branch logic with the agent, and own every response in your own database.
169
-
170
- </td>
171
- <td width="33%" align="center" valign="top">
172
-
173
- **Brain**
174
-
175
- <a href="https://agent-native.com/templates/brain"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F9c9fe3b5b9494e33803cd3f494cba356?format=webp&width=800" alt="Brain template" width="100%" /></a>
176
-
177
- **Agent-Native company memory**
178
-
179
- Ask questions over cited company knowledge from approved Slack, meetings, transcripts, GitHub, and decisions.
180
-
181
- </td>
182
- </tr>
183
- <tr>
184
- <td width="33%" align="center" valign="top">
185
-
186
- **Assets**
187
-
188
- <a href="https://agent-native.com/templates/assets"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F769092170a14474f998cbca47384f891?format=webp&width=800" alt="Assets template" width="100%" /></a>
189
-
190
- **Agent-Native asset library**
191
-
192
- Upload, organize, search, and generate on-brand image and video assets that other apps can reuse.
193
-
194
136
  </td>
195
137
  </tr>
196
138
  </table>
197
139
 
198
140
  Every template is a complete cloneable SaaS — fork it, customize it with the agent, own it. Try them with example data before connecting your own sources.
199
141
 
142
+ View the full template gallery at **[agent-native.com/templates](https://agent-native.com/templates)**.
143
+
200
144
  ## Quick Start
201
145
 
146
+ One command to fork a template and start building locally.
147
+
202
148
  ```bash
203
149
  npx @agent-native/core@latest create my-platform
204
150
  cd my-platform
@@ -2,6 +2,21 @@ declare const _default: import("@agent-native/core").ActionDefinition<{
2
2
  provider: string;
3
3
  url?: string | undefined;
4
4
  maxBytes?: unknown;
5
+ maxChars?: unknown;
6
+ responseMode?: "text" | "metadata" | "raw" | "links" | "auto" | "markdown" | "matches" | undefined;
7
+ extract?: "none" | "readability" | "all-visible" | undefined;
8
+ includeLinks?: unknown;
9
+ search?: {
10
+ query?: string | string[] | undefined;
11
+ queries?: string[] | undefined;
12
+ terms?: string[] | undefined;
13
+ regex?: string | undefined;
14
+ regexFlags?: string | undefined;
15
+ source?: "raw" | "extracted" | undefined;
16
+ maxMatches?: unknown;
17
+ contextChars?: unknown;
18
+ caseSensitive?: unknown;
19
+ } | undefined;
5
20
  }, unknown>;
6
21
  export default _default;
7
22
  //# sourceMappingURL=provider-api-docs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider-api-docs.d.ts","sourceRoot":"","sources":["../../src/actions/provider-api-docs.ts"],"names":[],"mappings":";;;;;AAIA,wBA4BG"}
1
+ {"version":3,"file":"provider-api-docs.d.ts","sourceRoot":"","sources":["../../src/actions/provider-api-docs.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAoBA,wBAmDG"}
@@ -1,6 +1,18 @@
1
1
  import { defineAction } from "@agent-native/core";
2
2
  import { z } from "zod";
3
3
  import { fetchProviderApiDocs } from "../server/lib/provider-api.js";
4
+ const BooleanFromQuerySchema = z.preprocess((value) => (typeof value === "string" ? value === "true" : value), z.boolean());
5
+ const WebContentSearchSchema = z.object({
6
+ query: z.union([z.string(), z.array(z.string())]).optional(),
7
+ queries: z.array(z.string()).optional(),
8
+ terms: z.array(z.string()).optional(),
9
+ regex: z.string().optional(),
10
+ regexFlags: z.string().optional(),
11
+ source: z.enum(["extracted", "raw"]).optional(),
12
+ maxMatches: z.coerce.number().int().min(1).max(500).optional(),
13
+ contextChars: z.coerce.number().int().min(0).max(1_000).optional(),
14
+ caseSensitive: BooleanFromQuerySchema.optional(),
15
+ });
4
16
  export default defineAction({
5
17
  description: "Inspect provider API docs/spec metadata, or fetch ANY public API documentation page, OpenAPI spec, changelog, or web page. Registered docs/spec URLs from provider-api-catalog are curated starting points, but any public https/http URL is allowed. Use web-search to find documentation URLs first when uncertain, then fetch them here. SSRF guard still applies — private/internal addresses are blocked.",
6
18
  schema: z.object({
@@ -20,6 +32,23 @@ export default defineAction({
20
32
  .max(4 * 1024 * 1024)
21
33
  .optional()
22
34
  .describe("Maximum response bytes to read. Default 1MB, max 4MB."),
35
+ maxChars: z.coerce
36
+ .number()
37
+ .int()
38
+ .min(1)
39
+ .max(200_000)
40
+ .optional()
41
+ .describe("Maximum extracted content characters to return."),
42
+ responseMode: z
43
+ .enum(["auto", "raw", "text", "markdown", "links", "metadata", "matches"])
44
+ .optional()
45
+ .describe("How to return fetched docs. Default auto extracts HTML to markdown; use matches with search for compact snippets."),
46
+ extract: z
47
+ .enum(["readability", "all-visible", "none"])
48
+ .optional()
49
+ .describe("HTML extraction strategy. Default readability."),
50
+ includeLinks: BooleanFromQuerySchema.optional().describe("Include compact links from extracted HTML. Default true."),
51
+ search: WebContentSearchSchema.optional().describe("Optional post-fetch search over extracted content by default. Supports query, queries, terms, regex, source, maxMatches, and contextChars."),
23
52
  }),
24
53
  http: { method: "GET" },
25
54
  readOnly: true,
@@ -1 +1 @@
1
- {"version":3,"file":"provider-api-docs.js","sourceRoot":"","sources":["../../src/actions/provider-api-docs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErE,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,gZAAgZ;IAClZ,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,CACP,sIAAsI,CACvI;QACH,GAAG,EAAE,CAAC;aACH,MAAM,EAAE;aACR,GAAG,EAAE;aACL,QAAQ,EAAE;aACV,QAAQ,CACP,mNAAmN,CACpN;QACH,QAAQ,EAAE,CAAC,CAAC,MAAM;aACf,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,KAAK,CAAC;aACV,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;aACpB,QAAQ,EAAE;aACV,QAAQ,CAAC,uDAAuD,CAAC;KACrE,CAAC;IACF,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;IACvB,QAAQ,EAAE,IAAI;IACd,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC;CAChD,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { z } from \"zod\";\nimport { fetchProviderApiDocs } from \"../server/lib/provider-api.js\";\n\nexport default defineAction({\n description:\n \"Inspect provider API docs/spec metadata, or fetch ANY public API documentation page, OpenAPI spec, changelog, or web page. Registered docs/spec URLs from provider-api-catalog are curated starting points, but any public https/http URL is allowed. Use web-search to find documentation URLs first when uncertain, then fetch them here. SSRF guard still applies — private/internal addresses are blocked.\",\n schema: z.object({\n provider: z\n .string()\n .min(1)\n .describe(\n \"Provider whose API docs/spec to inspect. Can be a built-in provider id or a custom provider id registered via provider-api-register.\",\n ),\n url: z\n .string()\n .url()\n .optional()\n .describe(\n \"Optional URL to fetch. Can be any public https/http URL — API documentation pages, OpenAPI specs, changelogs, README files, etc. Registered docs/spec URLs from provider-api-catalog are curated starting points.\",\n ),\n maxBytes: z.coerce\n .number()\n .int()\n .min(1_000)\n .max(4 * 1024 * 1024)\n .optional()\n .describe(\"Maximum response bytes to read. Default 1MB, max 4MB.\"),\n }),\n http: { method: \"GET\" },\n readOnly: true,\n run: async (args) => fetchProviderApiDocs(args),\n});\n"]}
1
+ {"version":3,"file":"provider-api-docs.js","sourceRoot":"","sources":["../../src/actions/provider-api-docs.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { z } from \"zod\";\nimport { fetchProviderApiDocs } from \"../server/lib/provider-api.js\";\n\nconst BooleanFromQuerySchema = z.preprocess(\n (value) => (typeof value === \"string\" ? value === \"true\" : value),\n z.boolean(),\n);\nconst WebContentSearchSchema = z.object({\n query: z.union([z.string(), z.array(z.string())]).optional(),\n queries: z.array(z.string()).optional(),\n terms: z.array(z.string()).optional(),\n regex: z.string().optional(),\n regexFlags: z.string().optional(),\n source: z.enum([\"extracted\", \"raw\"]).optional(),\n maxMatches: z.coerce.number().int().min(1).max(500).optional(),\n contextChars: z.coerce.number().int().min(0).max(1_000).optional(),\n caseSensitive: BooleanFromQuerySchema.optional(),\n});\n\nexport default defineAction({\n description:\n \"Inspect provider API docs/spec metadata, or fetch ANY public API documentation page, OpenAPI spec, changelog, or web page. Registered docs/spec URLs from provider-api-catalog are curated starting points, but any public https/http URL is allowed. Use web-search to find documentation URLs first when uncertain, then fetch them here. SSRF guard still applies — private/internal addresses are blocked.\",\n schema: z.object({\n provider: z\n .string()\n .min(1)\n .describe(\n \"Provider whose API docs/spec to inspect. Can be a built-in provider id or a custom provider id registered via provider-api-register.\",\n ),\n url: z\n .string()\n .url()\n .optional()\n .describe(\n \"Optional URL to fetch. Can be any public https/http URL — API documentation pages, OpenAPI specs, changelogs, README files, etc. Registered docs/spec URLs from provider-api-catalog are curated starting points.\",\n ),\n maxBytes: z.coerce\n .number()\n .int()\n .min(1_000)\n .max(4 * 1024 * 1024)\n .optional()\n .describe(\"Maximum response bytes to read. Default 1MB, max 4MB.\"),\n maxChars: z.coerce\n .number()\n .int()\n .min(1)\n .max(200_000)\n .optional()\n .describe(\"Maximum extracted content characters to return.\"),\n responseMode: z\n .enum([\"auto\", \"raw\", \"text\", \"markdown\", \"links\", \"metadata\", \"matches\"])\n .optional()\n .describe(\n \"How to return fetched docs. Default auto extracts HTML to markdown; use matches with search for compact snippets.\",\n ),\n extract: z\n .enum([\"readability\", \"all-visible\", \"none\"])\n .optional()\n .describe(\"HTML extraction strategy. Default readability.\"),\n includeLinks: BooleanFromQuerySchema.optional().describe(\n \"Include compact links from extracted HTML. Default true.\",\n ),\n search: WebContentSearchSchema.optional().describe(\n \"Optional post-fetch search over extracted content by default. Supports query, queries, terms, regex, source, maxMatches, and contextChars.\",\n ),\n }),\n http: { method: \"GET\" },\n readOnly: true,\n run: async (args) => fetchProviderApiDocs(args),\n});\n"]}
@@ -1,4 +1,4 @@
1
- import { type ProviderApiId, type ProviderApiMethod, type ProviderApiRequestArgs } from "@agent-native/core/provider-api";
1
+ import { type ProviderApiDocsOptions, type ProviderApiId, type ProviderApiMethod, type ProviderApiRequestArgs } from "@agent-native/core/provider-api";
2
2
  export declare const DISPATCH_APP_ID = "dispatch";
3
3
  export declare const DISPATCH_PROVIDER_API_IDS: readonly ["amplitude", "apollo", "bigquery", "commonroom", "dataforseo", "ga4", "gcloud", "github", "gmail", "gong", "google_calendar", "google_drive", "granola", "grafana", "hubspot", "jira", "mixpanel", "notion", "posthog", "prometheus", "pylon", "sentry", "slack", "stripe", "twitter"];
4
4
  export type DispatchProviderApiId = ProviderApiId;
@@ -19,10 +19,8 @@ export declare function listProviderApiCatalog(provider?: string): {
19
19
  notes: readonly string[];
20
20
  templateUses: readonly import("@agent-native/core").WorkspaceConnectionTemplateUse[];
21
21
  }[] | Promise<unknown[]>;
22
- export declare function fetchProviderApiDocs(options: {
22
+ export declare function fetchProviderApiDocs(options: ProviderApiDocsOptions & {
23
23
  provider: string;
24
- url?: string;
25
- maxBytes?: number;
26
24
  }): Promise<unknown>;
27
25
  export declare function executeProviderApiRequest(args: ProviderApiRequestArgs): Promise<unknown>;
28
26
  //# sourceMappingURL=provider-api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider-api.d.ts","sourceRoot":"","sources":["../../../src/server/lib/provider-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAC;AAGzC,eAAO,MAAM,eAAe,aAAa,CAAC;AAC1C,eAAO,MAAM,yBAAyB,kSAAmB,CAAC;AAC1D,MAAM,MAAM,qBAAqB,GAAG,aAAa,CAAC;AAClD,YAAY,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,CAAC;AA0C1D,wBAAgB,sBAAsB,CAAC,QAAQ,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;yBAEvD;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,oBAEA;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,sBAAsB,oBAErE"}
1
+ {"version":3,"file":"provider-api.d.ts","sourceRoot":"","sources":["../../../src/server/lib/provider-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,sBAAsB,EAE3B,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAC;AAGzC,eAAO,MAAM,eAAe,aAAa,CAAC;AAC1C,eAAO,MAAM,yBAAyB,kSAAmB,CAAC;AAC1D,MAAM,MAAM,qBAAqB,GAAG,aAAa,CAAC;AAClD,YAAY,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,CAAC;AA0C1D,wBAAgB,sBAAsB,CAAC,QAAQ,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;yBAEvD;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,sBAAsB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,oBAGvD;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,sBAAsB,oBAErE"}
@@ -1 +1 @@
1
- {"version":3,"file":"provider-api.js","sourceRoot":"","sources":["../../../src/server/lib/provider-api.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,mBAAmB,GAIpB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAC;AAC1C,MAAM,CAAC,MAAM,yBAAyB,GAAG,gBAAgB,CAAC;AAI1D,SAAS,UAAU,CAAC,MAAc;IAChC,MAAM,GAAG,GAAG,oBAAoB,EAAE,CAAC;IACnC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,yBAAyB,MAAM,6CAA6C,CAC7E,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,OAAO,GAAG,wBAAwB,CAAC;IACvC,KAAK,EAAE,eAAe;IACtB,qBAAqB,EAAE,gBAAgB;IACvC,oBAAoB,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;IAClD,kBAAkB,EAAE,KAAK,IAAI,EAAE;QAC7B,MAAM,GAAG,GAAG,oBAAoB,EAAE,CAAC;QACnC,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,2DAA2D;QAC3D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;YACvC,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,SAAS,CAAC;YAC1C,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;SACxE,CAAC,CAAC;QACH,MAAM,aAAa,GACjB,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,YAAY,GAChB,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,2EAA2E;QAC3E,iDAAiD;QACjD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAS,gBAAuC,CAAC,CAAC;QACtE,MAAM,MAAM,GAAG,EAAE,CAAC;QAClB,KAAK,MAAM,CAAC,IAAI,CAAC,GAAG,aAAa,EAAE,GAAG,YAAY,CAAC,EAAE,CAAC;YACpD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;gBACpB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,UAAU,sBAAsB,CAAC,QAAiB;IACtD,OAAO,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAIpC;IACC,OAAO,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,IAA4B;IACpE,OAAO,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC","sourcesContent":["import {\n PROVIDER_API_IDS,\n createProviderApiRuntime,\n listCustomProviders,\n type ProviderApiId,\n type ProviderApiMethod,\n type ProviderApiRequestArgs,\n} from \"@agent-native/core/provider-api\";\nimport { getCredentialContext } from \"@agent-native/core/server\";\n\nexport const DISPATCH_APP_ID = \"dispatch\";\nexport const DISPATCH_PROVIDER_API_IDS = PROVIDER_API_IDS;\nexport type DispatchProviderApiId = ProviderApiId;\nexport type { ProviderApiMethod, ProviderApiRequestArgs };\n\nfunction requireCtx(action: string) {\n const ctx = getCredentialContext();\n if (!ctx) {\n throw new Error(\n `Dispatch provider API ${action} requires an authenticated request context.`,\n );\n }\n return ctx;\n}\n\nconst runtime = createProviderApiRuntime({\n appId: DISPATCH_APP_ID,\n localCredentialSource: \"dispatch_local\",\n getCredentialContext: () => requireCtx(\"requests\"),\n getCustomProviders: async () => {\n const ctx = getCredentialContext();\n if (!ctx) return [];\n // Load custom providers for both user scope and org scope.\n const results = await Promise.allSettled([\n listCustomProviders(\"user\", ctx.userEmail),\n ctx.orgId ? listCustomProviders(\"org\", ctx.orgId) : Promise.resolve([]),\n ]);\n const userProviders =\n results[0].status === \"fulfilled\" ? results[0].value : [];\n const orgProviders =\n results[1].status === \"fulfilled\" ? results[1].value : [];\n // Merge: user-scope providers take precedence over org-scope ones with the\n // same id, and neither can shadow a built-in id.\n const seen = new Set<string>(PROVIDER_API_IDS as unknown as string[]);\n const merged = [];\n for (const p of [...userProviders, ...orgProviders]) {\n if (!seen.has(p.id)) {\n seen.add(p.id);\n merged.push(p);\n }\n }\n return merged;\n },\n});\n\nexport function listProviderApiCatalog(provider?: string) {\n return runtime.listCatalog(provider);\n}\n\nexport function fetchProviderApiDocs(options: {\n provider: string;\n url?: string;\n maxBytes?: number;\n}) {\n return runtime.fetchDocs(options);\n}\n\nexport function executeProviderApiRequest(args: ProviderApiRequestArgs) {\n return runtime.executeRequest(args);\n}\n"]}
1
+ {"version":3,"file":"provider-api.js","sourceRoot":"","sources":["../../../src/server/lib/provider-api.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EAExB,mBAAmB,GAIpB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAC;AAC1C,MAAM,CAAC,MAAM,yBAAyB,GAAG,gBAAgB,CAAC;AAI1D,SAAS,UAAU,CAAC,MAAc;IAChC,MAAM,GAAG,GAAG,oBAAoB,EAAE,CAAC;IACnC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,yBAAyB,MAAM,6CAA6C,CAC7E,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,OAAO,GAAG,wBAAwB,CAAC;IACvC,KAAK,EAAE,eAAe;IACtB,qBAAqB,EAAE,gBAAgB;IACvC,oBAAoB,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;IAClD,kBAAkB,EAAE,KAAK,IAAI,EAAE;QAC7B,MAAM,GAAG,GAAG,oBAAoB,EAAE,CAAC;QACnC,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,2DAA2D;QAC3D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;YACvC,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,SAAS,CAAC;YAC1C,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;SACxE,CAAC,CAAC;QACH,MAAM,aAAa,GACjB,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,YAAY,GAChB,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,2EAA2E;QAC3E,iDAAiD;QACjD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAS,gBAAuC,CAAC,CAAC;QACtE,MAAM,MAAM,GAAG,EAAE,CAAC;QAClB,KAAK,MAAM,CAAC,IAAI,CAAC,GAAG,aAAa,EAAE,GAAG,YAAY,CAAC,EAAE,CAAC;YACpD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;gBACpB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,UAAU,sBAAsB,CAAC,QAAiB;IACtD,OAAO,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,OAAsD;IAEtD,OAAO,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,IAA4B;IACpE,OAAO,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC","sourcesContent":["import {\n PROVIDER_API_IDS,\n createProviderApiRuntime,\n type ProviderApiDocsOptions,\n listCustomProviders,\n type ProviderApiId,\n type ProviderApiMethod,\n type ProviderApiRequestArgs,\n} from \"@agent-native/core/provider-api\";\nimport { getCredentialContext } from \"@agent-native/core/server\";\n\nexport const DISPATCH_APP_ID = \"dispatch\";\nexport const DISPATCH_PROVIDER_API_IDS = PROVIDER_API_IDS;\nexport type DispatchProviderApiId = ProviderApiId;\nexport type { ProviderApiMethod, ProviderApiRequestArgs };\n\nfunction requireCtx(action: string) {\n const ctx = getCredentialContext();\n if (!ctx) {\n throw new Error(\n `Dispatch provider API ${action} requires an authenticated request context.`,\n );\n }\n return ctx;\n}\n\nconst runtime = createProviderApiRuntime({\n appId: DISPATCH_APP_ID,\n localCredentialSource: \"dispatch_local\",\n getCredentialContext: () => requireCtx(\"requests\"),\n getCustomProviders: async () => {\n const ctx = getCredentialContext();\n if (!ctx) return [];\n // Load custom providers for both user scope and org scope.\n const results = await Promise.allSettled([\n listCustomProviders(\"user\", ctx.userEmail),\n ctx.orgId ? listCustomProviders(\"org\", ctx.orgId) : Promise.resolve([]),\n ]);\n const userProviders =\n results[0].status === \"fulfilled\" ? results[0].value : [];\n const orgProviders =\n results[1].status === \"fulfilled\" ? results[1].value : [];\n // Merge: user-scope providers take precedence over org-scope ones with the\n // same id, and neither can shadow a built-in id.\n const seen = new Set<string>(PROVIDER_API_IDS as unknown as string[]);\n const merged = [];\n for (const p of [...userProviders, ...orgProviders]) {\n if (!seen.has(p.id)) {\n seen.add(p.id);\n merged.push(p);\n }\n }\n return merged;\n },\n});\n\nexport function listProviderApiCatalog(provider?: string) {\n return runtime.listCatalog(provider);\n}\n\nexport function fetchProviderApiDocs(\n options: ProviderApiDocsOptions & { provider: string },\n) {\n return runtime.fetchDocs(options);\n}\n\nexport function executeProviderApiRequest(args: ProviderApiRequestArgs) {\n return runtime.executeRequest(args);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/dispatch",
3
- "version": "0.10.4",
3
+ "version": "0.11.0",
4
4
  "type": "module",
5
5
  "description": "Dispatch — workspace control plane for agent-native apps. Vault, integrations, destinations, scheduled jobs, and cross-app delegation, shipped as a single drop-in package.",
6
6
  "license": "MIT",
@@ -34,14 +34,6 @@
34
34
  "dist",
35
35
  "src"
36
36
  ],
37
- "scripts": {
38
- "build": "tsc && tsc-alias --resolve-full-paths",
39
- "dev": "tsc --watch & tsc-alias --watch --resolve-full-paths",
40
- "typecheck": "tsc --noEmit",
41
- "test": "vitest --run src --passWithNoTests",
42
- "prepack": "npm run build && cp ../../README.md ./README.md",
43
- "prepublishOnly": "npm run build"
44
- },
45
37
  "peerDependencies": {
46
38
  "@agent-native/core": ">=0.8.0",
47
39
  "react": ">=18",
@@ -97,7 +89,6 @@
97
89
  "zod": "^4.3.6"
98
90
  },
99
91
  "devDependencies": {
100
- "@agent-native/core": "workspace:*",
101
92
  "@react-router/dev": "^7.16.0",
102
93
  "@types/node": "^24.2.1",
103
94
  "@types/react": "^19.2.14",
@@ -107,7 +98,14 @@
107
98
  "react-router": "^7.16.0",
108
99
  "tsc-alias": "^1.8.10",
109
100
  "typescript": "^6.0.3",
110
- "vite": "catalog:",
111
- "vitest": "^4.1.5"
101
+ "vite": "8.0.3",
102
+ "vitest": "^4.1.5",
103
+ "@agent-native/core": "0.54.0"
104
+ },
105
+ "scripts": {
106
+ "build": "tsc && tsc-alias --resolve-full-paths",
107
+ "dev": "tsc --watch & tsc-alias --watch --resolve-full-paths",
108
+ "typecheck": "tsc --noEmit",
109
+ "test": "vitest --run src --passWithNoTests"
112
110
  }
113
- }
111
+ }
@@ -2,6 +2,22 @@ import { defineAction } from "@agent-native/core";
2
2
  import { z } from "zod";
3
3
  import { fetchProviderApiDocs } from "../server/lib/provider-api.js";
4
4
 
5
+ const BooleanFromQuerySchema = z.preprocess(
6
+ (value) => (typeof value === "string" ? value === "true" : value),
7
+ z.boolean(),
8
+ );
9
+ const WebContentSearchSchema = z.object({
10
+ query: z.union([z.string(), z.array(z.string())]).optional(),
11
+ queries: z.array(z.string()).optional(),
12
+ terms: z.array(z.string()).optional(),
13
+ regex: z.string().optional(),
14
+ regexFlags: z.string().optional(),
15
+ source: z.enum(["extracted", "raw"]).optional(),
16
+ maxMatches: z.coerce.number().int().min(1).max(500).optional(),
17
+ contextChars: z.coerce.number().int().min(0).max(1_000).optional(),
18
+ caseSensitive: BooleanFromQuerySchema.optional(),
19
+ });
20
+
5
21
  export default defineAction({
6
22
  description:
7
23
  "Inspect provider API docs/spec metadata, or fetch ANY public API documentation page, OpenAPI spec, changelog, or web page. Registered docs/spec URLs from provider-api-catalog are curated starting points, but any public https/http URL is allowed. Use web-search to find documentation URLs first when uncertain, then fetch them here. SSRF guard still applies — private/internal addresses are blocked.",
@@ -26,6 +42,29 @@ export default defineAction({
26
42
  .max(4 * 1024 * 1024)
27
43
  .optional()
28
44
  .describe("Maximum response bytes to read. Default 1MB, max 4MB."),
45
+ maxChars: z.coerce
46
+ .number()
47
+ .int()
48
+ .min(1)
49
+ .max(200_000)
50
+ .optional()
51
+ .describe("Maximum extracted content characters to return."),
52
+ responseMode: z
53
+ .enum(["auto", "raw", "text", "markdown", "links", "metadata", "matches"])
54
+ .optional()
55
+ .describe(
56
+ "How to return fetched docs. Default auto extracts HTML to markdown; use matches with search for compact snippets.",
57
+ ),
58
+ extract: z
59
+ .enum(["readability", "all-visible", "none"])
60
+ .optional()
61
+ .describe("HTML extraction strategy. Default readability."),
62
+ includeLinks: BooleanFromQuerySchema.optional().describe(
63
+ "Include compact links from extracted HTML. Default true.",
64
+ ),
65
+ search: WebContentSearchSchema.optional().describe(
66
+ "Optional post-fetch search over extracted content by default. Supports query, queries, terms, regex, source, maxMatches, and contextChars.",
67
+ ),
29
68
  }),
30
69
  http: { method: "GET" },
31
70
  readOnly: true,
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  PROVIDER_API_IDS,
3
3
  createProviderApiRuntime,
4
+ type ProviderApiDocsOptions,
4
5
  listCustomProviders,
5
6
  type ProviderApiId,
6
7
  type ProviderApiMethod,
@@ -57,11 +58,9 @@ export function listProviderApiCatalog(provider?: string) {
57
58
  return runtime.listCatalog(provider);
58
59
  }
59
60
 
60
- export function fetchProviderApiDocs(options: {
61
- provider: string;
62
- url?: string;
63
- maxBytes?: number;
64
- }) {
61
+ export function fetchProviderApiDocs(
62
+ options: ProviderApiDocsOptions & { provider: string },
63
+ ) {
65
64
  return runtime.fetchDocs(options);
66
65
  }
67
66