Skip to content

feat: streaming AI upgrade with cloud-first provider failover - #1

Merged
Ocean82 merged 3 commits into
mainfrom
feat/streaming-ai-upgrade
Jul 7, 2026
Merged

feat: streaming AI upgrade with cloud-first provider failover#1
Ocean82 merged 3 commits into
mainfrom
feat/streaming-ai-upgrade

Conversation

@Ocean82

@Ocean82 Ocean82 commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add streaming AI responses with faster model support
  • Add Groq cloud + Ollama local provider routing with cloud-first failover
  • Add landing page and workspace/lockfile metadata updates

Test plan

  • Verify AI streaming works with configured cloud provider
  • Verify failover to local Ollama when cloud is unavailable
  • Confirm landing page renders correctly
  • Run app locally and smoke test core spreadsheet flows

Summary by Sourcery

Introduce streaming AI chat with multi-provider routing and cloud-first failover, plus a new public landing page and updated model configuration.

New Features:

  • Add a streaming SSE chat endpoint and frontend client for real-time AI responses.
  • Support multiple AI backends (Groq, OpenRouter, Hugging Face, Ollama) with configurable provider order and automatic failover.
  • Extend intent resolution with richer spreadsheet commands for formulas, charts, formatting, and column operations.
  • Add a static marketing landing page and Nginx config for smartsht.com deployment.

Enhancements:

  • Simplify and shorten the system prompt and spreadsheet context to speed up inference on small models.
  • Switch the recommended local model to Qwen2.5-Coder-1.5B and tune default context/num_predict for faster CPU inference.
  • Improve health reporting and startup logging to reflect available AI providers and models.
  • Refine chat UI loading text and reduce server/client timeouts for snappier behavior.

Build:

  • Update model setup script and workspace metadata for the new default GGUF model.

Deployment:

  • Add Nginx and PM2 configs for hosting the landing page, SPA app, and API server in production.

Documentation:

  • Update README and models documentation for the new model, streaming behavior, and cloud provider configuration.

Summary by CodeRabbit

  • New Features

    • Added streaming chat responses for a smoother, more responsive AI experience.
    • Expanded the app’s spreadsheet automation capabilities with more template, formula, chart, and formatting options.
    • Improved support for multiple AI providers with automatic fallback when one is unavailable.
    • Launched a new public landing page and updated the site’s production setup.
  • Bug Fixes

    • Improved response handling so AI output is more consistently structured and reliable.
    • Reduced long wait times and updated default model settings for faster results.
  • Documentation

    • Updated setup and configuration guides with the latest recommended models and environment settings.

Ocean82 added 3 commits July 7, 2026 04:58
…page

- Swap model from Qwen3.5-4B (2.7GB, slow) to Qwen2.5-Coder-1.5B (1.6GB, 3x faster)
- Add streaming SSE endpoint (/api/chat/stream) for real-time token display
- Add Groq as primary cloud AI backend (sub-1s responses, free tier)
- Keep Ollama as local fallback for privacy/offline use
- Expand intent system to cover more patterns instantly (no LLM needed)
- Reduce context overhead (30 cells max, shorter system prompt, 4 exchanges)
- Add landing page for smartsht.com (static HTML, self-contained)
- Add nginx config for production deployment
- Add PM2 ecosystem config for server process management
- Update homepage to smartsht.com
Improve production chat reliability by adding configurable provider order with OpenRouter, Hugging Face, Groq, and Ollama fallbacks, and document new environment variables for deployment.
Add VS Code Snyk auto-organization setting and persist the package license field in the lockfile for consistent local tooling behavior.
@sourcery-ai

sourcery-ai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Reviewer's Guide

Implements streaming AI responses over SSE, adds a cloud-first multi-provider LLM routing layer with failover to local Ollama, significantly expands intent fast-path handling, and introduces a marketing landing page plus deployment/config docs for smartsht.com.

Sequence diagram for streaming chat with cloud-first LLM failover

