Skip to content

feat: add nansen web search and nansen web fetch commands (ECINT-6393)#295

Merged
kome12 merged 9 commits intomainfrom
ecint-6393-add-web_search-web_fetch-to-cli
Mar 16, 2026
Merged

feat: add nansen web search and nansen web fetch commands (ECINT-6393)#295
kome12 merged 9 commits intomainfrom
ecint-6393-add-web_search-web_fetch-to-cli

Conversation

@kome12
Copy link
Contributor

@kome12 kome12 commented Mar 13, 2026

Summary

Adds two new top-level CLI commands backed by the internal /api/v1/search/web-search and /api/v1/search/web-fetch endpoints.

Commands

nansen web-search

nansen web-search "bitcoin price"
nansen web-search "solana news" --num-results 5
nansen web-search --query "btc" --query "eth"   # repeated flag
nansen web-search "btc" --query "eth"            # positional + flag merged

nansen web-fetch

nansen web-fetch https://nansen.ai --question "What does Nansen do?"
nansen web-fetch --url https://a.com --url https://b.com --question "Compare?"
nansen web-fetch https://a.com --url https://b.com --question "Diff?"  # positional + flag merged

Changes

  • src/api.jswebSearch() and webFetch() API methods
  • src/cli.js — command handlers + HELP banner entries + NaN guard for --num-results
  • src/schema.json — command metadata
  • skills/nansen-web-search/SKILL.md — agent skill file
  • skills/nansen-web-fetch/SKILL.md — agent skill file
  • src/__tests__/cli.internal.test.js — 18 new tests covering all parameter combinations (incl. NaN guard)
  • src/__tests__/telemetry-tracking.test.js — telemetry coverage for both commands
  • .changeset/add-web-search-web-fetch.md — minor version bump

Test output

Test Files  20 passed (20)
Tests       1049 passed | 2 skipped (1051)
Duration    20.55s

Closes ECINT-6393

Ko Miyatake (Openclaw Bot) added 3 commits March 13, 2026 03:53
…6393)

- POST /api/v1/search/web-search — parallel web search via Serper
- POST /api/v1/search/web-fetch — fetch + AI analysis of URLs via Gemini
- Both commands accept positional args or --query/--url flags
- web-search: supports --num-results (1-20, default 10)
- web-fetch: requires --question for AI analysis prompt
- Updated schema.json, HELP banner, telemetry tracking tests, changeset
@nansen-pr-reviewer
Copy link

nansen-pr-reviewer bot commented Mar 13, 2026

pr-reviewer Summary

📝 2 findings

Review completed. Please address the findings below.

Findings by Severity

Severity Count
🟡 Medium 1
🔵 Low 1

Review effort: 3/5 (Moderate)

Summary

This PR adds nansen web search and nansen web fetch as subcommands under a new nansen web group, following existing codebase patterns well. Tests are comprehensive, schema.json is correctly updated per CLAUDE.md requirements, and validation logic (NaN guard, URL scheme check, empty query/URL filtering) is solid. Two issues are worth addressing before or after merge.

Findings

src/cli.js — Medium: nansen web search --help / nansen web fetch --help do not surface option descriptions or examples

The commit e13f1c5 fix: show options and examples in --help added rendering of cmdSchema.options and cmdSchema.examples to the command-level help block (reached via nansen web --help). However, nansen web search --help and nansen web fetch --help are handled by the pre-existing generateSubcommandHelp() function (lines 1491–1531), which takes a different code path that:

  • Does not include opt.description in the params list
  • Does not use subSchema.examples

So running nansen web search --help produces:

web search — Search the web for one or more queries in parallel
Params (* required): --query, --num-results (10)
Example: nansen web search

…with no option descriptions and no examples, despite the rich documentation in schema.json. The schema effort is essentially invisible to users hitting --help on the subcommand. The fix is to extend generateSubcommandHelp to include opt.description in the param list and append subSchema.examples when present — the same logic added for the command-level path.


src/cli.js — Low: No CLI-level maximum URL count enforcement for web fetch

