diff --git a/.env b/.env index 419976f..ab9c670 100644 --- a/.env +++ b/.env @@ -1 +1,5 @@ +# This specifies the Invariant Explorer instance where the proxy will push the traces +# Set this to https://preview-explorer.invariantlabs.ai if you want to push to Preview. +# If you want to push to a local instance of explorer, then specify the app-api docker container name like: +# http://:8000 to push to the local explorer instance. INVARIANT_API_URL=https://explorer.invariantlabs.ai diff --git a/README.md b/README.md index 9520fac..1ad0f1f 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,43 @@ # **Invariant Proxy** -Invariant Proxy is a lightweight Docker service that acts as an intermediary between AI Agents and LLM providers (such as OpenAI and Anthropic). It captures and forwards agent interactions to the [Invariant Explorer](https://explorer.invariantlabs.ai/), enabling seamless debugging, visualization and exploration of traces. +Invariant Proxy is a lightweight Docker service that acts as an intermediary between AI Agents and LLM providers (such as OpenAI and Anthropic). It captures and forwards agent interactions to the [Invariant Explorer](https://explorer.invariantlabs.ai/), enabling seamless debugging, visualization, and exploration of traces. ![Invariant Proxy Diagram](resources/images/invariant-proxy.png) +--- + ## **Why Use Invariant Proxy?** - ✅ **Intercept AI interactions** for better debugging and analysis. - ✅ **Seamlessly forward API requests** to OpenAI, Anthropic, and other LLM providers (**supports streaming responses too**). +- ✅ **Works with AI Agents** like OpenHands, SWE-agent, etc. - ✅ **Automatically store and organize traces** in the Invariant Explorer. -## **Getting Started** -To integrate the Proxy with your AI agent, you’ll need to modify how your client interacts with LLM providers. +--- -1. **Setup an Invariant API Key** - Follow the instructions [here](https://explorer.invariantlabs.ai/docs/explorer/Explorer_API/1_client_setup/) to obtain an API key. +## **Getting Started** + +### **Run the Proxy Locally** +To start the Invariant Proxy, run: + +```bash +bash run.sh build && bash run.sh up +``` + +This will launch the proxy at [http://localhost:8005/api/v1/proxy/](http://localhost:8005/api/v1/proxy/docs/). + +### **Set Up an Invariant API Key** +1. Follow the instructions [here](https://explorer.invariantlabs.ai/docs/explorer/Explorer_API/1_client_setup/) to obtain an API key. This allows the proxy to push traces to [Invariant Explorer](https://explorer.invariantlabs.ai). + +--- + +## **Integration Guides** ### **🔹 OpenAI Integration** -2. To setup an OpenAI API key follow the steps [here](https://platform.openai.com/docs/quickstart#create-and-export-an-api-key). -3. **Modify OpenAI Client Setup** - Instead of connecting directly to OpenAI, configure your `OpenAI` client to use the proxy. +1. Follow [these steps](https://platform.openai.com/docs/quickstart#create-and-export-an-api-key) to obtain an OpenAI API key. +2. **Modify OpenAI Client Setup** + + Instead of connecting directly to OpenAI, configure your `OpenAI` client to use the proxy: ```python from httpx import Client @@ -31,17 +49,16 @@ To integrate the Proxy with your AI agent, you’ll need to modify how your clie "Invariant-Authorization": "Bearer your-invariant-api-key" }, ), - base_url="https://explorer.invariantlabs.ai/api/v1/proxy/{add-your-dataset-name-here}/openai", + base_url="http://localhost:8005/api/v1/proxy/{add-your-dataset-name-here}/openai", ) - # If a dataset with the given name already doesn't exist in Invariant Explorer, this will create the dataset - # before adding the traces to it. - # Make API requests to OpenAI using the client as usual. + ``` + + > **Note:** Do not include the curly braces `{}`. If the dataset does not exist in Invariant Explorer, it will be created before adding traces. ### **🔹 Anthropic Integration** -2. To setup an Anthropic API key follow the steps [here](https://docs.anthropic.com/en/docs/initial-setup#set-your-api-key). -3. **Modify Anthropic Client Setup** - Instead of connecting directly to Anthropic, configure your `Anthropic` client to use the proxy. +1. Follow [these steps](https://docs.anthropic.com/en/docs/initial-setup#set-your-api-key) to obtain an Anthropic API key. +2. **Modify Anthropic Client Setup** ```python from httpx import Client @@ -53,19 +70,72 @@ To integrate the Proxy with your AI agent, you’ll need to modify how your clie "Invariant-Authorization": "Bearer your-invariant-api-key" }, ), - base_url="https://explorer.invariantlabs.ai/api/v1/proxy/{add-your-dataset-name-here}/anthropic", + base_url="http://localhost:8005/api/v1/proxy/{add-your-dataset-name-here}/anthropic", ) - - # If a dataset with the given name already doesn't exist in Invariant Explorer, this will create the dataset - # before adding the traces to it. - # Make API requests to Anthropic using the client as usual. + ``` -### Run -```bash -./run.sh up + > **Note:** Do not include the curly braces `{}`. If the dataset does not exist in Invariant Explorer, it will be created before adding traces. +--- + +## **OpenHands Integration** +[OpenHands](https://github.com/All-Hands-AI/OpenHands) (formerly OpenDevin) is a platform for software development agents powered by AI. + +### **How to Integrate OpenHands with Invariant Proxy** + +#### **Step 1: Modify the API Base** +Enable the `Advanced Options` toggle under settings and update the `Base URL`: + + + +#### **Step 2: Adjust the API Key Format** +Modify the API Key format in the settings modal: + +```text +{your-llm-api-key}|invariant-auth: {your-invariant-api-key} ``` -### Run tests +> **Note:** Do not include the curly braces `{}`. + +The Invariant Proxy extracts the `invariant-auth` field from the API key and correctly forwards it to Invariant Explorer while sending the actual API key to OpenAI or Anthropic. + +--- + +## **SWE-agent Integration** +[SWE-agent](https://github.com/SWE-agent/SWE-agent) allows your preferred language model (e.g., GPT-4o or Claude Sonnet 3.5) to autonomously utilize tools for various tasks, such as fixing issues in real GitHub repositories. + +### **Using SWE-agent with Invariant Proxy** +SWE-agent does not support custom headers, so you **cannot** pass the Invariant API Key via `Invariant-Authorization`. However, **there is a workaround** using the Invariant Proxy. + +#### **Step 1: Modify the API Base** + +Run `sweagent` with the following flag: + +```bash +--agent.model.api_base=http://localhost:8005/api/v1/proxy/{add-your-dataset-name-here}/openai +``` + +> **Note:** Do not include the curly braces `{}`. + +#### **Step 2: Adjust the API Key Format** +Instead of setting your API Key normally, modify the environment variable as follows: + +```bash +export OPENAI_API_KEY={your-openai-api-key}|invariant-auth: {your-invariant-api-key} +export ANTHROPIC_API_KEY={your-anthropic-api-key}|invariant-auth: {your-invariant-api-key} +``` + +> **Note:** Do not include the curly braces `{}`. + +This setup ensures that SWE-agent works seamlessly with Invariant Proxy, maintaining compatibility while enabling full functionality. 🚀 + +--- + +## **Development** + +### **Run Tests** +To run tests, execute: + ```bash ./run.sh tests ``` + diff --git a/docker-compose.local.yml b/docker-compose.local.yml index 3096fe1..c6a8606 100644 --- a/docker-compose.local.yml +++ b/docker-compose.local.yml @@ -15,8 +15,10 @@ services: target: /srv/proxy networks: - invariant-explorer-web - ports: [] + ports: + - "8005:8000" # Direct access without Traefik labels: + # For access via Traefik - "traefik.enable=true" - "traefik.http.routers.explorer-proxy-api.rule=(Host(`localhost`) && PathPrefix(`/api/v1/proxy/`)) || (Host(`127.0.0.1`) && PathPrefix(`/api/v1/proxy/`))" - "traefik.http.routers.explorer-proxy-api.entrypoints=invariant-explorer-web" diff --git a/resources/images/openhands-integration.png b/resources/images/openhands-integration.png new file mode 100644 index 0000000..5d17002 Binary files /dev/null and b/resources/images/openhands-integration.png differ diff --git a/run.sh b/run.sh index 6561b48..01f1bb4 100755 --- a/run.sh +++ b/run.sh @@ -6,8 +6,8 @@ up() { # Start your local docker-compose services docker compose -f docker-compose.local.yml up -d - echo "Proxy started at http://localhost/api/v1/proxy/" - echo "See http://localhost/api/v1/proxy/docs for API documentation" + echo "Proxy started at http://localhost:8005/api/v1/proxy/" + echo "See http://localhost:8005/api/v1/proxy/docs for API documentation" } build() {