Metadata-Version: 2.4
Name: jaato-server
Version: 1.1.0
Summary: Jaato Server - LLM tool orchestration runtime and daemon
Author: apanoia
License-Expression: BUSL-1.1
Project-URL: Repository, https://github.com/Jaato-framework-and-examples/jaato
Project-URL: Issues, https://github.com/Jaato-framework-and-examples/jaato/issues
Keywords: llm,ai,tools,orchestration,vertex-ai,gemini
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.12
Description-Content-Type: text/markdown
Requires-Dist: jaato-sdk>=0.28.0.dev0
Requires-Dist: requests
Requires-Dist: mcp[cli]
Requires-Dist: google-api-core
Requires-Dist: certifi
Requires-Dist: python-dotenv
Requires-Dist: pyreadline3; sys_platform == "win32"
Requires-Dist: pyyaml
Requires-Dist: websockets>=12.0
Requires-Dist: anthropic>=0.40.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: psutil>=5.0.0
Requires-Dist: watchdog>=4.0.0
Requires-Dist: rich>=13.0.0
Requires-Dist: wcwidth
Requires-Dist: jsonschema>=4.0.0
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Requires-Dist: radon; extra == "dev"
Provides-Extra: google
Requires-Dist: google-genai; extra == "google"
Requires-Dist: google-auth; extra == "google"
Provides-Extra: github-models
Requires-Dist: azure-ai-inference>=1.0.0b7; extra == "github-models"
Provides-Extra: nim
Requires-Dist: openai>=1.0; extra == "nim"
Provides-Extra: openai
Requires-Dist: openai>=1.66; extra == "openai"
Provides-Extra: azure-openai
Requires-Dist: openai>=1.66; extra == "azure-openai"
Requires-Dist: azure-identity>=1.15.0; extra == "azure-openai"
Provides-Extra: bedrock
Requires-Dist: boto3>=1.35; extra == "bedrock"
Provides-Extra: openrouter
Requires-Dist: openai>=1.0; extra == "openrouter"
Provides-Extra: ovhcloud
Requires-Dist: openai>=1.0; extra == "ovhcloud"
Provides-Extra: web
Requires-Dist: trafilatura>=1.6.0; extra == "web"
Requires-Dist: html2text>=2024.2.26; extra == "web"
Requires-Dist: beautifulsoup4>=4.12.0; extra == "web"
Requires-Dist: lxml>=5.0.0; extra == "web"
Requires-Dist: pymupdf4llm>=0.2.0; extra == "web"
Requires-Dist: ddgs>=7.0.0; extra == "web"
Provides-Extra: interactive
Requires-Dist: pexpect>=4.8.0; sys_platform != "win32" and extra == "interactive"
Requires-Dist: wexpect>=4.0.0; sys_platform == "win32" and extra == "interactive"
Requires-Dist: pywin32>=220; sys_platform == "win32" and extra == "interactive"
Requires-Dist: setuptools; sys_platform == "win32" and extra == "interactive"
Provides-Extra: ast
Requires-Dist: ast-grep-py>=0.30.0; extra == "ast"
Provides-Extra: notebook
Requires-Dist: ipython-pygments-lexers>=1.0.0; extra == "notebook"
Provides-Extra: diagrams
Requires-Dist: Pillow>=10.0.0; extra == "diagrams"
Provides-Extra: templates
Requires-Dist: pybars3>=0.9.7; extra == "templates"
Requires-Dist: Jinja2>=3.1.0; extra == "templates"
Provides-Extra: kaggle
Requires-Dist: kaggle>=1.5.0; extra == "kaggle"
Provides-Extra: kerberos
Requires-Dist: pyspnego[kerberos]>=0.10.0; extra == "kerberos"
Provides-Extra: telemetry
Requires-Dist: opentelemetry-api>=1.20.0; extra == "telemetry"
Requires-Dist: opentelemetry-sdk>=1.20.0; extra == "telemetry"
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.20.0; extra == "telemetry"
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.20.0; extra == "telemetry"
Provides-Extra: all
Requires-Dist: jaato-server[ast,azure-openai,bedrock,dev,diagrams,github-models,google,interactive,kaggle,kerberos,nim,notebook,openai,openrouter,ovhcloud,telemetry,templates,web]; extra == "all"

# Changelog

## 1.1.0 (2026-09-26)