sequenceDiagram
    actor User
    participant ChatPanel
    participant useStore
    participant AgentClient as chatWithAgentServerStream
    participant Api as Express_index_ts
    participant Router as callProviderStream
    participant OpenRouter as chatWithOpenAiCompatibleStream
    participant Groq as chatWithGroqStream
    participant Ollama as chatWithOllamaStream

    User->>ChatPanel: submit message
    ChatPanel->>useStore: sendAIMessage
    useStore->>AgentClient: chatWithAgentServerStream(message, context, history, onToken)
    AgentClient->>Api: POST /api/chat/stream

    Api->>Api: resolveIntent
    alt template fast path
        Api-->>AgentClient: SSE data:{type:'complete', source:'template'}
        AgentClient->>useStore: on complete
        useStore->>ChatPanel: update messages
    else LLM path
        Api->>Api: providerOrder, providerIsConfigured
        loop providers in order
            Api->>Router: callProviderStream(provider, messages)
            alt OpenRouter/HuggingFace
                Router->>OpenRouter: chatWithOpenAiCompatibleStream
                OpenRouter-->>Router: tokens
            else Groq
                Router->>Groq: chatWithGroqStream
                Groq-->>Router: tokens
            else Ollama
                Router->>Ollama: chatWithOllamaStream
                Ollama-->>Router: tokens
            end
            Router-->>Api: fullText
            Api-->>AgentClient: SSE data:{type:'token', content}
            AgentClient->>useStore: onToken(token)
            useStore->>ChatPanel: append streaming assistant content
        end
        Api-->>AgentClient: SSE data:{type:'complete', source:'llm'}
        AgentClient->>useStore: final ServerChatResponse
        useStore->>ChatPanel: replace streaming message with final
    end
Loading

File-Level Changes

Change Details Files
Add cloud-first LLM provider routing with configurable priority order and health reporting, including Groq and generic OpenAI-compatible backends with Ollama fallback.
  • Introduce ProviderName type, providerOrder(), providerIsConfigured(), callProvider(), and callProviderStream() helpers to centralize provider selection and invocation.
  • Wire Groq (OpenAI-compatible) and generic OpenAI-compatible providers (OpenRouter, Hugging Face) into the server, including availability checks and per-provider config.
  • Update /health endpoint and server startup logs to surface provider availability, configured models, and provider order, and relax ok to true if any cloud or local provider is usable.
  • Adjust chat controller to iterate through configured providers in order, with graceful fallback payloads when all providers are unavailable.
server/src/index.ts
server/src/config.ts
server/src/groq.ts
server/src/openaiCompatible.ts
Implement end-to-end streaming chat over SSE with frontend integration and Ollama/Groq/OpenAI-compatible streaming support, while retaining a non-streaming JSON fallback API.
  • Add /api/chat/stream SSE endpoint that streams token events and a final complete event, handling AbortSignal cancellation, template fast-path, and provider failover.
  • Implement streaming clients for Groq, OpenRouter/HuggingFace (OpenAI-compatible), and Ollama, parsing provider-specific streaming formats into incremental text chunks.
  • Add chatWithAgentServerStream on the frontend to consume SSE, parse events, and incrementally update the UI via onToken callbacks.
  • Refactor useStore AI flow to create a placeholder assistant message, stream tokens into it, then replace it with the final structured message or a local intent-based fallback if streaming fails.
  • Reduce non-streaming timeouts (server and client) to 120s to keep requests bounded with the faster model stack.
server/src/index.ts
server/src/groq.ts
server/src/openaiCompatible.ts
server/src/ollama.ts
src/ai/agentClient.ts
src/store/useStore.ts
Tighten and expand intent fast-path handling to cover more spreadsheet operations and reduce reliance on LLMs.
  • Reorganize intent.ts with clear sections (templates, charts, formulas, column modifications, formatting, analysis, clear/reset, greetings/help/thanks).
  • Add new intents for project/todo trackers, HR/payroll, richer chart types (scatter, generic visualization), more formulas (AVERAGE, COUNT, MAX, MIN), column operations (percent increases/decreases, doubling), and formatting commands.
  • Expand help and greeting responses with more capabilities and acknowledgements, and add clear/reset intent that maps to a clear_sheet tool.
  • Ensure unmatched queries fall through to the LLM by returning empty message/actions, preserving existing behavior.
