This is an automated email from the ASF dual-hosted git repository.
bobbai00 pushed a commit to branch release/v1.1.0-incubating
in repository https://gitbox.apache.org/repos/asf/texera.git
The following commit(s) were added to refs/heads/release/v1.1.0-incubating by
this push:
new 14051c4d4e feat(deployment, v1.1.0-incubating): add agent-service and
litellm to single-node deployment (#4592)
14051c4d4e is described below
commit 14051c4d4eab41f777886fea08f1f565714c18f6
Author: Jiadong Bai <[email protected]>
AuthorDate: Thu Apr 30 23:09:34 2026 -0700
feat(deployment, v1.1.0-incubating): add agent-service and litellm to
single-node deployment (#4592)
### What changes were proposed in this PR?
Backport of #4544.
### Any related issues, documentation, discussions?
### How was this PR tested?
### Was this PR authored or co-authored using generative AI tooling?
Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
Co-authored-by: Xinyuan Lin <[email protected]>
Co-authored-by: Chen Li <[email protected]>
---
.github/workflows/build-and-push-images.yml | 3 ++
bin/agent-service.dockerfile | 36 +++++++++++++++
bin/single-node/.env | 14 ++++++
bin/single-node/README.md | 71 +++++++++++++++++++++++++++--
bin/single-node/docker-compose.yml | 46 ++++++++++++++++++-
bin/single-node/litellm-config.yaml | 29 ++++++++++++
bin/single-node/nginx.conf | 27 +++++++++++
7 files changed, 219 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/build-and-push-images.yml
b/.github/workflows/build-and-push-images.yml
index b63743ec2c..d6688336b8 100644
--- a/.github/workflows/build-and-push-images.yml
+++ b/.github/workflows/build-and-push-images.yml
@@ -276,6 +276,9 @@ jobs:
"workflow-computing-unit-managing-service")
image_name="texera-workflow-computing-unit-managing-service"
;;
+ "agent-service")
+ image_name="texera-agent-service"
+ ;;
*)
# Default: use service name as-is
image_name="$service"
diff --git a/bin/agent-service.dockerfile b/bin/agent-service.dockerfile
new file mode 100644
index 0000000000..e0f6c0c232
--- /dev/null
+++ b/bin/agent-service.dockerfile
@@ -0,0 +1,36 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+FROM oven/bun:1-alpine
+
+WORKDIR /app
+
+COPY agent-service/package.json agent-service/bun.lock ./
+
+RUN bun install --frozen-lockfile --production
+
+COPY agent-service/src ./src
+COPY agent-service/tsconfig.json ./
+
+COPY LICENSE-binary ./LICENSE
+COPY NOTICE-binary ./NOTICE
+COPY DISCLAIMER-WIP ./DISCLAIMER-WIP
+COPY licenses ./licenses
+
+EXPOSE 3001
+
+CMD ["bun", "run", "src/server.ts"]
diff --git a/bin/single-node/.env b/bin/single-node/.env
index dafec10ccc..54aa2f5b32 100644
--- a/bin/single-node/.env
+++ b/bin/single-node/.env
@@ -83,3 +83,17 @@ STORAGE_ICEBERG_CATALOG_POSTGRES_PASSWORD=password
# File service endpoints
FILE_SERVICE_GET_PRESIGNED_URL_ENDPOINT=http://file-service:9092/api/dataset/presign-download
FILE_SERVICE_UPLOAD_ONE_FILE_TO_DATASET_ENDPOINT=http://file-service:9092/api/dataset/did/upload
+
+# Toggles the texera agent panel; set false to hide it in the GUI.
+GUI_WORKFLOW_WORKSPACE_COPILOT_ENABLED=true
+
+# Litellm key and URL for internal LLM traffic
+LITELLM_MASTER_KEY=sk-texera-internal-do-not-share
+LITELLM_BASE_URL=http://litellm:4000
+
+# Configurations for agent-service to connect to Texera's services
+LLM_ENDPOINT=http://nginx:8080
+LLM_API_KEY=dummy
+TEXERA_DASHBOARD_SERVICE_ENDPOINT=http://dashboard-service:8080
+WORKFLOW_COMPILING_SERVICE_ENDPOINT=http://workflow-compiling-service:9090
+WORKFLOW_EXECUTION_SERVICE_ENDPOINT=http://workflow-runtime-coordinator-service:8085
diff --git a/bin/single-node/README.md b/bin/single-node/README.md
index 605801f216..fd45b068c4 100644
--- a/bin/single-node/README.md
+++ b/bin/single-node/README.md
@@ -88,7 +88,7 @@ Press `Ctrl+C` in the terminal to stop Texera.
If you already closed the terminal, you can go to the installation folder and
run:
```bash
-docker compose stop
+docker compose --profile examples stop
```
to stop Texera.
@@ -98,11 +98,33 @@ Same as the way you [launch Texera](#launch-texera).
### Uninstall
To remove Texera and all its data, go to the installation folder and run:
```bash
-docker compose down -v
+docker compose --profile examples down -v
```
> ⚠️ Warning: This will permanently delete all the data used by Texera.
+## Enable the Texera Agent
+
+The Texera agent is powered by a large language model (LLM). By default,
Texera uses [Claude Haiku 4.5](https://www.anthropic.com/claude/haiku) as the
LLM and queries it through [LiteLLM](https://docs.litellm.ai/). Without an API
key, the Texera agent panel still appears but model calls will fail with a
provider auth error.
+
+To enable it:
+
+1. [Stop Texera](#stop) if it is already running.
+2. Get an API key for the LLM. Since Claude Haiku 4.5 is enabled by default,
you need an [Anthropic API key](https://console.anthropic.com/settings/keys).
+3. Export the key and restart Texera:
+ ```bash
+ export ANTHROPIC_API_KEY=sk-ant-...
+ docker compose --profile examples up
+ ```
+
+Once Texera is up, create a new workflow and open the Texera agent panel at
the bottom right. Type a task like:
+
+> For /texera/popular-movies-of-imdb/v1/TMDb_updated.csv, visualize the top 10
most-voted movies.
+
+To switch providers or add more LLMs, see [Add more LLMs or
providers](#add-more-llms-or-providers).
+
+
+
## Advanced Settings
Before making any of the changes below, please [stop Texera](#stop) first.
Once you finish the changes, [restart Texera](#restart) to apply them.
@@ -146,6 +168,45 @@ $ docker compose up
y // answer y to this prompt
```
+### Add more LLMs or providers
+Only Claude Haiku 4.5 is enabled by default. To add more LLMs, open
`litellm-config.yaml` in the installation folder and append entries under
`model_list`. Each entry follows this shape:
+```diff
+ model_list:
+ ...
++ - model_name: <name shown in Texera>
++ litellm_params:
++ model: <provider model id>
++ api_key: "os.environ/<API_KEY_ENV_VAR>"
+```
+For example, to add OpenAI's GPT-5.2 and Google's Gemini 2.5 Pro:
+```diff
+ model_list:
+ ...
++ - model_name: gpt-5.2
++ litellm_params:
++ model: gpt-5.2
++ api_key: "os.environ/OPENAI_API_KEY"
++
++ - model_name: gemini-2.5-pro
++ litellm_params:
++ model: gemini/gemini-2.5-pro
++ api_key: "os.environ/GEMINI_API_KEY"
+```
+Make sure to set the corresponding API key environment variable when you
launch Texera (see [Enable the Texera Agent](#enable-the-texera-agent)). Get
keys from each provider's console — for example,
[OpenAI](https://platform.openai.com/api-keys) or
[Google](https://aistudio.google.com/apikey).
+
+If your provider is not Anthropic, OpenAI, or Google, also pass its key into
the LiteLLM container by editing `docker-compose.yml`:
+```diff
+ litellm:
+ ...
+ environment:
+ ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
+ OPENAI_API_KEY: ${OPENAI_API_KEY:-}
+ GEMINI_API_KEY: ${GEMINI_API_KEY:-}
++ <NEW_API_KEY>: ${<NEW_API_KEY>:-}
+```
+
+For the full list of supported providers and model IDs, see the [LiteLLM proxy
config docs](https://docs.litellm.ai/docs/providers).
+
## Troubleshooting
### Port conflicts
@@ -166,8 +227,8 @@ PostgreSQL only runs the database initialization scripts on
first startup (when
To resolve this, remove all existing volumes and start fresh:
```
-docker compose down -v
-docker compose up
+docker compose --profile examples down -v
+docker compose --profile examples up
```
-> ⚠️ Warning: `docker compose down -v` permanently deletes all Texera data.
+> ⚠️ Warning: `docker compose --profile examples down -v` permanently deletes
all Texera data.
diff --git a/bin/single-node/docker-compose.yml
b/bin/single-node/docker-compose.yml
index 4329bb3e71..e26fe8aa95 100644
--- a/bin/single-node/docker-compose.yml
+++ b/bin/single-node/docker-compose.yml
@@ -299,7 +299,7 @@ services:
timeout: 3s
retries: 10
- # AccessControlService handles user permissions and access control
+ # AccessControlService handles user permissions and proxies LLM API traffic
access-control-service:
image:
${IMAGE_REGISTRY:-ghcr.io/apache}/texera-access-control-service:${IMAGE_TAG:-latest}
container_name: access-control-service
@@ -364,7 +364,7 @@ services:
volumes:
- workflow_result_data:/amber/user-resources
- # DashboardService provides endpoints for hub resource management.
+ # DashboardService provides endpoints for community resource (e.g.
workflows, users) management
dashboard-service:
image:
${IMAGE_REGISTRY:-ghcr.io/apache}/texera-dashboard-service:${IMAGE_TAG:-latest}
container_name: dashboard-service
@@ -386,6 +386,47 @@ services:
timeout: 3s
retries: 10
+ # LLM API proxy for different providers
+ litellm:
+ image: ghcr.io/berriai/litellm:v1.83.10-stable
+ container_name: litellm
+ restart: always
+ # Keys read from shell first, falling back to .env.
+ environment:
+ ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
+ OPENAI_API_KEY: ${OPENAI_API_KEY:-}
+ GEMINI_API_KEY: ${GEMINI_API_KEY:-}
+ LITELLM_MASTER_KEY: ${LITELLM_MASTER_KEY:-}
+ volumes:
+ - ./litellm-config.yaml:/app/config.yaml:ro
+ command: ["--config", "/app/config.yaml", "--port", "4000", "--host",
"0.0.0.0"]
+ healthcheck:
+ test: ["CMD", "python", "-c", "import urllib.request;
urllib.request.urlopen('http://localhost:4000/health/liveliness').read()"]
+ interval: 10s
+ timeout: 5s
+ retries: 10
+ start_period: 15s
+
+ # AgentService manages the texera agents' interal states, and provide
endpoints for CRUD agents
+ agent-service:
+ image:
${IMAGE_REGISTRY:-ghcr.io/apache}/texera-agent-service:${IMAGE_TAG:-latest}
+ container_name: agent-service
+ restart: always
+ depends_on:
+ dashboard-service:
+ condition: service_healthy
+ workflow-compiling-service:
+ condition: service_healthy
+ workflow-runtime-coordinator-service:
+ condition: service_started
+ env_file:
+ - .env
+ healthcheck:
+ test: ["CMD", "wget", "--spider", "-q",
"http://localhost:3001/api/healthcheck"]
+ interval: 5s
+ timeout: 3s
+ retries: 10
+
# Part 3: reverse proxy service for Texera's micro services
nginx:
image: nginx:alpine
@@ -398,6 +439,7 @@ services:
- config-service
- access-control-service
- workflow-computing-unit-managing-service
+ - agent-service
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
ports:
diff --git a/bin/single-node/litellm-config.yaml
b/bin/single-node/litellm-config.yaml
new file mode 100644
index 0000000000..1a4ff14a4c
--- /dev/null
+++ b/bin/single-node/litellm-config.yaml
@@ -0,0 +1,29 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# LiteLLM model list for the single-node deployment. API keys are read
+# from environment variables passed to the container. To add more
+# models, follow the same shape — see
https://docs.litellm.ai/docs/proxy/configs.
+
+litellm_settings:
+ drop_params: true
+
+model_list:
+ - model_name: claude-haiku-4.5
+ litellm_params:
+ model: claude-haiku-4-5-20251001
+ api_key: "os.environ/ANTHROPIC_API_KEY"
diff --git a/bin/single-node/nginx.conf b/bin/single-node/nginx.conf
index 7ab4295a2b..515a7016da 100644
--- a/bin/single-node/nginx.conf
+++ b/bin/single-node/nginx.conf
@@ -21,6 +21,9 @@ http {
include mime.types;
default_type application/octet-stream;
+ # Suppress per-request access logs; errors still go to error_log.
+ access_log off;
+
server {
listen 8080;
@@ -54,6 +57,30 @@ http {
proxy_set_header X-Real-IP $remote_addr;
}
+ # LLM API traffic goes through access-control-service, which then
forwards to LiteLLM.
+ location = /api/models {
+ proxy_pass http://access-control-service:9096;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ }
+
+ location /api/chat/ {
+ proxy_pass http://access-control-service:9096;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ }
+
+ location /api/agents {
+ proxy_pass http://agent-service:3001;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_read_timeout 1d;
+ proxy_send_timeout 1d;
+ }
+
location /api/ {
proxy_pass http://dashboard-service:8080;
proxy_set_header Host $host;