feat(backend): Phase 3 agent scheduling - item claim/heartbeat/release/done - #165
Conversation
…e/done Adds item_claims table and a claim.rs module in agentflare-backend, a thin wrapper over agentflare-db-kit's generic ClaimLedger (already race-fixed and tested there - no bespoke atomic-upsert SQL duplicated here). item::claim/claim_done compose the lease with item state: claiming an unclaimed item sets the assignee and moves state into the project's "started" group (started_at set via update_state); marking done moves it into "completed" and frees the claim for reclaiming. A live claim held by another owner returns Held and leaves the item untouched. Four new MCP tools in the existing #[tool_router] block: backend_item_claim, backend_item_heartbeat, backend_item_release, backend_item_done. TTL defaults to 4h (AGENTFLARE_BACKEND_CLAIM_TTL_SECS), separate from src/claims.rs's 30-min GitHub-issue-claim default since work items are plausibly longer-running.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe backend adds persistent item claims with acquisition, heartbeat, release, and completion operations. Successful claims update item ownership and state, while MCP tools expose the claim lifecycle with configurable TTL handling. ChangesItem claiming
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant MCPClient
participant AgentflareMcp
participant Backend
participant ItemClaims
participant ItemState
MCPClient->>AgentflareMcp: Claim item_id
AgentflareMcp->>Backend: item::claim(item_id, owner, now, ttl)
Backend->>ItemClaims: Acquire claim
ItemClaims-->>Backend: Acquisition result
Backend->>ItemState: Update owner and started state
Backend-->>AgentflareMcp: Claim result
AgentflareMcp-->>MCPClient: Status JSON
MCPClient->>AgentflareMcp: Complete item_id
AgentflareMcp->>Backend: item::claim_done(item_id, owner, now)
Backend->>ItemClaims: Complete claim
Backend->>ItemState: Update completed state
Backend-->>AgentflareMcp: Completion result
AgentflareMcp-->>MCPClient: Done JSON
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/agentflare-backend/src/item.rs`:
- Around line 415-427: Make the claim lifecycle operations atomic: in
crates/agentflare-backend/src/item.rs lines 415-427, wrap acquisition, the
started-state transition, and assignee update in one transaction; in lines
435-440, wrap the done transition and completed-state update in the same
transaction. Update the surrounding item lifecycle methods without changing
their existing success or failure behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 44ec386b-196a-434d-bf73-70dfdb2f7842
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (7)
crates/agentflare-backend/Cargo.tomlcrates/agentflare-backend/src/claim.rscrates/agentflare-backend/src/item.rscrates/agentflare-backend/src/lib.rscrates/agentflare-backend/src/schema.sqlcrates/agentflare-backend/src/state.rssrc/mcp_server.rs
acquire+started-transition+assignee-update, and done-transition+completed- update, were each three/two separately auto-committed statements. A mid-sequence failure could leave item_claims saying "claimed"/"done" while the item itself never reflected it. Wrapped each in a transaction, same pattern item::create() already uses.
Summary
item_claimstable +claim.rsmodule inagentflare-backend- a thin wrapper overagentflare-db-kit's genericClaimLedger(no bespoke atomic-upsert SQL duplicated here; that logic is already race-fixed and unit-tested in db-kit).item::claim/item::claim_donecompose the lease with item state: claiming an unclaimed item sets the assignee and moves state into the project's "started" group (started_atset via the existingupdate_state); marking done moves it into "completed" and frees the claim for reclaiming by anyone. A live claim held by another owner returnsHeldand leaves the item untouched.#[tool_router]block:backend_item_claim,backend_item_heartbeat,backend_item_release,backend_item_done.AGENTFLARE_BACKEND_CLAIM_TTL_SECS- deliberately separate fromsrc/claims.rs'sAGENTFLARE_CLAIM_TTL_SECS(30 min default for GitHub-issue claims) since work items claimed here are plausibly longer-running.Test plan
cargo test --workspace- all green (333 in the main binary, 55 inagentflare-backendincl. 7 new claim tests, 9 inagentflare-db-kitunchanged)cargo clippy --workspace --all-targets -- -D warnings -A unsafe_code -A clippy::pedantic- clean (CI's actual gate)cargo fmt --check- cleancargo deny check- advisories/bans/licenses/sources all ok#[tool_router]-tagged impl block (grep-verified)Heldand leaves the item unchanged; a stale claim is stealable by a different owner;claim_donemoves to completed and is re-claimable; heartbeat/release/done are owner-scopedSummary by CodeRabbit