server/src/intent.ts
Optimize system prompt and spreadsheet context to better fit small, fast local models and structured tool-calling.
  • Rewrite buildSystemPrompt to produce a shorter, JSON-focused instruction block, including only the first ~30 cell summaries and a compact context line.
  • Align tool-calling instructions with the new JSON-only contract and emphasize short, plain-English messages and actions arrays.
  • Reduce MAX_SUMMARY_CELLS from 80 to 30 to shrink prompt size and improve latency on CPU models.
server/src/prompt.ts
src/ai/buildContext.ts
Switch to a smaller, faster Qwen2.5-Coder-1.5B local model and tune generation parameters, docs, and setup scripts accordingly.
  • Update config defaults to point at qwen2.5-coder-1.5b-q8_0.gguf, halve numCtx, and increase numPredict to 512 for slightly longer answers.
  • Lower Ollama temperature and timeout for both streaming and non-streaming chat to prioritize deterministic, fast responses.
  • Refresh models/README.md and setup-model script messaging to focus on the new 1.5B model, performance characteristics, and guidance for legacy 4B users.
  • Adjust project README to describe the new model, streaming SSE support, reduced RAM requirements, and new AI environment variables.
server/src/config.ts
server/src/ollama.ts
models/README.md
server/scripts/setup-model.mjs
README.md
Add a static marketing landing page and deployment artifacts for smartsht.com, including Nginx and PM2 configs.
  • Introduce landing/index.html as a standalone static marketing site that links to the app, GitHub, and explains the product and setup.
  • Add smartsht.nginx.conf with routing for landing page, SPA /app, and /api proxy with streaming-friendly proxy settings.
  • Add PM2 ecosystem.config.cjs to run the Express API in production with sensible defaults.
  • Update package.json homepage and add VS Code settings and .env.example scaffold for better DX and deployment.
  • Ensure README and docs reference the new smartsht.com landing page and updated RAM/model guidance.
landing/index.html
landing/smartsht.nginx.conf
server/ecosystem.config.cjs
package.json
README.md
.env.example
.vscode/settings.json

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@Ocean82
Ocean82 merged commit 4486cb0 into main Jul 7, 2026
1 of 2 checks passed
@Ocean82
Ocean82 deleted the feat/streaming-ai-upgrade branch July 7, 2026 10:43
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3a1a5411-f337-47ca-ad25-67fa46f38cc8

📥 Commits

Reviewing files that changed from the base of the PR and between ab78605 and 4d157b7.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (21)
  • .env.example
  • .vscode/settings.json
  • README.md
  • landing/index.html
  • landing/smartsht.nginx.conf
  • models/README.md
  • package.json
  • server/Modelfile
  • server/ecosystem.config.cjs
  • server/scripts/setup-model.mjs
  • server/src/config.ts
  • server/src/groq.ts
  • server/src/index.ts
  • server/src/intent.ts
  • server/src/ollama.ts
  • server/src/openaiCompatible.ts
  • server/src/prompt.ts
  • src/ai/agentClient.ts
  • src/ai/buildContext.ts
  • src/components/ChatPanel.tsx
  • src/store/useStore.ts

📝 Walkthrough

Walkthrough

This PR adds multi-provider LLM support (OpenRouter, Hugging Face, Groq, Ollama) with ordered failover and SSE streaming across server and client, switches the default local model to Qwen2.5-Coder-1.5B, expands intent detection, and adds a new landing page with nginx deployment config.

Changes

Multi-provider LLM Streaming Chat

Layer / File(s) Summary
Provider config and model defaults
.env.example, README.md, server/src/config.ts, server/ecosystem.config.cjs, server/Modelfile, server/scripts/setup-model.mjs, models/README.md
Adds provider API key/model/base URL env vars and LLM_PROVIDER_ORDER, switches default local model to Qwen2.5-Coder-1.5B, and adjusts numCtx/numPredict defaults.
Provider client implementations
server/src/groq.ts, server/src/openaiCompatible.ts, server/src/ollama.ts
Adds Groq and OpenAI-compatible chat clients (streaming and non-streaming) and adds a streaming variant to the Ollama client.
Server chat endpoints and routing
server/src/index.ts
Adds provider order/availability helpers, updates /health, adds POST /api/chat/stream SSE endpoint with fast-path/failover, and rewrites POST /api/chat.
Prompt and intent logic
server/src/prompt.ts, server/src/intent.ts
Compacts the system prompt and expands intent detection with new templates, formulas, and column-modification actions.
Client streaming consumption
src/ai/agentClient.ts, src/store/useStore.ts, src/ai/buildContext.ts, src/components/ChatPanel.tsx
Adds streaming client function, refactors sendMessage to use a streaming placeholder message, reduces context sample size, and updates chat status text.

