← Back to PRs

#15117: feat: add Kimi (Moonshot AI) as web_search provider

by adshine open 2026-02-13 02:03 View on GitHub →
agents stale size: M
## Summary Adds **Kimi** (by [Moonshot AI](https://platform.moonshot.ai/)) as a fourth `web_search` provider, alongside Brave, Perplexity, and Grok. Kimi's API includes a **native built-in `$web_search` tool** — the model performs real-time web searches server-side and synthesizes answers with citations, similar to how the Grok provider works. This means users who already have a Kimi/Moonshot API key get web search for free, without needing a separate Brave Search API key. ## How it works Kimi's `$web_search` uses a **two-turn conversation flow** (unlike Grok's single-shot): 1. **Turn 1**: Send the query with `tools: [{type: "builtin_function", function: {name: "$web_search"}}]` - Kimi performs the search server-side and returns `finish_reason: "tool_calls"` with a `search_id` 2. **Turn 2**: Echo back the assistant message (with `reasoning_content` — required by Kimi's reasoning mode) and the tool result - Kimi synthesizes a final answer from the search results and returns `content` with citations If Kimi answers directly without searching (e.g., for simple queries), the implementation handles that too — it checks `finish_reason` and returns immediately. ### API compatibility note Kimi has two API endpoints: - `https://api.moonshot.cn/v1` — Standard Moonshot API (uses `MOONSHOT_API_KEY`) - `https://api.kimi.com/coding/v1` — Kimi for Coding API (uses `KIMI_API_KEY` / `sk-kimi-*` keys) Both support `$web_search`. The default `baseUrl` is `api.moonshot.cn/v1`, but users with Kimi for Coding keys can override via `tools.web.search.kimi.baseUrl`. ## Configuration ```json5 { tools: { web: { search: { provider: "kimi", kimi: { apiKey: "your-kimi-or-moonshot-api-key", // or set KIMI_API_KEY / MOONSHOT_API_KEY env baseUrl: "https://api.moonshot.cn/v1", // optional, default shown model: "moonshot-v1-128k", // optional, default shown }, }, }, }, } ``` Environment variable fallback chain: config `apiKey` → `KIMI_API_KEY` → `MOONSHOT_API_KEY` ## Changes - **`src/config/types.tools.ts`** — Added `"kimi"` to the provider union type and `kimi` config block - **`src/agents/tools/web-search.ts`** — Full provider implementation following existing patterns: - `resolveKimiConfig`, `resolveKimiApiKey`, `resolveKimiModel`, `resolveKimiBaseUrl` - `runKimiSearch` with two-turn `$web_search` flow - Cache key, description, API key resolution, and dispatch integrated into `createWebSearchTool` - **`src/agents/tools/web-search.test.ts`** — 9 new tests for config resolution (API key fallback chain, model defaults, baseUrl defaults) ## Test plan - [x] All 34 unit tests pass (`pnpm vitest run src/agents/tools/web-search.test.ts`) - [x] TypeScript compiles with zero errors (`tsc --noEmit`) - [x] Lint passes (`oxlint --type-aware`) - [x] Live-tested against Kimi API — confirmed two-turn $web_search flow produces real search results - [ ] Verify with `provider: "kimi"` in a running Gateway session ## AI-assisted PR - Built with Claude Opus 4.6 - Fully tested (unit + live API integration) - Author understands the code and verified the implementation against Kimi's API behavior 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR adds a new `web_search` provider (`kimi`) alongside Brave, Perplexity, and Grok by extending the provider union/config types and wiring a new `runKimiSearch` implementation into `createWebSearchTool` dispatch. Implementation-wise, Kimi is modeled as a 2-turn tool-calling flow against a `/chat/completions` endpoint using a builtin `$web_search` tool, with config resolution for apiKey/model/baseUrl and caching integrated into the existing web-search cache. <h3>Confidence Score: 3/5</h3> - This PR is close to mergeable, but the Kimi 2-turn tool-calling flow likely won’t work as implemented. - Most changes are additive and follow existing patterns (provider selection, config typing, cache integration, unit tests for config resolution). However, the Kimi second-turn request appears to send tool-call arguments instead of tool results, which would break the intended web-search synthesis behavior. - src/agents/tools/web-search.ts <sub>Last reviewed commit: f2e5652</sub> <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs