Skip to main content

Developed by Dr. Sai's team at the Institute of High Energy Physics, Chinese Academy of Sciences (IHEP, CAS), this is a development framework designed for both single-agent and multi-agent collaborative systems

Project description

DrSai

A framework for developing AI Agent and Multi-Agent Systems, based on AutoGen 0.5.7. Developed by Dr. Sai's team at IHEP, CAS.


Quick Start (End Users)

# Prerequisites: Python ≥ 3.11. (Node.js is auto-downloaded on first run.)

pip install drsai
drsai             # Launches the interactive TUI

That's it. The wheel ships with a pre-built TUI bundle, and on first launch DrSai auto-downloads a portable Node.js runtime (~25 MB, one-time, cached in ~/.drsai/cache/node/). Subsequent launches are instant.

If you'd rather use a system Node, install Node.js ≥ 20 from https://nodejs.org/ and DrSai will use it automatically.


Architecture

DrSai ships two processes that talk over JSON-RPC:

┌─────────────────────────────────┐         ┌─────────────────────────────────┐
│  ui-tui (TypeScript + Ink)      │ ◀────▶  │  tui_gateway (Python)           │
│  React-based terminal UI        │  stdio  │  Agent orchestrator + RPC       │
└─────────────────────────────────┘         └─────────────────────────────────┘
                                                          │
                                                          ▼
                                            DrSaiCLIAssistant (autogen agent)
  • ui-tui/ — TypeScript/React/Ink frontend (compiled to single 5 MB ESM bundle)
  • python/packages/drsai/ — Python backend: agent, gateway, slash commands, session store

Requirements

Tool Version Why
Python ≥ 3.11 Backend, agent runtime
Node.js ≥ 20 Run the TUI bundle. Auto-downloaded on first launch (~25 MB) if not on PATH.
pnpm ≥ 9 (dev only) Build the TUI bundle
pip / build latest Build the wheel
twine latest Upload to PyPI

Building & Publishing

One-shot release build

From the repo root:

./scripts/build-wheel.sh

This script does three things:

  1. pnpm install && pnpm build in ui-tui/ → produces ui-tui/dist/entry.mjs (esbuild bundle, ~5 MB)
  2. python -m build --wheel in python/packages/drsai/ → produces dist/drsai-X.Y.Z-py3-none-any.whl (~1.6 MB compressed)
  3. Verifies the bundle is correctly embedded inside the wheel at drsai/ui_tui/dist/entry.mjs

Output:

python/packages/drsai/dist/drsai-1.2.8-py3-none-any.whl  (1.6 MB)

Manual step-by-step

Useful when debugging a single stage:

# 1. Build the TUI bundle
cd ui-tui
pnpm install          # first time only
pnpm build            # → dist/entry.mjs
cd -

# 2. Build the Python wheel
cd python/packages/drsai
rm -rf dist build     # clean previous artifacts
python -m build --wheel
cd -

# 3. Verify wheel contents
python -m zipfile -l python/packages/drsai/dist/drsai-*.whl | grep -E "ui_tui|entry\.mjs"
# Expected:
#   drsai/ui_tui/package.json
#   drsai/ui_tui/dist/entry.mjs

Local install test (recommended before publishing)

# Test the wheel in a fresh venv
python -m venv /tmp/drsai-test
/tmp/drsai-test/bin/pip install python/packages/drsai/dist/drsai-1.2.8-py3-none-any.whl
/tmp/drsai-test/bin/drsai chat   # should launch the TUI

# Cleanup
rm -rf /tmp/drsai-test

Upload to PyPI

# First time: install twine
pip install twine

# Test on TestPyPI first (recommended)
python -m twine upload --repository testpypi python/packages/drsai/dist/drsai-*.whl

# Then production PyPI
python -m twine upload python/packages/drsai/dist/drsai-*.whl

Credentials are read from ~/.pypirc or env vars TWINE_USERNAME / TWINE_PASSWORD.

Example ~/.pypirc:

[distutils]
index-servers =
    pypi
    testpypi

[pypi]
username = __token__
password = pypi-AgEIcHlwaS5vcmcC...   # your API token

[testpypi]
repository = https://test.pypi.org/legacy/
username = __token__
password = pypi-...                     # TestPyPI token

Bumping the version

Edit a single file:

# python/packages/drsai/src/drsai/version.py
__version__ = "1.2.9"  # ← bump here

pyproject.toml reads this dynamically via [tool.hatch.version]. No other file needs to change.

Full release checklist

# 1. Bump version
$EDITOR python/packages/drsai/src/drsai/version.py

