Skip to content

feat: prepare VoltAgent 3 next prerelease - #1378

Open
omeraplak wants to merge 14 commits into
mainfrom
next
Open

feat: prepare VoltAgent 3 next prerelease#1378
omeraplak wants to merge 14 commits into
mainfrom
next

Conversation

@omeraplak

@omeraplak omeraplak commented Jul 9, 2026

Copy link
Copy Markdown
Member

PR Checklist

Please check if your PR fulfills the following requirements:

Bugs / Features

What is the current behavior?

What is the new behavior?

fixes (issue)

Notes for reviewers


Summary by cubic

Prepares the VoltAgent 3 prerelease on the next channel with Node 22, zod@^4, and AI SDK v7-first tooling. Updates @voltagent/core with tool()/ToolSet, raw AI SDK tool pass-through, and re-exports; refreshes examples/CI and adds @voltagent/libsql working memory.

  • Dependencies

    • Enables Changesets prerelease mode with tag next and CI verification; CI runs on Node.js 22.
    • Bumps @voltagent/* to 3.0.0-next.x, ai@^7, @ai-sdk/openai@^4, @ai-sdk/react@^4, @openrouter/ai-sdk-provider@^3, ollama-ai-provider-v2@^4, and zod@^4.
    • Publishes AI SDK v7 tool compatibility in @voltagent/core: native contextSchema/toolsContext, pass-through of runtimeContext/telemetry/lifecycle callbacks, withVoltAgentMetadata, enhanceTool(), and re-exported AI SDK primitives/types.
    • Adds docs: docs/ai-sdk-first-vnext-plan.md with tool approval guidance (RFC: Make VoltAgent vNext an ai-sdk-first outer framework #1373); standardizes package.json type/types order.
  • Migration

    • Require Node.js 22 and zod@^4; install via @next/3.0.0-next.x.
    • Tools: createTool -> tool, parameters -> inputSchema; configure tools as an object map (ToolSet).
    • Usage fields: use usage.outputTokenDetails.reasoningTokens and usage.inputTokenDetails.cacheReadTokens.
    • Streaming: toUIMessageStreamResponse({ onEnd }) replaces onFinish.
    • Attachments: { type: "file", data, mediaType } replaces { type: "image", image }.
    • generateObject: pass instructions instead of system.

Written for commit aef2a09. Summary will update on new commits.

Review in cubic

@changeset-bot

changeset-bot Bot commented Jul 9, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: aef2a09

The changes in this PR will be included in the next version bump.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 418 files, which is 118 over the limit of 300.

To get a review, reduce the PR to 300 files or fewer by splitting it into smaller PRs or changing its base branch.

Usage-priced reviews support at most 300 files.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c081c6b3-4765-42a7-afb8-45a72e1997ac

📥 Commits

Reviewing files that changed from the base of the PR and between c21aa3e and aef2a09.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (418)
  • .changeset/ai-sdk-tools-next.md
  • .changeset/pre.json
  • .changeset/voltagent-3-next.md
  • .github/workflows/prerelease.yml
  • docs/ai-sdk-first-vnext-plan.md
  • docs/testing.md
  • examples/base/package.json
  • examples/github-repo-analyzer/package.json
  • examples/github-repo-analyzer/src/index.ts
  • examples/github-repo-analyzer/src/tools.ts
  • examples/github-star-stories/package.json
  • examples/github-star-stories/src/index.ts
  • examples/github-star-stories/src/tools.ts
  • examples/next-js-chatbot-starter-template/components/ai-elements/context.tsx
  • examples/next-js-chatbot-starter-template/lib/tools/calculator.ts
  • examples/next-js-chatbot-starter-template/lib/tools/datetime.ts
  • examples/next-js-chatbot-starter-template/lib/tools/index.ts
  • examples/next-js-chatbot-starter-template/lib/tools/random.ts
  • examples/next-js-chatbot-starter-template/package.json
  • examples/with-a2a-server/README.md
  • examples/with-a2a-server/package.json
  • examples/with-a2a-server/src/agents/assistant.ts
  • examples/with-ad-creator/CHANGELOG.md
  • examples/with-ad-creator/README.md
  • examples/with-ad-creator/package.json
  • examples/with-ad-creator/src/agents/ad-creator.agent.ts
  • examples/with-ad-creator/src/agents/landing-page-analyzer.agent.ts
  • examples/with-ad-creator/src/tools/image-generation/instagram-ad-gemini.tool.ts
  • examples/with-agent-tool/package.json
  • examples/with-airtable/package.json
  • examples/with-airtable/src/index.ts
  • examples/with-amazon-bedrock/README.md
  • examples/with-amazon-bedrock/package.json
  • examples/with-amazon-bedrock/src/index.ts
  • examples/with-anthropic/README.md
  • examples/with-anthropic/package.json
  • examples/with-anthropic/src/index.ts
  • examples/with-assistant-ui/CHANGELOG.md
  • examples/with-assistant-ui/package.json
  • examples/with-assistant-ui/voltagent/agents.ts
  • examples/with-auth/package.json
  • examples/with-auth/src/index.ts
  • examples/with-auth/src/tools/weather.ts
  • examples/with-cerbos/README.md
  • examples/with-cerbos/package.json
  • examples/with-chat-sdk/README.md
  • examples/with-chat-sdk/lib/agent.ts
  • examples/with-chat-sdk/package.json
  • examples/with-chroma/package.json
  • examples/with-client-side-tools/README.md
  • examples/with-client-side-tools/package.json
  • examples/with-client-side-tools/voltagent/agents.ts
  • examples/with-cloudflare-workers/README.md
  • examples/with-cloudflare-workers/package.json
  • examples/with-cloudflare-workers/src/index.ts
  • examples/with-cloudflare-workers/src/tools/index.ts
  • examples/with-composio-mcp/README.md
  • examples/with-composio-mcp/package.json
  • examples/with-copilotkit/server/CHANGELOG.md
  • examples/with-copilotkit/server/package.json
  • examples/with-copilotkit/server/src/index.ts
  • examples/with-custom-endpoints/package.json
  • examples/with-dynamic-parameters/package.json
  • examples/with-dynamic-parameters/src/index.ts
  • examples/with-dynamic-prompts/package.json
  • examples/with-feedback/package.json
  • examples/with-google-ai/package.json
  • examples/with-google-drive-mcp/server/package.json
  • examples/with-google-drive-mcp/server/src/index.ts
  • examples/with-google-vertex-ai/package.json
  • examples/with-groq-ai/package.json
  • examples/with-guardrails/package.json
  • examples/with-hooks/package.json
  • examples/with-hooks/src/index.ts
  • examples/with-hugging-face-mcp/README.md
  • examples/with-hugging-face-mcp/package.json
  • examples/with-jwt-auth/CHANGELOG.md
  • examples/with-jwt-auth/package.json
  • examples/with-lancedb/README.md
  • examples/with-lancedb/package.json
  • examples/with-langfuse/package.json
  • examples/with-langfuse/src/index.ts
  • examples/with-langfuse/src/tools/calendar.ts
  • examples/with-langfuse/src/tools/search.ts
  • examples/with-langfuse/src/tools/weather.ts
  • examples/with-live-evals/CHANGELOG.md
  • examples/with-live-evals/package.json
  • examples/with-live-evals/src/index.ts
  • examples/with-mcp-elicitation/README.md
  • examples/with-mcp-elicitation/package.json
  • examples/with-mcp-elicitation/src/mcp-server.ts
  • examples/with-mcp-server/README.md
  • examples/with-mcp-server/package.json
  • examples/with-mcp-server/src/index.ts
  • examples/with-mcp/package.json
  • examples/with-memory-rest-api/package.json
  • examples/with-middleware/package.json
  • examples/with-nestjs/README.md
  • examples/with-nestjs/package.json
  • examples/with-nestjs/src/voltagent/voltagent.service.ts
  • examples/with-netlify-functions/README.md
  • examples/with-netlify-functions/package.json
  • examples/with-netlify-functions/src/index.ts
  • examples/with-netlify-functions/src/tools/index.ts
  • examples/with-nextjs-resumable-stream/app/api/chat/route.ts
  • examples/with-nextjs-resumable-stream/components/ai-elements/context.tsx
  • examples/with-nextjs-resumable-stream/package.json
  • examples/with-nextjs-resumable-stream/voltagent/agents.ts
  • examples/with-nextjs-resumable-stream/voltagent/tools.ts
  • examples/with-nextjs/package.json
  • examples/with-nextjs/voltagent/agents.ts
  • examples/with-nuxt/package.json
  • examples/with-nuxt/voltagent/index.ts
  • examples/with-offline-evals/package.json
  • examples/with-ollama/package.json
  • examples/with-ollama/src/index.ts
  • examples/with-openrouter/README.md
  • examples/with-openrouter/package.json
  • examples/with-peaka-mcp/package.json
  • examples/with-pinecone/package.json
  • examples/with-planagents/README.md
  • examples/with-planagents/package.json
  • examples/with-planagents/src/index.ts
  • examples/with-planagents/src/tools.ts
  • examples/with-playwright/package.json
  • examples/with-playwright/src/tools/navigationTool.ts
  • examples/with-playwright/tsconfig.json
  • examples/with-postgres/package.json
  • examples/with-qdrant/package.json
  • examples/with-rag-chatbot/package.json
  • examples/with-recipe-generator/README.md
  • examples/with-recipe-generator/package.json
  • examples/with-research-assistant/README.md
  • examples/with-research-assistant/package.json
  • examples/with-resumable-streams/package.json
  • examples/with-retries-fallback/package.json
  • examples/with-retrieval/package.json
  • examples/with-slack/package.json
  • examples/with-slack/src/index.ts
  • examples/with-slack/src/tools/weather.ts
  • examples/with-subagents/package.json
  • examples/with-subagents/src/index.ts
  • examples/with-summarization/README.md
  • examples/with-summarization/package.json
  • examples/with-summarization/src/index.ts
  • examples/with-supabase/package.json
  • examples/with-tavily-search/package.json
  • examples/with-tavily-search/src/index.ts
  • examples/with-tavily-search/src/tools.ts
  • examples/with-thinking-tool/package.json
  • examples/with-tool-routing/package.json
  • examples/with-tool-routing/src/index.ts
  • examples/with-tools/package.json
  • examples/with-tools/src/index.ts
  • examples/with-tools/src/tools/calendar.ts
  • examples/with-tools/src/tools/search.ts
  • examples/with-tools/src/tools/weather.ts
  • examples/with-turso/package.json
  • examples/with-vector-search/package.json
  • examples/with-vercel-ai/package.json
  • examples/with-viteval/package.json
  • examples/with-viteval/src/agents/general.dataset.ts
  • examples/with-viteval/src/agents/geography.dataset.ts
  • examples/with-viteval/src/agents/history.dataset.ts
  • examples/with-viteval/src/agents/math.dataset.ts
  • examples/with-viteval/src/agents/math.ts
  • examples/with-viteval/src/agents/science.dataset.ts
  • examples/with-viteval/src/agents/supervisor.dataset.ts
  • examples/with-voice-elevenlabs/package.json
  • examples/with-voice-openai/package.json
  • examples/with-voice-xsai/package.json
  • examples/with-voltagent-actions/package.json
  • examples/with-voltagent-actions/src/config.ts
  • examples/with-voltagent-actions/src/index.ts
  • examples/with-voltagent-actions/src/tools/airtable.ts
  • examples/with-voltagent-exporter/package.json
  • examples/with-voltagent-exporter/src/index.ts
  • examples/with-voltagent-exporter/src/tools/calendar.ts
  • examples/with-voltagent-exporter/src/tools/search.ts
  • examples/with-voltagent-exporter/src/tools/weather.ts
  • examples/with-voltagent-managed-memory/README.md
  • examples/with-voltagent-managed-memory/package.json
  • examples/with-voltops-resumable-streams/package.json
  • examples/with-voltops-retrieval/package.json
  • examples/with-whatsapp/README.md
  • examples/with-whatsapp/package.json
  • examples/with-whatsapp/src/index.ts
  • examples/with-whatsapp/src/tools/check-order-status.ts
  • examples/with-whatsapp/src/tools/create-order.ts
  • examples/with-whatsapp/src/tools/list-menu-items.ts
  • examples/with-whatsapp/src/webhooks/whatsapp.ts
  • examples/with-workflow-chain/package.json
  • examples/with-workflow/package.json
  • examples/with-working-memory/package.json
  • examples/with-workspace/package.json
  • examples/with-xquik-tools/package.json
  • examples/with-xquik-tools/src/tools.ts
  • examples/with-youtube-to-blog/package.json
  • examples/with-zapier-mcp/README.md
  • examples/with-zapier-mcp/package.json
  • package.json
  • packages/a2a-server/CHANGELOG.md
  • packages/a2a-server/package.json
  • packages/a2a-server/src/server.spec.ts
  • packages/a2a-server/tsup.config.ts
  • packages/ag-ui/CHANGELOG.md
  • packages/ag-ui/package.json
  • packages/ag-ui/src/voltagent-agent.spec.ts
  • packages/ag-ui/src/voltagent-agent.ts
  • packages/ag-ui/tsup.config.ts
  • packages/cli/CHANGELOG.md
  • packages/cli/package.json
  • packages/cli/tsup.config.ts
  • packages/cloudflare-d1/CHANGELOG.md
  • packages/cloudflare-d1/package.json
  • packages/cloudflare-d1/tsup.config.ts
  • packages/cloudflare-d1/vitest.config.mts
  • packages/core/CHANGELOG.md
  • packages/core/package.json
  • packages/core/src/agent/agent-observability.spec.ts
  • packages/core/src/agent/agent-semantic-search.spec.ts
  • packages/core/src/agent/agent.spec-d.ts
  • packages/core/src/agent/agent.spec.ts
  • packages/core/src/agent/agent.ts
  • packages/core/src/agent/concurrent-tool-spans.spec.ts
  • packages/core/src/agent/context-keys.ts
  • packages/core/src/agent/eval.ts
  • packages/core/src/agent/guardrail.integration.spec.ts
  • packages/core/src/agent/hooks/index.spec.ts
  • packages/core/src/agent/hooks/index.ts
  • packages/core/src/agent/open-telemetry/trace-context.ts
  • packages/core/src/agent/providers/base/types.ts
  • packages/core/src/agent/streaming/guardrail-stream.spec.ts
  • packages/core/src/agent/streaming/guardrail-stream.ts
  • packages/core/src/agent/subagent/index.spec.ts
  • packages/core/src/agent/subagent/index.ts
  • packages/core/src/agent/subagent/test-utils.ts
  • packages/core/src/agent/subagent/types.ts
  • packages/core/src/agent/test-utils.ts
  • packages/core/src/agent/types.ts
  • packages/core/src/index.spec.ts
  • packages/core/src/index.ts
  • packages/core/src/mcp/client/index.spec.ts
  • packages/core/src/mcp/client/index.ts
  • packages/core/src/memory/index.ts
  • packages/core/src/observability/types.ts
  • packages/core/src/planagent/plan-agent.ts
  • packages/core/src/tool/ai-sdk-tool.ts
  • packages/core/src/tool/index.spec.ts
  • packages/core/src/tool/index.ts
  • packages/core/src/tool/manager/BaseToolManager.ts
  • packages/core/src/tool/manager/ToolManager.ts
  • packages/core/src/tool/manager/ToolkitManager.ts
  • packages/core/src/tool/manager/index.spec.ts
  • packages/core/src/tool/routing/types.ts
  • packages/core/src/utils/message-converter.spec.ts
  • packages/core/src/utils/message-helpers.spec.ts
  • packages/core/src/utils/message-helpers.ts
  • packages/core/src/utils/toolParser/index.spec.ts
  • packages/core/src/utils/toolParser/index.ts
  • packages/core/src/utils/usage-converter.ts
  • packages/core/src/workflow/chain.spec-d.ts
  • packages/core/src/workflow/core.ts
  • packages/core/src/workflow/types.ts
  • packages/core/src/workflow/usage-tracking.spec.ts
  • packages/core/src/workspace/tool-policy.ts
  • packages/core/tsup.config.ts
  • packages/create-voltagent-app/CHANGELOG.md
  • packages/create-voltagent-app/package.json
  • packages/create-voltagent-app/src/cli.integration.spec.ts
  • packages/create-voltagent-app/src/types.ts
  • packages/create-voltagent-app/src/utils/dependency-installer.ts
  • packages/create-voltagent-app/tsup.config.ts
  • packages/docs-mcp/CHANGELOG.md
  • packages/docs-mcp/package.json
  • packages/docs-mcp/tsup.config.ts
  • packages/e2e/package.json
  • packages/e2e/src/agent-runtime.e2e.spec.ts
  • packages/e2e/src/message-persistence.libsql.e2e.spec.ts
  • packages/evals/CHANGELOG.md
  • packages/evals/package.json
  • packages/evals/tsconfig.json
  • packages/evals/tsup.config.ts
  • packages/internal/CHANGELOG.md
  • packages/internal/package.json
  • packages/internal/tsup.config.ts
  • packages/langfuse-exporter/CHANGELOG.md
  • packages/langfuse-exporter/package.json
  • packages/langfuse-exporter/tsup.config.ts
  • packages/libsql/CHANGELOG.md
  • packages/libsql/package.json
  • packages/libsql/tsconfig.json
  • packages/libsql/tsup.config.ts
  • packages/logger/CHANGELOG.md
  • packages/logger/package.json
  • packages/logger/tsup.config.ts
  • packages/mcp-server/CHANGELOG.md
  • packages/mcp-server/package.json
  • packages/mcp-server/src/adapters/agent.spec.ts
  • packages/mcp-server/tsup.config.ts
  • packages/postgres/CHANGELOG.md
  • packages/postgres/package.json
  • packages/postgres/tsup.config.ts
  • packages/rag/CHANGELOG.md
  • packages/rag/package.json
  • packages/rag/tsconfig.json
  • packages/rag/tsup.config.ts
  • packages/resumable-streams/CHANGELOG.md
  • packages/resumable-streams/package.json
  • packages/resumable-streams/src/chat-handlers.ts
  • packages/resumable-streams/src/chat-session.ts
  • packages/resumable-streams/tsup.config.ts
  • packages/resumable-streams/vitest.config.ts
  • packages/sandbox-blaxel/CHANGELOG.md
  • packages/sandbox-blaxel/package.json
  • packages/sandbox-blaxel/tsup.config.ts
  • packages/sandbox-daytona/CHANGELOG.md
  • packages/sandbox-daytona/package.json
  • packages/sandbox-daytona/tsup.config.ts
  • packages/sandbox-e2b/CHANGELOG.md
  • packages/sandbox-e2b/package.json
  • packages/sandbox-e2b/tsup.config.ts
  • packages/scorers/CHANGELOG.md
  • packages/scorers/package.json
  • packages/scorers/src/llm/answer-correctness.ts
  • packages/scorers/src/llm/answer-relevancy.ts
  • packages/scorers/src/llm/classifiers.ts
  • packages/scorers/src/llm/context-precision.ts
  • packages/scorers/src/llm/context-recall.ts
  • packages/scorers/src/llm/context-relevancy.ts
  • packages/scorers/src/llm/moderation.ts
  • packages/scorers/src/llm/structured-output.ts
  • packages/scorers/src/test-utils.ts
  • packages/scorers/tsup.config.ts
  • packages/sdk/CHANGELOG.md
  • packages/sdk/package.json
  • packages/sdk/tsup.config.ts
  • packages/server-core/CHANGELOG.md
  • packages/server-core/package.json
  • packages/server-core/src/handlers/agent.handlers.spec.ts
  • packages/server-core/src/handlers/agent.handlers.ts
  • packages/server-core/src/handlers/tool.handlers.ts
  • packages/server-core/src/schemas/agent.schemas.ts
  • packages/server-core/src/utils/options.ts
  • packages/server-core/tsup.config.ts
  • packages/server-elysia/CHANGELOG.md
  • packages/server-elysia/THIRD_PARTY_NOTICES.md
  • packages/server-elysia/example/package.json
  • packages/server-elysia/package.json
  • packages/server-elysia/src/elysia-server-provider.spec.ts
  • packages/server-elysia/src/elysia-server-provider.ts
  • packages/server-elysia/src/utils/zod-adapter.ts
  • packages/server-elysia/tsup.config.ts
  • packages/server-hono/CHANGELOG.md
  • packages/server-hono/package.json
  • packages/server-hono/src/routes/agent.routes.ts
  • packages/server-hono/src/routes/index.ts
  • packages/server-hono/src/routes/memory.routes.ts
  • packages/server-hono/src/routes/path-params.ts
  • packages/server-hono/src/routes/tool.routes.ts
  • packages/server-hono/src/zod-openapi-compat.ts
  • packages/server-hono/tsup.config.ts
  • packages/serverless-hono/CHANGELOG.md
  • packages/serverless-hono/package.json
  • packages/supabase/CHANGELOG.md
  • packages/supabase/package.json
  • packages/supabase/src/memory-adapter.ts
  • packages/supabase/tsup.config.ts
  • packages/vercel-ai-exporter/CHANGELOG.md
  • packages/vercel-ai-exporter/package.json
  • packages/vercel-ai-exporter/src/exporter.ts
  • packages/vercel-ai-exporter/tsup.config.ts
  • packages/voice/CHANGELOG.md
  • packages/voice/package.json
  • packages/voice/tsup.config.ts
  • packages/voltagent-memory/CHANGELOG.md
  • packages/voltagent-memory/package.json
  • packages/voltagent-memory/tsup.config.ts
  • packages/voltagent-memory/vitest.config.mts
  • website/docs/agents/cancellation.md
  • website/docs/agents/context.md
  • website/docs/agents/dynamic-agents.md
  • website/docs/agents/hooks.md
  • website/docs/agents/mcp/mcp-server.md
  • website/docs/agents/memory.md
  • website/docs/agents/memory/cloudflare-d1.md
  • website/docs/agents/memory/in-memory.md
  • website/docs/agents/memory/overview.md
  • website/docs/agents/message-types.md
  • website/docs/agents/overview.md
  • website/docs/agents/plan-agent.md
  • website/docs/agents/resumable-streaming.md
  • website/docs/agents/structured-output.md
  • website/docs/agents/subagents.md
  • website/docs/agents/tools.md
  • website/docs/api/endpoints/agents.md
  • website/docs/getting-started/migration-guide.md
  • website/docs/getting-started/model-router.md
  • website/docs/getting-started/quick-start.md
  • website/docs/integrations/nextjs.md
  • website/docs/integrations/vercel-ai.md
  • website/docs/observability/logging.md
  • website/docs/rag/chroma.md
  • website/docs/rag/lancedb.md
  • website/docs/rag/pinecone.md
  • website/docs/rag/qdrant.md
  • website/docs/tools/overview.md
  • website/docs/tools/tool-routing.md
  • website/docs/ui/ai-sdk-integration.md
  • website/docs/ui/assistant-ui.md
  • website/docs/ui/copilotkit.md
  • website/docs/workflows/steps/and-agent.md
  • website/docs/workflows/steps/and-then.md
  • website/docs/workflows/streaming.md
  • website/docs/workspaces/overview.md
  • website/sidebars.ts
  • website/src/components/live-preview/index.tsx
  • website/src/data/tweets.json

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch next

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 9, 2026

Copy link
Copy Markdown

Deploying voltagent with  Cloudflare Pages  Cloudflare Pages

Latest commit: aef2a09
Status: ✅  Deploy successful!
Preview URL: https://0af98310.voltagent.pages.dev
Branch Preview URL: https://next.voltagent.pages.dev

View logs

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 33 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/cloudflare-d1/CHANGELOG.md">

<violation number="1" location="packages/cloudflare-d1/CHANGELOG.md:158">
P1: The CHANGELOG code example shows `voltagent: { name: 'refundCustomer', purpose: 'Issue customer refunds' }` but the `VoltAgentToolMetadata` type in `packages/core/src/tool/ai-sdk-tool.ts` defines neither `name` nor `purpose` fields. This example won't compile. Either add those fields to `VoltAgentToolMetadata` (the CHANGELOG implies they are supported), or update the example to use existing metadata properties like `voltagent.metadata.name` and `voltagent.metadata.purpose`.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

},
voltagent: {
name: "refundCustomer",
purpose: "Issue customer refunds",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The CHANGELOG code example shows voltagent: { name: 'refundCustomer', purpose: 'Issue customer refunds' } but the VoltAgentToolMetadata type in packages/core/src/tool/ai-sdk-tool.ts defines neither name nor purpose fields. This example won't compile. Either add those fields to VoltAgentToolMetadata (the CHANGELOG implies they are supported), or update the example to use existing metadata properties like voltagent.metadata.name and voltagent.metadata.purpose.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/cloudflare-d1/CHANGELOG.md, line 158:

<comment>The CHANGELOG code example shows `voltagent: { name: 'refundCustomer', purpose: 'Issue customer refunds' }` but the `VoltAgentToolMetadata` type in `packages/core/src/tool/ai-sdk-tool.ts` defines neither `name` nor `purpose` fields. This example won't compile. Either add those fields to `VoltAgentToolMetadata` (the CHANGELOG implies they are supported), or update the example to use existing metadata properties like `voltagent.metadata.name` and `voltagent.metadata.purpose`.</comment>

<file context>
@@ -155,8 +155,7 @@
       name: "refundCustomer",
-      purpose: "Issue customer refunds after approval",
-      needsApproval: true,
+      purpose: "Issue customer refunds",
     },
   });
</file context>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

13 issues found and verified against the latest diff

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/server-core/src/utils/options.ts">

<violation number="1" location="packages/server-core/src/utils/options.ts:55">
P2: Malformed request payloads can now crash option processing before defaults are applied. The new `in` check runs on unvalidated `body.options`, so adding an object/null guard before this check would avoid a runtime TypeError.</violation>
</file>

<file name="examples/with-ollama/package.json">

<violation number="1" location="examples/with-ollama/package.json:10">
P2: Zod version inconsistency: `with-ollama` and `with-openrouter` specify `zod@^4.1.8` while every other example in this batch keeps `zod@^3.25.76`. This creates an inconsistency that could cause confusion for developers using these examples as templates. For `with-openrouter` specifically, `zod` is added as a dependency even though it is never imported in the example source code. Consider aligning these two examples with the rest of the batch — either keep `zod@^3.25.76` for consistency, or if all examples should be on v4, update them uniformly.</violation>
</file>

<file name="packages/create-voltagent-app/package.json">

<violation number="1" location="packages/create-voltagent-app/package.json:4">
P3: CLI version string in cli.ts (`program.version("0.1.0")`) is out of sync with package.json (`"1.0.0-next.0"`). Running `create-voltagent-app --version` will report the wrong version. Import the version from package.json or update the hardcoded string to match.</violation>
</file>

<file name="packages/server-core/src/schemas/agent.schemas.ts">

<violation number="1" location="packages/server-core/src/schemas/agent.schemas.ts:348">
P2: Type safety for exported generation options is lost because `GenerateOptionsSchema` is explicitly widened to `ZodTypeAny`. Removing the annotation preserves the full inferred schema type for SDK/server consumers.</violation>
</file>

<file name="packages/server-hono/src/zod-openapi-compat.ts">

<violation number="1" location="packages/server-hono/src/zod-openapi-compat.ts:94">
P2: `OpenAPIHonoType` now hides part of the real `app.openapi` API, so callers typed against this export can no longer pass the optional `hook` callback even though runtime supports it. Keeping the method type aligned with the instance method avoids this type regression and preserves chain typing.</violation>
</file>

<file name="packages/core/src/tool/manager/ToolkitManager.ts">

<violation number="1" location="packages/core/src/tool/manager/ToolkitManager.ts:7">
P1: NamedAiSdkTool items with `type: "ai-sdk"` passed to a ToolkitManager will be silently dropped. The inherited `addStandaloneTool` from `BaseToolManager` only handles `ProviderTool` (`type === "provider"`) and `BaseTool` (`type === "user-defined"`). A `NamedAiSdkTool` with `type: "ai-sdk"` falls through to the unsupported-tool error path and returns `false` without actually storing the tool. `ToolManager` works around this by overriding `addStandaloneTool` and delegating to an internal `aiSdkTools` map — `ToolkitManager` needs the same treatment before `NamedAiSdkTool` is added to its type signature.</violation>
</file>

<file name="examples/github-star-stories/package.json">

<violation number="1" location="examples/github-star-stories/package.json:8">
P3: Bumping `@voltagent/server-hono` to `^3.0.0-next.0` on a line where its only import in this example is commented out (`src/index.ts:4`). Unless this example is expected to switch from serverless to server-hono soon, the dependency is dead weight — it adds install time, lockfile churn, and a stale version to maintain. Consider dropping the dependency (and the commented import) if it's not needed.</violation>
</file>

<file name="examples/with-tavily-search/package.json">

<violation number="1" location="examples/with-tavily-search/package.json:10">
P2: Example missing `engines` field for Node.js requirement after bumping `ai` to v7.0.0 and VoltAgent packages to v3.0.0-next.0 — AI SDK 7 requires Node.js 22+ (tested on 22, 24, 26; Node 18/20 no longer supported). Without declaring `engines`, someone running this example with Node.js 20 will hit runtime failures from the `ai` v7 dependency.</violation>
</file>

<file name="examples/with-planagents/package.json">

<violation number="1" location="examples/with-planagents/package.json:12">
P1: The `ai` SDK v7 (`^7.0.0`) requires Node.js >= 22, but this example documents Node.js v20+ as its minimum and the project lists `node@>=20`. Users on Node.js 20 or 21 will hit a runtime/install failure. Consider bumping the documented minimum to Node.js 22 or pinning `ai` to `^6.0.0` if v20 support must be maintained.</violation>
</file>

<file name="examples/with-tools/package.json">

<violation number="1" location="examples/with-tools/package.json:11">
P2: `ai@^7.0.0` requires Node.js 22+. Users running Node 20 or 21 who install this example will encounter runtime errors. Consider either pinning `ai` to `^6.0.0` for broader compatibility or adding an `"engines": {"node": ">=22"}` field to this example's `package.json` to surface the requirement early during install.</violation>
</file>

<file name="examples/with-chat-sdk/package.json">

<violation number="1" location="examples/with-chat-sdk/package.json:10">
P2: The README documents Node.js 20+ as a prerequisite, but `ai@^7.0.0` (added by this change) requires Node.js 22+. The minimum Node.js version listed in `examples/with-chat-sdk/README.md` needs to be updated to 22+ to match the new dependency.</violation>
</file>

<file name="packages/vercel-ai-exporter/src/exporter.ts">

<violation number="1" location="packages/vercel-ai-exporter/src/exporter.ts:1132">
P2: Semantic field name mismatch: the property was renamed from `system` to `instructions`, but the mapped value is still `gen_ai.system` / `ai.model.provider` — which in OpenTelemetry conventions represents the AI provider name (e.g. "openai", "anthropic"), not agent instructions. A downstream consumer seeing `instructions: "openai"` would be misled into thinking this contains the agent's system prompt or behavioral instructions.</violation>
</file>

<file name="packages/core/src/agent/streaming/guardrail-stream.ts">

<violation number="1" location="packages/core/src/agent/streaming/guardrail-stream.ts:217">
P1: UI finish callback may be silently dropped when guardrails are active. The `createUIMessageStream` option was renamed from `onFinish` to `onEnd`, but the value still reads `streamOptions.onFinish`. If `UIMessageStreamOptions` in ai v7 drops the `onFinish` property (consistent with the rest of this PR's renames), then `streamOptions.onFinish` is always `undefined` and the user-supplied finish callback never executes. Update to `streamOptions.onEnd ?? streamOptions.onFinish` to safely handle the rename.</violation>
</file>

Note: This PR contains a large number of files. cubic only reviews up to 200 files per PR, so some files may not have been reviewed. cubic prioritizes the most important files to review.

Re-trigger cubic


export class ToolkitManager extends BaseToolManager<AgentTool | VercelTool, never> {
export class ToolkitManager extends BaseToolManager<
AgentTool | VercelTool | NamedAiSdkTool,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: NamedAiSdkTool items with type: "ai-sdk" passed to a ToolkitManager will be silently dropped. The inherited addStandaloneTool from BaseToolManager only handles ProviderTool (type === "provider") and BaseTool (type === "user-defined"). A NamedAiSdkTool with type: "ai-sdk" falls through to the unsupported-tool error path and returns false without actually storing the tool. ToolManager works around this by overriding addStandaloneTool and delegating to an internal aiSdkTools map — ToolkitManager needs the same treatment before NamedAiSdkTool is added to its type signature.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core/src/tool/manager/ToolkitManager.ts, line 7:

<comment>NamedAiSdkTool items with `type: "ai-sdk"` passed to a ToolkitManager will be silently dropped. The inherited `addStandaloneTool` from `BaseToolManager` only handles `ProviderTool` (`type === "provider"`) and `BaseTool` (`type === "user-defined"`). A `NamedAiSdkTool` with `type: "ai-sdk"` falls through to the unsupported-tool error path and returns `false` without actually storing the tool. `ToolManager` works around this by overriding `addStandaloneTool` and delegating to an internal `aiSdkTools` map — `ToolkitManager` needs the same treatment before `NamedAiSdkTool` is added to its type signature.</comment>

<file context>
@@ -1,15 +1,18 @@
 
-export class ToolkitManager extends BaseToolManager<AgentTool | VercelTool, never> {
+export class ToolkitManager extends BaseToolManager<
+  AgentTool | VercelTool | NamedAiSdkTool,
+  never
+> {
</file context>

"@voltagent/libsql": "^3.0.0-next.0",
"@voltagent/logger": "^3.0.0-next.0",
"@voltagent/server-hono": "^3.0.0-next.0",
"ai": "^7.0.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The ai SDK v7 (^7.0.0) requires Node.js >= 22, but this example documents Node.js v20+ as its minimum and the project lists node@>=20. Users on Node.js 20 or 21 will hit a runtime/install failure. Consider bumping the documented minimum to Node.js 22 or pinning ai to ^6.0.0 if v20 support must be maintained.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At examples/with-planagents/package.json, line 12:

<comment>The `ai` SDK v7 (`^7.0.0`) requires Node.js >= 22, but this example documents Node.js v20+ as its minimum and the project lists `node@>=20`. Users on Node.js 20 or 21 will hit a runtime/install failure. Consider bumping the documented minimum to Node.js 22 or pinning `ai` to `^6.0.0` if v20 support must be maintained.</comment>

<file context>
@@ -4,12 +4,12 @@
+    "@voltagent/libsql": "^3.0.0-next.0",
+    "@voltagent/logger": "^3.0.0-next.0",
+    "@voltagent/server-hono": "^3.0.0-next.0",
+    "ai": "^7.0.0",
     "zod": "^3.25.76"
   },
</file context>

originalMessages: streamOptions.originalMessages,
onError,
onFinish: streamOptions.onFinish,
onEnd: streamOptions.onFinish,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: UI finish callback may be silently dropped when guardrails are active. The createUIMessageStream option was renamed from onFinish to onEnd, but the value still reads streamOptions.onFinish. If UIMessageStreamOptions in ai v7 drops the onFinish property (consistent with the rest of this PR's renames), then streamOptions.onFinish is always undefined and the user-supplied finish callback never executes. Update to streamOptions.onEnd ?? streamOptions.onFinish to safely handle the rename.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core/src/agent/streaming/guardrail-stream.ts, line 217:

<comment>UI finish callback may be silently dropped when guardrails are active. The `createUIMessageStream` option was renamed from `onFinish` to `onEnd`, but the value still reads `streamOptions.onFinish`. If `UIMessageStreamOptions` in ai v7 drops the `onFinish` property (consistent with the rest of this PR's renames), then `streamOptions.onFinish` is always `undefined` and the user-supplied finish callback never executes. Update to `streamOptions.onEnd ?? streamOptions.onFinish` to safely handle the rename.</comment>

<file context>
@@ -211,7 +214,7 @@ export function createGuardrailPipeline(
       originalMessages: streamOptions.originalMessages,
       onError,
-      onFinish: streamOptions.onFinish,
+      onEnd: streamOptions.onFinish,
       generateId: streamOptions.generateMessageId,
       execute: async ({ writer }) => {
</file context>
Suggested change
onEnd: streamOptions.onFinish,
onEnd: streamOptions.onEnd ?? streamOptions.onFinish,

}

function normalizeVoltAgentRuntimeOptions(options: RuntimeOptionsInput): Record<string, any> {
if (!("voltagent" in options)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Malformed request payloads can now crash option processing before defaults are applied. The new in check runs on unvalidated body.options, so adding an object/null guard before this check would avoid a runtime TypeError.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/server-core/src/utils/options.ts, line 55:

<comment>Malformed request payloads can now crash option processing before defaults are applied. The new `in` check runs on unvalidated `body.options`, so adding an object/null guard before this check would avoid a runtime TypeError.</comment>

<file context>
@@ -31,6 +51,48 @@ function normalizeRequestHeaders(
 }
 
+function normalizeVoltAgentRuntimeOptions(options: RuntimeOptionsInput): Record<string, any> {
+  if (!("voltagent" in options)) {
+    return options;
+  }
</file context>
Suggested change
if (!("voltagent" in options)) {
if (!options || typeof options !== "object" || !("voltagent" in options)) {

Comment thread examples/with-ollama/package.json Outdated
"@voltagent/server-hono": "^3.0.0-next.0",
"ai": "^7.0.0",
"ollama-ai-provider-v2": "^4.0.0",
"zod": "^4.1.8"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Zod version inconsistency: with-ollama and with-openrouter specify zod@^4.1.8 while every other example in this batch keeps zod@^3.25.76. This creates an inconsistency that could cause confusion for developers using these examples as templates. For with-openrouter specifically, zod is added as a dependency even though it is never imported in the example source code. Consider aligning these two examples with the rest of the batch — either keep zod@^3.25.76 for consistency, or if all examples should be on v4, update them uniformly.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At examples/with-ollama/package.json, line 10:

<comment>Zod version inconsistency: `with-ollama` and `with-openrouter` specify `zod@^4.1.8` while every other example in this batch keeps `zod@^3.25.76`. This creates an inconsistency that could cause confusion for developers using these examples as templates. For `with-openrouter` specifically, `zod` is added as a dependency even though it is never imported in the example source code. Consider aligning these two examples with the rest of the batch — either keep `zod@^3.25.76` for consistency, or if all examples should be on v4, update them uniformly.</comment>

<file context>
@@ -1,13 +1,13 @@
+    "@voltagent/server-hono": "^3.0.0-next.0",
+    "ai": "^7.0.0",
+    "ollama-ai-provider-v2": "^4.0.0",
+    "zod": "^4.1.8"
   },
   "devDependencies": {
</file context>

"@voltagent/libsql": "^3.0.0-next.0",
"@voltagent/logger": "^3.0.0-next.0",
"@voltagent/server-hono": "^3.0.0-next.0",
"ai": "^7.0.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: ai@^7.0.0 requires Node.js 22+. Users running Node 20 or 21 who install this example will encounter runtime errors. Consider either pinning ai to ^6.0.0 for broader compatibility or adding an "engines": {"node": ">=22"} field to this example's package.json to surface the requirement early during install.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At examples/with-tools/package.json, line 11:

<comment>`ai@^7.0.0` requires Node.js 22+. Users running Node 20 or 21 who install this example will encounter runtime errors. Consider either pinning `ai` to `^6.0.0` for broader compatibility or adding an `"engines": {"node": ">=22"}` field to this example's `package.json` to surface the requirement early during install.</comment>

<file context>
@@ -2,13 +2,13 @@
+    "@voltagent/libsql": "^3.0.0-next.0",
+    "@voltagent/logger": "^3.0.0-next.0",
+    "@voltagent/server-hono": "^3.0.0-next.0",
+    "ai": "^7.0.0",
     "zod": "^3.25.76"
   },
</file context>

"ai": "^6.0.0",
"@voltagent/cli": "^1.0.0-next.0",
"@voltagent/core": "^3.0.0-next.0",
"ai": "^7.0.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The README documents Node.js 20+ as a prerequisite, but ai@^7.0.0 (added by this change) requires Node.js 22+. The minimum Node.js version listed in examples/with-chat-sdk/README.md needs to be updated to 22+ to match the new dependency.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At examples/with-chat-sdk/package.json, line 10:

<comment>The README documents Node.js 20+ as a prerequisite, but `ai@^7.0.0` (added by this change) requires Node.js 22+. The minimum Node.js version listed in `examples/with-chat-sdk/README.md` needs to be updated to 22+ to match the new dependency.</comment>

<file context>
@@ -5,9 +5,9 @@
-    "ai": "^6.0.0",
+    "@voltagent/cli": "^1.0.0-next.0",
+    "@voltagent/core": "^3.0.0-next.0",
+    "ai": "^7.0.0",
     "chat": "^4.14.0",
     "next": "^16.0.7",
</file context>

? (attributes["gen_ai.finishReason"]?.toString() ?? null)
: null,
system:
instructions:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Semantic field name mismatch: the property was renamed from system to instructions, but the mapped value is still gen_ai.system / ai.model.provider — which in OpenTelemetry conventions represents the AI provider name (e.g. "openai", "anthropic"), not agent instructions. A downstream consumer seeing instructions: "openai" would be misled into thinking this contains the agent's system prompt or behavioral instructions.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/vercel-ai-exporter/src/exporter.ts, line 1132:

<comment>Semantic field name mismatch: the property was renamed from `system` to `instructions`, but the mapped value is still `gen_ai.system` / `ai.model.provider` — which in OpenTelemetry conventions represents the AI provider name (e.g. "openai", "anthropic"), not agent instructions. A downstream consumer seeing `instructions: "openai"` would be misled into thinking this contains the agent's system prompt or behavioral instructions.</comment>

<file context>
@@ -1129,7 +1129,7 @@ export class VoltAgentExporter implements SpanExporter {
             ? (attributes["gen_ai.finishReason"]?.toString() ?? null)
             : null,
-      system:
+      instructions:
         "gen_ai.system" in attributes
           ? (attributes["gen_ai.system"]?.toString() ?? null)
</file context>

"name": "create-voltagent-app",
"description": "Create VoltAgent applications with one command",
"version": "0.2.19",
"version": "1.0.0-next.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: CLI version string in cli.ts (program.version("0.1.0")) is out of sync with package.json ("1.0.0-next.0"). Running create-voltagent-app --version will report the wrong version. Import the version from package.json or update the hardcoded string to match.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/create-voltagent-app/package.json, line 4:

<comment>CLI version string in cli.ts (`program.version("0.1.0")`) is out of sync with package.json (`"1.0.0-next.0"`). Running `create-voltagent-app --version` will report the wrong version. Import the version from package.json or update the hardcoded string to match.</comment>

<file context>
@@ -1,7 +1,7 @@
   "name": "create-voltagent-app",
   "description": "Create VoltAgent applications with one command",
-  "version": "0.2.19",
+  "version": "1.0.0-next.0",
   "bin": {
     "create-voltagent": "./dist/index.js",
</file context>

"@voltagent/cli": "^1.0.0-next.0",
"@voltagent/core": "^3.0.0-next.0",
"@voltagent/logger": "^3.0.0-next.0",
"@voltagent/server-hono": "^3.0.0-next.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Bumping @voltagent/server-hono to ^3.0.0-next.0 on a line where its only import in this example is commented out (src/index.ts:4). Unless this example is expected to switch from serverless to server-hono soon, the dependency is dead weight — it adds install time, lockfile churn, and a stale version to maintain. Consider dropping the dependency (and the commented import) if it's not needed.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At examples/github-star-stories/package.json, line 8:

<comment>Bumping `@voltagent/server-hono` to `^3.0.0-next.0` on a line where its only import in this example is commented out (`src/index.ts:4`). Unless this example is expected to switch from serverless to server-hono soon, the dependency is dead weight — it adds install time, lockfile churn, and a stale version to maintain. Consider dropping the dependency (and the commented import) if it's not needed.</comment>

<file context>
@@ -2,11 +2,11 @@
+    "@voltagent/cli": "^1.0.0-next.0",
+    "@voltagent/core": "^3.0.0-next.0",
+    "@voltagent/logger": "^3.0.0-next.0",
+    "@voltagent/server-hono": "^3.0.0-next.0",
+    "@voltagent/serverless-hono": "^3.0.0-next.0",
     "dotenv": "^16.4.5",
</file context>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 146 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/server-elysia/src/utils/zod-adapter.ts">

<violation number="1" location="packages/server-elysia/src/utils/zod-adapter.ts:123">
P2: Schemas that include Zod unrepresentable types will lose validation and OpenAPI detail because `unrepresentable: "any"` converts them to `{}`, which this adapter maps to `Type.Any()`. Consider explicitly overriding supported cases such as `z.date()` or keeping throw behavior with tests so unsupported schemas fail loudly instead of accepting any value.</violation>
</file>

<file name="examples/with-voice-xsai/package.json">

<violation number="1" location="examples/with-voice-xsai/package.json:14">
P1: Zod bumped to v4 but `openai@^4.91.0` only declares `zod: '^3.23.8'` as a peer dependency — it doesn't support zod v4. This will produce peer dep warnings at install time, and openai may import zod in ways that break with v4 internals. Bump `openai` to `^6.0.0` or higher, which widened its zod peer range to `^3.25 || ^4.0`.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

"dotenv": "^16.4.5",
"openai": "^4.91.0",
"zod": "^3.25.76"
"zod": "^4.1.11"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Zod bumped to v4 but openai@^4.91.0 only declares zod: '^3.23.8' as a peer dependency — it doesn't support zod v4. This will produce peer dep warnings at install time, and openai may import zod in ways that break with v4 internals. Bump openai to ^6.0.0 or higher, which widened its zod peer range to ^3.25 || ^4.0.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At examples/with-voice-xsai/package.json, line 14:

<comment>Zod bumped to v4 but `openai@^4.91.0` only declares `zod: '^3.23.8'` as a peer dependency — it doesn't support zod v4. This will produce peer dep warnings at install time, and openai may import zod in ways that break with v4 internals. Bump `openai` to `^6.0.0` or higher, which widened its zod peer range to `^3.25 || ^4.0`.</comment>

<file context>
@@ -11,7 +11,7 @@
     "dotenv": "^16.4.5",
     "openai": "^4.91.0",
-    "zod": "^3.25.76"
+    "zod": "^4.1.11"
   },
   "devDependencies": {
</file context>

export function zodToTypeBox<T extends ZodType>(zodSchema: T): TSchema {
const jsonSchema = z.toJSONSchema(zodSchema, {
target: "draft-7",
unrepresentable: "any",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Schemas that include Zod unrepresentable types will lose validation and OpenAPI detail because unrepresentable: "any" converts them to {}, which this adapter maps to Type.Any(). Consider explicitly overriding supported cases such as z.date() or keeping throw behavior with tests so unsupported schemas fail loudly instead of accepting any value.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/server-elysia/src/utils/zod-adapter.ts, line 123:

<comment>Schemas that include Zod unrepresentable types will lose validation and OpenAPI detail because `unrepresentable: "any"` converts them to `{}`, which this adapter maps to `Type.Any()`. Consider explicitly overriding supported cases such as `z.date()` or keeping throw behavior with tests so unsupported schemas fail loudly instead of accepting any value.</comment>

<file context>
@@ -114,10 +117,12 @@ function mapJsonSchemaToTypeBox(schema: any): TSchema {
+export function zodToTypeBox<T extends ZodType>(zodSchema: T): TSchema {
+  const jsonSchema = z.toJSONSchema(zodSchema, {
+    target: "draft-7",
+    unrepresentable: "any",
+    reused: "inline",
+    cycles: "throw",
</file context>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

6 issues found across 56 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="website/docs/getting-started/quick-start.md">

<violation number="1" location="website/docs/getting-started/quick-start.md:62">
P2: During the VoltAgent 3 prerelease period, the quick-start requirements note now claims v3.x runtime boundaries (Node 22, ESM-only), but the scaffolding command above it still uses `npm create voltagent-app@latest`. On npm, `@latest` points to the latest stable release, which likely remains 2.x while 3.0.0 prereleases are published under a different dist-tag. Users following this guide may unknowingly scaffold a v2 project while being told they need a v3 runtime, leading to install/runtime/API confusion. Consider using the prerelease dist-tag (e.g., `@next`) in the create command during prerelease, or adding a clarifying note about which tag to use for v3.</violation>
</file>

<file name="packages/server-core/src/handlers/tool.handlers.ts">

<violation number="1" location="packages/server-core/src/handlers/tool.handlers.ts:161">
P2: When multiple agents register a tool with the same name, `mergeToolMetadata` silently drops metadata from later agents. Top-level `tags` and `agents` are properly merged, but `metadata` is strictly first-write-only (`existing.metadata ??= update.metadata`). Since the `metadata` payload contains a `voltagent` sub-object with its own `tags`, `purpose`, `api`, and custom metadata, this means the aggregated `metadata.voltagent` only reflects the first agent that registered the tool, producing inconsistent output. Consider merging the metadata payloads so that `voltagent` properties from subsequent agents are also consolidated.</violation>
</file>

<file name="website/docs/agents/tools.md">

<violation number="1" location="website/docs/agents/tools.md:656">
P1: The `readClipboardTool` output schema was updated to expect `{ text: string }`, but the Interactive Client-Side Tools example later in this same doc sends `{ content: text }` via `addToolResult`. This mismatch means users who copy both snippets will see a schema validation failure when the client-side tool result is returned. Align the schema field with the existing `addToolResult` payload by using `content` instead of `text`.</violation>
</file>

<file name="packages/core/src/agent/agent.ts">

<violation number="1" location="packages/core/src/agent/agent.ts:2578">
P1: The newly-added `await` on `this.getMergedHooks(options).onError?.({...})` (seen in both `streamText` and `streamObject` error handlers) is outside the `try/finally` that guarantees `flushObservability(...)` runs. If a merged hook throws, execution exits early so `userOnError`, telemetry span finalization, and observability flushing are all skipped. This is a direct consequence of changing the hook invocation from fire-and-forget to awaited without wrapping it in the existing cleanup guarantees.

Suggested fix: move the framework hook call inside the `try` block (or wrap it in its own `try/catch`) so a hook failure cannot prevent `flushObservability` and the user callback from running.</violation>
</file>

<file name="website/docs/agents/overview.md">

<violation number="1" location="website/docs/agents/overview.md:613">
P2: The updated Tools example introduces a new object-map registration pattern (`tools: { get_weather: weatherTool }`) and an unnamed `tool()` call, but other examples on the same page still use the older array style (`tools: [weatherTool, searchTool]` and `tools: [writerAgent.toTool(), editorAgent.toTool()]`). This inconsistency can confuse readers about which API contract to follow in VoltAgent 3. Consider aligning the remaining examples with the new object-map pattern, or adding an explicit note that both forms are supported.</violation>

<violation number="2" location="website/docs/agents/overview.md:862">
P1: The Operation Context example is incomplete: `hooks` is created with `createHooks` but never wired into an `Agent` or method call. Because the agent-level `onStart` that sets `requestId` never runs, the tool-level hook reading `options.context?.get("requestId")` would always resolve to `undefined`. Consider completing the example by attaching `hooks` to an `Agent` and showing the `generateText` call so readers can copy a working pattern.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

execute: async ({ message }) => {
return { logged: true, message };
},
voltagent: {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The Operation Context example is incomplete: hooks is created with createHooks but never wired into an Agent or method call. Because the agent-level onStart that sets requestId never runs, the tool-level hook reading options.context?.get("requestId") would always resolve to undefined. Consider completing the example by attaching hooks to an Agent and showing the generateText call so readers can copy a working pattern.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At website/docs/agents/overview.md, line 862:

<comment>The Operation Context example is incomplete: `hooks` is created with `createHooks` but never wired into an `Agent` or method call. Because the agent-level `onStart` that sets `requestId` never runs, the tool-level hook reading `options.context?.get("requestId")` would always resolve to `undefined`. Consider completing the example by attaching `hooks` to an `Agent` and showing the `generateText` call so readers can copy a working pattern.</comment>

<file context>
@@ -828,18 +844,28 @@ await agent.generateText("Hello", {
+  execute: async ({ message }) => {
+    return { logged: true, message };
+  },
+  voltagent: {
+    hooks: {
+      onStart: ({ args, options }) => {
</file context>

parameters: z.object({}),
inputSchema: z.object({}),
outputSchema: z.object({
text: z.string(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The readClipboardTool output schema was updated to expect { text: string }, but the Interactive Client-Side Tools example later in this same doc sends { content: text } via addToolResult. This mismatch means users who copy both snippets will see a schema validation failure when the client-side tool result is returned. Align the schema field with the existing addToolResult payload by using content instead of text.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At website/docs/agents/tools.md, line 656:

<comment>The `readClipboardTool` output schema was updated to expect `{ text: string }`, but the Interactive Client-Side Tools example later in this same doc sends `{ content: text }` via `addToolResult`. This mismatch means users who copy both snippets will see a schema validation failure when the client-side tool result is returned. Align the schema field with the existing `addToolResult` payload by using `content` instead of `text`.</comment>

<file context>
@@ -706,25 +638,29 @@ A tool without an `execute` function is automatically client-side.
-  parameters: z.object({}),
+  inputSchema: z.object({}),
+  outputSchema: z.object({
+    text: z.string(),
+  }),
 });
</file context>

Comment on lines +2578 to 2581
await this.getMergedHooks(options).onError?.({
agent: this,
error: actualError as Error,
context: oc,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The newly-added await on this.getMergedHooks(options).onError?.({...}) (seen in both streamText and streamObject error handlers) is outside the try/finally that guarantees flushObservability(...) runs. If a merged hook throws, execution exits early so userOnError, telemetry span finalization, and observability flushing are all skipped. This is a direct consequence of changing the hook invocation from fire-and-forget to awaited without wrapping it in the existing cleanup guarantees.

Suggested fix: move the framework hook call inside the try block (or wrap it in its own try/catch) so a hook failure cannot prevent flushObservability and the user callback from running.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core/src/agent/agent.ts, line 2578:

<comment>The newly-added `await` on `this.getMergedHooks(options).onError?.({...})` (seen in both `streamText` and `streamObject` error handlers) is outside the `try/finally` that guarantees `flushObservability(...)` runs. If a merged hook throws, execution exits early so `userOnError`, telemetry span finalization, and observability flushing are all skipped. This is a direct consequence of changing the hook invocation from fire-and-forget to awaited without wrapping it in the existing cleanup guarantees.

Suggested fix: move the framework hook call inside the `try` block (or wrap it in its own `try/catch`) so a hook failure cannot prevent `flushObservability` and the user callback from running.</comment>

<file context>
@@ -2464,7 +2575,7 @@ export class Agent {
 
                 // Call error hooks if they exist
-                this.getMergedHooks(options).onError?.({
+                await this.getMergedHooks(options).onError?.({
                   agent: this,
                   error: actualError as Error,
</file context>

@@ -483,7 +610,9 @@ const agent = new Agent({
name: "Weather Assistant",
instructions: "Answer weather questions using the get_weather tool.",
model: "openai/gpt-4o",
tools: [weatherTool],
tools: {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The updated Tools example introduces a new object-map registration pattern (tools: { get_weather: weatherTool }) and an unnamed tool() call, but other examples on the same page still use the older array style (tools: [weatherTool, searchTool] and tools: [writerAgent.toTool(), editorAgent.toTool()]). This inconsistency can confuse readers about which API contract to follow in VoltAgent 3. Consider aligning the remaining examples with the new object-map pattern, or adding an explicit note that both forms are supported.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At website/docs/agents/overview.md, line 613:

<comment>The updated Tools example introduces a new object-map registration pattern (`tools: { get_weather: weatherTool }`) and an unnamed `tool()` call, but other examples on the same page still use the older array style (`tools: [weatherTool, searchTool]` and `tools: [writerAgent.toTool(), editorAgent.toTool()]`). This inconsistency can confuse readers about which API contract to follow in VoltAgent 3. Consider aligning the remaining examples with the new object-map pattern, or adding an explicit note that both forms are supported.</comment>

<file context>
@@ -596,7 +610,9 @@ const agent = new Agent({
   instructions: "Answer weather questions using the get_weather tool.",
   model: "openai/gpt-4o",
-  tools: [weatherTool],
+  tools: {
+    get_weather: weatherTool,
+  },
</file context>

@@ -59,7 +59,7 @@ cd my-agent-app
```

:::info requirement
Be sure your environment is running Node.js 20.19 or newer so the generated tsdown build works without ESM resolution issues.
Be sure your environment is running Node.js 22 or newer. VoltAgent 3.x follows AI SDK 7's Node.js and ESM-only runtime boundary.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: During the VoltAgent 3 prerelease period, the quick-start requirements note now claims v3.x runtime boundaries (Node 22, ESM-only), but the scaffolding command above it still uses npm create voltagent-app@latest. On npm, @latest points to the latest stable release, which likely remains 2.x while 3.0.0 prereleases are published under a different dist-tag. Users following this guide may unknowingly scaffold a v2 project while being told they need a v3 runtime, leading to install/runtime/API confusion. Consider using the prerelease dist-tag (e.g., @next) in the create command during prerelease, or adding a clarifying note about which tag to use for v3.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At website/docs/getting-started/quick-start.md, line 62:

<comment>During the VoltAgent 3 prerelease period, the quick-start requirements note now claims v3.x runtime boundaries (Node 22, ESM-only), but the scaffolding command above it still uses `npm create voltagent-app@latest`. On npm, `@latest` points to the latest stable release, which likely remains 2.x while 3.0.0 prereleases are published under a different dist-tag. Users following this guide may unknowingly scaffold a v2 project while being told they need a v3 runtime, leading to install/runtime/API confusion. Consider using the prerelease dist-tag (e.g., `@next`) in the create command during prerelease, or adding a clarifying note about which tag to use for v3.</comment>

<file context>
@@ -59,7 +59,7 @@ cd my-agent-app
 
 :::info requirement
-Be sure your environment is running Node.js 20.19 or newer so the generated tsdown build works without ESM resolution issues.
+Be sure your environment is running Node.js 22 or newer. VoltAgent 3.x follows AI SDK 7's Node.js and ESM-only runtime boundary.
 :::
 
</file context>


existing.displayName ??= update.displayName;
existing.purpose ??= update.purpose;
existing.metadata ??= update.metadata;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: When multiple agents register a tool with the same name, mergeToolMetadata silently drops metadata from later agents. Top-level tags and agents are properly merged, but metadata is strictly first-write-only (existing.metadata ??= update.metadata). Since the metadata payload contains a voltagent sub-object with its own tags, purpose, api, and custom metadata, this means the aggregated metadata.voltagent only reflects the first agent that registered the tool, producing inconsistent output. Consider merging the metadata payloads so that voltagent properties from subsequent agents are also consolidated.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/server-core/src/handlers/tool.handlers.ts, line 161:

<comment>When multiple agents register a tool with the same name, `mergeToolMetadata` silently drops metadata from later agents. Top-level `tags` and `agents` are properly merged, but `metadata` is strictly first-write-only (`existing.metadata ??= update.metadata`). Since the `metadata` payload contains a `voltagent` sub-object with its own `tags`, `purpose`, `api`, and custom metadata, this means the aggregated `metadata.voltagent` only reflects the first agent that registered the tool, producing inconsistent output. Consider merging the metadata payloads so that `voltagent` properties from subsequent agents are also consolidated.</comment>

<file context>
@@ -62,19 +74,135 @@ const isZodLikeSchema = (
+
+  existing.displayName ??= update.displayName;
+  existing.purpose ??= update.purpose;
+  existing.metadata ??= update.metadata;
+};
+
</file context>

Comment thread packages/core/src/agent/agent.spec-d.ts

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 11 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="website/docs/agents/tools.md">

<violation number="1" location="website/docs/agents/tools.md:15">
P2: The new `contextSchema` example looks like a standalone, copy-pasteable snippet but is missing required imports and uses an undefined helper. The PR splits `tool` to import from `ai` (good), but accidentally drops the `Agent` import, omits the `zod` import, and introduces `fetchWeather` without defining it. Adding these imports and either defining or replacing the undefined helper would make the snippet immediately usable for readers trying out the new `contextSchema`/`toolsContext` APIs.</violation>
</file>

<file name="packages/core/src/tool/ai-sdk-tool.ts">

<violation number="1" location="packages/core/src/tool/ai-sdk-tool.ts:194">
P2: The `withVoltAgentMetadata` helper is a new standalone public API, but it does not preserve the tool's input/output types for `needsApproval` callbacks the way the `tool()` wrapper does. The metadata parameter accepts `VoltAgentToolMetadata` with default `unknown` generics, so a `needsApproval` callback attached via this helper loses its typed `input` parameter compared to using the `tool()` wrapper. Consider aligning the type signature so the metadata generics are derived from the tool type, keeping both APIs consistent for consumers who attach metadata to raw AI SDK tools.</violation>

<violation number="2" location="packages/core/src/tool/ai-sdk-tool.ts:194">
P2: `withVoltAgentMetadata()` can leave metadata in an inconsistent state when called multiple times on the same tool. The underlying `setVoltAgentToolMetadata()` updates a WeakMap first and then defines a non-configurable symbol property; if the property already exists, `Object.defineProperty` throws after the WeakMap has been mutated. Making the symbol property `configurable: true` (and `writable: true`) allows the setter to be safely called repeatedly, or the operation could be made atomic by using `try/finally` so the WeakMap and symbol always agree.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread website/docs/agents/tools.md Outdated

```ts
import { createTool } from "@voltagent/core";
import { tool } from "ai";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The new contextSchema example looks like a standalone, copy-pasteable snippet but is missing required imports and uses an undefined helper. The PR splits tool to import from ai (good), but accidentally drops the Agent import, omits the zod import, and introduces fetchWeather without defining it. Adding these imports and either defining or replacing the undefined helper would make the snippet immediately usable for readers trying out the new contextSchema/toolsContext APIs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At website/docs/agents/tools.md, line 15:

<comment>The new `contextSchema` example looks like a standalone, copy-pasteable snippet but is missing required imports and uses an undefined helper. The PR splits `tool` to import from `ai` (good), but accidentally drops the `Agent` import, omits the `zod` import, and introduces `fetchWeather` without defining it. Adding these imports and either defining or replacing the undefined helper would make the snippet immediately usable for readers trying out the new `contextSchema`/`toolsContext` APIs.</comment>

<file context>
@@ -9,10 +9,11 @@ Tools enable agents to interact with external systems, APIs, databases, and perf
 
 ```ts
-import { Agent, tool } from "@voltagent/core";
+import { tool } from "ai";
+import { Agent } from "@voltagent/core";
 import { z } from "zod";
</file context>

* Attach VoltAgent metadata to a raw AI SDK tool without changing the tool
* definition or sending the metadata to the model provider.
*/
export function withVoltAgentMetadata<T extends VercelTool<any, any, any>>(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The withVoltAgentMetadata helper is a new standalone public API, but it does not preserve the tool's input/output types for needsApproval callbacks the way the tool() wrapper does. The metadata parameter accepts VoltAgentToolMetadata with default unknown generics, so a needsApproval callback attached via this helper loses its typed input parameter compared to using the tool() wrapper. Consider aligning the type signature so the metadata generics are derived from the tool type, keeping both APIs consistent for consumers who attach metadata to raw AI SDK tools.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core/src/tool/ai-sdk-tool.ts, line 194:

<comment>The `withVoltAgentMetadata` helper is a new standalone public API, but it does not preserve the tool's input/output types for `needsApproval` callbacks the way the `tool()` wrapper does. The metadata parameter accepts `VoltAgentToolMetadata` with default `unknown` generics, so a `needsApproval` callback attached via this helper loses its typed `input` parameter compared to using the `tool()` wrapper. Consider aligning the type signature so the metadata generics are derived from the tool type, keeping both APIs consistent for consumers who attach metadata to raw AI SDK tools.</comment>

<file context>
@@ -202,34 +187,35 @@ export function getRawAiSdkTool(tool: NamedAiSdkTool): VercelTool<any, any, any>
+ * Attach VoltAgent metadata to a raw AI SDK tool without changing the tool
+ * definition or sending the metadata to the model provider.
+ */
+export function withVoltAgentMetadata<T extends VercelTool<any, any, any>>(
+  tool: T,
+  metadata: VoltAgentToolMetadata,
</file context>

* Attach VoltAgent metadata to a raw AI SDK tool without changing the tool
* definition or sending the metadata to the model provider.
*/
export function withVoltAgentMetadata<T extends VercelTool<any, any, any>>(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: withVoltAgentMetadata() can leave metadata in an inconsistent state when called multiple times on the same tool. The underlying setVoltAgentToolMetadata() updates a WeakMap first and then defines a non-configurable symbol property; if the property already exists, Object.defineProperty throws after the WeakMap has been mutated. Making the symbol property configurable: true (and writable: true) allows the setter to be safely called repeatedly, or the operation could be made atomic by using try/finally so the WeakMap and symbol always agree.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core/src/tool/ai-sdk-tool.ts, line 194:

<comment>`withVoltAgentMetadata()` can leave metadata in an inconsistent state when called multiple times on the same tool. The underlying `setVoltAgentToolMetadata()` updates a WeakMap first and then defines a non-configurable symbol property; if the property already exists, `Object.defineProperty` throws after the WeakMap has been mutated. Making the symbol property `configurable: true` (and `writable: true`) allows the setter to be safely called repeatedly, or the operation could be made atomic by using `try/finally` so the WeakMap and symbol always agree.</comment>

<file context>
@@ -202,34 +187,35 @@ export function getRawAiSdkTool(tool: NamedAiSdkTool): VercelTool<any, any, any>
+ * Attach VoltAgent metadata to a raw AI SDK tool without changing the tool
+ * definition or sending the metadata to the model provider.
+ */
+export function withVoltAgentMetadata<T extends VercelTool<any, any, any>>(
+  tool: T,
+  metadata: VoltAgentToolMetadata,
</file context>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8 issues found across 108 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="examples/with-cloudflare-workers/README.md">

<violation number="1" location="examples/with-cloudflare-workers/README.md:207">
P3: The updated custom-tools example references `weatherTool` (and returns an undefined `result`), but the snippet never defines or imports them, so the example won't compile if copied as-is. Consider defining a minimal `weatherTool` stub or adding a comment that it represents an existing tool defined elsewhere.</violation>
</file>

<file name="website/docs/agents/dynamic-agents.md">

<violation number="1" location="website/docs/agents/dynamic-agents.md:211">
P3: The updated example returns a named ToolSet object ({ get_help, admin_action }) from the dynamic tools function, but the surrounding docs still describe tools as "a static array or a function returning an array" and the Type System section documents ToolsDynamicValue as array-only. This now contradicts the shown example. Object-keyed returns are valid (AgentToolInput accepts a ToolSet and the name comes from the object key), so either the example or the prose should be aligned to avoid misleading readers.</violation>
</file>

<file name="website/docs/agents/mcp/mcp-server.md">

<violation number="1" location="website/docs/agents/mcp/mcp-server.md:202">
P2: In this MCP-only example, `statusTool` is created with the AI SDK `tool()` helper, which returns a bare VercelTool carrying `inputSchema`/`description`/`execute` but no `name`, `id`, or `parameters`. The MCPServer's configured-tools path (`normalizeConfiguredTools` + `toMcpTool`) keys on `tool.id ?? tool.name` and reads `tool.parameters`, none of which exist on this object, so the `~status~` entry is silently skipped and never exposed to MCP clients. Unlike the `Agent.tools` field (which wraps AI SDK tools via `createNamedAiSdkTool`), the MCPServer `tools` field is consumed raw. Worth verifying this example against the current mcp-server build — if it is intended to work, the server likely needs to wrap AI SDK tools (e.g. `createNamedAiSdkTool("status", statusTool)`) the same way the agent path does.</violation>
</file>

<file name="examples/with-whatsapp/README.md">

<violation number="1" location="examples/with-whatsapp/README.md:311">
P3: Now that customerPhone is a required field in contextSchema and always injected via toolsContext, the `if (!customerPhone)` guard in checkOrderStatus can never trigger and its "Please login to the system" branch is dead code. Consider dropping the guard (and the unused branch) since the documented setup guarantees the value, to avoid teaching a defensive pattern the schema no longer needs.</violation>

<violation number="2" location="examples/with-whatsapp/README.md:543">
P3: The `- Confirm order and clear working memory` line is indented two spaces while the sibling instruction lines in the same list use three spaces, so it renders misaligned inside the instructions template literal. Align it with the other list items.</violation>
</file>

<file name="packages/core/src/agent/agent.ts">

<violation number="1">
P2: Routed native tools ignore `toolsContext` changes returned by `prepareStep`: `callTool` resolves its context from this initial snapshot, while direct AI SDK tools use the current step context. Thread the current step's context into routed execution (or update the stored value in the `prepareStep` wrapper) before resolving/validating the target context.</violation>
</file>

<file name="website/docs/agents/context.md">

<violation number="1" location="website/docs/agents/context.md:345">
P2: In the "Accessing Input" example the hook callback destructures `{ context }` from the OperationContext, which gives the user Map, not the operation context. The Map has no `.input`, so `context.input` will be `undefined` when a reader copies this example. Keep the OperationContext and read its `input` field directly instead.</violation>

<violation number="2" location="website/docs/agents/context.md:795">
P2: In the "Complete Flow Example" the new `onToolEnd` destructures `{ context, output }`, so `context` becomes the user Map; then `context.context.set(...)` accesses `.context` on that Map, which is undefined and would throw when a user copies this handler. Use `context.set(...)` directly on the destructured Map (the adjacent `onStart`/`onEnd` keep the OperationContext as the callback arg, so they correctly use `context.context`).</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

@@ -199,7 +198,9 @@ const supportAgent = new Agent({
instructions:
"Use internal knowledge to triage customer tickets and respond with routing guidance.",
model: "openai/gpt-4o-mini",
tools: [statusTool],
tools: {
status: statusTool,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: In this MCP-only example, statusTool is created with the AI SDK tool() helper, which returns a bare VercelTool carrying inputSchema/description/execute but no name, id, or parameters. The MCPServer's configured-tools path (normalizeConfiguredTools + toMcpTool) keys on tool.id ?? tool.name and reads tool.parameters, none of which exist on this object, so the ~status~ entry is silently skipped and never exposed to MCP clients. Unlike the Agent.tools field (which wraps AI SDK tools via createNamedAiSdkTool), the MCPServer tools field is consumed raw. Worth verifying this example against the current mcp-server build — if it is intended to work, the server likely needs to wrap AI SDK tools (e.g. createNamedAiSdkTool("status", statusTool)) the same way the agent path does.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At website/docs/agents/mcp/mcp-server.md, line 202:

<comment>In this MCP-only example, `statusTool` is created with the AI SDK `tool()` helper, which returns a bare VercelTool carrying `inputSchema`/`description`/`execute` but no `name`, `id`, or `parameters`. The MCPServer's configured-tools path (`normalizeConfiguredTools` + `toMcpTool`) keys on `tool.id ?? tool.name` and reads `tool.parameters`, none of which exist on this object, so the `~status~` entry is silently skipped and never exposed to MCP clients. Unlike the `Agent.tools` field (which wraps AI SDK tools via `createNamedAiSdkTool`), the MCPServer `tools` field is consumed raw. Worth verifying this example against the current mcp-server build — if it is intended to work, the server likely needs to wrap AI SDK tools (e.g. `createNamedAiSdkTool("status", statusTool)`) the same way the agent path does.</comment>

<file context>
@@ -199,7 +198,9 @@ const supportAgent = new Agent({
   model: "openai/gpt-4o-mini",
-  tools: [statusTool],
+  tools: {
+    status: statusTool,
+  },
 });
</file context>

instructions: "Answer concisely.",
hooks: createHooks({
onStart: ({ context }) => {
const input = context.input;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: In the "Accessing Input" example the hook callback destructures { context } from the OperationContext, which gives the user Map, not the operation context. The Map has no .input, so context.input will be undefined when a reader copies this example. Keep the OperationContext and read its input field directly instead.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At website/docs/agents/context.md, line 345:

<comment>In the "Accessing Input" example the hook callback destructures `{ context }` from the OperationContext, which gives the user Map, not the operation context. The Map has no `.input`, so `context.input` will be `undefined` when a reader copies this example. Keep the OperationContext and read its `input` field directly instead.</comment>

<file context>
@@ -357,20 +334,19 @@ The `OperationContext` provides access to both the input and output of the curre
+  instructions: "Answer concisely.",
+  hooks: createHooks({
+    onStart: ({ context }) => {
+      const input = context.input;
+      console.log("Original input:", input);
+      // input can be: string, UIMessage[], or ModelMessage[]
</file context>

hooks: createHooks({
onStart: (context) => {
console.log("🚀 Operation started");
context.context.set("operationId", `op-${Date.now()}`);
},
onToolEnd: ({ context, output }) => {
if (output && typeof output === "object" && "count" in output) {
context.context.set("counter", output.count);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: In the "Complete Flow Example" the new onToolEnd destructures { context, output }, so context becomes the user Map; then context.context.set(...) accesses .context on that Map, which is undefined and would throw when a user copies this handler. Use context.set(...) directly on the destructured Map (the adjacent onStart/onEnd keep the OperationContext as the callback arg, so they correctly use context.context).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At website/docs/agents/context.md, line 795:

<comment>In the "Complete Flow Example" the new `onToolEnd` destructures `{ context, output }`, so `context` becomes the user Map; then `context.context.set(...)` accesses `.context` on that Map, which is undefined and would throw when a user copies this handler. Use `context.set(...)` directly on the destructured Map (the adjacent `onStart`/`onEnd` keep the OperationContext as the callback arg, so they correctly use `context.context`).</comment>

<file context>
@@ -810,12 +782,19 @@ const fullAgent = new Agent({
     },
+    onToolEnd: ({ context, output }) => {
+      if (output && typeof output === "object" && "count" in output) {
+        context.context.set("counter", output.count);
+      }
+    },
</file context>
Suggested change
context.context.set("counter", output.count);
context.set("counter", output.count);

// ...
tools: [weatherTool, customTool],
tools: {
getWeather: weatherTool,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The updated custom-tools example references weatherTool (and returns an undefined result), but the snippet never defines or imports them, so the example won't compile if copied as-is. Consider defining a minimal weatherTool stub or adding a comment that it represents an existing tool defined elsewhere.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At examples/with-cloudflare-workers/README.md, line 207:

<comment>The updated custom-tools example references `weatherTool` (and returns an undefined `result`), but the snippet never defines or imports them, so the example won't compile if copied as-is. Consider defining a minimal `weatherTool` stub or adding a comment that it represents an existing tool defined elsewhere.</comment>

<file context>
@@ -187,21 +187,26 @@ id = "your-namespace-id"
   // ...
-  tools: [weatherTool, customTool],
+  tools: {
+    getWeather: weatherTool,
+    toolName: customTool,
+  },
</file context>

return [basicTool, adminTool]; // Admins get both tools
} else {
return [basicTool]; // Regular users get basic tools only
return {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The updated example returns a named ToolSet object ({ get_help, admin_action }) from the dynamic tools function, but the surrounding docs still describe tools as "a static array or a function returning an array" and the Type System section documents ToolsDynamicValue as array-only. This now contradicts the shown example. Object-keyed returns are valid (AgentToolInput accepts a ToolSet and the name comes from the object key), so either the example or the prose should be aligned to avoid misleading readers.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At website/docs/agents/dynamic-agents.md, line 211:

<comment>The updated example returns a named ToolSet object ({ get_help, admin_action }) from the dynamic tools function, but the surrounding docs still describe tools as "a static array or a function returning an array" and the Type System section documents ToolsDynamicValue as array-only. This now contradicts the shown example. Object-keyed returns are valid (AgentToolInput accepts a ToolSet and the name comes from the object key), so either the example or the prose should be aligned to avoid misleading readers.</comment>

<file context>
@@ -210,10 +208,15 @@ const agent = new Agent({
-      return [basicTool, adminTool]; // Admins get both tools
-    } else {
-      return [basicTool]; // Regular users get basic tools only
+      return {
+        get_help: basicTool,
+        admin_action: adminTool,
</file context>

try {
// Get customer phone from context userId
const customerPhone = context?.userId || "unknown";
const customerPhone = context.customerPhone;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Now that customerPhone is a required field in contextSchema and always injected via toolsContext, the if (!customerPhone) guard in checkOrderStatus can never trigger and its "Please login to the system" branch is dead code. Consider dropping the guard (and the unused branch) since the documented setup guarantees the value, to avoid teaching a defensive pattern the schema no longer needs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At examples/with-whatsapp/README.md, line 311:

<comment>Now that customerPhone is a required field in contextSchema and always injected via toolsContext, the `if (!customerPhone)` guard in checkOrderStatus can never trigger and its "Please login to the system" branch is dead code. Consider dropping the guard (and the unused branch) since the documented setup guarantees the value, to avoid teaching a defensive pattern the schema no longer needs.</comment>

<file context>
@@ -303,10 +305,10 @@ export const createOrderTool = createTool({
     try {
-      // Get customer phone from context userId
-      const customerPhone = context?.userId || "unknown";
+      const customerPhone = context.customerPhone;
 
       // Calculate total amount
</file context>

- Change orderStatus to "completed"
- Execute createOrder tool (with orders and deliveryAddress)
- Confirm order and clear working memory
- Confirm order and clear working memory

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The - Confirm order and clear working memory line is indented two spaces while the sibling instruction lines in the same list use three spaces, so it renders misaligned inside the instructions template literal. Align it with the other list items.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At examples/with-whatsapp/README.md, line 543:

<comment>The `- Confirm order and clear working memory` line is indented two spaces while the sibling instruction lines in the same list use three spaces, so it renders misaligned inside the instructions template literal. Align it with the other list items.</comment>

<file context>
@@ -534,11 +540,15 @@ Order Flow:
    - Change orderStatus to "completed"
    - Execute createOrder tool (with orders and deliveryAddress)
-   - Confirm order and clear working memory
+  - Confirm order and clear working memory
 
 Always be friendly and helpful. Start with "Welcome!" greeting.`,
</file context>
Suggested change
- Confirm order and clear working memory
- Confirm order and clear working memory

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant