docs: Ask AI chat grounded in the docs vector store#5172
Conversation
Adds an "Ask AI" chat to the docs site. A floating launcher opens a panel backed by the Vercel AI SDK (OpenAI provider, OPENAI_API_KEY from the environment). The chat is grounded via a searchDocs tool that runs a vector search over the existing docs embeddings and returns source links, so answers cite real pages. - app/api/chat/route.ts — streaming POST handler (streamText + searchDocs tool) - components/ai/ask-ai.tsx — useChat panel with streamed answers + source chips - wired into the docs layout; reuses the existing OPENAI_API_KEY and embeddings Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@ouiliame is attempting to deploy a commit to the Sim Team on Vercel. A member of the Team first needs to authorize it. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Better grounding/instruction-following than gpt-4o-mini at docs-chat volumes; still overridable via OPENAI_CHAT_MODEL. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Markdown: render assistant messages with streamdown (the same AI-streaming markdown component the main app's chat uses), so bold/lists/code render instead of raw **asterisks**. User messages stay plain text. Abuse guards: the endpoint proxies a paid LLM, so cap the cost of any single request — max messages, max input size, max output tokens, fewer tool steps — and reject obvious cross-origin calls (lenient: Origin is a filter, not a boundary). Durable per-IP rate limiting, a provider spend cap, and edge bot protection are provisioned separately. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The size cap previously measured the whole serialized message array, so a follow-up question failed (413) once the history carried the prior answer plus retrieved doc chunks. Count only user-authored text instead, and loosen all bounds ~20x so normal multi-turn use never hits them — they remain only as a backstop against egregious abuse. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PR SummaryMedium Risk Overview A new The client uses Reviewed by Cursor Bugbot for commit d807260. Bugbot is set up for automated code reviews on this repo. Configure here. |
|
@ouiliame run the review loop and fix the comments and re-run |
- Guard req.json() with try/catch → 400 on malformed body (was 500) - Scope vector search to the reader's locale (mirrors site search); client forwards the active locale to the route - Backstop the whole serialized payload so assistant/tool parts can't be stuffed past the user-text cap - Split the scroll effect: instant jump on panel open, smooth on new messages - Add rel="noopener noreferrer" target="_blank" to source-chip links Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@greptile review |
A message that's a valid JSON array element but missing parts/role would throw in userInputChars and surface as a 500. Reject malformed messages with a 400. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@greptile review |
|
@waleedlatif1 ready for merge — review loop is at 5/5 ✅
All review comments addressed across three rounds: One call for you: the Cursor Medium Risk stays until those infra controls land. Merge now with the checklist as a fast-follow, or want them in first? |
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 34197725 | Triggered | Basic Auth String | d807260 | apps/sim/executor/handlers/pi/cloud-backend.test.ts | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secret safely. Learn here the best practices.
- Revoke and rotate this secret.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d807260. Configure here.
| const result = streamText({ | ||
| model: openai(CHAT_MODEL), | ||
| system: SYSTEM_PROMPT, | ||
| messages: convertToModelMessages(messages), |
There was a problem hiding this comment.
Client messages bypass grounding
Medium Severity
The chat route accepts a client-supplied messages array after minimal structural checks and passes it to convertToModelMessages. Crafted assistant tool parts or extra system messages can inject fake doc search results or instructions, so replies may not reflect actual searchDocs output.
Reviewed by Cursor Bugbot for commit d807260. Configure here.
| if (part.type === 'text') total += part.text.length | ||
| } | ||
| } | ||
| return total |
There was a problem hiding this comment.
Invalid text parts crash route
Medium Severity
userInputChars assumes every part with type === 'text' has a string text field. A crafted message that passes isValidMessage but omits text throws when reading .length, turning the request into an unhandled server error instead of a 400 response.
Reviewed by Cursor Bugbot for commit d807260. Configure here.


Summary
Adds an Ask AI chat to the docs site so readers can ask questions about Sim in natural language and get answers grounded in the documentation.
components/ai/ask-ai.tsx) built on the Vercel AI SDK'suseChat. Assistant replies render as markdown viastreamdown(the same AI-streaming markdown renderer the main app's chat uses), with source chips linking back to cited pages.app/api/chat/route.ts) usingstreamTextwith the OpenAI provider. AsearchDocstool runs a vector search over the existingdocs_embeddingsstore and returns source links, so the model answers from real docs rather than memory.OPENAI_API_KEYalready in the environment (same key the docs search uses for embeddings). Model defaults togpt-5.4-mini, overridable viaOPENAI_CHAT_MODEL.Abuse hardening
This endpoint proxies a paid LLM, so an unauthenticated public route is a target for scripted "free inference". Shipped in this PR (cost caps per request):
DOCS_ALLOWED_ORIGINSto extend)Infra-side follow-ups (dashboard/provisioning, not code) — do before public launch:
Notes
llms.txt,llms-full.txt,.md/.mdxroutes,Acceptnegotiation) already existed — this PR adds only the Ask AI chat.text-embedding-3-small); only the chat completion uses the chat model. Branch is offstaging;bun run buildandtype-checkpass for the docs app.🤖 Generated with Claude Code