Repository Chat
Purpose and Scope
Repository chat is the interactive companion to an OpenWiki repository wiki. The README describes OpenWiki as a Next.js app backed by an eve agent that plans a source-cited wiki, publishes it, keeps it fresh, and offers repository chat using the same indexed source context. In the product flow, a reader can browse generated documentation first, then switch into chat when they need a focused explanation, a starting point, or a guided tour through runtime files. That makes chat a read interface over repository evidence rather than a separate generic assistant.
Sources: README.md
The chat system has three visible layers. A repository route renders the full-page chat experience for a specific owner and repository. A compact floating entry point on wiki pages links readers into that route. Two API route handlers then bridge the browser to eve: one starts a repository-message session and another streams session events back to the browser. The agent runner prepares live GitHub context, chooses sandbox files, constructs the prompt, and starts a conversational eve session. These pieces keep UI concerns, HTTP validation, and source-context construction separated.
Sources: app/(wiki)/[owner]/[repo]/chat/page.tsx, app/components/repo-chat.tsx, app/components/repo-chat-full-page.tsx, app/api/chat/route.ts, app/api/chat/stream/[sessionId]/route.ts, agent/lib/repo-message/run-repo-message.ts
Relevant Source Files
- README.md — Defines repository chat as a first-class OpenWiki feature that uses indexed source context alongside source-grounded wikis.
- app/(wiki)/[owner]/[repo]/chat/page.tsx — Implements the dynamic repository chat page, derives the GitHub repository URL, and passes route data into the full-page chat component.
- app/components/repo-chat.tsx — Provides the small wiki-page affordance that links a reader into the dedicated chat page for the current repository.
- app/components/repo-chat-full-page.tsx — Implements the client-side chat interface, message state, suggestions, streaming resume behavior, local persistence, and rendering of assistant output.
- app/api/chat/route.ts — Validates chat start requests, applies chat rate limits, normalizes GitHub repository URLs, calls the eve repo-message endpoint, and returns session metadata.
- app/api/chat/stream/[sessionId]/route.ts — Proxies a specific eve session stream to the browser and validates stream continuation parameters.
- agent/lib/repo-message/run-repo-message.ts — Builds the repository snapshot, reads chat context, selects sandbox files, creates the prompt, and starts the conversational eve session.
User-Facing Chat Flow
The public chat page lives under the wiki route for a repository. The page receives the dynamic owner and repository name, constructs a label such as owner slash repository, builds the canonical GitHub URL, and computes both wiki and chat links for the navbar. It is explicitly dynamic, which is appropriate because chat state and query-driven initial questions should not be treated like static wiki pages. The page also accepts an optional query value for an initial question, letting other parts of the product deep-link into a prefilled or immediately submitted repository question.
Sources: app/(wiki)/[owner]/[repo]/chat/page.tsx
On regular wiki pages, the compact chat affordance is intentionally minimal. The component renders a fixed, bottom-positioned link with accessible labeling and text that invites the reader to ask a question. It receives only a chat URL and repository label, so it does not own any session behavior. That division is useful because wiki pages can advertise chat without loading the full conversational client. The full chat state, streaming, retries, and message persistence are reserved for the dedicated full-page component after the reader chooses to open chat.
Sources: app/components/repo-chat.tsx, app/components/repo-chat-full-page.tsx
The full-page client component models messages with roles, assistant states, citations, and tool calls. It offers starter suggestions such as where to start reading, how the repository is organized, key runtime flows, and public API files. Those prompts reflect OpenWiki’s intended repository-analysis tasks instead of open-ended small talk. The component also tracks sending state, hydration state, a revealing assistant message, an abort controller, and an active run. This gives the UI enough information to show progress, stop a response, recover after reloads, and continue displaying partial output while the server stream advances.
Sources: app/components/repo-chat-full-page.tsx
API Components
Starting a chat turn is handled by the chat POST route. The route expects a JSON body with a repository URL, a non-empty message, and optional recent history. Request validation caps the current message at eight thousand characters, each history item at four thousand characters, and history length at eight messages. After parsing, it requires the URL to resolve to a public GitHub repository. Before contacting eve, it enforces the chat rate limit for the repository full name and maps known storage configuration failures into user-facing responses.
Sources: app/api/chat/route.ts
When validation and rate limiting succeed, the POST route calls the embedded eve route for the repo-message task. It forwards only normalized data: the cleaned repository URL, the current message, and optional history. It includes server headers from the shared eve-client helpers and uses a JSON content type. If the embedded eve route cannot be reached, the API returns a gateway-style error that tells local developers to start the app with the development server. On success, the browser receives repository identity and session metadata with an accepted status, not the final answer.
Sources: app/api/chat/route.ts
Streaming is a separate GET route addressed by session identifier. The route rejects an empty session identifier and validates that an optional start index is a non-negative integer. It then opens the corresponding eve session stream, passes through the request abort signal, and returns the upstream body with cache-control and content-type headers. The default content type is newline-delimited JSON, which matches the client component’s stream-event model. Separating session creation from streaming lets the UI resume from a stream index instead of restarting the whole chat turn.
Sources: app/api/chat/stream/[sessionId]/route.ts, app/components/repo-chat-full-page.tsx
Compact route reference
| Surface | Method | Main inputs | Main output | Notable behavior |
|---|---|---|---|---|
/api/chat | POST | repoUrl, message, optional history | Repository identity and eve session | Validates request, rate limits, starts repo-message session, returns status 202 |
/api/chat/stream/[sessionId] | GET | Path sessionId, optional startIndex | Proxied eve stream body | Validates continuation inputs, forwards headers, preserves stream status |
/{owner}/{repo}/chat | Page | Route params and optional q | Full-page chat UI | Builds repository label, wiki href, chat href, and GitHub URL |
Source Context and Agent Session Construction
The repo-message runner is where chat becomes repository-grounded. It parses the GitHub URL, obtains a prepared repository snapshot, reads chat context from that snapshot, and passes those snippets into prompt construction. It also selects a bounded set of files for the sandbox. The selection starts with the paths already needed by the chat context, then adds inventory files that are small enough for the sandbox. This helps the assistant answer from concrete repository material while keeping the session startup and sandbox footprint bounded.
Sources: agent/lib/repo-message/run-repo-message.ts
The sandbox file selection has explicit limits: no more than thirty-six files, and only inventory entries at or below one hundred eighty thousand bytes are considered for automatic addition. Priority favors shallow, high-signal project files. Root readmes, package manifests, TypeScript configuration, index files, main entry points, documentation, examples, packages, source, and app directories are promoted. Tests and hidden metadata directories are deprioritized. This scoring makes chat more likely to have architectural and public API context available before it spends space on generated, hidden, or narrowly diagnostic files.
Sources: agent/lib/repo-message/run-repo-message.ts
The eve session is started in conversation mode with a continuation token prefixed for OpenWiki chat. The state records the repository URL, default branch, commit SHA, and selected sandbox paths. Those details are important for reproducibility: the assistant’s answer can be tied to a particular repository snapshot and a known set of files available to the sandbox. The runner returns the continuation token, session identifier, and an initial stream index of zero, which lines up with the browser’s later stream request and resume bookkeeping.
Sources: agent/lib/repo-message/run-repo-message.ts, app/components/repo-chat-full-page.tsx
Client Streaming, Persistence, and Recovery
The full-page component treats a response as a session-backed run rather than a single blocking request. Its stream-event type includes status, incremental message text, accumulated message text, actions, and results. The component defines retryable stream-open status codes, reconnect attempts, an idle timeout, and a reconnect delay. It also tracks a stream index inside the persisted active run. Together, those fields let the browser reopen a stream after transient server or network failures and ask for events from the last known position instead of duplicating the assistant response.
Sources: app/components/repo-chat-full-page.tsx, app/api/chat/stream/[sessionId]/route.ts
The client persists repository chat state under an OpenWiki-specific storage prefix and version. It caps stored messages at forty and records any active run with the assistant message identifier, session metadata, and update time. On hydration, the component reads the persisted snapshot for the repository URL, restores messages, restores an active run when present, and can resume streaming. This is especially useful for long repository-analysis answers because a page refresh or navigation interruption does not necessarily erase the user’s current conversation context.
Sources: app/components/repo-chat-full-page.tsx
Operational Boundaries and Next Steps
Repository chat inherits several operational boundaries from the route and runner design. Only public GitHub repositories are accepted by the API parser. Oversized requests are rejected before they reach the agent. Rate-limited clients receive a structured response with limit, reset time, retry-after, and scope details. The route can surface storage configuration errors when rate-limit state cannot be accessed, and it reports embedded eve connectivity failures separately. These behaviors make chat failures more diagnosable for both hosted deployments and local development sessions.
Sources: app/api/chat/route.ts
When extending repository chat, preserve the separation between presentation, request validation, stream proxying, and source-context assembly. UI improvements should usually live in the full-page component or the compact link component. Request-shape changes belong in the POST route schema and should be reflected in the agent input type. Changes to grounding, sandbox scope, or prompt construction should be made in the repo-message runner and related prompt/context modules. For nearby implementation details, continue with the chat API reference, agent architecture, indexing engine, and rate-limits pages.