# 2. Build
./scripts/build-wheel.sh

# 3. Test in fresh venv
python -m venv /tmp/drsai-test
/tmp/drsai-test/bin/pip install python/packages/drsai/dist/drsai-1.2.9-py3-none-any.whl
/tmp/drsai-test/bin/drsai version           # confirm version
/tmp/drsai-test/bin/drsai chat              # confirm TUI works
rm -rf /tmp/drsai-test

# 4. Test full test suite still passes
python -m pytest python/packages/drsai/tests/tui_gateway/ -q
cd ui-tui && ./scripts/e2e-test.sh && cd -

# 5. Tag git release
git add -A
git commit -m "release: v1.2.9"
git tag v1.2.9
git push && git push --tags

# 6. Publish to TestPyPI
python -m twine upload --repository testpypi python/packages/drsai/dist/drsai-1.2.9-py3-none-any.whl

# 7. Verify install from TestPyPI
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple drsai==1.2.9

# 8. Publish to PyPI
python -m twine upload python/packages/drsai/dist/drsai-1.2.9-py3-none-any.whl

Development Setup

Editable install (Python only)

cd python/packages/drsai
pip install -e .

Run TUI from source (no bundle build)

cd ui-tui
pnpm install
pnpm dev          # runs tsx src/entry.tsx with hot reload

This spawns the Python gateway as a subprocess; the gateway picks up the drsai install (editable or otherwise).

Run gateway standalone (for WebSocket attach)

DRSAI_TUI_ENABLE_WS=1 DRSAI_TUI_WS_PORT=8765 python -m drsai.backend.tui_gateway

# Then in another terminal:
drsai chat --attach ws://127.0.0.1:8765/attach

Testing

Python (gateway handlers)

cd /home/xiongdb/drsai
python -m pytest python/packages/drsai/tests/tui_gateway/ -v
# Expected: 7 passed in ~21s

TypeScript (type check)

cd ui-tui
pnpm type-check

End-to-end (UI + gateway + RPC)

cd ui-tui
./scripts/e2e-test.sh
# Expected: 4 checks pass

Manual TUI smoke

cd ui-tui && pnpm dev    # or: drsai chat after pip install
# In the TUI:
/help                    # 42 slash commands listed
/model                   # pops up model picker
/list                    # pops up session picker
/dangerous on            # toggle, watch StatusBar badge update

Project Layout

drsai/
├── ui-tui/                                  # TypeScript/Ink frontend
│   ├── src/                                 # source (entry.tsx, app.tsx, components/, hooks/)
│   ├── scripts/build.mjs                    # esbuild bundler
│   ├── dist/entry.mjs                       # built bundle (gitignored, regenerated)
│   └── package.json
│
├── python/packages/drsai/                   # Python package
│   ├── src/drsai/
│   │   ├── backend/
│   │   │   ├── run_cli.py                   # `drsai` CLI entry (thin launcher)
│   │   │   ├── tui_gateway/                 # JSON-RPC gateway
│   │   │   │   ├── entry.py                 # `drsai-gateway` entry point
│   │   │   │   ├── server.py                # RPC dispatcher
│   │   │   │   ├── handlers/                # session.*, prompt.*, slash.*, tools.*
│   │   │   │   └── adapter/                 # agent_runner, event_translator, callbacks
│   │   │   ├── gateway.py                   # Legacy SSE gateway (Electron desktop only)
│   │   │   ├── _deprecated/                 # Old prompt_toolkit REPL (kept for reference)
│   │   │   └── cli/                         # Shared utilities (config, history, commands)
│   │   ├── modules/agents/                  # DrSaiCLIAssistant, sub-agents
│   │   └── version.py                       # Single source of version
│   ├── tests/tui_gateway/                   # pytest suite
│   ├── docs/                                # design docs, migration guide
│   ├── pyproject.toml                       # build config
│   └── README.md                            # ← you are here
│
├── scripts/build-wheel.sh                   # One-shot release builder
└── desktop/                                 # Electron client (separate project)

CLI Reference

drsai                       # Launch TUI (default)
drsai chat                  # Same as above
drsai chat --attach <ws>    # Connect to existing gateway via WebSocket
drsai tui-gateway           # Run gateway as standalone process
drsai gateway --port 8642   # Legacy SSE gateway (for Electron desktop)
drsai config --show         # View/edit config
drsai sessions              # List saved sessions
drsai version               # Print version

Console scripts installed by pip:

Command Module
drsai drsai.backend.run_cli:run
drsai-tui drsai.backend.run_cli:run (alias)
drsai-gateway drsai.backend.tui_gateway.entry:main

