Skip to content

Feat/LLM chat #29

Open
1amKhush wants to merge 22 commits into
ContextVM:masterfrom
1amKhush:feat/chat-phase1
Open

Feat/LLM chat #29
1amKhush wants to merge 22 commits into
ContextVM:masterfrom
1amKhush:feat/chat-phase1

Conversation

@1amKhush
Copy link
Copy Markdown

Description

Resolves #26 - LLM chat integration

This PR implements Phase 1 of the ContextVM web chat interface. It provides a robust, zero-friction LLM experience for users out of the box, alongside full Bring-Your-Own-Token (BYOT) support and IndexedDB conversation persistence.

Key Features

  • Zero-Friction Auto Mode: Ships with a default (fund-less) OpenRouter API key. It dynamically fetches models, filters for the :free suffix, and automatically rotates through free models if a 429 Rate Limit is encountered.
  • Conversation Management: Uses IndexedDB to persist chats across sessions. The UI includes a collapsible Shadcn sidebar allowing users to create, rename, and delete conversations.
  • Smart Comboboxes:
    • Providers: A preset list allowing one-click switching between OpenRouter, OpenAI, Ollama, LM Studio, and Custom base URLs.
    • Models: Dynamically queries the active provider's /v1/models endpoint. Features an "Auto (free models)" mode pinned to the top for OpenRouter.
  • Phase 2 Readiness: The Sidebar component uses a panel-switcher pattern currently defaulting to "Conversations". This is stubbed and ready to accept a "Servers" panel in Phase 2 that will tap directly into the existing mcpClientService singleton.

Technical Notes

  • All new chat types, logic, and components are namespaced under src/lib/types/chat-types.ts, src/lib/services/llm.ts, src/lib/services/auto-mode.ts, and src/lib/components/chat/.
  • openai SDK is used under the hood configured with dangerouslyAllowBrowser: true as this is entirely a client-side execution.
  • Implements robust stale-closure guards and AbortControllers to handle rapid context switching and stream cancellation.

Testing

  • Verified zero-config Auto Mode successfully rotates models.
  • Verified IndexedDB properly stores and recovers chat state on reload.
  • Verified BYOT configuration accurately fetches and streams from selected models.
  • Svelte-check passes with 0 errors/warnings.

Copilot AI review requested due to automatic review settings May 18, 2026 20:55
@vercel
Copy link
Copy Markdown

vercel Bot commented May 18, 2026

@1amKhush is attempting to deploy a commit to the ContextVM's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Implements Phase 1 of an in-browser LLM chat workspace at /chat, including provider/model selection, OpenRouter "Auto free models" rotation, streaming responses via the OpenAI SDK in the browser, IndexedDB-backed conversation persistence, and a new Shadcn-style sidebar primitive set.

Changes:

  • Adds chat UI (Chat, ChatInput, ChatBubble, sidebar with conversation list, settings sheet with provider/model/key comboboxes) and a top-nav entry.
  • Adds client-side services: LLMService (OpenAI SDK with dangerouslyAllowBrowser), FreeModelRotator for OpenRouter :free rotation on 429s, and an IndexedDB conversation store with reactive $state.
  • Adds new generic UI primitives (sidebar, popover, command, scroll-area) and the openai dependency; ships a hardcoded "default" OpenRouter API key for zero-config use.

Reviewed changes

Copilot reviewed 51 out of 52 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/routes/chat/+page.svelte, +page.ts New chat route, wires sidebar/header/config/Chat.
src/lib/types/chat-types.ts Shared chat types, provider presets, and the hardcoded default OpenRouter key.
src/lib/services/llm.ts OpenAI SDK wrapper with streaming, base URL normalization, and free-model fallback.
src/lib/services/auto-mode.ts Free-model fetching, caching, rate-limit detection, and round-robin rotation.
src/lib/services/conversation-store.svelte.ts IndexedDB-backed conversation CRUD and reactive store.
src/lib/components/chat/* Chat UI: Chat, ChatBubble, ChatInput, ChatSidebar, ConversationList, LLMConfig, ProviderCombobox, ModelCombobox, AutoModeBanner.
src/lib/components/ui/sidebar/* New sidebar primitive set (provider/context/root/header/footer/menu/etc.).
src/lib/components/ui/popover/, command/, scroll-area/* New UI primitives consumed by the chat settings and conversation list.
src/lib/components/header.svelte Adds Chat link to desktop and mobile navs.
package.json, bun.lock Adds openai@^4.0.0 and its transitive deps.
.changeset/chat-phase-one.md Minor changeset entry.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/lib/types/chat-types.ts Outdated
Comment thread src/lib/components/chat/Chat.svelte Outdated
Comment thread src/lib/services/llm.ts
Comment thread src/lib/services/conversation-store.svelte.ts Outdated
Comment thread src/lib/components/chat/Chat.svelte
Comment thread src/lib/components/chat/ChatBubble.svelte Outdated
Comment thread package.json Outdated
@vercel
Copy link
Copy Markdown

vercel Bot commented May 19, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
contextvm-site Ready Ready Preview, Comment May 21, 2026 9:10am

@ContextVM-org
Copy link
Copy Markdown
Contributor

I'm noticing some issues. First, the sidebar collapses in a bad way and cannot be expanded again.
Screenshot from 2026-05-19 11-26-49
When I try the chat I got
'''
Uncaught (in promise) DataCloneError: Failed to execute 'put' on 'IDBObjectStore': [object Array] could not be cloned.
at zn (6.DvmS0QwY.js:1:14167)
at async Fr (6.DvmS0QwY.js:1:15140)
at async Object.m [as onSend] (6.DvmS0QwY.js:19:11371)
'''
In the browser console so it doesnt work.
Also the textarea for input is disabled after removing a conversation and you need to manually create a new one in order to write. This doesnt need to be like that and new conversations can be handled more gracefully.
In general this needs more care

@1amKhush 1amKhush force-pushed the feat/chat-phase1 branch from 115bd28 to 1ab7bfa Compare May 19, 2026 09:45
@ContextVM-org
Copy link
Copy Markdown
Contributor

Great, the error are gone, but I'm not able to receive a response when writing a message, tested with the auto mode, with another model, and with my own key. Nothing happens

@1amKhush
Copy link
Copy Markdown
Author

but I'm not able to receive a response when writing a message, tested with the auto mode, with another model, and with my own key. Nothing happens

I'll have a look (did test before and it seemed to work)

@ContextVM-org
Copy link
Copy Markdown
Contributor

I cannot get it to work. Tested in the vercel deployment and in my own dev enviroment. But nothing happens, I send a message to the chat an there is no loading or nothing, also nothing in the console

@1amKhush
Copy link
Copy Markdown
Author

1amKhush commented May 19, 2026

I cannot get it to work. Tested in the vercel deployment and in my own dev enviroment. But nothing happens, I send a message to the chat an there is no loading or nothing, also nothing in the console

Honestly was a very small issue, Svelte’s $state() automatically wraps objects to track changes. But some native browser objects and SDKs, like AbortController and the OpenAI client, break when wrapped this way.

The fix was simple, i stored those objects as normal let variables instead of reactive $state variables. That keeps them untouched and everything works normally again. I must have wrapped them during the compilation error bug fixing i think

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.

LLM chat integration

3 participants