-
Notifications
You must be signed in to change notification settings - Fork 1
feat: informational tooling #131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughAdds multiple CoinGecko-backed server tools, new Coingecko types and API wrappers, asset price helpers, a reusable AssetListItem UI, three ToolCard UIs (Trending, TopGainers/Losers, NewCoins), registers those UIs, and wires tools into the chat router with a logging wrapper. Changes
Sequence Diagram(s)sequenceDiagram
participant User as Chat User
participant UI as Client UI (ToolCard)
participant Server as Agentic Server (routes/chat)
participant Tool as Tool Executor (executeGet*)
participant CG as CoinGecko API
participant Resolver as AssetId Resolver
User->>UI: request (e.g., "show trending tokens")
UI->>Server: invoke registered tool execute
Server->>Tool: executeGetTrendingTokens / executeGetTopGainersLosers / ...
Tool->>CG: fetch raw data (getTrendingSearch / getTopGainersLosers / ...)
CG-->>Tool: raw response
Tool->>Resolver: map & resolve assetId/coingecko -> Trimmed*
Resolver-->>Tool: trimmed items
Tool-->>Server: trimmed tool output
Server-->>UI: deliver tool output
UI->>UI: useToolStateRender handles loading/error
UI->>User: render ToolCard with AssetListItem rows
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Areas to focus on:
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (8)
apps/agentic-server/src/tools/send.ts (1)
121-132: Prompt update is clear and safe; consider one extra guardrail about execution claimsThe new description cleanly scopes the tool’s behavior around the send card and should help reduce redundant or verbose replies. As a minor improvement, you might explicitly add that the assistant must not claim the transaction has already been sent or executed (only prepared/pending user confirmation), to avoid any misleading language about on-chain state.
apps/agentic-server/src/tools/receive.ts (1)
34-45: Clear tool description; consider softening the “Do not repeat the address” ruleThe expanded description is clear and matches the UI‑card pattern in this PR. One small tweak: the hard “Do not repeat the address” could conflict with cases where the user explicitly asks “What’s my address?” or where the card fails to render (e.g., non‑UI contexts).
Consider something like:
-Your role is to supplement the card, not duplicate it. Do not repeat the address. +Your role is to supplement the card, not duplicate it. Avoid repeating the full address +unless the user explicitly asks for it or the card is not visible.This keeps responses concise in the normal UI flow while leaving room for edge cases.
apps/agentic-server/src/context.ts (1)
24-24: Helpful guidance for unsupported swaps.The new line provides clear instruction on how to handle user requests for swaps with unsupported assets, which improves the user experience.
Optional: Consider capitalizing consistently with line 17.
For consistency with line 17 (which uses lowercase: "bitcoin, litecoin, dogecoin, bitcoincash, cosmos, thorchain, tron, cardano, sui"), you might use lowercase in the examples here as well:
- - If user requests swap with unsupported assets (Bitcoin, Cardano, etc.), explain swaps only support EVM and Solana + - If user requests swap with unsupported assets (bitcoin, cardano, etc.), explain swaps only support EVM and Solanaapps/agentic-chat/src/components/ui/AssetListItem.tsx (1)
24-49: Consider extractingIconFromUrlas a shared component or consolidating withAssetIcon.The
IconFromUrlcomponent duplicates fallback logic present inAssetIcon(lines 22-35 ofAssetIcon.tsx). Both components handle image error states and render initials as fallback. If this pattern is used elsewhere, consider a shared primitive.That said, the current implementation is correct and self-contained.
apps/agentic-server/src/tools/getTrendingPools.ts (1)
67-69: Consider aligning price change period with the requested duration.The
priceChange24hfield always usesh24regardless of thedurationparameter. If the user requests 1h trending pools, showing 24h price change may be unexpected.You could either:
- Keep as-is (24h is a standard metric) and clarify in the output field name
- Dynamically select the price change period based on duration
// Option 2: Dynamic selection const durationToKey: Record<string, keyof NonNullable<typeof pool.attributes.price_change_percentage>> = { '5m': 'm5', '1h': 'h1', '6h': 'h6', '24h': 'h24', } priceChange: pool.attributes.price_change_percentage?.[durationToKey[duration]] ?? null,apps/agentic-server/src/tools/getNewCoins.ts (1)
17-30: Consider guardingformatTimeAgoagainst future timestampsIf
activated_atever lands slightly in the future (clock skew, API oddities),diffMsbecomes negative and everything collapses to'Just now'. Not a bug, but an easy robustness win would be an early guard:function formatTimeAgo(timestamp: number): string { const now = Date.now() - const diffMs = now - timestamp * 1000 + const diffMs = now - timestamp * 1000 + if (diffMs <= 0) return 'Just now'and then keep the existing hour/day logic.
apps/agentic-server/src/tools/getAssets.ts (2)
62-87: Single-asset resolution and network inference deserve a quick sanity checkThe precedence
searchTerm→ firstassetIds[0]→undefinedis clear, and inferringnetworkfromchainIdToNetworkwith an'ethereum'fallback ensures the field is always populated. Two things worth verifying:
- That combinations like
{ searchTerm, assetIds }are either not used or intentionally favorsearchTerm.- That using the optional
networkparameter as an override (rather than purely a filter) for the returned asset’snetworkis acceptable for all current callers.If either assumption doesn’t hold, you may want to document this behavior or split “filter network” from “override network” semantics.
89-113: Bulk price path looks correct; consider minor alignment on priceChange nullabilityThe bulk path:
- Filters out unknown assets,
- Fetches prices once via
getSimplePrices(assetIds),- Overlays
priceandpriceChange24honto static assets while inferringnetworksimilarly to the single-asset path.One small consistency tweak you might consider: explicitly normalizing
priceChange24htonullwhen missing so that both single-asset and bulk responses use the samenumber | nullshape instead of mixingundefinedandnull. Not mandatory, but it can simplify UI checks.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (24)
apps/agentic-chat/src/components/toolUIRegistry.tsx(2 hunks)apps/agentic-chat/src/components/tools/NewCoinsUI.tsx(1 hunks)apps/agentic-chat/src/components/tools/TopGainersLosersUI.tsx(1 hunks)apps/agentic-chat/src/components/tools/TrendingTokensUI.tsx(1 hunks)apps/agentic-chat/src/components/ui/AssetListItem.tsx(1 hunks)apps/agentic-server/src/context.ts(1 hunks)apps/agentic-server/src/index.ts(1 hunks)apps/agentic-server/src/lib/asset/coingecko/api.ts(2 hunks)apps/agentic-server/src/lib/asset/coingecko/index.ts(1 hunks)apps/agentic-server/src/lib/asset/coingecko/types.ts(1 hunks)apps/agentic-server/src/routes/chat.ts(2 hunks)apps/agentic-server/src/tools/getAssets.ts(2 hunks)apps/agentic-server/src/tools/getCategories.ts(1 hunks)apps/agentic-server/src/tools/getNewCoins.ts(1 hunks)apps/agentic-server/src/tools/getShapeShiftKnowledge.ts(1 hunks)apps/agentic-server/src/tools/getTopGainersLosers.ts(1 hunks)apps/agentic-server/src/tools/getTrendingPools.ts(1 hunks)apps/agentic-server/src/tools/getTrendingTokens.ts(1 hunks)apps/agentic-server/src/tools/initiateSwap.ts(4 hunks)apps/agentic-server/src/tools/portfolio.ts(4 hunks)apps/agentic-server/src/tools/receive.ts(1 hunks)apps/agentic-server/src/tools/send.ts(1 hunks)apps/agentic-server/src/tools/transactionHistory.ts(1 hunks)apps/agentic-server/src/utils/assetHelpers.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-18T20:08:31.777Z
Learnt from: kaladinlight
Repo: shapeshift/agentic-chat PR: 73
File: apps/agentic-chat/src/components/assistant-ui/GetPortalsAssets.tsx:30-33
Timestamp: 2025-09-18T20:08:31.777Z
Learning: In assistant UI components using makeAssistantToolUI, the toolName should match the exact key name as defined in the agent's tools configuration object, not the underlying tool's id. For example, if a tool is referenced as 'getPortalsAssetsTool' in the agent's tools object, the UI component should use toolName: 'getPortalsAssetsTool'.
Applied to files:
apps/agentic-chat/src/components/toolUIRegistry.tsx
🧬 Code graph analysis (11)
apps/agentic-chat/src/components/tools/TopGainersLosersUI.tsx (5)
apps/agentic-chat/src/components/tools/toolUIHelpers.tsx (2)
ToolUIComponentProps(6-8)useToolStateRender(10-31)apps/agentic-server/src/index.ts (1)
TrimmedGainerLoserCoin(93-93)apps/agentic-server/src/lib/asset/coingecko/types.ts (1)
TrimmedGainerLoserCoin(202-212)apps/agentic-chat/src/components/ui/ToolCard.tsx (1)
ToolCard(71-78)apps/agentic-chat/src/components/ui/AssetListItem.tsx (1)
AssetListItem(51-112)
apps/agentic-chat/src/components/tools/NewCoinsUI.tsx (5)
apps/agentic-chat/src/components/tools/toolUIHelpers.tsx (2)
ToolUIComponentProps(6-8)useToolStateRender(10-31)apps/agentic-server/src/index.ts (1)
TrimmedNewCoin(96-96)apps/agentic-server/src/lib/asset/coingecko/types.ts (1)
TrimmedNewCoin(236-243)apps/agentic-chat/src/components/ui/ToolCard.tsx (1)
ToolCard(71-78)apps/agentic-chat/src/components/ui/AssetListItem.tsx (1)
AssetListItem(51-112)
apps/agentic-server/src/tools/getTrendingPools.ts (2)
apps/agentic-server/src/lib/asset/coingecko/types.ts (3)
TrimmedTrendingPool(214-225)TrendingPoolIncluded(148-159)TrendingPoolData(105-146)apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
getTrendingPools(134-142)
apps/agentic-server/src/routes/chat.ts (6)
apps/agentic-server/src/index.ts (5)
getTrendingTokensTool(67-67)getTopGainersLosersTool(73-73)getTrendingPoolsTool(79-79)getCategoriesTool(85-85)getNewCoinsTool(90-90)apps/agentic-server/src/tools/getTrendingTokens.ts (1)
getTrendingTokensTool(39-54)apps/agentic-server/src/tools/getTopGainersLosers.ts (1)
getTopGainersLosersTool(53-68)apps/agentic-server/src/tools/getTrendingPools.ts (1)
getTrendingPoolsTool(77-81)apps/agentic-server/src/tools/getCategories.ts (1)
getCategoriesTool(42-46)apps/agentic-server/src/tools/getNewCoins.ts (1)
getNewCoinsTool(53-68)
apps/agentic-chat/src/components/toolUIRegistry.tsx (3)
apps/agentic-chat/src/components/tools/TrendingTokensUI.tsx (1)
TrendingTokensUI(10-56)apps/agentic-chat/src/components/tools/TopGainersLosersUI.tsx (1)
TopGainersLosersUI(10-95)apps/agentic-chat/src/components/tools/NewCoinsUI.tsx (1)
NewCoinsUI(10-55)
apps/agentic-server/src/lib/asset/coingecko/api.ts (2)
apps/agentic-server/src/lib/asset/coingecko/index.ts (10)
getTrendingSearch(4-4)TrendingSearchResponse(13-13)getTopGainersLosers(5-5)TopGainersLosersResponse(14-14)getTrendingPools(6-6)TrendingPoolsResponse(15-15)getCategories(7-7)CategoriesResponse(16-16)getNewCoins(8-8)NewCoinsResponse(17-17)apps/agentic-server/src/lib/asset/coingecko/types.ts (5)
TrendingSearchResponse(62-74)TopGainersLosersResponse(92-95)TrendingPoolsResponse(161-164)CategoriesResponse(179-179)NewCoinsResponse(189-189)
apps/agentic-server/src/utils/assetHelpers.ts (4)
apps/agentic-server/src/lib/schemas/swapSchemas.ts (1)
AssetInput(76-76)packages/types/src/asset.ts (1)
Asset(28-28)apps/agentic-server/src/index.ts (1)
executeGetAssets(5-5)apps/agentic-server/src/tools/getAssets.ts (1)
executeGetAssets(115-129)
apps/agentic-server/src/tools/portfolio.ts (2)
apps/agentic-server/src/tools/getAssets.ts (1)
executeGetAssets(115-129)packages/types/src/asset.ts (1)
asset(3-26)
apps/agentic-chat/src/components/ui/AssetListItem.tsx (5)
packages/caip/src/constants.ts (1)
AssetId(176-176)apps/agentic-chat/src/lib/utils.ts (1)
cn(5-7)apps/agentic-chat/src/lib/bignumber.ts (1)
bnOrZero(5-13)apps/agentic-chat/src/components/ui/AssetIcon.tsx (1)
AssetIcon(12-47)apps/agentic-chat/src/lib/number.ts (2)
formatFiat(70-82)formatPercent(98-117)
apps/agentic-server/src/tools/getTrendingTokens.ts (3)
apps/agentic-server/src/lib/asset/coingecko/types.ts (2)
TrimmedTrendingCoin(192-200)TrendingCoinItem(37-60)apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
getTrendingSearch(107-110)packages/caip/src/adapters/coingecko/index.ts (1)
coingeckoToAssetIds(57-57)
apps/agentic-server/src/tools/getAssets.ts (4)
packages/types/src/asset.ts (2)
asset(3-26)Asset(28-28)packages/utils/src/AssetService.ts (1)
assetService(135-135)packages/types/src/network.ts (1)
chainIdToNetwork(84-86)apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
getSimplePrices(56-101)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: main
🔇 Additional comments (33)
apps/agentic-server/src/tools/transactionHistory.ts (1)
114-115: Tool description update is clear and aligned with behaviorThe new description cleanly communicates that this tool is for filtered transaction queries and that responses should present/format data directly without assuming UI cards. This matches the implementation and the broader analytics‑focused tooling direction.
apps/agentic-server/src/context.ts (1)
20-20: LGTM! Clearer section heading.The change from "Tool Usage:" to "Network-Specific Capabilities:" better describes the content of this section and improves documentation clarity.
apps/agentic-server/src/tools/getShapeShiftKnowledge.ts (1)
60-64: Clarified tool semantics look goodThe updated description clearly signals that this is a pure informational tool with no UI card, which should reduce redundant card-oriented phrasing in responses. No behavioral changes—safe update.
apps/agentic-server/src/utils/assetHelpers.ts (1)
5-32: Good migration to unifiedexecuteGetAssetsSwitching
resolveAssetto useexecuteGetAssetswith{ searchTerm, network }keeps the single-asset resolution semantics while routing through the new shared asset pipeline. The length checks and error messages still correctly enforce “exactly one asset” behavior.apps/agentic-server/src/tools/portfolio.ts (2)
10-118: executeGetAssets integration and 24h change mapping look consistentUsing
executeGetAssets({ assetIds })aligns this tool with the new unified asset API and still supports both single- and multi-asset portfolios via the internal branching. NormalizingpriceChange24hwith?? undefinedis a nice touch to avoid leakingnullwhile keeping zero changes intact.
153-168: Rich portfolio description matches UI‑card patternThe expanded
portfolioTool.descriptionclearly documents what the card shows and how the assistant should respond (brief, non-duplicative summaries). This aligns well with the new informational tooling guidelines.apps/agentic-chat/src/components/tools/TrendingTokensUI.tsx (1)
1-55: Trending tokens UI is wired cleanly and matches existing patternsState handling via
useToolStateRender, the output cast, and theToolCard+AssetListItemcomposition all mirror your other tool UIs. Prop usage (price, priceChange24h, rank, assetId) matchesTrimmedTrendingCoinandAssetListItemexpectations, so this should render reliably.apps/agentic-chat/src/components/tools/TopGainersLosersUI.tsx (1)
1-95: Top gainers/losers UI is consistent and robust to empty setsThe component cleanly splits gainers and losers into separate
ToolCards, usesvariant="gain"/"loss"correctly for styling, and short‑circuits when both arrays are empty. The type assertion matchesTrimmedGainerLoserCoin, so as long as the server keeps that contract, this should be solid.apps/agentic-server/src/tools/initiateSwap.ts (2)
21-362: USD swap flow’s move toexecuteGetAssetspreserves behaviorUsing
executeGetAssetsto resolve the sell asset inexecuteInitiateSwapUsd(withsearchTerm+ optionalnetwork) keeps the previous semantics: clear errors on zero/multiple matches, then price‑based conversion to crypto before delegating toexecuteSwapInternal. The rest of the swap pipeline (rate selection, approvals, summary) stays untouched, so behavior should match the old path while benefiting from the unified asset API.
293-308: Swap tool descriptions now align with the card‑first UXBoth
initiateSwapToolandinitiateSwapUsdToolnow explicitly describe what the UI card shows and instruct the assistant to add a short, supplementary sentence instead of restating data. This should significantly reduce verbose or duplicative responses around swap details.Also applies to: 364-379
apps/agentic-chat/src/components/tools/NewCoinsUI.tsx (1)
1-55: New coins UI component is well‑structured and type‑alignedThis follows the established tool UI pattern: proper loading/error handling, safe early return on empty data, and a clear
ToolCardlayout. TheAssetListItemprops line up withTrimmedNewCoin, and the “Listed {activatedAtFormatted}” subtitle is a nice contextual touch.apps/agentic-chat/src/components/toolUIRegistry.tsx (1)
9-38: Tool registry entries are correctly implemented with names matching agent configuration.The three new registry entries—
getTrendingTokensTool,getTopGainersLosersTool, andgetNewCoinsTool—align perfectly with the tool definitions exported from the server and configured in the agent's tools object (apps/agentic-server/src/routes/chat.ts). The UI component imports are also properly in place. No issues detected.apps/agentic-chat/src/components/ui/AssetListItem.tsx (1)
51-112: LGTM!The component correctly handles:
- Optional rank display with proper formatting
- Icon priority cascade (assetId → iconUrl → initials fallback)
- Conditional price/change rendering guarded by
hasPrice/hasChange- Variant-based color override with sensible defaults
- Proper use of
tabular-numsfor numeric alignmentapps/agentic-server/src/lib/asset/coingecko/index.ts (1)
1-23: LGTM!Clean barrel file that correctly re-exports the new CoinGecko API functions and associated types. The exports are well-organized with functions and types separated.
apps/agentic-server/src/tools/getTrendingPools.ts (1)
21-75: LGTM!The implementation correctly:
- Builds lookup maps from the
includedarray with type filtering- Handles missing relationships and attributes with sensible fallbacks
- Slices results to the requested limit before processing
- Maintains null safety throughout the mapping
apps/agentic-server/src/tools/getCategories.ts (2)
21-40: LGTM!Clean implementation with:
- Sensible defaults (market_cap_change_24h for trending relevance)
- Proper mapping from user-friendly input to API parameters
- Null-safe field access with fallbacks
- Efficient slice-then-map pattern
6-12: LGTM!The schema provides clear validation with helpful descriptions. The limit bounds (1-20) are appropriate for category data.
apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
103-168: No issues found — original review is accurate.All CoinGecko Pro API endpoints are correctly implemented:
/search/trending— valid trending search endpoint ✓/coins/top_gainers_losers— valid gainers/losers endpoint with correct duration/top_coins parameters ✓/onchain/networks/trending_pools— valid all-networks trending pools endpoint with correct include and duration params ✓/coins/categories— valid categories endpoint with correct order parameter ✓/coins/list/new— valid new coins endpoint ✓The function signatures, parameter defaults, and types all align with CoinGecko Pro API documentation. The implementation is clean, well-documented, and consistent with the existing codebase patterns.
apps/agentic-server/src/tools/getTrendingTokens.ts (3)
7-15: Input schema and output typing are well-boundedLimit validation (1–15 with a default of 5) and the dedicated
GetTrendingTokensInput/GetTrendingTokensOutputtypes give a clear, narrow surface for the tool; no issues from a correctness standpoint.
17-36: Trending token mapping looks correct and null-safeSlicing by
limitand mappingTrendingCoinItemintoTrimmedTrendingCoin(including optionalassetIdviacoingeckoToAssetIds) is clean and handles missingdatafields via optional chaining and null fallbacks. This should be robust even when CoinGecko omits nested fields.
39-53: Tool description aligns with UI-card patternThe description clearly constrains the LLM to “supplement” the card rather than re-list data, and the default responses are short and on-brand. This is consistent with the other informational tools introduced in this PR.
apps/agentic-server/src/tools/getNewCoins.ts (3)
7-15: New-coins schema is consistent with the other toolsThe
limitbounds (1–20, default 5) and dedicated input/output types mirror the other CoinGecko tools and provide a predictable interface.
32-51: New-coin mapping and assetId resolution look soundSlicing by
limit, mapping toTrimmedNewCoin, and derivingassetIdviacoingeckoToAssetIdsis straightforward. The dual fieldsactivatedAt(raw) andactivatedAtFormatted(human-readable) should make UI rendering flexible without extra client logic.
53-68: Tool description clearly scopes LLM behaviorThe “UI CARD DISPLAYS…” block plus sample default sentences fits the new informational-tool pattern and should help keep responses concise and non-duplicative of card contents.
apps/agentic-server/src/tools/getTopGainersLosers.ts (2)
7-21: Duration and limit parameters are well-scopedThe duration enum and limit (1–10, default 5) provide a tidy and self-documenting API for this tool. Leaving
durationoptional with a default of'24h'is a reasonable choice.
53-68: Top gainers/losers tool description is precise and UI-awareThe copy clearly instructs the model not to re-list tokens or percentages already visible in the card, and the suggested one-liners keep responses succinct. This matches the intended “informational tooling” UX.
apps/agentic-server/src/index.ts (1)
66-97: Public exports for new tools and types are coherentRe-exporting the new tools and their input/output types, plus the
Trimmed*CoinGecko types, keeps the server’s public surface consistent with existing tooling. This should make it straightforward for both the router and UI to consume these features without reaching into deep paths.apps/agentic-server/src/routes/chat.ts (1)
21-27: New informational tools are wired into the chat router consistentlyThe added imports and
buildToolsentries forgetTrendingTokensTool,getTopGainersLosersTool,getTrendingPoolsTool,getCategoriesTool, andgetNewCoinsToolmirror the existing pattern: spread the base tool, wrapexecutewith a logging layer, and avoid touching wallet context for these wallet-agnostic calls. No correctness issues spotted here.Also applies to: 163-197
apps/agentic-server/src/tools/getAssets.ts (4)
32-35: UnifiedGetAssetsOutputsimplifies the API surfaceConsolidating into a single
{ assets: AssetWithMarketData[] }output removes the split between “basic” and “with market data” paths, which should reduce branching for callers and UI.
36-60:enrichWithMarketDatacorrectly layers CoinGecko fields on top of static assetsThe enrichment step safely handles missing fields (using
?? nulland optional chaining) and augments the baseAssetwith icon, market cap, volume, supply, sentiment, rank, and description. The scoped error log plus null return is a reasonable pattern that lets the caller gracefully fall back.
115-129: Routing logic inexecuteGetAssetsmatches the new API modelThe dispatcher cleanly chooses:
- single-asset enrichment when
searchTermis present or exactly oneassetIdis provided,- bulk price fetch when
assetIds.length > 1,- otherwise returns an empty list.
This is straightforward and keeps the branching close to the tool entrypoint.
131-147: UpdatedgetAssetsTooldescription matches the informational tooling patternThe guidance around the UI card (what it shows vs what the LLM should add) is clear and mirrors the new market-info tools. Wiring
executetoexecuteGetAssetscompletes the refactor to the unified output.apps/agentic-server/src/lib/asset/coingecko/types.ts (1)
36-243: New CoinGecko endpoint and trimmed types are consistent with tool usageThe added types (
TrendingCoinItem,TopGainersLosersResponse,TrendingPool*,CategoryData,NewCoinData, and the variousTrimmed*shapes) align with how the tools consume and emit data:
- Raw response types expose the full CoinGecko payloads, including optional nested fields.
- Trimmed variants keep only the minimal fields the tools and UI need, helping to control LLM context size.
- Nullability and optionality (e.g.,
pricevspriceChange*,marketCapRank,assetId?) match the access patterns in the new tools.I don’t see structural mismatches between these definitions and the tool mappers in this PR.
3f66c45 to
2b59446
Compare
2b59446 to
ea292ab
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
apps/agentic-server/src/tools/getTopGainersLosers.ts (1)
7-13: Align duration support with exposed price‑change fields
durationaccepts'1h' | '24h' | '7d' | '14d' | '30d'andGainerLoserCoinincludesusd_14d_change/usd_30d_change, butTrimmedGainerLoserCoinandmapCoinonly surface 1h/24h/7d. Callers can never see 14d/30d changes even when requesting those durations.Either (a) extend the trimmed type and mapper, or (b) narrow the allowed
durationvalues to the periods you actually expose:-// apps/agentic-server/src/lib/asset/coingecko/types.ts export type TrimmedGainerLoserCoin = { id: string name: string symbol: string price: number priceChange24h: number priceChange1h?: number priceChange7d?: number + priceChange14d?: number + priceChange30d?: number marketCapRank: number | null assetId?: string }-// apps/agentic-server/src/tools/getTopGainersLosers.ts price: coin.usd, priceChange24h: coin.usd_24h_change, priceChange1h: coin.usd_1h_change, - priceChange7d: coin.usd_7d_change, + priceChange7d: coin.usd_7d_change, + priceChange14d: coin.usd_14d_change, + priceChange30d: coin.usd_30d_change,Alternatively, if you intend to always show 24h change regardless of selection, consider restricting
durationto'1h' | '24h' | '7d'to avoid implying 14d/30d data is available.Also applies to: 31-43
🧹 Nitpick comments (5)
apps/agentic-server/src/context.ts (1)
20-24: Docs update is accurate; consider a minor wording polishThe new section correctly describes capabilities and clarifies unsupported swap assets; this is a useful addition and matches the preceding lists of supported networks. To tighten the language, you might make the last bullet a bit clearer and more grammatical:
- - If user requests swap with unsupported assets (Bitcoin, Cardano, etc.), explain swaps only support EVM and Solana + - If the user requests a swap with unsupported assets (e.g., Bitcoin, Cardano), explain that swaps only support EVM chains and SolanaThis keeps it consistent with the “SUPPORTED/NOT SUPPORTED” phrasing above and reads more naturally.
apps/agentic-chat/src/components/ui/AssetListItem.tsx (1)
66-79: Consider simplifying formatting and clarifyingvariantvs numeric sign behaviorYou currently wrap
price/priceChange24hwithbnOrZeroand then pass the resulting BigNumbers intoformatFiat/formatPercent, which already applybnOrZerointernally. You could pass the raw props directly (and potentially drop the memos) to trim a bit of indirection.Also,
variant('gain' | 'loss') only affects color while the arrow direction and leading+come fromchangeNum. If a caller ever passesvariant='gain'|'loss'with a contradictory or missing numeric change, the visuals could diverge from the intent; consider either deriving the icon/sign fromvariantin those cases or documenting thatvariantis purely cosmetic.Also applies to: 99-107
apps/agentic-server/src/tools/getNewCoins.ts (1)
17-30: Consider handling edge cases informatTimeAgo.The function assumes positive time differences. If
activated_atis in the future (data anomaly) or very old (months/years), the output may be misleading.Consider adding handling for edge cases:
function formatTimeAgo(timestamp: number): string { const now = Date.now() const diffMs = now - timestamp * 1000 + + if (diffMs < 0) return 'Just now' // Future timestamp edge case + const diffHours = Math.floor(diffMs / (1000 * 60 * 60)) const diffDays = Math.floor(diffHours / 24) if (diffDays > 0) { return `${diffDays} day${diffDays === 1 ? '' : 's'} ago` } if (diffHours > 0) { return `${diffHours} hour${diffHours === 1 ? '' : 's'} ago` } return 'Just now' }apps/agentic-server/src/routes/chat.ts (1)
36-46: Type signature could be simplified.The generic constraint uses
execute: (args: never) => unknownwhich is unconventional. While theas Tcast makes it work, this loses compile-time safety for the wrapped execute call.Consider a cleaner signature:
-function wrapToolWithLogging< - T extends { description: string; inputSchema: unknown; execute: (args: never) => unknown }, ->(name: string, tool: T): T { +function wrapToolWithLogging<TArgs, TReturn>( + name: string, + tool: { description: string; inputSchema: unknown; execute: (args: TArgs) => TReturn } +): typeof tool { return { ...tool, - execute: (args: Parameters<T['execute']>[0]) => { + execute: (args: TArgs) => { console.log(`[Tool] ${name}:`, JSON.stringify(args, null, 2)) return tool.execute(args) }, - } as T + } }apps/agentic-server/src/tools/getAssets.ts (1)
89-113: Potential mismatch betweenassetIdsandstaticAssets.Line 99 calls
getSimplePrices(assetIds)with the original input, butstaticAssets(lines 93-96) may have filtered out invalid assets. IfassetService.getAsset(id)returnsundefinedfor some IDs, the price fetching will include IDs that won't appear in the final output.This isn't a bug per se (extra prices are just ignored), but it's slightly inefficient.
Consider using the filtered asset IDs for price fetching:
const staticAssets = assetIds .map(id => assetService.getAsset(id)) .filter((a): a is NonNullable<typeof a> => a !== undefined) if (staticAssets.length === 0) return { assets: [] } - const prices = await getSimplePrices(assetIds) + const prices = await getSimplePrices(staticAssets.map(a => a.assetId))
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (24)
apps/agentic-chat/src/components/toolUIRegistry.tsx(2 hunks)apps/agentic-chat/src/components/tools/NewCoinsUI.tsx(1 hunks)apps/agentic-chat/src/components/tools/TopGainersLosersUI.tsx(1 hunks)apps/agentic-chat/src/components/tools/TrendingTokensUI.tsx(1 hunks)apps/agentic-chat/src/components/ui/AssetListItem.tsx(1 hunks)apps/agentic-server/src/context.ts(1 hunks)apps/agentic-server/src/index.ts(1 hunks)apps/agentic-server/src/lib/asset/coingecko/api.ts(2 hunks)apps/agentic-server/src/lib/asset/coingecko/index.ts(1 hunks)apps/agentic-server/src/lib/asset/coingecko/types.ts(1 hunks)apps/agentic-server/src/routes/chat.ts(6 hunks)apps/agentic-server/src/tools/getAssets.ts(2 hunks)apps/agentic-server/src/tools/getCategories.ts(1 hunks)apps/agentic-server/src/tools/getNewCoins.ts(1 hunks)apps/agentic-server/src/tools/getShapeShiftKnowledge.ts(1 hunks)apps/agentic-server/src/tools/getTopGainersLosers.ts(1 hunks)apps/agentic-server/src/tools/getTrendingPools.ts(1 hunks)apps/agentic-server/src/tools/getTrendingTokens.ts(1 hunks)apps/agentic-server/src/tools/initiateSwap.ts(4 hunks)apps/agentic-server/src/tools/portfolio.ts(4 hunks)apps/agentic-server/src/tools/receive.ts(1 hunks)apps/agentic-server/src/tools/send.ts(1 hunks)apps/agentic-server/src/tools/transactionHistory.ts(1 hunks)apps/agentic-server/src/utils/assetHelpers.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (9)
- apps/agentic-server/src/tools/initiateSwap.ts
- apps/agentic-chat/src/components/tools/TrendingTokensUI.tsx
- apps/agentic-server/src/tools/getCategories.ts
- apps/agentic-chat/src/components/tools/NewCoinsUI.tsx
- apps/agentic-server/src/tools/receive.ts
- apps/agentic-server/src/tools/transactionHistory.ts
- apps/agentic-server/src/tools/getShapeShiftKnowledge.ts
- apps/agentic-chat/src/components/toolUIRegistry.tsx
- apps/agentic-server/src/index.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-22T20:32:10.539Z
Learnt from: kaladinlight
Repo: shapeshift/agentic-chat PR: 76
File: apps/agentic-server/src/mastra/tools/asset/coingecko/constants.ts:1-10
Timestamp: 2025-09-22T20:32:10.539Z
Learning: When cross-app dependencies are identified (like server code importing from chat packages), the user prefers to extract shared constants into dedicated packages in the packages/ directory following the existing pattern of shapeshiftoss/types and shapeshiftoss/utils.
Applied to files:
apps/agentic-server/src/routes/chat.ts
🧬 Code graph analysis (8)
apps/agentic-server/src/tools/getTrendingPools.ts (2)
apps/agentic-server/src/lib/asset/coingecko/types.ts (3)
TrimmedTrendingPool(214-225)TrendingPoolIncluded(148-159)TrendingPoolData(105-146)apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
getTrendingPools(134-142)
apps/agentic-server/src/tools/getTrendingTokens.ts (3)
apps/agentic-server/src/lib/asset/coingecko/types.ts (2)
TrimmedTrendingCoin(192-200)TrendingCoinItem(37-60)apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
getTrendingSearch(107-110)packages/caip/src/adapters/coingecko/index.ts (1)
coingeckoToAssetIds(57-57)
apps/agentic-server/src/tools/getNewCoins.ts (3)
apps/agentic-server/src/lib/asset/coingecko/types.ts (2)
TrimmedNewCoin(236-243)NewCoinData(182-187)apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
getNewCoins(165-168)packages/caip/src/adapters/coingecko/index.ts (1)
coingeckoToAssetIds(57-57)
apps/agentic-chat/src/components/ui/AssetListItem.tsx (5)
packages/caip/src/constants.ts (1)
AssetId(176-176)apps/agentic-chat/src/lib/utils.ts (1)
cn(5-7)apps/agentic-chat/src/lib/bignumber.ts (1)
bnOrZero(5-13)apps/agentic-chat/src/components/ui/AssetIcon.tsx (1)
AssetIcon(12-47)apps/agentic-chat/src/lib/number.ts (2)
formatFiat(70-82)formatPercent(98-117)
apps/agentic-server/src/utils/assetHelpers.ts (4)
apps/agentic-server/src/lib/schemas/swapSchemas.ts (1)
AssetInput(76-76)packages/types/src/asset.ts (1)
Asset(28-28)apps/agentic-server/src/index.ts (1)
executeGetAssets(5-5)apps/agentic-server/src/tools/getAssets.ts (1)
executeGetAssets(115-129)
apps/agentic-server/src/routes/chat.ts (7)
apps/agentic-server/src/tools/getAssets.ts (1)
getAssetsTool(131-146)apps/agentic-server/src/tools/getShapeShiftKnowledge.ts (1)
getShapeShiftKnowledgeTool(60-64)apps/agentic-server/src/tools/getTrendingTokens.ts (1)
getTrendingTokensTool(39-54)apps/agentic-server/src/tools/getTopGainersLosers.ts (1)
getTopGainersLosersTool(53-68)apps/agentic-server/src/tools/getTrendingPools.ts (1)
getTrendingPoolsTool(77-81)apps/agentic-server/src/tools/getCategories.ts (1)
getCategoriesTool(42-46)apps/agentic-server/src/tools/getNewCoins.ts (1)
getNewCoinsTool(53-68)
apps/agentic-server/src/tools/getTopGainersLosers.ts (5)
apps/agentic-server/src/index.ts (4)
GetTopGainersLosersInput(75-75)GetTopGainersLosersOutput(76-76)TrimmedGainerLoserCoin(93-93)executeGetTopGainersLosers(74-74)apps/agentic-server/src/lib/asset/coingecko/types.ts (1)
TrimmedGainerLoserCoin(202-212)apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
getTopGainersLosers(116-128)apps/agentic-server/src/lib/asset/coingecko/index.ts (1)
getTopGainersLosers(5-5)packages/caip/src/adapters/coingecko/index.ts (1)
coingeckoToAssetIds(57-57)
apps/agentic-server/src/lib/asset/coingecko/types.ts (2)
apps/agentic-server/src/lib/asset/coingecko/index.ts (10)
TrendingCoinItem(20-20)TrendingSearchResponse(13-13)TopGainersLosersResponse(14-14)TrendingPoolData(21-21)TrendingPoolIncluded(22-22)TrendingPoolsResponse(15-15)CategoryData(18-18)CategoriesResponse(16-16)NewCoinData(19-19)NewCoinsResponse(17-17)apps/agentic-server/src/index.ts (5)
TrimmedTrendingCoin(92-92)TrimmedGainerLoserCoin(93-93)TrimmedTrendingPool(94-94)TrimmedCategory(95-95)TrimmedNewCoin(96-96)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: main
🔇 Additional comments (31)
apps/agentic-server/src/tools/send.ts (1)
121-132: LGTM! Clear UX guidance for the AI agent.The expanded description provides excellent context for the AI agent:
- Clarifies what the UI card already displays
- Establishes the "supplement, not duplicate" principle
- Offers natural, concise response examples
- Sets clear expectations for when to elaborate
This aligns with the broader PR pattern of UI-focused tool descriptions.
apps/agentic-server/src/utils/assetHelpers.ts (1)
5-11: Switch toexecuteGetAssetspreservesresolveAssetbehaviorUsing
executeGetAssets({ searchTerm, network })keeps the zero/one/many‑asset handling intact while routing through the unified asset lookup, so this refactor looks safe and consistent with the new API surface.apps/agentic-server/src/tools/portfolio.ts (1)
11-12: Portfolio integration withexecuteGetAssetsand priceChange handling looks solidFetching assets via
executeGetAssets({ assetIds })correctly delegates to the bulk pricing path, and mappingpriceChange24h: asset.priceChange24h ?? undefinedaligns with the optional number type instead of leakingnull. The updatedportfolioTooldescription also matches the new UI‑card convention.Also applies to: 78-79, 98-106, 153-167
apps/agentic-chat/src/components/tools/TopGainersLosersUI.tsx (1)
11-51: TopGainersLosersUI wiring matches server types and tool UI patternsThe component cleanly reuses
useToolStateRender, safely bails when there’s no data, and renders gainers/losers viaAssetListItemwith the expected{ gainers, losers, duration }shape from the server; this is consistent with the other tool UIs and looks good.Also applies to: 53-88
apps/agentic-server/src/lib/asset/coingecko/index.ts (1)
1-23: Barrel export cleanly centralizes CoinGecko APIs and typesThis index module neatly re‑exports the CoinGecko functions and their value/response types, simplifying imports elsewhere without changing behavior.
apps/agentic-server/src/tools/getTrendingPools.ts (1)
6-19: Trending pools tool mapping and fallbacks look robustThe schema/defaults, included‑resource maps, and pool mapper all line up with
TrimmedTrendingPool, and the fallbacks for missing tokens/dex/network/metrics ('Unknown','Unknown DEX','unknown',null) make this resilient to partial API responses. The tool wrapper is consistent with the rest of the CoinGecko tools.Also applies to: 21-75, 77-81
apps/agentic-server/src/tools/getTrendingTokens.ts (1)
7-15: Trending tokens tool is consistent and safely maps CoinGecko data
executeGetTrendingTokensenforces a sensible limit, slices the API response, and maps toTrimmedTrendingCoinwith appropriate null fallbacks and optionalassetId, matching the shared types and patterns used by the other CoinGecko-backed tools.Also applies to: 17-37, 39-54
apps/agentic-server/src/lib/asset/coingecko/api.ts (6)
5-14: LGTM!Import additions are clean and correctly typed to match the new API functions.
103-110: LGTM!Simple, well-documented endpoint wrapper following the established pattern.
116-128: LGTM!Good use of typed union literals for
durationandtopCoinsparameters with sensible defaults.
134-142: LGTM!Properly includes related entities (
base_token,quote_token,dex,network) for enriched pool data.
148-159: LGTM!The order parameter type properly enumerates all valid CoinGecko sort options.
165-168: LGTM!Simple endpoint wrapper consistent with the other functions.
apps/agentic-server/src/tools/getNewCoins.ts (4)
1-5: LGTM!Imports are appropriate for the tool's functionality.
7-9: LGTM!Schema properly defines optional limit with reasonable bounds (1-20) and self-documenting description.
32-51: LGTM!The execution logic is clean - fetches data, slices to limit, and maps to trimmed format. The
assetId: assetIds[0]correctly handles the case where no mapping exists (will beundefined).
53-67: LGTM!Tool description follows the established pattern with clear UI card guidance and natural response examples.
apps/agentic-server/src/routes/chat.ts (4)
21-26: LGTM!New tool imports are correctly added and alphabetically ordered.
79-81: LGTM!Good refactoring - simple tools that don't need walletContext now use the unified logging wrapper.
144-149: LGTM!All five new informational tools are properly registered with consistent logging wrappers.
194-199: LGTM!Good addition to the system prompt - categorizing tools helps the LLM select the appropriate tool for user queries.
apps/agentic-server/src/tools/getAssets.ts (5)
32-34: LGTM!Simplified output type consolidates previous basic and market data variants.
36-60: LGTM!Good rename to
enrichWithMarketDatawhich better describes the function's purpose. Error handling returnsnullallowing callers to fallback gracefully.
62-87: LGTM!Clean single-asset flow with proper fallback when CoinGecko enrichment fails.
115-129: LGTM!Clear routing logic: single asset (by search or single ID) goes to detailed fetch, multiple IDs go to bulk pricing.
131-146: LGTM!Tool description follows the established pattern with clear UI card guidance.
apps/agentic-server/src/lib/asset/coingecko/types.ts (5)
36-74: LGTM!Well-structured types matching the CoinGecko trending search API response. The nested
dataobject with optional fields properly handles the variable response shape.
76-95: LGTM!Clean type definition for gainers/losers with appropriate optional fields for different time periods.
97-164: LGTM!Comprehensive pool types capturing the nested structure of the onchain API response, including relationships and included entities.
166-189: LGTM!Categories and new coins types are straightforward and match the API response shapes.
191-243: LGTM!Trimmed types effectively reduce payload size for LLM context while preserving essential fields. Good design decision to include
assetIdas optional for UI linking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
apps/agentic-server/src/tools/getTopGainersLosers.ts (1)
23-51: Align supported durations with exposed price-change fields and de-duplicate loggingTwo small gaps here:
The schema and API both support
'14d'and'30d', and the response type includesusd_14d_change/usd_30d_change, butTrimmedGainerLoserCoin+mapCoinonly expose 1h/24h/7d changes. Either:
- Extend
TrimmedGainerLoserCoinandmapCointo surface 14d/30d changes as optional fields, or- Restrict
durationto the intervals you actually expose (e.g.,'1h' | '24h' | '7d').
executeGetTopGainersLoserslogs its input, and inroutes/chat.tsthis tool is also wrapped withwrapToolWithLogging, so each call will be logged twice. Similar togetNewCoins, consider removing the localconsole.logand relying on the wrapper for logging.
🧹 Nitpick comments (10)
apps/agentic-server/src/tools/receive.ts (1)
34-45: Updated receiveTool description is clear and matches the card-centric UXThe new description does a good job of:
- Making the card the primary surface (address + QR) and clearly stating the tool should supplement, not duplicate.
- Steering the model toward short, natural confirmations by default and only elaborating when asked.
One small optional refinement: the hard “Do not repeat the address” rule might be too strict for edge cases (e.g., explicit user request, accessibility/screen readers). You could soften it to something like “Avoid re-printing the full address unless the user explicitly asks for it.”
apps/agentic-server/src/tools/getCategories.ts (1)
21-40: Clean implementation with proper defaults and null-safe mapping.The executor correctly:
- Applies sensible defaults for
sortByandlimit- Constructs the API order parameter appropriately
- Maps the response with null-safe handling using
??The
console.logon line 22 is acceptable for debugging, but consider using a structured logger for consistency with production logging practices if one exists in the codebase.apps/agentic-server/src/tools/getNewCoins.ts (2)
17-30: Time-ago helper works but treats future timestamps as “Just now”If
activated_atis ever slightly in the future (clock skew, delayed ingestion),diffMsbecomes negative and you still return'Just now'. Consider clampingdiffMsat 0 or explicitly handling future values (e.g.,'in X hours'or'0 hours ago') if that matters for the UI.
32-51: Avoid duplicate logging now that tools are wrapped in chat.ts
executeGetNewCoinslogs its input, and inapps/agentic-server/src/routes/chat.tsthis tool is also passed throughwrapToolWithLogging, so each call will be logged twice. Consider dropping the localconsole.logand relying on the shared wrapper for consistent, centralized logging.apps/agentic-server/src/tools/getTopGainersLosers.ts (1)
7-21: Consider narrowing the output duration type for better safety
GetTopGainersLosersOutput.durationis typed asstringeven though the schema only permits'1h' | '24h' | '7d' | '14d' | '30d'. Narrowing this to the same union would give better type safety to consumers without changing runtime behavior.apps/agentic-server/src/routes/chat.ts (2)
77-81: Central logging is good; consider cleaning up per-tool console.log callsUsing
wrapToolWithLoggingfor mathCalculator, getAssets, account, switchNetwork, and the new market-data tools gives you a nice, consistent logging story. Some of those tool executors (e.g.,executeGetNewCoins,executeGetTopGainersLosers) also perform their ownconsole.log, which will now double-log arguments.Suggested follow-up: standardize on router-level logging via
wrapToolWithLoggingand strip redundant logging from the tool modules themselves.Also applies to: 127-149
36-46: The type constraint is awkward but currently safe; the concern about argument loss is theoreticalAll tools in the codebase follow a single-parameter
executesignature (e.g.,execute: (input: SomeInput) => Promise<Output>). The current constraint correctly enforces this pattern for all 11 wrapped tools. The use ofneverin the type is semantically confusing, but it doesn't cause practical issues today since no multi-argument tools exist. The suggested refactor using(...args: any[]) => unknownis defensive programming—it would prevent accidental argument loss if a multi-argument tool were added—but it's not addressing a current problem. This is worth considering for future extensibility, though the current approach is type-safe as written.apps/agentic-server/src/tools/portfolio.ts (1)
75-106: executeGetAssets integration and priceChange24h threading look good; consider passing network explicitlyRouting
assetIdsthroughexecuteGetAssetscleanly reuses the bulk pricing path, and mappingpriceChange24h: asset.priceChange24h ?? undefinedkeeps the portfolio type aligned with the new optional market-data field while allowing JSON serialization to drop missing values.If you want to make the network semantics more explicit (and avoid relying on
chainIdToNetworkinference ingetBulkAssetPrices), you could also passnetworkintoexecuteGetAssets({ assetIds, network }); behavior should be equivalent today but slightly clearer.apps/agentic-server/src/tools/getAssets.ts (2)
89-113: TightengetBulkAssetPricesto price only known assets and optionally fail open on pricing errorsThe bulk path is straightforward, but there are two small improvements you might consider:
You currently call
getSimplePrices(assetIds)even for IDs whereassetService.getAssetreturnedundefined. Passing only the resolved IDs would avoid unnecessary downstream lookups and keep behavior aligned with the assets you actually return:const prices = await getSimplePrices(assetIds)
const priceMap = new Map(prices.map(p => [p.assetId, { price: p.price, priceChange24h: p.priceChange24h }]))
- const pricedAssetIds = staticAssets.map(a => a.assetId)
- const prices = await getSimplePrices(pricedAssetIds)
- const priceMap = new Map(
- prices.map(p => [p.assetId, { price: p.price, priceChange24h: p.priceChange24h }]),
- )
- Unlike the single-asset path (which catches enrichment failures), any exception from `getSimplePrices` will currently bubble up and fail the entire tool. If you want similar resilience for bulk requests, you could wrap this call in a `try/catch` and fall back to returning `staticAssets` with `price: '0'` and inferred `network`. --- `115-128`: **executeGetAssets routing is clear; consider toning down logging if traffic is high** The routing logic (searchTerm/single asset → `getAssetWithMarketData`, multi-asset → `getBulkAssetPrices`, else empty) is easy to follow and matches the intended API. If this tool ends up on a hot path, you may eventually want to downgrade `console.log('[getAssets]:', input)` to a debug-level logger or gate it by environment to avoid noisy logs, but it’s fine for initial rollout. </blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used**: CodeRabbit UI **Review profile**: CHILL **Plan**: Pro **Disabled knowledge base sources:** - Linear integration is disabled by default for public repositories > You can enable these sources in your CodeRabbit configuration. <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 2b594463552c3b4c427c04833ac743c6ad88313a and ea292abc50ea97fb6f57dc98e08db17c85cb486e. </details> <details> <summary>📒 Files selected for processing (24)</summary> * `apps/agentic-chat/src/components/toolUIRegistry.tsx` (2 hunks) * `apps/agentic-chat/src/components/tools/NewCoinsUI.tsx` (1 hunks) * `apps/agentic-chat/src/components/tools/TopGainersLosersUI.tsx` (1 hunks) * `apps/agentic-chat/src/components/tools/TrendingTokensUI.tsx` (1 hunks) * `apps/agentic-chat/src/components/ui/AssetListItem.tsx` (1 hunks) * `apps/agentic-server/src/context.ts` (1 hunks) * `apps/agentic-server/src/index.ts` (1 hunks) * `apps/agentic-server/src/lib/asset/coingecko/api.ts` (2 hunks) * `apps/agentic-server/src/lib/asset/coingecko/index.ts` (1 hunks) * `apps/agentic-server/src/lib/asset/coingecko/types.ts` (1 hunks) * `apps/agentic-server/src/routes/chat.ts` (6 hunks) * `apps/agentic-server/src/tools/getAssets.ts` (2 hunks) * `apps/agentic-server/src/tools/getCategories.ts` (1 hunks) * `apps/agentic-server/src/tools/getNewCoins.ts` (1 hunks) * `apps/agentic-server/src/tools/getShapeShiftKnowledge.ts` (1 hunks) * `apps/agentic-server/src/tools/getTopGainersLosers.ts` (1 hunks) * `apps/agentic-server/src/tools/getTrendingPools.ts` (1 hunks) * `apps/agentic-server/src/tools/getTrendingTokens.ts` (1 hunks) * `apps/agentic-server/src/tools/initiateSwap.ts` (4 hunks) * `apps/agentic-server/src/tools/portfolio.ts` (4 hunks) * `apps/agentic-server/src/tools/receive.ts` (1 hunks) * `apps/agentic-server/src/tools/send.ts` (1 hunks) * `apps/agentic-server/src/tools/transactionHistory.ts` (1 hunks) * `apps/agentic-server/src/utils/assetHelpers.ts` (1 hunks) </details> <details> <summary>🚧 Files skipped from review as they are similar to previous changes (12)</summary> * apps/agentic-server/src/tools/initiateSwap.ts * apps/agentic-server/src/tools/getTrendingTokens.ts * apps/agentic-chat/src/components/tools/TopGainersLosersUI.tsx * apps/agentic-server/src/utils/assetHelpers.ts * apps/agentic-server/src/context.ts * apps/agentic-server/src/lib/asset/coingecko/index.ts * apps/agentic-server/src/tools/send.ts * apps/agentic-server/src/tools/getTrendingPools.ts * apps/agentic-server/src/index.ts * apps/agentic-server/src/tools/transactionHistory.ts * apps/agentic-chat/src/components/toolUIRegistry.tsx * apps/agentic-server/src/lib/asset/coingecko/types.ts </details> <details> <summary>🧰 Additional context used</summary> <details> <summary>🧠 Learnings (1)</summary> <details> <summary>📚 Learning: 2025-09-22T20:32:10.539Z</summary>Learnt from: kaladinlight
Repo: shapeshift/agentic-chat PR: 76
File: apps/agentic-server/src/mastra/tools/asset/coingecko/constants.ts:1-10
Timestamp: 2025-09-22T20:32:10.539Z
Learning: When cross-app dependencies are identified (like server code importing from chat packages), the user prefers to extract shared constants into dedicated packages in the packages/ directory following the existing pattern of shapeshiftoss/types and shapeshiftoss/utils.**Applied to files:** - `apps/agentic-server/src/routes/chat.ts` </details> </details><details> <summary>🧬 Code graph analysis (5)</summary> <details> <summary>apps/agentic-chat/src/components/tools/TrendingTokensUI.tsx (4)</summary><blockquote> <details> <summary>apps/agentic-chat/src/components/tools/toolUIHelpers.tsx (2)</summary> * `ToolUIComponentProps` (6-8) * `useToolStateRender` (10-31) </details> <details> <summary>apps/agentic-server/src/lib/asset/coingecko/types.ts (1)</summary> * `TrimmedTrendingCoin` (192-200) </details> <details> <summary>apps/agentic-chat/src/components/ui/ToolCard.tsx (1)</summary> * `ToolCard` (71-78) </details> <details> <summary>apps/agentic-chat/src/components/ui/AssetListItem.tsx (1)</summary> * `AssetListItem` (60-110) </details> </blockquote></details> <details> <summary>apps/agentic-server/src/tools/portfolio.ts (3)</summary><blockquote> <details> <summary>apps/agentic-server/src/index.ts (1)</summary> * `executeGetAssets` (5-5) </details> <details> <summary>apps/agentic-server/src/tools/getAssets.ts (1)</summary> * `executeGetAssets` (115-129) </details> <details> <summary>packages/types/src/asset.ts (1)</summary> * `asset` (3-26) </details> </blockquote></details> <details> <summary>apps/agentic-server/src/tools/getNewCoins.ts (3)</summary><blockquote> <details> <summary>apps/agentic-server/src/lib/asset/coingecko/types.ts (2)</summary> * `TrimmedNewCoin` (236-243) * `NewCoinData` (182-187) </details> <details> <summary>apps/agentic-server/src/lib/asset/coingecko/api.ts (1)</summary> * `getNewCoins` (165-168) </details> <details> <summary>packages/caip/src/adapters/coingecko/index.ts (1)</summary> * `coingeckoToAssetIds` (57-57) </details> </blockquote></details> <details> <summary>apps/agentic-server/src/lib/asset/coingecko/api.ts (2)</summary><blockquote> <details> <summary>apps/agentic-server/src/lib/asset/coingecko/index.ts (10)</summary> * `getTrendingSearch` (4-4) * `TrendingSearchResponse` (13-13) * `getTopGainersLosers` (5-5) * `TopGainersLosersResponse` (14-14) * `getTrendingPools` (6-6) * `TrendingPoolsResponse` (15-15) * `getCategories` (7-7) * `CategoriesResponse` (16-16) * `getNewCoins` (8-8) * `NewCoinsResponse` (17-17) </details> <details> <summary>apps/agentic-server/src/lib/asset/coingecko/types.ts (5)</summary> * `TrendingSearchResponse` (62-74) * `TopGainersLosersResponse` (92-95) * `TrendingPoolsResponse` (161-164) * `CategoriesResponse` (179-179) * `NewCoinsResponse` (189-189) </details> </blockquote></details> <details> <summary>apps/agentic-server/src/routes/chat.ts (7)</summary><blockquote> <details> <summary>apps/agentic-server/src/tools/getAssets.ts (1)</summary> * `getAssetsTool` (131-146) </details> <details> <summary>apps/agentic-server/src/tools/getShapeShiftKnowledge.ts (1)</summary> * `getShapeShiftKnowledgeTool` (60-64) </details> <details> <summary>apps/agentic-server/src/tools/getTrendingTokens.ts (1)</summary> * `getTrendingTokensTool` (39-54) </details> <details> <summary>apps/agentic-server/src/tools/getTopGainersLosers.ts (1)</summary> * `getTopGainersLosersTool` (53-68) </details> <details> <summary>apps/agentic-server/src/tools/getTrendingPools.ts (1)</summary> * `getTrendingPoolsTool` (77-81) </details> <details> <summary>apps/agentic-server/src/tools/getCategories.ts (1)</summary> * `getCategoriesTool` (42-46) </details> <details> <summary>apps/agentic-server/src/tools/getNewCoins.ts (1)</summary> * `getNewCoinsTool` (53-68) </details> </blockquote></details> </details> </details> <details> <summary>🔇 Additional comments (15)</summary><blockquote> <details> <summary>apps/agentic-server/src/tools/getShapeShiftKnowledge.ts (1)</summary><blockquote> `60-64`: **LGTM!** The updated description is more concise and aligns with the consistent pattern used across the new tools in this PR. </blockquote></details> <details> <summary>apps/agentic-chat/src/components/tools/TrendingTokensUI.tsx (1)</summary><blockquote> `10-55`: **Well-structured component following established patterns.** The implementation correctly uses `useToolStateRender` for state management and `AssetListItem` for consistent rendering. The 1-based ranking display is appropriate. One consideration: returning `null` for empty tokens (lines 23-25) means the UI silently disappears. If this is intentional for cleaner UX, it's fine. Otherwise, consider showing an empty state message like "No trending tokens found." </blockquote></details> <details> <summary>apps/agentic-chat/src/components/tools/NewCoinsUI.tsx (1)</summary><blockquote> `10-55`: **LGTM!** The component follows the established pattern from `TrendingTokensUI` with appropriate differentiation (Sparkles icon, purple color, "Listed" subtitle). The implementation is consistent and well-structured. </blockquote></details> <details> <summary>apps/agentic-chat/src/components/ui/AssetListItem.tsx (2)</summary><blockquote> `30-58`: **Well-implemented fallback handling for icons.** The `FallbackIcon` and `IconFromUrl` subcomponents provide good fallback behavior. The `onError` handler in `IconFromUrl` gracefully degrades to the initials-based fallback. Minor observation: The `!url` check on line 46 is defensive since the parent already gates `IconFromUrl` rendering on `iconUrl` being truthy (line 86), but this extra safety is harmless. --- `60-109`: **LGTM!** The component is well-designed with: - Clear icon rendering priority (assetId → iconUrl → fallback) - Appropriate memoization for BigNumber conversion - Flexible variant system for gain/loss styling - Clean conditional rendering for optional price/change display This reusable component will serve the multiple tool UIs well. </blockquote></details> <details> <summary>apps/agentic-server/src/tools/getCategories.ts (1)</summary><blockquote> `42-46`: **LGTM!** The tool export follows the established pattern with a clear description indicating no UI card, consistent with other tools in this PR. </blockquote></details> <details> <summary>apps/agentic-server/src/tools/getNewCoins.ts (1)</summary><blockquote> `53-68`: **Tool contract is clear and aligned with the “supplement the card” pattern** The description, schema, and trimmed output shape match the informational-card usage pattern from the other tools; nothing blocking here. </blockquote></details> <details> <summary>apps/agentic-server/src/lib/asset/coingecko/api.ts (1)</summary><blockquote> `103-168`: **New market-data wrapper functions look consistent and type-safe** Each helper cleanly wraps a single endpoint with specific param unions and returns the matching response type, consistent with `./types`. Centralizing these calls behind the shared client and small wrappers looks good. </blockquote></details> <details> <summary>apps/agentic-server/src/tools/getTopGainersLosers.ts (1)</summary><blockquote> `53-68`: **Tool description and schema/output wiring look solid** Description text, schema, executor, and exported tool object are coherent and follow the same “informational card” pattern as the other tools; no blockers here. </blockquote></details> <details> <summary>apps/agentic-server/src/routes/chat.ts (1)</summary><blockquote> `194-199`: **System prompt updates correctly reflect new tool surface** The new **Tool Categories** section clearly lists the added informational tools (trending tokens, gainers/losers, new coins, categories, pools) and keeps behavior guidance consistent with the rest of the prompt. Looks good. </blockquote></details> <details> <summary>apps/agentic-server/src/tools/portfolio.ts (2)</summary><blockquote> `11-11`: **Switch to unified `executeGetAssets` entrypoint looks correct** Using `executeGetAssets` here keeps the portfolio tool on the new consolidated API surface and avoids the deprecated basic variant; no further wiring changes are needed in this file. --- `154-165`: **Updated `portfolioTool` description matches the new UI-card pattern** The card-focused description and examples clearly instruct the model not to echo portfolio data and to respond tersely by default, which is consistent with the new informational tools and should help keep responses clean. </blockquote></details> <details> <summary>apps/agentic-server/src/tools/getAssets.ts (3)</summary><blockquote> `32-55`: **Market-data enrichment mapping is solid; just confirm how `description` is rendered** The `AssetWithMarketData` shape and field mapping from CoinGecko (`price`, caps, volumes, supplies, sentiment, rank) look consistent and defensively handle missing data with `null`/`'0'` fallbacks. One thing to double-check: `data.description?.en` often contains HTML from CoinGecko. If any UI renders this as HTML instead of plain text, ensure it’s properly sanitized/escaped to avoid XSS issues. --- `62-87`: **Single-asset flow and fallback behavior look correct** The single-asset path (search term or one assetId) cleanly: - Resolves a base asset. - Infers a network (falling back to `'ethereum'`). - Attempts CoinGecko enrichment and falls back to the static asset with `price: '0'` if anything fails. This is a reasonable balance between enriching results and staying resilient when market data isn’t available. --- `132-146`: **Updated `getAssetsTool` description and executor wiring look good** The new description clearly communicates the UI-card behavior and keeps responses terse by default, and wiring `execute` to `executeGetAssets` matches the new unified API surface. </blockquote></details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
ea292ab to
810111f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (2)
apps/agentic-server/src/tools/getTopGainersLosers.ts (1)
31-44: Missing priceChange14d and priceChange30d fields in the mapper.The schema accepts
'14d'and'30d'durations, and the API returnsusd_14d_changeandusd_30d_changefields inGainerLoserCoin, but the mapper only populatespriceChange1h,priceChange24h, andpriceChange7d. Users requesting 14d/30d data won't see the corresponding price changes.Either add the missing fields to the mapper and type:
const mapCoin = (coin: (typeof data.top_gainers)[0]): TrimmedGainerLoserCoin => { const assetIds = coingeckoToAssetIds(coin.id) return { id: coin.id, name: coin.name, symbol: coin.symbol, price: coin.usd, priceChange24h: coin.usd_24h_change, priceChange1h: coin.usd_1h_change, priceChange7d: coin.usd_7d_change, + priceChange14d: coin.usd_14d_change, + priceChange30d: coin.usd_30d_change, marketCapRank: coin.market_cap_rank, assetId: assetIds[0], } }Or narrow the allowed
durationvalues to'1h' | '24h' | '7d'if you don't intend to expose longer periods.apps/agentic-server/src/lib/asset/coingecko/types.ts (1)
202-212: Add missingpriceChange14dandpriceChange30dfields.
GainerLoserCoinincludesusd_14d_changeandusd_30d_change(lines 88-89), butTrimmedGainerLoserCoinonly has fields up to 7d. This should be updated to support the full range of durations allowed by the tool schema.export type TrimmedGainerLoserCoin = { id: string name: string symbol: string price: number priceChange24h: number priceChange1h?: number priceChange7d?: number + priceChange14d?: number + priceChange30d?: number marketCapRank: number | null assetId?: string }
🧹 Nitpick comments (7)
apps/agentic-chat/src/components/tools/TrendingTokensUI.tsx (1)
10-55: Tighten output typing and consider an explicit empty-stateThe UI flow looks solid. Two small refinements you might consider:
- Instead of casting
output as { tokens: TrimmedTrendingCoin[] }, import and use the concrete tool output type from the server package so type drift is caught at compile time.- When
tokensis empty you currently returnnull, which means the whole card disappears; if this tool is user-invoked, a short “No trending tokens found” message might be a nicer UX than rendering nothing.apps/agentic-server/src/tools/initiateSwap.ts (1)
323-341: Avoid double-resolvingsellAssetin the USD swap pathIn
executeInitiateSwapUsdyou resolvesellAsset(including a price lookup viaresolveAsset→getAssetPrices) to computesellAmountCrypto, and thenexecuteSwapInternalresolves both assets again viaresolveSwapAssets, which triggers another price lookup for the same sell asset.This is functionally correct, but:
- It adds an extra asset/price lookup on every USD swap.
- It can introduce slight drift between the price used to derive
sellAmountCryptoand the price used later for USD summaries.If you want to tighten this up, consider passing pre-resolved assets into
executeSwapInternal(or extracting a shared helper that both paths can use) so the USD-path only resolves/prices the sell asset once.apps/agentic-chat/src/components/ui/AssetListItem.tsx (1)
11-110: Well-structured list item; minor nits around change handlingThis component is nicely factored (icon fallback, URL loader, main row). Two small, non-blocking nits:
changeNumis computed on every render even whenpriceChange24hisnull/undefined; you could gatebnOrZerobehindhasChangeto skip unnecessary work for rows without change data.- With
changeNum.gte(0)you’ll show a “trending up” icon for exactly 0% moves; if you’d prefer a neutral or “no change” representation, you might special-casechangeNum.isZero().Neither is critical; just potential polish if you revisit this component.
apps/agentic-server/src/lib/asset/prices.ts (1)
12-33: Consider tightening thegetSimplePricescall to known assets and de-duping IDsFunctionally this looks good, but there are a couple of easy efficiency wins:
- You currently call
getSimplePrices(assetIds)even though you filter out unknown IDs when buildingstaticAssets. If callers ever pass bad IDs, you may be asking CoinGecko for prices you’ll never use. PassingstaticAssets.map(a => a.assetId)instead would align the remote call with the assets you actually return.- If
assetIdscan contain duplicates, a simpleSet-based dedupe before callinggetSimplePriceswould avoid redundant lookups while preserving the returned order viastaticAssets.Not blocking, but worth considering if this helper ends up on hot paths like portfolio or batch tools.
apps/agentic-server/src/tools/getTrendingPools.ts (1)
6-81: Trending pools mapping looks solid; a few small type/ergonomic tweaksThe mapping from the raw CoinGecko response into
TrimmedTrendingPoolis careful and defensive (good use of safe fallbacks for missing relationships). A few minor refinements you might consider:
limitis anumberbut not constrained to integers; if a caller passed3.5,slice(0, limit)would effectively use3. If that matters, you could normalize (e.g.,Math.floor(limit)) or validate/round before slicing.GetTrendingPoolsOutput.durationis typed asstringeven though it’s always one of'5m' | '1h' | '6h' | '24h'. Tightening that type makes downstream consumers safer.- The
console.log('[getTrendingPools]:', input)is useful during development but may get noisy in production; switching to your structured logger or removing once this endpoint is stable would keep logs cleaner.All low-priority; the core implementation looks correct.
apps/agentic-server/src/routes/chat.ts (1)
36-46: Consider improving the type signature for better type safety.The
nevertype forargsloses type information. A more precise generic signature would preserve the execute function's parameter type:-function wrapToolWithLogging< - T extends { description: string; inputSchema: unknown; execute: (args: never) => unknown }, ->(name: string, tool: T): T { +function wrapToolWithLogging<TArgs, TReturn, T extends { description: string; inputSchema: unknown; execute: (args: TArgs) => TReturn }>( + name: string, + tool: T +): T { return { ...tool, - execute: (args: Parameters<T['execute']>[0]) => { + execute: (args: TArgs) => { console.log(`[Tool] ${name}:`, JSON.stringify(args, null, 2)) return tool.execute(args) }, } as T }That said, the current implementation works correctly at runtime since TypeScript erases types anyway.
apps/agentic-server/src/tools/getAssets.ts (1)
62-87: Clarify behavior when bothsearchTermandassetIdare provided.When both parameters are supplied,
searchTermsilently takes precedence (lines 65-69). Consider either:
- Documenting this in the schema descriptions, or
- Using
assetIdwhen provided (more specific lookup) and falling back tosearchTerm- const asset = searchTerm - ? assetService.search(searchTerm, network)[0] - : assetId - ? assetService.getAsset(assetId) - : undefined + const asset = assetId + ? assetService.getAsset(assetId) + : searchTerm + ? assetService.search(searchTerm, network)[0] + : undefinedThis prioritizes the more specific
assetIdlookup over the fuzzysearchTermsearch.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (25)
apps/agentic-chat/src/components/toolUIRegistry.tsx(2 hunks)apps/agentic-chat/src/components/tools/NewCoinsUI.tsx(1 hunks)apps/agentic-chat/src/components/tools/TopGainersLosersUI.tsx(1 hunks)apps/agentic-chat/src/components/tools/TrendingTokensUI.tsx(1 hunks)apps/agentic-chat/src/components/ui/AssetListItem.tsx(1 hunks)apps/agentic-server/src/context.ts(1 hunks)apps/agentic-server/src/index.ts(1 hunks)apps/agentic-server/src/lib/asset/coingecko/api.ts(2 hunks)apps/agentic-server/src/lib/asset/coingecko/index.ts(1 hunks)apps/agentic-server/src/lib/asset/coingecko/types.ts(1 hunks)apps/agentic-server/src/lib/asset/prices.ts(1 hunks)apps/agentic-server/src/routes/chat.ts(6 hunks)apps/agentic-server/src/tools/getAssets.ts(3 hunks)apps/agentic-server/src/tools/getCategories.ts(1 hunks)apps/agentic-server/src/tools/getNewCoins.ts(1 hunks)apps/agentic-server/src/tools/getShapeShiftKnowledge.ts(1 hunks)apps/agentic-server/src/tools/getTopGainersLosers.ts(1 hunks)apps/agentic-server/src/tools/getTrendingPools.ts(1 hunks)apps/agentic-server/src/tools/getTrendingTokens.ts(1 hunks)apps/agentic-server/src/tools/initiateSwap.ts(3 hunks)apps/agentic-server/src/tools/portfolio.ts(4 hunks)apps/agentic-server/src/tools/receive.ts(1 hunks)apps/agentic-server/src/tools/send.ts(1 hunks)apps/agentic-server/src/tools/transactionHistory.ts(1 hunks)apps/agentic-server/src/utils/assetHelpers.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (12)
- apps/agentic-server/src/tools/send.ts
- apps/agentic-server/src/tools/receive.ts
- apps/agentic-server/src/tools/getTrendingTokens.ts
- apps/agentic-chat/src/components/tools/TopGainersLosersUI.tsx
- apps/agentic-server/src/tools/getShapeShiftKnowledge.ts
- apps/agentic-chat/src/components/toolUIRegistry.tsx
- apps/agentic-server/src/tools/getCategories.ts
- apps/agentic-chat/src/components/tools/NewCoinsUI.tsx
- apps/agentic-server/src/context.ts
- apps/agentic-server/src/tools/getNewCoins.ts
- apps/agentic-server/src/tools/portfolio.ts
- apps/agentic-server/src/tools/transactionHistory.ts
🧰 Additional context used
🧬 Code graph analysis (3)
apps/agentic-server/src/tools/getTrendingPools.ts (2)
apps/agentic-server/src/lib/asset/coingecko/types.ts (3)
TrimmedTrendingPool(214-225)TrendingPoolIncluded(148-159)TrendingPoolData(105-146)apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
getTrendingPools(108-116)
apps/agentic-server/src/tools/getAssets.ts (5)
packages/types/src/network.ts (2)
NETWORKS(23-42)chainIdToNetwork(84-86)packages/types/src/asset.ts (2)
asset(3-26)Asset(28-28)packages/utils/src/AssetService.ts (1)
assetService(135-135)packages/utils/src/index.ts (1)
assetService(35-35)packages/caip/src/adapters/coingecko/index.ts (1)
assetIdToCoingecko(59-59)
apps/agentic-server/src/routes/chat.ts (7)
apps/agentic-server/src/tools/getAssets.ts (1)
getAssetsTool(101-116)apps/agentic-server/src/tools/getShapeShiftKnowledge.ts (1)
getShapeShiftKnowledgeTool(60-64)apps/agentic-server/src/tools/getTrendingTokens.ts (1)
getTrendingTokensTool(39-54)apps/agentic-server/src/tools/getTopGainersLosers.ts (1)
getTopGainersLosersTool(53-68)apps/agentic-server/src/tools/getTrendingPools.ts (1)
getTrendingPoolsTool(77-81)apps/agentic-server/src/tools/getCategories.ts (1)
getCategoriesTool(42-46)apps/agentic-server/src/tools/getNewCoins.ts (1)
getNewCoinsTool(53-68)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: main
🔇 Additional comments (15)
apps/agentic-server/src/utils/assetHelpers.ts (1)
8-24: Confirm first-result selection semantics inresolveAsset
assetService.searchmay return multiple candidates but you now always takeassets[0]and treat that as the resolved asset. That’s fine ifsearchis ordered deterministically with the “best” match first, but it does change behavior vs explicit multi-match handling (e.g. ambiguous symbols across networks). It’d be good to confirm this ordering guarantee and whether you still want to surface ambiguity to the caller in any cases (like cross-chain symbols), or if “first match wins” is now the intentional contract.apps/agentic-server/src/tools/initiateSwap.ts (2)
291-303: UpdatedinitiateSwapTooldescription looks clear and card-centricThe new description tightly scopes the tool to the UI card and avoids duplicating card data in text responses. No code issues here; this should help produce more concise assistant output around swaps.
345-356:initiateSwapUsdTooldescription aligns well with the new card UXSame as the crypto-amount variant, the updated description is focused on the UI card and gives the agent clear guidance to avoid repeating data already visible to the user. Implementation looks good.
apps/agentic-server/src/lib/asset/coingecko/index.ts (1)
1-23: Expanded CoinGecko exports look consistent and completeRe-exporting the new API functions (
getTrendingSearch,getTopGainersLosers,getTrendingPools,getCategories,getNewCoins) and their response/trimmed types from this index keeps the CoinGecko integration surface centralized. Names are consistent with the underlyingapiandtypesmodules; no issues here.apps/agentic-server/src/index.ts (1)
66-97: New informational tools and trimmed types are cleanly exposed from the server rootExporting the new tools (
getTrendingTokensTool,getTopGainersLosersTool,getTrendingPoolsTool,getCategoriesTool,getNewCoinsTool) plus their execute/input/output types, alongside the trimmed CoinGecko types, makes the agentic-server package a nice single entry point for both tool wiring and UI typing (e.g.,TrendingTokensUIconsumingTrimmedTrendingCoin). Names and groupings are consistent with the rest of the file.apps/agentic-server/src/tools/getTopGainersLosers.ts (1)
53-68: LGTM!The tool description is well-structured with clear guidance for UI card integration and appropriate response behavior.
apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
89-134: LGTM!The new API functions follow the existing patterns in this file: thin wrappers around axios calls with appropriate type annotations and sensible defaults. Error handling is delegated to callers, consistent with the existing
getMarketDataandgetBulkPricesfunctions.apps/agentic-server/src/routes/chat.ts (2)
79-81: LGTM!The new tools are properly integrated with the logging wrapper. The distinction between tools using
wrapToolWithLogging(stateless tools) vs inline wrappers (tools requiringwalletContextinjection) is logical.Also applies to: 127-127, 144-149
194-199: LGTM!The new Tool Categories section in the system prompt provides clear organization of available tools, improving the LLM's ability to select appropriate tools for user requests.
apps/agentic-server/src/tools/getAssets.ts (2)
36-60: LGTM!The
enrichWithMarketDatafunction handles errors gracefully by logging and returningnull, allowing callers to fall back to unenriched data. The field mapping from CoinGecko response toAssetWithMarketDatais comprehensive.
101-116: LGTM!The tool description follows the established pattern for UI card integration, guiding the LLM to supplement rather than duplicate displayed data.
apps/agentic-server/src/lib/asset/coingecko/types.ts (4)
36-95: LGTM!The trending tokens and gainers/losers type definitions accurately model the CoinGecko API response structures with appropriate optional fields.
97-164: LGTM!The trending pools types comprehensively model the nested structure including relationships for base/quote tokens, DEX, and network data.
166-189: LGTM!Categories and new coins types are well-defined with appropriate optional fields matching the CoinGecko API responses.
191-201: LGTM!The trimmed types for TrendingCoin, TrendingPool, Category, and NewCoin provide lean payloads for LLM context while preserving essential data for UI rendering.
Also applies to: 214-243
810111f to
1e8fba8
Compare
1e8fba8 to
8120fa9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
apps/agentic-server/src/tools/getTopGainersLosers.ts (1)
31-44: Missing 14d/30d price change fields — previously flagged.The schema supports
'14d'and'30d'durations, but the mapper only populatespriceChange1h,priceChange24h, andpriceChange7d. This was already identified in a previous review.
🧹 Nitpick comments (7)
apps/agentic-chat/src/components/ui/AssetListItem.tsx (1)
43-48: Tighten TypeScript types/narrowing forassetIdandiconUrlconditionalsAt runtime the conditionals are safe, but with strict typing there’s a good chance these patterns will complain:
IconFromUrlrequiresurl: string, but it’s called as{!assetId && iconUrl && <IconFromUrl url={iconUrl} ... />}, whereiconUrlisstring | undefined.- Similarly,
AssetIconlikely expectsassetId: AssetId, but is called as{assetId && <AssetIcon assetId={assetId} ... />}whereassetIdisAssetId | undefined.Consider one of:
- Narrow before render:
const hasAssetId = !!assetId const hasIconUrl = !!iconUrl {hasAssetId && <AssetIcon assetId={assetId!} className="w-8 h-8" />} {!hasAssetId && hasIconUrl && <IconFromUrl url={iconUrl!} symbol={symbol} />}
- Or relax the child prop types to accept
string | undefinedand handle fallback inside.This keeps the nice JSX conditionals while avoiding TS complaints in strict mode.
Also applies to: 72-88, 94-105
apps/agentic-server/src/lib/asset/coingecko/types.ts (1)
36-190: Types look good; consider minor tightening forassetIdand nullable ranksThe new response and trimmed types align well with the API wrappers and intended UI usage. Two small optional refinements:
- For the trimmed types, you could reuse
AssetIdinstead ofstringforassetIdto preserve stronger typing end‑to‑end.- If CoinGecko ever omits
market_cap_rankin trending results, you may wantmarketCapRank: number | nullonTrimmedTrendingCoin(to mirrorGainerLoserCoin) to reflect that possibility.Not blocking, but would make the types a bit more future‑proof.
Also applies to: 191-243
apps/agentic-server/src/utils/assetHelpers.ts (1)
2-5:resolveAssetcorrectly unifies search, pricing, and network resolutionThe new flow (search → first match → price via
getAssetPrices→ inferred network) is coherent and handles missing price data by falling back to'0'. This should improve consistency with other price‑aware paths. There is a tiny redundancy in re‑looking up the asset insidegetAssetPrices, but that’s a micro‑optimization you can defer.Also applies to: 8-24
apps/agentic-chat/src/components/tools/TopGainersLosersUI.tsx (1)
63-71: Type assertion without runtime validation may cause subtle bugs.The type assertion on
outputassumes a specific shape. If the tool output structure changes or is malformed, accessingdata.gainersordata.loserscould fail silently or cause unexpected behavior.Consider adding a minimal runtime check or using a type guard:
const data = output as | { gainers: TrimmedGainerLoserCoin[]; losers: TrimmedGainerLoserCoin[]; duration: string } | undefined - if (!data || (data.gainers.length === 0 && data.losers.length === 0)) { + if (!data || !Array.isArray(data.gainers) || !Array.isArray(data.losers)) { + return null + } + + if (data.gainers.length === 0 && data.losers.length === 0) { return null }apps/agentic-server/src/tools/getTrendingTokens.ts (1)
17-18: Redundant logging —wrapToolWithLoggingalready logs tool calls.The
console.logstatement here duplicates the logging added bywrapToolWithLogginginchat.ts. Consider removing this line to avoid duplicate log entries.export async function executeGetTrendingTokens(input: GetTrendingTokensInput): Promise<GetTrendingTokensOutput> { - console.log('[getTrendingTokens]:', input) - const limit = input.limit ?? 5apps/agentic-server/src/tools/getTopGainersLosers.ts (1)
23-24: Redundant logging —wrapToolWithLoggingalready logs tool calls.Same as
getTrendingTokens, this console.log duplicates the logging wrapper inchat.ts.export async function executeGetTopGainersLosers(input: GetTopGainersLosersInput): Promise<GetTopGainersLosersOutput> { - console.log('[getTopGainersLosers]:', input) - const duration = input.duration ?? '24h'apps/agentic-server/src/routes/chat.ts (1)
36-46: Type constraint could be improved for better safety.The
execute: (args: never) => unknownconstraint is overly restrictive in the type definition but works at runtime due to theas Tcast. Consider a more precise generic:-function wrapToolWithLogging< - T extends { description: string; inputSchema: unknown; execute: (args: never) => unknown }, ->(name: string, tool: T): T { +function wrapToolWithLogging<TArgs, TReturn, T extends { description: string; inputSchema: unknown; execute: (args: TArgs) => TReturn }>( + name: string, + tool: T +): T { return { ...tool, - execute: (args: Parameters<T['execute']>[0]) => { + execute: (args: TArgs) => { console.log(`[Tool] ${name}:`, JSON.stringify(args, null, 2)) return tool.execute(args) }, } as T }That said, the current implementation works correctly at runtime.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (25)
apps/agentic-chat/src/components/toolUIRegistry.tsx(2 hunks)apps/agentic-chat/src/components/tools/NewCoinsUI.tsx(1 hunks)apps/agentic-chat/src/components/tools/TopGainersLosersUI.tsx(1 hunks)apps/agentic-chat/src/components/tools/TrendingTokensUI.tsx(1 hunks)apps/agentic-chat/src/components/ui/AssetListItem.tsx(1 hunks)apps/agentic-server/src/context.ts(1 hunks)apps/agentic-server/src/index.ts(1 hunks)apps/agentic-server/src/lib/asset/coingecko/api.ts(2 hunks)apps/agentic-server/src/lib/asset/coingecko/index.ts(1 hunks)apps/agentic-server/src/lib/asset/coingecko/types.ts(1 hunks)apps/agentic-server/src/lib/asset/prices.ts(1 hunks)apps/agentic-server/src/routes/chat.ts(6 hunks)apps/agentic-server/src/tools/getAssets.ts(3 hunks)apps/agentic-server/src/tools/getCategories.ts(1 hunks)apps/agentic-server/src/tools/getNewCoins.ts(1 hunks)apps/agentic-server/src/tools/getShapeShiftKnowledge.ts(1 hunks)apps/agentic-server/src/tools/getTopGainersLosers.ts(1 hunks)apps/agentic-server/src/tools/getTrendingPools.ts(1 hunks)apps/agentic-server/src/tools/getTrendingTokens.ts(1 hunks)apps/agentic-server/src/tools/initiateSwap.ts(3 hunks)apps/agentic-server/src/tools/portfolio.ts(4 hunks)apps/agentic-server/src/tools/receive.ts(1 hunks)apps/agentic-server/src/tools/send.ts(1 hunks)apps/agentic-server/src/tools/transactionHistory.ts(1 hunks)apps/agentic-server/src/utils/assetHelpers.ts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- apps/agentic-server/src/context.ts
🚧 Files skipped from review as they are similar to previous changes (9)
- apps/agentic-server/src/tools/getCategories.ts
- apps/agentic-server/src/tools/getTrendingPools.ts
- apps/agentic-chat/src/components/tools/TrendingTokensUI.tsx
- apps/agentic-chat/src/components/tools/NewCoinsUI.tsx
- apps/agentic-server/src/index.ts
- apps/agentic-server/src/lib/asset/prices.ts
- apps/agentic-server/src/tools/getNewCoins.ts
- apps/agentic-chat/src/components/toolUIRegistry.tsx
- apps/agentic-server/src/tools/receive.ts
🧰 Additional context used
🧬 Code graph analysis (6)
apps/agentic-server/src/tools/getTrendingTokens.ts (4)
apps/agentic-server/src/lib/asset/coingecko/types.ts (2)
TrimmedTrendingCoin(192-200)TrendingCoinItem(37-60)apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
getTrendingSearch(89-92)apps/agentic-server/src/lib/asset/coingecko/index.ts (2)
getTrendingSearch(4-4)TrendingCoinItem(20-20)packages/caip/src/adapters/coingecko/index.ts (1)
coingeckoToAssetIds(57-57)
apps/agentic-server/src/utils/assetHelpers.ts (4)
apps/agentic-server/src/lib/schemas/swapSchemas.ts (1)
AssetInput(76-76)packages/types/src/asset.ts (1)
Asset(28-28)apps/agentic-server/src/lib/asset/prices.ts (1)
getAssetPrices(12-33)packages/types/src/network.ts (1)
chainIdToNetwork(84-86)
apps/agentic-server/src/tools/initiateSwap.ts (1)
apps/agentic-server/src/utils/assetHelpers.ts (1)
resolveAsset(8-25)
apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
apps/agentic-server/src/lib/asset/coingecko/types.ts (5)
TrendingSearchResponse(62-74)TopGainersLosersResponse(92-95)TrendingPoolsResponse(161-164)CategoriesResponse(179-179)NewCoinsResponse(189-189)
apps/agentic-server/src/lib/asset/coingecko/types.ts (2)
apps/agentic-server/src/lib/asset/coingecko/index.ts (10)
TrendingCoinItem(20-20)TrendingSearchResponse(13-13)TopGainersLosersResponse(14-14)TrendingPoolData(21-21)TrendingPoolIncluded(22-22)TrendingPoolsResponse(15-15)CategoryData(18-18)CategoriesResponse(16-16)NewCoinData(19-19)NewCoinsResponse(17-17)apps/agentic-server/src/index.ts (5)
TrimmedTrendingCoin(92-92)TrimmedGainerLoserCoin(93-93)TrimmedTrendingPool(94-94)TrimmedCategory(95-95)TrimmedNewCoin(96-96)
apps/agentic-server/src/routes/chat.ts (7)
apps/agentic-server/src/tools/getAssets.ts (1)
getAssetsTool(101-116)apps/agentic-server/src/tools/getShapeShiftKnowledge.ts (1)
getShapeShiftKnowledgeTool(60-64)apps/agentic-server/src/tools/getTrendingTokens.ts (1)
getTrendingTokensTool(39-54)apps/agentic-server/src/tools/getTopGainersLosers.ts (1)
getTopGainersLosersTool(53-68)apps/agentic-server/src/tools/getTrendingPools.ts (1)
getTrendingPoolsTool(77-81)apps/agentic-server/src/tools/getCategories.ts (1)
getCategoriesTool(42-46)apps/agentic-server/src/tools/getNewCoins.ts (1)
getNewCoinsTool(39-54)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: main
🔇 Additional comments (14)
apps/agentic-server/src/tools/send.ts (1)
121-132: Send tool description aligns well with new UI‑card patternThe updated description clearly constrains responses to supplement the card and provides good default phrasing; no behavioral risks here.
apps/agentic-chat/src/components/ui/AssetListItem.tsx (1)
30-41: Overall AssetListItem implementation looks solidIcon fallback behavior, price/change guards, and variant-based coloring are all straightforward and cohesive; aside from the TS‑narrowing note above, this is ready to use as a shared row component.
Also applies to: 50-58, 79-108
apps/agentic-server/src/tools/transactionHistory.ts (1)
113-125: Transaction history description matches the new UI‑card guidanceThe updated description clearly frames this as a card‑backed tool with concise default responses; no impact on existing query/filter behavior.
apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
5-14: New CoinGecko API wrappers are straightforward and consistent with existing clientThe added functions (
getTrendingSearch,getTopGainersLosers,getTrendingPools,getCategories,getNewCoins) cleanly wrap the respective endpoints, reuse the shared axios client, and keep error propagation simple. Combined with the existinggetSimplePricesfallback behavior, this is a solid foundation for the new informational tools.Also applies to: 31-87, 89-134
apps/agentic-server/src/tools/portfolio.ts (1)
6-8: Portfolio now leverages shared pricing helper and card‑centric descriptionSwitching to
getAssetPricesfor balance enrichment keeps pricing logic centralized and lets you surfacepriceChange24hcleanly. The updatedportfolioTooldescription matches the new UI‑card interaction model and shouldn’t affect existing behavior.Also applies to: 75-113, 153-165
apps/agentic-chat/src/components/tools/TopGainersLosersUI.tsx (1)
18-51: LGTM!The
GainerLoserCardcomponent is well-structured with appropriate early return for empty arrays, clean JSX composition, and proper use of theToolCardcompound component pattern.apps/agentic-server/src/tools/getShapeShiftKnowledge.ts (1)
60-64: LGTM!The updated description is concise and clearly communicates that this tool has no UI card, guiding the LLM to format the response itself. This aligns with the pattern established by other tools in this PR (e.g.,
getCategoriesTool,getTrendingPoolsTool).apps/agentic-server/src/lib/asset/coingecko/index.ts (1)
1-23: LGTM!The barrel file cleanly re-exports the new API functions and types, maintaining a clear separation between function exports and type exports. This provides a well-organized public API surface for the coingecko module.
apps/agentic-server/src/tools/initiateSwap.ts (2)
327-332: LGTM!The refactor to use
resolveAssetdirectly simplifies the USD-path flow. The error handling correctly validates that a price is available before proceeding with the USD-to-crypto conversion.
292-306: LGTM!The updated tool descriptions provide clear UI card guidance and example responses, maintaining consistency with other tools in this PR. The instruction to "supplement the card, not duplicate it" will help reduce verbose LLM responses.
apps/agentic-server/src/tools/getTrendingTokens.ts (1)
23-37: LGTM!The mapping logic safely handles optional fields with nullish coalescing, and correctly extracts the first assetId from the coingecko mapping (which may be undefined for unmapped tokens, as allowed by the
TrimmedTrendingCointype).apps/agentic-server/src/tools/getTopGainersLosers.ts (1)
53-68: LGTM!The tool definition follows the established pattern with clear UI card guidance and example responses.
apps/agentic-server/src/routes/chat.ts (2)
77-150: LGTM!The
buildToolsfunction appropriately useswrapToolWithLoggingfor stateless tools and inline wrappers for tools requiringwalletContextinjection. The new informational tools are correctly integrated.
194-201: LGTM!The system prompt updates provide clear tool categorization and UI behavior guidance that aligns with the individual tool descriptions. This will help the LLM make better tool selection decisions and produce appropriate responses.
8120fa9 to
1a23586
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
apps/agentic-server/src/tools/getAssets.ts (1)
97-112: LGTM - Clear tool description with UI card guidance.The description provides good instructions for the LLM on how to supplement the UI card without duplicating information.
🧹 Nitpick comments (6)
apps/agentic-server/src/tools/portfolio.ts (1)
105-105: Minor: Redundant nullish coalescing withundefined.
asset.priceChange24h ?? undefinedis equivalent to justasset.priceChange24hwhen the fallback isundefined. However, this is harmless and makes the intent explicit.apps/agentic-server/src/tools/getTrendingTokens.ts (1)
17-21: Consider adding error handling for API failures.The
getTrendingSearch()call doesn't have try/catch. If the CoinGecko API fails, the error will propagate up. This may be intentional if handled at a higher level, but consider whether a graceful fallback or specific error message would improve UX.#!/bin/bash # Check if there's error handling at the route/tool execution level rg -n "getTrendingTokensTool" --type=ts -A 10 -B 2apps/agentic-server/src/tools/getCategories.ts (1)
21-40: Consider adding error handling for the API call.The
getCategories(order)call at line 28 can throw on network failures or API errors. Other similar tools in the codebase have try-catch blocks. Consider wrapping in try-catch to provide a meaningful error message or empty result.export async function executeGetCategories(input: GetCategoriesInput): Promise<GetCategoriesOutput> { console.log('[getCategories]:', input) const sortBy = input.sortBy ?? 'market_cap_change_24h' const limit = input.limit ?? 10 const order = sortBy === 'market_cap' ? 'market_cap_desc' : 'market_cap_change_24h_desc' - const data = await getCategories(order) + let data + try { + data = await getCategories(order) + } catch (error) { + console.error('[getCategories] API error:', error) + return { categories: [], sortedBy: sortBy } + } const categories: TrimmedCategory[] = data.slice(0, limit).map((cat: CategoryData) => ({apps/agentic-server/src/tools/getTrendingPools.ts (1)
50-72: Consider defensive check fordata.databefore slicing.If the API returns an unexpected response structure,
data.datacould be undefined, causing a runtime error on.slice().- const pools: TrimmedTrendingPool[] = data.data.slice(0, limit).map((pool: TrendingPoolData) => { + const pools: TrimmedTrendingPool[] = (data.data ?? []).slice(0, limit).map((pool: TrendingPoolData) => {apps/agentic-server/src/routes/chat.ts (1)
36-46: Good abstraction, but theas Tcast bypasses type checking.The wrapper correctly preserves the tool structure, but casting to
Tat line 45 could hide type mismatches. Consider using a more precise return type or ensuring the spread preserves the exact type.The current implementation works correctly for the use cases in this file. The cast is acceptable given the controlled usage pattern.
apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
16-24: Consider adding validation forCOINGECKO_API_KEYat module load time, following the pattern used elsewhere in the codebase.The API key is read from the environment but never validated. If undefined, axios will send the string
"undefined"in the auth header, causing API authentication failures with unclear error messages. The codebase already establishes this validation pattern (e.g.,tools/send.ts,utils/feeEstimation.ts). Add a check like:const COINGECKO_API_KEY = process.env.COINGECKO_API_KEY if (!COINGECKO_API_KEY) { throw new Error('COINGECKO_API_KEY environment variable is required') }This prevents confusing auth errors and aligns with existing error-handling conventions.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (25)
apps/agentic-chat/src/components/toolUIRegistry.tsx(2 hunks)apps/agentic-chat/src/components/tools/NewCoinsUI.tsx(1 hunks)apps/agentic-chat/src/components/tools/TopGainersLosersUI.tsx(1 hunks)apps/agentic-chat/src/components/tools/TrendingTokensUI.tsx(1 hunks)apps/agentic-chat/src/components/ui/AssetListItem.tsx(1 hunks)apps/agentic-server/src/context.ts(1 hunks)apps/agentic-server/src/index.ts(1 hunks)apps/agentic-server/src/lib/asset/coingecko/api.ts(2 hunks)apps/agentic-server/src/lib/asset/coingecko/index.ts(1 hunks)apps/agentic-server/src/lib/asset/coingecko/types.ts(1 hunks)apps/agentic-server/src/lib/asset/prices.ts(1 hunks)apps/agentic-server/src/routes/chat.ts(6 hunks)apps/agentic-server/src/tools/getAssets.ts(3 hunks)apps/agentic-server/src/tools/getCategories.ts(1 hunks)apps/agentic-server/src/tools/getNewCoins.ts(1 hunks)apps/agentic-server/src/tools/getShapeShiftKnowledge.ts(1 hunks)apps/agentic-server/src/tools/getTopGainersLosers.ts(1 hunks)apps/agentic-server/src/tools/getTrendingPools.ts(1 hunks)apps/agentic-server/src/tools/getTrendingTokens.ts(1 hunks)apps/agentic-server/src/tools/initiateSwap.ts(3 hunks)apps/agentic-server/src/tools/portfolio.ts(4 hunks)apps/agentic-server/src/tools/receive.ts(1 hunks)apps/agentic-server/src/tools/send.ts(1 hunks)apps/agentic-server/src/tools/transactionHistory.ts(1 hunks)apps/agentic-server/src/utils/assetHelpers.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (12)
- apps/agentic-server/src/context.ts
- apps/agentic-chat/src/components/tools/TopGainersLosersUI.tsx
- apps/agentic-chat/src/components/tools/TrendingTokensUI.tsx
- apps/agentic-server/src/tools/initiateSwap.ts
- apps/agentic-chat/src/components/toolUIRegistry.tsx
- apps/agentic-chat/src/components/tools/NewCoinsUI.tsx
- apps/agentic-server/src/tools/getShapeShiftKnowledge.ts
- apps/agentic-server/src/tools/getTopGainersLosers.ts
- apps/agentic-server/src/lib/asset/prices.ts
- apps/agentic-server/src/index.ts
- apps/agentic-server/src/tools/receive.ts
- apps/agentic-server/src/tools/getNewCoins.ts
🧰 Additional context used
🧬 Code graph analysis (8)
apps/agentic-server/src/tools/getTrendingPools.ts (2)
apps/agentic-server/src/lib/asset/coingecko/types.ts (3)
TrimmedTrendingPool(214-225)TrendingPoolIncluded(148-159)TrendingPoolData(105-146)apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
getTrendingPools(108-116)
apps/agentic-server/src/tools/getCategories.ts (2)
apps/agentic-server/src/lib/asset/coingecko/types.ts (2)
TrimmedCategory(227-234)CategoryData(167-177)apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
getCategories(118-129)
apps/agentic-server/src/tools/portfolio.ts (2)
apps/agentic-server/src/lib/asset/prices.ts (1)
getAssetPrices(12-33)packages/types/src/asset.ts (1)
asset(3-26)
apps/agentic-server/src/utils/assetHelpers.ts (4)
apps/agentic-server/src/lib/schemas/swapSchemas.ts (1)
AssetInput(76-76)packages/types/src/asset.ts (1)
Asset(28-28)apps/agentic-server/src/lib/asset/prices.ts (1)
getAssetPrices(12-33)packages/types/src/network.ts (1)
chainIdToNetwork(84-86)
apps/agentic-server/src/tools/getAssets.ts (5)
packages/types/src/network.ts (2)
NETWORKS(23-42)chainIdToNetwork(84-86)packages/types/src/asset.ts (2)
asset(3-26)Asset(28-28)packages/utils/src/AssetService.ts (1)
assetService(135-135)packages/utils/src/index.ts (1)
assetService(35-35)packages/caip/src/adapters/coingecko/index.ts (1)
assetIdToCoingecko(59-59)
apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
apps/agentic-server/src/lib/asset/coingecko/types.ts (5)
TrendingSearchResponse(62-74)TopGainersLosersResponse(92-95)TrendingPoolsResponse(161-164)CategoriesResponse(179-179)NewCoinsResponse(189-189)
apps/agentic-server/src/routes/chat.ts (7)
apps/agentic-server/src/tools/getAssets.ts (1)
getAssetsTool(97-112)apps/agentic-server/src/tools/getShapeShiftKnowledge.ts (1)
getShapeShiftKnowledgeTool(60-64)apps/agentic-server/src/tools/getTrendingTokens.ts (1)
getTrendingTokensTool(39-54)apps/agentic-server/src/tools/getTopGainersLosers.ts (1)
getTopGainersLosersTool(53-68)apps/agentic-server/src/tools/getTrendingPools.ts (1)
getTrendingPoolsTool(77-81)apps/agentic-server/src/tools/getCategories.ts (1)
getCategoriesTool(42-46)apps/agentic-server/src/tools/getNewCoins.ts (1)
getNewCoinsTool(39-54)
apps/agentic-server/src/lib/asset/coingecko/types.ts (2)
apps/agentic-server/src/lib/asset/coingecko/index.ts (10)
TrendingCoinItem(20-20)TrendingSearchResponse(13-13)TopGainersLosersResponse(14-14)TrendingPoolData(21-21)TrendingPoolIncluded(22-22)TrendingPoolsResponse(15-15)CategoryData(18-18)CategoriesResponse(16-16)NewCoinData(19-19)NewCoinsResponse(17-17)apps/agentic-server/src/index.ts (5)
TrimmedTrendingCoin(92-92)TrimmedGainerLoserCoin(93-93)TrimmedTrendingPool(94-94)TrimmedCategory(95-95)TrimmedNewCoin(96-96)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: main
🔇 Additional comments (25)
apps/agentic-server/src/tools/transactionHistory.ts (1)
114-125: Card‑oriented description is clear and consistentThe updated
descriptionclearly frames this as a card‑supplement tool, with good guardrails against duplicating card data and appropriately short default responses. No issues from a correctness or API standpoint.apps/agentic-server/src/tools/send.ts (1)
121-132: Description update follows consistent UI-card pattern.The multi-line description with UI guidance aligns with the broader tooling updates in this PR. The format is consistent with other tools (portfolio, getTrendingTokens) and provides clear instructions for supplementing rather than duplicating card data.
apps/agentic-server/src/tools/portfolio.ts (3)
6-6: Import change aligns with new asset pricing utility.The switch to
getAssetPricesconsolidates asset price fetching and provides consistentpriceChange24hdata across the codebase.
78-78: Asset resolution updated to use centralized pricing utility.This change properly aligns with the new
getAssetPricesfunction which returns enriched asset data including prices and 24h changes.
154-165: Description follows consistent UI-card guidance pattern.The multi-line description with example responses aligns with the PR's approach across all updated tools.
apps/agentic-server/src/utils/assetHelpers.ts (2)
9-16: Simplified asset resolution with proper error handling.The refactored
resolveAssetnow usesassetService.search()directly and properly handles the case where no assets are found. The error message appropriately includes the network context when provided.
18-24: Price fetching and network resolution look correct.The function correctly:
- Fetches price data for the resolved asset
- Falls back to
'0'if no price is available- Resolves network from input, then chainId mapping, then empty string
One consideration: the
networkfield in the return type comes fromchainIdToNetworkwhich returnsNetwork | undefinedbased on the type snippet. The fallback chain handles this appropriately.apps/agentic-server/src/lib/asset/coingecko/index.ts (1)
1-23: Clean barrel exports for CoinGecko module.The expanded exports properly expose new API functions and types. Using
export typefor type-only exports is the correct pattern for TypeScript.apps/agentic-server/src/tools/getTrendingTokens.ts (3)
7-9: Schema looks good with sensible defaults.The Zod schema properly validates the limit parameter with min/max constraints and provides a clear description.
39-54: Tool description follows consistent UI-card pattern.The description properly guides the AI to supplement rather than duplicate card data, with appropriate example responses.
23-34: The review comment is incorrect.AssetListItemgracefully handles undefinedassetIdthrough fallback logic.The
assetIdfield is intentionally optional in theTrimmedTrendingCointype definition (line 199 of types.ts:assetId?: string). WhenassetIds[0]is undefined, theAssetListItemcomponent handles it safely:
- If
assetIdexists, it renders anAssetIcon(line 85)- If
assetIdis undefined buticonUrlis provided, it uses that (line 86)- If neither exists, it renders a
FallbackIconwith the symbol's first letter (line 87)This defensive UI pattern is consistent across the codebase and works correctly when CoinGecko IDs lack CAIP mappings.
apps/agentic-chat/src/components/ui/AssetListItem.tsx (3)
30-41: LGTM - Simple and effective fallback icon.Clean implementation using first character of symbol as fallback.
43-58: LGTM - Good error handling for image loading.The
hasErrorstate andonErrorcallback provide graceful degradation to the fallback icon.
60-109: LGTM - Well-structured component with proper conditional rendering.The icon fallback chain (assetId → iconUrl → symbol initials) and conditional price/change display are implemented correctly.
apps/agentic-server/src/tools/getCategories.ts (1)
6-19: LGTM - Schema and types are well-defined.Good use of optional parameters with sensible defaults documented in descriptions.
apps/agentic-server/src/tools/getTrendingPools.ts (1)
29-48: LGTM - Clean lookup map construction with proper fallbacks.Good use of Maps for efficient lookups. The fallback values ensure graceful handling of missing data.
apps/agentic-server/src/lib/asset/coingecko/api.ts (1)
89-134: LGTM - Consistent API endpoint implementations.All new functions follow the established pattern and have proper type annotations. Default parameter values align with the CoinGecko API documentation.
apps/agentic-server/src/tools/getAssets.ts (1)
36-60: LGTM - Robust error handling and field mapping.Proper null coalescing for all optional market data fields, and the try-catch ensures graceful degradation.
apps/agentic-server/src/routes/chat.ts (2)
144-149: LGTM - New informational tools properly integrated.All new tools (getTrendingTokensTool, getTopGainersLosersTool, getTrendingPoolsTool, getCategoriesTool, getNewCoinsTool) are correctly wrapped with logging and added to the tools object.
194-201: LGTM - Clear tool categorization in system prompt.The organized tool categories and UI behavior guidance will help the LLM use tools appropriately.
apps/agentic-server/src/lib/asset/coingecko/types.ts (5)
36-74: Well-structured trending tokens types.The type definitions for trending tokens are comprehensive and properly handle optional fields and nested structures. The separation between required fields (id, name, symbol, etc.) and optional data object is appropriate for API response handling.
76-95: Good null handling in top gainers/losers types.The types correctly handle nullable values with
market_cap_rank: number | nulland appropriately mark time-based change fields as optional, reflecting the varying availability of historical data.
97-164: Comprehensive trending pools types with proper optionality.The trending pools types handle complex nested structures well, with appropriate optional fields throughout. The separation of
dataandincludedarrays follows JSON:API conventions, and the relationships structure enables proper entity linking.
166-189: Clean and straightforward category and new coins types.The category and new coins types are well-defined with appropriate optionality. The required
activated_atfield as a number (timestamp) is the correct choice for reliable temporal data.
191-243: Excellent design of trimmed types for LLM context optimization.The trimmed types demonstrate thoughtful design:
- Convention consistency: Switching from
snake_case(raw API) tocamelCase(application layer) shows good separation of concerns- Context optimization: Reducing fields to minimize LLM token usage is a practical consideration
- Type safety preserved: Proper null handling and optional fields maintain type safety
- Enrichment support: Optional
assetIdfields enable integration with ShapeShift's asset system- Formatted timestamps:
activatedAtFormattedinTrimmedNewCoinimproves readabilityThe apparent inconsistency in numeric types (e.g.,
price: string | nullvsprice: number) correctly reflects the underlying API differences between endpoints.
Summary by CodeRabbit
New Features
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.