Environment Variables

Variable Purpose Default
DRSAI_PYTHON Python interpreter for gateway subprocess python3
DRSAI_PYTHON_SRC_ROOT Override PYTHONPATH for gateway auto
DRSAI_UI_TUI_DIR Override ui-tui location auto
DRSAI_NODE Explicit path to a node executable (skips auto-download) unset
DRSAI_NODE_MIRROR Mirror for portable Node download (e.g. https://npmmirror.com/mirrors/node for China) https://nodejs.org/dist
DRSAI_NODE_CACHE_DIR Where to cache the portable Node runtime ~/.drsai/cache/node
DRSAI_NODE_NO_DOWNLOAD Set to 1 to disable auto-download (air-gapped envs) unset
DRSAI_TUI_ENABLE_WS Start WebSocket server in gateway unset
DRSAI_TUI_WS_PORT WebSocket port 8765
DRSAI_TUI_ATTACH_URL UI attaches via WebSocket instead of spawning unset
DRSAI_TUI_STARTUP_TIMEOUT_MS Gateway boot timeout 15000
DRSAI_TUI_RPC_TIMEOUT_MS RPC call timeout 120000
DRSAI_TUI_RPC_POOL_WORKERS Gateway threadpool size 4
HEPAI_API_KEY / ANTHROPIC_API_KEY / OPENAI_API_KEY LLM credentials unset
LLM_CONFIG_FILE Path to model catalog YAML/JSON from config
SYSTEM_SKILLS_DIR Override skills directory from config

Troubleshooting

pip install succeeded but drsai chat errors out on Node download

DrSai auto-downloads a portable Node.js runtime (~25 MB) on first launch from https://nodejs.org/dist. If that fails (offline, behind a proxy, blocked region):

Option 1 — use a closer mirror

export DRSAI_NODE_MIRROR=https://npmmirror.com/mirrors/node   # China mirror
drsai

Option 2 — install Node.js system-wide and let DrSai pick it up

# macOS:    brew install node
# Ubuntu:   apt install nodejs
# Windows:  https://nodejs.org/ (LTS installer)
node --version    # must succeed
drsai

Option 3 — point at an existing node binary

export DRSAI_NODE=/full/path/to/node
drsai

Option 4 — air-gapped install Pre-download a Node tarball matching your platform from https://nodejs.org/dist/v20.18.0/, extract under ~/.drsai/cache/node/v20.18.0/<platform>/ (so e.g. ~/.drsai/cache/node/v20.18.0/linux-x64/bin/node exists), then:

export DRSAI_NODE_NO_DOWNLOAD=1
drsai

TUI starts but gateway crashes

Check the crash log:

tail -50 ~/.drsai/logs/tui_gateway_crash.log

Bundle missing from wheel after build

The force-include paths in pyproject.toml are relative to the wheel build root, which is python/packages/drsai/. So ../../../ui-tui/dist/entry.mjs walks up to the repo root. If you move the repo layout, update those paths.

Verify with:

python -m zipfile -l python/packages/drsai/dist/drsai-*.whl | grep ui_tui

Expected output:

drsai/ui_tui/package.json
drsai/ui_tui/dist/entry.mjs

python -m build complains about hatchling

Install / upgrade the build toolchain:

pip install --upgrade build hatchling twine

Tests fail with "session not found"

The test suite resolves sessions for the current user; sessions are stored in ~/.drsai/. If you've never run drsai before, session.create will be exercised first.

drsai gateway prints a deprecation warning

That's intentional. The old SSE gateway.py is preserved only for the Electron desktop client. The new TUI uses drsai-gateway (JSON-RPC).


Documentation


License

MIT — see top-level LICENSE in the repo root.

Authors

Dr. Sai's team — Institute of High Energy Physics, Chinese Academy of Sciences. Contact: xiongdb@ihep.ac.cn / hepai@ihep.ac.cn

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

drsai-1.3.4-py3-none-any.whl (1.7 MB view details)

Uploaded Python 3

File details

Details for the file drsai-1.3.4-py3-none-any.whl.

File metadata

  • Download URL: drsai-1.3.4-py3-none-any.whl
  • Upload date:
  • Size: 1.7 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for drsai-1.3.4-py3-none-any.whl
Algorithm Hash digest
SHA256 5747969f1f9629c403a0f1b0fe820784782914c5f64e33e069968f96ea7ba301
MD5 f18a0654c65d1bcb5ff1a62065970787
BLAKE2b-256 933791809f12ac88ae4cec67a12734eb8c8435fca4ea44388e82fa8feb7f8621

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page