Metadata-Version: 2.4
Name: jaato-server
Version: 1.2.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.29.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.2.0 (2026-09-30)

- Re-anchor a proposeReference reversion on the new call site
- Let a profile make catalog templates the only way to write a page
- Retarget the heard-audio media reversion at part_media_views
- Reserve the output a request carries in every context check (#1444)
- Count what the wire carries in the instruction budget (#1440)
- Refresh a running session's references catalog when disk changes (#1145)
- Keep links a proposal makes to pages not in the catalog yet
- Keep every @ in a prompt that no enricher resolved (#1429)
- Validate through the daemon for SDK-only installs (#1267, tier 3)
- Release the plugins a validate run starts
- Let installed packages contribute validate findings (#1306)
- Profile facts in the scaffold snapshot; SDK-only `new` emits instead of refusing (#1267, tier 2)
- Ship jaato-scaffold with the SDK; server contributes introspection verbs (#1267, tier 1)
- References: split update_links validation to meet the complexity ceiling
- References: edit a catalog reference's typed links from the web client
- References: promote a claim into a named bundle, and reconcile its index
- References: only proposeReference writes a claim on a confined host
- References: where there is an embedding index, a cut depth keeps the nearest
- References: rank each depth by its links before the transitive cap cuts it
- References: agents propose typed links; validate and the web panel show them
- References: typed links between references (wikiLLM Seam 3)
- Docs: the claims listing, correlated curation, and witnessed_by
- Reference claims: a witness stamp, and a curator's listing (protocol 1.32)
- Files panel: find any workspace file by name, hidden or not (protocol 1.32)
- feat(references): a person promotes an agent's claim into the catalog (protocol 1.32)
- feat(references): agents can propose a reference (claim, not catalog)
- references: a reference records where it ARRIVED, not who wrote it
- Fix CI on #1414: split the note scan, re-anchor a moved reversion
- Mark jaato's own model-facing notes so they do not read as injection (#1414)
- Add scripts/check.py: run locally what CI runs, read from the workflows (#1415)
- fix(permission): persist runtime decisions from the enforcer, not the daemon's copy (#1412)
- Disclose that notebook cells import the daemon's jaato (#1413)
- Regenerate the authoring snapshot in the pre-commit hook
- Point the env-block reversion at authoring_facts
- Decouple scaffold authoring from introspection (#1267, step 1)
- Files panel: ask git what a clone ignores
- Keep Python bytecode out of the workspace tree
- Let a confined process read /etc/mime.types (template v42)
- Split the #1355 AST guard helper under the complexity ceiling
- Run session save and shutdown off the daemon loop (#1355)
- Refuse to stage a file through a symlink planted in the workspace (#1386)
- workspace home: point GRADLE_USER_HOME at <home>/.gradle
- private /tmp: a private /dev/shm too; every body reads /proc/cpuinfo and its limits
- web_coder_toolchains: a private /tmp may run what it holds too
- web_coder_toolchains: a managed workspace may run what it builds
- AppArmor: write-deny the cache fragment tier (template v40)
- Toolchain hint for the model and the page from one place: the toolchain_offer plugin (#1344)
- fix(scaffold): report .tmp/ only when it exists unprotected (#1381)
- feat(sandbox): a private /tmp per workspace (#1381, step 1)
- Point the agent at the repository's own guidance files (#1347)
- Rename the app_write owner local so the #1226 reversion anchor stays unique
- Have the daemon write a GitHub binding's .env reference the BFF cannot reach
- Doctor survives an unreadable source; confined /tmp matches the profile (#1360, #1361)
- Finished sessions: tolerate records without the mark; pin the two new row keys
- Replay a pending permission or clarification to a client that attaches
- Fix three things a fresh workspace told the model wrongly (#1357, #1358, #1359)
- Finished sessions: keep a session the person ended, the agent completed or the budget stopped
- Split the report-guard's AST helper under the complexity ceiling
- Show subagent reports and plan lines collapsed in the chat
- test: isolate the #1345 guard from a leaked introspection session
- get_environment: a runtime aspect that says what a session can run (#1346)
- lsp: hide the LSP tools when no language server is configured (#1345)
- Re-anchor the #1326 record reversion on the new _record_grants call
- Split glob_to_regex under the complexity ceiling (#1348)
- Name the cause when the AppArmor profile refuses a cli command (#1348)
- Re-anchor the #1321 reversions after the v38 template change
- Render the #1342 guard's workspace under tmp_path, not /root
- Let confined sessions run Rust coreutils and script commands (#1342)
- Give cli's synchronous path the workspace HOME (#1339)
- Run a backgrounded tool once, not twice (#1338)
- Redact credential values a tool prints before they leave the runner (#1215)
- feat(history): paged history for WS clients and the web coder
- feat(history): paged, rendered history replay (protocol 1.28)
- chore(release): jaato-sdk 0.29.0, jaato-server 1.2.0
- Bring the API key list box back into the session picker
- Redesign the web coder's workspace and session pickers (protocol 1.26)
- Show what a session's AppArmor profile grants in the diagnostics panel (#1326)
- Start the notebook kernel in //child; stop trusting the base profile (#1323)
- Don't pass --system-site-packages when it is the runner's own install (#1322)
- Stop the tool-venv importing the daemon's jaato (#1322)
- fix(apparmor): let confined sessions exec git's HTTPS helper (#1321)

---

# 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).
