@agent-native/dispatch 0.9.3 → 0.10.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
@@ -11,6 +11,7 @@ The agent and the UI are equal citizens of the same system. Every action works b
11
11
  ![Agents and UIs fully connected](https://cdn.builder.io/api/v1/file/assets%2FYJIGb4i01jvw0SRdL5Bt%2Fadc1e9e9368e4a8cb1b4dbb5aae5aaa2)
12
12
 
13
13
  - **Everything syncs** — Agent and UI share one database and one state. Changes from either side show up instantly on the other.
14
+ - **Real-time multiplayer** — Humans and agents collaborate in the same document simultaneously: CRDT merging, live presence (cursors, selection rings, who's on which slide), and the agent as a first-class peer editor. Works on any SQL database and any host, including serverless.
14
15
  - **Context-aware** — The agent knows what you're looking at. Select text, hit Cmd+I, and tell it what to do.
15
16
  - **Per-user workspace** — Skills, memory, instructions, sub-agents, and MCP servers — SQL-backed, customizable per user. Claude-Code-level flexibility, SaaS-grade economics.
16
17
  - **Agents call agents** — Tag another agent from any app. They discover each other over A2A and take action across your stack.
@@ -19,6 +20,21 @@ The agent and the UI are equal citizens of the same system. Every action works b
19
20
  - **Any database, any host** — Any SQL database Drizzle supports. Any hosting target Nitro supports. No lock-in.
20
21
  - **Any AI agent** — Claude Code, Codex, Gemini CLI, OpenCode, or Builder.io. Use whichever agent you prefer.
21
22
 
23
+ ## Try it with a skill
24
+
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:
26
+
27
+ ```bash
28
+ npx @agent-native/core@latest skills add visual-plan
29
+ ```
30
+
31
+ It installs the skills, registers the hosted MCP connector, and signs you in in one step. You get two slash commands that upgrade how your agent plans and reports its work:
32
+
33
+ - **`/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
+ - **`/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.
35
+
36
+ See the **[Skills Guide](https://agent-native.com/docs/skills-guide#app-backed-skills)** for more skills and local installs.
37
+
22
38
  ## Templates
23
39
 
24
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.
@@ -49,6 +65,19 @@ Manage events, sync with Google Calendar, and share a public booking page with A
49
65
  </td>
50
66
  <td width="33%" align="center" valign="top">
51
67
 
68
+ **Plans**
69
+
70
+ <a href="https://agent-native.com/templates/plan"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2Fb6f4213ac7cc42eeb10c12e8ccda8936?format=webp&width=800" alt="Plans template" width="100%" /></a>
71
+
72
+ **Visual plan mode for coding agents**
73
+
74
+ Install `/visual-plan` and `/visual-recap` so your coding agent can plan before it builds and recap changes after they land — high-level code reviews with diagrams, wireframes, annotations, and review links.
75
+
76
+ </td>
77
+ </tr>
78
+ <tr>
79
+ <td width="33%" align="center" valign="top">
80
+
52
81
  **Content**
53
82
 
54
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>
@@ -58,8 +87,6 @@ Manage events, sync with Google Calendar, and share a public booking page with A
58
87
  Write and organize content with an agent that knows your brand and publishing workflow.
59
88
 
60
89
  </td>
61
- </tr>
62
- <tr>
63
90
  <td width="33%" align="center" valign="top">
64
91
 
65
92
  **Slides**
@@ -82,6 +109,8 @@ Generate and edit React-based presentations via prompt or point-and-click.
82
109
  Create and edit Remotion video compositions with agent assistance.
83
110
 
84
111
  </td>
112
+ </tr>
113
+ <tr>
85
114
  <td width="33%" align="center" valign="top">
86
115
 
87
116
  **Analytics**
@@ -93,8 +122,6 @@ Create and edit Remotion video compositions with agent assistance.
93
122
  Connect analytics data sources, prompt for real charts, and build reusable dashboards. Shared workspace connections can provide provider credentials, while Analytics still owns metrics, source-of-truth choices, and saved analyses.
94
123
 
95
124
  </td>
96
- </tr>
97
- <tr>
98
125
  <td width="33%" align="center" valign="top">
99
126
 
100
127
  **Clips**
@@ -117,6 +144,8 @@ Record your screen with auto-transcripts, shareable links, and an agent that sum
117
144
  Create and edit visual designs by prompt or by hand, with the agent as your co-designer.
118
145
 
119
146
  </td>
147
+ </tr>
148
+ <tr>
120
149
  <td width="33%" align="center" valign="top">
121
150
 
122
151
  **Dispatch**
@@ -128,8 +157,6 @@ Create and edit visual designs by prompt or by hand, with the agent as your co-d
128
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.
129
158
 
130
159
  </td>
131
- </tr>
132
- <tr>
133
160
  <td width="33%" align="center" valign="top">
134
161
 
135
162
  **Forms**
@@ -145,18 +172,20 @@ Generate forms from a prompt, branch logic with the agent, and own every respons
145
172
 
146
173
  **Brain**
147
174
 
148
- <a href="https://agent-native.com/templates/brain">Brain template</a>
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>
149
176
 
150
177
  **Agent-Native company memory**
151
178
 
152
179
  Ask questions over cited company knowledge from approved Slack, meetings, transcripts, GitHub, and decisions.
153
180
 
154
181
  </td>
182
+ </tr>
183
+ <tr>
155
184
  <td width="33%" align="center" valign="top">
156
185
 
157
186
  **Assets**
158
187
 
159
- <a href="https://agent-native.com/templates/assets">Assets template</a>
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>
160
189
 
161
190
  **Agent-Native asset library**
162
191
 
@@ -185,50 +214,6 @@ Want a single app, no monorepo? Use `--standalone`:
185
214
  npx @agent-native/core create my-app --standalone --template mail
186
215
  ```
187
216
 
188
- Need a coding agent workspace? `agent-native` or `agent-native code` opens an open-source Claude Code/Codex-like Code workspace with no prompt required. From there, type a task, run slash goals interactively, or call them directly from your shell:
189
-
190
- ```bash
191
- npx @agent-native/core@latest
192
- npx @agent-native/core@latest "fix the failing auth tests"
193
- npx @agent-native/core@latest code
194
- npx @agent-native/core@latest code "fix the failing auth tests"
195
- npx @agent-native/core@latest code exec "fix the failing auth tests"
196
- npx @agent-native/core@latest code -p "fix the failing auth tests"
197
- npx @agent-native/core@latest code --plan "explain the auth test failures"
198
- npx @agent-native/core@latest code --auto "fix the failing auth tests"
199
- npx @agent-native/core@latest code /migrate ./my-next-app --out ../migrated-app
200
- npx @agent-native/core@latest code /migrate ./my-next-app --emit ../migration-dossier
201
- npx @agent-native/core@latest code list
202
- npx @agent-native/core@latest code status --last
203
- npx @agent-native/core@latest code attach --last
204
- npx @agent-native/core@latest code logs --last
205
- npx @agent-native/core@latest code stop --last
206
- npx @agent-native/core@latest code ui
207
- npx @agent-native/core@latest code approve --last
208
- npx @agent-native/core@latest code resume --last
209
- npx @agent-native/core@latest code --continue "check the auth edge cases next"
210
- npx @agent-native/core@latest code resume --last "check the auth edge cases next"
211
- ```
212
-
213
- Slash goals can run from the interactive shell or directly from the command line, and `agent-native code goals` shows the goals registered in your checkout. A bare prompt starts a local coding-agent session, streams work, records transcript/status/tool events, and accepts follow-up prompts; `/migrate` is one specialized capability inside that general Code workspace. Project-specific slash commands live in `.agents/commands/*.md`, so teams can add prompts such as `/release-check` or `/migrate-commerce` without changing the framework. Installed `agent-native` with no arguments launches the Code workspace; `agent-native "fix tests"` starts an Agent-Native Code task directly. Use `agent-native create` when you want to create apps or workspaces.
214
-
215
- Working inside this repository? Use `pnpm dev` for the lazy framework dev gateway. It exposes the core templates on one local origin and starts each app only when you visit it, which keeps memory usage much lower than booting every server at once. To focus on specific templates, pass `--apps`, for example `pnpm dev -- --apps analytics,brain`. Use `pnpm dev:eager` only when you intentionally want the older eager mode that starts the selected template servers, frame, docs, and core watcher immediately. The old `pnpm dev:all` name still works as an alias for eager mode.
216
-
217
- Use `pnpm dev:cli ...` to run the source CLI without building first, for example `pnpm dev:cli --help` or `pnpm dev:cli code goals`.
218
-
219
- The Code workspace uses the familiar Codex/Claude-style session loop: pick a previous session, list runs, check status, attach to live output, print logs, stop work, resume with context, open the local UI, and continue the same run from Desktop or CLI. The Desktop Code tab, `agent-native code ui`, background sessions, and sub-agent sessions all converge on the shared run harness/controller model instead of separate ad hoc runners. The primary modes are intentionally simple:
220
-
221
- - **Plan mode** (`--plan`) inspects, explains, and proposes without writing files.
222
- - **Auto mode** (`--auto`, default) edits files, runs checks, and only pauses for genuinely destructive file, git, publish, or data operations.
223
-
224
- `agent-native migrate` still works as a direct shortcut; `code /migrate` is the Agent-Native Code entrypoint for the migration goal. By default it creates an Agent-Native Code session and portable migration dossier, not a scaffolded app/template. `resume --last` reopens the latest run handoff; adding a quoted prompt records it as a follow-up transcript event for that run so the next active coding agent can pick it up. If a high-risk command is paused for approval, `code approve --last` runs that one pending command and then points you back to resume the session. Use `--app-surface` only when you want the legacy hidden migration detail app for assessment, approval, tasks, artifacts, and verification.
225
- Use `--emit` when you want only the portable dossier for Codex, Claude Code, Cursor, or another coding agent.
226
- Agent-Native Code also includes lightweight goals such as `/audit`:
227
-
228
- ```bash
229
- npx @agent-native/core@latest code /audit --url https://example.com
230
- ```
231
-
232
217
  ## Workspaces (Monorepo)
233
218
 
234
219
  A workspace is the default shape of an agent-native project. Every app sits under `apps/`, and `packages/shared/` is available for the small amount of code, instructions, skills, or branding that should truly apply to every app.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAqF7D;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAqFvD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAsF7D;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAsFvD,CAAC"}
@@ -56,6 +56,7 @@ import previewDreamProposal from "./preview-dream-proposal.js";
56
56
  import previewWorkspaceResourceChange from "./preview-workspace-resource-change.js";
57
57
  import providerApiCatalog from "./provider-api-catalog.js";
58
58
  import providerApiDocs from "./provider-api-docs.js";
59
+ import providerApiRegister from "./provider-api-register.js";
59
60
  import providerApiRequest from "./provider-api-request.js";
60
61
  import rejectDispatchChange from "./reject-dispatch-change.js";
61
62
  import rejectDreamProposal from "./reject-dream-proposal.js";
@@ -146,6 +147,7 @@ export const dispatchActions = {
146
147
  "preview-workspace-resource-change": previewWorkspaceResourceChange,
147
148
  "provider-api-catalog": providerApiCatalog,
148
149
  "provider-api-docs": providerApiDocs,
150
+ "provider-api-register": providerApiRegister,
149
151
  "provider-api-request": providerApiRequest,
150
152
  "reject-dispatch-change": rejectDispatchChange,
151
153
  "reject-dream-proposal": rejectDreamProposal,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ActionEntry } from \"@agent-native/core/server\";\nimport approveDispatchChange from \"./approve-dispatch-change.js\";\nimport approveVaultRequest from \"./approve-vault-request.js\";\nimport archiveWorkspaceApp from \"./archive-workspace-app.js\";\nimport askApp from \"./ask_app.js\";\nimport createLinkToken from \"./create-link-token.js\";\nimport createPylonTicket from \"./create-pylon-ticket.js\";\nimport createVaultGrant from \"./create-vault-grant.js\";\nimport createVaultSecret from \"./create-vault-secret.js\";\nimport createWorkspaceResourceGrant from \"./create-workspace-resource-grant.js\";\nimport createWorkspaceResource from \"./create-workspace-resource.js\";\nimport createDreamReport from \"./create-dream-report.js\";\nimport createEmbedSession from \"./create_embed_session.js\";\nimport deleteDestination from \"./delete-destination.js\";\nimport deleteVaultSecret from \"./delete-vault-secret.js\";\nimport deleteWorkspaceResource from \"./delete-workspace-resource.js\";\nimport denyVaultRequest from \"./deny-vault-request.js\";\nimport ensureDreamJob from \"./ensure-dream-job.js\";\nimport getAppCreationSettings from \"./get-app-creation-settings.js\";\nimport getAgentThreadDebug from \"./get-agent-thread-debug.js\";\nimport getDream from \"./get-dream.js\";\nimport getDreamSettings from \"./get-dream-settings.js\";\nimport getDispatchSettings from \"./get-dispatch-settings.js\";\nimport getVaultAccessSettings from \"./get-vault-access-settings.js\";\nimport getWorkspaceResourceEffectiveContext from \"./get-workspace-resource-effective-context.js\";\nimport getWorkspaceInfo from \"./get-workspace-info.js\";\nimport grantWorkspaceResourcesToApp from \"./grant-workspace-resources-to-app.js\";\nimport grantVaultSecretsToApp from \"./grant-vault-secrets-to-app.js\";\nimport listAgentThreadSources from \"./list-agent-thread-sources.js\";\nimport listAvailableWorkspaceTemplates from \"./list-available-workspace-templates.js\";\nimport listConnectedAgents from \"./list-connected-agents.js\";\nimport listDestinations from \"./list-destinations.js\";\nimport listDispatchApprovals from \"./list-dispatch-approvals.js\";\nimport listDispatchAudit from \"./list-dispatch-audit.js\";\nimport listDispatchOverview from \"./list-dispatch-overview.js\";\nimport listDispatchUsageMetrics from \"./list-dispatch-usage-metrics.js\";\nimport listDreamCandidates from \"./list-dream-candidates.js\";\nimport listDreams from \"./list-dreams.js\";\nimport listIntegrationsCatalog from \"./list-integrations-catalog.js\";\nimport listLinkedIdentities from \"./list-linked-identities.js\";\nimport listMcpAppAccess from \"./list-mcp-app-access.js\";\nimport listApps from \"./list_apps.js\";\nimport listVaultAudit from \"./list-vault-audit.js\";\nimport listVaultGrants from \"./list-vault-grants.js\";\nimport listVaultRequests from \"./list-vault-requests.js\";\nimport listVaultSecretOptions from \"./list-vault-secret-options.js\";\nimport listVaultSecrets from \"./list-vault-secrets.js\";\nimport listWorkspaceApps from \"./list-workspace-apps.js\";\nimport listWorkspaceResourceOptions from \"./list-workspace-resource-options.js\";\nimport listWorkspaceResourceGrants from \"./list-workspace-resource-grants.js\";\nimport listWorkspaceResourcesForApp from \"./list-workspace-resources-for-app.js\";\nimport listWorkspaceResources from \"./list-workspace-resources.js\";\nimport navigate from \"./navigate.js\";\nimport openApp from \"./open_app.js\";\nimport applyDreamProposal from \"./apply-dream-proposal.js\";\nimport previewDreamProposal from \"./preview-dream-proposal.js\";\nimport previewWorkspaceResourceChange from \"./preview-workspace-resource-change.js\";\nimport providerApiCatalog from \"./provider-api-catalog.js\";\nimport providerApiDocs from \"./provider-api-docs.js\";\nimport providerApiRequest from \"./provider-api-request.js\";\nimport rejectDispatchChange from \"./reject-dispatch-change.js\";\nimport rejectDreamProposal from \"./reject-dream-proposal.js\";\nimport removePendingWorkspaceApp from \"./remove-pending-workspace-app.js\";\nimport requestVaultSecret from \"./request-vault-secret.js\";\nimport revokeVaultGrant from \"./revoke-vault-grant.js\";\nimport revokeWorkspaceResourceGrant from \"./revoke-workspace-resource-grant.js\";\nimport restoreStarterWorkspaceResources from \"./restore-starter-workspace-resources.js\";\nimport scaffoldWorkspaceApp from \"./scaffold-workspace-app.js\";\nimport searchAgentThreads from \"./search-agent-threads.js\";\nimport sendCodeAgentRemoteCommand from \"./send-code-agent-remote-command.js\";\nimport sendPlatformMessage from \"./send-platform-message.js\";\nimport setAppCreationSettings from \"./set-app-creation-settings.js\";\nimport setDispatchApprovalPolicy from \"./set-dispatch-approval-policy.js\";\nimport setDreamSettings from \"./set-dream-settings.js\";\nimport setMcpAppAccess from \"./set-mcp-app-access.js\";\nimport setVaultAccessSettings from \"./set-vault-access-settings.js\";\nimport startWorkspaceAppCreation from \"./start-workspace-app-creation.js\";\nimport syncVaultToApp from \"./sync-vault-to-app.js\";\nimport unarchiveWorkspaceApp from \"./unarchive-workspace-app.js\";\nimport updateWorkspaceAppMetadata from \"./update-workspace-app-metadata.js\";\nimport updateVaultSecret from \"./update-vault-secret.js\";\nimport updateWorkspaceResource from \"./update-workspace-resource.js\";\nimport upsertDestination from \"./upsert-destination.js\";\nimport viewScreen from \"./view-screen.js\";\n\n/**\n * Dispatch's actions registered as a flat name→entry map. Imported by\n * `@agent-native/dispatch/server`'s side-effect block, which calls\n * `registerPackageActions(dispatchActions)` so the framework's action\n * loader picks them up.\n */\nexport const dispatchActions: Record<string, ActionEntry> = {\n \"approve-dispatch-change\": approveDispatchChange,\n \"approve-vault-request\": approveVaultRequest,\n \"archive-workspace-app\": archiveWorkspaceApp,\n ask_app: askApp,\n \"create-link-token\": createLinkToken,\n \"create-pylon-ticket\": createPylonTicket,\n \"create-vault-grant\": createVaultGrant,\n \"create-vault-secret\": createVaultSecret,\n \"create-workspace-resource-grant\": createWorkspaceResourceGrant,\n \"create-workspace-resource\": createWorkspaceResource,\n \"create-dream-report\": createDreamReport,\n create_embed_session: createEmbedSession,\n \"delete-destination\": deleteDestination,\n \"delete-vault-secret\": deleteVaultSecret,\n \"delete-workspace-resource\": deleteWorkspaceResource,\n \"deny-vault-request\": denyVaultRequest,\n \"ensure-dream-job\": ensureDreamJob,\n \"get-app-creation-settings\": getAppCreationSettings,\n \"get-agent-thread-debug\": getAgentThreadDebug,\n \"get-dream\": getDream,\n \"get-dream-settings\": getDreamSettings,\n \"get-dispatch-settings\": getDispatchSettings,\n \"get-vault-access-settings\": getVaultAccessSettings,\n \"get-workspace-resource-effective-context\":\n getWorkspaceResourceEffectiveContext,\n \"get-workspace-info\": getWorkspaceInfo,\n \"grant-workspace-resources-to-app\": grantWorkspaceResourcesToApp,\n \"grant-vault-secrets-to-app\": grantVaultSecretsToApp,\n \"list-agent-thread-sources\": listAgentThreadSources,\n \"list-available-workspace-templates\": listAvailableWorkspaceTemplates,\n \"list-connected-agents\": listConnectedAgents,\n \"list-destinations\": listDestinations,\n \"list-dispatch-approvals\": listDispatchApprovals,\n \"list-dispatch-audit\": listDispatchAudit,\n \"list-dispatch-overview\": listDispatchOverview,\n \"list-dispatch-usage-metrics\": listDispatchUsageMetrics,\n \"list-dream-candidates\": listDreamCandidates,\n \"list-dreams\": listDreams,\n \"list-integrations-catalog\": listIntegrationsCatalog,\n \"list-linked-identities\": listLinkedIdentities,\n \"list-mcp-app-access\": listMcpAppAccess,\n list_apps: listApps,\n \"list-vault-audit\": listVaultAudit,\n \"list-vault-grants\": listVaultGrants,\n \"list-vault-requests\": listVaultRequests,\n \"list-vault-secret-options\": listVaultSecretOptions,\n \"list-vault-secrets\": listVaultSecrets,\n \"list-workspace-apps\": listWorkspaceApps,\n \"list-workspace-resource-options\": listWorkspaceResourceOptions,\n \"list-workspace-resource-grants\": listWorkspaceResourceGrants,\n \"list-workspace-resources-for-app\": listWorkspaceResourcesForApp,\n \"list-workspace-resources\": listWorkspaceResources,\n navigate: navigate,\n open_app: openApp,\n \"apply-dream-proposal\": applyDreamProposal,\n \"preview-dream-proposal\": previewDreamProposal,\n \"preview-workspace-resource-change\": previewWorkspaceResourceChange,\n \"provider-api-catalog\": providerApiCatalog,\n \"provider-api-docs\": providerApiDocs,\n \"provider-api-request\": providerApiRequest,\n \"reject-dispatch-change\": rejectDispatchChange,\n \"reject-dream-proposal\": rejectDreamProposal,\n \"remove-pending-workspace-app\": removePendingWorkspaceApp,\n \"request-vault-secret\": requestVaultSecret,\n \"revoke-vault-grant\": revokeVaultGrant,\n \"revoke-workspace-resource-grant\": revokeWorkspaceResourceGrant,\n \"restore-starter-workspace-resources\": restoreStarterWorkspaceResources,\n \"scaffold-workspace-app\": scaffoldWorkspaceApp,\n \"search-agent-threads\": searchAgentThreads,\n \"send-code-agent-remote-command\": sendCodeAgentRemoteCommand,\n \"send-platform-message\": sendPlatformMessage,\n \"set-app-creation-settings\": setAppCreationSettings,\n \"set-dispatch-approval-policy\": setDispatchApprovalPolicy,\n \"set-dream-settings\": setDreamSettings,\n \"set-mcp-app-access\": setMcpAppAccess,\n \"set-vault-access-settings\": setVaultAccessSettings,\n \"start-workspace-app-creation\": startWorkspaceAppCreation,\n \"sync-vault-to-app\": syncVaultToApp,\n \"unarchive-workspace-app\": unarchiveWorkspaceApp,\n \"update-workspace-app-metadata\": updateWorkspaceAppMetadata,\n \"update-vault-secret\": updateVaultSecret,\n \"update-workspace-resource\": updateWorkspaceResource,\n \"upsert-destination\": upsertDestination,\n \"view-screen\": viewScreen,\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ActionEntry } from \"@agent-native/core/server\";\nimport approveDispatchChange from \"./approve-dispatch-change.js\";\nimport approveVaultRequest from \"./approve-vault-request.js\";\nimport archiveWorkspaceApp from \"./archive-workspace-app.js\";\nimport askApp from \"./ask_app.js\";\nimport createLinkToken from \"./create-link-token.js\";\nimport createPylonTicket from \"./create-pylon-ticket.js\";\nimport createVaultGrant from \"./create-vault-grant.js\";\nimport createVaultSecret from \"./create-vault-secret.js\";\nimport createWorkspaceResourceGrant from \"./create-workspace-resource-grant.js\";\nimport createWorkspaceResource from \"./create-workspace-resource.js\";\nimport createDreamReport from \"./create-dream-report.js\";\nimport createEmbedSession from \"./create_embed_session.js\";\nimport deleteDestination from \"./delete-destination.js\";\nimport deleteVaultSecret from \"./delete-vault-secret.js\";\nimport deleteWorkspaceResource from \"./delete-workspace-resource.js\";\nimport denyVaultRequest from \"./deny-vault-request.js\";\nimport ensureDreamJob from \"./ensure-dream-job.js\";\nimport getAppCreationSettings from \"./get-app-creation-settings.js\";\nimport getAgentThreadDebug from \"./get-agent-thread-debug.js\";\nimport getDream from \"./get-dream.js\";\nimport getDreamSettings from \"./get-dream-settings.js\";\nimport getDispatchSettings from \"./get-dispatch-settings.js\";\nimport getVaultAccessSettings from \"./get-vault-access-settings.js\";\nimport getWorkspaceResourceEffectiveContext from \"./get-workspace-resource-effective-context.js\";\nimport getWorkspaceInfo from \"./get-workspace-info.js\";\nimport grantWorkspaceResourcesToApp from \"./grant-workspace-resources-to-app.js\";\nimport grantVaultSecretsToApp from \"./grant-vault-secrets-to-app.js\";\nimport listAgentThreadSources from \"./list-agent-thread-sources.js\";\nimport listAvailableWorkspaceTemplates from \"./list-available-workspace-templates.js\";\nimport listConnectedAgents from \"./list-connected-agents.js\";\nimport listDestinations from \"./list-destinations.js\";\nimport listDispatchApprovals from \"./list-dispatch-approvals.js\";\nimport listDispatchAudit from \"./list-dispatch-audit.js\";\nimport listDispatchOverview from \"./list-dispatch-overview.js\";\nimport listDispatchUsageMetrics from \"./list-dispatch-usage-metrics.js\";\nimport listDreamCandidates from \"./list-dream-candidates.js\";\nimport listDreams from \"./list-dreams.js\";\nimport listIntegrationsCatalog from \"./list-integrations-catalog.js\";\nimport listLinkedIdentities from \"./list-linked-identities.js\";\nimport listMcpAppAccess from \"./list-mcp-app-access.js\";\nimport listApps from \"./list_apps.js\";\nimport listVaultAudit from \"./list-vault-audit.js\";\nimport listVaultGrants from \"./list-vault-grants.js\";\nimport listVaultRequests from \"./list-vault-requests.js\";\nimport listVaultSecretOptions from \"./list-vault-secret-options.js\";\nimport listVaultSecrets from \"./list-vault-secrets.js\";\nimport listWorkspaceApps from \"./list-workspace-apps.js\";\nimport listWorkspaceResourceOptions from \"./list-workspace-resource-options.js\";\nimport listWorkspaceResourceGrants from \"./list-workspace-resource-grants.js\";\nimport listWorkspaceResourcesForApp from \"./list-workspace-resources-for-app.js\";\nimport listWorkspaceResources from \"./list-workspace-resources.js\";\nimport navigate from \"./navigate.js\";\nimport openApp from \"./open_app.js\";\nimport applyDreamProposal from \"./apply-dream-proposal.js\";\nimport previewDreamProposal from \"./preview-dream-proposal.js\";\nimport previewWorkspaceResourceChange from \"./preview-workspace-resource-change.js\";\nimport providerApiCatalog from \"./provider-api-catalog.js\";\nimport providerApiDocs from \"./provider-api-docs.js\";\nimport providerApiRegister from \"./provider-api-register.js\";\nimport providerApiRequest from \"./provider-api-request.js\";\nimport rejectDispatchChange from \"./reject-dispatch-change.js\";\nimport rejectDreamProposal from \"./reject-dream-proposal.js\";\nimport removePendingWorkspaceApp from \"./remove-pending-workspace-app.js\";\nimport requestVaultSecret from \"./request-vault-secret.js\";\nimport revokeVaultGrant from \"./revoke-vault-grant.js\";\nimport revokeWorkspaceResourceGrant from \"./revoke-workspace-resource-grant.js\";\nimport restoreStarterWorkspaceResources from \"./restore-starter-workspace-resources.js\";\nimport scaffoldWorkspaceApp from \"./scaffold-workspace-app.js\";\nimport searchAgentThreads from \"./search-agent-threads.js\";\nimport sendCodeAgentRemoteCommand from \"./send-code-agent-remote-command.js\";\nimport sendPlatformMessage from \"./send-platform-message.js\";\nimport setAppCreationSettings from \"./set-app-creation-settings.js\";\nimport setDispatchApprovalPolicy from \"./set-dispatch-approval-policy.js\";\nimport setDreamSettings from \"./set-dream-settings.js\";\nimport setMcpAppAccess from \"./set-mcp-app-access.js\";\nimport setVaultAccessSettings from \"./set-vault-access-settings.js\";\nimport startWorkspaceAppCreation from \"./start-workspace-app-creation.js\";\nimport syncVaultToApp from \"./sync-vault-to-app.js\";\nimport unarchiveWorkspaceApp from \"./unarchive-workspace-app.js\";\nimport updateWorkspaceAppMetadata from \"./update-workspace-app-metadata.js\";\nimport updateVaultSecret from \"./update-vault-secret.js\";\nimport updateWorkspaceResource from \"./update-workspace-resource.js\";\nimport upsertDestination from \"./upsert-destination.js\";\nimport viewScreen from \"./view-screen.js\";\n\n/**\n * Dispatch's actions registered as a flat name→entry map. Imported by\n * `@agent-native/dispatch/server`'s side-effect block, which calls\n * `registerPackageActions(dispatchActions)` so the framework's action\n * loader picks them up.\n */\nexport const dispatchActions: Record<string, ActionEntry> = {\n \"approve-dispatch-change\": approveDispatchChange,\n \"approve-vault-request\": approveVaultRequest,\n \"archive-workspace-app\": archiveWorkspaceApp,\n ask_app: askApp,\n \"create-link-token\": createLinkToken,\n \"create-pylon-ticket\": createPylonTicket,\n \"create-vault-grant\": createVaultGrant,\n \"create-vault-secret\": createVaultSecret,\n \"create-workspace-resource-grant\": createWorkspaceResourceGrant,\n \"create-workspace-resource\": createWorkspaceResource,\n \"create-dream-report\": createDreamReport,\n create_embed_session: createEmbedSession,\n \"delete-destination\": deleteDestination,\n \"delete-vault-secret\": deleteVaultSecret,\n \"delete-workspace-resource\": deleteWorkspaceResource,\n \"deny-vault-request\": denyVaultRequest,\n \"ensure-dream-job\": ensureDreamJob,\n \"get-app-creation-settings\": getAppCreationSettings,\n \"get-agent-thread-debug\": getAgentThreadDebug,\n \"get-dream\": getDream,\n \"get-dream-settings\": getDreamSettings,\n \"get-dispatch-settings\": getDispatchSettings,\n \"get-vault-access-settings\": getVaultAccessSettings,\n \"get-workspace-resource-effective-context\":\n getWorkspaceResourceEffectiveContext,\n \"get-workspace-info\": getWorkspaceInfo,\n \"grant-workspace-resources-to-app\": grantWorkspaceResourcesToApp,\n \"grant-vault-secrets-to-app\": grantVaultSecretsToApp,\n \"list-agent-thread-sources\": listAgentThreadSources,\n \"list-available-workspace-templates\": listAvailableWorkspaceTemplates,\n \"list-connected-agents\": listConnectedAgents,\n \"list-destinations\": listDestinations,\n \"list-dispatch-approvals\": listDispatchApprovals,\n \"list-dispatch-audit\": listDispatchAudit,\n \"list-dispatch-overview\": listDispatchOverview,\n \"list-dispatch-usage-metrics\": listDispatchUsageMetrics,\n \"list-dream-candidates\": listDreamCandidates,\n \"list-dreams\": listDreams,\n \"list-integrations-catalog\": listIntegrationsCatalog,\n \"list-linked-identities\": listLinkedIdentities,\n \"list-mcp-app-access\": listMcpAppAccess,\n list_apps: listApps,\n \"list-vault-audit\": listVaultAudit,\n \"list-vault-grants\": listVaultGrants,\n \"list-vault-requests\": listVaultRequests,\n \"list-vault-secret-options\": listVaultSecretOptions,\n \"list-vault-secrets\": listVaultSecrets,\n \"list-workspace-apps\": listWorkspaceApps,\n \"list-workspace-resource-options\": listWorkspaceResourceOptions,\n \"list-workspace-resource-grants\": listWorkspaceResourceGrants,\n \"list-workspace-resources-for-app\": listWorkspaceResourcesForApp,\n \"list-workspace-resources\": listWorkspaceResources,\n navigate: navigate,\n open_app: openApp,\n \"apply-dream-proposal\": applyDreamProposal,\n \"preview-dream-proposal\": previewDreamProposal,\n \"preview-workspace-resource-change\": previewWorkspaceResourceChange,\n \"provider-api-catalog\": providerApiCatalog,\n \"provider-api-docs\": providerApiDocs,\n \"provider-api-register\": providerApiRegister,\n \"provider-api-request\": providerApiRequest,\n \"reject-dispatch-change\": rejectDispatchChange,\n \"reject-dream-proposal\": rejectDreamProposal,\n \"remove-pending-workspace-app\": removePendingWorkspaceApp,\n \"request-vault-secret\": requestVaultSecret,\n \"revoke-vault-grant\": revokeVaultGrant,\n \"revoke-workspace-resource-grant\": revokeWorkspaceResourceGrant,\n \"restore-starter-workspace-resources\": restoreStarterWorkspaceResources,\n \"scaffold-workspace-app\": scaffoldWorkspaceApp,\n \"search-agent-threads\": searchAgentThreads,\n \"send-code-agent-remote-command\": sendCodeAgentRemoteCommand,\n \"send-platform-message\": sendPlatformMessage,\n \"set-app-creation-settings\": setAppCreationSettings,\n \"set-dispatch-approval-policy\": setDispatchApprovalPolicy,\n \"set-dream-settings\": setDreamSettings,\n \"set-mcp-app-access\": setMcpAppAccess,\n \"set-vault-access-settings\": setVaultAccessSettings,\n \"start-workspace-app-creation\": startWorkspaceAppCreation,\n \"sync-vault-to-app\": syncVaultToApp,\n \"unarchive-workspace-app\": unarchiveWorkspaceApp,\n \"update-workspace-app-metadata\": updateWorkspaceAppMetadata,\n \"update-vault-secret\": updateVaultSecret,\n \"update-workspace-resource\": updateWorkspaceResource,\n \"upsert-destination\": upsertDestination,\n \"view-screen\": viewScreen,\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"provider-api-catalog.d.ts","sourceRoot":"","sources":["../../src/actions/provider-api-catalog.ts"],"names":[],"mappings":";AASA,wBAiBG"}
1
+ {"version":3,"file":"provider-api-catalog.d.ts","sourceRoot":"","sources":["../../src/actions/provider-api-catalog.ts"],"names":[],"mappings":";AAIA,wBAqBG"}
@@ -1,18 +1,21 @@
1
1
  import { defineAction } from "@agent-native/core";
2
2
  import { z } from "zod";
3
- import { DISPATCH_PROVIDER_API_IDS, listProviderApiCatalog, } from "../server/lib/provider-api.js";
4
- const ProviderSchema = z.enum(DISPATCH_PROVIDER_API_IDS);
3
+ import { listProviderApiCatalog } from "../server/lib/provider-api.js";
5
4
  export default defineAction({
6
- description: "List raw HTTP API capabilities for shared workspace integrations and configured providers. Use before provider-api-request when grant/setup metadata is not enough and the provider's actual API must be inspected. Returns base URLs, auth style, credential key names, docs/spec URLs, placeholders, and examples; never returns secret values.",
5
+ description: "List raw HTTP API capabilities for shared workspace integrations, configured providers, and custom registered providers. Use before provider-api-request when grant/setup metadata is not enough and the provider's actual API must be inspected. Returns base URLs, auth style, credential key names, docs/spec URLs, placeholders, and examples; never returns secret values. Custom providers registered via provider-api-register are included.",
7
6
  schema: z.object({
8
- provider: ProviderSchema.optional().describe("Optional provider id to inspect. Omit to list every provider API escape hatch."),
7
+ provider: z
8
+ .string()
9
+ .optional()
10
+ .describe("Optional provider id to inspect (built-in or custom). Omit to list every available provider API."),
9
11
  }),
10
12
  http: { method: "GET" },
11
13
  readOnly: true,
12
14
  run: async ({ provider }) => {
15
+ const providers = await listProviderApiCatalog(provider);
13
16
  return {
14
- providers: listProviderApiCatalog(provider),
15
- guidance: "Workspace integrations and grants are not capability limits. When a provider can answer a question through its HTTP API, inspect docs/spec URLs here and call provider-api-request with the exact provider API method/path/query/body instead of adding a rigid one-off action.",
17
+ providers,
18
+ guidance: "Workspace integrations and grants are not capability limits. When a provider can answer a question through its HTTP API, inspect docs/spec URLs here and call provider-api-request with the exact provider API method/path/query/body instead of adding a rigid one-off action. Custom providers registered via provider-api-register also appear here.",
16
19
  };
17
20
  },
18
21
  });
@@ -1 +1 @@
1
- {"version":3,"file":"provider-api-catalog.js","sourceRoot":"","sources":["../../src/actions/provider-api-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;AAEzD,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,mVAAmV;IACrV,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAC1C,gFAAgF,CACjF;KACF,CAAC;IACF,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;IACvB,QAAQ,EAAE,IAAI;IACd,GAAG,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC1B,OAAO;YACL,SAAS,EAAE,sBAAsB,CAAC,QAAQ,CAAC;YAC3C,QAAQ,EACN,iRAAiR;SACpR,CAAC;IACJ,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { z } from \"zod\";\nimport {\n DISPATCH_PROVIDER_API_IDS,\n listProviderApiCatalog,\n} from \"../server/lib/provider-api.js\";\n\nconst ProviderSchema = z.enum(DISPATCH_PROVIDER_API_IDS);\n\nexport default defineAction({\n description:\n \"List raw HTTP API capabilities for shared workspace integrations and configured providers. Use before provider-api-request when grant/setup metadata is not enough and the provider's actual API must be inspected. Returns base URLs, auth style, credential key names, docs/spec URLs, placeholders, and examples; never returns secret values.\",\n schema: z.object({\n provider: ProviderSchema.optional().describe(\n \"Optional provider id to inspect. Omit to list every provider API escape hatch.\",\n ),\n }),\n http: { method: \"GET\" },\n readOnly: true,\n run: async ({ provider }) => {\n return {\n providers: listProviderApiCatalog(provider),\n guidance:\n \"Workspace integrations and grants are not capability limits. When a provider can answer a question through its HTTP API, inspect docs/spec URLs here and call provider-api-request with the exact provider API method/path/query/body instead of adding a rigid one-off action.\",\n };\n },\n});\n"]}
1
+ {"version":3,"file":"provider-api-catalog.js","sourceRoot":"","sources":["../../src/actions/provider-api-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,qbAAqb;IACvb,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,kGAAkG,CACnG;KACJ,CAAC;IACF,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;IACvB,QAAQ,EAAE,IAAI;IACd,GAAG,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC1B,MAAM,SAAS,GAAG,MAAM,sBAAsB,CAAC,QAAQ,CAAC,CAAC;QACzD,OAAO;YACL,SAAS;YACT,QAAQ,EACN,yVAAyV;SAC5V,CAAC;IACJ,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { z } from \"zod\";\nimport { listProviderApiCatalog } from \"../server/lib/provider-api.js\";\n\nexport default defineAction({\n description:\n \"List raw HTTP API capabilities for shared workspace integrations, configured providers, and custom registered providers. Use before provider-api-request when grant/setup metadata is not enough and the provider's actual API must be inspected. Returns base URLs, auth style, credential key names, docs/spec URLs, placeholders, and examples; never returns secret values. Custom providers registered via provider-api-register are included.\",\n schema: z.object({\n provider: z\n .string()\n .optional()\n .describe(\n \"Optional provider id to inspect (built-in or custom). Omit to list every available provider API.\",\n ),\n }),\n http: { method: \"GET\" },\n readOnly: true,\n run: async ({ provider }) => {\n const providers = await listProviderApiCatalog(provider);\n return {\n providers,\n guidance:\n \"Workspace integrations and grants are not capability limits. When a provider can answer a question through its HTTP API, inspect docs/spec URLs here and call provider-api-request with the exact provider API method/path/query/body instead of adding a rigid one-off action. Custom providers registered via provider-api-register also appear here.\",\n };\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"provider-api-docs.d.ts","sourceRoot":"","sources":["../../src/actions/provider-api-docs.ts"],"names":[],"mappings":";AASA,wBAyBG"}
1
+ {"version":3,"file":"provider-api-docs.d.ts","sourceRoot":"","sources":["../../src/actions/provider-api-docs.ts"],"names":[],"mappings":";AAIA,wBA4BG"}
@@ -1,16 +1,18 @@
1
1
  import { defineAction } from "@agent-native/core";
2
2
  import { z } from "zod";
3
- import { DISPATCH_PROVIDER_API_IDS, fetchProviderApiDocs, } from "../server/lib/provider-api.js";
4
- const ProviderSchema = z.enum(DISPATCH_PROVIDER_API_IDS);
3
+ import { fetchProviderApiDocs } from "../server/lib/provider-api.js";
5
4
  export default defineAction({
6
- description: "Inspect provider API docs/spec metadata, or fetch a registered provider docs/spec URL. Use this before arbitrary provider-api-request calls when the exact endpoint, filter operator, payload shape, pagination, or API version is uncertain.",
5
+ 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.",
7
6
  schema: z.object({
8
- provider: ProviderSchema.describe("Provider whose API docs/spec to inspect."),
7
+ provider: z
8
+ .string()
9
+ .min(1)
10
+ .describe("Provider whose API docs/spec to inspect. Can be a built-in provider id or a custom provider id registered via provider-api-register."),
9
11
  url: z
10
12
  .string()
11
13
  .url()
12
14
  .optional()
13
- .describe("Optional docs/spec URL from provider-api-catalog to fetch. Only registered docs/spec origins are allowed."),
15
+ .describe("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."),
14
16
  maxBytes: z.coerce
15
17
  .number()
16
18
  .int()
@@ -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,EACL,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;AAEzD,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,+OAA+O;IACjP,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAC/B,0CAA0C,CAC3C;QACD,GAAG,EAAE,CAAC;aACH,MAAM,EAAE;aACR,GAAG,EAAE;aACL,QAAQ,EAAE;aACV,QAAQ,CACP,2GAA2G,CAC5G;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 {\n DISPATCH_PROVIDER_API_IDS,\n fetchProviderApiDocs,\n} from \"../server/lib/provider-api.js\";\n\nconst ProviderSchema = z.enum(DISPATCH_PROVIDER_API_IDS);\n\nexport default defineAction({\n description:\n \"Inspect provider API docs/spec metadata, or fetch a registered provider docs/spec URL. Use this before arbitrary provider-api-request calls when the exact endpoint, filter operator, payload shape, pagination, or API version is uncertain.\",\n schema: z.object({\n provider: ProviderSchema.describe(\n \"Provider whose API docs/spec to inspect.\",\n ),\n url: z\n .string()\n .url()\n .optional()\n .describe(\n \"Optional docs/spec URL from provider-api-catalog to fetch. Only registered docs/spec origins are allowed.\",\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":"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"]}
@@ -0,0 +1,3 @@
1
+ declare const _default: any;
2
+ export default _default;
3
+ //# sourceMappingURL=provider-api-register.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-api-register.d.ts","sourceRoot":"","sources":["../../src/actions/provider-api-register.ts"],"names":[],"mappings":";AA+CA,wBAsJG"}
@@ -0,0 +1,160 @@
1
+ import { defineAction } from "@agent-native/core";
2
+ import { z } from "zod";
3
+ import { upsertCustomProvider, deleteCustomProvider, listCustomProviders, getCustomProvider, } from "@agent-native/core/provider-api";
4
+ import { getCredentialContext } from "@agent-native/core/server";
5
+ const AuthSchema = z.discriminatedUnion("type", [
6
+ z.object({
7
+ type: z.literal("none"),
8
+ }),
9
+ z.object({
10
+ type: z.literal("bearer"),
11
+ credentialKey: z
12
+ .string()
13
+ .min(1)
14
+ .describe("Name of the credential key (e.g. MY_API_TOKEN). Must already be saved via app secrets — this action never accepts secret values."),
15
+ }),
16
+ z.object({
17
+ type: z.literal("basic"),
18
+ usernameKey: z
19
+ .string()
20
+ .min(1)
21
+ .describe("Credential key name for the username/login."),
22
+ passwordKey: z
23
+ .string()
24
+ .min(1)
25
+ .describe("Credential key name for the password/secret."),
26
+ }),
27
+ z.object({
28
+ type: z.literal("api-key-header"),
29
+ credentialKey: z
30
+ .string()
31
+ .min(1)
32
+ .describe("Credential key name for the API key value."),
33
+ headerName: z
34
+ .string()
35
+ .min(1)
36
+ .describe("HTTP header name to send the key in (e.g. X-Api-Key)."),
37
+ }),
38
+ ]);
39
+ export default defineAction({
40
+ description: `Register or update a custom API provider so the agent can call it via provider-api-request and look up its docs via provider-api-docs.
41
+
42
+ IMPORTANT — credentials:
43
+ - This action stores only credential KEY NAMES, never secret values.
44
+ - If the required API key is not yet saved, instruct the user to add it via app Settings → Keys, or use the create-vault-secret action, before calling this action.
45
+ - Supported auth kinds: none, bearer, basic, api-key-header.
46
+ google-service-account and oauth-bearer are NOT supported for custom providers.
47
+
48
+ After registration the provider appears in provider-api-catalog and can be used with provider-api-request.`,
49
+ schema: z.object({
50
+ operation: z
51
+ .enum(["upsert", "delete", "list", "get"])
52
+ .default("upsert")
53
+ .describe("Operation: upsert (create or update), delete (remove), list (all custom providers), get (single provider)."),
54
+ id: z
55
+ .string()
56
+ .min(1)
57
+ .max(64)
58
+ .optional()
59
+ .describe("Provider slug (e.g. my-api). Lowercase letters, digits, hyphens only. Required for upsert/delete/get."),
60
+ label: z
61
+ .string()
62
+ .min(1)
63
+ .max(200)
64
+ .optional()
65
+ .describe("Human-readable name (e.g. 'My Analytics API'). Required for upsert."),
66
+ baseUrl: z
67
+ .string()
68
+ .url()
69
+ .optional()
70
+ .describe("Base URL for the API (e.g. https://api.example.com/v1). Required for upsert. Must be a public https/http URL."),
71
+ auth: AuthSchema.optional().describe("Auth configuration. Required for upsert. Use type 'none' for public APIs."),
72
+ docsUrls: z
73
+ .array(z.string().url())
74
+ .optional()
75
+ .describe("Optional list of documentation URLs for this provider."),
76
+ allowedHostSuffixes: z
77
+ .array(z.string())
78
+ .optional()
79
+ .describe("Optional list of additional host suffixes requests may target beyond the base URL origin (e.g. ['example.com'])."),
80
+ defaultHeaders: z
81
+ .record(z.string(), z.string())
82
+ .optional()
83
+ .describe("Optional headers to include on every request (e.g. { 'Accept': 'application/json' })."),
84
+ notes: z
85
+ .string()
86
+ .max(1000)
87
+ .optional()
88
+ .describe("Optional notes about this provider shown in the catalog."),
89
+ scope: z
90
+ .enum(["user", "org"])
91
+ .default("org")
92
+ .describe("Whether to store the provider for the current user only ('user') or for the whole workspace ('org')."),
93
+ }),
94
+ http: false,
95
+ run: async ({ operation, id, label, baseUrl, auth, docsUrls, allowedHostSuffixes, defaultHeaders, notes, scope, }) => {
96
+ const ctx = getCredentialContext();
97
+ if (!ctx) {
98
+ throw new Error("provider-api-register requires an authenticated request context.");
99
+ }
100
+ const scopeId = scope === "org" ? (ctx.orgId ?? ctx.userEmail) : ctx.userEmail;
101
+ if (operation === "list") {
102
+ const providers = await listCustomProviders(scope, scopeId);
103
+ return {
104
+ providers: providers.map((p) => ({
105
+ id: p.id,
106
+ label: p.label,
107
+ baseUrl: p.baseUrl,
108
+ authType: p.auth.type,
109
+ docsUrls: p.docsUrls,
110
+ notes: p.notes,
111
+ updatedAt: p.updatedAt,
112
+ })),
113
+ count: providers.length,
114
+ };
115
+ }
116
+ if (operation === "get") {
117
+ if (!id)
118
+ throw new Error("id is required for get operation.");
119
+ const provider = await getCustomProvider(scope, scopeId, id);
120
+ if (!provider) {
121
+ return { found: false, id };
122
+ }
123
+ return { found: true, provider };
124
+ }
125
+ if (operation === "delete") {
126
+ if (!id)
127
+ throw new Error("id is required for delete operation.");
128
+ const deleted = await deleteCustomProvider(scope, scopeId, id);
129
+ return { deleted, id };
130
+ }
131
+ // upsert
132
+ if (!id)
133
+ throw new Error("id is required for upsert operation.");
134
+ if (!label)
135
+ throw new Error("label is required for upsert operation.");
136
+ if (!baseUrl)
137
+ throw new Error("baseUrl is required for upsert operation.");
138
+ if (!auth)
139
+ throw new Error("auth is required for upsert operation.");
140
+ await upsertCustomProvider({
141
+ scope,
142
+ scopeId,
143
+ id,
144
+ label,
145
+ baseUrl,
146
+ auth,
147
+ docsUrls,
148
+ allowedHostSuffixes,
149
+ defaultHeaders,
150
+ notes,
151
+ });
152
+ return {
153
+ registered: true,
154
+ id,
155
+ label,
156
+ message: `Custom provider "${id}" registered. Use provider-api-catalog to inspect it and provider-api-request to call it.`,
157
+ };
158
+ },
159
+ });
160
+ //# sourceMappingURL=provider-api-register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-api-register.js","sourceRoot":"","sources":["../../src/actions/provider-api-register.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { z } from \"zod\";\nimport {\n upsertCustomProvider,\n deleteCustomProvider,\n listCustomProviders,\n getCustomProvider,\n} from \"@agent-native/core/provider-api\";\nimport { getCredentialContext } from \"@agent-native/core/server\";\n\nconst AuthSchema = z.discriminatedUnion(\"type\", [\n z.object({\n type: z.literal(\"none\"),\n }),\n z.object({\n type: z.literal(\"bearer\"),\n credentialKey: z\n .string()\n .min(1)\n .describe(\n \"Name of the credential key (e.g. MY_API_TOKEN). Must already be saved via app secrets — this action never accepts secret values.\",\n ),\n }),\n z.object({\n type: z.literal(\"basic\"),\n usernameKey: z\n .string()\n .min(1)\n .describe(\"Credential key name for the username/login.\"),\n passwordKey: z\n .string()\n .min(1)\n .describe(\"Credential key name for the password/secret.\"),\n }),\n z.object({\n type: z.literal(\"api-key-header\"),\n credentialKey: z\n .string()\n .min(1)\n .describe(\"Credential key name for the API key value.\"),\n headerName: z\n .string()\n .min(1)\n .describe(\"HTTP header name to send the key in (e.g. X-Api-Key).\"),\n }),\n]);\n\nexport default defineAction({\n description: `Register or update a custom API provider so the agent can call it via provider-api-request and look up its docs via provider-api-docs.\n\nIMPORTANT — credentials:\n- This action stores only credential KEY NAMES, never secret values.\n- If the required API key is not yet saved, instruct the user to add it via app Settings → Keys, or use the create-vault-secret action, before calling this action.\n- Supported auth kinds: none, bearer, basic, api-key-header.\n google-service-account and oauth-bearer are NOT supported for custom providers.\n\nAfter registration the provider appears in provider-api-catalog and can be used with provider-api-request.`,\n schema: z.object({\n operation: z\n .enum([\"upsert\", \"delete\", \"list\", \"get\"])\n .default(\"upsert\")\n .describe(\n \"Operation: upsert (create or update), delete (remove), list (all custom providers), get (single provider).\",\n ),\n id: z\n .string()\n .min(1)\n .max(64)\n .optional()\n .describe(\n \"Provider slug (e.g. my-api). Lowercase letters, digits, hyphens only. Required for upsert/delete/get.\",\n ),\n label: z\n .string()\n .min(1)\n .max(200)\n .optional()\n .describe(\n \"Human-readable name (e.g. 'My Analytics API'). Required for upsert.\",\n ),\n baseUrl: z\n .string()\n .url()\n .optional()\n .describe(\n \"Base URL for the API (e.g. https://api.example.com/v1). Required for upsert. Must be a public https/http URL.\",\n ),\n auth: AuthSchema.optional().describe(\n \"Auth configuration. Required for upsert. Use type 'none' for public APIs.\",\n ),\n docsUrls: z\n .array(z.string().url())\n .optional()\n .describe(\"Optional list of documentation URLs for this provider.\"),\n allowedHostSuffixes: z\n .array(z.string())\n .optional()\n .describe(\n \"Optional list of additional host suffixes requests may target beyond the base URL origin (e.g. ['example.com']).\",\n ),\n defaultHeaders: z\n .record(z.string(), z.string())\n .optional()\n .describe(\n \"Optional headers to include on every request (e.g. { 'Accept': 'application/json' }).\",\n ),\n notes: z\n .string()\n .max(1000)\n .optional()\n .describe(\"Optional notes about this provider shown in the catalog.\"),\n scope: z\n .enum([\"user\", \"org\"])\n .default(\"org\")\n .describe(\n \"Whether to store the provider for the current user only ('user') or for the whole workspace ('org').\",\n ),\n }),\n http: false,\n run: async ({\n operation,\n id,\n label,\n baseUrl,\n auth,\n docsUrls,\n allowedHostSuffixes,\n defaultHeaders,\n notes,\n scope,\n }) => {\n const ctx = getCredentialContext();\n if (!ctx) {\n throw new Error(\n \"provider-api-register requires an authenticated request context.\",\n );\n }\n const scopeId =\n scope === \"org\" ? (ctx.orgId ?? ctx.userEmail) : ctx.userEmail;\n\n if (operation === \"list\") {\n const providers = await listCustomProviders(scope, scopeId);\n return {\n providers: providers.map((p) => ({\n id: p.id,\n label: p.label,\n baseUrl: p.baseUrl,\n authType: p.auth.type,\n docsUrls: p.docsUrls,\n notes: p.notes,\n updatedAt: p.updatedAt,\n })),\n count: providers.length,\n };\n }\n\n if (operation === \"get\") {\n if (!id) throw new Error(\"id is required for get operation.\");\n const provider = await getCustomProvider(scope, scopeId, id);\n if (!provider) {\n return { found: false, id };\n }\n return { found: true, provider };\n }\n\n if (operation === \"delete\") {\n if (!id) throw new Error(\"id is required for delete operation.\");\n const deleted = await deleteCustomProvider(scope, scopeId, id);\n return { deleted, id };\n }\n\n // upsert\n if (!id) throw new Error(\"id is required for upsert operation.\");\n if (!label) throw new Error(\"label is required for upsert operation.\");\n if (!baseUrl) throw new Error(\"baseUrl is required for upsert operation.\");\n if (!auth) throw new Error(\"auth is required for upsert operation.\");\n\n await upsertCustomProvider({\n scope,\n scopeId,\n id,\n label,\n baseUrl,\n auth,\n docsUrls,\n allowedHostSuffixes,\n defaultHeaders,\n notes,\n });\n\n return {\n registered: true,\n id,\n label,\n message: `Custom provider \"${id}\" registered. Use provider-api-catalog to inspect it and provider-api-request to call it.`,\n };\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"provider-api-request.d.ts","sourceRoot":"","sources":["../../src/actions/provider-api-request.ts"],"names":[],"mappings":";AAUA,wBAmEG"}
1
+ {"version":3,"file":"provider-api-request.d.ts","sourceRoot":"","sources":["../../src/actions/provider-api-request.ts"],"names":[],"mappings":";AAMA,wBA8GG"}
@@ -1,12 +1,14 @@
1
1
  import { defineAction } from "@agent-native/core";
2
2
  import { z } from "zod";
3
- import { DISPATCH_PROVIDER_API_IDS, executeProviderApiRequest, } from "../server/lib/provider-api.js";
4
- const ProviderSchema = z.enum(DISPATCH_PROVIDER_API_IDS);
3
+ import { executeProviderApiRequest } from "../server/lib/provider-api.js";
5
4
  const MethodSchema = z.enum(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"]);
6
5
  export default defineAction({
7
- description: "Make an arbitrary authenticated HTTP request to a shared workspace integration or configured provider API. Use this as the flexible escape hatch when Dispatch needs a provider endpoint, filter, pagination mode, payload, or API version that no canned action models. The request is constrained to the provider host, uses configured credentials automatically, blocks private/internal URLs, and redacts secrets from responses.",
6
+ description: "Make an arbitrary authenticated HTTP request to a shared workspace integration, configured provider API, or custom provider registered via provider-api-register. Use this as the flexible escape hatch when Dispatch needs a provider endpoint, filter, pagination mode, payload, or API version that no canned action models. The request is constrained to the provider host, uses configured credentials automatically, blocks private/internal URLs, and redacts secrets from responses.",
8
7
  schema: z.object({
9
- provider: ProviderSchema.describe("Configured provider API to call, e.g. slack, github, notion, hubspot, gmail, google_drive, google_calendar, granola, stripe, jira."),
8
+ provider: z
9
+ .string()
10
+ .min(1)
11
+ .describe("Provider id to call — built-in (e.g. slack, github, notion, hubspot, gmail, google_drive, google_calendar, granola, stripe, jira) or a custom provider id registered via provider-api-register. Use provider-api-catalog to list available providers."),
10
12
  method: MethodSchema.default("GET").describe("HTTP method to use."),
11
13
  path: z
12
14
  .string()
@@ -49,7 +51,33 @@ export default defineAction({
49
51
  .min(1_000)
50
52
  .max(4 * 1024 * 1024)
51
53
  .optional()
52
- .describe("Maximum response bytes to read. Default 1MB, max 4MB."),
54
+ .describe("Maximum response bytes to read. Default 1MB, max 4MB. Ignored when saveToFile is set (allows up to 20MB)."),
55
+ saveToFile: z
56
+ .string()
57
+ .optional()
58
+ .describe("Workspace file path to save the full response body to instead of returning it in context (e.g. 'analysis/hubspot-deals.json'). When set, returns only a compact summary {savedTo, status, bytes, preview} and allows up to 20MB response. Useful for large datasets that would overflow context."),
59
+ fetchAllPages: z
60
+ .object({
61
+ cursorPath: z
62
+ .string()
63
+ .describe("Dot-path in the JSON response body where the next-page cursor lives, e.g. 'meta.next_cursor' or 'pagination.next_page_token'."),
64
+ cursorParam: z
65
+ .string()
66
+ .describe("Query parameter name to pass the cursor on subsequent pages, e.g. 'cursor' or 'page_token'."),
67
+ itemsPath: z
68
+ .string()
69
+ .optional()
70
+ .describe("Dot-path to the items array in each response, e.g. 'results' or 'data.items'. When omitted, the whole response body is appended per page."),
71
+ maxPages: z.coerce
72
+ .number()
73
+ .int()
74
+ .min(1)
75
+ .max(50)
76
+ .optional()
77
+ .describe("Maximum pages to fetch. Default 10, max 50. Stops early when the cursor is empty."),
78
+ })
79
+ .optional()
80
+ .describe("Enable cursor-based pagination. After each response, reads cursorPath from the JSON body and re-issues the request with cursorParam set, accumulating items from itemsPath (or whole bodies) until cursor is empty or maxPages is reached. Combine with saveToFile to write the full dataset to a workspace file."),
53
81
  }),
54
82
  http: false,
55
83
  run: async (args) => executeProviderApiRequest(args),
@@ -1 +1 @@
1
- {"version":3,"file":"provider-api-request.js","sourceRoot":"","sources":["../../src/actions/provider-api-request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,+BAA+B,CAAC;AAEvC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;AACzD,MAAM,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAE/E,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,waAAwa;IAC1a,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAC/B,oIAAoI,CACrI;QACD,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC;QACnE,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,CACP,wMAAwM,CACzM;QACH,KAAK,EAAE,CAAC;aACL,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CACP,4FAA4F,CAC7F;QACH,OAAO,EAAE,CAAC;aACP,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;aAC/B,QAAQ,EAAE;aACV,QAAQ,CACP,mHAAmH,CACpH;QACH,IAAI,EAAE,CAAC;aACJ,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CACP,iFAAiF,CAClF;QACH,IAAI,EAAE,CAAC;aACJ,IAAI,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;aACzB,OAAO,CAAC,SAAS,CAAC;aAClB,QAAQ,CACP,iIAAiI,CAClI;QACH,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,oGAAoG,CACrG;QACH,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,8GAA8G,CAC/G;QACH,SAAS,EAAE,CAAC,CAAC,MAAM;aAChB,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,KAAK,CAAC;aACV,GAAG,CAAC,OAAO,CAAC;aACZ,QAAQ,EAAE;aACV,QAAQ,CAAC,6DAA6D,CAAC;QAC1E,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,KAAK;IACX,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC;CACrD,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { z } from \"zod\";\nimport {\n DISPATCH_PROVIDER_API_IDS,\n executeProviderApiRequest,\n} from \"../server/lib/provider-api.js\";\n\nconst ProviderSchema = z.enum(DISPATCH_PROVIDER_API_IDS);\nconst MethodSchema = z.enum([\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"HEAD\"]);\n\nexport default defineAction({\n description:\n \"Make an arbitrary authenticated HTTP request to a shared workspace integration or configured provider API. Use this as the flexible escape hatch when Dispatch needs a provider endpoint, filter, pagination mode, payload, or API version that no canned action models. The request is constrained to the provider host, uses configured credentials automatically, blocks private/internal URLs, and redacts secrets from responses.\",\n schema: z.object({\n provider: ProviderSchema.describe(\n \"Configured provider API to call, e.g. slack, github, notion, hubspot, gmail, google_drive, google_calendar, granola, stripe, jira.\",\n ),\n method: MethodSchema.default(\"GET\").describe(\"HTTP method to use.\"),\n path: z\n .string()\n .min(1)\n .describe(\n \"Provider API path such as /search.messages, /repos/org/repo/issues, /crm/v3/objects/deals/search, or a full URL on an allowed provider host. Use placeholders from provider-api-catalog when provided.\",\n ),\n query: z\n .unknown()\n .optional()\n .describe(\n \"Optional query params as a JSON object/string. Array values produce repeated query params.\",\n ),\n headers: z\n .record(z.string(), z.unknown())\n .optional()\n .describe(\n \"Optional extra headers. Unsafe hop-by-hop headers are ignored. Auth headers are injected from stored credentials.\",\n ),\n body: z\n .unknown()\n .optional()\n .describe(\n \"Optional request body. Objects/arrays are JSON encoded; strings are sent as-is.\",\n ),\n auth: z\n .enum([\"default\", \"none\"])\n .default(\"default\")\n .describe(\n \"Use default to inject configured provider auth. Use none only for public provider endpoints that intentionally require no auth.\",\n ),\n connectionId: z\n .string()\n .optional()\n .describe(\n \"Optional shared workspace connection id to use when the provider has multiple granted connections.\",\n ),\n accountId: z\n .string()\n .optional()\n .describe(\n \"Optional OAuth account id to use for OAuth-backed providers such as Gmail, Google Calendar, or Google Drive.\",\n ),\n timeoutMs: z.coerce\n .number()\n .int()\n .min(1_000)\n .max(120_000)\n .optional()\n .describe(\"Request timeout in milliseconds. Default 30000, max 120000.\"),\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: false,\n run: async (args) => executeProviderApiRequest(args),\n});\n"]}
1
+ {"version":3,"file":"provider-api-request.js","sourceRoot":"","sources":["../../src/actions/provider-api-request.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineAction } from \"@agent-native/core\";\nimport { z } from \"zod\";\nimport { executeProviderApiRequest } from \"../server/lib/provider-api.js\";\n\nconst MethodSchema = z.enum([\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"HEAD\"]);\n\nexport default defineAction({\n description:\n \"Make an arbitrary authenticated HTTP request to a shared workspace integration, configured provider API, or custom provider registered via provider-api-register. Use this as the flexible escape hatch when Dispatch needs a provider endpoint, filter, pagination mode, payload, or API version that no canned action models. The request is constrained to the provider host, uses configured credentials automatically, blocks private/internal URLs, and redacts secrets from responses.\",\n schema: z.object({\n provider: z\n .string()\n .min(1)\n .describe(\n \"Provider id to call — built-in (e.g. slack, github, notion, hubspot, gmail, google_drive, google_calendar, granola, stripe, jira) or a custom provider id registered via provider-api-register. Use provider-api-catalog to list available providers.\",\n ),\n method: MethodSchema.default(\"GET\").describe(\"HTTP method to use.\"),\n path: z\n .string()\n .min(1)\n .describe(\n \"Provider API path such as /search.messages, /repos/org/repo/issues, /crm/v3/objects/deals/search, or a full URL on an allowed provider host. Use placeholders from provider-api-catalog when provided.\",\n ),\n query: z\n .unknown()\n .optional()\n .describe(\n \"Optional query params as a JSON object/string. Array values produce repeated query params.\",\n ),\n headers: z\n .record(z.string(), z.unknown())\n .optional()\n .describe(\n \"Optional extra headers. Unsafe hop-by-hop headers are ignored. Auth headers are injected from stored credentials.\",\n ),\n body: z\n .unknown()\n .optional()\n .describe(\n \"Optional request body. Objects/arrays are JSON encoded; strings are sent as-is.\",\n ),\n auth: z\n .enum([\"default\", \"none\"])\n .default(\"default\")\n .describe(\n \"Use default to inject configured provider auth. Use none only for public provider endpoints that intentionally require no auth.\",\n ),\n connectionId: z\n .string()\n .optional()\n .describe(\n \"Optional shared workspace connection id to use when the provider has multiple granted connections.\",\n ),\n accountId: z\n .string()\n .optional()\n .describe(\n \"Optional OAuth account id to use for OAuth-backed providers such as Gmail, Google Calendar, or Google Drive.\",\n ),\n timeoutMs: z.coerce\n .number()\n .int()\n .min(1_000)\n .max(120_000)\n .optional()\n .describe(\"Request timeout in milliseconds. Default 30000, max 120000.\"),\n maxBytes: z.coerce\n .number()\n .int()\n .min(1_000)\n .max(4 * 1024 * 1024)\n .optional()\n .describe(\n \"Maximum response bytes to read. Default 1MB, max 4MB. Ignored when saveToFile is set (allows up to 20MB).\",\n ),\n saveToFile: z\n .string()\n .optional()\n .describe(\n \"Workspace file path to save the full response body to instead of returning it in context (e.g. 'analysis/hubspot-deals.json'). When set, returns only a compact summary {savedTo, status, bytes, preview} and allows up to 20MB response. Useful for large datasets that would overflow context.\",\n ),\n fetchAllPages: z\n .object({\n cursorPath: z\n .string()\n .describe(\n \"Dot-path in the JSON response body where the next-page cursor lives, e.g. 'meta.next_cursor' or 'pagination.next_page_token'.\",\n ),\n cursorParam: z\n .string()\n .describe(\n \"Query parameter name to pass the cursor on subsequent pages, e.g. 'cursor' or 'page_token'.\",\n ),\n itemsPath: z\n .string()\n .optional()\n .describe(\n \"Dot-path to the items array in each response, e.g. 'results' or 'data.items'. When omitted, the whole response body is appended per page.\",\n ),\n maxPages: z.coerce\n .number()\n .int()\n .min(1)\n .max(50)\n .optional()\n .describe(\n \"Maximum pages to fetch. Default 10, max 50. Stops early when the cursor is empty.\",\n ),\n })\n .optional()\n .describe(\n \"Enable cursor-based pagination. After each response, reads cursorPath from the JSON body and re-issues the request with cursorParam set, accumulating items from itemsPath (or whole bodies) until cursor is empty or maxPages is reached. Combine with saveToFile to write the full dataset to a workspace file.\",\n ),\n }),\n http: false,\n run: async (args) => executeProviderApiRequest(args),\n});\n"]}
@@ -2,7 +2,7 @@ import { type ProviderApiId, type ProviderApiMethod, type ProviderApiRequestArgs
2
2
  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"];
3
3
  export type DispatchProviderApiId = ProviderApiId;
4
4
  export type { ProviderApiMethod, ProviderApiRequestArgs };
5
- export declare function listProviderApiCatalog(provider?: DispatchProviderApiId): {
5
+ export declare function listProviderApiCatalog(provider?: string): {
6
6
  id: "amplitude" | "bigquery" | "sentry" | "posthog" | "mixpanel" | "github" | "slack" | "twitter" | "notion" | "gmail" | "google_drive" | "hubspot" | "granola" | "apollo" | "commonroom" | "dataforseo" | "ga4" | "gcloud" | "gong" | "google_calendar" | "grafana" | "jira" | "prometheus" | "pylon" | "stripe";
7
7
  label: string;
8
8
  defaultBaseUrl: string;
@@ -17,9 +17,9 @@ export declare function listProviderApiCatalog(provider?: DispatchProviderApiId)
17
17
  examples: readonly import("@agent-native/core/provider-api").ProviderApiExample[];
18
18
  notes: readonly string[];
19
19
  templateUses: readonly import("@agent-native/core").WorkspaceConnectionTemplateUse[];
20
- }[];
20
+ }[] | Promise<unknown[]>;
21
21
  export declare function fetchProviderApiDocs(options: {
22
- provider: DispatchProviderApiId;
22
+ provider: string;
23
23
  url?: string;
24
24
  maxBytes?: number;
25
25
  }): Promise<unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"provider-api.d.ts","sourceRoot":"","sources":["../../../src/server/lib/provider-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAC;AAGzC,eAAO,MAAM,yBAAyB,kSAAmB,CAAC;AAC1D,MAAM,MAAM,qBAAqB,GAAG,aAAa,CAAC;AAClD,YAAY,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,CAAC;AAgB1D,wBAAgB,sBAAsB,CAAC,QAAQ,CAAC,EAAE,qBAAqB;;;;;;;;;;;;;;;IAEtE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,QAAQ,EAAE,qBAAqB,CAAC;IAChC,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,EAIL,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAC;AAGzC,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,15 +1,39 @@
1
- import { PROVIDER_API_IDS, createProviderApiRuntime, } from "@agent-native/core/provider-api";
1
+ import { PROVIDER_API_IDS, createProviderApiRuntime, listCustomProviders, } from "@agent-native/core/provider-api";
2
2
  import { getCredentialContext } from "@agent-native/core/server";
3
3
  export const DISPATCH_PROVIDER_API_IDS = PROVIDER_API_IDS;
4
+ function requireCtx(action) {
5
+ const ctx = getCredentialContext();
6
+ if (!ctx) {
7
+ throw new Error(`Dispatch provider API ${action} requires an authenticated request context.`);
8
+ }
9
+ return ctx;
10
+ }
4
11
  const runtime = createProviderApiRuntime({
5
12
  appId: "dispatch",
6
13
  localCredentialSource: "dispatch_local",
7
- getCredentialContext: () => {
14
+ getCredentialContext: () => requireCtx("requests"),
15
+ getCustomProviders: async () => {
8
16
  const ctx = getCredentialContext();
9
- if (!ctx) {
10
- throw new Error("Dispatch provider API requests require an authenticated request context.");
17
+ if (!ctx)
18
+ return [];
19
+ // Load custom providers for both user scope and org scope.
20
+ const results = await Promise.allSettled([
21
+ listCustomProviders("user", ctx.userEmail),
22
+ ctx.orgId ? listCustomProviders("org", ctx.orgId) : Promise.resolve([]),
23
+ ]);
24
+ const userProviders = results[0].status === "fulfilled" ? results[0].value : [];
25
+ const orgProviders = results[1].status === "fulfilled" ? results[1].value : [];
26
+ // Merge: user-scope providers take precedence over org-scope ones with the
27
+ // same id, and neither can shadow a built-in id.
28
+ const seen = new Set(PROVIDER_API_IDS);
29
+ const merged = [];
30
+ for (const p of [...userProviders, ...orgProviders]) {
31
+ if (!seen.has(p.id)) {
32
+ seen.add(p.id);
33
+ merged.push(p);
34
+ }
11
35
  }
12
- return ctx;
36
+ return merged;
13
37
  },
14
38
  });
15
39
  export function listProviderApiCatalog(provider) {
@@ -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,GAIzB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,CAAC,MAAM,yBAAyB,GAAG,gBAAgB,CAAC;AAI1D,MAAM,OAAO,GAAG,wBAAwB,CAAC;IACvC,KAAK,EAAE,UAAU;IACjB,qBAAqB,EAAE,gBAAgB;IACvC,oBAAoB,EAAE,GAAG,EAAE;QACzB,MAAM,GAAG,GAAG,oBAAoB,EAAE,CAAC;QACnC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CACb,0EAA0E,CAC3E,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,UAAU,sBAAsB,CAAC,QAAgC;IACrE,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 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_PROVIDER_API_IDS = PROVIDER_API_IDS;\nexport type DispatchProviderApiId = ProviderApiId;\nexport type { ProviderApiMethod, ProviderApiRequestArgs };\n\nconst runtime = createProviderApiRuntime({\n appId: \"dispatch\",\n localCredentialSource: \"dispatch_local\",\n getCredentialContext: () => {\n const ctx = getCredentialContext();\n if (!ctx) {\n throw new Error(\n \"Dispatch provider API requests require an authenticated request context.\",\n );\n }\n return ctx;\n },\n});\n\nexport function listProviderApiCatalog(provider?: DispatchProviderApiId) {\n return runtime.listCatalog(provider);\n}\n\nexport function fetchProviderApiDocs(options: {\n provider: DispatchProviderApiId;\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,EACxB,mBAAmB,GAIpB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,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,UAAU;IACjB,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_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\",\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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/dispatch",
3
- "version": "0.9.3",
3
+ "version": "0.10.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",
@@ -57,6 +57,7 @@ import previewDreamProposal from "./preview-dream-proposal.js";
57
57
  import previewWorkspaceResourceChange from "./preview-workspace-resource-change.js";
58
58
  import providerApiCatalog from "./provider-api-catalog.js";
59
59
  import providerApiDocs from "./provider-api-docs.js";
60
+ import providerApiRegister from "./provider-api-register.js";
60
61
  import providerApiRequest from "./provider-api-request.js";
61
62
  import rejectDispatchChange from "./reject-dispatch-change.js";
62
63
  import rejectDreamProposal from "./reject-dream-proposal.js";
@@ -149,6 +150,7 @@ export const dispatchActions: Record<string, ActionEntry> = {
149
150
  "preview-workspace-resource-change": previewWorkspaceResourceChange,
150
151
  "provider-api-catalog": providerApiCatalog,
151
152
  "provider-api-docs": providerApiDocs,
153
+ "provider-api-register": providerApiRegister,
152
154
  "provider-api-request": providerApiRequest,
153
155
  "reject-dispatch-change": rejectDispatchChange,
154
156
  "reject-dream-proposal": rejectDreamProposal,
@@ -1,27 +1,26 @@
1
1
  import { defineAction } from "@agent-native/core";
2
2
  import { z } from "zod";
3
- import {
4
- DISPATCH_PROVIDER_API_IDS,
5
- listProviderApiCatalog,
6
- } from "../server/lib/provider-api.js";
7
-
8
- const ProviderSchema = z.enum(DISPATCH_PROVIDER_API_IDS);
3
+ import { listProviderApiCatalog } from "../server/lib/provider-api.js";
9
4
 
10
5
  export default defineAction({
11
6
  description:
12
- "List raw HTTP API capabilities for shared workspace integrations and configured providers. Use before provider-api-request when grant/setup metadata is not enough and the provider's actual API must be inspected. Returns base URLs, auth style, credential key names, docs/spec URLs, placeholders, and examples; never returns secret values.",
7
+ "List raw HTTP API capabilities for shared workspace integrations, configured providers, and custom registered providers. Use before provider-api-request when grant/setup metadata is not enough and the provider's actual API must be inspected. Returns base URLs, auth style, credential key names, docs/spec URLs, placeholders, and examples; never returns secret values. Custom providers registered via provider-api-register are included.",
13
8
  schema: z.object({
14
- provider: ProviderSchema.optional().describe(
15
- "Optional provider id to inspect. Omit to list every provider API escape hatch.",
16
- ),
9
+ provider: z
10
+ .string()
11
+ .optional()
12
+ .describe(
13
+ "Optional provider id to inspect (built-in or custom). Omit to list every available provider API.",
14
+ ),
17
15
  }),
18
16
  http: { method: "GET" },
19
17
  readOnly: true,
20
18
  run: async ({ provider }) => {
19
+ const providers = await listProviderApiCatalog(provider);
21
20
  return {
22
- providers: listProviderApiCatalog(provider),
21
+ providers,
23
22
  guidance:
24
- "Workspace integrations and grants are not capability limits. When a provider can answer a question through its HTTP API, inspect docs/spec URLs here and call provider-api-request with the exact provider API method/path/query/body instead of adding a rigid one-off action.",
23
+ "Workspace integrations and grants are not capability limits. When a provider can answer a question through its HTTP API, inspect docs/spec URLs here and call provider-api-request with the exact provider API method/path/query/body instead of adding a rigid one-off action. Custom providers registered via provider-api-register also appear here.",
25
24
  };
26
25
  },
27
26
  });
@@ -1,25 +1,23 @@
1
1
  import { defineAction } from "@agent-native/core";
2
2
  import { z } from "zod";
3
- import {
4
- DISPATCH_PROVIDER_API_IDS,
5
- fetchProviderApiDocs,
6
- } from "../server/lib/provider-api.js";
7
-
8
- const ProviderSchema = z.enum(DISPATCH_PROVIDER_API_IDS);
3
+ import { fetchProviderApiDocs } from "../server/lib/provider-api.js";
9
4
 
10
5
  export default defineAction({
11
6
  description:
12
- "Inspect provider API docs/spec metadata, or fetch a registered provider docs/spec URL. Use this before arbitrary provider-api-request calls when the exact endpoint, filter operator, payload shape, pagination, or API version is uncertain.",
7
+ "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.",
13
8
  schema: z.object({
14
- provider: ProviderSchema.describe(
15
- "Provider whose API docs/spec to inspect.",
16
- ),
9
+ provider: z
10
+ .string()
11
+ .min(1)
12
+ .describe(
13
+ "Provider whose API docs/spec to inspect. Can be a built-in provider id or a custom provider id registered via provider-api-register.",
14
+ ),
17
15
  url: z
18
16
  .string()
19
17
  .url()
20
18
  .optional()
21
19
  .describe(
22
- "Optional docs/spec URL from provider-api-catalog to fetch. Only registered docs/spec origins are allowed.",
20
+ "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.",
23
21
  ),
24
22
  maxBytes: z.coerce
25
23
  .number()
@@ -0,0 +1,198 @@
1
+ import { defineAction } from "@agent-native/core";
2
+ import { z } from "zod";
3
+ import {
4
+ upsertCustomProvider,
5
+ deleteCustomProvider,
6
+ listCustomProviders,
7
+ getCustomProvider,
8
+ } from "@agent-native/core/provider-api";
9
+ import { getCredentialContext } from "@agent-native/core/server";
10
+
11
+ const AuthSchema = z.discriminatedUnion("type", [
12
+ z.object({
13
+ type: z.literal("none"),
14
+ }),
15
+ z.object({
16
+ type: z.literal("bearer"),
17
+ credentialKey: z
18
+ .string()
19
+ .min(1)
20
+ .describe(
21
+ "Name of the credential key (e.g. MY_API_TOKEN). Must already be saved via app secrets — this action never accepts secret values.",
22
+ ),
23
+ }),
24
+ z.object({
25
+ type: z.literal("basic"),
26
+ usernameKey: z
27
+ .string()
28
+ .min(1)
29
+ .describe("Credential key name for the username/login."),
30
+ passwordKey: z
31
+ .string()
32
+ .min(1)
33
+ .describe("Credential key name for the password/secret."),
34
+ }),
35
+ z.object({
36
+ type: z.literal("api-key-header"),
37
+ credentialKey: z
38
+ .string()
39
+ .min(1)
40
+ .describe("Credential key name for the API key value."),
41
+ headerName: z
42
+ .string()
43
+ .min(1)
44
+ .describe("HTTP header name to send the key in (e.g. X-Api-Key)."),
45
+ }),
46
+ ]);
47
+
48
+ export default defineAction({
49
+ description: `Register or update a custom API provider so the agent can call it via provider-api-request and look up its docs via provider-api-docs.
50
+
51
+ IMPORTANT — credentials:
52
+ - This action stores only credential KEY NAMES, never secret values.
53
+ - If the required API key is not yet saved, instruct the user to add it via app Settings → Keys, or use the create-vault-secret action, before calling this action.
54
+ - Supported auth kinds: none, bearer, basic, api-key-header.
55
+ google-service-account and oauth-bearer are NOT supported for custom providers.
56
+
57
+ After registration the provider appears in provider-api-catalog and can be used with provider-api-request.`,
58
+ schema: z.object({
59
+ operation: z
60
+ .enum(["upsert", "delete", "list", "get"])
61
+ .default("upsert")
62
+ .describe(
63
+ "Operation: upsert (create or update), delete (remove), list (all custom providers), get (single provider).",
64
+ ),
65
+ id: z
66
+ .string()
67
+ .min(1)
68
+ .max(64)
69
+ .optional()
70
+ .describe(
71
+ "Provider slug (e.g. my-api). Lowercase letters, digits, hyphens only. Required for upsert/delete/get.",
72
+ ),
73
+ label: z
74
+ .string()
75
+ .min(1)
76
+ .max(200)
77
+ .optional()
78
+ .describe(
79
+ "Human-readable name (e.g. 'My Analytics API'). Required for upsert.",
80
+ ),
81
+ baseUrl: z
82
+ .string()
83
+ .url()
84
+ .optional()
85
+ .describe(
86
+ "Base URL for the API (e.g. https://api.example.com/v1). Required for upsert. Must be a public https/http URL.",
87
+ ),
88
+ auth: AuthSchema.optional().describe(
89
+ "Auth configuration. Required for upsert. Use type 'none' for public APIs.",
90
+ ),
91
+ docsUrls: z
92
+ .array(z.string().url())
93
+ .optional()
94
+ .describe("Optional list of documentation URLs for this provider."),
95
+ allowedHostSuffixes: z
96
+ .array(z.string())
97
+ .optional()
98
+ .describe(
99
+ "Optional list of additional host suffixes requests may target beyond the base URL origin (e.g. ['example.com']).",
100
+ ),
101
+ defaultHeaders: z
102
+ .record(z.string(), z.string())
103
+ .optional()
104
+ .describe(
105
+ "Optional headers to include on every request (e.g. { 'Accept': 'application/json' }).",
106
+ ),
107
+ notes: z
108
+ .string()
109
+ .max(1000)
110
+ .optional()
111
+ .describe("Optional notes about this provider shown in the catalog."),
112
+ scope: z
113
+ .enum(["user", "org"])
114
+ .default("org")
115
+ .describe(
116
+ "Whether to store the provider for the current user only ('user') or for the whole workspace ('org').",
117
+ ),
118
+ }),
119
+ http: false,
120
+ run: async ({
121
+ operation,
122
+ id,
123
+ label,
124
+ baseUrl,
125
+ auth,
126
+ docsUrls,
127
+ allowedHostSuffixes,
128
+ defaultHeaders,
129
+ notes,
130
+ scope,
131
+ }) => {
132
+ const ctx = getCredentialContext();
133
+ if (!ctx) {
134
+ throw new Error(
135
+ "provider-api-register requires an authenticated request context.",
136
+ );
137
+ }
138
+ const scopeId =
139
+ scope === "org" ? (ctx.orgId ?? ctx.userEmail) : ctx.userEmail;
140
+
141
+ if (operation === "list") {
142
+ const providers = await listCustomProviders(scope, scopeId);
143
+ return {
144
+ providers: providers.map((p) => ({
145
+ id: p.id,
146
+ label: p.label,
147
+ baseUrl: p.baseUrl,
148
+ authType: p.auth.type,
149
+ docsUrls: p.docsUrls,
150
+ notes: p.notes,
151
+ updatedAt: p.updatedAt,
152
+ })),
153
+ count: providers.length,
154
+ };
155
+ }
156
+
157
+ if (operation === "get") {
158
+ if (!id) throw new Error("id is required for get operation.");
159
+ const provider = await getCustomProvider(scope, scopeId, id);
160
+ if (!provider) {
161
+ return { found: false, id };
162
+ }
163
+ return { found: true, provider };
164
+ }
165
+
166
+ if (operation === "delete") {
167
+ if (!id) throw new Error("id is required for delete operation.");
168
+ const deleted = await deleteCustomProvider(scope, scopeId, id);
169
+ return { deleted, id };
170
+ }
171
+
172
+ // upsert
173
+ if (!id) throw new Error("id is required for upsert operation.");
174
+ if (!label) throw new Error("label is required for upsert operation.");
175
+ if (!baseUrl) throw new Error("baseUrl is required for upsert operation.");
176
+ if (!auth) throw new Error("auth is required for upsert operation.");
177
+
178
+ await upsertCustomProvider({
179
+ scope,
180
+ scopeId,
181
+ id,
182
+ label,
183
+ baseUrl,
184
+ auth,
185
+ docsUrls,
186
+ allowedHostSuffixes,
187
+ defaultHeaders,
188
+ notes,
189
+ });
190
+
191
+ return {
192
+ registered: true,
193
+ id,
194
+ label,
195
+ message: `Custom provider "${id}" registered. Use provider-api-catalog to inspect it and provider-api-request to call it.`,
196
+ };
197
+ },
198
+ });
@@ -1,20 +1,19 @@
1
1
  import { defineAction } from "@agent-native/core";
2
2
  import { z } from "zod";
3
- import {
4
- DISPATCH_PROVIDER_API_IDS,
5
- executeProviderApiRequest,
6
- } from "../server/lib/provider-api.js";
3
+ import { executeProviderApiRequest } from "../server/lib/provider-api.js";
7
4
 
8
- const ProviderSchema = z.enum(DISPATCH_PROVIDER_API_IDS);
9
5
  const MethodSchema = z.enum(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"]);
10
6
 
11
7
  export default defineAction({
12
8
  description:
13
- "Make an arbitrary authenticated HTTP request to a shared workspace integration or configured provider API. Use this as the flexible escape hatch when Dispatch needs a provider endpoint, filter, pagination mode, payload, or API version that no canned action models. The request is constrained to the provider host, uses configured credentials automatically, blocks private/internal URLs, and redacts secrets from responses.",
9
+ "Make an arbitrary authenticated HTTP request to a shared workspace integration, configured provider API, or custom provider registered via provider-api-register. Use this as the flexible escape hatch when Dispatch needs a provider endpoint, filter, pagination mode, payload, or API version that no canned action models. The request is constrained to the provider host, uses configured credentials automatically, blocks private/internal URLs, and redacts secrets from responses.",
14
10
  schema: z.object({
15
- provider: ProviderSchema.describe(
16
- "Configured provider API to call, e.g. slack, github, notion, hubspot, gmail, google_drive, google_calendar, granola, stripe, jira.",
17
- ),
11
+ provider: z
12
+ .string()
13
+ .min(1)
14
+ .describe(
15
+ "Provider id to call — built-in (e.g. slack, github, notion, hubspot, gmail, google_drive, google_calendar, granola, stripe, jira) or a custom provider id registered via provider-api-register. Use provider-api-catalog to list available providers.",
16
+ ),
18
17
  method: MethodSchema.default("GET").describe("HTTP method to use."),
19
18
  path: z
20
19
  .string()
@@ -71,7 +70,47 @@ export default defineAction({
71
70
  .min(1_000)
72
71
  .max(4 * 1024 * 1024)
73
72
  .optional()
74
- .describe("Maximum response bytes to read. Default 1MB, max 4MB."),
73
+ .describe(
74
+ "Maximum response bytes to read. Default 1MB, max 4MB. Ignored when saveToFile is set (allows up to 20MB).",
75
+ ),
76
+ saveToFile: z
77
+ .string()
78
+ .optional()
79
+ .describe(
80
+ "Workspace file path to save the full response body to instead of returning it in context (e.g. 'analysis/hubspot-deals.json'). When set, returns only a compact summary {savedTo, status, bytes, preview} and allows up to 20MB response. Useful for large datasets that would overflow context.",
81
+ ),
82
+ fetchAllPages: z
83
+ .object({
84
+ cursorPath: z
85
+ .string()
86
+ .describe(
87
+ "Dot-path in the JSON response body where the next-page cursor lives, e.g. 'meta.next_cursor' or 'pagination.next_page_token'.",
88
+ ),
89
+ cursorParam: z
90
+ .string()
91
+ .describe(
92
+ "Query parameter name to pass the cursor on subsequent pages, e.g. 'cursor' or 'page_token'.",
93
+ ),
94
+ itemsPath: z
95
+ .string()
96
+ .optional()
97
+ .describe(
98
+ "Dot-path to the items array in each response, e.g. 'results' or 'data.items'. When omitted, the whole response body is appended per page.",
99
+ ),
100
+ maxPages: z.coerce
101
+ .number()
102
+ .int()
103
+ .min(1)
104
+ .max(50)
105
+ .optional()
106
+ .describe(
107
+ "Maximum pages to fetch. Default 10, max 50. Stops early when the cursor is empty.",
108
+ ),
109
+ })
110
+ .optional()
111
+ .describe(
112
+ "Enable cursor-based pagination. After each response, reads cursorPath from the JSON body and re-issues the request with cursorParam set, accumulating items from itemsPath (or whole bodies) until cursor is empty or maxPages is reached. Combine with saveToFile to write the full dataset to a workspace file.",
113
+ ),
75
114
  }),
76
115
  http: false,
77
116
  run: async (args) => executeProviderApiRequest(args),
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  PROVIDER_API_IDS,
3
3
  createProviderApiRuntime,
4
+ listCustomProviders,
4
5
  type ProviderApiId,
5
6
  type ProviderApiMethod,
6
7
  type ProviderApiRequestArgs,
@@ -11,26 +12,52 @@ export const DISPATCH_PROVIDER_API_IDS = PROVIDER_API_IDS;
11
12
  export type DispatchProviderApiId = ProviderApiId;
12
13
  export type { ProviderApiMethod, ProviderApiRequestArgs };
13
14
 
15
+ function requireCtx(action: string) {
16
+ const ctx = getCredentialContext();
17
+ if (!ctx) {
18
+ throw new Error(
19
+ `Dispatch provider API ${action} requires an authenticated request context.`,
20
+ );
21
+ }
22
+ return ctx;
23
+ }
24
+
14
25
  const runtime = createProviderApiRuntime({
15
26
  appId: "dispatch",
16
27
  localCredentialSource: "dispatch_local",
17
- getCredentialContext: () => {
28
+ getCredentialContext: () => requireCtx("requests"),
29
+ getCustomProviders: async () => {
18
30
  const ctx = getCredentialContext();
19
- if (!ctx) {
20
- throw new Error(
21
- "Dispatch provider API requests require an authenticated request context.",
22
- );
31
+ if (!ctx) return [];
32
+ // Load custom providers for both user scope and org scope.
33
+ const results = await Promise.allSettled([
34
+ listCustomProviders("user", ctx.userEmail),
35
+ ctx.orgId ? listCustomProviders("org", ctx.orgId) : Promise.resolve([]),
36
+ ]);
37
+ const userProviders =
38
+ results[0].status === "fulfilled" ? results[0].value : [];
39
+ const orgProviders =
40
+ results[1].status === "fulfilled" ? results[1].value : [];
41
+ // Merge: user-scope providers take precedence over org-scope ones with the
42
+ // same id, and neither can shadow a built-in id.
43
+ const seen = new Set<string>(PROVIDER_API_IDS as unknown as string[]);
44
+ const merged = [];
45
+ for (const p of [...userProviders, ...orgProviders]) {
46
+ if (!seen.has(p.id)) {
47
+ seen.add(p.id);
48
+ merged.push(p);
49
+ }
23
50
  }
24
- return ctx;
51
+ return merged;
25
52
  },
26
53
  });
27
54
 
28
- export function listProviderApiCatalog(provider?: DispatchProviderApiId) {
55
+ export function listProviderApiCatalog(provider?: string) {
29
56
  return runtime.listCatalog(provider);
30
57
  }
31
58
 
32
59
  export function fetchProviderApiDocs(options: {
33
- provider: DispatchProviderApiId;
60
+ provider: string;
34
61
  url?: string;
35
62
  maxBytes?: number;
36
63
  }) {