Local AI-Assisted Cost Insights with Privacy-Preserving Inference#285
Draft
etiennechabert wants to merge 18 commits into
Draft
Local AI-Assisted Cost Insights with Privacy-Preserving Inference#285etiennechabert wants to merge 18 commits into
etiennechabert wants to merge 18 commits into
Conversation
… InsightType, AIPreferences) Implemented AI types following branded type and discriminated union patterns: - ModelName branded type for AI model identifiers - InsightType union for trend-summary, optimization, and conversational insights - AIPreferences interface for user AI settings - OllamaStatus discriminated union for connection state - InsightParams and InsightResult discriminated unions with type safety - InsightGenerationState to prevent impossible states Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…ting and inference Implemented OllamaHandle interface with three core methods: - checkStatus(): checks Ollama availability and version - listModels(): retrieves available AI models - generate(): executes inference with streaming support Follows project patterns from s3-client.ts: - Factory function returning interface handle - Proper error handling with discriminated unions - Native fetch API with timeout support - Comprehensive test coverage (22 tests) All TypeScript strict checks pass, ESLint clean, tests passing. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…trends, and optimizations Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…and model management - Created OllamaManager with factory pattern following sync-client.ts - Wraps OllamaHandle from core for health checks, model listing, and inference - Implements caching for status (30s TTL) and models list (5min TTL) - Provides invalidateCache() and terminate() lifecycle methods - Added comprehensive test suite (17 tests) covering all functionality - All tests pass, TypeScript strict checks pass, ESLint clean Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Added import for AI types (AIInsight, AIModel, AIPreferences, InsightParams, OllamaStatus) - Added 5 new methods to CostApi interface: - getAIPreferences(): Get AI feature preferences - saveAIPreferences(): Save AI feature preferences - getOllamaStatus(): Check Ollama service connection - listAIModels(): List available Ollama models - generateInsight(): Generate AI insights from cost data - All methods follow existing patterns (Promise return types, JSDoc comments) - TypeScript compilation and ESLint checks pass Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented AI IPC handlers for managing AI preferences, Ollama status, model listing, and insight generation. Key changes: - Created packages/desktop/src/main/handlers/ai.ts with 5 IPC handlers: * ai:get-preferences - Load AI preferences from JSON * ai:save-preferences - Save AI preferences to JSON * ai:get-status - Check Ollama connection status * ai:list-models - List available Ollama models * ai:generate-insight - Generate AI insights from cost data - Updated packages/desktop/src/preload/preload.ts to expose AI methods to the renderer process - Updated packages/ui/src/__fixtures__/mock-api.ts to stub AI methods for UI testing The handlers follow existing patterns from query-costs.ts and ui.ts: - Use discriminated unions for insight parameters (trend-summary, optimization, conversational) - Query cost data using buildCostQuery and buildTrendQuery from core - Build prompts using buildPrompt from core - Call OllamaManager for inference - Parse JSON responses with proper type guards - Handle errors gracefully All TypeScript strict checks pass, ESLint clean, all tests pass. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added ollama ^0.5.11 as a runtime dependency to @costgoblin/desktop. This enables future use of the official Ollama JavaScript SDK alongside the custom HTTP client implementation. All checks pass: TypeScript compilation clean, ESLint no violations, 61 tests passing. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…on (use-ai-insight.ts) Created packages/ui/src/hooks/use-ai-insight.ts with useAIInsight hook that wraps the async generateInsight API call in a useQuery state machine. Hook handles all three InsightParams types (trend-summary, optimization, conversational) with proper dependency extraction for re-generation when inputs change. Updated packages/core/src/browser.ts to export AI types from ai/index.js. Updated packages/core/src/types/index.ts to re-export AI types for browser consumption. All TypeScript strict checks pass, ESLint clean with no violations, all tests pass (356 tests in core, 125 tests in ui). Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
auto-claude: subtask-3-3 - Build AIChat component for conversational queries Created AIChat component with: - Conversational UI with message history (user/assistant bubbles) - Real-time message input with submit handling - Integration with CostApi.generateInsight for conversational queries - Loading states with visual feedback - Supporting data display for AI responses - Auto-scroll to latest messages - Empty state with example prompts Added comprehensive test suite covering: - Empty state rendering - Initial message display - Supporting data rendering - Input handling and form submission - Loading state behavior - Validation for empty/whitespace inputs Follows project patterns: - Uses useCostApi hook for API access - Follows styling patterns from command-palette and ai-insight-card - Uses lucide-react icons (Bot, User, Send, Loader2) - Proper TypeScript types with exactOptionalPropertyTypes compliance - No console.log statements - All tests pass (137 total in UI package) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> @
…ions and insights display
…ge index Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…age cost Implemented ai-query MCP tool that accepts natural language queries about cloud costs and returns structured cost data. The tool: - Parses natural language queries to extract intent (cost/trend/comparison) - Detects dimension to group by (service, account, region, team, etc.) - Extracts time periods (last week, last month, etc.) - Identifies entity filters (S3, EC2, etc.) - Executes appropriate queries (cost or trend analysis) - Returns formatted markdown tables with cost breakdowns Follows patterns from query-costs.ts with proper error handling, type safety, and markdown formatting. Uses tool-helpers for common operations. Registered tool in MCP server with natural language description and schema. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Integrated OllamaManager into Electron main process and added AI Insights
navigation to the desktop app.
Changes:
- main.ts: Initialize OllamaManager and pass to registerIpcHandlers
* Import createOllamaManager and OllamaManager type
* Create ollamaManager instance in main() function
* Update createWindow signature to accept ollamaManager parameter
* Pass ollamaManager to registerIpcHandlers via options parameter
* Update app.on('activate') handler to pass ollamaManager
- App.tsx: Add AIInsights view to navigation
* Import AIInsights component from @costgoblin/ui
* Add 'ai-insights' to View type union
* Add AI Insights to command palette items
* Add 'ai-insights' case in handleNavClick
* Add 'ai-insights' case in activeNavId
* Update Sparkles button to navigate to ai-insights
* Add AIInsights view rendering with Profiler
- mcp-server.test.ts: Update test expectations for ai_query tool
* Update tool count from 10 to 11
* Add ai_query to expected tool names
All TypeScript type checks pass, ESLint clean, all 576 tests passing.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented new AI insight widget that displays on the Overview page, allowing users to generate AI-powered cost trend summaries. Changes: - Added 'ai-insight' widget type to WidgetSpec union in core/types/views.ts - Created AIInsightWidget component in ui/widgets/ai-insight-widget.tsx * Shows "Generate AI Insight" button when no insight exists * Checks Ollama connection status before allowing generation * Displays loading state during insight generation * Shows generated insights using AIInsightCard component * Provides regenerate and retry functionality - Registered ai-insight widget in WIDGET_REGISTRY and WIDGET_CATALOG - Updated views serialization and validation to handle ai-insight type - Added ai-insight widget to Overview seed view (displayed as first row) - Updated widget-inspector.tsx to support ai-insight in editor The widget integrates with existing AI infrastructure: - Uses useCostApi() to access getOllamaStatus() and generateInsight() - Generates trend-summary insights for the current date range and filters - Groups by 'service' dimension by default - Follows existing widget patterns (WidgetCommonProps, loading states) All TypeScript strict checks pass, ESLint clean, all 576 tests passing. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Created MCP protocol test script (test-ai-query.mjs) to verify ai_query tool integration: - Health endpoint check confirms server running on port 19532 - JSON-RPC session initialization and lifecycle management working - ai_query tool properly registered and discoverable via tools/list - Tool invocation via tools/call follows MCP specification - Response format correct (JSON-RPC with SSE) Verification results: ✅ MCP server running and responsive ✅ ai_query tool registered (11 tools total) ✅ Protocol compliance confirmed ✅ External AI assistants can discover and invoke tool ✅ Natural language query parsing integrated Created verification-subtask-5-4.md documenting test methodology, integration architecture, and verification results. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Integrate a local language model (via Ollama or llama.cpp) to provide natural language cost insights. The AI analyzes DuckDB query results to: summarize trends in plain language, suggest optimization opportunities based on spending patterns and Cost Optimization Hub data, answer natural language queries ('Which team spent the most on S3 last month?'), and generate executive summary narratives. All inference runs locally — no cloud API calls — consistent with CostGoblin's privacy-first architecture. AI features are opt-in and require the user to install a local model.