Skip to content

Clarify where the API key files should live.#9759

Closed
dpage wants to merge 9 commits intopgadmin-org:masterfrom
dpage:ai_key_docs
Closed

Clarify where the API key files should live.#9759
dpage wants to merge 9 commits intopgadmin-org:masterfrom
dpage:ai_key_docs

Conversation

@dpage
Copy link
Contributor

@dpage dpage commented Mar 16, 2026

#9758

Summary by CodeRabbit

  • Bug Fixes

    • Fixed LLM responses not streaming or rendering properly in the AI Assistant.
  • New Features

    • Added response streaming capability for LLM interactions across all supported providers.
    • Enhanced NLQ chat panel with incremental Markdown rendering and SQL code block formatting.
    • Added inline SQL actions (insert, replace, copy) for better usability.
    • Added hyperlink color theming for dark, light, and high contrast themes.
  • Documentation

    • Clarified API Key File path semantics for Anthropic and OpenAI providers.

dpage and others added 9 commits March 16, 2026 14:09
- Anthropic: preserve separators between text blocks in streaming to
  match _parse_response() behavior.
- Docker: validate that the API URL points to a loopback address to
  constrain the request surface.
- Docker/OpenAI: raise LLMClientError on empty streams instead of
  yielding blank LLMResponse objects, matching non-streaming behavior.
- SQL extraction: strip trailing semicolons before joining blocks to
  avoid double semicolons in output.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ing.

- Use distinct 3-tuple ('complete', text, messages) for completion events
  to avoid ambiguity with ('tool_use', [...]) 2-tuples in chat streaming.
- Pass conversation history from request into chat_with_database_stream()
  so follow-up NLQ turns retain context.
- Add re.IGNORECASE to SQL fence regex for case-insensitive matching.
- Render MarkdownContent as block element instead of span to avoid
  invalid DOM when response contains paragraphs, lists, or tables.
- Keep stop notice as a separate message instead of appending to partial
  markdown, preventing it from being swallowed by open code fences.
- Snapshot streamingIdRef before setMessages in error handler to avoid
  race condition where ref is cleared before React executes the updater.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix critical NameError: use self._api_url instead of undefined API_URL
  in anthropic and openai streaming _process_stream() methods.
- Match sync path auth handling: conditionally set API key headers in
  streaming paths for both anthropic and openai providers.
- Remove unconditional temperature from openai streaming payload to
  match sync path compatibility approach.
- Add URL scheme validation to OllamaClient.__init__ to prevent unsafe
  local/resource access via non-http schemes.
- Guard ollama streaming finalizer: raise error when stream drops
  without a done frame and no content was received.
- Update chat.py type hint and docstring for 3-tuple completion event.
- Serialize and return filtered conversation history in the complete
  SSE event so the client can round-trip it on follow-up turns.
- Store and send conversation history from NLQChatPanel, clear on
  conversation reset.
- Fix JSON-fallback SQL render path: clear content when SQL was
  extracted without fenced blocks so ChatMessage uses sql-only renderer.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adding block scoping to the error case introduced an unmatched brace
that prevented the switch statement from closing properly, causing
an eslint parse error.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace compaction module imports with inline history deserialization
  and filtering since compaction.py is on a different branch.
- Add rstrip(';') to SQL extraction test to match production code,
  fixing double-semicolon assertion failure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The rstrip(';') applied to each block before joining means single
blocks and the last block in multi-block joins no longer have
trailing semicolons. Update expected values to match.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Truncated content from a dropped connection should not be treated as
a complete response, even if partial text was streamed. Always raise
when final_data is None, matching CodeRabbit's recommendation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Mar 16, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 86f27c38-70c3-41e2-896f-d4f6ccb8900f

📥 Commits

Reviewing files that changed from the base of the PR and between e347210 and aa28e7f.

📒 Files selected for processing (17)
  • docs/en_US/ai_tools.rst
  • docs/en_US/preferences.rst
  • docs/en_US/release_notes_9_14.rst
  • web/pgadmin/llm/__init__.py
  • web/pgadmin/llm/chat.py
  • web/pgadmin/llm/client.py
  • web/pgadmin/llm/prompts/nlq.py
  • web/pgadmin/llm/providers/anthropic.py
  • web/pgadmin/llm/providers/docker.py
  • web/pgadmin/llm/providers/ollama.py
  • web/pgadmin/llm/providers/openai.py
  • web/pgadmin/static/js/Theme/dark.js
  • web/pgadmin/static/js/Theme/high_contrast.js
  • web/pgadmin/static/js/Theme/light.js
  • web/pgadmin/tools/sqleditor/__init__.py
  • web/pgadmin/tools/sqleditor/static/js/components/sections/NLQChatPanel.jsx
  • web/pgadmin/tools/sqleditor/tests/test_nlq_chat.py

Walkthrough

This PR adds streaming support to the LLM chat infrastructure across multiple providers (Anthropic, OpenAI, Docker, Ollama), refactors the NLQ chat flow to consume streamed responses with incremental markdown rendering, clarifies API key file path documentation, and updates frontend components and themes accordingly.