- test(apparmor): build the #1305 space-in-path workspace under tmp_path
- feat: keep a daemon-resolved app:// credential through the secret scrub (#1228)
- Revert "Let a profile-less workspace exempt GH_TOKEN from secret scrubbing"
- Let a profile-less workspace exempt GH_TOKEN from secret scrubbing
- Quote workspace_path in every AppArmor rule (#1305)
- docs(scaffold): name a profile-set after what varies, not who selects it
- server: tool_class, diff fields and auto_allow_housekeeping (jaato/#1304 §2 prerequisites)
- file_edit: steer writeNewFile/updateFile/removeFile over shell equivalents
- Fix WS sessions running unconfined: JaatoWSServer had no _event_loop
- Treat reasoning tokens as one quantity inside the output (#1047)
- Fix complexity ratchet violations from the #1294 diagnostics command
- Add self-service session diagnostics live view (#1294)
- Add observability to the WS AppArmor pre-init hook's silent exits (#1296)
- Fix stale WS-server reference and CREATE-path config_root gap (#1293)
- Persist reasoning parts instead of replaying them as text (#1290)
- fix(scaffold): Pi follow-ups after adopting #1093
- Re-anchor two reversions Phase 3 moved in session_manager.py
- Session group messaging phase 3: files on a message
- Session group messaging phase 2: the durable inbox
- fix: one attachment decoder for session.wake and session.message
- feat: session group messaging via the courier plugin (phase 1)
- Memories rail in the web client, backed by quiet daemon verbs (#1232)
- fix(runner): thread the managed workspace root through the SessionManager spawn path (#1280)
- fix(sandbox): fail closed on the SessionManager spawn path when confinement is required (#1253)
- notebook: detect, diagnose, and recover from a crashed subprocess kernel (#1275)
- Model subprocesses: jaato tools and installed tools on PATH, managed tool venv
- Staging: a file over 1 MiB closed the socket and hung for 120 s
- chore(release): jaato-sdk 0.28.0 — the cut absorbs #1263's protocol 1.21
- Web coder: bootstrap the jaato-sdk skill into every workspace (#1263)
- chore(release): cut jaato-sdk 0.27.1, jaato-server 1.1.0, jaato-tui 1.0.1, jaato-eval 0.3.3
- integration: add --refresh (overwrite only when nothing local is lost)
- Frame prompt-library skills as reference, list with descriptions (#1262)
- Co-locate #1253 WS reversions with the tests they name (#1065)
- fix(sandbox): WS session must be confined before its runner serves work (#1253)
- fix: recover double-JSON-encoded tool-call arguments (#1242)
- fix(sandbox): revived runner denies cli exec of /bin/sh and gh (#1251)
- feat(scaffold): add Pi skill integration

---

# jaato-server

The runtime and daemon behind [jaato](https://github.com/Jaato-framework-and-examples/jaato) — a multi-provider agentic tool orchestrator. This package holds the session runtime, the plugin system, ~24 model-provider adapters, and the daemon that clients connect to over a Unix socket or WebSocket.

You install this on the machine where agents should *run*. To talk to it from Python, install [`jaato-sdk`](https://pypi.org/project/jaato-sdk/); for a terminal client, [`jaato-tui`](https://pypi.org/project/jaato-tui/).

## Installation

```bash
pip install jaato-server
# or:  uv pip install jaato-server
```

The base install carries the daemon, the session runtime and the plugins that need no third-party SDK. Provider SDKs and the heavier tool plugins are extras, so you install only the ones you use:

| Extra | Brings |
|-------|--------|
| `google` | Google GenAI / Vertex AI |
| `openai` | OpenAI (Chat Completions + the Responses API) |
| `azure-openai` | Azure OpenAI, including Microsoft Entra ID auth |
| `bedrock` | AWS Bedrock (`boto3`) |
| `openrouter`, `nim`, `ovhcloud` | OpenAI-compatible gateways |
| `github-models` | GitHub Models (`azure-ai-inference`) |
| `web` | `web_fetch` / `web_search` — extraction, PDF and search backends |
| `interactive` | `interactive_shell` — PTY sessions (`pexpect` / `wexpect`) |
| `ast` | `ast_search` — structural code search |
| `notebook`, `diagrams`, `templates`, `kaggle` | the matching tool plugins |
| `telemetry` | OpenTelemetry tracing |
| `kerberos` | SPNEGO/Negotiate proxy auth |
| `all` | everything above, plus the dev tooling |

```bash
pip install 'jaato-server[all]'
```

Anthropic's SDK, `mcp`, `websockets` and `jaato-sdk` are base dependencies — Claude, MCP servers and the WebSocket transport work out of the box. Requires Python 3.12+.

## Quick start

Start the daemon:

```bash
# Local clients over a Unix domain socket
jaato-server --ipc-socket /tmp/jaato.sock --daemon

# Add a WebSocket port for remote or browser clients.  A bearer token is
# generated at ~/.jaato/ws.token on first WS start if you supply none.
jaato-server --ipc-socket /tmp/jaato.sock --web-socket :8080 --daemon

jaato-server --status
jaato-server --stop
```

Then drive it from Python:

```python
import asyncio
import jaato          # from jaato-sdk

async def main():
    async with jaato.session(mode="ipc", profile="researcher") as s:
        print(await s.ask("What changed in this repo last week?"))

asyncio.run(main())
```

The same code runs against an embedded runtime (`mode="in_process"`, no daemon), a local daemon (`"ipc"`), or a remote one (`"ws"`).

## Model providers

One session interface over every backend below; a profile picks the provider and model, and `enter_tier` can switch bindings mid-session.

| | |
|---|---|
| **Hosted APIs** | Anthropic, OpenAI, Azure OpenAI, Google GenAI / Vertex AI, AWS Bedrock, GitHub Models, Zhipu AI, MiniMax, Moonshot Kimi, Xiaomi MiMo |
| **Gateways** | OpenRouter (300+ models), NVIDIA NIM, Nebius Token Factory, OVHcloud AI Endpoints, Doubleword |
| **Self-hosted** | Ollama, LM Studio, vLLM, NVIDIA TensorRT-LLM, Triton |
| **On-device** | Chrome built-in AI (Gemini Nano, over the DevTools Protocol) |
| **Subscription-backed** | Claude Code CLI, Google Antigravity |

Several ship an interactive auth command (`anthropic-auth login`, `github-auth login`, `openrouter-auth key …`) so a credential need never be pasted into a shell profile.

## Plugins

Tools reach the model through plugins, discovered from this package and from any installed distribution declaring a `jaato.plugins` entry point. Built-ins include:

- **Execution** — `cli` (shell), `interactive_shell` (PTY sessions for REPLs, debuggers, wizards), `notebook`, `mcp` (any stdio MCP server)
- **Code and files** — `file_edit`, `filesystem_query`, `ast_search`, `lsp`, `references`
- **Web** — `web_fetch`, `web_search`, `webmcp`, `service_connector` (call an OpenAPI service by alias), `webhook` (inbound events)
- **Orchestration** — `subagent`, `todo`, `clarification`, `waypoint`, `reliability`, `template`
- **Context management** — four GC strategies (`gc_truncate`, `gc_summarize`, `gc_hybrid`, `gc_budget`) plus provider prompt-caching plugins
- **Control** — `permission`, `sandbox_manager`, `telemetry`

## Agent profiles

A profile is a YAML file in `.jaato/profiles/` binding a model, a provider, a plugin set, a GC strategy and resource ceilings:

```yaml
name: researcher
description: Deep research profile
provider: anthropic
model: claude-sonnet-4-20250514
plugins: [cli, web_search, memory, todo(preload)]
default_agent: researcher        # the persona in .jaato/agents/researcher.md
runtime_limits:
  max_parallel_tools: 2
  max_orphan_seconds: 300
budget_control:
  limits: {usd: 5.0, tool_calls: 200}
  degrade:
    - {at: 95,  action: finalize}
    - {at: 100, action: abort}
```

`jaato-scaffold` interrogates the *installed* framework rather than a copy of the docs, so it cannot go stale:

```bash
jaato-scaffold explain profile         # every profile key, with its vocabulary
jaato-scaffold explain providers       # providers, their knobs and caveats
jaato-scaffold explain plugins         # what is installed, and where it came from
jaato-scaffold validate                # check a workspace before you run it
jaato-scaffold new client --profile researcher
```

`explain` covers 20-odd scopes — `env`, `tiers`, `completion`, `runtime`, `paths`, `services` among them.

## Isolation and secrets

Sessions run in a subprocess runner, and the daemon confines it where the host allows:

- **AppArmor** — a per-boundary profile confines the runner to its workspace when the LSM is available. Opt in per client, or require it with `JAATO_REQUIRE_APPARMOR=1` so an unconfined host refuses to start rather than degrading silently.
- **cgroup v2** — `runtime_limits` caps memory, pids and CPU; tool timeouts, output size, tool-pool width and two wall-clock bounds are enforced by the framework itself.
- **Secret scrubbing** — provider keys and tokens are stripped from the environment handed to every model-driven subprocess by default; `scrub_secret_env` narrows or waives it, and waiving is announced.
- **Permissions** — every tool call passes a policy that can allow, deny or ask, per session, with the decision recorded.

## Configuration

Workspace configuration lives under `.jaato/` (profiles, agents, GC settings, permissions) with `~/.jaato/` as the fallback tier. MCP servers are declared in `.mcp.json`. Credentials resolve from a profile knob, then the environment, then a stored auth file — `pass://` and `vault://` URIs are resolved daemon-side so a secret never sits on disk in the clear.

`jaato-scaffold explain env` prints every environment variable the installed tree reads, each tagged with its scope and the typed profile key that supersedes it.

## Documentation

- [Project README](https://github.com/Jaato-framework-and-examples/jaato/blob/main/README.md)
- [Architecture](https://github.com/Jaato-framework-and-examples/jaato/blob/main/docs/architecture.md) · [Sequence diagrams](https://github.com/Jaato-framework-and-examples/jaato/blob/main/docs/sequence-diagram-architecture.md)
- [Design philosophy](https://github.com/Jaato-framework-and-examples/jaato/blob/main/docs/design-philosophy.md)
- [Permission system](https://github.com/Jaato-framework-and-examples/jaato/blob/main/docs/jaato_permission_system.md)
- [AppArmor setup](https://github.com/Jaato-framework-and-examples/jaato/blob/main/docs/apparmor-setup.md)
- [OpenTelemetry](https://github.com/Jaato-framework-and-examples/jaato/blob/main/docs/opentelemetry-design.md)
- [Issues](https://github.com/Jaato-framework-and-examples/jaato/issues)

## License

BUSL-1.1. See [LICENSE](https://github.com/Jaato-framework-and-examples/jaato/blob/main/LICENSE).
