Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ jobs:
- name: Install protobuf Go plugins
run: |
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.36.11
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.6.2
echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"

- name: Build embedded Gateway WebUI
Expand Down
81 changes: 0 additions & 81 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ COPY --from=gateway-builder /out/liveagent-gateway /usr/local/bin/liveagent-gate
USER liveagent

ENV PORT=8080
ENV LIVEAGENT_GATEWAY_GRPC_ADDR=:50051

EXPOSE 8080 50051
EXPOSE 8080

ENTRYPOINT ["/usr/local/bin/liveagent-gateway"]
5 changes: 2 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ DESKTOP_RELEASE_TAURI_CONFIG_FLAGS ?= --config $(DESKTOP_RELEASE_TAURI_CONFIG) $

DEV_GATEWAY_TOKEN ?= dev-token
DEV_GATEWAY_HTTP_ADDR ?= :50052
DEV_GATEWAY_GRPC_ADDR ?= :50051
DEV_WEBUI_PROXY_API ?= http://localhost:50052
GATEWAY_DOCKER_IMAGE ?= liveagent-gateway:local
RELEASE_TAG ?=
Expand Down Expand Up @@ -108,7 +107,7 @@ check-github-release-tag:

## Gateway development
dev-gateway:
go -C $(AGENT_GATEWAY_DIR) run ./cmd/gateway --token=$(DEV_GATEWAY_TOKEN) --http-addr=$(DEV_GATEWAY_HTTP_ADDR) --grpc-addr=$(DEV_GATEWAY_GRPC_ADDR)
go -C $(AGENT_GATEWAY_DIR) run ./cmd/gateway --token=$(DEV_GATEWAY_TOKEN) --http-addr=$(DEV_GATEWAY_HTTP_ADDR)

dev-webui:
npm_config_proxy_api=$(DEV_WEBUI_PROXY_API) pnpm --dir $(AGENT_GATEWAY_WEB_DIR) dev
Expand Down Expand Up @@ -137,7 +136,7 @@ gateway-docker-build:
docker build -t $(GATEWAY_DOCKER_IMAGE) .

gateway-docker-run:
docker run --rm -p 8080:8080 -p 50051:50051 -e LIVEAGENT_GATEWAY_TOKEN=$(DEV_GATEWAY_TOKEN) $(GATEWAY_DOCKER_IMAGE)
docker run --rm -p 8080:8080 -e LIVEAGENT_GATEWAY_TOKEN=$(DEV_GATEWAY_TOKEN) $(GATEWAY_DOCKER_IMAGE)

gateway-docker-smoke: gateway-docker-build
@set -e; \
Expand Down
70 changes: 22 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ LiveAgent is a **local-first** AI agent desktop client. It deeply integrates lar

### 🌐 Remote Gateway

- **Access from any browser** — Go + gRPC gateway with a WebUI for remotely controlling the local agent
- **Access from any browser** — Go gateway (WebSocket + Protobuf) with a WebUI for remotely controlling the local agent
- **Disconnect recovery** — a bounded seq window replays short outages, with desktop-side persistence as the safety net

---
Expand Down Expand Up @@ -172,12 +172,11 @@ The desktop app works out of the box and depends on no server. Deploy the Gatewa
# Pull the image (built by GitHub Actions, multi-arch: amd64 / arm64)
docker pull ghcr.io/stack-cairn/liveagent-gateway:latest