skills/nansen-web-fetch/SKILL.md documents a limit of 20 URLs, but the fetch handler only checks that at least one URL is present. Supplying 21+ URLs will hit the API and return a backend error rather than a clean, user-friendly CLI validation message.

Suggested fix:

if (urls.length > 20) {
  throw new NansenError('Too many URLs: maximum 20 allowed per request', ErrorCode.INVALID_PARAMS);
}

Token usage: 17 input, 16,140 output, 256,620 cache read, 41,625 cache write

src/cli.js Outdated
trade quote, execute
wallet create, list, show, export, default, delete, forget-password
alerts list, create, update, toggle, delete
web-search Search the web for one or more queries
Copy link
Contributor

Choose a reason for hiding this comment

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

💭 How about web with web search and web fetch?

@kome12 kome12 self-assigned this Mar 13, 2026
Per Tim's feedback: replace flat top-level `web-search`/`web-fetch` commands
with a `web` group: `nansen web search` / `nansen web fetch`.

Also adds --num-results range validation (1-20) with INVALID_PARAM error for
out-of-range values (previously passed through to API silently).

Changes:
- src/cli.js: `web` handler with `search` and `fetch` subcommands; range check
- src/schema.json: `web.subcommands.{search,fetch}` structure
- src/__tests__/cli.internal.test.js: updated tests + 2 new range tests
- src/__tests__/telemetry-tracking.test.js: updated command references
- skills/nansen-web-{search,fetch}/SKILL.md: updated command syntax
@kome12 kome12 marked this pull request as ready for review March 16, 2026 00:37
Copy link
Contributor

@0xlaveen 0xlaveen left a comment

Choose a reason for hiding this comment

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

Nice clean PR! Tested the tools end-to-end and everything works well. A few minor nits for polish:

1. Empty string query passes client validation
nansen web search "" passes the queries.length === 0 check (length is 1) and gets a 422 from the API. Suggestion: queries = queries.filter(q => q.trim()) before the length check.

2. Invalid URLs not validated client side
nansen web fetch "not-a-url" --question "test" passes the CLI and gets a generic 422. A quick new URL(u) try/catch or startsWith('http') guard would give a clearer local error.

3. Wrong error code for --num-results out of range
nansen web search "test" --num-results 0 returns "code":"UNKNOWN" instead of INVALID_PARAM. The throw uses ErrorCode.INVALID_PARAM but it maps to UNKNOWN in the output. Minor since the message is clear, but worth fixing for programmatic consumers.

4. Whitespace only --question passes validation (API side)
The question field uses min_length=1 which only checks character count. " " (spaces) passes validation, burns a Gemini API call, and returns a useless response. Fix: add strip_whitespace=True to the Pydantic field, or a custom validator that strips then checks length. One liner.

- Filter empty/whitespace queries before length check so 'nansen web search ""' fails with a clear error
- Add client-side URL validation via new URL() to catch bare strings like 'not-a-url' before hitting the API
- Fix ErrorCode.INVALID_PARAM → ErrorCode.INVALID_PARAMS (trailing s) for --num-results range check
- Validate --question is not blank/whitespace-only (client-side guard)
- Add 6 new tests covering the above cases (371 total, all passing)
TimNooren
TimNooren previously approved these changes Mar 16, 2026
@kome12 kome12 changed the title feat: add nansen web-search and nansen web-fetch commands (ECINT-6393) feat: add nansen web search and nansen web fetch commands (ECINT-6393) Mar 16, 2026
- Remove 'Internal-only endpoint' from both skill descriptions
- Update web-fetch reference in nansen-web-search SKILL.md to use correct 'nansen web fetch' command syntax
@kome12 kome12 merged commit e811e30 into main Mar 16, 2026
7 checks passed
@kome12 kome12 deleted the ecint-6393-add-web_search-web_fetch-to-cli branch March 16, 2026 10:02
@github-actions github-actions bot mentioned this pull request Mar 16, 2026
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.

3 participants