https://github.com/just-be-dev/agents
https://github.com/just-be-dev/agents
Last synced: 3 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/just-be-dev/agents
- Owner: just-be-dev
- Created: 2026-02-20T23:49:23.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-03-14T14:50:49.000Z (3 months ago)
- Last Synced: 2026-03-15T01:39:13.634Z (3 months ago)
- Language: TypeScript
- Size: 783 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# @just-be/agents
A monorepo for building and deploying multiple AI agents as Cloudflare Workers with Durable Objects. Each agent is isolated in its own workspace but shares common packages and a unified deployment router.
## Structure
```
agents/
├── agents/ # Individual agent implementations
│ └── github/ # GitHub App agent (webhook handler, issue/PR automation)
├── packages/ # Shared code across agents (available for future use)
├── src/ # Unified router (routes webhooks to specific agents)
│ └── index.ts # Entry point that routes to agent Durable Objects
├── wrangler.jsonc # Cloudflare Workers deployment configuration
└── package.json # Monorepo root with workspace configuration
```
## Architecture
The monorepo uses a **router pattern** where a single Worker (`src/index.ts`) routes incoming requests to the appropriate agent Durable Object:
```
POST /webhooks/github
→ Worker Router (src/index.ts)
→ Extract repo name from payload
→ Route to GitHubAgent Durable Object (agents/github/)
→ Agent instance per repository (isolated state)
→ SQLite storage, WebSocket state updates
→ GitHub API integration
GET /
→ Status endpoint listing all available agents
```
Each agent:
- Runs as a **Durable Object** with isolated state and SQLite storage
- Uses the [Agents SDK](https://www.npmjs.com/package/agents) for stateful WebSocket connections and RPC
- Gets its own instance per resource (e.g., one GitHub agent per repository)
## Getting Started
### Prerequisites
- [Bun](https://bun.sh) runtime (managed via [mise](https://mise.jdx.dev))
- [Cloudflare account](https://dash.cloudflare.com/sign-up)
- Wrangler CLI (installed via `bun install`)
### Installation
```bash
# Install Bun via mise (if not already installed)
mise install
# Install all dependencies (for all workspaces)
bun install
# Type check all packages
bun run typecheck
```
### Local Development
```bash
# Run the router worker locally with hot reload
bun run dev
# The dev server starts at http://localhost:8787
# Test the status endpoint: curl http://localhost:8787
```
### Deployment
```bash
# Deploy the unified router and all agents to Cloudflare
bun run deploy
```
The router worker will be deployed to your Cloudflare account with all configured Durable Object bindings.
## Available Agents
### GitHub Agent
A GitHub App agent that handles webhook events, stores them in SQLite, and can respond via the GitHub API.
- **Location**: `agents/github/`
- **Webhook Path**: `/webhooks/github`
- **Features**: Per-repo isolation, event storage, auto-commenting, WebSocket state
- **Documentation**: See [agents/github/README.md](./agents/github/README.md)
Example usage:
```bash
# GitHub webhooks are sent to:
POST https://your-worker.workers.dev/webhooks/github
```
## Adding a New Agent
Follow these steps to add a new agent to the monorepo:
### 1. Create Agent Directory
```bash
mkdir -p agents/my-agent/src
cd agents/my-agent
```
### 2. Create `package.json`
```json
{
"name": "@just-be/my-agent",
"type": "module",
"scripts": {
"typecheck": "tsc --noEmit"
},
"dependencies": {
"agents": "^0.5.1"
},
"devDependencies": {
"@types/bun": "latest",
"wrangler": "^4.67.0"
},
"peerDependencies": {
"typescript": "^5"
}
}
```
### 3. Implement Agent Class
Create `agents/my-agent/src/my-agent.ts`:
```typescript
import { Agent } from "agents";
export class MyAgent extends Agent {
constructor(state: DurableObjectState, env: Env) {
super(state, env);
}
async fetch(request: Request): Promise {
const url = new URL(request.url);
// Handle webhooks or other requests
if (request.method === "POST" && url.pathname === "/webhook") {
// Process webhook
return Response.json({ status: "received" });
}
return new Response("Not found", { status: 404 });
}
}
```
### 4. Add Router Integration
Update `src/index.ts` to export your agent and add routing:
```typescript
import { MyAgent } from "../agents/my-agent/src/my-agent.ts";
export { GitHubAgent, MyAgent };
interface Env {
GITHUB_AGENT: DurableObjectNamespace;
MY_AGENT: DurableObjectNamespace; // Add this
}
export default {
async fetch(request: Request, env: Env): Promise {
const url = new URL(request.url);
// Add your agent's route
if (url.pathname.startsWith("/webhooks/my-agent")) {
return handleMyAgentRoute(request, env);
}
// ... existing routes
},
};
async function handleMyAgentRoute(request: Request, env: Env): Promise {
// Get agent instance (use a name/ID scheme that makes sense)
const id = env.MY_AGENT.idFromName("default");
const stub = env.MY_AGENT.get(id);
return stub.fetch(request);
}
```
### 5. Update Wrangler Configuration
Add your agent to `wrangler.jsonc`:
```jsonc
{
"durable_objects": {
"bindings": [
{
"name": "GITHUB_AGENT",
"class_name": "GitHubAgent",
"script_name": "agents-router",
},
{
"name": "MY_AGENT",
"class_name": "MyAgent",
"script_name": "agents-router",
},
],
},
"migrations": [
{
"tag": "v1",
"new_sqlite_classes": ["GitHubAgent"],
},
{
"tag": "v2",
"new_sqlite_classes": ["MyAgent"],
},
],
}
```
### 6. Test and Deploy
```bash
# Type check your new agent
bun run typecheck
# Test locally
bun run dev
# Deploy to Cloudflare
bun run deploy
```
Your new agent is now available at `/webhooks/my-agent` (or whatever path you configured).
## Development Commands
```bash
# Install dependencies for all workspaces
bun install
# Type check all packages
bun run typecheck
# Run development server (with hot reload)
bun run dev
# Deploy to Cloudflare Workers
bun run deploy
# Build GitHub agent CLI tool
bun run build:cli
```
## Architecture Patterns
### Per-Instance Isolation
Agents use Durable Objects to provide per-resource isolation. For example:
- GitHub agent: One instance per repository (`repo.full_name.replace("/", "-")`)
- Slack agent: One instance per workspace/channel
- Custom agent: One instance per user, organization, etc.
### State Management
Each agent instance has:
- **Durable Object storage**: Key-value store for small state
- **SQLite**: Relational database for structured data
- **WebSocket connections**: Real-time state updates to clients
### Webhook Routing
The router extracts identifying information from webhooks and routes to the correct agent instance:
```typescript
// Example: Route GitHub webhooks by repository
const agentName = repo.full_name.replace("/", "-");
const id = env.GITHUB_AGENT.idFromName(agentName);
const stub = env.GITHUB_AGENT.get(id);
return stub.fetch(request);
```
## License
MIT