feat: actionable AI pipeline suggestions with conversation UI#88
feat: actionable AI pipeline suggestions with conversation UI#88TerrifiedBug merged 26 commits intomainfrom
Conversation
…e suggestion cards
Greptile SummaryThis PR transforms the AI pipeline dialog from a raw text output into a structured, conversational suggestion system. It introduces persistent Key changes by layer:
Issue to address: Confidence Score: 3/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant U as User (Browser)
participant D as AiPipelineDialog
participant H as useAiConversation
participant API as /api/ai/pipeline (SSE)
participant DB as PostgreSQL
participant AI as AI Provider
U->>D: Opens Review tab
D->>H: useAiConversation({ pipelineId })
H->>+DB: trpc.ai.getConversation (VIEWER)
DB-->>-H: AiConversation + AiMessages
H->>D: messages[], conversationId
U->>D: Submits prompt
D->>H: sendReview(prompt)
H->>+API: POST { pipelineId, conversationId, prompt }
API->>DB: Verify pipeline ownership & team membership
API->>DB: AiMessage.create (role: user)
API->>DB: AiMessage.findMany (last 10 for history)
API-->>H: SSE: { conversationId }
API->>AI: streamCompletion(systemPrompt + history)
AI-->>API: token stream
API-->>H: SSE: { token } (streamed)
API->>DB: AiMessage.create (role: assistant + suggestions JSON)
API->>DB: writeAuditLog(pipeline.ai_review)
API-->>-H: SSE: { done }
H->>DB: fetchQuery getConversation (staleTime: 0)
DB-->>H: Updated messages with real IDs
H->>D: setMessages(refetched)
U->>D: Clicks "Apply Selected"
D->>H: onApplySelected(messageId, suggestions)
H->>D: applySuggestions(suggestions) via flow-store
D->>DB: trpc.ai.markSuggestionsApplied (EDITOR)
DB-->>D: { applied: N }
|
|
@greptile review |
- Verify pipelineId belongs to teamId in streaming route - Verify conversationId belongs to pipelineId when reusing conversations - Add pipeline ownership check in markSuggestionsApplied (conversationId↔pipelineId) - Use TRPCError instead of raw Error for consistent error handling - Add withAudit middleware to startNewConversation mutation
…tion tracking - Only push undo snapshot when at least one suggestion is applied (prevents ghost Ctrl+Z entries when all suggestions fail) - Replace manual writeAuditLog with withAudit middleware in markSuggestionsApplied to match project conventions
- Await prisma.aiMessage.create before sending done:true SSE event, eliminating the race where client refetch returns stale data - Replace temp message IDs with real server-persisted IDs by refetching after streaming completes, so markSuggestionsApplied finds the row - Guard markSuggestionsApplied against temp- prefixed IDs as a safety net - Clear TanStack Query cache in startNewConversation to prevent the sync guard from repopulating the old conversation from cache
…-e78 # Conflicts: # agent/internal/agent/agent.go # agent/internal/agent/poller.go # src/server/services/ws-auth.ts
- Add isNewConversationRef to block the render-time sync guard from repopulating old messages after React Query background refetches - Resolve dot-notation keys in modify_config changes (e.g. "codec.fields") into proper nested objects instead of creating literal flat keys
|
@greptile fixed [Critical] Missing team membership check — False positive. The membership check already exists at [Important] "New Conversation" refetch loop — Fixed. The previous removeQueries fix was incomplete because [Important] Shallow config merge — Fixed. Added setAtPath() helper that recursively resolves dot-notation |
The read-modify-write on the JSONB suggestions column was not atomic, so concurrent team members marking different suggestions could silently overwrite each other's appliedAt markers.
Summary
AiConversation+AiMessagePrisma models)Changes
Data Layer: New
AiConversationandAiMessagemodels with cascade delete on Pipeline, SetNull on UserBackend:
streamCompletionextended to accept conversation message historyairouter (getConversation,startNewConversation,markSuggestionsApplied)conversationIdvia SSE, writes audit logsClient Logic:
applySuggestionsbatch action with single undo snapshotUI:
useAiConversationhook for conversation loading, streaming, and managementAiSuggestionCardwith status/priority/type badges and conflict warningsAiMessageBubblewith selection state and Apply All / Apply SelectedAiPipelineDialogrewritten with conversation thread, New Conversation button, and graceful markdown fallbackTest plan