-
-
Notifications
You must be signed in to change notification settings - Fork 456
feat: update nextjs examples #933
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
📝 WalkthroughWalkthroughThis PR refactors example projects to run VoltAgent as a separate process: agent definitions moved to Changes
Sequence Diagram(s)sequenceDiagram
participant User as Browser / User
participant App as Next.js App
participant API as Next.js API Route
participant VA as VoltAgent REST Server (http://localhost:3141)
participant Agent as Agent Logic (in VA)
participant Console as VoltAgent Console
User->>App: Open chat UI
App->>API: POST /api/chat (user message)
API->>VA: Forward message to VoltAgent REST API
VA->>Agent: Execute agent logic / tools
Agent-->>VA: Return response / streaming
VA-->>API: Return agent response (stream or JSON)
API-->>App: Stream response to UI
Note right of Console: Console connects to VA at :3141 for inspection
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 📜 Recent review detailsConfiguration used: defaults Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (5)
🚧 Files skipped from review as they are similar to previous changes (4)
🧰 Additional context used🧠 Learnings (2)📓 Common learnings📚 Learning: 2026-01-07T05:09:23.216ZApplied to files:
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
🔇 Additional comments (1)
Comment |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No issues found across 34 files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
examples/with-nextjs/app/api/chat/route.ts (1)
26-26: Replace JSON.stringify with safeStringify.The error response uses
JSON.stringify, which violates the project's coding guidelines.As per coding guidelines: Never use JSON.stringify; use the
safeStringifyfunction instead, imported from@voltagent/internal.🔧 Proposed fix
+import { safeStringify } from "@voltagent/internal"; + import { supervisorAgent } from "@/voltagent";- return new Response(JSON.stringify({ error: "Internal server error" }), { + return new Response(safeStringify({ error: "Internal server error" }), { status: 500, headers: { "Content-Type": "application/json" }, });examples/next-js-chatbot-starter-template/app/api/chat/route.ts (1)
12-12: Replace all JSON.stringify calls with safeStringify.Multiple error responses use
JSON.stringify, which violates the project's coding guidelines. All instances must be replaced withsafeStringify.As per coding guidelines: Never use JSON.stringify; use the
safeStringifyfunction instead, imported from@voltagent/internal.🔧 Proposed fix
Add the import at the top:
import { validateAIConfig } from "@/lib/ai/config"; import type { ChatRequest } from "@/lib/types/api"; import { chatbotAgent } from "@/voltagent"; +import { safeStringify } from "@voltagent/internal";Replace all three usages:
return new Response( - JSON.stringify({ + safeStringify({ error: configValidation.error || "Invalid AI configuration. Please check your .env.local file.", }),- return new Response(JSON.stringify({ error: "Messages array is required" }), { + return new Response(safeStringify({ error: "Messages array is required" }), { status: 400,return new Response( - JSON.stringify({ + safeStringify({ error: error instanceof Error ? error.message : "Internal server error", }),Also applies to: 28-28, 46-46
examples/with-client-side-tools/app/api/chat/route.ts (1)
14-23: ReplaceJSON.stringifywithsafeStringifyper TypeScript coding guidelines.The codebase requires using
safeStringifyinstead ofJSON.stringifyfor all.tsfiles. This function safely handles circular references and edge cases.Proposed fix
+import { safeStringify } from "@voltagent/internal"; import { agent } from "@/voltagent"; export async function POST(req: Request) { try { const { messages } = await req.json(); const result = await agent.streamText(messages, {}); return result.toUIMessageStreamResponse({ sendReasoning: true, sendSources: true, }); } catch (error) { console.error("API route error:", error); return new Response( - JSON.stringify({ + safeStringify({ error: error instanceof Error ? error.message : "Internal server error", }), { status: 500, headers: { "Content-Type": "application/json" }, }, ); } }website/docs/integrations/nextjs.md (1)
87-114: Critical security vulnerability: eval() usage in calculator tool.Line 108 uses
eval()to evaluate mathematical expressions, which is a severe code injection vulnerability. Even though there's a comment saying "in production, use a proper math parser", developers often copy example code directly, and this creates a critical security risk.🔒 Recommended fix: Use a safe math parser
Replace the eval() implementation with a safe math evaluation library:
+// Install: npm install mathjs +import { evaluate } from 'mathjs'; + const calculatorTool = createTool({ name: "calculate", description: "Perform basic mathematical calculations", parameters: z.object({ expression: z .string() - .describe("Mathematical expression to evaluate (e.g., '2 + 2', '10 * 5')"), + .describe("Mathematical expression to evaluate (e.g., '2 + 2', '10 * 5')") + .regex(/^[\d\s+\-*/().]+$/, "Expression must only contain numbers and basic operators"), }), execute: async (args) => { try { - // Simple evaluation - in production, use a proper math parser - const result = eval(args.expression); + const result = evaluate(args.expression); return { result, expression: args.expression }; } catch { return { error: "Invalid mathematical expression", expression: args.expression }; } }, });Alternative: If you want to keep dependencies minimal, implement a simple recursive descent parser for basic arithmetic, or at minimum add strict input validation to prevent code injection.
website/docs/ui/assistant-ui.md (1)
44-143: Update agent instructions to match actual implementation.The documentation code snippet for
voltagent/agents.ts(lines 64–70) shows simplified instructions that don't match the actual file. The real instructions include "gracefully describe any image or file attachments the user provides" and "Ask clarifying questions when context is missing," which should be reflected in the documented code.All other patterns verified (module structure,
new VoltAgent({ agents: {...}, server: honoServer() })initialization, agent exports, re-exports, and theagent.streamText().toUIMessageStreamResponse()API) align correctly with the actual implementation.
🤖 Fix all issues with AI agents
In @examples/next-js-chatbot-starter-template/voltagent/server.ts:
- Around line 5-10: Assign the VoltAgent instance to a variable (e.g., const
voltagent = new VoltAgent(...)) and wrap creation/initialization in a try/catch
to log errors via console.error and exit(1) on failure; after successful
creation, add signal handlers for SIGINT and SIGTERM that call the instance's
cleanup method (e.g., voltagent.shutdown() or voltagent.close() — check which
API exists) and then process.exit, and ensure any async init (if VoltAgent
exposes init/start) is awaited before registering handlers so the instance
reference is valid for graceful shutdown.
In @examples/with-assistant-ui/package.json:
- Line 40: The lockfile is out of sync with the updated "tsx" dependency in
package.json; regenerate the lockfile by installing dependencies (e.g., run npm
install or pnpm install / yarn install) in the examples/with-assistant-ui
workspace so package-lock.json / pnpm-lock.yaml / yarn.lock is updated and the
CI pipeline will pass.
In @examples/with-client-side-tools/app/api/chat/route.ts:
- Line 1: The error response uses JSON.stringify directly; import safeStringify
from "@voltagent/internal" (add: import { safeStringify } from
"@voltagent/internal"; alongside the existing import of agent) and replace
JSON.stringify({...}) with safeStringify({...}) in the error handler where the
response body is created (the error response block that currently calls
JSON.stringify). Ensure you only change the import and the serializer call
(leave the payload object unchanged).
In @examples/with-nextjs-resumable-stream/README.md:
- Around line 55-64: The instructions currently list both commands together and
risk people running them in one terminal; update the README to split the
commands into two separate code blocks and label them (e.g., "Terminal 1" with
the pnpm dev command and "Terminal 2" with the pnpm voltagent:run command) so
readers clearly run pnpm dev and pnpm voltagent:run in different terminals.
In @website/docs/ui/assistant-ui.md:
- Line 219: Wrap the bare URLs in the markdown text so MD034 is satisfied:
replace occurrences of the raw URL (e.g., http://localhost:3000 mentioned in the
sentence that starts "Open http://localhost:3000 and chat…") and the other bare
URL on the adjacent line with either markdown link syntax
[http://localhost:3000](http://localhost:3000) or inline code
`http://localhost:3000` (do the same for the URL on the other line) so the links
remain visible but are no longer bare.
- Line 219: The markdown contains bare URLs (e.g., the phrase "Open
http://localhost:3000 and chat" and the other occurrence on the same page) that
violate MD034; replace those bare URLs with markdown link syntax like
[http://localhost:3000](http://localhost:3000) (or a descriptive label such as
[Localhost:3000](http://localhost:3000)) in the assistant-ui.md content where
the "Open http://localhost:3000 and chat" sentence and the other URL occurrence
appear so both instances (lines around 219 and 221) are wrapped as proper
markdown links.
🧹 Nitpick comments (7)
examples/with-nextjs/app/api/health/route.ts (1)
3-5: LGTM! Clean health check implementation.The health check endpoint follows Next.js patterns correctly and uses
NextResponse.json()appropriately.Optional: Add return type annotation for better type safety
Per the coding guidelines to maintain type safety in the TypeScript-first codebase, consider adding a return type annotation:
-export async function GET() { +export async function GET(): Promise<NextResponse> { return NextResponse.json({ message: "OK" }); }examples/next-js-chatbot-starter-template/voltagent/agents.ts (1)
1-3: Consider consolidating the exports.The file exports
chatbotAgenttwice (once directly, once aliased asagent) using three separate statements. While functional, this could be streamlined for better maintainability.♻️ Consolidate exports into a single statement
-export { chatbotAgent } from "../lib/agent"; -export { sharedMemory } from "../lib/agent"; -export { chatbotAgent as agent } from "../lib/agent"; +export { chatbotAgent, sharedMemory, chatbotAgent as agent } from "../lib/agent";examples/with-nextjs/voltagent/agents.ts (1)
34-45: Consider renaming for clarity.The tool is named
writeStorybut only returns the topic without actually writing the story (the agent handles the creative writing). This might confuse developers unfamiliar with this pattern.Consider renaming to better reflect its purpose, such as
acknowledgeStoryTopicorprepareStoryPrompt.♻️ Optional naming improvement
-// Story writing tool -const storyWriterTool = createTool({ - name: "writeStory", - description: "Write a 50-word story about the given text", +// Story topic acknowledgment tool +const storyWriterTool = createTool({ + name: "acknowledgeStoryTopic", + description: "Acknowledge the story topic to prepare for writing", parameters: z.object({ text: z.string().describe("Text to write a story about"), }), execute: async (args) => { // The agent will handle the creative writing return { topic: args.text }; }, });examples/with-assistant-ui/voltagent/server.ts (1)
1-10: Avoid “nakednew” at module top-level; assign/export the instance (lint + clarity).If this repo enables rules like
no-new, this may fail linting; also exporting the instance makes the entrypoint more inspectable.Possible tweak
import { VoltAgent } from "@voltagent/core"; import { honoServer } from "@voltagent/server-hono"; import { agent } from "./agents"; -new VoltAgent({ +export const voltAgent = new VoltAgent({ agents: { agent, }, server: honoServer(), });Also, if AGENTS.md recommends a registry pattern for agents/tools, consider aligning once this example grows beyond a single agent. Based on learnings, use the established registry patterns for agent and tool management in VoltAgent.
examples/next-js-chatbot-starter-template/voltagent/index.ts (1)
1-3: Consolidate re-exports into a single statement.Optional cleanup
-export { agent } from "./agents"; -export { chatbotAgent } from "./agents"; -export { sharedMemory } from "./agents"; +export { agent, chatbotAgent, sharedMemory } from "./agents";website/docs/ui/assistant-ui.md (2)
120-143: Clarify server process separation requirement.The documentation clearly introduces the separate server process architecture, but it might be helpful to add a brief note earlier (e.g., in the prerequisites or after the agent definition) explaining that VoltAgent now runs in a separate process from the Next.js dev server, which is a change from previous patterns. This sets expectations before users see the new file structure.
Consider adding a short callout like:
Note: VoltAgent now runs as a separate process via the
voltagent:runscript. During development, you'll run bothpnpm dev(Next.js) andpnpm voltagent:run(VoltAgent server) concurrently. This separation enables independent scaling and deployment in production.This could be placed after the agent definition or in the prerequisites section to make the architectural change explicit.
120-143: Clarify the server process separation as an architectural change.The separate-process pattern is introduced correctly, but the architectural shift from in-process to separate server might benefit from an explicit callout earlier in the doc (e.g., after the agent definition or in a prerequisites note). This sets expectations before users encounter the new file structure.
Consider adding a note like:
Architecture Note: VoltAgent now runs as a separate process from your Next.js application. During development, you'll run both
pnpm devandpnpm voltagent:runconcurrently. This decoupling enables independent scaling and deployment in production.Placing this before or after the agent definition would make the pattern explicit upfront.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (33)
examples/next-js-chatbot-starter-template/README.mdexamples/next-js-chatbot-starter-template/app/api/chat/route.tsexamples/next-js-chatbot-starter-template/instrumentation.tsexamples/next-js-chatbot-starter-template/lib/agent/index.tsexamples/next-js-chatbot-starter-template/package.jsonexamples/next-js-chatbot-starter-template/voltagent/agents.tsexamples/next-js-chatbot-starter-template/voltagent/index.tsexamples/next-js-chatbot-starter-template/voltagent/server.tsexamples/with-assistant-ui/README.mdexamples/with-assistant-ui/package.jsonexamples/with-assistant-ui/voltagent/agents.tsexamples/with-assistant-ui/voltagent/index.tsexamples/with-assistant-ui/voltagent/server.tsexamples/with-client-side-tools/README.mdexamples/with-client-side-tools/app/api/chat/route.tsexamples/with-client-side-tools/package.jsonexamples/with-client-side-tools/voltagent/agents.tsexamples/with-client-side-tools/voltagent/index.tsexamples/with-client-side-tools/voltagent/server.tsexamples/with-nextjs-resumable-stream/README.mdexamples/with-nextjs-resumable-stream/package.jsonexamples/with-nextjs-resumable-stream/voltagent/agents.tsexamples/with-nextjs-resumable-stream/voltagent/index.tsexamples/with-nextjs-resumable-stream/voltagent/server.tsexamples/with-nextjs/README.mdexamples/with-nextjs/app/api/chat/route.tsexamples/with-nextjs/app/api/health/route.tsexamples/with-nextjs/package.jsonexamples/with-nextjs/voltagent/agents.tsexamples/with-nextjs/voltagent/index.tsexamples/with-nextjs/voltagent/server.tswebsite/docs/integrations/nextjs.mdwebsite/docs/ui/assistant-ui.md
💤 Files with no reviewable changes (1)
- examples/next-js-chatbot-starter-template/lib/agent/index.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
**/*.ts: Maintain type safety in TypeScript-first codebase
Never use JSON.stringify; use thesafeStringifyfunction instead, imported from@voltagent/internal
Files:
examples/next-js-chatbot-starter-template/voltagent/index.tsexamples/with-nextjs/voltagent/server.tsexamples/with-client-side-tools/voltagent/server.tsexamples/with-nextjs-resumable-stream/voltagent/server.tsexamples/next-js-chatbot-starter-template/instrumentation.tsexamples/next-js-chatbot-starter-template/voltagent/agents.tsexamples/with-nextjs/app/api/health/route.tsexamples/with-nextjs-resumable-stream/voltagent/agents.tsexamples/with-client-side-tools/voltagent/index.tsexamples/with-assistant-ui/voltagent/agents.tsexamples/with-nextjs/voltagent/index.tsexamples/next-js-chatbot-starter-template/voltagent/server.tsexamples/with-assistant-ui/voltagent/index.tsexamples/with-assistant-ui/voltagent/server.tsexamples/with-nextjs/app/api/chat/route.tsexamples/with-client-side-tools/voltagent/agents.tsexamples/with-client-side-tools/app/api/chat/route.tsexamples/with-nextjs/voltagent/agents.tsexamples/with-nextjs-resumable-stream/voltagent/index.tsexamples/next-js-chatbot-starter-template/app/api/chat/route.ts
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: VoltAgent/voltagent PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-07T05:09:23.217Z
Learning: Use the established registry patterns for agent and tool management in VoltAgent
Learnt from: CR
Repo: VoltAgent/voltagent PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-07T05:09:23.217Z
Learning: Always check existing patterns before implementing new features in VoltAgent
📚 Learning: 2026-01-07T05:09:23.216Z
Learnt from: CR
Repo: VoltAgent/voltagent PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-07T05:09:23.216Z
Learning: Applies to **/*.ts : Maintain type safety in TypeScript-first codebase
Applied to files:
examples/with-nextjs/package.jsonexamples/with-nextjs-resumable-stream/package.jsonexamples/with-assistant-ui/package.jsonexamples/next-js-chatbot-starter-template/package.jsonexamples/with-client-side-tools/package.json
📚 Learning: 2026-01-07T05:09:23.217Z
Learnt from: CR
Repo: VoltAgent/voltagent PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-07T05:09:23.217Z
Learning: Use the established registry patterns for agent and tool management in VoltAgent
Applied to files:
examples/with-nextjs/voltagent/server.tsexamples/with-client-side-tools/voltagent/server.tsexamples/with-nextjs-resumable-stream/voltagent/server.tsexamples/with-nextjs/voltagent/index.tsexamples/next-js-chatbot-starter-template/voltagent/server.tsexamples/with-assistant-ui/voltagent/server.tsexamples/with-client-side-tools/voltagent/agents.tswebsite/docs/ui/assistant-ui.mdwebsite/docs/integrations/nextjs.md
📚 Learning: 2026-01-07T05:09:13.519Z
Learnt from: CR
Repo: VoltAgent/voltagent PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-07T05:09:13.519Z
Learning: Always read the `AGENTS.md` file in the root of the repository and apply the instructions to the current task
Applied to files:
examples/with-client-side-tools/voltagent/index.ts
📚 Learning: 2026-01-07T05:09:23.217Z
Learnt from: CR
Repo: VoltAgent/voltagent PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-07T05:09:23.217Z
Learning: Always check existing patterns before implementing new features in VoltAgent
Applied to files:
examples/with-client-side-tools/voltagent/agents.ts
🧬 Code graph analysis (7)
examples/with-nextjs/voltagent/server.ts (1)
packages/server-hono/src/index.ts (1)
honoServer(8-12)
examples/with-client-side-tools/voltagent/server.ts (1)
packages/server-hono/src/index.ts (1)
honoServer(8-12)
examples/with-nextjs-resumable-stream/voltagent/server.ts (1)
packages/server-hono/src/index.ts (1)
honoServer(8-12)
examples/next-js-chatbot-starter-template/instrumentation.ts (1)
examples/with-nestjs/src/app.controller.ts (1)
process(22-39)
examples/with-assistant-ui/voltagent/agents.ts (5)
packages/core/src/tool/index.ts (1)
createTool(259-263)examples/next-js-chatbot-starter-template/voltagent/index.ts (2)
sharedMemory(3-3)agent(1-1)examples/next-js-chatbot-starter-template/lib/agent/index.ts (1)
sharedMemory(2-2)examples/with-client-side-tools/voltagent/agents.ts (1)
agent(40-46)examples/with-nextjs-resumable-stream/voltagent/agents.ts (1)
agent(15-33)
examples/next-js-chatbot-starter-template/voltagent/server.ts (1)
packages/server-hono/src/index.ts (1)
honoServer(8-12)
examples/with-assistant-ui/voltagent/server.ts (1)
packages/server-hono/src/index.ts (1)
honoServer(8-12)
🪛 GitHub Actions: PR Checks
examples/with-nextjs/package.json
[error] 1-1: Specifiers in lockfile do not match package.json dependencies.
examples/with-nextjs-resumable-stream/package.json
[error] 1-1: Specifiers in lockfile do not match package.json dependencies.
examples/with-assistant-ui/package.json
[error] 1-1: Specifiers in lockfile do not match package.json dependencies.
examples/next-js-chatbot-starter-template/package.json
[error] 1-1: Specifiers in lockfile do not match package.json dependencies.
examples/with-client-side-tools/package.json
[error] 1-1: Specifiers in lockfile do not match package.json dependencies.
🪛 markdownlint-cli2 (0.18.1)
website/docs/ui/assistant-ui.md
219-219: Bare URL used
(MD034, no-bare-urls)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: cubic · AI code reviewer
- GitHub Check: Cloudflare Pages
🔇 Additional comments (46)
examples/with-nextjs/package.json (2)
41-41: LGTM! Script aligns with separate-server architecture.The
voltagent:runscript correctly usestsxwith the--env-fileflag to execute the VoltAgent server. This supports the new pattern of running the agent server as a separate process.
29-29: No action needed—the lockfile is already up to date.The
tsxdependency is already present inpnpm-lock.yamland the working tree is clean, indicating the lockfile has already been regenerated and is in sync withpackage.json.Likely an incorrect or invalid review comment.
examples/with-client-side-tools/voltagent/agents.ts (1)
1-46: LGTM! Refactor follows established registry pattern.The removal of the
VoltAgentwrapper and direct export of theAgentinstance aligns with the PR's architectural shift. This decouples agent definitions from server lifecycle, making the code more modular and testable.Based on learnings, this follows the established registry patterns for agent and tool management in VoltAgent.
examples/next-js-chatbot-starter-template/README.md (1)
55-64: LGTM! Clear documentation for the new workflow.The "Run the Example" section provides clear instructions for starting both the Next.js app and the VoltAgent server in separate terminals, which aligns perfectly with the architectural changes in this PR.
examples/with-client-side-tools/README.md (1)
33-41: LGTM! Documentation accurately reflects the new separate-server workflow.The updated instructions clearly guide users to run the VoltAgent server separately and connect to the console, consistent with the architectural changes across all examples in this PR.
examples/with-client-side-tools/voltagent/server.ts (1)
1-10: VoltAgent automatically starts the server on instantiation—the code is correct.The VoltAgent constructor auto-starts the provided server in the background (lines 158–166 of
packages/core/src/voltagent.ts). When aserveroption is passed,startServer()is invoked asynchronously after construction, so no explicit.start()or.listen()call is required. The pattern used in your code is the established convention across all examples in the codebase.examples/with-client-side-tools/package.json (2)
9-9: LGTM! Dependencies align with the separate-server architecture.The additions of
@voltagent/server-honoandtsxalong with thevoltagent:runscript correctly support running VoltAgent as a separate process, aligning with the architectural refactor described in the PR.Also applies to: 22-22, 41-41
1-1: Revert the suggested fix - this is a pnpm monorepo.The repository uses pnpm with a monorepo structure, not npm. Example packages don't have individual lockfiles—the root
pnpm-lock.yamlmanages all dependencies. Runningnpm installin the subdirectory is incompatible with this setup. If lockfile synchronization is needed, the fix ispnpm installat the repository root, which the CI pipeline already handles.Likely an incorrect or invalid review comment.
examples/next-js-chatbot-starter-template/package.json (2)
60-60: LGTM! Dependencies align with the separate-server architecture.The additions of
tsxdevDependency and thevoltagent:runscript correctly support running VoltAgent as a separate process, consistent with the architectural refactor.Also applies to: 73-73
1-1: No lockfile mismatch exists; the pnpm-lock.yaml is already synchronized with package.json.The tsx dependency with specifier
^4.19.3in package.json correctly resolves to version4.20.4in pnpm-lock.yaml, which satisfies the semver range. No pipeline failure related to lockfile mismatch was found, and the working tree is clean with no uncommitted changes. The dependency additions and script are correct.Likely an incorrect or invalid review comment.
examples/next-js-chatbot-starter-template/voltagent/server.ts (1)
5-10: VoltAgent constructor automatically starts the server and provides ashutdown()method for lifecycle management.The API follows the expected pattern: when a server is provided,
new VoltAgent()automatically starts it (line 158-166 inpackages/core/src/voltagent.ts), and the publicshutdown()method provides comprehensive cleanup including stopping the server, suspending workflows, and shutting down telemetry.examples/next-js-chatbot-starter-template/instrumentation.ts (1)
10-14: Documentation for separate VoltAgent server is adequate.The README clearly documents the new architecture on lines 57-62, instructing users to run the Next.js app and VoltAgent server in separate terminals using
pnpm devandpnpm voltagent:run. Thevoltagent:runscript is defined in package.json. The instrumentation.ts comment (line 5) also explicitly states the VoltAgent server "should be started in a separate process." The breaking architectural change is properly documented.examples/with-nextjs/voltagent/index.ts (1)
1-9: LGTM! Clean public API surface.The re-export pattern creates a clean separation between the public API surface (index.ts) and implementation (agents.ts), making the module easier to maintain and consume.
examples/with-nextjs/voltagent/agents.ts (4)
1-4: LGTM! Proper imports.All dependencies are correctly imported and align with the library versions specified in the package.json.
7-32: LGTM! Tools are well-implemented.Both tools follow proper patterns:
- Clear zod schemas for parameters
- Appropriate string processing logic
- Correct return types
48-75: LGTM! Agents are properly configured.All three specialized agents follow consistent patterns:
- Clear, specific instructions
- Appropriate tool assignments
- Shared memory and model configuration
78-85: LGTM! Supervisor pattern correctly implemented.The supervisor agent properly demonstrates parallel delegation to all sub-agents. The emphatic instructions ("MUST delegate to ALL THREE agents") are appropriate for this example, ensuring consistent demonstration of the multi-agent workflow pattern.
examples/with-nextjs/voltagent/server.ts (1)
1-13: LGTM! Correct server bootstrap pattern.The VoltAgent instantiation follows the established registry pattern, with the constructor initializing and starting the server as a side effect. This aligns with the broader refactoring to separate-server architecture demonstrated across multiple examples.
Based on learnings, this matches the established registry patterns for agent management in VoltAgent.
examples/with-assistant-ui/package.json (1)
52-52: LGTM! Script properly configured.The
voltagent:runscript correctly uses tsx with environment file loading to run the separate VoltAgent server process, aligning with the new architecture pattern.examples/with-nextjs-resumable-stream/package.json (2)
69-69: LGTM! Script properly configured.The
voltagent:runscript correctly implements the separate server pattern using tsx with environment file loading.
56-56: Regenerate lockfile to fix pipeline failure.The pipeline is failing because the lockfile doesn't match the new
tsxdependency. You must regenerate the lockfile before merging.Run the following command to fix:
npm installOr if using pnpm/yarn:
pnpm install # or yarn install⛔ Skipped due to learnings
Learnt from: CR Repo: VoltAgent/voltagent PR: 0 File: AGENTS.md:0-0 Timestamp: 2026-01-07T05:09:23.216Z Learning: Applies to **/*.ts : Maintain type safety in TypeScript-first codebaseLearnt from: CR Repo: VoltAgent/voltagent PR: 0 File: AGENTS.md:0-0 Timestamp: 2026-01-07T05:09:23.217Z Learning: Applies to **/*.test.ts : Test your changes - ensure all tests pass before committingexamples/with-client-side-tools/voltagent/index.ts (1)
1-1: LGTM! Clean module pattern.This re-export centralizes the public API surface and follows the established pattern for agent management in VoltAgent.
examples/with-nextjs/app/api/chat/route.ts (1)
1-1: LGTM! Import aligns with centralized architecture.The updated import correctly references the centralized voltagent module, following the established registry patterns for agent management.
Based on learnings: Use the established registry patterns for agent and tool management in VoltAgent.
examples/with-nextjs-resumable-stream/voltagent/server.ts (1)
1-10: LGTM! Standard VoltAgent server setup.This follows the established pattern for initializing VoltAgent with agents and a Hono server provider. The centralized agent definition and server wiring align with the architectural changes in this PR.
Based on learnings: Use the established registry patterns for agent and tool management in VoltAgent.
examples/with-nextjs/README.md (1)
55-64: LGTM! Clear documentation of the new architecture.The documentation accurately reflects the separate-server workflow introduced in this PR, providing clear instructions for running the Next.js app and VoltAgent server concurrently.
examples/next-js-chatbot-starter-template/app/api/chat/route.ts (1)
3-3: LGTM! Import aligns with centralized architecture.The updated import correctly uses the centralized voltagent module, consistent with the established registry patterns for agent management.
Based on learnings: Use the established registry patterns for agent and tool management in VoltAgent.
examples/with-assistant-ui/README.md (2)
5-16: Docs update looks consistent with the new “separate server” architecture; just keep the port reference in sync with server config.If this example changes the server port via
honoServer(...)config (now or later), this line should be updated alongside it.
20-21: Good cross-references tovoltagent/agents.tsandvoltagent/server.ts.This makes the new boundaries discoverable and matches the “centralized agent wiring” direction.
examples/with-assistant-ui/voltagent/server.ts (1)
2-10: Default port 3141 is correctly configured and documented. The code uses 3141 as the fallback default inapp-factory.tswhen no explicit port is provided, and this is consistently shown throughout the changelog examples.examples/with-nextjs-resumable-stream/voltagent/index.ts (1)
1-1: LGTM! Clean re-export pattern.The centralized re-export from
./agentsaligns with the established registry patterns for agent management in VoltAgent and improves module organization.Based on learnings, this follows the established pattern for agent management.
examples/with-nextjs-resumable-stream/voltagent/agents.ts (2)
1-13: LGTM! Clean imports and well-structured instructions.The imports are properly typed and the research instructions are clearly defined. The multi-line string approach with
join("\n")maintains readability.
15-33: LGTM! Well-configured research agent.The PlanAgent configuration is comprehensive and appropriate for a deep research use case. The summarization settings (trigger at 1200 tokens, keep 6 messages) help manage context window effectively, and
virtualMode: trueis appropriate for example code.examples/with-assistant-ui/voltagent/agents.ts (3)
1-15: LGTM! Well-defined schema.The imports are clean and the weather output schema is properly structured with Zod for type safety.
17-40: LGTM! Well-implemented demo tool.The weather tool correctly uses
createToolwith proper schemas and generates appropriate mock data for demonstration purposes. The structured output with message formatting provides good UX.
42-51: LGTM! Clean agent configuration.The assistant agent is properly configured with clear instructions and the weather tool. Exporting both
assistantAgentandagent(as an alias) provides flexibility for different import patterns.examples/with-assistant-ui/voltagent/index.ts (1)
1-2: LGTM! Consistent re-export pattern.The re-exports from
./agentsprovide a clean public API surface and align with the established pattern for agent management in VoltAgent.Based on learnings, this follows the established registry patterns.
website/docs/integrations/nextjs.md (5)
45-53: LGTM! Helpful addition for debugging support.The documentation clearly explains the need for the built-in server dependencies and how they enable debugging through the VoltAgent console.
84-86: LGTM! Clear guidance on environment variables.Good reminder that the separate server process needs access to the same environment variables.
125-129: LGTM! Clear re-export pattern.The documentation correctly shows the centralized export pattern that aligns with the established registry patterns in VoltAgent.
Based on learnings, this demonstrates the established pattern for agent management.
131-156: LGTM! Well-documented API route pattern.The documentation correctly demonstrates:
- Avoiding VoltAgent/honoServer instantiation inside Next.js handlers (prevents port conflicts)
- Using
after()withsetWaitUntilfor non-blocking telemetry export- Clean error handling
158-189: LGTM! Excellent documentation of the separate server pattern.The documentation clearly explains:
- Why to run the server as a separate process (avoids port conflicts with Next.js workers)
- How to set up the server file
- How to configure the npm script with proper env file loading
This aligns well with the PR's objective to move to a separate-server architecture.
website/docs/ui/assistant-ui.md (5)
35-40: Prerequisites look appropriate.The addition of
tsxas a dev dependency is necessary to support the newvoltagent:runscript, and all other dependencies appear correctly specified for both server and client setup.
35-40: Prerequisites and dependencies look correct.The addition of
tsxas a dev dependency (line 36) is appropriate for supporting the newvoltagent:runTypeScript execution pattern. All server and client dependencies are properly specified.
176-181: No changes required. The API chainagent.streamText([...], {...}).toUIMessageStreamResponse({ sendReasoning: true })is correctly implemented and verified across the codebase. Both methods exist and are properly documented as the standard approach for streaming Assistant UI responses. This pattern is confirmed in:
- Production code:
packages/core/src/agent/agent.tsandpackages/server-core/src/handlers/agent.handlers.ts- Example implementations:
examples/with-assistant-ui/app/api/chat/route.tsand multiple other examples- Documentation: Explicitly stated on line 147 as the correct entry point for Assistant UI streaming
44-143: All documented patterns verified as correct and established conventions.The module structure (
voltagent/agents.ts,voltagent/server.ts,voltagent/index.ts), server initialization pattern (new VoltAgent({ agents: { agent }, server: honoServer() })), and API methods (agent.streamText()with.toUIMessageStreamResponse()) are all confirmed across the codebase as established conventions used consistently in all examples. The documentation accurately reflects the current implementation.
176-181: No action needed. Theagent.streamText().toUIMessageStreamResponse()API chain is properly implemented and documented. ThestreamTextmethod on the Agent class returns aStreamTextResultWithContexttype that explicitly includes thetoUIMessageStreamResponsemethod, which is sourced from the AI SDK'sStreamTextResulttype. This API is actively used in production code throughout the VoltAgent packages and is the correct method for streaming Assistant UI messages.Likely an incorrect or invalid review comment.
| new VoltAgent({ | ||
| agents: { | ||
| agent, | ||
| }, | ||
| server: honoServer(), | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Add error handling and lifecycle management.
The VoltAgent instance is created but not assigned or managed, which can lead to issues:
- No error handling: If initialization fails, the process crashes without meaningful error messages
- No graceful shutdown: The server won't clean up resources on SIGTERM/SIGINT
- No reference to instance: Cannot access or manage the VoltAgent instance after creation
♻️ Add error handling and lifecycle management
-new VoltAgent({
+const voltAgent = new VoltAgent({
agents: {
agent,
},
server: honoServer(),
});
+
+// Graceful shutdown
+process.on("SIGTERM", async () => {
+ console.log("SIGTERM received, shutting down gracefully");
+ await voltAgent.shutdown?.();
+ process.exit(0);
+});
+
+process.on("SIGINT", async () => {
+ console.log("SIGINT received, shutting down gracefully");
+ await voltAgent.shutdown?.();
+ process.exit(0);
+});
+
+process.on("unhandledRejection", (reason, promise) => {
+ console.error("Unhandled Rejection at:", promise, "reason:", reason);
+ process.exit(1);
+});📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| new VoltAgent({ | |
| agents: { | |
| agent, | |
| }, | |
| server: honoServer(), | |
| }); | |
| const voltAgent = new VoltAgent({ | |
| agents: { | |
| agent, | |
| }, | |
| server: honoServer(), | |
| }); | |
| // Graceful shutdown | |
| process.on("SIGTERM", async () => { | |
| console.log("SIGTERM received, shutting down gracefully"); | |
| await voltAgent.shutdown?.(); | |
| process.exit(0); | |
| }); | |
| process.on("SIGINT", async () => { | |
| console.log("SIGINT received, shutting down gracefully"); | |
| await voltAgent.shutdown?.(); | |
| process.exit(0); | |
| }); | |
| process.on("unhandledRejection", (reason, promise) => { | |
| console.error("Unhandled Rejection at:", promise, "reason:", reason); | |
| process.exit(1); | |
| }); |
🤖 Prompt for AI Agents
In @examples/next-js-chatbot-starter-template/voltagent/server.ts around lines 5
- 10, Assign the VoltAgent instance to a variable (e.g., const voltagent = new
VoltAgent(...)) and wrap creation/initialization in a try/catch to log errors
via console.error and exit(1) on failure; after successful creation, add signal
handlers for SIGINT and SIGTERM that call the instance's cleanup method (e.g.,
voltagent.shutdown() or voltagent.close() — check which API exists) and then
process.exit, and ensure any async init (if VoltAgent exposes init/start) is
awaited before registering handlers so the instance reference is valid for
graceful shutdown.
| @@ -1,4 +1,4 @@ | |||
| import { agent } from "@/lib/agent"; | |||
| import { agent } from "@/voltagent"; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Read the route.ts file to see actual code and confirm JSON.stringify usage
echo "=== Reading route.ts file ==="
cat -n examples/with-client-side-tools/app/api/chat/route.ts | head -30
# 2) Check the voltagent module structure in the example
echo -e "\n=== Exploring voltagent module in example ==="
find examples/with-client-side-tools -name "*.ts" -o -name "*.js" | grep -E "(voltagent|index)" | head -20
# 3) Verify safeStringify is available in the codebase
echo -e "\n=== Searching for safeStringify usage ==="
rg -n "safeStringify" --type=ts -B2 -A2 | head -30Repository: VoltAgent/voltagent
Length of output: 3331
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Reading voltagent/index.ts ==="
cat -n examples/with-client-side-tools/voltagent/index.ts
echo -e "\n=== Reading voltagent/agents.ts (first 30 lines) ==="
head -30 examples/with-client-side-tools/voltagent/agents.ts
echo -e "\n=== Checking for safeStringify import patterns in examples ==="
rg -n "safeStringify" examples/ --type=ts || echo "No safeStringify found in examples"
echo -e "\n=== Checking @voltagent/internal availability in example ==="
fd -a package.json examples/with-client-side-tools | xargs cat | grep -A5 -B5 "@voltagent" || echo "Checking package structure..."Repository: VoltAgent/voltagent
Length of output: 2851
Replace JSON.stringify with safeStringify from @voltagent/internal
This file violates the TypeScript guideline which requires using safeStringify instead of JSON.stringify. Import it and use it for the error response at lines 16-18:
import { safeStringify } from "@voltagent/internal";
Then replace JSON.stringify({...}) with safeStringify({...}) in the error handler.
🤖 Prompt for AI Agents
In @examples/with-client-side-tools/app/api/chat/route.ts at line 1, The error
response uses JSON.stringify directly; import safeStringify from
"@voltagent/internal" (add: import { safeStringify } from "@voltagent/internal";
alongside the existing import of agent) and replace JSON.stringify({...}) with
safeStringify({...}) in the error handler where the response body is created
(the error response block that currently calls JSON.stringify). Ensure you only
change the import and the serializer call (leave the payload object unchanged).
| ## Run the Example | ||
|
|
||
| Run the Next.js app and the VoltAgent built-in server in separate terminals: | ||
|
|
||
| ```bash | ||
| pnpm dev | ||
| pnpm voltagent:run | ||
| ``` | ||
|
|
||
| Then open `https://console.voltagent.dev` and connect it to `http://localhost:3141`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarify “separate terminals” by splitting the commands into two blocks.
Right now it’s easy to run both commands in the same terminal by mistake.
Proposed doc tweak
Run the Next.js app and the VoltAgent built-in server in separate terminals:
```bash
-pnpm dev
-pnpm voltagent:run
+# Terminal 1
+pnpm dev+bash +# Terminal 2 +pnpm voltagent:run +
+
Then open https://console.voltagent.dev and connect it to http://localhost:3141.
</details>
<details>
<summary>🤖 Prompt for AI Agents</summary>
In @examples/with-nextjs-resumable-stream/README.md around lines 55 - 64, The
instructions currently list both commands together and risk people running them
in one terminal; update the README to split the commands into two separate code
blocks and label them (e.g., "Terminal 1" with the pnpm dev command and
"Terminal 2" with the pnpm voltagent:run command) so readers clearly run pnpm
dev and pnpm voltagent:run in different terminals.
</details>
<!-- This is an auto-generated comment by CodeRabbit -->
| pnpm voltagent:run | ||
| ``` | ||
|
|
||
| Open http://localhost:3000 and chat—the UI will stream reasoning and messages from your VoltAgent agent. Attachments and thread persistence are handled automatically via the VoltAgent memory adapter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrap bare URLs in markdown link or code format.
The bare URLs on lines 219 and 221 violate the markdownlint rule MD034 (no-bare-urls). Wrap them in markdown link syntax or inline code blocks.
🔗 Proposed fix for bare URLs
-Open http://localhost:3000 and chat—the UI will stream reasoning and messages from your VoltAgent agent. Attachments and thread persistence are handled automatically via the VoltAgent memory adapter.
+Open [`http://localhost:3000`](http://localhost:3000) and chat—the UI will stream reasoning and messages from your VoltAgent agent. Attachments and thread persistence are handled automatically via the VoltAgent memory adapter.
-For debugging, open `https://console.voltagent.dev` and connect it to `http://localhost:3141`.
+For debugging, open [`https://console.voltagent.dev`](https://console.voltagent.dev) and connect it to [`http://localhost:3141`](http://localhost:3141).Also applies to: 221-221
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
219-219: Bare URL used
(MD034, no-bare-urls)
🤖 Prompt for AI Agents
In @website/docs/ui/assistant-ui.md at line 219, Wrap the bare URLs in the
markdown text so MD034 is satisfied: replace occurrences of the raw URL (e.g.,
http://localhost:3000 mentioned in the sentence that starts "Open
http://localhost:3000 and chat…") and the other bare URL on the adjacent line
with either markdown link syntax [http://localhost:3000](http://localhost:3000)
or inline code `http://localhost:3000` (do the same for the URL on the other
line) so the links remain visible but are no longer bare.
Wrap bare URLs to comply with markdownlint.
Lines 219 and 221 contain bare URLs that violate the MD034 rule (no-bare-urls). Wrap them in markdown link syntax.
🔗 Proposed fix for bare URLs
-Open http://localhost:3000 and chat—the UI will stream reasoning and messages from your VoltAgent agent. Attachments and thread persistence are handled automatically via the VoltAgent memory adapter.
+Open [`http://localhost:3000`](http://localhost:3000) and chat—the UI will stream reasoning and messages from your VoltAgent agent. Attachments and thread persistence are handled automatically via the VoltAgent memory adapter.
-For debugging, open `https://console.voltagent.dev` and connect it to `http://localhost:3141`.
+For debugging, open [`https://console.voltagent.dev`](https://console.voltagent.dev) and connect it to [`http://localhost:3141`](http://localhost:3141).Also applies to: 221-221
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
219-219: Bare URL used
(MD034, no-bare-urls)
🤖 Prompt for AI Agents
In @website/docs/ui/assistant-ui.md at line 219, The markdown contains bare URLs
(e.g., the phrase "Open http://localhost:3000 and chat" and the other occurrence
on the same page) that violate MD034; replace those bare URLs with markdown link
syntax like [http://localhost:3000](http://localhost:3000) (or a descriptive
label such as [Localhost:3000](http://localhost:3000)) in the assistant-ui.md
content where the "Open http://localhost:3000 and chat" sentence and the other
URL occurrence appear so both instances (lines around 219 and 221) are wrapped
as proper markdown links.
Deploying voltagent with
|
| Latest commit: |
ebb4db4
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://a4328e46.voltagent.pages.dev |
| Branch Preview URL: | https://feat-update-nextjs.voltagent.pages.dev |
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
Standardized Next.js examples to run the VoltAgent built-in server as a separate process and adopted a consistent agent export pattern for simpler setup and more reliable debugging via console.voltagent.dev.
Refactors
Dependencies
Written for commit ebb4db4. Summary will update on new commits.
Summary by CodeRabbit
New Features
Documentation
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.