A trust and safety agent that interacts with Osprey for investigation, real-time analysis, and prevention implementations
at main 133 lines 6.1 kB view raw view rendered
1# Phoebe 2 3Phoebe is an AI-powered trust and safety agent for the [AT Protocol](https://atproto.com/) network. It automates safety operations by analyzing network threats and creating rules to detect and resolve emerging issues. Phoebe uses three different services to achieve this: 4 5- **[Osprey](https://github.com/roostorg/osprey)** - Real-time rules engine for threat detection 6- **[Ozone](https://github.com/bluesky-social/ozone)** - Moderation service for labeling and takedowns 7- **[ClickHouse](https://clickhouse.com/)** - Event analytics database for pattern discovery, which is populated by Osprey 8 9This allows it to: 10 11- **Rule Management** - Write, validate, and deploy rules for Osprey 12- **Data Analysis** - Query ClickHouse to analyze what is happening on your network 13- **Investigation** - Look up domains, IPs, URLs, and WHOIS records to investigate threats 14- **Content Detection** - Find similar posts to detect coordinated spam and templated abuse 15- **Moderation** - Apply labels and take moderation actions via Ozone (not actually implemented yet...) 16 17## How It Works 18 19Phoebe uses a model API as its reasoning backer. The agent writes and executes Typescript code in a sandboxed Deno runtime to interact with its tools — querying event data, creating safety rules, and managing moderation actions. 20 21``` 22┌─────────────────────────────────────────────────────────┐ 23│ Model API │ 24├─────────────────────────────────────────────────────────┤ 25│ Tool Execution (Deno Sandbox) │ 26├──────────┬───────────┬──────────────┬───────────────────┤ 27│ Osprey │ ClickHouse│ Ozone │ Investigation │ 28│ (Rules) │ (Queries) │ (Moderation) │ (Domain/IP/WHOIS) │ 29└──────────┴───────────┴──────────────┴───────────────────┘ 30``` 31 32#### Why not traditional tool calling? 33 34See [Cloudflare's blog post](https://blog.cloudflare.com/code-mode/) on this topic. 35 36One of the largest benefits of letting the agent write and execute its own code is that it allows for tool chaining and grouping. Traditionally, each subsequent tool call results in a round trip for _each_ tool call. When the agent can write its own code, it can instead 37chain these calls together. For example, if the agent knows it wants to grab the results of _three separate_ SQL queries, it can group all three of those calls in a single `execute_code` block and receive the context. 38 39When executing code inside of Deno, Deno is ran with the bare minimum of permissions. For example, it cannot access the file system, the network (local or remote), or use NPM packages. Both execution time and memory limits are applied. All network requests are done in Python, 40in code that _you_ write, not the agent. 41 42| Limit | Value | 43|-------|-------| 44| Max code size | 50,000 characters | 45| Max tool calls per execution | 25 | 46| Max output size | 1 MB | 47| Execution timeout | 60 seconds | 48| V8 heap memory | 256 MB | 49 50## Tools 51 52Phoebe has access to the following tools, organized by namespace: 53 54| Namespace | Tool | Description | 55|-----------|------|-------------| 56| `clickhouse` | `query(sql)` | Execute SQL queries against Clickhouse | 57| `clickhouse` | `getSchema()` | Get the table schema and column info | 58| `osprey` | `getConfig()` | Get available features, labels, rules, and actions | 59| `osprey` | `getUdfs()` | Get available UDFs for rule writing | 60| `osprey` | `listRuleFiles(directory?)` | List existing `.sml` rule files | 61| `osprey` | `readRuleFile(file_path)` | Read an existing rule file | 62| `osprey` | `saveRule(file_path, content)` | Save or create a rule file | 63| `osprey` | `validateRules()` | Validate the ruleset | 64| `content` | `similarity(text, threshold?, limit?)` | Find similar posts using n-gram distance | 65| `domain` | `checkDomain(domain)` | DNS lookups and HTTP status checks | 66| `ip` | `lookup(ip)` | GeoIP and ASN lookups | 67| `url` | `expand(url)` | Follow redirect chains and detect shorteners | 68| `whois` | `lookup(domain)` | Domain registration and WHOIS info | 69| `ozone` | `applyLabel(subject, label)` | Apply a moderation label (not yet implemented) | 70| `ozone` | `removeLabel(subject, label)` | Remove a moderation label (not yet implemented) | 71 72## Prerequisites 73 74- [Deno](https://deno.com/) runtime 75- [uv](https://github.com/astral-sh/uv) package manager 76 77## Installation 78 79```bash 80git clone https://github.com/haileyok/osprey-agent.git 81cd osprey-agent 82uv sync --frozen 83``` 84 85## Configuration 86 87Create a `.env` file in the project root: 88 89```env 90# Required 91MODEL_API_KEY="sk-ant-api03-..." 92MODEL_NAME="claude-sonnet-4-5-20250929" 93 94# Optional - Model API backend (default: anthropic) 95# MODEL_API="anthropic" # or "openai", "openapi" 96# MODEL_ENDPOINT="" # required for openapi, ie https://api.moonshot.ai/v1/completions 97 98# Osprey 99OSPREY_BASE_URL="http://localhost:5004" 100OSPREY_REPO_URL="https://github.com/roostorg/osprey" 101OSPREY_RULESET_URL="https://github.com/your-org/your-ruleset" 102 103# ClickHouse 104CLICKHOUSE_HOST="localhost" 105CLICKHOUSE_PORT=8123 106CLICKHOUSE_DATABASE="default" 107CLICKHOUSE_USER="default" 108CLICKHOUSE_PASSWORD="clickhouse" 109``` 110 111All settings can also be passed as CLI flags (see `--help`). 112 113## Usage 114 115### Interactive Chat 116 117Start a conversation with Phoebe to investigate threats and create rules: 118 119```bash 120uv run main.py chat 121``` 122 123### CLI Options 124 125Both commands accept overrides for any config value: 126 127```bash 128uv run main.py chat \ 129 --clickhouse-host localhost \ 130 --clickhouse-port 8123 \ 131 --osprey-base-url http://localhost:5004 \ 132 --model-api-key $ANTHROPIC_API_KEY 133```