Estimated code review effort: 4 (Complex) | ~60 minutes

Landing Page and Deployment Config

Layer / File(s) Summary
Landing page markup
landing/index.html
Adds a static marketing page with hero, terminal demo, features, and footer sections plus inline CSS.
Nginx deployment config
landing/smartsht.nginx.conf
Adds HTTPS/HTTP server blocks with API/health proxying, SPA routing, static caching, and TLS setup.
Package and workspace metadata
package.json, .vscode/settings.json, README.md
Updates homepage URL, adds Snyk workspace setting, and adds a smartsht.com link in README.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client as useStore (sendMessage)
  participant AgentClient as agentClient.ts
  participant Server as /api/chat/stream
  participant Provider as LLM Provider (Groq/OpenRouter/HF/Ollama)

  Client->>AgentClient: chatWithAgentServerStream(history, onToken)
  AgentClient->>Server: POST /api/chat/stream (SSE)
  Server->>Server: check fast-path intent template
  alt no fast-path match
    Server->>Provider: callProviderStream(messages)
    loop streamed tokens
      Provider-->>Server: token chunk
      Server-->>AgentClient: SSE "token" event
      AgentClient-->>Client: onToken(chunk) appends to placeholder
    end
    Server->>Server: parse accumulated response
  end
  Server-->>AgentClient: SSE "complete" event (message, actions)
  AgentClient-->>Client: final ServerChatResponse
  Client->>Client: replace placeholder message with final response
Loading

Poem

A hop, a skip, a streaming token flies,
Providers queue like carrots in a line. 🥕
Qwen's gone slim, now fast and spry,
A shiny landing page waves hello nearby.
Thump thump — this rabbit's code review is done! 🐇✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • The SSE client parsing in chatWithAgentServerStream assumes each data: line arrives as a complete chunk split by \n; consider buffering partial lines across reads or using a small SSE parser to avoid issues when events are split across chunks.
  • The provider selection logic (providerOrder, providerIsConfigured, callProvider, callProviderStream) is duplicated between streaming and non‑streaming endpoints; pulling this into a shared helper would reduce drift and make it easier to extend or adjust provider behavior in one place.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The SSE client parsing in `chatWithAgentServerStream` assumes each `data:` line arrives as a complete chunk split by `\n`; consider buffering partial lines across reads or using a small SSE parser to avoid issues when events are split across chunks.
- The provider selection logic (`providerOrder`, `providerIsConfigured`, `callProvider`, `callProviderStream`) is duplicated between streaming and non‑streaming endpoints; pulling this into a shared helper would reduce drift and make it easier to extend or adjust provider behavior in one place.

## Individual Comments

### Comment 1
<location path="models/README.md" line_range="28" />
<code_context>
+
+## Why this model?
+
+- **Speed**: 1.5B params generates tokens 3–4× faster than 4B on CPU
+- **Quality**: Qwen2.5-Coder-Instruct is specifically trained for structured output / JSON — perfect for tool calling
+- **Size**: Q8_0 quantization preserves quality while keeping the file under 1.6GB
</code_context>
<issue_to_address>
**issue (typo):** Use plural verb with "params" ("params generate" instead of "params generates").

This keeps subject–verb agreement with the plural noun "params."

```suggestion
- **Speed**: 1.5B params generate tokens 3–4× faster than 4B on CPU
```
</issue_to_address>

Fix all in Cursor


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread models/README.md

## Why this model?

- **Speed**: 1.5B params generates tokens 3–4× faster than 4B on CPU

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (typo): Use plural verb with "params" ("params generate" instead of "params generates").

This keeps subject–verb agreement with the plural noun "params."

Suggested change
- **Speed**: 1.5B params generates tokens 3–4× faster than 4B on CPU
- **Speed**: 1.5B params generate tokens 3–4× faster than 4B on CPU

Fix in Cursor

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.

1 participant