Skip to content

[codex] Add Bocha web search example#1341

Open
NiTingKY wants to merge 2 commits into
VoltAgent:mainfrom
NiTingKY:codex/add-bocha-search-example
Open

[codex] Add Bocha web search example#1341
NiTingKY wants to merge 2 commits into
VoltAgent:mainfrom
NiTingKY:codex/add-bocha-search-example

Conversation

@NiTingKY

@NiTingKY NiTingKY commented Jun 15, 2026

Copy link
Copy Markdown

Summary

Adds a runnable Bocha Web Search example for VoltAgent.

Changes

  • Added examples/with-bocha-search with a bochaSearch typed tool.
  • Added request-building and response-mapping helpers for Bocha web page results.
  • Added setup docs and .env.example for BOCHA_SEARCH_API_KEY and optional BOCHA_SEARCH_API_URL.
  • Added focused tests for request clamping/domain filters and source-linked response mapping.

Validation

  • pnpm exec vitest run --config examples/with-bocha-search/vitest.config.ts
  • pnpm --filter voltagent-example-with-bocha-search build
  • pnpm biome check examples/with-bocha-search
  • pnpm install --frozen-lockfile --ignore-scripts --offline --reporter=append-only
  • Local dev server smoke: pnpm --filter voltagent-example-with-bocha-search dev, verified http://localhost:3141 returned HTTP 200.
  • Missing-key smoke: invoking bochaSearchTool.execute(...) without BOCHA_SEARCH_API_KEY returns a clear configuration error.

Notes

No real API keys are committed. A live Bocha API query was not run in this environment because BOCHA_SEARCH_API_KEY was not configured.


Summary by cubic

Adds a runnable Bocha Web Search example for VoltAgent. It includes a bochaSearch typed tool, helpers, docs, and tests so agents can fetch current, source-linked results.

  • New Features

    • examples/with-bocha-search with a bochaSearch tool wired into a searchAgent using @voltagent/core and @voltagent/server-hono.
    • Helpers: request builder (clamps count to 10, supports freshness and include/exclude domains) and response mapper (normalizes title/link/snippet/source/publishedDate).
    • Env + docs: .env.example with BOCHA_SEARCH_API_KEY and optional BOCHA_SEARCH_API_URL, plus README with setup/run instructions.
    • Tests: vitest coverage for count clamping, domain filters, source-linked mapping, and clear error when the API key is missing.
  • Bug Fixes

    • Set https://api.bochaai.com/v1/web-search as the default endpoint when BOCHA_SEARCH_API_URL is not set; added a test to verify the default is used.

Written for commit 254c3d9. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added a new with-bocha-search example integrating Bocha Web Search as a typed tool inside a VoltAgent.
  • Documentation
    • Added an example README with setup, environment variables, run commands, and example queries.
    • Added an .env.example template for required/optional API settings.
  • Tests
    • Added Vitest coverage for request/response normalization and tool execution behavior (including mocked fetch).
  • Chores
    • Added example project configuration (package metadata, TypeScript, Vitest).

@changeset-bot

changeset-bot Bot commented Jun 15, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 254c3d9

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

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

Click here to learn what changesets are, and how to add one.

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

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a0b9edb6-69b3-445a-b29d-96d313c024b8

📥 Commits

Reviewing files that changed from the base of the PR and between c99790e and 254c3d9.

📒 Files selected for processing (4)
  • examples/with-bocha-search/.env.example
  • examples/with-bocha-search/README.md
  • examples/with-bocha-search/src/tools.spec.ts
  • examples/with-bocha-search/src/tools.ts
✅ Files skipped from review due to trivial changes (1)
  • examples/with-bocha-search/.env.example
🚧 Files skipped from review as they are similar to previous changes (3)
  • examples/with-bocha-search/README.md
  • examples/with-bocha-search/src/tools.spec.ts
  • examples/with-bocha-search/src/tools.ts

📝 Walkthrough

Walkthrough

