Conversation
🦋 Changeset detectedLatest commit: 98e53e7 The changes in this PR will be included in the next version bump. This PR includes no changesetsWhen 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 |
|
Important Review skippedToo many files! This PR contains 342 files, which is 192 over the limit of 150. To get a review, narrow the scope: Upgrade to a paid plan to raise the limit. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (342)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Deploying voltagent with
|
| Latest commit: |
98e53e7
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://5729482d.voltagent.pages.dev |
| Branch Preview URL: | https://next.voltagent.pages.dev |
There was a problem hiding this comment.
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", |
There was a problem hiding this comment.
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>
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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", |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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>
| onEnd: streamOptions.onFinish, | |
| onEnd: streamOptions.onEnd ?? streamOptions.onFinish, |
| } | ||
|
|
||
| function normalizeVoltAgentRuntimeOptions(options: RuntimeOptionsInput): Record<string, any> { | ||
| if (!("voltagent" in options)) { |
There was a problem hiding this comment.
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>
| if (!("voltagent" in options)) { | |
| if (!options || typeof options !== "object" || !("voltagent" in options)) { |
| "@voltagent/server-hono": "^3.0.0-next.0", | ||
| "ai": "^7.0.0", | ||
| "ollama-ai-provider-v2": "^4.0.0", | ||
| "zod": "^4.1.8" |
There was a problem hiding this comment.
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", |
There was a problem hiding this comment.
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", |
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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", |
There was a problem hiding this comment.
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", |
There was a problem hiding this comment.
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>
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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", |
There was a problem hiding this comment.
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>
There was a problem hiding this comment.
7 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/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>
<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="packages/core/src/agent/agent.spec-d.ts">
<violation number="1" location="packages/core/src/agent/agent.spec-d.ts:625">
P2: The新增 `expectTypeOf(step).toMatchTypeOf<unknown>()` assertion in the type-test suite is too weak to catch typing regressions. Because every type is assignable to `unknown`, this check will still pass if the parameter type drifts to `any` or is accidentally broadened. For a regression-catching type test, prefer `.toEqualTypeOf<unknown>()` (or a more specific AI SDK v7 step type if one is available), which enforces exact type equality rather than a one-way assignability check.</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>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| execute: async ({ message }) => { | ||
| return { logged: true, message }; | ||
| }, | ||
| voltagent: { |
There was a problem hiding this comment.
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(), |
There was a problem hiding this comment.
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>
| await this.getMergedHooks(options).onError?.({ | ||
| agent: this, | ||
| error: actualError as Error, | ||
| context: oc, |
There was a problem hiding this comment.
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: { | |||
There was a problem hiding this comment.
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. | |||
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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>
| onStepEnd: async (step) => { | ||
| expectTypeOf(step).toMatchTypeOf<unknown>(); | ||
| }, |
There was a problem hiding this comment.
P2: The新增 expectTypeOf(step).toMatchTypeOf<unknown>() assertion in the type-test suite is too weak to catch typing regressions. Because every type is assignable to unknown, this check will still pass if the parameter type drifts to any or is accidentally broadened. For a regression-catching type test, prefer .toEqualTypeOf<unknown>() (or a more specific AI SDK v7 step type if one is available), which enforces exact type equality rather than a one-way assignability check.
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.spec-d.ts, line 625:
<comment>The新增 `expectTypeOf(step).toMatchTypeOf<unknown>()` assertion in the type-test suite is too weak to catch typing regressions. Because every type is assignable to `unknown`, this check will still pass if the parameter type drifts to `any` or is accidentally broadened. For a regression-catching type test, prefer `.toEqualTypeOf<unknown>()` (or a more specific AI SDK v7 step type if one is available), which enforces exact type equality rather than a one-way assignability check.</comment>
<file context>
@@ -536,6 +579,123 @@ describe("Agent Type System", () => {
+ onLanguageModelCallEnd: async () => {},
+ onToolExecutionStart: async () => {},
+ onToolExecutionEnd: async () => {},
+ onStepEnd: async (step) => {
+ expectTypeOf(step).toMatchTypeOf<unknown>();
+ },
</file context>
| onStepEnd: async (step) => { | |
| expectTypeOf(step).toMatchTypeOf<unknown>(); | |
| }, | |
| onStepEnd: async (step) => { | |
| expectTypeOf(step).toEqualTypeOf<unknown>(); | |
| }, |
There was a problem hiding this comment.
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
|
|
||
| ```ts | ||
| import { createTool } from "@voltagent/core"; | ||
| import { tool } from "ai"; |
There was a problem hiding this comment.
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>>( |
There was a problem hiding this comment.
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>>( |
There was a problem hiding this comment.
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>
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
nextchannel, upgrading the repo, examples, and CI to Node 22 and AI SDK v7-compatible APIs. Aligns tools with AI SDK (newtool()/ToolSet, typed metadata), stabilizes tests, and adds@voltagent/libsqlworking memory persistence.Dependencies
next(.changeset/pre.json), normalized its formatting, and added CI verification.@voltagent/coreto3.0.0-next.1; most others to3.0.0-next.0.@voltagent/core; raw tools supportcontextSchema/toolsContext; attach metadata viawithVoltAgentMetadata.ai@^7,@ai-sdk/openai@^4,@ai-sdk/react@^4,@openrouter/ai-sdk-provider@^3,ollama-ai-provider-v2@^4, andzod@^4.22and verifies prerelease mode; standardizedpackage.jsontype/typesorder.docs/ai-sdk-first-vnext-plan.mdwith tool approval guidance (related issue: RFC: Make VoltAgent vNext an ai-sdk-first outer framework #1373).Migration
zod@^4; install prereleases via@next/3.0.0-next.x.createTool->tool,parameters->inputSchema, and configuretoolsas an object map (ToolSet).usage.outputTokenDetails.reasoningTokensandusage.inputTokenDetails.cacheReadTokens.toUIMessageStreamResponse({ onEnd })replacesonFinish.{ type: "file", data, mediaType }replaces{ type: "image", image }.generateObject: passinstructionsinstead ofsystem.Written for commit 98e53e7. Summary will update on new commits.