@agenthifive/openclaw 0.1.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 +124 -0
- package/dist/client.d.ts +27 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +136 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/jwt-utils.d.ts +29 -0
- package/dist/jwt-utils.d.ts.map +1 -0
- package/dist/jwt-utils.js +55 -0
- package/dist/jwt-utils.js.map +1 -0
- package/dist/patch-verify.d.ts +28 -0
- package/dist/patch-verify.d.ts.map +1 -0
- package/dist/patch-verify.js +72 -0
- package/dist/patch-verify.js.map +1 -0
- package/dist/pending-approvals.d.ts +55 -0
- package/dist/pending-approvals.d.ts.map +1 -0
- package/dist/pending-approvals.js +95 -0
- package/dist/pending-approvals.js.map +1 -0
- package/dist/prompt-reference.d.ts +51 -0
- package/dist/prompt-reference.d.ts.map +1 -0
- package/dist/prompt-reference.js +645 -0
- package/dist/prompt-reference.js.map +1 -0
- package/dist/register.d.ts +20 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +551 -0
- package/dist/register.js.map +1 -0
- package/dist/runtime.d.ts +66 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +87 -0
- package/dist/runtime.js.map +1 -0
- package/dist/session-context.d.ts +39 -0
- package/dist/session-context.d.ts.map +1 -0
- package/dist/session-context.js +58 -0
- package/dist/session-context.js.map +1 -0
- package/dist/setup-wizard.d.ts +28 -0
- package/dist/setup-wizard.d.ts.map +1 -0
- package/dist/setup-wizard.js +303 -0
- package/dist/setup-wizard.js.map +1 -0
- package/dist/tools.d.ts +27 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +128 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +93 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/vault-action-proxy.d.ts +75 -0
- package/dist/vault-action-proxy.d.ts.map +1 -0
- package/dist/vault-action-proxy.js +152 -0
- package/dist/vault-action-proxy.js.map +1 -0
- package/dist/vault-provider.d.ts +52 -0
- package/dist/vault-provider.d.ts.map +1 -0
- package/dist/vault-provider.js +37 -0
- package/dist/vault-provider.js.map +1 -0
- package/dist/vault-token-manager.d.ts +42 -0
- package/dist/vault-token-manager.d.ts.map +1 -0
- package/dist/vault-token-manager.js +124 -0
- package/dist/vault-token-manager.js.map +1 -0
- package/openclaw.plugin.json +59 -0
- package/package.json +58 -0
- package/patches/README.md +85 -0
- package/patches/model-auth.patch +44 -0
|
@@ -0,0 +1,645 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentHiFive Vault Prompt Reference — Chunked Architecture
|
|
3
|
+
*
|
|
4
|
+
* Provides two modes of API reference injection:
|
|
5
|
+
*
|
|
6
|
+
* 1. **Inline mode** (`buildApiReferencePrompt`): Assembles a single prompt
|
|
7
|
+
* string from provider sections. Used by the MCP server and simple consumers.
|
|
8
|
+
*
|
|
9
|
+
* 2. **Chunked file mode** (`writeReferenceFiles`): Writes a base reference
|
|
10
|
+
* file (tools, permissions, action templates) plus per-service API reference
|
|
11
|
+
* files to a state directory. The system prompt then contains a lean pointer
|
|
12
|
+
* listing available files. Used by the OpenClaw plugin for better accuracy.
|
|
13
|
+
*
|
|
14
|
+
* Chunked > monolithic: eval showed 89% accuracy (chunked) vs 72% (monolithic)
|
|
15
|
+
* with realistic production-sized prompts. Models get overwhelmed when all
|
|
16
|
+
* provider API docs are in one blob.
|
|
17
|
+
*/
|
|
18
|
+
import { writeFileSync } from "node:fs";
|
|
19
|
+
import { join } from "node:path";
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Provider-to-service aliasing (deduplicates docs for provider aliases)
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
const PROVIDER_TO_SERVICE = {
|
|
24
|
+
gmail: "google",
|
|
25
|
+
msteams: "microsoft",
|
|
26
|
+
};
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Inline Prompt Header/Footer (for simple buildApiReferencePrompt mode)
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
const PROMPT_HEADER = `## AgentHiFive API Reference
|
|
31
|
+
|
|
32
|
+
All external API calls go through the \`agenthifive.execute\` tool.
|
|
33
|
+
Authentication is handled automatically by the vault — do not add Authorization headers.
|
|
34
|
+
|
|
35
|
+
Before making API calls, use \`agenthifive.connections_list\` to discover available connections and their IDs.`;
|
|
36
|
+
const PROMPT_FOOTER = `### Notes
|
|
37
|
+
- All dates use ISO 8601 format (e.g., "2026-01-15T09:00:00Z")
|
|
38
|
+
- Google and Microsoft use the same connectionId for all their APIs (one OAuth connection covers mail + calendar + drive)
|
|
39
|
+
- If a request is blocked by policy, the error will indicate which URL patterns are allowed`;
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Inline per-provider sections (for simple buildApiReferencePrompt mode)
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
export const API_REFERENCE_SECTIONS = {
|
|
44
|
+
google: `### Google Gmail (provider: google)
|
|
45
|
+
|
|
46
|
+
List messages:
|
|
47
|
+
GET https://gmail.googleapis.com/gmail/v1/users/me/messages
|
|
48
|
+
query: { q: "search query", maxResults: "10", labelIds: "INBOX" }
|
|
49
|
+
|
|
50
|
+
Get message:
|
|
51
|
+
GET https://gmail.googleapis.com/gmail/v1/users/me/messages/{messageId}
|
|
52
|
+
query: { format: "full" }
|
|
53
|
+
|
|
54
|
+
Send message:
|
|
55
|
+
POST https://gmail.googleapis.com/gmail/v1/users/me/messages/send
|
|
56
|
+
body: { raw: "<base64url-encoded RFC 2822 message>" }
|
|
57
|
+
|
|
58
|
+
Search operators: from:, to:, subject:, newer_than:1d, older_than:7d, has:attachment, is:unread
|
|
59
|
+
|
|
60
|
+
### Google Calendar (provider: google)
|
|
61
|
+
|
|
62
|
+
List events:
|
|
63
|
+
GET https://www.googleapis.com/calendar/v3/calendars/primary/events
|
|
64
|
+
query: { timeMin: "ISO8601", timeMax: "ISO8601", singleEvents: "true", orderBy: "startTime" }
|
|
65
|
+
|
|
66
|
+
Create event:
|
|
67
|
+
POST https://www.googleapis.com/calendar/v3/calendars/primary/events
|
|
68
|
+
body: { summary: "...", start: { dateTime: "ISO8601" }, end: { dateTime: "ISO8601" }, attendees: [{ email: "..." }] }
|
|
69
|
+
|
|
70
|
+
### Google Drive (provider: google)
|
|
71
|
+
|
|
72
|
+
List files:
|
|
73
|
+
GET https://www.googleapis.com/drive/v3/files
|
|
74
|
+
query: { q: "'root' in parents", fields: "files(id,name,mimeType,modifiedTime)", pageSize: "20" }
|
|
75
|
+
|
|
76
|
+
Get file metadata:
|
|
77
|
+
GET https://www.googleapis.com/drive/v3/files/{fileId}
|
|
78
|
+
query: { fields: "id,name,mimeType,size,modifiedTime,webViewLink" }`,
|
|
79
|
+
notion: `### Notion (provider: notion)
|
|
80
|
+
|
|
81
|
+
⚠ Every request MUST include the Notion-Version header in the headers field:
|
|
82
|
+
headers: { "Notion-Version": "2022-06-28" }
|
|
83
|
+
⚠ Notion uses POST for search and database queries — these are read operations despite using POST.
|
|
84
|
+
|
|
85
|
+
Search pages and databases:
|
|
86
|
+
POST https://api.notion.com/v1/search
|
|
87
|
+
body: { query: "search text" }
|
|
88
|
+
|
|
89
|
+
Get page:
|
|
90
|
+
GET https://api.notion.com/v1/pages/{pageId}
|
|
91
|
+
|
|
92
|
+
Get page property:
|
|
93
|
+
GET https://api.notion.com/v1/pages/{pageId}/properties/{propertyId}
|
|
94
|
+
|
|
95
|
+
Get database:
|
|
96
|
+
GET https://api.notion.com/v1/databases/{databaseId}
|
|
97
|
+
|
|
98
|
+
Query database:
|
|
99
|
+
POST https://api.notion.com/v1/databases/{databaseId}/query
|
|
100
|
+
body: { filter: { property: "Status", select: { equals: "Active" } }, sorts: [{ property: "Date", direction: "descending" }] }
|
|
101
|
+
|
|
102
|
+
List block children:
|
|
103
|
+
GET https://api.notion.com/v1/blocks/{blockId}/children
|
|
104
|
+
|
|
105
|
+
Create page:
|
|
106
|
+
POST https://api.notion.com/v1/pages
|
|
107
|
+
body: { parent: { database_id: "..." }, properties: { Name: { title: [{ text: { content: "..." } }] } } }
|
|
108
|
+
|
|
109
|
+
Update page:
|
|
110
|
+
PATCH https://api.notion.com/v1/pages/{pageId}
|
|
111
|
+
body: { properties: { Status: { select: { name: "Done" } } } }
|
|
112
|
+
|
|
113
|
+
Append blocks to page:
|
|
114
|
+
PATCH https://api.notion.com/v1/blocks/{blockId}/children
|
|
115
|
+
body: { children: [{ object: "block", type: "paragraph", paragraph: { rich_text: [{ text: { content: "..." } }] } }] }
|
|
116
|
+
|
|
117
|
+
List comments:
|
|
118
|
+
GET https://api.notion.com/v1/comments
|
|
119
|
+
query: { block_id: "..." }
|
|
120
|
+
|
|
121
|
+
Create comment:
|
|
122
|
+
POST https://api.notion.com/v1/comments
|
|
123
|
+
body: { parent: { page_id: "..." }, rich_text: [{ text: { content: "..." } }] }`,
|
|
124
|
+
microsoft: `### Microsoft Graph — Mail (provider: microsoft)
|
|
125
|
+
|
|
126
|
+
List messages:
|
|
127
|
+
GET https://graph.microsoft.com/v1.0/me/messages
|
|
128
|
+
query: { "$top": "10", "$orderby": "receivedDateTime desc", "$select": "subject,from,receivedDateTime,bodyPreview" }
|
|
129
|
+
|
|
130
|
+
Send mail:
|
|
131
|
+
POST https://graph.microsoft.com/v1.0/me/sendMail
|
|
132
|
+
body: { message: { subject: "...", body: { contentType: "Text", content: "..." }, toRecipients: [{ emailAddress: { address: "..." } }] } }
|
|
133
|
+
|
|
134
|
+
### Microsoft Graph — Calendar (provider: microsoft)
|
|
135
|
+
|
|
136
|
+
List events:
|
|
137
|
+
GET https://graph.microsoft.com/v1.0/me/calendarView
|
|
138
|
+
query: { startDateTime: "ISO8601", endDateTime: "ISO8601", "$select": "subject,start,end,location,organizer" }
|
|
139
|
+
|
|
140
|
+
### Microsoft Graph — Files (provider: microsoft)
|
|
141
|
+
|
|
142
|
+
List files:
|
|
143
|
+
GET https://graph.microsoft.com/v1.0/me/drive/root/children
|
|
144
|
+
query: { "$select": "id,name,size,lastModifiedDateTime,webUrl" }`,
|
|
145
|
+
};
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
// Inline prompt builder (for MCP server / simple consumers)
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
/**
|
|
150
|
+
* Build an API reference prompt from the given provider names.
|
|
151
|
+
*
|
|
152
|
+
* Only includes sections for providers that have entries in
|
|
153
|
+
* `API_REFERENCE_SECTIONS`. Unknown providers are silently ignored.
|
|
154
|
+
*/
|
|
155
|
+
export function buildApiReferencePrompt(providers) {
|
|
156
|
+
const sections = [];
|
|
157
|
+
for (const provider of providers) {
|
|
158
|
+
const section = API_REFERENCE_SECTIONS[provider];
|
|
159
|
+
if (section) {
|
|
160
|
+
sections.push(section);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (sections.length === 0) {
|
|
164
|
+
return "";
|
|
165
|
+
}
|
|
166
|
+
return [PROMPT_HEADER, ...sections, PROMPT_FOOTER].join("\n\n");
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Full API reference prompt with all providers.
|
|
170
|
+
* Kept for backwards compatibility and programmatic access.
|
|
171
|
+
*/
|
|
172
|
+
export const API_REFERENCE_PROMPT = buildApiReferencePrompt(Object.keys(API_REFERENCE_SECTIONS));
|
|
173
|
+
// ===========================================================================
|
|
174
|
+
// CHUNKED FILE MODE (for OpenClaw plugin)
|
|
175
|
+
// ===========================================================================
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
// Base reference sections (no provider API docs — those go in per-service files)
|
|
178
|
+
// ---------------------------------------------------------------------------
|
|
179
|
+
const SECTION_HEADER = `# AgentHiFive Vault Reference
|
|
180
|
+
|
|
181
|
+
This file is auto-generated at startup. It describes how to use the AgentHiFive vault
|
|
182
|
+
to access external services (email, calendar, files, messaging).
|
|
183
|
+
|
|
184
|
+
Authentication is handled automatically by the vault — never add Authorization headers yourself.`;
|
|
185
|
+
const SECTION_TOOLS = `## Available Tools
|
|
186
|
+
|
|
187
|
+
| Tool | Purpose |
|
|
188
|
+
|------|---------|
|
|
189
|
+
| \`request_permission\` | Request access to a service (workspace owner approves in dashboard) |
|
|
190
|
+
| \`vault_execute\` | Make an API call through the vault proxy — vault injects credentials, enforces policies, logs audit |
|
|
191
|
+
| \`vault_download\` | Download a file through the vault and save to disk — returns local file path. Use for binary downloads (Drive files, attachments, images) |
|
|
192
|
+
| \`vault_connections_list\` | List active connections (service name, label, status) |
|
|
193
|
+
| \`vault_await_approval\` | (Fallback) Block until a step-up approval resolves. Only use if the user explicitly asks you to wait — the system auto-notifies you by default |
|
|
194
|
+
| \`list_approvals\` | Check status of step-up approval requests (pending, approved, denied, expired, consumed) |`;
|
|
195
|
+
const SECTION_PERMISSION_FLOW = `## How It Works
|
|
196
|
+
|
|
197
|
+
1. **Request access:** Call \`request_permission\` with:
|
|
198
|
+
- \`actionTemplateId\`: the capability ID (see table below)
|
|
199
|
+
- \`reason\`: why you need it (e.g., "User asked me to send a Telegram message")
|
|
200
|
+
2. **Tell the user** you've requested access and they need to approve it in the AgentHiFive dashboard
|
|
201
|
+
3. **After approval, make API calls:** Call \`vault_execute\` with:
|
|
202
|
+
- \`service\`: the service name (e.g., \`"telegram"\`, \`"anthropic-messages"\`, \`"gmail"\`)
|
|
203
|
+
- \`method\`: HTTP method (GET, POST, PUT, DELETE, PATCH)
|
|
204
|
+
- \`url\`: the provider API URL (see API Reference below)
|
|
205
|
+
- \`body\`: request body (for POST/PUT/PATCH)
|
|
206
|
+
- For multi-account services (Google, Microsoft), also pass \`connectionId\` from \`vault_connections_list\`
|
|
207
|
+
|
|
208
|
+
### Step-Up Approvals
|
|
209
|
+
|
|
210
|
+
Some actions require per-request approval (e.g., downloading files, sending emails in strict mode).
|
|
211
|
+
When \`vault_execute\` returns \`approvalRequired: true\` (HTTP 202):
|
|
212
|
+
|
|
213
|
+
1. **Note the \`approvalRequestId\`** from the response
|
|
214
|
+
2. **Tell the user** this specific action needs approval in the AgentHiFive dashboard
|
|
215
|
+
3. **Do NOT call \`vault_await_approval\`** — the system will automatically notify you when the approval resolves. You will receive an approval notification with the approvalId when the user approves (or a denial/expiry notice).
|
|
216
|
+
4. **When you receive the notification**, re-submit the **exact same request** with \`approvalId\` set to the \`approvalRequestId\`:
|
|
217
|
+
\`vault_execute({ ...sameParams, approvalId: "the-approval-id" })\`
|
|
218
|
+
5. **If denied or expired**, inform the user and do not retry.
|
|
219
|
+
|
|
220
|
+
The approval is single-use: once consumed by a successful re-submit, it cannot be reused.
|
|
221
|
+
|
|
222
|
+
**Important:** Never add Authorization headers — the vault injects credentials automatically.
|
|
223
|
+
Never modify \`credentials.vault.connections\` in openclaw.json — the vault resolves connections automatically by service name.`;
|
|
224
|
+
const SECTION_ACTION_TEMPLATES = `## Action Template IDs
|
|
225
|
+
|
|
226
|
+
| ID | Service | Description |
|
|
227
|
+
|----|---------|-------------|
|
|
228
|
+
| \`gmail-read\` | Google Gmail | Read messages and search |
|
|
229
|
+
| \`gmail-manage\` | Google Gmail | Read, send, compose drafts, manage labels |
|
|
230
|
+
| \`calendar-read\` | Google Calendar | Read events |
|
|
231
|
+
| \`calendar-manage\` | Google Calendar | Read, create, edit, delete events |
|
|
232
|
+
| \`drive-read\` | Google Drive | Read files |
|
|
233
|
+
| \`drive-manage\` | Google Drive | Read, upload, edit, delete files |
|
|
234
|
+
| \`docs-read\` | Google Docs | Read documents |
|
|
235
|
+
| \`docs-manage\` | Google Docs | Read, create, edit documents |
|
|
236
|
+
| \`sheets-read\` | Google Sheets | Read spreadsheets |
|
|
237
|
+
| \`sheets-manage\` | Google Sheets | Read, create, edit spreadsheets |
|
|
238
|
+
| \`contacts-read\` | Google Contacts | Read contacts and contact groups |
|
|
239
|
+
| \`contacts-manage\` | Google Contacts | Read, create, edit, delete contacts |
|
|
240
|
+
| \`outlook-read\` | Microsoft Outlook | Read mail |
|
|
241
|
+
| \`outlook-manage\` | Microsoft Outlook | Read, send, manage emails |
|
|
242
|
+
| \`outlook-calendar-read\` | Outlook Calendar | Read events |
|
|
243
|
+
| \`outlook-calendar-manage\` | Outlook Calendar | Read, create, edit, delete events |
|
|
244
|
+
| \`outlook-contacts-read\` | Outlook Contacts | Read contacts |
|
|
245
|
+
| \`outlook-contacts-manage\` | Outlook Contacts | Read, create, edit, delete contacts |
|
|
246
|
+
| \`onedrive-read\` | OneDrive | Read files |
|
|
247
|
+
| \`onedrive-manage\` | OneDrive | Read, upload, edit, delete files |
|
|
248
|
+
| \`teams-read\` | Microsoft Teams | Read messages |
|
|
249
|
+
| \`teams-manage\` | Microsoft Teams | Read, send messages, manage files |
|
|
250
|
+
| \`slack\` | Slack | Read/send messages, upload files, manage reactions |
|
|
251
|
+
| \`telegram\` | Telegram | Send/receive messages via bot |
|
|
252
|
+
| \`anthropic-messages\` | Anthropic | Claude LLM API |
|
|
253
|
+
| \`openai\` | OpenAI | Chat completions, embeddings, model listing |
|
|
254
|
+
| \`gemini\` | Google Gemini | Content generation, embeddings, model listing |
|
|
255
|
+
| \`openrouter\` | OpenRouter | Chat completions and model listing |
|
|
256
|
+
| \`notion-read\` | Notion | Read pages, databases, blocks, and search |
|
|
257
|
+
| \`notion-manage\` | Notion | Read, create, update pages and databases |
|
|
258
|
+
| \`trello-read\` | Trello | Read boards, lists, cards, and labels |
|
|
259
|
+
| \`trello-manage\` | Trello | Read, create, update cards and lists |
|
|
260
|
+
| \`jira-read\` | Jira | Search and read issues, projects, and comments |
|
|
261
|
+
| \`jira-manage\` | Jira | Read, create, update issues and comments |`;
|
|
262
|
+
const SECTION_NOTES = `## Notes
|
|
263
|
+
|
|
264
|
+
- **Vault-managed channels need NO tokens.** Telegram, Slack, and other vault-managed channels do NOT need bot tokens, app tokens, or API keys in openclaw.json. The vault injects all credentials automatically. NEVER ask users for tokens for vault-managed services.
|
|
265
|
+
- **Do NOT use the built-in \`message\` tool for vault-managed channels.** The \`message\` tool uses OpenClaw's native channel routing, which does not have real credentials for vault-managed services. Always use \`vault_execute\` to send messages to Telegram, Slack, and other vault-managed channels. The \`message\` tool will return 404 errors for these channels.
|
|
266
|
+
- **Enabling a channel:** Use \`config.patch\` to add a minimal \`channels.<name>\` section and set \`plugins.entries.<name>.enabled: true\`. The vault channel watcher will auto-start the poller.
|
|
267
|
+
- Telegram: \`{ channels: { telegram: { botToken: "vault-managed", dmPolicy: "open", allowFrom: ["*"] } }, plugins: { entries: { telegram: { enabled: true } } } }\`
|
|
268
|
+
- Slack: \`{ channels: { slack: {} }, plugins: { entries: { slack: { enabled: true } } } }\`
|
|
269
|
+
- **Disabling a channel:** Use \`config.patch\` with \`{ plugins: { entries: { <name>: { enabled: false } } } }\`. The poller stops within 60 seconds.
|
|
270
|
+
- **Auto-polling:** When a channel is enabled and the vault has an active connection, incoming messages are automatically polled and dispatched to you. You do NOT need to call getUpdates or conversations.history yourself for receiving messages.
|
|
271
|
+
- **No connection UUIDs for singletons:** Telegram, Slack, Anthropic, OpenAI, Gemini, and OpenRouter are singletons (one connection per workspace). Always use \`service: "telegram"\`, \`service: "slack"\`, \`service: "anthropic-messages"\`, \`service: "openai"\`, \`service: "gemini"\`, or \`service: "openrouter"\` — never use a connection UUID for these.
|
|
272
|
+
- Multi-account services (Google, Microsoft) may have multiple connections — use \`connectionId\` from \`vault_connections_list\` only for these.
|
|
273
|
+
- All dates use ISO 8601 format (e.g., "2026-01-15T09:00:00Z")
|
|
274
|
+
- Do NOT modify \`credentials.vault.connections\` in openclaw.json — the vault resolves connections automatically by service name.
|
|
275
|
+
|
|
276
|
+
## Retry & Failure Rules
|
|
277
|
+
|
|
278
|
+
- **Never retry the same \`vault_execute\` call more than once.** If the same call fails twice (original + 1 retry), stop and explain the error to the user. Do NOT keep trying.
|
|
279
|
+
- **Empty or missing response body:** If a \`vault_execute\` call returns an empty body, no data, or times out, treat it as a definitive failure. Do NOT retry. Report the issue to the user immediately.
|
|
280
|
+
- **Binary file downloads:** \`vault_execute\` cannot return binary data — it returns a \`_binaryContent\` metadata object instead. Before downloading any file, check its content type or mimeType. Prefer structured API access (JSON) over binary downloads whenever possible. When binary is unavoidable, use \`vault_download\` — it saves the file to disk and returns the local file path.
|
|
281
|
+
- **Large responses saved to disk:** When a \`vault_execute\` response exceeds ~50KB (e.g., JSON with embedded base64 attachments), the full JSON is automatically saved to disk. The result includes \`responseSavedToDisk: true\`, \`path\` (local file), \`preview\` (structural summary), and \`hint\`. Read the file with your file tools to access specific fields. This prevents large payloads from filling your context window.
|
|
282
|
+
|
|
283
|
+
## Error Handling
|
|
284
|
+
|
|
285
|
+
When the vault blocks a request, the response includes an \`error\` field and often a \`hint\` field. **Always read the hint** — it tells you exactly how to fix your request:
|
|
286
|
+
- **Wrong HTTP method:** hint lists the allowed methods (e.g., "Allowed methods: POST" — common with Slack)
|
|
287
|
+
- **Wrong URL path:** hint lists allowed path patterns
|
|
288
|
+
- **Wrong host:** hint lists which hosts have allowlist rules
|
|
289
|
+
- **Rate limited:** hint tells you when to retry (\`retryAfter\` seconds)
|
|
290
|
+
- **Model mismatch:** hint tells you which execution model to use instead
|
|
291
|
+
- **No permission:** call \`request_permission\` to request the needed capability
|
|
292
|
+
- **Step-up required (202):** hint tells you to re-submit with \`approvalId\` after user approval
|
|
293
|
+
- **Download blocked by approval:** If \`vault_download\` returns a step-up approval (202), tell the user their options:
|
|
294
|
+
1. Approve the download in the AgentHiFive dashboard (you'll retry with the \`approvalId\`)
|
|
295
|
+
2. If the file is a convertible type (documents, spreadsheets, PDFs, presentations), you can try the copy-convert approach instead — it reads content through structured APIs without a binary download, which may not require the same approval`;
|
|
296
|
+
// ---------------------------------------------------------------------------
|
|
297
|
+
// Per-provider API sections (chunked — one file per service group)
|
|
298
|
+
// ---------------------------------------------------------------------------
|
|
299
|
+
export const CHUNKED_API_SECTIONS = {
|
|
300
|
+
google: `### Google APIs (provider: google, multi-account — use connectionId)
|
|
301
|
+
|
|
302
|
+
Google APIs use standard REST: GET for reads, POST for writes. Use \`connectionId\` from \`vault_connections_list\`.
|
|
303
|
+
|
|
304
|
+
**Gmail** (base: \`https://gmail.googleapis.com\`):
|
|
305
|
+
- List messages: \`GET /gmail/v1/users/me/messages\` — query: \`{ q, maxResults, labelIds }\`
|
|
306
|
+
- Get message: \`GET /gmail/v1/users/me/messages/{id}\` — query: \`{ format: "full" }\`
|
|
307
|
+
- Get attachment: \`GET /gmail/v1/users/me/messages/{id}/attachments/{attachmentId}\`
|
|
308
|
+
- List labels: \`GET /gmail/v1/users/me/labels\`
|
|
309
|
+
- Send message: \`POST /gmail/v1/users/me/messages/send\` — body: \`{ raw: "<base64url-encoded RFC 2822 email>" }\`
|
|
310
|
+
⚠ The \`raw\` field must be a base64url-encoded string of a complete RFC 2822 email (with To, Subject, MIME headers).
|
|
311
|
+
- Search operators: \`from:\`, \`to:\`, \`subject:\`, \`newer_than:1d\`, \`has:attachment\`, \`is:unread\`
|
|
312
|
+
- Policy notes (vary by user's security tier — vault returns a hint if a rule blocks you):
|
|
313
|
+
- **Strict read**: only messages with \`newer_than:Xd\` (1–7 days) in the query are allowed without approval; always include a recency filter
|
|
314
|
+
- **Balanced read/manage**: attachment requests (\`/attachments/\`) require the user's approval
|
|
315
|
+
- **Strict manage**: same read constraints apply; sends and drafts also require approval; deletions are blocked
|
|
316
|
+
|
|
317
|
+
**Calendar** (base: \`https://www.googleapis.com\`):
|
|
318
|
+
- List events: \`GET /calendar/v3/calendars/primary/events\` — query: \`{ timeMin, timeMax, singleEvents, orderBy }\`
|
|
319
|
+
- Create event: \`POST /calendar/v3/calendars/primary/events\` — body: \`{ summary, start, end, attendees }\`
|
|
320
|
+
- Policy notes:
|
|
321
|
+
- **Strict read**: listing events is allowed; reading individual event details requires approval
|
|
322
|
+
- **Strict manage**: same read constraints; event creation/modification requires approval; deletion is blocked
|
|
323
|
+
- **Balanced**: all reads allowed; writes allowed within rate limits
|
|
324
|
+
|
|
325
|
+
**Drive** (base: \`https://www.googleapis.com\`):
|
|
326
|
+
- List files: \`GET /drive/v3/files\` — query: \`{ q, fields, pageSize }\`
|
|
327
|
+
- Get file metadata: \`GET /drive/v3/files/{id}\` — query: \`{ fields: "id,name,mimeType,size,webViewLink" }\`
|
|
328
|
+
- Export Google-native file: \`GET /drive/v3/files/{id}/export\` — query: \`{ mimeType: "text/csv" }\` (or \`text/plain\`, \`application/pdf\`)
|
|
329
|
+
- Copy file: \`POST /drive/v3/files/{id}/copy\` — body: \`{ mimeType: "application/vnd.google-apps.spreadsheet" }\`
|
|
330
|
+
- Download binary file: \`vault_download({ url: "https://www.googleapis.com/drive/v3/files/{id}?alt=media", connectionId: "..." })\`
|
|
331
|
+
- Policy notes:
|
|
332
|
+
- **Strict**: binary downloads (\`alt=media\`) are blocked; use copy-convert or export instead. File listing is allowed; metadata reads require approval
|
|
333
|
+
- **Balanced**: binary downloads require approval; all reads allowed; writes allowed within rate limits
|
|
334
|
+
- **Minimal**: all operations allowed within rate limits
|
|
335
|
+
|
|
336
|
+
**Reading file contents — decision tree:**
|
|
337
|
+
1. Get file metadata first (\`GET /drive/v3/files/{id}?fields=mimeType,name\`)
|
|
338
|
+
2. **Google-native file** (\`application/vnd.google-apps.*\`):
|
|
339
|
+
- Spreadsheet → use Sheets API via \`vault_execute\` (returns structured JSON)
|
|
340
|
+
- Document → use Docs API via \`vault_execute\` (returns structured JSON)
|
|
341
|
+
- Or export: \`GET /drive/v3/files/{id}/export?mimeType=text/csv\` via \`vault_execute\`
|
|
342
|
+
3. **Convertible file** — copy-convert to a Google-native format, then read via structured API:
|
|
343
|
+
- \`POST /drive/v3/files/{id}/copy\` with body \`{ mimeType: "<target>" }\`
|
|
344
|
+
- Read the converted copy via the appropriate API (\`vault_execute\`), then delete the copy
|
|
345
|
+
- Target mimeType by source:
|
|
346
|
+
- \`.xls\`, \`.xlsx\`, \`.csv\`, \`.ods\` → \`application/vnd.google-apps.spreadsheet\` → read via Sheets API
|
|
347
|
+
- \`.docx\`, \`.doc\`, \`.rtf\`, \`.odt\`, \`.html\`, \`.txt\` → \`application/vnd.google-apps.document\` → read via Docs API
|
|
348
|
+
- \`.pptx\`, \`.ppt\`, \`.odp\` → \`application/vnd.google-apps.presentation\` → export as \`text/plain\`
|
|
349
|
+
- PDF → \`application/vnd.google-apps.document\` (OCR) → read via Docs API or export as \`text/plain\`
|
|
350
|
+
- Images (when extracting text) → \`application/vnd.google-apps.document\` (OCR)
|
|
351
|
+
- Prefer this over \`vault_download\` whenever you need text content — it avoids binary transfer entirely
|
|
352
|
+
- OCR quality varies: works well for text-heavy PDFs/images, poorly for scans or complex layouts
|
|
353
|
+
4. **Non-convertible binary** (audio, video, archives, proprietary formats) → use \`vault_download\`
|
|
354
|
+
5. **Never** use \`vault_execute\` with \`alt=media\` — binary data cannot pass through JSON serialization
|
|
355
|
+
|
|
356
|
+
**Docs** (base: \`https://docs.googleapis.com\`):
|
|
357
|
+
- Get document: \`GET /v1/documents/{documentId}\`
|
|
358
|
+
- Create document: \`POST /v1/documents\` — body: \`{ title: "..." }\`
|
|
359
|
+
- Batch update: \`POST /v1/documents/{documentId}:batchUpdate\` — body: \`{ requests: [...] }\`
|
|
360
|
+
Common requests: \`insertText\` (\`{ location: { index }, text }\`), \`deleteContentRange\` (\`{ range: { startIndex, endIndex } }\`), \`replaceAllText\` (\`{ containsText: { text, matchCase }, replaceText }\`)
|
|
361
|
+
|
|
362
|
+
**Sheets** (base: \`https://sheets.googleapis.com\`):
|
|
363
|
+
- Get spreadsheet: \`GET /v4/spreadsheets/{spreadsheetId}\` — query: \`{ ranges, includeGridData }\`
|
|
364
|
+
- Read values: \`GET /v4/spreadsheets/{spreadsheetId}/values/{range}\` — range format: \`Sheet1!A1:D10\`
|
|
365
|
+
- Update values: \`PUT /v4/spreadsheets/{spreadsheetId}/values/{range}\` — query: \`{ valueInputOption: "USER_ENTERED" }\` — body: \`{ values: [[...]] }\`
|
|
366
|
+
- Append rows: \`POST /v4/spreadsheets/{spreadsheetId}/values/{range}:append\` — query: \`{ valueInputOption: "USER_ENTERED" }\` — body: \`{ values: [[...]] }\`
|
|
367
|
+
- Create spreadsheet: \`POST /v4/spreadsheets\` — body: \`{ properties: { title: "..." } }\`
|
|
368
|
+
|
|
369
|
+
**Contacts** (base: \`https://people.googleapis.com\`):
|
|
370
|
+
- List contacts: \`GET /v1/people/me/connections\` — query: \`{ personFields: "names,emailAddresses,phoneNumbers", pageSize: 100 }\`
|
|
371
|
+
- Get contact: \`GET /v1/people/{resourceName}\` — query: \`{ personFields: "names,emailAddresses,phoneNumbers,addresses,organizations" }\`
|
|
372
|
+
- resourceName format: \`people/c1234567890\`
|
|
373
|
+
- Search contacts: \`GET /v1/people:searchContacts\` — query: \`{ query: "search term", readMask: "names,emailAddresses" }\`
|
|
374
|
+
- Create contact: \`POST /v1/people:createContact\` — body: \`{ names: [{ givenName, familyName }], emailAddresses: [{ value }], phoneNumbers: [{ value }] }\`
|
|
375
|
+
- Update contact: \`PATCH /v1/people/{resourceName}:updateContact\` — query: \`{ updatePersonFields: "names,emailAddresses" }\` — body: same as create
|
|
376
|
+
- Delete contact: \`DELETE /v1/people/{resourceName}:deleteContact\`
|
|
377
|
+
- List contact groups: \`GET /v1/contactGroups\`
|
|
378
|
+
- ⚠ Always include \`personFields\` (for get/list) or \`readMask\` (for search) — the API returns no data without it
|
|
379
|
+
- Policy notes:
|
|
380
|
+
- **Minimal**: notes/biographies stripped, all other fields visible
|
|
381
|
+
- **Balanced**: PII fields (phone numbers, addresses, birthdays) stripped by default. To access full fields for a **specific contact**, add \`requestFullFields: true\` to vault_execute — this triggers step-up approval. Only works on individual contact endpoints (e.g. \`GET /v1/people/c1234567890\`), NOT on list or search endpoints. Once approved, re-submit with both \`approvalId\` and \`requestFullFields: true\`. Notes remain stripped even with approval.
|
|
382
|
+
- **Strict**: PII fields always stripped, no way to request them. Deletion is blocked on manage connections.`,
|
|
383
|
+
gmail: ``, // covered by "google"
|
|
384
|
+
microsoft: `### Microsoft Graph APIs (provider: microsoft, multi-account — use connectionId)
|
|
385
|
+
|
|
386
|
+
Microsoft Graph uses standard REST: GET for reads, POST for writes. Use \`connectionId\` from \`vault_connections_list\`.
|
|
387
|
+
Base URL: \`https://graph.microsoft.com/v1.0\`
|
|
388
|
+
⚠ Query parameters use OData syntax with \`$\` prefix: \`$top\`, \`$select\`, \`$orderby\`, \`$filter\`.
|
|
389
|
+
|
|
390
|
+
**Mail:**
|
|
391
|
+
- List messages: \`GET /me/messages\` — query: \`{ $top, $orderby, $select }\`
|
|
392
|
+
- Send mail: \`POST /me/sendMail\` — body: \`{ message: { subject, body: { contentType, content }, toRecipients: [{ emailAddress: { address } }] } }\`
|
|
393
|
+
- Policy notes:
|
|
394
|
+
- **Strict read**: listing messages is allowed; reading message body/attachments requires approval
|
|
395
|
+
- **Strict manage**: same read constraints; sending mail requires approval; deletion is blocked
|
|
396
|
+
- **Balanced**: all reads allowed; attachment downloads require approval
|
|
397
|
+
|
|
398
|
+
**Calendar:**
|
|
399
|
+
- List events: \`GET /me/calendarView\` — query: \`{ startDateTime, endDateTime, $select }\`
|
|
400
|
+
- Create event: \`POST /me/events\` — body: \`{ subject, start, end, attendees }\`
|
|
401
|
+
- Policy notes:
|
|
402
|
+
- **Strict read**: listing events is allowed; reading individual event details requires approval
|
|
403
|
+
- **Strict manage**: same read constraints; event creation/modification requires approval; deletion is blocked
|
|
404
|
+
- **Balanced**: all reads allowed; writes allowed within rate limits
|
|
405
|
+
|
|
406
|
+
**Teams:**
|
|
407
|
+
- List chats: \`GET /me/chats\` — query: \`{ $top }\`
|
|
408
|
+
- Read messages: \`GET /me/chats/{chatId}/messages\` — query: \`{ $top }\`
|
|
409
|
+
- Send to chat: \`POST /me/chats/{chatId}/messages\` — body: \`{ body: { content } }\`
|
|
410
|
+
- Send to channel: \`POST /teams/{teamId}/channels/{channelId}/messages\` — body: \`{ body: { content } }\`
|
|
411
|
+
|
|
412
|
+
**Contacts:**
|
|
413
|
+
- List contacts: \`GET /me/contacts\` — query: \`{ $top, $select, $orderby }\`
|
|
414
|
+
- Get contact: \`GET /me/contacts/{contactId}\`
|
|
415
|
+
- Search people: \`GET /me/people\` — query: \`{ $search: "name", $top }\`
|
|
416
|
+
- Create contact: \`POST /me/contacts\` — body: \`{ givenName, surname, emailAddresses: [{ address, name }], businessPhones: ["..."] }\`
|
|
417
|
+
- Update contact: \`PATCH /me/contacts/{contactId}\` — body: updated fields
|
|
418
|
+
- Delete contact: \`DELETE /me/contacts/{contactId}\`
|
|
419
|
+
- List contact folders: \`GET /me/contactFolders\`
|
|
420
|
+
- Policy notes:
|
|
421
|
+
- **Minimal**: notes stripped, all other fields visible
|
|
422
|
+
- **Balanced**: PII fields (phone numbers, addresses, birthdays) stripped by default. To access full fields for a **specific contact**, add \`requestFullFields: true\` to vault_execute — only works on individual contact endpoints (e.g. \`GET /v1.0/me/contacts/{id}\`), NOT on list endpoints. Once approved, re-submit with both \`approvalId\` and \`requestFullFields: true\`. Notes remain stripped.
|
|
423
|
+
- **Strict**: PII fields always stripped, no way to request them. Deletion is blocked on manage connections.
|
|
424
|
+
|
|
425
|
+
**Files (OneDrive):**
|
|
426
|
+
- List root files: \`GET /me/drive/root/children\` — query: \`{ $select, $top, $orderby }\`
|
|
427
|
+
- List folder contents: \`GET /me/drive/items/{itemId}/children\`
|
|
428
|
+
- Get file metadata: \`GET /me/drive/items/{itemId}\` — query: \`{ $select: "id,name,file,size,webUrl" }\`
|
|
429
|
+
- Search files: \`GET /me/drive/root/search(q='{query}')\`
|
|
430
|
+
- Upload small file (<4MB): \`PUT /me/drive/root:/{path}:/content\` — body: file bytes, header: \`Content-Type: application/octet-stream\`
|
|
431
|
+
- Create folder: \`POST /me/drive/root/children\` — body: \`{ name, folder: {}, "@microsoft.graph.conflictBehavior": "rename" }\`
|
|
432
|
+
- Delete item: \`DELETE /me/drive/items/{itemId}\`
|
|
433
|
+
- Move/rename: \`PATCH /me/drive/items/{itemId}\` — body: \`{ name, parentReference: { id } }\`
|
|
434
|
+
- Create sharing link: \`POST /me/drive/items/{itemId}/createLink\` — body: \`{ type: "view"|"edit", scope: "organization"|"anonymous" }\`
|
|
435
|
+
- Invite collaborator: \`POST /me/drive/items/{itemId}/invite\` — body: \`{ recipients: [{ email }], roles: ["read"|"write"] }\`
|
|
436
|
+
|
|
437
|
+
**Excel Workbook API** (read spreadsheet content as structured JSON — no binary download):
|
|
438
|
+
- List worksheets: \`GET /me/drive/items/{itemId}/workbook/worksheets\`
|
|
439
|
+
- Read used range: \`GET /me/drive/items/{itemId}/workbook/worksheets/{sheetName}/usedRange\` — returns \`{ values: [[...]] }\`
|
|
440
|
+
- Read specific range: \`GET /me/drive/items/{itemId}/workbook/worksheets/{sheetName}/range(address='A1:Z100')\`
|
|
441
|
+
- Update cells: \`PATCH /me/drive/items/{itemId}/workbook/worksheets/{sheetName}/range(address='A1:B2')\` — body: \`{ values: [["a","b"],["c","d"]] }\`
|
|
442
|
+
- Add rows: \`POST /me/drive/items/{itemId}/workbook/tables/{tableId}/rows\` — body: \`{ values: [["a","b"]] }\`
|
|
443
|
+
|
|
444
|
+
**Reading OneDrive file contents — decision tree:**
|
|
445
|
+
1. Get file metadata first: \`GET /me/drive/items/{id}?$select=name,file,size\` — check \`file.mimeType\`
|
|
446
|
+
2. **Excel files** (\`.xlsx\`, \`.xls\`, \`.csv\` opened in Excel) → Use the Excel Workbook API above via \`vault_execute\` — returns structured JSON with cell values, no binary download needed
|
|
447
|
+
3. **Text files** (\`.txt\`, \`.csv\`, \`.json\`, \`.md\`, \`.log\`, \`.xml\`, \`.html\`) → \`vault_download\` to save to disk, then read the local file
|
|
448
|
+
4. **Other binary files** (images, PDFs, \`.docx\`, \`.pptx\`, audio, video) → \`vault_download\`
|
|
449
|
+
5. **Never** use \`vault_execute\` with \`/content\` — the \`/content\` endpoint returns binary data via a redirect to SharePoint, which cannot pass through JSON serialization. You will get a \`_binaryContent\` metadata response instead of actual file content.
|
|
450
|
+
6. **Do NOT use Google APIs** (Sheets, Docs, Drive) to read OneDrive files — they are different providers.
|
|
451
|
+
|
|
452
|
+
- Policy notes (OneDrive):
|
|
453
|
+
- **Strict**: binary downloads (\`/content\`) are blocked; use the Excel Workbook API for spreadsheets. File listing is allowed; metadata reads require approval
|
|
454
|
+
- **Balanced**: binary downloads require approval; all reads allowed; writes allowed within rate limits
|
|
455
|
+
- **Minimal**: all operations allowed within rate limits`,
|
|
456
|
+
msteams: ``, // covered by "microsoft"
|
|
457
|
+
slack: `### Slack API (provider: slack, singleton)
|
|
458
|
+
|
|
459
|
+
**⚠ ALL Slack API methods use POST — never use GET.** This is not standard REST. Even read operations
|
|
460
|
+
(conversations.history, users.info) require POST with parameters in the JSON body, not query strings.
|
|
461
|
+
|
|
462
|
+
Use \`service: "slack"\` with \`vault_execute\`. The vault injects the bot token as a Bearer header automatically.
|
|
463
|
+
|
|
464
|
+
**Read operations (all POST):**
|
|
465
|
+
- Read messages: \`POST https://slack.com/api/conversations.history\` — body: \`{ channel, limit }\`
|
|
466
|
+
- Read thread: \`POST https://slack.com/api/conversations.replies\` — body: \`{ channel, ts }\`
|
|
467
|
+
- List channels: \`POST https://slack.com/api/conversations.list\` — body: \`{ types, limit }\`
|
|
468
|
+
- Get user info: \`POST https://slack.com/api/users.info\` — body: \`{ user }\`
|
|
469
|
+
- List emoji: \`POST https://slack.com/api/emoji.list\`
|
|
470
|
+
- List pins: \`POST https://slack.com/api/pins.list\` — body: \`{ channel }\`
|
|
471
|
+
|
|
472
|
+
**Write operations (all POST):**
|
|
473
|
+
- Send message: \`POST https://slack.com/api/chat.postMessage\` — body: \`{ channel, text, blocks }\`
|
|
474
|
+
- Update message: \`POST https://slack.com/api/chat.update\` — body: \`{ channel, ts, text }\`
|
|
475
|
+
- Delete message: \`POST https://slack.com/api/chat.delete\` — body: \`{ channel, ts }\`
|
|
476
|
+
- Upload file: \`POST https://slack.com/api/files.uploadV2\` — body: \`{ channel_id, content, filename }\`
|
|
477
|
+
- Add reaction: \`POST https://slack.com/api/reactions.add\` — body: \`{ channel, timestamp, name }\`
|
|
478
|
+
|
|
479
|
+
Wrong: \`GET https://slack.com/api/conversations.history?channel=C123&limit=10\`
|
|
480
|
+
Right: \`POST https://slack.com/api/conversations.history\` with body \`{ "channel": "C123", "limit": 10 }\``,
|
|
481
|
+
telegram: `### Telegram Bot API (provider: telegram, singleton)
|
|
482
|
+
|
|
483
|
+
**URL format:** \`https://api.telegram.org/bot/<method>\` — the vault injects the real bot token automatically.
|
|
484
|
+
Do NOT put a token or placeholder in the URL (NOT \`/bot{token}/sendMessage\`, NOT \`/bot123:ABC/sendMessage\`).
|
|
485
|
+
|
|
486
|
+
**Write operations (POST):**
|
|
487
|
+
- Send message: \`POST https://api.telegram.org/bot/sendMessage\` — body: \`{ chat_id, text, parse_mode }\`
|
|
488
|
+
- Send photo: \`POST https://api.telegram.org/bot/sendPhoto\` — body: \`{ chat_id, photo }\`
|
|
489
|
+
- Forward message: \`POST https://api.telegram.org/bot/forwardMessage\` — body: \`{ chat_id, from_chat_id, message_id }\`
|
|
490
|
+
|
|
491
|
+
**Read operations (GET):**
|
|
492
|
+
- Get updates: \`GET https://api.telegram.org/bot/getUpdates\` — query: \`{ offset, timeout }\`
|
|
493
|
+
- Get chat: \`GET https://api.telegram.org/bot/getChat\` — query: \`{ chat_id }\`
|
|
494
|
+
|
|
495
|
+
Use \`service: "telegram"\` with \`vault_execute\`. Never use a connectionId for Telegram.
|
|
496
|
+
Incoming messages are auto-polled — you do NOT need to call getUpdates yourself.`,
|
|
497
|
+
notion: `### Notion API (provider: notion, multi-account — use connectionId)
|
|
498
|
+
|
|
499
|
+
**Base URL:** \`https://api.notion.com\`
|
|
500
|
+
⚠ **Every request MUST include the \`Notion-Version\` header.** Pass it in the \`headers\` field:
|
|
501
|
+
\`headers: { "Notion-Version": "2022-06-28" }\`
|
|
502
|
+
|
|
503
|
+
⚠ **Notion uses POST for some read operations** (search, database queries). These are NOT writes — they just happen to use POST.
|
|
504
|
+
|
|
505
|
+
Use \`connectionId\` from \`vault_connections_list\`. Notion is NOT a singleton — each user authorizes their own workspace.
|
|
506
|
+
|
|
507
|
+
**Read operations:**
|
|
508
|
+
- Search pages & databases: \`POST https://api.notion.com/v1/search\` — body: \`{ query: "search text" }\`
|
|
509
|
+
- Get page: \`GET https://api.notion.com/v1/pages/{page_id}\`
|
|
510
|
+
- Get page property: \`GET https://api.notion.com/v1/pages/{page_id}/properties/{property_id}\`
|
|
511
|
+
- Get database: \`GET https://api.notion.com/v1/databases/{database_id}\`
|
|
512
|
+
- Query database: \`POST https://api.notion.com/v1/databases/{database_id}/query\` — body: \`{ filter: {...}, sorts: [...] }\`
|
|
513
|
+
- Get block: \`GET https://api.notion.com/v1/blocks/{block_id}\`
|
|
514
|
+
- List block children: \`GET https://api.notion.com/v1/blocks/{block_id}/children\`
|
|
515
|
+
- List comments: \`GET https://api.notion.com/v1/comments\` — query: \`{ block_id }\`
|
|
516
|
+
- List users: \`GET https://api.notion.com/v1/users\`
|
|
517
|
+
|
|
518
|
+
**Write operations:**
|
|
519
|
+
- Create page: \`POST https://api.notion.com/v1/pages\` — body: \`{ parent: { database_id: "..." }, properties: {...} }\`
|
|
520
|
+
- Update page: \`PATCH https://api.notion.com/v1/pages/{page_id}\` — body: \`{ properties: {...} }\`
|
|
521
|
+
- Update block: \`PATCH https://api.notion.com/v1/blocks/{block_id}\` — body: \`{ type: {...} }\`
|
|
522
|
+
- Append blocks: \`PATCH https://api.notion.com/v1/blocks/{block_id}/children\` — body: \`{ children: [...] }\`
|
|
523
|
+
- Delete block: \`DELETE https://api.notion.com/v1/blocks/{block_id}\`
|
|
524
|
+
- Create comment: \`POST https://api.notion.com/v1/comments\` — body: \`{ parent: { page_id: "..." }, rich_text: [...] }\`
|
|
525
|
+
|
|
526
|
+
**Common property formats:**
|
|
527
|
+
- Title: \`{ title: [{ text: { content: "..." } }] }\`
|
|
528
|
+
- Rich text: \`{ rich_text: [{ text: { content: "..." } }] }\`
|
|
529
|
+
- Select: \`{ select: { name: "Option" } }\`
|
|
530
|
+
- Date: \`{ date: { start: "2026-01-15" } }\`
|
|
531
|
+
- Checkbox: \`{ checkbox: true }\``,
|
|
532
|
+
trello: `### Trello API (provider: trello, multi-account — use connectionId)
|
|
533
|
+
|
|
534
|
+
**Base URL:** \`https://api.trello.com\`
|
|
535
|
+
⚠ **Do NOT include \`key\` or \`token\` query parameters** — the vault injects both automatically.
|
|
536
|
+
|
|
537
|
+
Use \`connectionId\` from \`vault_connections_list\`. Trello is NOT a singleton — each user connects their own account.
|
|
538
|
+
|
|
539
|
+
**Read operations (GET):**
|
|
540
|
+
- List boards: \`GET https://api.trello.com/1/members/me/boards\`
|
|
541
|
+
- Get board: \`GET https://api.trello.com/1/boards/{boardId}\`
|
|
542
|
+
- Board lists: \`GET https://api.trello.com/1/boards/{boardId}/lists\`
|
|
543
|
+
- Board cards: \`GET https://api.trello.com/1/boards/{boardId}/cards\`
|
|
544
|
+
- Board labels: \`GET https://api.trello.com/1/boards/{boardId}/labels\`
|
|
545
|
+
- Get list: \`GET https://api.trello.com/1/lists/{listId}\`
|
|
546
|
+
- List cards: \`GET https://api.trello.com/1/lists/{listId}/cards\`
|
|
547
|
+
- Get card: \`GET https://api.trello.com/1/cards/{cardId}\`
|
|
548
|
+
- Card activity: \`GET https://api.trello.com/1/cards/{cardId}/actions\`
|
|
549
|
+
- Card attachments: \`GET https://api.trello.com/1/cards/{cardId}/attachments\`
|
|
550
|
+
- Card checklists: \`GET https://api.trello.com/1/cards/{cardId}/checklists\`
|
|
551
|
+
|
|
552
|
+
**Write operations:**
|
|
553
|
+
- Create card: \`POST https://api.trello.com/1/cards\` — body: \`{ name, idList, desc }\`
|
|
554
|
+
- Update card: \`PUT https://api.trello.com/1/cards/{cardId}\` — body: \`{ name, desc, closed, idList }\`
|
|
555
|
+
- Delete card: \`DELETE https://api.trello.com/1/cards/{cardId}\`
|
|
556
|
+
- Archive card: \`PUT https://api.trello.com/1/cards/{cardId}\` — body: \`{ closed: true }\`
|
|
557
|
+
- Add comment: \`POST https://api.trello.com/1/cards/{cardId}/actions/comments\` — body: \`{ text }\`
|
|
558
|
+
- Create list: \`POST https://api.trello.com/1/lists\` — body: \`{ name, idBoard }\`
|
|
559
|
+
- Update list: \`PUT https://api.trello.com/1/lists/{listId}\` — body: \`{ name }\``,
|
|
560
|
+
jira: `### Jira Cloud REST API v3
|
|
561
|
+
|
|
562
|
+
Base URL: \`https://{siteUrl}/rest/api/3/\` (use the site URL from your connection)
|
|
563
|
+
|
|
564
|
+
**Read operations:**
|
|
565
|
+
- \`GET /rest/api/3/myself\` — current user info
|
|
566
|
+
- \`GET /rest/api/3/search/jql?jql={query}\` — search issues with JQL (preferred)
|
|
567
|
+
- \`GET /rest/api/3/search?jql={query}\` — search issues (deprecated, use search/jql instead)
|
|
568
|
+
- \`GET /rest/api/3/issue/{issueIdOrKey}\` — get issue details
|
|
569
|
+
- \`GET /rest/api/3/issue/{issueIdOrKey}/comment\` — get issue comments
|
|
570
|
+
- \`GET /rest/api/3/project\` — list projects
|
|
571
|
+
- \`GET /rest/api/3/project/{projectIdOrKey}\` — get project details
|
|
572
|
+
|
|
573
|
+
**Write operations:**
|
|
574
|
+
- \`POST /rest/api/3/issue\` — create issue (body: \`{"fields":{"project":{"key":"PROJ"},"summary":"...","issuetype":{"name":"Task"}}}\`)
|
|
575
|
+
- \`PUT /rest/api/3/issue/{issueIdOrKey}\` — update issue fields
|
|
576
|
+
- \`POST /rest/api/3/issue/{issueIdOrKey}/comment\` — add comment (body: \`{"body":{"type":"doc","version":1,"content":[{"type":"paragraph","content":[{"type":"text","text":"..."}]}]}}\`)
|
|
577
|
+
- \`POST /rest/api/3/issue/{issueIdOrKey}/transitions\` — transition issue (body: \`{"transition":{"id":"..."}}\`)
|
|
578
|
+
- \`DELETE /rest/api/3/issue/{issueIdOrKey}\` — delete issue
|
|
579
|
+
|
|
580
|
+
> Do NOT include Authorization headers; the vault injects Basic auth credentials automatically.
|
|
581
|
+
> Always use the full URL including your Jira site domain.`,
|
|
582
|
+
};
|
|
583
|
+
// ---------------------------------------------------------------------------
|
|
584
|
+
// Chunked file writing
|
|
585
|
+
// ---------------------------------------------------------------------------
|
|
586
|
+
/**
|
|
587
|
+
* Write chunked reference files to a state directory.
|
|
588
|
+
*
|
|
589
|
+
* - Base file (vault-reference.md): tools, permission flow, action templates, notes
|
|
590
|
+
* - Per-service files (vault-ref-{service}.md): API docs for each provider
|
|
591
|
+
*
|
|
592
|
+
* Returns the paths so the system prompt can list them.
|
|
593
|
+
*/
|
|
594
|
+
export function writeReferenceFiles(stateDir, logger) {
|
|
595
|
+
// 1. Write base reference (no provider API docs)
|
|
596
|
+
const basePath = join(stateDir, "vault-reference.md");
|
|
597
|
+
const baseContent = [
|
|
598
|
+
SECTION_HEADER,
|
|
599
|
+
SECTION_TOOLS,
|
|
600
|
+
SECTION_PERMISSION_FLOW,
|
|
601
|
+
SECTION_ACTION_TEMPLATES,
|
|
602
|
+
SECTION_NOTES,
|
|
603
|
+
].join("\n\n");
|
|
604
|
+
writeFileSync(basePath, baseContent, "utf-8");
|
|
605
|
+
logger?.info?.(`wrote base reference to ${basePath} (${baseContent.length} chars)`);
|
|
606
|
+
// 2. Write ALL per-service API reference files.
|
|
607
|
+
const serviceFiles = [];
|
|
608
|
+
const seen = new Set();
|
|
609
|
+
for (const [provider, section] of Object.entries(CHUNKED_API_SECTIONS)) {
|
|
610
|
+
if (!section || seen.has(section)) {
|
|
611
|
+
continue;
|
|
612
|
+
}
|
|
613
|
+
seen.add(section);
|
|
614
|
+
const serviceName = PROVIDER_TO_SERVICE[provider] ?? provider;
|
|
615
|
+
const filePath = join(stateDir, `vault-ref-${serviceName}.md`);
|
|
616
|
+
writeFileSync(filePath, section, "utf-8");
|
|
617
|
+
serviceFiles.push(filePath);
|
|
618
|
+
logger?.info?.(`wrote service reference to ${filePath} (${section.length} chars)`);
|
|
619
|
+
}
|
|
620
|
+
return { basePath, serviceFiles };
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Build the lean system prompt that points to the chunked reference files.
|
|
624
|
+
* Injected via the before_agent_start / before_prompt_build hook.
|
|
625
|
+
*/
|
|
626
|
+
export function buildChunkedPrompt(basePath, serviceFiles) {
|
|
627
|
+
const instructions = [
|
|
628
|
+
`You have AgentHiFive vault integration for external services (email, calendar, files, messaging).`,
|
|
629
|
+
`For vault-managed services, ALWAYS use vault_execute — never the built-in message tool (it will 404). Never ask for credentials or tokens directly.`,
|
|
630
|
+
`Base reference (tools, permissions, action templates): ${basePath}`,
|
|
631
|
+
...(serviceFiles.length > 0
|
|
632
|
+
? [
|
|
633
|
+
`Service API docs (read the relevant file before making vault_execute calls):`,
|
|
634
|
+
...serviceFiles.map((f) => ` - ${f}`),
|
|
635
|
+
]
|
|
636
|
+
: []),
|
|
637
|
+
`When asked about available integrations, supported services, or new connections: read the vault reference file FIRST (action templates table) to see what's supported — before calling vault_connections_list. The reference is the source of truth for supported services; connections only show what's currently active.`,
|
|
638
|
+
`CRITICAL — Enabling/disabling vault-managed channels: ALWAYS use config.patch, NOT request_permission.`,
|
|
639
|
+
`NEVER ask users for bot tokens, app tokens, or API keys — the vault injects credentials automatically.`,
|
|
640
|
+
`If the vault returns a "hint" field in an error response, follow its guidance.`,
|
|
641
|
+
`Step-up approvals: when vault_execute returns 202 (approval required), tell the user their request needs approval and to check the dashboard. Do NOT call vault_await_approval — the system will automatically notify you when the approval resolves. When you receive an approval notification, re-submit the exact same vault_execute call with the approvalId provided.`,
|
|
642
|
+
].join("\n");
|
|
643
|
+
return `<vault-context silent="true">\n${instructions}\n</vault-context>`;
|
|
644
|
+
}
|
|
645
|
+
//# sourceMappingURL=prompt-reference.js.map
|