Adds a new examples/with-bocha-search package that integrates the Bocha Web Search API into a VoltAgent agent as a typed tool. The package includes TypeScript types and helpers for Bocha request/response mapping, a Zod-schemed bochaSearchTool, a VoltAgent agent bootstrap, Vitest tests, and full project configuration files.

Changes

Bocha Web Search VoltAgent Example

Layer / File(s) Summary
Project scaffolding and docs
examples/with-bocha-search/package.json, examples/with-bocha-search/tsconfig.json, examples/with-bocha-search/vitest.config.ts, examples/with-bocha-search/.env.example, examples/with-bocha-search/README.md
Defines package identity, npm scripts, TypeScript compilation config, Vitest test discovery, required environment variable placeholders, and developer setup/run/test instructions.
Bocha API types and helpers
examples/with-bocha-search/src/bocha.ts
Exports BochaSearchInput, BochaSearchRequest, BochaSearchResponse, and BochaSearchResult types, plus buildBochaSearchRequest (defaults, result count clamping, pipe-delimited domain filtering) and mapBochaSearchResponse (safe field extraction with title/snippet/date fallbacks).
bochaSearchTool schemas and execute logic
examples/with-bocha-search/src/tools.ts, examples/with-bocha-search/src/tools.spec.ts
Defines Zod schemas for tool input and output, implements the exported bochaSearchTool with env-driven credentials, authenticated POST fetch, result mapping/slicing, structured success/failure payloads, and error handling. Vitest tests validate request normalization, response mapping, and API endpoint calls.
Agent bootstrap
examples/with-bocha-search/src/index.ts
Initializes Pino logger and LibSQL-backed Memory, instantiates the searchAgent with bochaSearchTool, and registers it in VoltAgent with honoServer().

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Poem

🐇 A rabbit hops through the web each day,
Searching for results without delay—
Bocha's keys unlock the gate,
buildBochaSearchRequest sets it straight!
With Zod schemas crisp and bright,
The agent finds answers overnight. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title '[codex] Add Bocha web search example' clearly and concisely summarizes the main change—adding a new Bocha web search example to the VoltAgent project.
Description check ✅ Passed The PR description is comprehensive and covers the required template sections: summary of changes, validation steps performed, and notes about API key security. It directly addresses what was added and how it was tested.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

❤️ Share

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

@NiTingKY NiTingKY marked this pull request as ready for review June 15, 2026 03:47

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

2 issues found across 10 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread examples/with-bocha-search/src/tools.ts
Comment thread examples/with-bocha-search/src/bocha.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
examples/with-bocha-search/src/bocha.ts (1)

62-69: ⚡ Quick win

Clamp count to a minimum bound in buildBochaSearchRequest.

Line 63 only enforces the max bound. Because this helper is exported, direct callers can pass 0/negative values and produce invalid request counts.

