feat(api): add chat read tools for summary/retrospective/metrics (#82) - #180
Conversation
There was a problem hiding this comment.
Three clean read-only IAiTool wrappers over existing MediatR queries. User scoping is enforced at the query layer (GetHabitMetricsQuery filters by both HabitId and UserId in the DB predicate; the other two pass UserId through to their handlers). All three use IUserDateService.GetUserTodayAsync for date defaulting, in full compliance with the timezone hard-rule. PayGate/failure Results surface correctly as ToolResult(false, Error: ...) rather than being swallowed, matching the existing GamificationOverview pattern. DI registration and catalog wiring are minimal and correct. Unit test coverage is solid — success, PayGate propagation, and argument-derivation cases are all present for each tool.
Add three read-only IAiTool implementations that wrap existing MediatR queries so in-app chat users can ask for their daily summary, a retrospective, or a single habit's metrics: - get_daily_summary -> GetDailySummaryQuery (defaults dates to user-today) - get_retrospective -> GetRetrospectiveQuery (period -> date-range) - get_habit_metrics -> GetHabitMetricsQuery (GUID-validated) PayGate / failure results surface as ToolResult(false, Error: ...) rather than being swallowed. Registered in DI and mapped onto the existing HabitMetricsRead / DailySummaryRead / RetrospectiveRead catalog capabilities via chatTools. Refs thomasluizon/orbit-ui-mobile#82 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Three clean read-only IAiTool wrappers over existing MediatR queries. All three use IUserDateService.GetUserTodayAsync for date defaulting (timezone hard-rule satisfied), pass userId through to their queries (user scoping enforced at the query layer), and surface PayGate/failure Results as ToolResult(false, Error: ...) rather than swallowing them — consistent with the GamificationOverview pattern. GUID boundary validation in GetHabitMetricsTool is correct. Catalog wiring maps onto the existing DailySummaryRead/RetrospectiveRead/HabitMetricsRead capabilities with no new capabilities added. Unit test coverage is solid across success, PayGate propagation, and argument-derivation cases for all three tools.
@
Adds three read-only
IAiToolimplementations to the in-app chat agent, each a thin wrapper over an existing MediatR query:get_daily_summary->GetDailySummaryQuery(date range defaults to user-today viaIUserDateService)get_retrospective->GetRetrospectiveQuery(period-> date-range, mirroringHabitsController.GetRetrospective)get_habit_metrics->GetHabitMetricsQuery(validateshabit_idas a GUID at the boundary)All three are
IsReadOnly => true. PayGate / failureResults surface asToolResult(false, Error: ...)(mirroringGetGamificationOverviewTool) rather than being swallowed —get_daily_summaryfor non-Pro /ai_summaryoff,get_retrospectivefor non-YearlyPro /ai_retrospectiveoff.Registered in DI (
ServiceCollectionExtensions.cs) and mapped onto the existingHabitMetricsRead/DailySummaryRead/RetrospectiveReadcatalog capabilities via theirchatToolsarrays (no new capabilities;risk_class: Low,confirmation: Noneunchanged).Tests
tests/Orbit.Application.Tests/Chat/Tools/.ChatToolMetadataTests.cs(names/descriptions/schemas).EveryChatTool_IsMappedToTheCatalog(Infrastructure.Tests) auto-discovers the new tools and stays green.dotnet buildclean; Application.Tests (1689) + Infrastructure.Tests (917) all pass.Refs thomasluizon/orbit-ui-mobile#82
Stacked on #175 (#79) — shares the chat catalog/DI files (
ServiceCollectionExtensions.cs+AgentCatalogService.cs). Base isissue-79; review/merge #175 first.🤖 Generated with Claude Code
@