title: asa-api
emoji: 🔎
colorFrom: yellow
colorTo: indigo
sdk: docker
pinned: false
license: mit
asa-api (Self-Hosted Docker + Tor)
asa-api is a self-hosted Docker API + GUI wrapper around asa::run_task().
It uses:
R+plumberfor HTTP endpoints- The
asapackage for orchestration (run_task,run_task_batch) - A lightweight password-protected browser GUI at
/ - A local Tor daemon for search/web egress inside the container
What This Service Exposes
GET /healthzPOST /v1/runfor a single promptPOST /v1/batchfor many promptsGET /GUI pagePOST /gui/queryused by the GUI
Security Model
- API bearer auth is required for
/v1/*:- Include
Authorization: Bearer 999
- Include
- GUI auth is password-based:
/gui/querychecksGUI_PASSWORD
Required Environment Variables
Set these when running the container:
GOOGLE_API_KEY(or the provider key you use)GUI_PASSWORD
Optional secrets / vars:
ASA_DEFAULT_BACKEND(defaults togeminiif unset; examples:openai,groq,anthropic,gemini,openrouter)ASA_DEFAULT_MODEL(example:gemini-2.5-flash)ASA_CONDA_ENV(default:asa_env)ASA_USE_BROWSER_DEFAULT(default:false, recommended for container stability)CORS_ALLOW_ORIGIN(default:*)
Provider-specific keys supported by asa include:
OPENAI_API_KEYGROQ_API_KEYANTHROPIC_API_KEYGOOGLE_API_KEY(orGEMINI_API_KEY)OPENROUTER_API_KEY- Bedrock credentials if using
bedrock
API Usage
1) Health check
curl -s http://localhost:7860/healthz
2) Single query
curl -s http://localhost:7860/v1/run \
-H "Content-Type: application/json" \
-H "Authorization: Bearer 999" \
-d '{
"prompt": "What is the population of Tokyo?",
"config": {
"backend": "gemini",
"model": "gemini-2.5-flash"
},
"run": {
"output_format": "text",
"recursion_limit": 20
}
}'
3) Structured JSON output
curl -s http://localhost:7860/v1/run \
-H "Authorization: Bearer 999" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Find Marie Curie birth year and nationality. Return JSON.",
"run": {
"output_format": "json"
}
}'
4) Batch query
curl -s http://localhost:7860/v1/batch \
-H "Authorization: Bearer 999" \
-H "Content-Type: application/json" \
-d '{
"prompts": [
"What is the capital of France?",
"What is the capital of Japan?"
],
"parallel": false,
"run": {
"output_format": "text"
}
}'
/v1/batch accepts only a plain JSON array of strings for prompts. Structured row objects that mirror upstream asa::run_task_batch() data-frame inputs are rejected by this adapter.
Request Shape
POST /v1/run
{
"prompt": "string, required",
"config": {
"...": "any asa::asa_config argument"
},
"run": {
"...": "any asa::run_task argument except prompt/config/agent"
},
"include_raw_output": false,
"include_trace_json": false
}
POST /v1/batch
{
"prompts": ["required", "array", "of strings"],
"config": {
"...": "any asa::asa_config argument"
},
"run": {
"...": "batch-compatible shared options only; single-run-only keys are rejected"
},
"batch": {
"...": "any asa::run_task_batch argument except prompts/config/agent"
},
"parallel": false,
"include_raw_output": false,
"include_trace_json": false
}
Future Compatibility Strategy
The adapter is intentionally resilient to asa changes:
- It dynamically inspects
formals(asa::asa_config),formals(asa::run_task), andformals(asa::run_task_batch). - It only forwards request keys that exist in current function signatures.
- For
/v1/batch, it rejects single-run-only passthrough keys instead of silently dropping them. - This avoids hard crashes when upstream adds/removes optional args.
GUI
- Open
/in your browser. - Enter
GUI_PASSWORD. - Enter prompt and choose output format.
- Leave
Use direct provider call (skip ASA)unchecked to run the normal ASA agent flow. - Check
Use direct provider call (skip ASA)to send the prompt straight to the configured provider/model without ASA search/tool orchestration. - Submit (Ctrl/Cmd + Enter is supported).
Notes:
- The checkbox is GUI-only;
/v1/runand/v1/batchremain ASA endpoints. - The provider/model selection stays server-side and is not user-selectable in the GUI.
Docker Build and Runtime
The Dockerfile clones asa-software during build and installs asa from source.
R dependency strategy in this image:
- Base image is
rocker/r2u:24.04. - Core R runtime packages (
plumber,jsonlite,reticulate,remotes) are installed as binary apt packages (r-cran-*), not compiled from CRAN source. - This avoids source-compile failures such as
sodium->plumberinstall breaks. - The Docker build pre-creates
asa_envwith pinnedpython=3.12.3andopenssl=3.0.13before callingasa::build_backend(), reducing rebuild drift that can breakreticulateSSL imports on Ubuntu 24.04 / Hugging Face rebuilds. - Runtime linker guardrails are set so
reticulateprefers conda environment libraries (/opt/conda/envs/asa_env/liband/opt/conda/lib) to avoid C++ ABI loader mismatches. - Tor is installed in the image and started before the API. If Tor does not become ready, the container exits instead of serving direct search traffic.
Build args:
ASA_SOFTWARE_REPO(default:https://github.com/cjerzak/asa-software)ASA_SOFTWARE_REF(default:main)ASA_CONDA_PYTHON_VERSION(default:3.12.3)ASA_CONDA_OPENSSL_VERSION(default:3.0.13)
Local build:
docker build -t asa-api .
Local run:
docker run --rm -p 7860:7860 \
-e GOOGLE_API_KEY=... \
-e GUI_PASSWORD=XXX \
asa-api
Then open:
http://localhost:7860/healthzhttp://localhost:7860/
Tor Deployment Defaults
The container deploys Tor locally and exports these runtime defaults before starting plumber:
ASA_PROXY=socks5h://127.0.0.1:9050TOR_CONTROL_PORT=9051ASA_TOR_CONTROL_COOKIE=/tmp/tor/control.authcookie
Tor scope is intentionally limited:
- Search and webpage retrieval traffic uses Tor.
- LLM provider API traffic remains direct, matching upstream
asabehavior. - Browser/Selenium search remains disabled by default.
Startup behavior is fail-closed:
- Tor must answer a probe to
https://check.torproject.org/api/ipwithIsTor=true. - If the SOCKS proxy, ControlPort, or cookie setup never becomes ready, the container exits non-zero.
GET /healthz now includes Tor readiness fields:
tor_enabledtor_readytor_proxytor_control_porttor_cookie_presenttor_cookie_readable
You can override the local proxy defaults if needed:
ASA_PROXYTOR_CONTROL_PORTASA_TOR_CONTROL_COOKIEASA_TOR_PROBE_URLASA_TOR_STARTUP_TIMEOUT_SEC
Notes
- Browser/Selenium tier is disabled by default (
use_browser = FALSE) for better reliability in minimal containers. - If you want browser tier, set
config.use_browser = trueexplicitly per request and ensure supporting binaries are installed. - If startup fails with Python import/linker errors (for example
CXXABI_1.3.15 not found), inspect container logs and verifyGET /healthzforboot_errordetails once the service is up.