Suggested patch
 export function buildBochaSearchRequest(input: BochaSearchInput): BochaSearchRequest {
-  const count = Math.min(input.count ?? DEFAULT_RESULT_COUNT, MAX_RESULT_COUNT);
+  const requestedCount = input.count ?? DEFAULT_RESULT_COUNT;
+  const count = Math.max(1, Math.min(requestedCount, MAX_RESULT_COUNT));
   const request: BochaSearchRequest = {
     query: input.query,
     freshness: input.freshness ?? "noLimit",
     summary: true,
     count,
   };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/with-bocha-search/src/bocha.ts` around lines 62 - 69, The
buildBochaSearchRequest function only enforces a maximum bound on count using
Math.min(), allowing 0 or negative values to pass through when callers provide
them directly. Update the count calculation to also enforce a minimum bound
using Math.max() alongside the existing Math.min() call, ensuring that count
cannot fall below a minimum threshold (such as 1) while still respecting the
maximum bound.
examples/with-bocha-search/src/tools.spec.ts (1)

5-22: ⚡ Quick win

Add a regression case for non-positive count normalization.

Current tests assert max clamping, but not lower-bound behavior. Add coverage for count: 0 (and/or negative) to lock in safe request normalization.

Suggested test addition
 describe("Bocha search tool helpers", () => {
   it("builds a conservative Bocha search request", () => {
@@
   });
+
+  it("normalizes non-positive count to minimum bound", () => {
+    expect(
+      buildBochaSearchRequest({
+        query: "agent news",
+        count: 0,
+      }),
+    ).toMatchObject({
+      query: "agent news",
+      count: 1,
+    });
+  });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/with-bocha-search/src/tools.spec.ts` around lines 5 - 22, The test
suite for buildBochaSearchRequest currently only covers positive count values
with max clamping, but lacks coverage for non-positive (zero or negative) count
values. Add a new test case that invokes buildBochaSearchRequest with count: 0
or a negative number and verifies that the function normalizes this to a safe
minimum value, ensuring proper lower-bound behavior in the request normalization
logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/with-bocha-search/package.json`:
- Around line 14-17: The example package.json is missing dependencies required
to run its test suite independently. Add the vitest package with version
"^3.2.4" to the devDependencies section alongside the existing `@types/node`, tsx,
and typescript entries. Additionally, add a "test" script to the scripts section
that runs the vitest command. This ensures the example can execute its
vitest.config.ts configuration and src/tools.spec.ts test file without relying
on the workspace root.

In `@examples/with-bocha-search/src/tools.ts`:
- Around line 72-80: Add a default timeout mechanism for the fetch call in the
Bocha API request handler. When options.abortSignal is not provided, create an
AbortController with a reasonable timeout value (e.g., 30 seconds) and use its
signal in the fetch call. This ensures the fetch operation will not hang
indefinitely if no explicit abort signal is passed through options. Store the
abort controller conditionally so you can use its signal in the fetch options,
falling back to options?.abortSignal if it exists.

In `@examples/with-bocha-search/tsconfig.json`:
- Around line 3-5: The moduleResolution setting in tsconfig.json is set to
"bundler" which allows extensionless imports, but the example is executed with
plain node command on the compiled dist output, and Node's ESM runtime cannot
resolve extensionless imports like "./tools" or "./bocha". Change the
moduleResolution value from "bundler" to "NodeNext" to align TypeScript's module
resolution with Node's ESM resolution behavior, or alternatively update all
source file imports to explicitly include .js file extensions before the build
step.

---

Nitpick comments:
In `@examples/with-bocha-search/src/bocha.ts`:
- Around line 62-69: The buildBochaSearchRequest function only enforces a
maximum bound on count using Math.min(), allowing 0 or negative values to pass
through when callers provide them directly. Update the count calculation to also
enforce a minimum bound using Math.max() alongside the existing Math.min() call,
ensuring that count cannot fall below a minimum threshold (such as 1) while
still respecting the maximum bound.

In `@examples/with-bocha-search/src/tools.spec.ts`:
- Around line 5-22: The test suite for buildBochaSearchRequest currently only
covers positive count values with max clamping, but lacks coverage for
non-positive (zero or negative) count values. Add a new test case that invokes
buildBochaSearchRequest with count: 0 or a negative number and verifies that the
function normalizes this to a safe minimum value, ensuring proper lower-bound
behavior in the request normalization logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e430b03e-bf48-49fe-a3be-a5bbb71c844d

📥 Commits

Reviewing files that changed from the base of the PR and between 1e1af65 and c99790e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • examples/with-bocha-search/.env.example
  • examples/with-bocha-search/README.md
  • examples/with-bocha-search/package.json
  • examples/with-bocha-search/src/bocha.ts
  • examples/with-bocha-search/src/index.ts
  • examples/with-bocha-search/src/tools.spec.ts
  • examples/with-bocha-search/src/tools.ts
  • examples/with-bocha-search/tsconfig.json
  • examples/with-bocha-search/vitest.config.ts

Comment thread examples/with-bocha-search/package.json
Comment thread examples/with-bocha-search/src/tools.ts
Comment thread examples/with-bocha-search/tsconfig.json
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant