|
| 1 | +# Omnigent |
| 2 | + |
| 3 | +<!-- AUTO-GENERATED: stability-banner-start --> |
| 4 | +:::warning Beta plugin |
| 5 | +This plugin is currently **beta**. APIs may change between minor releases. Import from `@databricks/appkit/beta`. See [Plugin Stability Tiers](./stability.md). |
| 6 | +::: |
| 7 | +<!-- AUTO-GENERATED: stability-banner-end --> |
| 8 | + |
| 9 | +The `omnigent` plugin embeds [Omnigent](https://github.com/omnigent-ai/omnigent), the open-source agent meta-harness, in a Databricks AppKit app. Your users get Claude Agent SDK, Pi and OpenAI Agents SDK sessions inside the app, with model calls going through Unity AI Gateway as the app's service principal. |
| 10 | + |
| 11 | +Omnigent owns the agent loop: sessions, history, approvals. The plugin runs it safely inside a Databricks App. Use the [`agents`](./agents.md) plugin when you want AppKit to own the loop against one serving endpoint. Use `omnigent` when you want the harnesses themselves. |
| 12 | + |
| 13 | +## Install |
| 14 | + |
| 15 | +```ts |
| 16 | +import { createApp, server } from "@databricks/appkit"; |
| 17 | +import { omnigent } from "@databricks/appkit/beta"; |
| 18 | + |
| 19 | +await createApp({ |
| 20 | + plugins: [ |
| 21 | + server(), |
| 22 | + omnigent({ instructions: "You help the team explore order data." }), |
| 23 | + ], |
| 24 | +}); |
| 25 | +``` |
| 26 | + |
| 27 | +The app also needs: |
| 28 | + |
| 29 | +- **Python.** Add a `pyproject.toml` with `requires-python = ">=3.12,<3.13"` and `omnigent[databricks]`, plus a `uv.lock`. Databricks Apps then builds a Python 3.12 venv next to `npm install`. A plain `requirements.txt` gets Python 3.11, which Omnigent does not support. The lockfile must reference public PyPI. |
| 30 | +- **Harness CLIs.** Add them to your `package.json`, so you pin their versions: `@anthropic-ai/claude-code` and `@earendil-works/pi-coding-agent`. The plugin only offers harnesses whose CLI is installed. The Claude Agent SDK's bundled CLI is too old for current Claude models, so add `@anthropic-ai/claude-code` even though the SDK ships one. |
| 31 | +- **Start with `node`.** In `app.yaml`, use `command: ["node", "server.js"]`, not `npm run start`. npm does not pass SIGTERM on, so the plugin never gets to stop its child processes. As a backstop, each child also exits when Node does, so a redeploy still succeeds. |
| 32 | + |
| 33 | +## Configuration |
| 34 | + |
| 35 | +| Option | Default | | |
| 36 | +|---|---|---| |
| 37 | +| `instructions` | a generic assistant prompt | System instructions for every session | |
| 38 | +| `harnesses` | `claude-sdk`, `pi`, `openai-agents` | Harnesses users may pick | |
| 39 | +| `defaultHarness`, `defaultModel` | first available | | |
| 40 | +| `runtime.python` | `./.venv/bin/python` | | |
| 41 | +| `runtime.home` | `$TMPDIR/appkit-omnigent` | The plugin's state directory | |
| 42 | +| `runtime.hostIdleMs` | 30 min | Stop a user's Omnigent host after this long idle | |
| 43 | + |
| 44 | +Each harness is offered the Unity AI Gateway `system.ai` models whose API it speaks: Claude Agent SDK the Anthropic Messages API, Pi the Codex Responses API, OpenAI Agents SDK the OpenAI Responses API. |
| 45 | + |
| 46 | +## Routes |
| 47 | + |
| 48 | +All routes are under `/api/omnigent` and scoped to the signed-in user. |
| 49 | + |
| 50 | +| Route | | |
| 51 | +|---|---| |
| 52 | +| `GET /harnesses` | Harnesses available to the user, each with the gateway models it can drive | |
| 53 | +| `GET /sessions`, `POST /sessions` | List, create (`harness`, `model`, `message`, `title`) | |
| 54 | +| `GET /sessions/:id`, `DELETE /sessions/:id` | Snapshot (items, status), delete | |
| 55 | +| `POST /sessions/:id/messages` | `{ "text": "..." }` | |
| 56 | +| `GET /sessions/:id/stream` | Server-sent events (Omnigent's session stream, which replays from `Last-Event-ID`) | |
| 57 | +| `POST /sessions/:id/interrupt` | Stop the current turn | |
| 58 | +| `GET /status` | Runtime health: hosts, gateway counters | |
| 59 | + |
| 60 | +## How it works |
| 61 | + |
| 62 | +- **One Omnigent server, one host per user.** The server listens on loopback in Omnigent's header-auth mode, under a random header name only the plugin knows. Each active user gets their own host process, registered as that user; Omnigent only runs a session on its owner's host. An idle host stops after `runtime.hostIdleMs`. |
| 63 | +- **No credential in any child process.** The harnesses' Databricks profile points at a model gateway inside the plugin, on loopback, with a placeholder token. The gateway forwards only model-serving paths to the workspace and adds the service principal's token. Every other path returns 403. |
| 64 | + |
| 65 | +## Limits |
| 66 | + |
| 67 | +- **Sessions live in the container.** Omnigent keeps them in SQLite under the plugin's state directory, so they survive a process restart but not a redeploy. |
| 68 | +- **Only gateway harnesses.** Harnesses that sign in with their vendor (Cursor, Copilot, Gemini and others) bypass Unity AI Gateway, so they are not offered. Native terminal harnesses (`claude-native`, `pi-native`) are not offered yet: they need tmux and a terminal client. |
| 69 | +- **Shared gateway limits.** All users' model traffic uses the service principal's gateway limits. |
0 commit comments