Skip to content

feat: distinguish failed/partial TWAP orders from expired - #203

Merged
premiumjibles merged 2 commits into
mainfrom
feat/twap-failed-status
Mar 9, 2026
Merged

premiumjibles merged 2 commits into
mainfrom
feat/twap-failed-status

Conversation

@premiumjibles

@premiumjibles premiumjibles commented Mar 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Refactored isTwapFulfilled → getTwapFilledPartCount to return fill count instead of boolean
  • TWAP orders that expire now resolve to three distinct end states: fulfilled (all parts filled), partiallyFilled (some parts filled), failed (zero parts filled)
  • Added failed and partiallyFilled to type unions across server and chat app
  • Added UI badges: Failed (orange, AlertTriangle) and Partially Filled (yellow, AlertCircle)
  • Updated system prompt with guidance for failed/partial TWAP statuses

Test plan

  • bunx tsc --noEmit — type-check passes
  • Verify a TWAP with 0 fills shows "Failed" badge
  • Verify a TWAP with partial fills shows "Partially Filled" badge
  • Verify a fully filled TWAP still shows "Filled" badge
  • Verify filtering by failed and partiallyFilled statuses works

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added two new order statuses: Failed and Partially Filled.
    • Registry orders now include an optional numParts field and status filtering recognizes the new statuses.
    • UI updated to show the new statuses with corresponding visuals.
  • Tests

    • Expanded TWAP test suite with comprehensive status derivation and filled-part counting scenarios.
    • Added reusable TWAP/COW test fixtures for easier test construction.

@vercel

vercel Bot commented Mar 9, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
shapeshift-agentic Ready Ready Preview, Comment Mar 9, 2026 3:34am

Request Review

@coderabbitai

coderabbitai Bot commented Mar 9, 2026 •

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: addae9b2-1c35-43a5-b1bb-005d5555b1da

📥 Commits

Reviewing files that changed from the base of the PR and between 2bfd4f3 and e7c8f28.

📒 Files selected for processing (9)
  • .tickets/sa-ppkj.md
  • apps/agentic-chat/src/components/tools/GetTwapOrdersUI.tsx
  • apps/agentic-chat/src/stores/orderStore.ts
  • apps/agentic-server/src/lib/cow/types.ts
  • apps/agentic-server/src/routes/chat.ts
  • apps/agentic-server/src/tools/twap/__tests__/fixtures.ts
  • apps/agentic-server/src/tools/twap/__tests__/getTwapOrders.test.ts
  • apps/agentic-server/src/tools/twap/getTwapOrders.ts
  • apps/agentic-server/src/utils/walletContextSimple.ts

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.


📝 Walkthrough

Walkthrough

Adds two TWAP statuses ('failed', 'partiallyFilled'), updates types/schema across client and server, refactors TWAP status derivation into exported helper functions, updates UI/status config, and adds fixtures and extensive tests for status and filled-part computation.

Changes

Cohort / File(s) Summary
Ticket Update
\.tickets/sa-ppkj.md
Ticket status flipped from open to done.
Type & Interface Expansions
apps/agentic-chat/src/stores/orderStore.ts, apps/agentic-server/src/lib/cow/types.ts, apps/agentic-server/src/utils/walletContextSimple.ts
Extended order status unions to include 'failed' and 'partiallyFilled'.
UI Component Updates
apps/agentic-chat/src/components/tools/GetTwapOrdersUI.tsx
Added AlertTriangle import, extended TwapOrderStatus union and STATUS_CONFIG to support failed and partiallyFilled with icons/labels/classes.
API Schema & Chat Docs
apps/agentic-server/src/routes/chat.ts
Expanded registry order status enum to include new statuses and added optional numParts field to registry entries; updated guidance text.
Core TWAP Logic
apps/agentic-server/src/tools/twap/getTwapOrders.ts
Replaced inline fulfillment logic with exported deriveTwapStatus() and getTwapFilledPartCount(); added cowApiFailed handling; extended input schema to allow new status filters; removed isTwapFulfilled.
Tests & Fixtures
apps/agentic-server/src/tools/twap/__tests__/fixtures.ts, apps/agentic-server/src/tools/twap/__tests__/getTwapOrders.test.ts
Added fixtures/constants and factory helpers; introduced comprehensive tests covering deriveTwapStatus and filled-part counting across many edge cases.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant AgenticServer
  participant CoW_API
  participant OrderStore

  Client->>AgenticServer: getTwapOrders(request with status filter)
  AgenticServer->>OrderStore: fetch active TWAP summaries
  AgenticServer->>CoW_API: fetch CoW orders for TWAP parts
  CoW_API-->>AgenticServer: cow orders (or failure)
  AgenticServer->>AgenticServer: getTwapFilledPartCount(order, cowOrders)
  AgenticServer->>AgenticServer: deriveTwapStatus(order, cowOrders, isActive, now, cowApiFailed)
  AgenticServer-->>Client: registry orders with derived status / numParts
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I hopped through types, I hopped through tests,

