feat(cloud-agent): event-driven agent host + message-first CLI#1
feat(cloud-agent): event-driven agent host + message-first CLI#1SarkarShubhdeep wants to merge 6 commits into
Conversation
- Add @mieweb/cloud-agent with hostAgent() API - Session DO for queue-driven turns, suspend/resume, alarms - Storage module for sessions, events, messages, activity_events, summaries - Add @mieweb/cloud-agent-cli with message-first dispatcher - Support --call (streaming) and -txt/--put (fire-and-forget) modes - Update README with new packages Co-authored-by: Cursor <[email protected]>
…a createTools POST /messages now executes the turn inline instead of only enqueueing, and hostAgent accepts an optional createTools(ctx) factory so agents like Jerry can bind runtime tools with DB/vector/alarm context. Co-authored-by: Cursor <[email protected]>
Document the feature/cloud-agent PR opened on mieweb/cloud and track Jerry's vendor/cloud pin (ecb8aa7) in phase-1 plan, README, and chat10. Co-authored-by: Cursor <[email protected]>
|
| export async function initSchema(db: CloudDatabase): Promise<void> { | ||
| await db.exec(` | ||
| CREATE TABLE IF NOT EXISTS sessions ( | ||
| id TEXT PRIMARY KEY, | ||
| user_id TEXT, | ||
| status TEXT NOT NULL DEFAULT 'idle', | ||
| conversation_id TEXT, | ||
| continuation TEXT, | ||
| created_at TEXT NOT NULL, | ||
| updated_at TEXT NOT NULL | ||
| ); | ||
|
|
||
| CREATE TABLE IF NOT EXISTS events ( | ||
| id TEXT PRIMARY KEY, | ||
| session_id TEXT NOT NULL, |
There was a problem hiding this comment.
I'm wondering if this should be using https://orm.drizzle.team/
Take a look and see if this makes more sense. it might be more of a mieweb/cloud thing that we should support drizzle.
There was a problem hiding this comment.
Looked into Drizzle for cloud-agent storage. Right now this is pretty small, just one agent (Jerry), a few simple tables, and the schema lives in storage.ts with basic D1-style queries. Adding Drizzle here would mostly add dependency and migration overhead without much benefit.
Note: If we want Drizzle later, it should be a @mieweb/cloud / vendor/cloud platform thing (optional helper on top of CloudDatabase), not something Jerry owns. That way any future agent can use it across Cloudflare, local SQLite, and libSQL.
Fine to defer for now and revisit when we have more agents or the schema/query surface gets more complex.
There was a problem hiding this comment.
Pull request overview
This PR introduces an event-driven “agent host” package (@mieweb/cloud-agent) that wires an AgentDefinition + AgentRuntime into a Durable Object with queue-driven turns, plus a message-first CLI dispatcher package (@mieweb/cloud-agent-cli) for synchronous --call and async enqueue usage.
Changes:
- Added
@mieweb/cloud-agenthost wiring (hostAgent, session DO) and a D1/SQLite-compatible storage layer with initial tests. - Added
@mieweb/cloud-agent-cliwith argument parsing, HTTP client (streaming-or-JSON), and a generic bin dispatcher. - Updated the packages README to document the new packages.
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/README.md | Documents the new cloud-agent and cloud-agent-cli packages in the monorepo index. |
| packages/cloud-agent/src/types.ts | Defines host/session/storage/runtime types for the agent host. |
| packages/cloud-agent/src/storage.ts | Implements schema init + CRUD helpers for sessions/events/messages/activity/summaries. |
| packages/cloud-agent/src/storage.test.ts | Adds basic tests for storage helpers using a mock DB. |
| packages/cloud-agent/src/session.ts | Implements the session Durable Object turn lifecycle, suspend/resume, and alarm handling. |
| packages/cloud-agent/src/index.ts | Public exports for the cloud-agent package. |
| packages/cloud-agent/src/host.ts | Worker wiring: HTTP routes (/v1/sessions/...) + queue forwarding into the session DO. |
| packages/cloud-agent/package.json | Declares the new @mieweb/cloud-agent package metadata/exports/scripts. |
| packages/cloud-agent-cli/src/types.ts | Defines CLI config/options and streamed event types. |
| packages/cloud-agent-cli/src/run.ts | Implements CLI command dispatch and help/version output. |
| packages/cloud-agent-cli/src/parse.ts | Implements message-first CLI argument parsing. |
| packages/cloud-agent-cli/src/parse.test.ts | Adds tests for CLI parsing behavior. |
| packages/cloud-agent-cli/src/index.ts | Public exports for the cloud-agent-cli package. |
| packages/cloud-agent-cli/src/client.ts | Implements HTTP client for /messages (call) and /enqueue (put). |
| packages/cloud-agent-cli/package.json | Declares the new @mieweb/cloud-agent-cli package metadata/bin/scripts. |
| packages/cloud-agent-cli/bin/agent-cli.js | Adds a generic agent CLI bin entrypoint. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Add lockfile entries for @types/node@^20.0.0 in cloud-agent and cloud-agent-cli so CI pnpm install --frozen-lockfile succeeds. Co-authored-by: Cursor <[email protected]>
Tests use `node --import tsx` but tsx was not declared, causing CI unit job failures on a clean install. Co-authored-by: Cursor <[email protected]>
✅
|
| Contract | Backend | Result |
|---|---|---|
| D1 | libSQL | ✅ pass |
| Vectorize | libsql-vec | ✅ pass |
| R2 | MinIO (S3) | ✅ pass |
| KV | Valkey | ✅ pass |
| Queue | valkey-queue | ✅ pass |
5/5 passed.
2. Jerry on mieweb target (mieweb --target mieweb dev)
| Check | Binding exercised | Result |
|---|---|---|
GET /health |
worker on mieweb target | ✅ pass |
GET /v1/sessions/:id/status |
libSQL + inproc DO | ✅ pass |
POST /v1/events |
libSQL (activity_events) |
✅ pass |
POST /v1/sessions/:id/enqueue |
Valkey queue + DO | ✅ pass |
| session alive after queue turn | queue consumer | ✅ pass |
Persistence confirmed in libSQL: sessions = 2 rows, activity_events = 2 rows.
Note
Full end-to-end agent turns (jerry --call … / sync /messages) require a running Ollama (:11434), which is application-level and outside target/infra conformance. The DB / KV / queue / object-storage contracts all pass on the mieweb backends.
CI status on the branch: unit ✅ + conformance ✅ (after the lockfile + tsx devDependency fixes).
- Forward profile and userId through the /enqueue path into TurnJob so async turns honor the per-request privacy profile. - Persist the enqueued user message and status transitions inside handleTurn so queued turns actually consume the new message; slim handleMessage to delegate and avoid double-inserts. - Reset session status to idle (and log an error event) when a turn throws, preventing sessions from getting stuck in "running". - Retry failed/exception queue jobs instead of ack-ing them so transient failures are not dropped permanently. Co-authored-by: Cursor <[email protected]>
- alarm(): create the scheduled_wake event first and reuse its eventId for the queued wake job, and only delete alarm_payload after JOBS.send() succeeds so a failed enqueue can be retried. - insertEvent(): only store NULL when payload is undefined, so falsy payloads (0, false, "") are persisted instead of silently dropped. Co-authored-by: Cursor <[email protected]>
PR.1-vid.mp4
Summary
Adds
@mieweb/cloud-agentand@mieweb/cloud-agent-cli— the L2 event shell that binds anAgentDefinition+AgentRuntimeto a Durable Object with queue-driven turns, suspend/resume, and alarms.Developed and exercised by the Jerry project (Phase 1 MVP) via the
vendor/cloudsubmodule pin atecb8aa7.@mieweb/cloud-agenthostAgent()— returnsSessionClass,handleFetch,handleQueue, and optionalhandleScheduledTurnJobmessages one at a timeCloudDatabase)createTools(ctx)factory — optional per-turn tool injection (used by Jerry for DB/vector/alarm-bound tools)POST /v1/sessions/:id/messagesruns turns synchronously for--callCLI ergonomics;/enqueuekeeps the async path@mieweb/cloud-agent-cli--call(streaming fetch),-txt/--put(fire-and-forget enqueue)basename(argv[0]); agent-specific packages (jerry, etc.) wrap with configJerry consumer
vendor/cloud@ecb8aa7ondevelopmentpackages/jerry-appuseshostAgent()+createJerryToolspackages/clithin wrapper over@mieweb/cloud-agent-cliCommits
c154c39— initialcloud-agent+cloud-agent-clipackagesecb8aa7— synchronous--callturns;createToolsinjection; profile passthroughTest plan
storage.test.ts— schema init, session/event/message CRUDparse.test.ts— CLI flag/message parsinglocaltarget (pnpm dev+jerry --call …)mieweb(libSQL + Valkey + MinIO) — tracked in Jerry Phase 1Made with Cursor