Changes

Cohort / File(s) Summary
Documentation & Release Notes
docs/en_US/ai_tools.rst, docs/en_US/preferences.rst, docs/en_US/release_notes_9_14.rst
Clarified API key file path semantics for Anthropic/OpenAI to indicate filesystem context relative to the server and ~ expansion, and added release note entry for bug fix #9734 regarding LLM response streaming/rendering.
LLM Core Streaming Infrastructure
web/pgadmin/llm/chat.py, web/pgadmin/llm/client.py
Added new chat_with_database_stream generator function and chat_stream base method to enable streaming chat responses with tool call handling and incremental message history updates.
LLM Provider Implementations
web/pgadmin/llm/providers/anthropic.py, web/pgadmin/llm/providers/openai.py, web/pgadmin/llm/providers/docker.py, web/pgadmin/llm/providers/ollama.py
Implemented chat_stream with server-sent event (SSE) parsing for each provider, including streaming payload construction, incremental text/tool-call aggregation, error handling, and response finalization into LLMResponse objects.
NLQ Prompt Configuration
web/pgadmin/llm/prompts/nlq.py
Updated response format to require SQL statements in fenced code blocks with sql tag instead of JSON-only format, supporting multiple SQL blocks and per-query explanations.
LLM Help Text
web/pgadmin/llm/__init__.py
Extended help strings for Anthropic and OpenAI API key file fields to clarify that paths are server-relative and that ~ expands to the server user's home directory.
NLQ Chat Backend Refactor
web/pgadmin/tools/sqleditor/__init__.py
Migrated from chat_with_database to chat_with_database_stream, rewrote history handling to rebuild Message objects from provided history, and updated streaming event processing to handle text deltas, tool-use events, and final completion signals.
NLQ Chat Frontend Streaming UI
web/pgadmin/tools/sqleditor/static/js/components/sections/NLQChatPanel.jsx
Added incremental markdown rendering with parseMarkdownSegments, renderMarkdownText, and new MarkdownContent component; extended message types to include STREAMING mode; reworked SQL/code block rendering to support streaming content display with per-block actions (insert, replace, copy).
Theme Configuration
web/pgadmin/static/js/Theme/dark.js, web/pgadmin/static/js/Theme/light.js, web/pgadmin/static/js/Theme/high_contrast.js
Added hyperlinkColor property to otherVars for each theme to support styled hyperlink rendering.
Test Updates
web/pgadmin/tools/sqleditor/tests/test_nlq_chat.py
Updated NLQ chat test fixtures from JSON response format to markdown code fences; added test generator side-effect for chat_with_database_stream; added new test classes for SQL extraction from markdown and SSE event validation; removed history sync assertions.

Sequence Diagram(s)

sequenceDiagram
    participant Browser
    participant pgAdminServer as pgAdmin<br/>Server
    participant LLMChat as LLM Chat<br/>Module
    participant Provider as LLM<br/>Provider
    participant LLMBackend as LLM<br/>Backend API

    Browser->>pgAdminServer: POST /nlq_chat_stream<br/>(user_message, sid, did)
    pgAdminServer->>LLMChat: chat_with_database_stream()<br/>stream generator
    LLMChat->>LLMChat: Build message history<br/>& system prompt
    LLMChat->>Provider: chat_stream(messages, tools)
    
    loop Streaming Response
        Provider->>LLMBackend: Streaming HTTP POST
        LLMBackend-->>Provider: SSE chunks<br/>(text deltas, tool calls)
        Provider->>Provider: Parse & aggregate<br/>content/tool_calls
        Provider-->>LLMChat: Yield text chunks
        LLMChat->>LLMChat: Accumulate streamed text
        LLMChat-->>pgAdminServer: Yield text delta
        pgAdminServer-->>Browser: SSE event<br/>(text content)
    end
    
    loop Tool Use (if needed)
        LLMChat->>LLMChat: Detect tool_use event
        LLMChat-->>pgAdminServer: Yield tool_use tuple
        pgAdminServer->>pgAdminServer: Execute tool<br/>(database query)
        LLMChat->>LLMChat: Append tool result<br/>to history
        LLMChat->>Provider: Resume chat_stream
    end
    
    Provider-->>LLMChat: Yield final LLMResponse<br/>(complete content, usage)
    LLMChat-->>pgAdminServer: Yield ('complete',<br/>final_text, history)
    pgAdminServer->>pgAdminServer: Extract SQL<br/>from markdown
    pgAdminServer-->>Browser: SSE complete event<br/>(SQL, explanation)
    Browser->>Browser: Render streamed<br/>markdown incrementally<br/>with code blocks
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • akshay-joshi
  • anilsahoo20
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

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 and usage tips.

@dpage
Copy link
Contributor Author

dpage commented Mar 16, 2026

Urgh - based on the wrong branch.

@dpage dpage closed this Mar 16, 2026
@dpage dpage deleted the ai_key_docs branch March 16, 2026 16:54
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