Failed and Partially Filled added to the nests.
Fixtures and logic now neatly aligned,
TWAP statuses sorted, counted, and signed.
A little rabbit cheers — code’s redesigned! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: distinguish failed/partial TWAP orders from expired' clearly and specifically summarizes the main change: adding new status distinctions for TWAP orders to differentiate failed and partially filled states from expired.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/twap-failed-status

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/agentic-server/src/tools/twap/getTwapOrders.ts (1)

81-102: ⚠️ Potential issue | 🟠 Major

Tighten child-order matching before using this count for terminal status.

On Lines 88-99, filledCount is inferred from totalSell / numParts plus pair/time-window matching. That can miscount in at least two cases: a TWAP whose total sell amount is not evenly divisible by numParts will drop the remainder and undercount one part, and two overlapping TWAPs on the same Safe with the same pair/part size can both match the same CoW child orders. Either case will surface the wrong failed/partiallyFilled/fulfilled status.

Please anchor the match to a parent-order identifier or metadata field if one exists, rather than relying on exact per-part amount plus timestamps alone.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/agentic-server/src/tools/twap/getTwapOrders.ts` around lines 81 - 102,
getTwapFilledPartCount currently matches child orders only by token pair, exact
per-part amount (expectedPartAmount) and timestamps which can undercount when
totalSell % numParts != 0 or mis-attribute child orders across overlapping
TWAPs; update getTwapFilledPartCount to first try anchoring child orders to a
parent identifier/metadata (check co.parentOrderId, co.metadata?.parentOrderId,
co.twapOrderId or similar) and match it to order.id or order.parentId, and only
fall back to amount/timestamp heuristics if no parent id exists; additionally,
when falling back avoid strict equality to expectedPartAmount—compute filled
parts by summing toBigInt(co.executedSellAmount) for matching child orders and
deriving count = min(numParts, floor(sumExecuted / expectedPartAmount) +
(sumExecuted % expectedPartAmount ? 1 : 0)) so remainders count as a filled part
rather than being dropped (use variables order, expectedPartAmount, cowOrders,
matchingFilledParts and return that adjusted count).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@apps/agentic-server/src/tools/twap/getTwapOrders.ts`:
- Around line 81-102: getTwapFilledPartCount currently matches child orders only
by token pair, exact per-part amount (expectedPartAmount) and timestamps which
can undercount when totalSell % numParts != 0 or mis-attribute child orders
across overlapping TWAPs; update getTwapFilledPartCount to first try anchoring
child orders to a parent identifier/metadata (check co.parentOrderId,
co.metadata?.parentOrderId, co.twapOrderId or similar) and match it to order.id
or order.parentId, and only fall back to amount/timestamp heuristics if no
parent id exists; additionally, when falling back avoid strict equality to
expectedPartAmount—compute filled parts by summing
toBigInt(co.executedSellAmount) for matching child orders and deriving count =
min(numParts, floor(sumExecuted / expectedPartAmount) + (sumExecuted %
expectedPartAmount ? 1 : 0)) so remainders count as a filled part rather than
being dropped (use variables order, expectedPartAmount, cowOrders,
matchingFilledParts and return that adjusted count).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5c341aef-83fe-4bfb-8d2b-ded7e9aea096

📥 Commits

Reviewing files that changed from the base of the PR and between 22368d2 and 2bfd4f3.

📒 Files selected for processing (9)
  • .tickets/sa-ppkj.md
  • apps/agentic-chat/src/components/tools/GetTwapOrdersUI.tsx
  • apps/agentic-chat/src/stores/orderStore.ts
  • apps/agentic-server/src/lib/cow/types.ts
  • apps/agentic-server/src/routes/chat.ts
  • apps/agentic-server/src/tools/twap/__tests__/fixtures.ts
  • apps/agentic-server/src/tools/twap/__tests__/getTwapOrders.test.ts
  • apps/agentic-server/src/tools/twap/getTwapOrders.ts
  • apps/agentic-server/src/utils/walletContextSimple.ts

premiumjibles and others added 2 commits March 9, 2026 10:33
TWAP orders that expire now show granular end states based on fill count:
- "failed" (0 fills) - solvers ignored all sub-orders
- "partiallyFilled" (some fills) - incomplete execution
- "fulfilled" (all fills) - unchanged behavior

Adds UI badges, system prompt guidance, and type updates across the stack.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
numParts was being stripped by Zod validation, causing all expired
TWAPs to show as 'expired' instead of 'failed'/'partiallyFilled'.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@premiumjibles
premiumjibles force-pushed the feat/twap-failed-status branch from 2bfd4f3 to e7c8f28 Compare March 9, 2026 03:33
@premiumjibles
premiumjibles merged commit b6f688c into main Mar 9, 2026
1 of 4 checks passed
@premiumjibles
premiumjibles deleted the feat/twap-failed-status branch March 9, 2026 03:33

This branch was successfully deployed

1 active deployment
Preview — e7c8f28d Deployed Mar 9, 2026 by vercel[bot]
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