Skip to content

feat(agents): Agent Layer v0 — agent-action ingestion backend#190

Open
saltyskip wants to merge 2 commits into
mainfrom
feat/agent-layer
Open

feat(agents): Agent Layer v0 — agent-action ingestion backend#190
saltyskip wants to merge 2 commits into
mainfrom
feat/agent-layer

Conversation

@saltyskip

Copy link
Copy Markdown
Owner

What

First slice of the Agent Layer — Rift's measurement + (future) controlled-handoff layer for instrumented MCP servers. Full design in docs/agent-layer-spec.md.

This PR is the backend landing zone: the place a drop-in MCP SDK posts one event per instrumented tool call, which Rift stores and (in later PRs) attributes across agents and through the web→app handoff.

Changes

  • services/agents/ — new domain: AgentActionEvent time-series store (agent_action_events, retention TTL, mirrors conversions/clicks) + record_action service (quota → mint journey token → persist).
  • POST /v1/agents/actions — ingest endpoint, rl_live_/x402 authed, 402 on quota. Quota enforced in the service layer per the transport rules.
  • Public-id typesAgentActionId (aae_) and JourneyToken (rj_).
  • WiringAppState + main.rs repo tuple, OpenAPI path/schemas + "Agents" tag.

Scope / non-goals

Backend only. Reuses the existing Resource::TrackEvent quota meter for v0 (split later when pricing is decided). The riftl-mcp Rust SDK crate (the Instrumented<ServerHandler> wrapper) + routing Rift's own RiftMcp through it (dogfood) land in the next PR.

Checks

cargo fmt --check ✅ · cargo clippy -D warnings ✅ · cargo test ✅ (556 tests)

🤖 Generated with Claude Code

The measurement landing zone for the Agent Layer (see
docs/agent-layer-spec.md): a drop-in MCP SDK will POST one event per
instrumented tool call to a new ingest endpoint, which Rift attributes
across agents. This commit ships the backend half.

- services/agents/: AgentActionEvent time-series store + record_action
  service (quota via TrackEvent → mint journey token → persist)
- POST /v1/agents/actions ingest (rl_live_/x402 auth, 402 on quota)
- AgentActionId (aae_) + JourneyToken (rj_) public-id types
- AppState/main.rs wiring + OpenAPI ("Agents" tag)

Backend only; the riftl-mcp SDK crate + RiftMcp dogfood land next.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
rift Ready Ready Preview, Comment Jun 5, 2026 8:14pm

Request Review

The sensor half of the Agent Layer: a standalone, drop-in crate that
instruments any rmcp ServerHandler and ships every tool call to Rift's
POST /v1/agents/actions ingest.

client/mcp-rust/ (riftl-mcp):
- Instrumented<H>: ServerHandler decorator wrapping the call_tool
  chokepoint; delegates get_info/initialize/list_tools/get_tool unchanged
- fail-open async emit (tokio::spawn) — never blocks or fails the tool call
- ActionEmitter trait + default HttpEmitter; .instrument(config) one-liner
- wire-contract test locking AgentAction JSON to the server's RecordActionRequest
- compiles unchanged against rmcp 1.2 and 1.7

server:
- optional, mcp-feature-gated path dependency on riftl-mcp
- mcp_router wraps RiftMcp via .instrument(...) when RIFT_AGENT_INGEST_URL
  + RIFT_AGENT_KEY are set (opt-in dogfood; off by default)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@saltyskip

Copy link
Copy Markdown
Owner Author

Update: the riftl-mcp SDK crate + RiftMcp dogfood wiring landed in this PR (commit 3ebd028), not a follow-up — it kept the slice coherent and the type-level dogfood (Instrumented<RiftMcp>) validates the whole approach. Gate green on both crate and server: fmtclippy -D warningstest ✅. Next PR is v1: the handoff rail (journey-token claim through /lifecycle/attribute, actor/agent_platform on touches, agent fields on the conversion webhook) → cross-agent conversion funnel.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant