Commit Graph

28 Commits

Author SHA1 Message Date
chihlasm
92cc62bcbd feat: add [TRIAGE_UPDATE] marker extraction and auto-PATCH (Phase 2)
- Add _parse_triage_update_marker() parser following existing marker pattern
- Add [TRIAGE_UPDATE] instructions to system prompt with grounding rules
- Add QuestionItem.options support in question parser
- Wire triage extraction into both main and branch-aware chat paths
- Auto-PATCH session: AI only fills null fields (manual edits win)
- Evidence items: AI appends only, never modifies existing
- Return triage_update in ChatMessageResponse for frontend header sync

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 22:40:49 +00:00
chihlasm
15781baeb7 feat: add cockpit triage backend foundation (Phase 1)
- Migration 071: add client_name, asset_name, issue_category,
  triage_hypothesis, evidence_items columns to ai_sessions
- TriageUpdate schema for AI-inferred header updates in chat responses
- QuestionItem.options field for quick-reply buttons
- PATCH /ai-sessions/{id}/triage endpoint for manual header edits
- POST /ai-sessions/{id}/handoff-draft streaming endpoint for conclude modal
- Structured handoff fields (root_cause, steps_taken, recommendations)
  on resolve/escalate requests, passed through to ResolutionOutputGenerator
- Triage fields exposed in AISessionDetail response for session resume

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 22:30:48 +00:00
chihlasm
7a5d56494b feat: make resolve endpoint non-blocking, documentation optional
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 23:04:38 +00:00
chihlasm
d456b1156e feat: add SSE endpoint for streaming ticket notes generation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 23:04:14 +00:00
chihlasm
96602a6676 fix: return pending_task_lane in session detail API response + debug logging
_build_session_detail was omitting pending_task_lane, is_branching, and
active_branch_id from the GET /ai-sessions/{id} response. The fields
existed on the schema and model but were never passed in the manual
constructor, so task lane state could never be restored on navigation.

Also adds console logging to AssistantChatPage selectChat flow to
diagnose message restoration, and fixes ScriptTemplateEditor stepper
dismiss firing during programmatic script_body updates.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 21:44:04 +00:00
chihlasm
4fa26149e6 fix: add payload size limits to task lane save endpoint
- Max 50 questions, 50 actions, 100 responses (Pydantic max_length)
- Max 256KB total serialized payload (prevents DB bloat)
- Existing guards: JWT auth, role check, ownership check, rate limit

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 19:16:06 +00:00
chihlasm
80af408f2d feat: persist task lane user responses to backend
Add PUT /ai-sessions/{id}/task-lane endpoint that saves the full task
lane state (AI questions/actions + user's in-progress responses) to
the pending_task_lane JSONB column. TaskLane debounce-saves to the
backend every 2s after changes. On session load, user responses are
restored from the backend into sessionStorage so TaskLane picks them
up on mount. Users can now close the browser, come back later, and
find their task lane exactly where they left it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 19:11:13 +00:00
chihlasm
11de850054 feat: wire PDF and text file content into AI chat messages
PDF uploads were stored in S3 and had text extracted during upload, but
fetch_upload_images() filtered exclusively for image MIME types, so
document content never reached the AI.

- Add fetch_upload_documents() in storage_service.py to retrieve
  extracted_content for PDFs and text files
- Update ai_sessions.py chat endpoint to call both fetch_upload_images
  and fetch_upload_documents, injecting document text as context
- Add PDF text extraction in _generate_ai_description (pypdf)
- Add pypdf>=4.0.0 to requirements.txt
- Fix test_db teardown to avoid connection pool issues
- Add 5 tests for fetch_upload_documents

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 21:02:56 +00:00
chihlasm
3c0a29115c feat: AI marker system prompt fixes, TaskLane activation, and FlowPilot updates
- Fix system prompt to ensure [QUESTIONS]/[ACTIONS] markers in AI responses
- Add format reminder injection to user messages for marker compliance
- Wire TaskLane activation in prefill and resume paths
- Add ActionCardGroup component for structured question/action rendering
- Update FlowPilot session and step card components
- Update ai-session schemas and types for marker data

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 19:57:39 +00:00
chihlasm
e0d4148702 feat: generate resolution outputs on session resolve
Integrates ResolutionOutputGenerator into the resolve endpoint so that
structured outputs (ticket note, KB article, etc.) are auto-generated
after every successful session resolution. Non-blocking — resolve still
succeeds if output generation fails.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:04:38 +00:00
chihlasm
8e7f13d2f8 refactor: remove dead assistant_chat system, consolidate image helpers
The old /assistant/chats/* CRUD endpoints and assistant_chat_service
chat functions were unused — the frontend exclusively uses
/ai-sessions/{id}/chat (unified_chat_service) for all chat operations.

Removed:
- Chat CRUD endpoints (create, list, get, send, delete, conclude)
- assistant_chat_service: create_chat, send_message,
  generate_conclusion_summary, CONCLUSION_SYSTEM_PROMPT
- Frontend: assistantChatApi chat methods, dead types
  (AssistantChat, AssistantChatMessage, ConcludeChatRequest, etc.)

Kept:
- /assistant/retention endpoints (used by ChatRetentionSettingsPage)
- Shared AI infrastructure (_call_ai, _call_anthropic_cached,
  ASSISTANT_SYSTEM_PROMPT, _auto_title) — imported by unified_chat_service

Moved:
- fetch_upload_images + resize_image_for_vision → storage_service.py
  (shared location, not tied to dead endpoint)

Also added "Image Analysis" section to system prompt so Claude knows
to describe attached screenshots.

-650 lines of dead code removed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 05:28:06 +00:00
chihlasm
36ca830481 fix: wire image uploads into correct chat endpoint (unified_chat_service)
The frontend calls /ai-sessions/{id}/chat (unified_chat_service), not
/assistant/chats/{id}/messages (assistant_chat_service). The previous
commit wired images into the wrong backend. This fixes it:

- ai_session.py schema: add upload_ids to ChatMessageRequest
- ai_sessions.py endpoint: fetch images via _fetch_upload_images
- unified_chat_service: accept and forward images to _call_ai

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 05:02:34 +00:00
b414502062 feat: unified sessions — merge assistant chat into ai_sessions table
Add session_type ('guided'|'chat') and title columns to ai_sessions,
enabling both FlowPilot guided sessions and assistant chat sessions to
live in a single table. This is the foundation for a unified session
history and consistent UX across both interaction modes.

Backend:
- Migration 066: session_type + title columns
- unified_chat_service: chat sessions on ai_sessions with same AI/RAG
- POST /ai-sessions supports session_type='chat' creation
- POST /ai-sessions/{id}/chat for chat messages
- DELETE /ai-sessions/{id} for session deletion
- session_type filter on GET /ai-sessions

Frontend:
- AssistantChatPage rewired to aiSessionsApi (no more assistantChatApi)
- /assistant/:sessionId route for deep-linking
- Session history: type filter pills (All/Guided/Chat), type icons
- Dashboard: both types shown with correct routing and icons
- Fixed glass-border → border-default in dashboard components

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 17:29:25 +00:00
fab25456a5 feat: mid-session status updates — ticket notes, client updates, email drafts
Engineers can now generate AI-powered status updates during active FlowPilot
sessions and after resolve/escalate. Three audiences (Ticket Notes, Client
Update, Email Draft) with Quick/Detailed length options. Copy to clipboard
with one click. Client names auto-inserted from intake/PSA context.

Backend: new endpoint POST /ai-sessions/{id}/status-update with audience-aware
system prompts. Frontend: StatusUpdateModal with 2-step selection flow,
Share Update button in action bar, Share Resolution/Escalation on completed
sessions. Also updates Solutions Library spec with Community tier design.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 06:26:32 +00:00
Michael Chihlas
6ecb5a9bbd fix(flowpilot): widen message bar, add close/abandon session support
- Message bar now fixed-positioned above action bar with full-width
  layout (respects both app sidebar and session sidebar)
- Added abandon_session endpoint (POST /ai-sessions/{id}/abandon)
- Added "Close" button to FlowPilot action bar with confirmation dialog
- Session can now be closed without resolving or escalating

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 18:20:34 -04:00
a7b916116d fix(escalations): fall back to account_id when team_id is null
Users without team_id (solo accounts, pro plans) couldn't see
escalations because the query filtered by team_id which was NULL.
Now falls back to account_id scoping for both the escalation queue
endpoint and the sidebar badge count.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 05:04:47 +00:00
cf23107735 fix(escalations): add sidebar badge count + show all team escalations
- Add escalation_count to sidebar stats (team-wide requesting_escalation)
- Show badge on Escalations nav item in sidebar
- Remove user_id filter from escalation queue — show all team escalations
  including your own (needed for solo users and visibility)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 04:41:27 +00:00
6122dda71d fix(flowpilot): extract _build_session_detail helper, fix link_ticket 500
The same model_validate bug existed in link_ticket endpoint (line 467).
Extracted the manual AISessionDetail construction into a shared helper
_build_session_detail() used by both get_session and link_ticket.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 06:28:11 +00:00
0118b80b63 fix(flowpilot): fix session detail 500 — build AISessionDetail manually
Root cause: AISessionDetail.model_validate(session) tried to validate the
ORM relationship 'steps' which has field 'id', but AISessionStepResponse
expects 'step_id'. This caused a Pydantic ValidationError on every session
detail load.

Fix: Construct AISessionDetail manually from ORM fields, passing the
already-built step_responses list directly instead of relying on
model_validate to serialize the ORM steps relationship.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 06:25:57 +00:00
5eeff0c83a debug: add detailed error reporting for session detail serialization
Temporary debug commit — surfaces the actual exception when GET /ai-sessions/{id}
fails with 500, instead of generic "Internal server error" from middleware.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 06:20:27 +00:00
eed771cb27 fix: prevent InFailedSQLTransactionError in session creation
Root cause: embedding generation could break the DB transaction via a failed
SQL statement. The except block caught the Python error but left the transaction
in a failed state. Subsequent queries (_record_usage → subscription lookup)
then failed with InFailedSQLTransactionError.

Fixes:
- session_embedding_service: use begin_nested() savepoint so failures don't
  poison the parent transaction
- ai_sessions.py: add db.rollback() before _record_usage in all 3 error
  handlers (create, respond, pickup) to recover from broken transactions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 04:36:12 +00:00
2ed8a2af15 fix: 6 integration audit fixes — ticket filter, admin nav, FK scope, debounce, error messages
- Fix AISession.ticket_id → psa_ticket_id in list_sessions filter query
- Add Gallery nav item (LayoutGrid icon) to AdminSidebar navItems array
- Remove ForeignKey from FileUpload.session_id (Python model) + migration b8d2f4a6c091 to drop DB constraint, allowing column to reference either session type
- Add 400ms debounce on AI session search input in SessionHistoryPage (aiSearchInput state + useRef timeout pattern)
- Show friendly 503 error message in RichTextInput upload error handler (both initial upload and retry paths)
- Add overflow-x-auto to FlowPilotAnalyticsPage tab bar container

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 04:06:41 +00:00
e356103408 feat(search): add semantic similar session matching via Voyage AI embeddings
Adds vector-based similar session discovery using the existing Voyage AI
embedding infrastructure and pgvector cosine similarity search.

- New AISessionEmbedding model with vector(1024) column
- session_embedding_service: generate + upsert embeddings, find similar sessions
- Embeddings generated on session create (from problem_summary/domain) and
  updated on resolve (adds resolution_summary)
- GET /ai-sessions/{id}/similar endpoint returns top-N similar sessions
- Migration a7c9e3b1f402 creates ai_session_embeddings table

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 03:48:09 +00:00
ce68fa84ca feat(search): add PostgreSQL FTS on AI sessions with Command Palette integration
- Migration: add generated tsvector column + GIN index on ai_sessions (problem_summary, resolution_summary, escalation_reason, problem_domain)
- Backend: wire FTS into list_sessions q param; add GET /ai-sessions/search endpoint returning AISessionSearchResult (registered before /{session_id} to avoid UUID routing conflict)
- Frontend: add AISessionSearchResult type, aiSessionsApi.search() method, and Command Palette group "FlowPilot Sessions" using Zap icon navigating to /pilot/:id

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 03:42:01 +00:00
c3afc7a059 feat(search): add structured filters to AI session list endpoint and frontend
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 03:34:54 +00:00
ce118b51d8 fix(flowpilot): fix 4 Phase 2 escalation bugs + update Tailwind version in CLAUDE.md
- Fix escalation status mismatch: hook set 'escalated' but backend returns
  'requesting_escalation'
- Fix list_sessions to include sessions picked up by Engineer B via
  escalation_package->>'picked_up_by' JSONB query
- Fix sidebar escalation icon color: was Tailwind class 'text-amber-400'
  passed to style={{color}}, now hex '#fbbf24'
- Replace window.location.reload() after ticket linking with
  onReloadSession callback to preserve session state
- Update CLAUDE.md: Tailwind CSS v3 → v4 (@tailwindcss/vite, CSS-only config)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 03:10:11 +00:00
bbe590bfec feat(ai-session): add Phase 2 PSA integration, escalation handoff, and session management
Phase 2 of the FlowPilot-First Pivot connecting AI sessions to ConnectWise PSA:

Slice 1 — PSA Ticket Intake:
- FlowPilotEngine accepts psa_ticket intake with graceful CW API fallback
- Ticket picker on intake screen (refactored TicketPickerModal for dual-mode)
- Ticket context card in session sidebar

Slice 2 — Auto Documentation Push:
- PSA documentation service with resolution/escalation note formatting
- Time entry creation via new ConnectWise provider method
- Automatic retry scheduler (APScheduler, 5min interval, 3 retries)
- PSA push status indicators in frontend with manual retry button
- Member mapping warning when CW member not mapped

Slice 3 — Session Pause/Resume & Escalation Handoff:
- Pause/resume endpoints for same-engineer session bookmarking
- Escalation flow: requesting_escalation status, self-escalation blocked
- Enhanced escalation package with LLM-generated hypotheses/suggestions
- Pickup endpoint with continue/fresh resume modes and briefing step
- Escalation queue (sidebar nav + dedicated page)
- SessionBriefing component with continue/fresh choice UI
- EscalateModal with PSA-aware button text

Slice 4 — Mid-Session Ticket Linking:
- Link ticket retroactively with context injection into system prompt
- Link Ticket button in session sidebar

Slice 5 — FlowPilot PSA Settings:
- Settings tab on IntegrationsPage with 7 configurable options
- Stored as flowpilot_settings JSONB on PsaConnection

Database: 2 migrations (flowpilot_settings, psa_post_log changes, status constraint)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 01:30:05 +00:00
5494816b06 feat(ai-session): add FlowPilot AI-powered troubleshooting sessions
Implements Phase 1 of the FlowPilot-First pivot — the core AI session
experience where engineers describe a problem and FlowPilot guides them
through structured diagnosis with selectable options, free-text escape
hatches, and auto-generated documentation on resolution.

Backend: AISession + AISessionStep models, FlowPilot Engine (LLM
orchestration with structured JSON output), Flow Matching Engine v1
(semantic + keyword + recency scoring), 8 API endpoints with auth,
rate limiting, and AI quota enforcement.

Frontend: Intake screen, conversational session view with sidebar,
step cards with options/actions/resolution suggestions, resolve/escalate
modals, documentation view with rating, session history integration,
and /pilot route with sidebar navigation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 14:27:36 +00:00