Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ to an operator decision instead of a flat hard-deny.

### Added

- **Two-tier runtime model.** Agents declare `runtime` (`direct` = vendor
runtime on a subscription, `claude` today; `api` = ritsu's own tool loop on
a metered key) + `provider`. Existing databases migrate automatically.
- **api providers:** `anthropic` / `openai` / `gemini` via their official
SDKs, `xai` (Grok), `openrouter`, `litellm` (key optional), `custom`
base_url. Tool calls stay in ritsu's loop — the approval gate applies
unchanged. Sampling params are sent only when set in `provider_options`.
- **Health tab (System).** Live checks: core runtime, one free probe per
stored provider key, and every configured connector.
- **Blocked sub-tab (Approvals → Blocked).** Lists recent inter-agent call
denials — caller → target, reason, detail, attempted message, age — live
over the approvals SSE stream. Escalation denials are visually flagged as
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ What's baked in:
- **Per-agent isolation enforced *before* tools fire.** `tools_allowlist` + per-path workspace permissions go through the SDK's `canUseTool` callback. An agent with no `Bash` and no writable workspace can't exfiltrate files even if perfectly socially-engineered.
- **AES-256-GCM secrets at rest.** Bot tokens, API keys; master key separable from the DB dir.
- **Strict CSP, audit log, OAuth 2.1 + DCR + PKCE + RFC 8707** — full posture in [`docs/threat-model.md`](./docs/threat-model.md).
- **Two runtimes.** `claude-sdk` (Max plan via `@anthropic-ai/claude-agent-sdk`, $0 per turn) or `ritsu-agent` (your API key against any OpenAI-compatible provider — OpenAI, OpenRouter, local LiteLLM, etc.). Same tools, same memory, same UI.
- **Two runtime tiers.** `direct` rides a vendor agent runtime on a subscription (Claude via `@anthropic-ai/claude-agent-sdk`, $0 per turn; more vendors as their runtimes ship). `api` runs ritsu's own tool loop against a metered keyAnthropic, OpenAI, and Gemini through their official SDKs, Grok via xAI's OpenAI-compatible API, plus OpenRouter, a local LiteLLM proxy, or any custom OpenAI-compatible endpoint. Same tools, same memory, same UI.

---

Expand Down
12 changes: 8 additions & 4 deletions docs/examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,18 @@ Each example below maps to the **Agents → Create / edit** form:
| `name` | name |
| `description` | description |
| `system_prompt` | system prompt (textarea) |
| `dispatcher` | dispatcher |
| `runtime` | runtime (direct / api) |
| `provider` | provider |
| `model` | model |
| `tools_allowlist` | tools allowlist (checkboxes) |
| `can_call` | can call (checkboxes — only enabled agents appear) |

`provider` / `api_key_ref` / `provider_options` are for the ritsu-agent
runtime (your-own-API-key path); leave them at `null` / `{}` for the
default Max-plan claude-sdk dispatcher.
`runtime: "direct"` + `provider: "claude"` is the Max-plan default.
`runtime: "api"` runs ritsu's own loop against a metered provider
(`anthropic` / `openai` / `gemini` / `xai` / `openrouter` / `litellm` /
`custom`) — set `api_key_ref` to a minted key (optional for
litellm/custom) and tune `provider_options` (temperature, max_tokens,
base_url) as needed.

## Pasting via curl

Expand Down
4 changes: 2 additions & 2 deletions docs/examples/code-reader.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
"name": "Code Reader",
"description": "Read-only code explorer for a single project workspace. Answers \"where is X defined / used / called from\" questions.",
"system_prompt": "You are a read-only code explorer for the workspace you have access to.\n\nWhen the user asks about the code:\n- Use Glob to find candidate files by pattern (`src/**/*.ts`).\n- Use Grep to locate symbol definitions / usages (matches against file contents).\n- Use Read to pull the relevant chunk and answer with file path + line numbers.\n\nWhen citing code: always include the path and line range. Never speculate about file contents you haven't actually read.\n\nYou are READ-ONLY. You do not have Write, Edit, or Bash. If asked to change code, explain that you can only describe the change — the user (or a different agent) has to apply it.\n\nFor durable facts about the project (module layout, naming conventions, recurring patterns), use mcp__memory__remember. Read your memories before answering, so you don't re-derive the same facts every session.",
"dispatcher": "claude-direct",
"runtime": "direct",
"model": "claude-sonnet-4-6",
"memory_backend": "sqlite",
"tools_allowlist": ["Read", "Glob", "Grep"],
"can_call": [],
"capabilities": [],
"provider": null,
"provider": "claude",
"api_key_ref": null,
"provider_options": {},
"enabled": true
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/notetaker.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
"name": "Notetaker",
"description": "Summarises any pasted text into bullet points + open questions.",
"system_prompt": "You are a notetaker. When given any block of text, your job is to:\n1. Extract the 3-5 most important facts as bullet points.\n2. Identify any open questions or unresolved action items as a separate list.\n3. Be brief — no preamble, no recap, just the bullets.\n\nUse mcp__memory__remember to persist durable preferences the user expresses (e.g. \"user prefers markdown bullets\", \"omit the open-questions list when there's only one\"). Read your existing memories at the start of every conversation and apply them.",
"dispatcher": "claude-direct",
"runtime": "direct",
"model": "claude-sonnet-4-6",
"memory_backend": "sqlite",
"tools_allowlist": [],
"can_call": [],
"capabilities": [],
"provider": null,
"provider": "claude",
"api_key_ref": null,
"provider_options": {},
"enabled": true
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/research-assistant.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
"name": "Research Assistant",
"description": "Web research agent with persistent memory. Searches via the configured searxng instance, fetches pages, and accumulates findings across sessions.",
"system_prompt": "You are a research assistant. Your job is to answer factual questions with concrete, sourced evidence — never from memory of your training data alone when fresh information is available.\n\nWorkflow:\n1. Use WebSearch to find candidate sources for the question.\n2. Use WebFetch to pull the actual page contents of the most promising 2-3 results.\n3. Synthesise an answer that quotes / cites the source URLs.\n4. Save any durable findings via mcp__memory__remember — e.g. \"AWS SQS FIFO queues have a 300 TPS limit per message group (https://...)\".\n\nDo NOT fabricate citations. If you can't find a source, say so. If WebSearch returns nothing useful, fall back to your trained knowledge but mark it clearly: \"(no fresh source; from training data, may be outdated)\".\n\nRead your existing memories at the start of every conversation — the user is building up a research base, and you should reuse prior findings instead of re-deriving them.",
"dispatcher": "claude-direct",
"runtime": "direct",
"model": "claude-sonnet-4-6",
"memory_backend": "sqlite",
"tools_allowlist": ["WebFetch", "WebSearch"],
"can_call": [],
"capabilities": [],
"provider": null,
"provider": "claude",
"api_key_ref": null,
"provider_options": {},
"enabled": true
Expand Down
3 changes: 2 additions & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ Go to **Agents** → fill out the form:
| type | `generic` |
| name | `Notetaker` |
| description | `Summarises text into bullet points.` |
| dispatcher | `claude-direct` |
| runtime | `direct` |
| provider | `claude` |
| model | `claude-sonnet-4-6` |
| memory backend | `sqlite` |
| system_prompt | (see below) |
Expand Down
Loading