[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-94611":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":16,"stars30d":17,"stars90d":15,"forks30d":15,"starsTrendScore":15,"compositeScore":18,"rankGlobal":9,"rankLanguage":9,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":20,"hasPages":20,"topics":22,"createdAt":9,"pushedAt":9,"updatedAt":23,"readmeContent":24,"aiSummary":25,"trendingCount":15,"starSnapshotCount":15,"syncStatus":26,"lastSyncTime":27,"discoverSource":28},94611,"chatbot-template","shadcn-ui\u002Fchatbot-template","shadcn-ui","A minimal chatbot template built with Next.js, AI SDK, shadcn\u002Fui, shadcn\u002Freact, shadcn\u002Ftypeset. It runs on the Vercel AI Gateway.",null,"TypeScript",708,64,260,7,0,14,448,66.44,"MIT License",false,"main",[],"2026-08-24 04:01:22","# chatbot-template\n\nA minimal chatbot template built with Next.js, the [AI SDK](https:\u002F\u002Fai-sdk.dev), [shadcn\u002Fui](https:\u002F\u002Fui.shadcn.com), [shadcn\u002Freact](https:\u002F\u002Fui.shadcn.com\u002Fdocs\u002Freact\u002Fmessage-scroller), [shadcn\u002Ftypeset](https:\u002F\u002Fui.shadcn.com\u002Fdocs\u002Ftypeset) and the [Vercel AI Gateway](https:\u002F\u002Fvercel.com\u002Fdocs\u002Fai-gateway).\n\n\u003Cp>\n  \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fshadcn-ui\u002Fchatbot-template\u002Fstargazers\">\u003Cimg src=\"https:\u002F\u002Fshieldcn.dev\u002Fgithub\u002Fstars\u002Fshadcn-ui\u002Fchatbot-template.svg?variant=secondary&size=xs\" alt=\"GitHub stars\" \u002F>\u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fshadcn-ui\u002Fchatbot-template\u002Fforks\">\u003Cimg src=\"https:\u002F\u002Fshieldcn.dev\u002Fgithub\u002Fforks\u002Fshadcn-ui\u002Fchatbot-template.svg?variant=secondary&size=xs\" alt=\"GitHub forks\" \u002F>\u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fshadcn-ui\u002Fchatbot-template\u002Fblob\u002Fmain\u002FLICENSE\">\u003Cimg src=\"https:\u002F\u002Fshieldcn.dev\u002Fgithub\u002Flicense\u002Fshadcn-ui\u002Fchatbot-template.svg?variant=secondary&size=xs\" alt=\"License\" \u002F>\u003C\u002Fa>\n\u003C\u002Fp>\n\n## Features\n\n- Streaming chat with markdown rendering and shadcn\u002Ftypeset\n- Tool calling example\n- Web search via each provider's built-in search tool\n- Human-in-the-loop questionnaire. The model can ask clarifying questions, answered with the shadcn questionnaire component\n\n## Deploy\n\n[![Deploy with Vercel](https:\u002F\u002Fvercel.com\u002Fbutton)](https:\u002F\u002Fvercel.com\u002Fnew\u002Fclone?repository-url=https%3A%2F%2Fgithub.com%2Fshadcn-ui%2Fchatbot-template&project-name=chatbot-template&repository-name=chatbot-template)\n\nThat's it — no configuration needed. Vercel deployments authenticate to the AI Gateway automatically via OIDC, and usage runs on your team's [AI Gateway credits](https:\u002F\u002Fvercel.com\u002Fdocs\u002Fai-gateway\u002Fpricing).\n\n## Local development\n\n```bash\npnpm install\n```\n\nThen give the app a gateway credential, either by pulling an OIDC token from your linked Vercel project:\n\n```bash\nvercel link\nvercel env pull\n```\n\nor by creating an API key in the Vercel dashboard (**AI Gateway → API Keys**) and adding it to `.env.local`:\n\n```bash\ncp .env.example .env.local\n# then set AI_GATEWAY_API_KEY=...\n```\n\nStart the dev server:\n\n```bash\npnpm dev\n```\n\n## Configuration\n\n| Env var              | Required       | Description                                                  |\n| -------------------- | -------------- | ------------------------------------------------------------ |\n| `AI_GATEWAY_API_KEY` | Local dev only | AI Gateway API key. Not needed on Vercel deployments (OIDC). |\n\nThe model list lives in [lib\u002Fmodels.ts](lib\u002Fmodels.ts) — the first entry is the default model.\n\n## Security\n\nThe `\u002Fapi\u002Fchat` route is **public and unauthenticated** — every request spends your AI Gateway credits. That's fine for a personal demo, but before putting it in front of real traffic you should:\n\n- **Rate limit it.** Add [Vercel Firewall \u002F WAF](https:\u002F\u002Fvercel.com\u002Fdocs\u002Fsecurity\u002Fvercel-waf) rules or [`@upstash\u002Fratelimit`](https:\u002F\u002Fgithub.com\u002Fupstash\u002Fratelimit-js) so a single client can't drain your credits (denial-of-wallet).\n- **Cap spend.** Set an [AI Gateway spend limit](https:\u002F\u002Fvercel.com\u002Fdocs\u002Fai-gateway\u002Fobservability-and-spend\u002Fbudgets) as a backstop.\n- **Add auth** if the chatbot isn't meant to be public.\n\nThe route already validates the request body, restricts models to [lib\u002Fmodels.ts](lib\u002Fmodels.ts), caps output tokens and step count, and aborts generation on client disconnect — but those bound a single request, not overall volume.\n\n## How it works\n\n- [app\u002Fapi\u002Fchat\u002Froute.ts](app\u002Fapi\u002Fchat\u002Froute.ts) streams responses with `streamText`\n- [components\u002Fchat.tsx](components\u002Fchat.tsx) renders the conversation with `useChat` and shadcn chat primitives.\n- [tools\u002F](tools) defines the tools — one file per tool (the filename is the model-facing tool name), composed in [tools\u002Findex.ts](tools\u002Findex.ts): a server-executed GitHub repo lookup, the interactive `ask_user` questionnaire, and provider-native web search.\n\n## Tool parts\n\nAssistant messages are a list of typed parts. [components\u002Fchat-message.tsx](components\u002Fchat-message.tsx) switches on `part.type` and delegates each one to a component in [components\u002Fparts\u002F](components\u002Fparts):\n\n| Part type          | Component                                                          | Renders                                                                                                                                       |\n| ------------------ | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |\n| `text`             | [text-part.tsx](components\u002Fparts\u002Ftext-part.tsx)                   | Markdown via react-markdown and shadcn\u002Ftypeset.                                                                                                |\n| `tool-github_repo` | [github-repo-part.tsx](components\u002Fparts\u002Fgithub-repo-part.tsx)     | A spinner while the lookup runs, then a linked stat line (stars, forks, language).                                                             |\n| `tool-web_search`  | [web-search-part.tsx](components\u002Fparts\u002Fweb-search-part.tsx)       | A \"Searching the web…\" status while the search runs, then a persistent \"Searched the web\" line per search.                                     |\n| `tool-ask_user`    | [ask-user-part.tsx](components\u002Fparts\u002Fask-user-part.tsx)           | The answered questions inline. Pending questions render in [question-card.tsx](components\u002Fquestion-card.tsx), pinned to the scroller bottom.   |\n| `source-url`       | [sources-part.tsx](components\u002Fparts\u002Fsources-part.tsx)             | Web search citations, deduped into a \"Searched N websites\" drawer once the message finishes streaming.                                         |\n\nTool parts move through states as the stream progresses — `input-streaming` → `input-available` → `output-available` (or `output-error`) — and each component switches on `part.state` to show progress, results, and failures.\n\n### Adding your own tool\n\n1. Create `tools\u002F\u003Cname>.ts` (the filename is the model-facing tool name) exporting a `tool()` with a `description`, an `inputSchema`, and an `execute` function (omit `execute` for tools the user answers in the UI, like `ask_user`), then register it in [tools\u002Findex.ts](tools\u002Findex.ts).\n2. Add a part component in [components\u002Fparts\u002F](components\u002Fparts) and a `case \"tool-\u003Cname>\"` in [chat-message.tsx](components\u002Fchat-message.tsx).\n\nMessage types are inferred from the tool definitions via `InferUITools`, so `part.input` and `part.output` are fully typed in your part component — renaming a tool field is a build error, not a silent `undefined`.\n\n## Adding components\n\n```bash\nnpx shadcn@latest add button\n```\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","这是一个基于 Next.js 和 Vercel AI Gateway 的轻量级聊天机器人模板，专为快速构建生产就绪的 AI 对话界面而设计。核心功能包括流式响应、Markdown 渲染、工具调用（如 Web 搜索）、人机协同问卷交互，并集成 shadcn\u002Fui 组件库实现一致美观的 UI。项目采用 TypeScript 编写，开箱即用支持 Vercel 部署与 OIDC 自动鉴权，本地开发也提供清晰的 API Key 配置路径。适用于需要快速验证 AI 产品原型、内部工具对话界面或嵌入式客服前端的中小型团队。",2,"2026-08-12 02:30:13","CREATED_QUERY"]