@voltagent/core 2.2.1 → 2.2.2
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/docs/actions-triggers-docs/actions/airtable.md +142 -0
- package/docs/actions-triggers-docs/actions/discord.md +142 -0
- package/docs/actions-triggers-docs/actions/gmail.md +134 -0
- package/docs/actions-triggers-docs/actions/google-calendar.md +145 -0
- package/docs/actions-triggers-docs/actions/google-drive.md +127 -0
- package/docs/actions-triggers-docs/actions/overview.md +100 -0
- package/docs/actions-triggers-docs/actions/postgres.md +115 -0
- package/docs/actions-triggers-docs/actions/slack.md +144 -0
- package/docs/actions-triggers-docs/overview.md +69 -0
- package/docs/actions-triggers-docs/triggers/airtable.md +157 -0
- package/docs/actions-triggers-docs/triggers/cron.md +135 -0
- package/docs/actions-triggers-docs/triggers/github.md +178 -0
- package/docs/actions-triggers-docs/triggers/gmail.md +189 -0
- package/docs/actions-triggers-docs/triggers/google-calendar.md +76 -0
- package/docs/actions-triggers-docs/triggers/google-drive.md +72 -0
- package/docs/actions-triggers-docs/triggers/overview.md +73 -0
- package/docs/actions-triggers-docs/triggers/slack.md +96 -0
- package/docs/actions-triggers-docs/triggers/usage.md +246 -0
- package/docs/actions.md +28 -0
- package/docs/agents/a2a/a2a-server.md +228 -0
- package/docs/agents/cancellation.md +397 -0
- package/docs/agents/context.md +932 -0
- package/docs/agents/dynamic-agents.md +436 -0
- package/docs/agents/hooks.md +583 -0
- package/docs/agents/mcp/authorization.md +557 -0
- package/docs/agents/mcp/mcp-server.md +338 -0
- package/docs/agents/mcp/mcp.md +334 -0
- package/docs/agents/memory/cloudflare-d1.md +160 -0
- package/docs/agents/memory/in-memory.md +142 -0
- package/docs/agents/memory/libsql.md +179 -0
- package/docs/agents/memory/managed-memory.md +276 -0
- package/docs/agents/memory/overview.md +355 -0
- package/docs/agents/memory/postgres.md +275 -0
- package/docs/agents/memory/semantic-search.md +238 -0
- package/docs/agents/memory/supabase.md +285 -0
- package/docs/agents/memory/working-memory.md +299 -0
- package/docs/agents/memory.md +67 -0
- package/docs/agents/message-types.md +531 -0
- package/docs/agents/middleware.md +105 -0
- package/docs/agents/multi-modal.md +308 -0
- package/docs/agents/overview.md +833 -0
- package/docs/agents/plan-agent.md +294 -0
- package/docs/agents/prompts.md +297 -0
- package/docs/agents/providers.md +56 -0
- package/docs/agents/resumable-streaming.md +710 -0
- package/docs/agents/retries-fallback.md +203 -0
- package/docs/agents/subagents.md +941 -0
- package/docs/agents/summarization.md +79 -0
- package/docs/agents/tools.md +1061 -0
- package/docs/agents/voice.md +479 -0
- package/docs/agents/voltagent-instance.md +195 -0
- package/docs/api/api-reference.md +315 -0
- package/docs/api/authentication.md +682 -0
- package/docs/api/custom-endpoints.md +680 -0
- package/docs/api/endpoints/agents.md +662 -0
- package/docs/api/endpoints/memory.md +216 -0
- package/docs/api/endpoints/tools.md +91 -0
- package/docs/api/endpoints/workflows.md +646 -0
- package/docs/api/overview.md +164 -0
- package/docs/api/server-architecture.md +521 -0
- package/docs/api/streaming.md +139 -0
- package/docs/blog/2025-04-21-first-ai-agent-github-repo-analyzer/index.md +266 -0
- package/docs/blog/2025-04-21-introducing-developer-console/index.md +100 -0
- package/docs/blog/2025-04-21-introducing-voltagent/index.md +78 -0
- package/docs/blog/2025-04-21-introducing-voltagent/intro-image.png +0 -0
- package/docs/blog/2025-04-23-multi-agent-llm/index.md +193 -0
- package/docs/blog/2025-04-24-rag-chatbot/index.md +303 -0
- package/docs/blog/2025-04-25-what-is-an-mcp-server/index.md +287 -0
- package/docs/blog/2025-04-26-peaka-mcp-voltagent/index.md +184 -0
- package/docs/blog/2025-04-27-building-voltagent/index.md +74 -0
- package/docs/blog/2025-04-28-building-google-drive-chatbot/index.md +171 -0
- package/docs/blog/2025-05-01-voltagent-marketplace/index.md +64 -0
- package/docs/blog/2025-05-13-llm-observability/index.md +148 -0
- package/docs/blog/2025-05-15-top-ai-agent-frameworks/index.md +374 -0
- package/docs/blog/2025-05-16-multimodal-rag/index.md +161 -0
- package/docs/blog/2025-05-19-llm-orchestration/index.md +286 -0
- package/docs/blog/2025-05-23-llm-agent-framework/index.md +454 -0
- package/docs/blog/2025-05-26-llm-agents/index.md +422 -0
- package/docs/blog/2025-05-28-langfuse/index.md +512 -0
- package/docs/blog/2025-05-30-rag-vs-finetuning/index.md +261 -0
- package/docs/blog/2025-06-03-vercel-ai-observability/index.md +365 -0
- package/docs/blog/2025-07-02-top-llm-observability/index.md +198 -0
- package/docs/blog/2025-07-16-ai-agent-orchestration/index.md +531 -0
- package/docs/blog/2025-07-20-llm-evaluation/index.md +440 -0
- package/docs/blog/2025-07-23-llm-testing/index.md +526 -0
- package/docs/blog/2025-07-24-crew-ai/index.md +186 -0
- package/docs/blog/2025-07-25-mcp-tutorial/index.md +254 -0
- package/docs/blog/2025-07-29-ts-ai-agent/index.md +550 -0
- package/docs/blog/2025-07-30-claude-code-agents/index.md +508 -0
- package/docs/blog/2025-08-04-ai-agent-vs-chatbot/index.md +251 -0
- package/docs/blog/2025-08-07-llm-guardrails/index.md +639 -0
- package/docs/blog/2025-08-08-agents-use-case/index.md +476 -0
- package/docs/blog/2025-08-11-llm-finetuning/index.md +352 -0
- package/docs/blog/2025-08-22-n8n-pricing/index.md +184 -0
- package/docs/blog/2025-09-05-agents-brief/index.md +178 -0
- package/docs/blog/2025-09-08-vector-db/index.md +325 -0
- package/docs/blog/2025-10-06-open-builder/index.md +72 -0
- package/docs/blog/2025-10-14-llmafactory/index.md +209 -0
- package/docs/blog/2025-10-14-vercel-ai-sdk/index.md +231 -0
- package/docs/blog/2025-10-20-guardrails/index.md +226 -0
- package/docs/blog/2025-10-21-ai-agent-examples/index.md +357 -0
- package/docs/blog/2026-01-23-tool-routing/index.md +245 -0
- package/docs/blog/authors.yml +26 -0
- package/docs/blog/image.png +0 -0
- package/docs/community/contributing.md +223 -0
- package/{LICENCE → docs/community/licence.md} +24 -2
- package/docs/community/overview.md +7 -0
- package/docs/deployment-docs/cloudflare-workers.md +375 -0
- package/docs/deployment-docs/local-tunnel.md +150 -0
- package/docs/deployment-docs/netlify-functions.md +176 -0
- package/docs/deployment-docs/overview.md +66 -0
- package/docs/deployment-docs/voltops.md +170 -0
- package/docs/deployment.md +21 -0
- package/docs/evals.md +19 -0
- package/docs/evaluation-docs/building-custom-scorers.md +550 -0
- package/docs/evaluation-docs/cli-reference.md +399 -0
- package/docs/evaluation-docs/datasets.md +378 -0
- package/docs/evaluation-docs/experiments.md +562 -0
- package/docs/evaluation-docs/live-evaluations.md +757 -0
- package/docs/evaluation-docs/offline-evaluations.md +1018 -0
- package/docs/evaluation-docs/overview.md +189 -0
- package/docs/evaluation-docs/prebuilt-scorers.md +892 -0
- package/docs/evaluation-docs/using-with-viteval.md +228 -0
- package/docs/getting-started/ai-assistants.md +116 -0
- package/docs/getting-started/comparison.mdx +211 -0
- package/docs/getting-started/manual-setup.md +298 -0
- package/docs/getting-started/migration-guide.md +806 -0
- package/docs/getting-started/model-router.md +101 -0
- package/docs/getting-started/overview.md +207 -0
- package/docs/getting-started/providers-models.md +369 -0
- package/docs/getting-started/quick-start.md +431 -0
- package/docs/guardrails/built-in.md +233 -0
- package/docs/guardrails/overview.md +660 -0
- package/docs/home.md +12 -0
- package/docs/integrations/nextjs.md +376 -0
- package/docs/integrations/overview.md +12 -0
- package/docs/integrations/vercel-ai.md +458 -0
- package/docs/models-docs/overview.md +199 -0
- package/docs/models-docs/providers/abacus.md +104 -0
- package/docs/models-docs/providers/aihubmix.md +81 -0
- package/docs/models-docs/providers/alibaba-cn.md +110 -0
- package/docs/models-docs/providers/alibaba.md +88 -0
- package/docs/models-docs/providers/amazon-bedrock.md +116 -0
- package/docs/models-docs/providers/anthropic.md +68 -0
- package/docs/models-docs/providers/azure-cognitive-services.md +138 -0
- package/docs/models-docs/providers/azure.md +140 -0
- package/docs/models-docs/providers/bailing.md +51 -0
- package/docs/models-docs/providers/baseten.md +55 -0
- package/docs/models-docs/providers/cerebras.md +51 -0
- package/docs/models-docs/providers/chutes.md +105 -0
- package/docs/models-docs/providers/cloudflare-ai-gateway.md +115 -0
- package/docs/models-docs/providers/cloudflare-workers-ai.md +102 -0
- package/docs/models-docs/providers/cohere.md +54 -0
- package/docs/models-docs/providers/cortecs.md +65 -0
- package/docs/models-docs/providers/deepinfra.md +56 -0
- package/docs/models-docs/providers/deepseek.md +51 -0
- package/docs/models-docs/providers/fastrouter.md +63 -0
- package/docs/models-docs/providers/fireworks-ai.md +65 -0
- package/docs/models-docs/providers/firmware.md +67 -0
- package/docs/models-docs/providers/friendli.md +60 -0
- package/docs/models-docs/providers/github-copilot.md +69 -0
- package/docs/models-docs/providers/github-models.md +104 -0
- package/docs/models-docs/providers/gitlab.md +50 -0
- package/docs/models-docs/providers/google-vertex-anthropic.md +58 -0
- package/docs/models-docs/providers/google-vertex.md +68 -0
- package/docs/models-docs/providers/google.md +74 -0
- package/docs/models-docs/providers/groq.md +56 -0
- package/docs/models-docs/providers/helicone.md +140 -0
- package/docs/models-docs/providers/huggingface.md +63 -0
- package/docs/models-docs/providers/iflowcn.md +63 -0
- package/docs/models-docs/providers/inception.md +51 -0
- package/docs/models-docs/providers/inference.md +58 -0
- package/docs/models-docs/providers/io-net.md +66 -0
- package/docs/models-docs/providers/kimi-for-coding.md +48 -0
- package/docs/models-docs/providers/llama.md +56 -0
- package/docs/models-docs/providers/lmstudio.md +52 -0
- package/docs/models-docs/providers/lucidquery.md +51 -0
- package/docs/models-docs/providers/minimax-cn.md +49 -0
- package/docs/models-docs/providers/minimax.md +49 -0
- package/docs/models-docs/providers/mistral.md +73 -0
- package/docs/models-docs/providers/modelscope.md +56 -0
- package/docs/models-docs/providers/moonshotai-cn.md +54 -0
- package/docs/models-docs/providers/moonshotai.md +54 -0
- package/docs/models-docs/providers/morph.md +52 -0
- package/docs/models-docs/providers/nano-gpt.md +70 -0
- package/docs/models-docs/providers/nebius.md +64 -0
- package/docs/models-docs/providers/novita-ai.md +126 -0
- package/docs/models-docs/providers/nvidia.md +115 -0
- package/docs/models-docs/providers/ollama-cloud.md +61 -0
- package/docs/models-docs/providers/openai.md +87 -0
- package/docs/models-docs/providers/opencode.md +76 -0
- package/docs/models-docs/providers/openrouter.md +188 -0
- package/docs/models-docs/providers/overview.md +102 -0
- package/docs/models-docs/providers/ovhcloud.md +64 -0
- package/docs/models-docs/providers/perplexity.md +50 -0
- package/docs/models-docs/providers/poe.md +164 -0
- package/docs/models-docs/providers/privatemode-ai.md +55 -0
- package/docs/models-docs/providers/requesty.md +69 -0
- package/docs/models-docs/providers/sap-ai-core.md +61 -0
- package/docs/models-docs/providers/scaleway.md +63 -0
- package/docs/models-docs/providers/siliconflow-cn.md +121 -0
- package/docs/models-docs/providers/siliconflow.md +124 -0
- package/docs/models-docs/providers/submodel.md +58 -0
- package/docs/models-docs/providers/synthetic.md +74 -0
- package/docs/models-docs/providers/togetherai.md +57 -0
- package/docs/models-docs/providers/upstage.md +52 -0
- package/docs/models-docs/providers/v0.md +50 -0
- package/docs/models-docs/providers/venice.md +74 -0
- package/docs/models-docs/providers/vercel.md +226 -0
- package/docs/models-docs/providers/vivgrid.md +48 -0
- package/docs/models-docs/providers/vultr.md +54 -0
- package/docs/models-docs/providers/wandb.md +59 -0
- package/docs/models-docs/providers/xai.md +69 -0
- package/docs/models-docs/providers/xiaomi.md +50 -0
- package/docs/models-docs/providers/zai-coding-plan.md +56 -0
- package/docs/models-docs/providers/zai.md +56 -0
- package/docs/models-docs/providers/zenmux.md +100 -0
- package/docs/models-docs/providers/zhipuai-coding-plan.md +57 -0
- package/docs/models-docs/providers/zhipuai.md +57 -0
- package/docs/observability/developer-console.md +262 -0
- package/docs/observability/feedback.md +9 -0
- package/docs/observability/langfuse.md +63 -0
- package/docs/observability/logging.md +725 -0
- package/docs/observability/overview.md +19 -0
- package/docs/observability-platform/alerts.md +197 -0
- package/docs/observability-platform/amazon-bedrock.md +15 -0
- package/docs/observability-platform/concept.md +56 -0
- package/docs/observability-platform/dashboard.md +175 -0
- package/docs/observability-platform/feedback.md +329 -0
- package/docs/observability-platform/google-vertex-ai.md +15 -0
- package/docs/observability-platform/huggingface.md +15 -0
- package/docs/observability-platform/llm-usage-and-costs.md +36 -0
- package/docs/observability-platform/overview.md +24 -0
- package/docs/observability-platform/setup.md +151 -0
- package/docs/observability-platform/tracing/feedback.md +23 -0
- package/docs/observability-platform/tracing/logs.md +18 -0
- package/docs/observability-platform/tracing/node-based.md +15 -0
- package/docs/observability-platform/tracing/overview.md +45 -0
- package/docs/observability-platform/tracing/users.md +50 -0
- package/docs/observability-platform/tracing/waterfall.md +25 -0
- package/docs/observability-platform/why.md +75 -0
- package/docs/prompt-engineering-docs/analytics.md +31 -0
- package/docs/prompt-engineering-docs/creating-prompts.md +134 -0
- package/docs/prompt-engineering-docs/import-export.md +156 -0
- package/docs/prompt-engineering-docs/overview.md +107 -0
- package/docs/prompt-engineering-docs/usage.md +533 -0
- package/docs/rag/chroma.md +552 -0
- package/docs/rag/chunkers/code-chunker.md +135 -0
- package/docs/rag/chunkers/html-chunker.md +45 -0
- package/docs/rag/chunkers/json-chunker.md +59 -0
- package/docs/rag/chunkers/late-chunker.md +47 -0
- package/docs/rag/chunkers/latex-chunker.md +42 -0
- package/docs/rag/chunkers/markdown-chunker.md +61 -0
- package/docs/rag/chunkers/neural-chunker.md +45 -0
- package/docs/rag/chunkers/overview.md +52 -0
- package/docs/rag/chunkers/recursive-chunker.md +55 -0
- package/docs/rag/chunkers/semantic-chunker.md +52 -0
- package/docs/rag/chunkers/semantic-markdown-chunker.md +58 -0
- package/docs/rag/chunkers/sentence-chunker.md +50 -0
- package/docs/rag/chunkers/slumber-chunker.md +48 -0
- package/docs/rag/chunkers/structured-document.md +68 -0
- package/docs/rag/chunkers/table-chunker.md +45 -0
- package/docs/rag/chunkers/token-chunker.md +62 -0
- package/docs/rag/custom-retrievers.md +353 -0
- package/docs/rag/lancedb.md +271 -0
- package/docs/rag/overview.md +241 -0
- package/docs/rag/pinecone.md +572 -0
- package/docs/rag/qdrant.md +381 -0
- package/docs/rag/voltagent.md +348 -0
- package/docs/recipes/ad-creator.md +1091 -0
- package/docs/recipes/airtable-agent.md +418 -0
- package/docs/recipes/anthropic.md +66 -0
- package/docs/recipes/authentication.md +103 -0
- package/docs/recipes/calling-agents.md +354 -0
- package/docs/recipes/custom-endpoints.md +135 -0
- package/docs/recipes/fallback.md +77 -0
- package/docs/recipes/google-ai.md +66 -0
- package/docs/recipes/groq.md +80 -0
- package/docs/recipes/guardrails.md +178 -0
- package/docs/recipes/hooks.md +90 -0
- package/docs/recipes/langfuse.md +90 -0
- package/docs/recipes/mcp-chatgpt.md +172 -0
- package/docs/recipes/mcp.md +108 -0
- package/docs/recipes/memory.md +108 -0
- package/docs/recipes/ollama.md +85 -0
- package/docs/recipes/overview.md +55 -0
- package/docs/recipes/recipe-creator.md +151 -0
- package/docs/recipes/research-assistant.md +408 -0
- package/docs/recipes/retrieval.md +105 -0
- package/docs/recipes/retrying.md +73 -0
- package/docs/recipes/slack-agent.md +455 -0
- package/docs/recipes/subagents.md +76 -0
- package/docs/recipes/tool-hooks.md +65 -0
- package/docs/recipes/tool-routing.md +143 -0
- package/docs/recipes/tools.md +70 -0
- package/docs/recipes/voice.md +103 -0
- package/docs/recipes/whatsapp-order.md +980 -0
- package/docs/recipes/workflows.md +124 -0
- package/docs/recipes/youtube-to-blog.md +288 -0
- package/docs/repo-docs/linting.md +32 -0
- package/docs/repo-docs/structure.md +83 -0
- package/docs/repo-docs/testing.md +150 -0
- package/docs/repo-docs/tool-routing-plan.md +99 -0
- package/docs/repo-docs/tooling.md +58 -0
- package/docs/site-examples/ad-creator.md +1091 -0
- package/docs/site-examples/mcp-chatgpt.md +172 -0
- package/docs/site-examples/recipe-creator.md +151 -0
- package/docs/site-examples/research-assistant.md +408 -0
- package/docs/site-examples/whatsapp-order.md +980 -0
- package/docs/site-examples/youtube-to-blog.md +288 -0
- package/docs/tools/overview.md +268 -0
- package/docs/tools/reasoning-tool.mdx +188 -0
- package/docs/tools/tool-routing.md +311 -0
- package/docs/triggers.md +29 -0
- package/docs/troubleshooting/connection.md +86 -0
- package/docs/ui/ai-sdk-integration.md +418 -0
- package/docs/ui/assistant-ui.md +220 -0
- package/docs/ui/copilotkit.md +206 -0
- package/docs/ui/overview.md +25 -0
- package/docs/utils/create-prompt.md +142 -0
- package/docs/utils/message-helpers.md +690 -0
- package/docs/workflows/execute-api.md +469 -0
- package/docs/workflows/hooks.md +306 -0
- package/docs/workflows/overview.md +654 -0
- package/docs/workflows/schemas.md +272 -0
- package/docs/workflows/steps/and-agent.md +344 -0
- package/docs/workflows/steps/and-all.md +326 -0
- package/docs/workflows/steps/and-branch.md +67 -0
- package/docs/workflows/steps/and-foreach.md +65 -0
- package/docs/workflows/steps/and-guardrail.md +112 -0
- package/docs/workflows/steps/and-loop.md +70 -0
- package/docs/workflows/steps/and-map.md +57 -0
- package/docs/workflows/steps/and-race.md +270 -0
- package/docs/workflows/steps/and-sleep-until.md +40 -0
- package/docs/workflows/steps/and-sleep.md +40 -0
- package/docs/workflows/steps/and-tap.md +163 -0
- package/docs/workflows/steps/and-then.md +258 -0
- package/docs/workflows/steps/and-when.md +177 -0
- package/docs/workflows/streaming.md +804 -0
- package/docs/workflows/suspend-resume.md +826 -0
- package/docs/workflows/workflow-state.md +62 -0
- package/package.json +5 -2
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Airtable Actions
|
|
2
|
+
|
|
3
|
+
Airtable is one of the most common destinations for agent output—customer records, research notes,
|
|
4
|
+
summaries, etc. VoltOps ships managed Airtable actions so you can create, update, delete, list, and
|
|
5
|
+
fetch records without touching the Airtable REST API directly.
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
1. An Airtable base + table you want to write to.
|
|
10
|
+
2. A Volt project (free or paid) with API keys (`pk_…`, `sk_…`).
|
|
11
|
+
3. An Airtable credential inside Volt:
|
|
12
|
+
- Go to **Settings → Integrations → Add Credential → Airtable**.
|
|
13
|
+
- Paste your Airtable access token and save. Volt generates a `cred_xxx` identifier.
|
|
14
|
+
4. (Recommended) Base and table IDs stored as environment variables:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
AIRTABLE_CREDENTIAL_ID=cred_xxx
|
|
18
|
+
AIRTABLE_BASE_ID=appxxxxxxxxxxxxxx
|
|
19
|
+
AIRTABLE_TABLE_ID=tblxxxxxxxxxxxxxx
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Running Airtable actions from code
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { VoltOpsClient } from "@voltagent/core";
|
|
26
|
+
|
|
27
|
+
const voltops = new VoltOpsClient({
|
|
28
|
+
publicKey: process.env.VOLTAGENT_PUBLIC_KEY!,
|
|
29
|
+
secretKey: process.env.VOLTAGENT_SECRET_KEY!,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
await voltops.actions.airtable.createRecord({
|
|
33
|
+
credential: { credentialId: process.env.AIRTABLE_CREDENTIAL_ID! },
|
|
34
|
+
baseId: process.env.AIRTABLE_BASE_ID!,
|
|
35
|
+
tableId: process.env.AIRTABLE_TABLE_ID!,
|
|
36
|
+
fields: {
|
|
37
|
+
Name: "Ada Lovelace",
|
|
38
|
+
Role: "Researcher",
|
|
39
|
+
Status: "Ready",
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// No stored credential? Pass your access token inline instead
|
|
44
|
+
await voltops.actions.airtable.createRecord({
|
|
45
|
+
credential: { apiKey: process.env.AIRTABLE_API_KEY! },
|
|
46
|
+
baseId: process.env.AIRTABLE_BASE_ID!,
|
|
47
|
+
tableId: process.env.AIRTABLE_TABLE_ID!,
|
|
48
|
+
fields: {
|
|
49
|
+
Name: "Grace Hopper",
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Every call appears in Volt → **Actions** with request/response payloads, so you can monitor failures
|
|
55
|
+
or re-run a specific payload without redeploying code.
|
|
56
|
+
|
|
57
|
+
## Treat Airtable actions as tools
|
|
58
|
+
|
|
59
|
+
The [`with-voltagent-actions`](https://github.com/voltagent/voltagent/tree/main/examples/with-voltagent-actions)
|
|
60
|
+
example demonstrates how to expose each Airtable action as a VoltAgent tool. Below is a simplified
|
|
61
|
+
version of the **Create Record** tool; the example repo includes create/update/delete/get/list
|
|
62
|
+
variants plus a UI drawer inside the Volt console to test payloads.
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { createTool } from "@voltagent/core";
|
|
66
|
+
import { VoltOpsClient } from "@voltagent/core";
|
|
67
|
+
import { z } from "zod";
|
|
68
|
+
|
|
69
|
+
const voltops = new VoltOpsClient({
|
|
70
|
+
publicKey: process.env.VOLTAGENT_PUBLIC_KEY!,
|
|
71
|
+
secretKey: process.env.VOLTAGENT_SECRET_KEY!,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
export const createAirtableRecordTool = createTool({
|
|
75
|
+
name: "createAirtableRecord",
|
|
76
|
+
description: "Create a CRM row inside Airtable",
|
|
77
|
+
parameters: z.object({
|
|
78
|
+
fields: z.record(z.unknown()),
|
|
79
|
+
baseId: z.string().optional(),
|
|
80
|
+
tableId: z.string().optional(),
|
|
81
|
+
}),
|
|
82
|
+
execute: async ({ fields, baseId, tableId }) => {
|
|
83
|
+
const result = await voltops.actions.airtable.createRecord({
|
|
84
|
+
credential: { credentialId: process.env.AIRTABLE_CREDENTIAL_ID! },
|
|
85
|
+
baseId: baseId ?? process.env.AIRTABLE_BASE_ID!,
|
|
86
|
+
tableId: tableId ?? process.env.AIRTABLE_TABLE_ID!,
|
|
87
|
+
fields,
|
|
88
|
+
typecast: true,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
actionId: result.actionId,
|
|
93
|
+
metadata: result.metadata,
|
|
94
|
+
record: result.responsePayload,
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Add the tool to an agent:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
const airtableAgent = new Agent({
|
|
104
|
+
name: "Airtable Assistant",
|
|
105
|
+
model: openai("gpt-4o-mini"),
|
|
106
|
+
instructions: "Use the Airtable tools to manage the operations database.",
|
|
107
|
+
tools: [createAirtableRecordTool, listAirtableRecordsTool, updateAirtableRecordTool],
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Now the agent can plan/tool-call requests like:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
User: "Add Ada Lovelace to the workspace table and show me the latest 5 entries."
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The planner will call `createAirtableRecord` followed by `listAirtableRecords`, and VoltOps will log
|
|
118
|
+
both action runs.
|
|
119
|
+
|
|
120
|
+
## Testing payloads in the console
|
|
121
|
+
|
|
122
|
+
While building, open **Volt Console → Actions → Add Action** and select Airtable. The drawer mirrors
|
|
123
|
+
the trigger UX with a credential step, configuration step (base/table dropdowns), and a **Payload &
|
|
124
|
+
Test** editor. Enter any JSON payload and click **Run Test**; successful responses include a
|
|
125
|
+
copy-pasteable SDK snippet, while errors display the raw provider message (e.g.,
|
|
126
|
+
`INVALID_VALUE_FOR_COLUMN`).
|
|
127
|
+
|
|
128
|
+
This makes it easy to iterate on Airtable data types before committing changes to an agent.
|
|
129
|
+
|
|
130
|
+
## Troubleshooting
|
|
131
|
+
|
|
132
|
+
- **Proxy/credential mismatch** – make sure the Volt credential uses the same service (case
|
|
133
|
+
sensitive). E.g., a credential named “airtable” must be attached to an Airtable action.
|
|
134
|
+
- **Column IDs vs names** – use `returnFieldsByFieldId: true` if you prefer Airtable field IDs; the
|
|
135
|
+
default returns user-friendly names.
|
|
136
|
+
- **Pagination** – `listRecords` accepts `pageSize`, `offset`, `view`, `filterByFormula`, and `sort`
|
|
137
|
+
parameters identical to Airtable’s REST API. VoltOps just forwards them.
|
|
138
|
+
- **Observability** – check **Volt → Actions → Runs** to inspect payloads, metadata, retries, and
|
|
139
|
+
provider errors (`INVALID_PERMISSIONS_OR_MODEL_NOT_FOUND`, etc.).
|
|
140
|
+
|
|
141
|
+
With VoltOps Actions you can keep agent logic focused on reasoning while Volt handles the last-mile
|
|
142
|
+
integration to Airtable.
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Discord Actions
|
|
2
|
+
|
|
3
|
+
Use Discord actions to announce deploys, coordinate incidents, or manage guild resources without
|
|
4
|
+
touching the Discord REST API. VoltOps supports bot-token actions for full control plus a lightweight
|
|
5
|
+
webhook action for simple notifications.
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
1. Discord application with a bot token. Invite the bot to the guild(s) you plan to use and grant
|
|
10
|
+
permissions for the actions you need (Send Messages, Manage Channels, Manage Roles, Add
|
|
11
|
+
Reactions, etc.).
|
|
12
|
+
2. (Optional) Discord incoming webhook URL if you only need to post messages via webhook.
|
|
13
|
+
3. A Volt project with API keys (`pk_…`, `sk_…`).
|
|
14
|
+
4. Discord credential inside Volt: **Settings → Integrations → Add Credential → Discord**, then pick
|
|
15
|
+
**Bot Token** or **Webhook** and save. Volt generates a `cred_xxx` identifier.
|
|
16
|
+
5. (Recommended) Store defaults as environment variables:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
DISCORD_CREDENTIAL_ID=cred_bot_xxx
|
|
20
|
+
DISCORD_WEBHOOK_CREDENTIAL_ID=cred_webhook_xxx
|
|
21
|
+
DISCORD_DEFAULT_GUILD_ID=123456789012345678
|
|
22
|
+
DISCORD_DEFAULT_CHANNEL_ID=123456789012345678
|
|
23
|
+
DISCORD_DEFAULT_THREAD_ID=987654321098765432
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Available actions
|
|
27
|
+
|
|
28
|
+
- `discord.sendMessage` / `discord.sendWebhookMessage`
|
|
29
|
+
- `discord.deleteMessage`, `discord.getMessage`, `discord.listMessages`
|
|
30
|
+
- `discord.reactToMessage`, `discord.removeReaction`
|
|
31
|
+
- `discord.createChannel`, `discord.updateChannel`, `discord.deleteChannel`
|
|
32
|
+
- `discord.getChannel`, `discord.listChannels`
|
|
33
|
+
- `discord.listMembers`
|
|
34
|
+
- `discord.addMemberRole`, `discord.removeMemberRole`
|
|
35
|
+
|
|
36
|
+
Message + channel actions require a bot token; webhook messages only require a webhook credential.
|
|
37
|
+
|
|
38
|
+
## Running Discord actions from code
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { VoltOpsClient } from "@voltagent/core";
|
|
42
|
+
|
|
43
|
+
const voltops = new VoltOpsClient({
|
|
44
|
+
publicKey: process.env.VOLTAGENT_PUBLIC_KEY!,
|
|
45
|
+
secretKey: process.env.VOLTAGENT_SECRET_KEY!,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Send a rich message with the bot token
|
|
49
|
+
await voltops.actions.discord.sendMessage({
|
|
50
|
+
credential: { credentialId: process.env.DISCORD_CREDENTIAL_ID! },
|
|
51
|
+
guildId: process.env.DISCORD_DEFAULT_GUILD_ID!,
|
|
52
|
+
channelId: process.env.DISCORD_DEFAULT_CHANNEL_ID!,
|
|
53
|
+
content: "Deploy finished ✅",
|
|
54
|
+
embeds: [
|
|
55
|
+
{
|
|
56
|
+
title: "Artifact",
|
|
57
|
+
url: "https://example.com/deploy/123",
|
|
58
|
+
description: "Shipped by VoltAgent",
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Send via webhook (no bot token required)
|
|
64
|
+
await voltops.actions.discord.sendWebhookMessage({
|
|
65
|
+
credential: { credentialId: process.env.DISCORD_WEBHOOK_CREDENTIAL_ID! },
|
|
66
|
+
content: "New signup from landing page!",
|
|
67
|
+
username: "VoltAgent Bot",
|
|
68
|
+
threadId: process.env.DISCORD_DEFAULT_THREAD_ID ?? undefined,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// React to a message
|
|
72
|
+
await voltops.actions.discord.reactToMessage({
|
|
73
|
+
credential: { credentialId: process.env.DISCORD_CREDENTIAL_ID! },
|
|
74
|
+
channelId: process.env.DISCORD_DEFAULT_CHANNEL_ID!,
|
|
75
|
+
messageId: "112233445566778899",
|
|
76
|
+
emoji: "eyes",
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Assign a role
|
|
80
|
+
await voltops.actions.discord.addMemberRole({
|
|
81
|
+
credential: { credentialId: process.env.DISCORD_CREDENTIAL_ID! },
|
|
82
|
+
guildId: process.env.DISCORD_DEFAULT_GUILD_ID!,
|
|
83
|
+
userId: "999888777666555444",
|
|
84
|
+
roleId: "444555666777888999",
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Treat Discord actions as tools
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { createTool } from "@voltagent/core";
|
|
92
|
+
import { VoltOpsClient } from "@voltagent/core";
|
|
93
|
+
import { z } from "zod";
|
|
94
|
+
|
|
95
|
+
const voltops = new VoltOpsClient({
|
|
96
|
+
publicKey: process.env.VOLTAGENT_PUBLIC_KEY!,
|
|
97
|
+
secretKey: process.env.VOLTAGENT_SECRET_KEY!,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
export const sendDiscordUpdate = createTool({
|
|
101
|
+
name: "sendDiscordUpdate",
|
|
102
|
+
description: "Send a Discord message to a channel or thread.",
|
|
103
|
+
parameters: z.object({
|
|
104
|
+
content: z.string().describe("Plain-text body"),
|
|
105
|
+
channelId: z.string().optional(),
|
|
106
|
+
threadId: z.string().optional(),
|
|
107
|
+
}),
|
|
108
|
+
execute: async ({ content, channelId, threadId }) => {
|
|
109
|
+
return await voltops.actions.discord.sendMessage({
|
|
110
|
+
credential: { credentialId: process.env.DISCORD_CREDENTIAL_ID! },
|
|
111
|
+
guildId: process.env.DISCORD_DEFAULT_GUILD_ID!,
|
|
112
|
+
channelId: channelId ?? process.env.DISCORD_DEFAULT_CHANNEL_ID!,
|
|
113
|
+
threadId: threadId ?? undefined,
|
|
114
|
+
content,
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Tools make it easy for an agent to narrate progress, open a new channel for an incident, or react to
|
|
121
|
+
messages during planning.
|
|
122
|
+
|
|
123
|
+
## Testing payloads in the console
|
|
124
|
+
|
|
125
|
+
- Open **Volt Console → Actions → Add Action** and select the Discord action (bot or webhook).
|
|
126
|
+
- Attach the correct credential type. Bot-token actions will also show guild/channel defaults you can
|
|
127
|
+
pre-fill.
|
|
128
|
+
- Enter the payload (content, embeds, components, IDs) in **Payload & Test** and run it. Successful
|
|
129
|
+
responses display the raw Discord payload plus an SDK snippet.
|
|
130
|
+
- Use console runs to capture message IDs for follow-up reactions, deletes, or replies.
|
|
131
|
+
|
|
132
|
+
## Troubleshooting
|
|
133
|
+
|
|
134
|
+
- 403/`Missing Permissions` errors usually mean the bot lacks the required permission (Send Messages,
|
|
135
|
+
Manage Channels/Roles) or is not in the guild.
|
|
136
|
+
- Use a webhook credential only for `discord.sendWebhookMessage`; other actions require a bot token.
|
|
137
|
+
- Provide `content`, `embeds`, or `components`—Discord rejects empty messages.
|
|
138
|
+
- `emoji` should be an emoji name (`thumbsup`) or custom emoji syntax (`name:id`). Colons are
|
|
139
|
+
optional.
|
|
140
|
+
- Channel, thread, and guild IDs must all belong to the guild your bot can access; mismatches return
|
|
141
|
+
404 errors.
|
|
142
|
+
- Check **Volt → Actions → Runs** for payloads, metadata, and provider error messages when debugging.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Gmail Actions
|
|
2
|
+
|
|
3
|
+
Send, reply, search, and fetch Gmail messages with VoltOps-managed actions—no MIME hand-crafting or
|
|
4
|
+
token juggling required.
|
|
5
|
+
|
|
6
|
+
## Prerequisites
|
|
7
|
+
|
|
8
|
+
1. Gmail API enabled for your Google project plus either:
|
|
9
|
+
- OAuth2 credential with `accessToken` + `refreshToken` + client ID/secret, or
|
|
10
|
+
- Service account with domain-wide delegation (client email, private key, and optional delegated
|
|
11
|
+
user).
|
|
12
|
+
2. A Volt project with API keys (`pk_…`, `sk_…`).
|
|
13
|
+
3. Gmail credential inside Volt: **Settings → Integrations → Add Credential → Gmail**, choose OAuth2
|
|
14
|
+
or Service Account, paste the values, and save. Volt returns a `cred_xxx` identifier.
|
|
15
|
+
4. (Recommended) Environment variables:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
GMAIL_CREDENTIAL_ID=cred_xxx
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Available actions
|
|
22
|
+
|
|
23
|
+
- `gmail.sendEmail` – send mail with text/html bodies, CC/BCC, Reply-To, attachments, or save as a
|
|
24
|
+
draft (`draft: true`).
|
|
25
|
+
- `gmail.replyToEmail` – reply using `threadId` or `inReplyTo` plus the same fields as send.
|
|
26
|
+
- `gmail.searchEmail` – search mailbox by query, sender/recipient, label, category, or timestamp
|
|
27
|
+
filters.
|
|
28
|
+
- `gmail.getEmail` – fetch a single message by `messageId` (formats: `full`, `minimal`, `raw`,
|
|
29
|
+
`metadata`).
|
|
30
|
+
- `gmail.getThread` – fetch an entire thread by `threadId`.
|
|
31
|
+
|
|
32
|
+
## Running Gmail actions from code
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { VoltOpsClient } from "@voltagent/core";
|
|
36
|
+
|
|
37
|
+
const voltops = new VoltOpsClient({
|
|
38
|
+
publicKey: process.env.VOLTAGENT_PUBLIC_KEY!,
|
|
39
|
+
secretKey: process.env.VOLTAGENT_SECRET_KEY!,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Send an email
|
|
43
|
+
await voltops.actions.gmail.sendEmail({
|
|
44
|
+
credential: { credentialId: process.env.GMAIL_CREDENTIAL_ID! },
|
|
45
|
+
to: ["teammate@example.com"],
|
|
46
|
+
cc: ["manager@example.com"],
|
|
47
|
+
subject: "Incident update",
|
|
48
|
+
htmlBody: "<p>All systems nominal.</p>",
|
|
49
|
+
textBody: "All systems nominal.",
|
|
50
|
+
replyTo: ["noreply@example.com"],
|
|
51
|
+
attachments: [
|
|
52
|
+
{
|
|
53
|
+
filename: "notes.txt",
|
|
54
|
+
content: Buffer.from("postmortem draft").toString("base64"),
|
|
55
|
+
contentType: "text/plain",
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Reply inside an existing thread
|
|
61
|
+
await voltops.actions.gmail.replyToEmail({
|
|
62
|
+
credential: { credentialId: process.env.GMAIL_CREDENTIAL_ID! },
|
|
63
|
+
to: ["teammate@example.com"],
|
|
64
|
+
subject: "Re: Incident update",
|
|
65
|
+
textBody: "Thanks for the quick fix.",
|
|
66
|
+
threadId: "188b6c3a3d9a1a2b",
|
|
67
|
+
inReplyTo: "<message-id@example.com>",
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Search and hydrate results
|
|
71
|
+
const search = await voltops.actions.gmail.searchEmail({
|
|
72
|
+
credential: { credentialId: process.env.GMAIL_CREDENTIAL_ID! },
|
|
73
|
+
query: "from:alerts@example.com after:1719700000",
|
|
74
|
+
maxResults: 5,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Fetch a message directly
|
|
78
|
+
await voltops.actions.gmail.getEmail({
|
|
79
|
+
credential: { credentialId: process.env.GMAIL_CREDENTIAL_ID! },
|
|
80
|
+
messageId: "188b6c3a3d9a1a2b",
|
|
81
|
+
format: "full",
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Treat Gmail actions as tools
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { createTool } from "@voltagent/core";
|
|
89
|
+
import { VoltOpsClient } from "@voltagent/core";
|
|
90
|
+
import { z } from "zod";
|
|
91
|
+
|
|
92
|
+
const voltops = new VoltOpsClient({
|
|
93
|
+
publicKey: process.env.VOLTAGENT_PUBLIC_KEY!,
|
|
94
|
+
secretKey: process.env.VOLTAGENT_SECRET_KEY!,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
export const sendGmailSummary = createTool({
|
|
98
|
+
name: "sendGmailSummary",
|
|
99
|
+
description: "Email a summary to a stakeholder.",
|
|
100
|
+
parameters: z.object({
|
|
101
|
+
to: z.string().email(),
|
|
102
|
+
subject: z.string(),
|
|
103
|
+
body: z.string(),
|
|
104
|
+
}),
|
|
105
|
+
execute: async ({ to, subject, body }) => {
|
|
106
|
+
return await voltops.actions.gmail.sendEmail({
|
|
107
|
+
credential: { credentialId: process.env.GMAIL_CREDENTIAL_ID! },
|
|
108
|
+
to,
|
|
109
|
+
subject,
|
|
110
|
+
textBody: body,
|
|
111
|
+
});
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Agents can now send follow-ups, reply in an existing thread, or fetch a message body as part of a
|
|
117
|
+
reasoning chain.
|
|
118
|
+
|
|
119
|
+
## Testing payloads in the console
|
|
120
|
+
|
|
121
|
+
- Open **Volt Console → Actions → Add Action → Gmail** and attach your Gmail credential.
|
|
122
|
+
- Pick the action, enter the payload (recipients, body, attachments), and run a test. Successful runs
|
|
123
|
+
show Gmail’s response plus an SDK snippet you can copy.
|
|
124
|
+
- Set `draft: true` to create a draft without sending—useful while validating payloads.
|
|
125
|
+
|
|
126
|
+
## Troubleshooting
|
|
127
|
+
|
|
128
|
+
- `invalid_grant` or auth failures usually mean the refresh token is missing/expired or the OAuth
|
|
129
|
+
app lacks offline access; re-authorize and store the new token.
|
|
130
|
+
- Service accounts require domain-wide delegation and a subject email if you are sending on behalf of
|
|
131
|
+
a user.
|
|
132
|
+
- Provide at least one of `htmlBody` or `textBody`; replies also need `threadId` or `inReplyTo`.
|
|
133
|
+
- Attachments must be base64-encoded content (no data URLs); include `contentType` when possible.
|
|
134
|
+
- Inspect **Volt → Actions → Runs** for request/response bodies, retries, and Gmail error messages.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Google Calendar Actions
|
|
2
|
+
|
|
3
|
+
Create, update, search, and delete Calendar events via VoltOps-managed actions—no webhook plumbing or
|
|
4
|
+
manual OAuth handling.
|
|
5
|
+
|
|
6
|
+
## Prerequisites
|
|
7
|
+
|
|
8
|
+
1. Google Calendar API enabled plus OAuth2 credentials (Volt managed app or your own). Provide
|
|
9
|
+
`accessToken` + `refreshToken` + client ID/secret, or pass a valid short-lived `accessToken`.
|
|
10
|
+
2. A Volt project with API keys (`pk_…`, `sk_…`).
|
|
11
|
+
3. Google Calendar credential in Volt: **Settings → Integrations → Add Credential → Google
|
|
12
|
+
Calendar**, paste your OAuth values, and copy the returned `cred_xxx`.
|
|
13
|
+
4. (Recommended) Environment variables:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
GOOGLE_CALENDAR_CREDENTIAL_ID=cred_xxx
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Available actions
|
|
20
|
+
|
|
21
|
+
- `calendar.createEvent` – create an event with attendees, reminders, locations, and time zones.
|
|
22
|
+
- `calendar.updateEvent` – patch an event’s summary, times, attendees, description, status, or
|
|
23
|
+
location.
|
|
24
|
+
- `calendar.deleteEvent` – remove an event by `eventId`.
|
|
25
|
+
- `calendar.listEvents` – list events for a calendar with time windows, pagination, ordering, and
|
|
26
|
+
query.
|
|
27
|
+
- `calendar.getEvent` – fetch a specific event by `eventId`.
|
|
28
|
+
|
|
29
|
+
## Running Google Calendar actions from code
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { VoltOpsClient } from "@voltagent/core";
|
|
33
|
+
|
|
34
|
+
const voltops = new VoltOpsClient({
|
|
35
|
+
publicKey: process.env.VOLTAGENT_PUBLIC_KEY!,
|
|
36
|
+
secretKey: process.env.VOLTAGENT_SECRET_KEY!,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Create an event on the primary calendar
|
|
40
|
+
await voltops.actions.googlecalendar.createEvent({
|
|
41
|
+
credential: { credentialId: process.env.GOOGLE_CALENDAR_CREDENTIAL_ID! },
|
|
42
|
+
calendarId: "primary",
|
|
43
|
+
summary: "Team sync",
|
|
44
|
+
description: "Weekly sync-up with the team",
|
|
45
|
+
location: "Video",
|
|
46
|
+
start: {
|
|
47
|
+
dateTime: new Date(Date.now() + 60 * 60 * 1000).toISOString(),
|
|
48
|
+
timeZone: "UTC",
|
|
49
|
+
},
|
|
50
|
+
end: {
|
|
51
|
+
dateTime: new Date(Date.now() + 2 * 60 * 60 * 1000).toISOString(),
|
|
52
|
+
timeZone: "UTC",
|
|
53
|
+
},
|
|
54
|
+
attendees: [{ email: "teammate@example.com" }],
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Update an existing event
|
|
58
|
+
await voltops.actions.googlecalendar.updateEvent({
|
|
59
|
+
credential: { credentialId: process.env.GOOGLE_CALENDAR_CREDENTIAL_ID! },
|
|
60
|
+
calendarId: "primary",
|
|
61
|
+
eventId: "event_123",
|
|
62
|
+
summary: "Updated team sync",
|
|
63
|
+
description: "Add roadmap review",
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// List upcoming events
|
|
67
|
+
const events = await voltops.actions.googlecalendar.listEvents({
|
|
68
|
+
credential: { credentialId: process.env.GOOGLE_CALENDAR_CREDENTIAL_ID! },
|
|
69
|
+
calendarId: "primary",
|
|
70
|
+
timeMin: new Date().toISOString(),
|
|
71
|
+
timeMax: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),
|
|
72
|
+
singleEvents: true,
|
|
73
|
+
orderBy: "startTime",
|
|
74
|
+
maxResults: 10,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Fetch a specific event
|
|
78
|
+
await voltops.actions.googlecalendar.getEvent({
|
|
79
|
+
credential: { credentialId: process.env.GOOGLE_CALENDAR_CREDENTIAL_ID! },
|
|
80
|
+
calendarId: "primary",
|
|
81
|
+
eventId: "event_123",
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Treat Calendar actions as tools
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { Agent, createTool, VoltOpsClient } from "@voltagent/core";
|
|
89
|
+
import { openai } from "@ai-sdk/openai";
|
|
90
|
+
import { z } from "zod";
|
|
91
|
+
|
|
92
|
+
const voltops = new VoltOpsClient({
|
|
93
|
+
publicKey: process.env.VOLTAGENT_PUBLIC_KEY!,
|
|
94
|
+
secretKey: process.env.VOLTAGENT_SECRET_KEY!,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
export const scheduleMeetingTool = createTool({
|
|
98
|
+
name: "scheduleMeeting",
|
|
99
|
+
description: "Create a meeting on the primary Google Calendar.",
|
|
100
|
+
parameters: z.object({
|
|
101
|
+
summary: z.string(),
|
|
102
|
+
description: z.string().optional(),
|
|
103
|
+
start: z.string().describe("ISO date string"),
|
|
104
|
+
end: z.string().describe("ISO date string"),
|
|
105
|
+
attendees: z.array(z.string().email()).optional(),
|
|
106
|
+
timeZone: z.string().optional(),
|
|
107
|
+
}),
|
|
108
|
+
execute: async ({ summary, description, start, end, attendees, timeZone }) => {
|
|
109
|
+
return await voltops.actions.googlecalendar.createEvent({
|
|
110
|
+
credential: { credentialId: process.env.GOOGLE_CALENDAR_CREDENTIAL_ID! },
|
|
111
|
+
calendarId: "primary",
|
|
112
|
+
summary,
|
|
113
|
+
description,
|
|
114
|
+
start: { dateTime: start, timeZone: timeZone ?? "UTC" },
|
|
115
|
+
end: { dateTime: end, timeZone: timeZone ?? "UTC" },
|
|
116
|
+
attendees: attendees?.map((email) => ({ email })),
|
|
117
|
+
});
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const calendarAgent = new Agent({
|
|
122
|
+
name: "Calendar Assistant",
|
|
123
|
+
model: openai("gpt-4o-mini"),
|
|
124
|
+
instructions: "Use Google Calendar tools to schedule and manage events.",
|
|
125
|
+
tools: [scheduleMeetingTool],
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Agents can now schedule meetings, modify them, or read back details inside reasoning chains.
|
|
130
|
+
|
|
131
|
+
## Testing payloads in the console
|
|
132
|
+
|
|
133
|
+
- Open **Volt Console → Actions → Add Action → Google Calendar** and attach your credential.
|
|
134
|
+
- Choose an action, enter the payload (`calendarId`, `summary`, `start`, `end`, etc.), and run a test.
|
|
135
|
+
- Inspect the request/response plus the SDK snippet shown in **How to use**.
|
|
136
|
+
|
|
137
|
+
## Troubleshooting
|
|
138
|
+
|
|
139
|
+
- Auth failures usually mean a missing/expired refresh token or mismatched OAuth client redirect URI;
|
|
140
|
+
re-authorize with offline access.
|
|
141
|
+
- Include `timeZone` on `start`/`end` to avoid defaulting to the calendar’s zone.
|
|
142
|
+
- Use `calendarId: "primary"` when unsure which calendar the credential owns.
|
|
143
|
+
- `listEvents` accepts `timeMin`, `timeMax`, `q`, `singleEvents`, `orderBy`, and pagination via
|
|
144
|
+
`pageToken`.
|
|
145
|
+
- Check **Volt → Actions → Runs** for the Google API response if an action fails.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Google Drive Actions
|
|
2
|
+
|
|
3
|
+
VoltOps ships managed Google Drive actions so agents can list, download, upload, move, copy, delete,
|
|
4
|
+
and share files without manually signing requests or refreshing OAuth tokens.
|
|
5
|
+
|
|
6
|
+
## Prerequisites
|
|
7
|
+
|
|
8
|
+
1. Google Drive API enabled plus OAuth2 credentials (Volt managed app or your own). Provide
|
|
9
|
+
`accessToken` + `refreshToken` + client ID/secret, or pass a valid short-lived `accessToken`.
|
|
10
|
+
2. A Volt project with API keys (`pk_…`, `sk_…`).
|
|
11
|
+
3. Google Drive credential inside Volt: **Settings → Integrations → Add Credential → Google Drive**,
|
|
12
|
+
paste your OAuth values, and copy the returned `cred_xxx`.
|
|
13
|
+
4. (Recommended) Environment variables:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
GOOGLE_DRIVE_CREDENTIAL_ID=cred_xxx
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Available actions
|
|
20
|
+
|
|
21
|
+
- `drive.listFiles` – list files/folders with search (`q`), ordering, pagination, and `includeTrashed`.
|
|
22
|
+
- `drive.getFileMetadata` – fetch metadata for a specific file.
|
|
23
|
+
- `drive.downloadFile` – download file content (base64 + content type).
|
|
24
|
+
- `drive.uploadFile` – upload binary or base64 content; supports parent folders.
|
|
25
|
+
- `drive.createFolder` – create a folder.
|
|
26
|
+
- `drive.moveFile` – move to a new parent (optionally remove previous parents).
|
|
27
|
+
- `drive.copyFile` – duplicate a file into another folder and/or name.
|
|
28
|
+
- `drive.deleteFile` – delete or move to trash depending on Drive settings.
|
|
29
|
+
- `drive.shareFilePublic` – create a public link (anyone with link can view).
|
|
30
|
+
|
|
31
|
+
## Running Google Drive actions from code
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { VoltOpsClient } from "@voltagent/core";
|
|
35
|
+
|
|
36
|
+
const voltops = new VoltOpsClient({
|
|
37
|
+
publicKey: process.env.VOLTAGENT_PUBLIC_KEY!,
|
|
38
|
+
secretKey: process.env.VOLTAGENT_SECRET_KEY!,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// List recent non-folder files
|
|
42
|
+
const list = await voltops.actions.googledrive.listFiles({
|
|
43
|
+
credential: { credentialId: process.env.GOOGLE_DRIVE_CREDENTIAL_ID! },
|
|
44
|
+
q: "mimeType != 'application/vnd.google-apps.folder' and trashed=false",
|
|
45
|
+
orderBy: "modifiedTime desc",
|
|
46
|
+
pageSize: 25,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Download a file (base64)
|
|
50
|
+
const download = await voltops.actions.googledrive.downloadFile({
|
|
51
|
+
credential: { credentialId: process.env.GOOGLE_DRIVE_CREDENTIAL_ID! },
|
|
52
|
+
fileId: "file_123",
|
|
53
|
+
});
|
|
54
|
+
const fileBuffer = Buffer.from(download.responsePayload.contentBase64, "base64");
|
|
55
|
+
|
|
56
|
+
// Upload a text file (base64)
|
|
57
|
+
await voltops.actions.googledrive.uploadFile({
|
|
58
|
+
credential: { credentialId: process.env.GOOGLE_DRIVE_CREDENTIAL_ID! },
|
|
59
|
+
name: "hello.txt",
|
|
60
|
+
mimeType: "text/plain",
|
|
61
|
+
parents: ["root"],
|
|
62
|
+
content: Buffer.from("Hello VoltAgent!").toString("base64"),
|
|
63
|
+
isBase64: true,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Share a file publicly
|
|
67
|
+
await voltops.actions.googledrive.shareFilePublic({
|
|
68
|
+
credential: { credentialId: process.env.GOOGLE_DRIVE_CREDENTIAL_ID! },
|
|
69
|
+
fileId: "file_123",
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Each method accepts either a stored `credentialId` or inline OAuth tokens
|
|
74
|
+
(`accessToken` or `refreshToken` + `clientId` + `clientSecret`).
|
|
75
|
+
|
|
76
|
+
## Treat Drive actions as tools
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { Agent, createTool, VoltOpsClient } from "@voltagent/core";
|
|
80
|
+
import { openai } from "@ai-sdk/openai";
|
|
81
|
+
import { z } from "zod";
|
|
82
|
+
|
|
83
|
+
const voltops = new VoltOpsClient({
|
|
84
|
+
publicKey: process.env.VOLTAGENT_PUBLIC_KEY!,
|
|
85
|
+
secretKey: process.env.VOLTAGENT_SECRET_KEY!,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
export const shareDriveFile = createTool({
|
|
89
|
+
name: "shareDriveFile",
|
|
90
|
+
description: "Share a Drive file publicly and return the webViewLink.",
|
|
91
|
+
parameters: z.object({
|
|
92
|
+
fileId: z.string(),
|
|
93
|
+
}),
|
|
94
|
+
execute: async ({ fileId }) => {
|
|
95
|
+
const result = await voltops.actions.googledrive.shareFilePublic({
|
|
96
|
+
credential: { credentialId: process.env.GOOGLE_DRIVE_CREDENTIAL_ID! },
|
|
97
|
+
fileId,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
return result.responsePayload;
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const driveAgent = new Agent({
|
|
105
|
+
name: "Drive Assistant",
|
|
106
|
+
model: openai("gpt-4o-mini"),
|
|
107
|
+
instructions: "Use Google Drive to fetch or share files for the user.",
|
|
108
|
+
tools: [shareDriveFile],
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Testing payloads in the console
|
|
113
|
+
|
|
114
|
+
- Open **Volt Console → Actions → Add Action → Google Drive** and attach your credential.
|
|
115
|
+
- Pick an action, enter the payload (`q`, `fileId`, `content`, etc.), and click **Run Test**.
|
|
116
|
+
- Review the response plus the SDK snippet shown in **How to use**.
|
|
117
|
+
|
|
118
|
+
## Troubleshooting
|
|
119
|
+
|
|
120
|
+
- Auth errors usually mean a missing/expired refresh token or incorrect OAuth client setup;
|
|
121
|
+
re-authorize with offline access.
|
|
122
|
+
- Service accounts must be added to the Drive or shared folders you target.
|
|
123
|
+
- Set `isBase64: true` when sending base64 content; omit it when streaming binary buffers.
|
|
124
|
+
- `listFiles` supports pagination with `pageToken`, filtering with `q`, and excluding trash via
|
|
125
|
+
`includeTrashed: false`.
|
|
126
|
+
- Public sharing grants anyone-with-link viewer access; use Drive’s native sharing for finer control.
|
|
127
|
+
- Inspect **Volt → Actions → Runs** for the Google API request/response if an action fails.
|