# Run in the background (gRPC → host 50051 | HTTP/WebSocket → host 50052)
# Run in the background (HTTP/WebSocket → host 3000)
docker run -d \
--name liveagent-gateway \
--restart unless-stopped \
-p 50051:50051 \
-p 50052:8080 \
-p 3000:8080 \
-e LIVEAGENT_GATEWAY_TOKEN=your-token \
ghcr.io/stack-cairn/liveagent-gateway:latest
```
Expand All @@ -190,8 +189,7 @@ docker pull ghcr.io/stack-cairn/liveagent-gateway:latest \
&& docker run -d \
--name liveagent-gateway \
--restart unless-stopped \
-p 50051:50051 \
-p 50052:8080 \
-p 3000:8080 \
-e LIVEAGENT_GATEWAY_TOKEN=your-token \
ghcr.io/stack-cairn/liveagent-gateway:latest \
&& docker image prune -f
Expand All @@ -200,60 +198,36 @@ docker pull ghcr.io/stack-cairn/liveagent-gateway:latest \
<details>
<summary><b>Nginx reverse proxy configuration</b> — reference for custom domains / TLS</summary>

> The Gateway serves two kinds of traffic:
> Since protocol v2, all traffic — the WebUI, the HTTP API, and the WebSocket links of both the browser and the desktop app — goes through the single HTTP port (default 3000).
>
> the desktop app's bidirectional gRPC stream (default 50051) and the browser's HTTP / WebSocket (default 50052).
>
> When exposing through Nginx, proxy them separately. Both gRPC and WebSocket are long-lived connections, so raise the timeouts:
> WebSocket upgrades happen on several paths (`/ws/v2`, `/ws/v2/agent`, `/ws/v2/terminal`, and tunnels under `/t/`), so the simplest correct setup enables the upgrade on the whole vhost:

```nginx
# GUI Remote: gRPC Authenticate + AgentConnect
location /liveagent.gateway.v1.AgentGateway/ {
grpc_pass grpc://127.0.0.1:50051;

grpc_set_header Host $host;
grpc_set_header Authorization $http_authorization;
grpc_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
grpc_set_header X-Forwarded-Proto $scheme;

grpc_socket_keepalive on;
grpc_read_timeout 24h;
grpc_send_timeout 24h;
}

# WebUI WebSocket
location = /ws {
proxy_pass http://127.0.0.1:50052;

# WebUI SPA/static/API + every WebSocket link (browser and desktop)
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;

# WebSocket upgrade
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

# Required: the Gateway's same-origin check compares the browser's
# Origin header against X-Forwarded-Proto + Host
proxy_set_header Host $host;
proxy_set_header Authorization $http_authorization;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

proxy_read_timeout 24h;
proxy_send_timeout 24h;
# The Gateway pings every WebSocket connection every 15s,
# so a generous-but-finite timeout is enough
proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_buffering off;
}

# WebUI SPA/static/API
location / {
proxy_pass http://127.0.0.1:50052;

proxy_set_header Host $host;
proxy_set_header Authorization $http_authorization;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

proxy_read_timeout 10m;
proxy_send_timeout 10m;
}
```

> Upstream ports map one-to-one to the host ports from the `docker run` above: gRPC 50051, HTTP/WebSocket 50052 (inside the container, HTTP actually listens on `PORT=8080`). The gRPC proxy requires Nginx to accept the desktop connection over HTTP/2 (`listen 443 ssl; http2 on;`).
> The upstream port maps to the host port from the `docker run` above: HTTP/WebSocket 3000 (inside the container, HTTP actually listens on `PORT=8080`). The server block needs `listen 443 ssl;` and a `client_max_body_size` large enough for attachment uploads (e.g. `100m`).

</details>

Expand All @@ -278,10 +252,10 @@ Expand the Development Guide below for the full set of Make commands.
│ WebSocket / HTTP
┌────────────────────────────▼─────────────────────────────────┐
│ Agent Gateway │
Go · gRPC · HTTP · Session Manager · Event Store │
│ Go · WebSocket · HTTP · Session Manager · Event Store │
│ (Railway / Docker / self-hosted) │
└────────────────────────────┬─────────────────────────────────┘
gRPC (bidirectional stream)
WebSocket v2 (bidirectional stream)
┌────────────────────────────▼─────────────────────────────────┐
│ Agent GUI │
│ Tauri 2 · React 19 · Rust │
Expand All @@ -300,10 +274,10 @@ Expand the Development Guide below for the full set of Make commands.
| **Agent GUI** · Build | Vite 8 + pnpm |
| **Agent GUI** · Styling | Tailwind CSS 4 + Radix UI |
| **Agent GUI** · Rendering | streamdown + KaTeX + Mermaid + Monaco Editor |
| **Agent GUI** · Backend | Rust + Tokio + SQLite (rusqlite) + gRPC (tonic) |
| **Agent GUI** · Backend | Rust + Tokio + SQLite (rusqlite) + WebSocket (tokio-tungstenite) |
| **Agent GUI** · LLM | @earendil-works/pi-ai · @openai/codex-sdk · claude-agent-sdk |
| **Gateway** · Language | Go 1.25 |
| **Gateway** · Protocols | gRPC + Protobuf + HTTP + WebSocket |
| **Gateway** · Protocols | WebSocket + Protobuf + HTTP |
| **Gateway** · Web UI | React + Vite + Tailwind CSS (embedded) |
| **Gateway** · Deployment | Docker multi-stage · Railway CI/CD |

Expand Down
Loading
Loading