diff --git a/extensions/chat-with-content/CHANGELOG.md b/extensions/chat-with-content/CHANGELOG.md index fd002cc0..0008e6ec 100644 --- a/extensions/chat-with-content/CHANGELOG.md +++ b/extensions/chat-with-content/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Rewrote the description and the README. (#448) - The setup screen now shows only the step still missing rather than repeating both. (#447) - Refreshed the default model names to Claude Sonnet 4.5. (#447) diff --git a/extensions/chat-with-content/CONTRIBUTING.md b/extensions/chat-with-content/CONTRIBUTING.md new file mode 100644 index 00000000..4331a3d4 --- /dev/null +++ b/extensions/chat-with-content/CONTRIBUTING.md @@ -0,0 +1,40 @@ +# Contributing to Chat with Content + +## Prerequisites + +- Python 3.10 or higher +- [uv](https://docs.astral.sh/uv/) + +## Setup + +Run `uv sync` to install the app and test dependencies. + +## Development + +Run `uv run shiny run app.py` to start the app locally. It reads the same +`CHATLAS_CHAT_PROVIDER_MODEL` / API-key environment variables described in the +[README](./README.md). + +## Tests + +Run `uv run pytest`. The tests cover the pure helpers in `helpers.py`, which is +where logic is put when it can be tested without a running session or any LLM / +Connect calls. What is left in `app.py` needs a live Shiny session, so check it +by running the app. CI runs the same command. + +## Bundle + +The files sent in the deployment bundle are: + +- `app.py` +- `helpers.py` +- `requirements.txt` +- `manifest.json` + +`pyproject.toml`, tests, and repo docs are not bundled. + +## Changelog + +Update the [CHANGELOG](./CHANGELOG.md) using the +[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format, referencing the +PR number, and bump `extension.version` in `manifest.json` to trigger a release. diff --git a/extensions/chat-with-content/README.md b/extensions/chat-with-content/README.md index 5ac24e24..801049e3 100644 --- a/extensions/chat-with-content/README.md +++ b/extensions/chat-with-content/README.md @@ -1,76 +1,81 @@ -# Chat with Content Extension +# Chat with Content -The "Chat with Content" extension for Posit Connect provides a way to interact with and query your static content using a chat interface powered by a Large Language Model (LLM). +## About this extension -## Overview +Chat with your content turns a report or data app you have published to Posit +Connect into something you can ask questions about. Pick a piece of static +content from a dropdown, and the app extracts its text, hands it to a Large +Language Model (LLM), and answers your questions about it in a chat panel beside +the rendered page. It opens each document with a short summary and a few +suggested questions, and answers using only the selected content. -This Shiny application allows users to select a piece of static content (such as static R Markdown, Quarto, or Jupyter Notebook documents) deployed on Posit Connect and ask questions about it. The application extracts the content from the selected document, provides it as context to an LLM, and displays the answers in a chat window. +It works with static, rendered content: Quarto, R Markdown, and Jupyter +documents, and static HTML. -Key features: -- Lists available static content from Connect for the user to choose from. -- Displays the selected content in an iframe. -- Provides a chat interface to ask questions about the content. -- Uses an LLM to generate answers based *only* on the provided content. -- Suggests relevant questions to ask about the content. +## How it works -## Setup - -### Administrator Setup - -As a Posit Connect administrator, you need to configure the environment for this extension to run correctly. - -1. **Publish the Extension**: Publish this application to Posit Connect. - -2. **Configure Environment Variables**: In the content settings, set the following environment variables to configure the LLM provider. This extension uses the `chatlas` library, which supports various LLM providers like OpenAI, Azure OpenAI, Google Gemini, Anthropic, and Anthropic on AWS Bedrock. - - Set `CHATLAS_CHAT_PROVIDER_MODEL` to specify the provider and model in the format `provider/model`. You also need to provide the API key for the chosen service. - - **Example for OpenAI:** - - - `CHATLAS_CHAT_PROVIDER_MODEL`: `openai/gpt-4o` - - `OPENAI_API_KEY`: `` (Set this as a secret) - - **Example for Google Gemini:** - - - `CHATLAS_CHAT_PROVIDER_MODEL`: `google/gemini-1.5-flash` - - `GOOGLE_API_KEY`: `` (Set this as a secret) - - **Example for Anthropic:** +The app calls the Connect API as the signed-in viewer, through a Connect Visitor +API Key integration, so each person sees and chats only with the content they +already have permission to open. No admin API key is stored in the app. When you +choose a document, the app renders it in the main panel, converts it to markdown, +and sends that markdown to the LLM as the only context, with a system prompt that +tells the model to answer from that content alone and to say when it can't. - - `CHATLAS_CHAT_PROVIDER_MODEL`: `anthropic/claude-sonnet-4-20250514` - - `ANTHROPIC_API_KEY`: `` (Set this as a secret) +The LLM connection is built with [chatlas](https://posit-dev.github.io/chatlas/), +so you can point it at OpenAI, Azure OpenAI, Anthropic, Google Gemini, or +Anthropic on AWS Bedrock by setting environment variables (see [Setup](#setup)). +Very large pages are truncated before they are sent to the model, so a big report +won't overflow its context window. - **Example for Azure OpenAI:** +## Deploy it - For Azure OpenAI, set `CHATLAS_CHAT_PROVIDER_MODEL` to `azure-openai` (with no model suffix) and pass the deployment-specific arguments via `CHATLAS_CHAT_ARGS`: +Deploy it straight from the Connect Gallery to get a copy running, then configure +it (below). To run a customized version, get the +[extension source](https://github.com/posit-dev/connect-extensions/tree/main/extensions/chat-with-content), +make your changes, and publish with +[`rsconnect deploy shiny`](https://docs.posit.co/rsconnect-python/) or a +[git-backed deployment](https://docs.posit.co/connect/user/git-backed/). Requires +Connect 2025.04.0 or newer with OAuth Integrations enabled. - - `CHATLAS_CHAT_PROVIDER_MODEL`: `azure-openai` - - `AZURE_OPENAI_API_KEY`: `` (Set this as a secret) - - `CHATLAS_CHAT_ARGS`: `{"deployment_id": "gpt-4.1-mini", "endpoint": "https://{your-resource-name}.openai.azure.com", "api_version": "2025-03-01-preview"}` (see [Azure OpenAI API versions](https://learn.microsoft.com/en-us/azure/ai-services/openai/api-version-deprecation)) - - **Example for Anthropic on AWS Bedrock:** - - The application uses the [botocore](https://botocore.amazonaws.com/v1/documentation/api/latest/reference/credentials.html) credential chain for AWS authentication. If the Connect server is running on an EC2 instance with an IAM role that grants access to Bedrock, credentials are automatically detected and no configuration is needed. In this case, the application uses the `us.anthropic.claude-sonnet-4-20250514-v1:0` model by default. - - To use Bedrock without an IAM role, set the following environment variables in the content settings: - - - `AWS_ACCESS_KEY_ID`: `` - - `AWS_SECRET_ACCESS_KEY`: `` (Set this as a secret) - - `AWS_REGION`: `` (e.g., `us-east-1`) - - `AWS_SESSION_TOKEN`: `` (Optional, for temporary credentials) - - For more details on supported providers and their arguments, see the [chatlas documentation](https://posit-dev.github.io/chatlas/reference/ChatAuto.html). - -3. **Enable Visitor API Key Integration**: This extension requires access to the Connect API on behalf of the visiting user to list their available content. In the content settings, add a "Connect Visitor API Key" integration. - -### User Setup - -Once the administrator has configured the extension, users can start using it. There is no specific setup required for end-users. - -## Usage +## Setup -1. Open the "Chat with Content" application in Posit Connect. -2. Use the dropdown menu to select a piece of content you want to chat with. The list shows static content you have access to. -3. The selected content will be displayed in the main panel. -4. The chat panel on the left will show a summary of the content and suggest some questions you can ask. -5. Type your questions about the content in the chat input box and press enter. The assistant will answer based on the information available in the document. +After deploying, configure two things in the content's settings: + +- Set an LLM provider and its API key on the **Advanced** tab, under + **Environment Variables**: set `CHATLAS_CHAT_PROVIDER_MODEL` plus the matching + key. For example, to use OpenAI's GPT-4o: + + ``` + CHATLAS_CHAT_PROVIDER_MODEL = openai/gpt-4o + OPENAI_API_KEY = + ``` + + Other providers follow the same pattern with their own model string and key + (`ANTHROPIC_API_KEY`, `GOOGLE_API_KEY`, ...); see the + [chatlas `ChatAuto` docs](https://posit-dev.github.io/chatlas/reference/ChatAuto.html) + for the full list. On AWS Bedrock with an instance role, credentials are + detected automatically and no variables are needed. (The older + `CHATLAS_CHAT_PROVIDER` and `CHATLAS_CHAT_ARGS` still work but are deprecated.) +- Add a "Connect Visitor API Key" integration so the app lists and reads content + as the viewer: on the **Access** tab, add it under **Integrations**. If it + isn't listed, an administrator must first create a **Connect API** integration + on your server. See the + [OAuth Integrations documentation](https://docs.posit.co/connect/user/oauth-integrations/). + +Until an LLM provider and the integration are configured, the app shows a setup +screen with just the step(s) still missing. + +## Customize it + +- Swap the model or provider by changing the environment variables above. +- Change how the assistant behaves by editing the system prompt in `app.py` (for + example, its tone or the suggested-prompt format). +- Adjust the context limit by changing `MAX_CONTEXT_CHARS` in `helpers.py`. The + browser also caps how much page HTML it sends, so to raise the limit much + above its default, raise `MAX_HTML_CHARS` in `app.py` too. + +## Learn more + +- [chatlas](https://posit-dev.github.io/chatlas/) +- [Shiny for Python](https://shiny.posit.co/py/) +- [Posit Connect OAuth integrations](https://docs.posit.co/connect/user/oauth-integrations/) diff --git a/extensions/chat-with-content/manifest.json b/extensions/chat-with-content/manifest.json index 72494caf..b176aa86 100644 --- a/extensions/chat-with-content/manifest.json +++ b/extensions/chat-with-content/manifest.json @@ -21,7 +21,7 @@ "extension": { "name": "chat-with-content", "title": "Chat with Content", - "description": "Provides a way to interact with and query content using an LLM chat interface.", + "description": "Chat with your published content on Connect using an LLM. Pick a report, notebook, or static page you can access, and the app answers questions about it in a chat panel beside the rendered page, running as the signed-in viewer through a Connect Visitor API Key so each person only chats with content they are allowed to open. Works with OpenAI, Anthropic, Google, Azure, or AWS Bedrock.", "homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/chat-with-content", "category": "extension", "tags": [ @@ -34,17 +34,17 @@ "requiredFeatures": [ "OAuth Integrations" ], - "version": "0.0.7" + "version": "0.0.8" }, "files": { "requirements.txt": { - "checksum": "cb941e127f37bee990fb5d435ae994ff" + "checksum": "8f588192fd4263ef2a3ea7400f23aa26" }, "app.py": { - "checksum": "7c91ec03b422e95d1b8a31bfd75d5fe5" + "checksum": "ff186b94b21ac5ee7fed82b34de326a7" }, "helpers.py": { - "checksum": "cf9684fe4097503d78c69724e795579b" + "checksum": "5e103f2e729b25f85e46da64ac171f84" } } }