# ----------------------------------------------------------------------------
#
#  Welcome to Baml! To use this generated code, please run the following:
#
#  $ pip install baml
#
# ----------------------------------------------------------------------------

# This file was generated by BAML: please do not edit it. Instead, edit the
# BAML files and re-generate this code using: baml-cli generate
# baml-cli is available with the baml package.

import typing
import typing_extensions
from pydantic import BaseModel, ConfigDict, Field

import baml_py

from . import types

StreamStateValueT = typing.TypeVar('StreamStateValueT')
class StreamState(BaseModel, typing.Generic[StreamStateValueT]):
    value: StreamStateValueT
    state: typing_extensions.Literal["Pending", "Incomplete", "Complete"]
# #########################################################################
# Generated classes (168)
# #########################################################################

class AICommandHistoryItem(BaseModel):
    # A single AI command history entry
    id: typing.Optional[str] = None
    command: typing.Optional[str] = None
    commandType: typing.Optional[types.AICommandType] = None
    originalContent: typing.Optional[str] = None
    editedContent: typing.Optional[str] = None
    section: typing.Optional[str] = None
    applied: typing.Optional[bool] = None
    explanation: typing.Optional[str] = None
    createdAt: typing.Optional[str] = None

class AICommandRequest(BaseModel):
    # Request to execute an AI command
    contentId: typing.Optional[str] = None
    section: typing.Optional[str] = None
    command: typing.Optional[str] = None
    currentContent: typing.Optional[str] = None
    commandType: typing.Optional[types.AICommandType] = None

class AICommandResult(BaseModel):
    # Response from executing an AI command
    editedContent: typing.Optional[str] = None
    explanation: typing.Optional[str] = None
    appliedChange: typing.Optional[str] = None
    commandId: typing.Optional[str] = None

class AccordionGroup(BaseModel):
    # Accordion group configuration
    id: typing.Optional[str] = None
    sections: typing.List["AccordionSection"]
    allowMultipleExpanded: typing.Optional[bool] = None
    defaultExpandedIds: typing.List[str]

class AccordionSection(BaseModel):
    # Accordion section for expandable UI components
    id: typing.Optional[str] = None
    title: typing.Optional[str] = None
    summary: typing.Optional[str] = None
    level: typing.Optional[int] = None
    expanded: typing.Optional[bool] = None
    children: typing.Optional[typing.List["AccordionSection"]] = None

class ActionError(BaseModel):
    code: typing.Optional[str] = None
    message: typing.Optional[str] = None
    retryable: typing.Optional[bool] = None
    details: typing.Dict[str, str]

class ActionEventPayload(BaseModel):
    # Payload for ACTION_* events
    actionId: typing.Optional[str] = None
    tool: typing.Optional[str] = None
    status: typing.Optional[str] = None
    parameters: typing.Dict[str, str]
    result: typing.Optional[typing.Dict[str, str]] = None
    error: typing.Optional[typing.Dict[str, str]] = None

class ActionItem(BaseModel):
    # An action item or invitation given to client
    id: typing.Optional[str] = None
    action: typing.Optional[str] = None
    specificity: typing.Optional[types.ActionSpecificity] = None
    details: typing.Optional[str] = None
    dueDate: typing.Optional[str] = None
    completed: typing.Optional[bool] = None

class ActionOutput(BaseModel):
    type: typing.Optional[str] = None
    text: typing.Optional[str] = None
    structured: typing.Dict[str, str]
    preview: typing.Optional[str] = None

class ActionRequest(BaseModel):
    conversationId: typing.Optional[str] = None
    tool: typing.Optional[types.ToolName] = None
    parameters: typing.Dict[str, str]
    context: typing.Optional["PageContext"] = None
    confirmed: typing.Optional[bool] = None

class ActionResponse(BaseModel):
    success: typing.Optional[bool] = None
    actionId: typing.Optional[str] = None
    tool: typing.Optional[types.ToolName] = None
    output: typing.Optional["ActionOutput"] = None
    error: typing.Optional["ActionError"] = None
    appliedChanges: typing.List[str]
    followUpMessage: typing.Optional[str] = None
    suggestedNextActions: typing.List["SuggestedAction"]

class AiTimingSuggestion(BaseModel):
    # Response from AI timing suggestion
    suggestedTime: typing.Optional[str] = None
    reason: typing.Optional[str] = None
    confidence: typing.Optional[float] = None
    alternativeTimes: typing.List[str]

class AiTimingSuggestionRequest(BaseModel):
    # Request for AI timing suggestion
    clientId: typing.Optional[int] = None
    messageType: typing.Optional[str] = None
    preferredTimeRange: typing.Optional[str] = None

class AuthVerifyResponse(BaseModel):
    authenticated: typing.Optional[bool] = None
    userId: typing.Optional[int] = None
    username: typing.Optional[str] = None
    email: typing.Optional[str] = None
    firstName: typing.Optional[str] = None
    lastName: typing.Optional[str] = None
    organizationId: typing.Optional[int] = None
    permissions: typing.List[str]

class BetweenSessionEvent(BaseModel):
    # Event from between sessions
    id: typing.Optional[str] = None
    type: typing.Optional[types.BetweenSessionEventType] = None
    summary: typing.Optional[str] = None
    sentiment: typing.Optional[types.Sentiment] = None
    timestamp: typing.Optional[str] = None

class CardAction(BaseModel):
    # Card action button
    id: typing.Optional[str] = None
    label: typing.Optional[str] = None
    icon: typing.Optional[str] = None
    variant: typing.Optional[types.ActionVariant] = None
    disabled: typing.Optional[bool] = None

class CardData(BaseModel):
    # Card component data
    id: typing.Optional[str] = None
    title: typing.Optional[str] = None
    subtitle: typing.Optional[str] = None
    description: typing.Optional[str] = None
    icon: typing.Optional[str] = None
    badge: typing.Optional[str] = None
    badgeVariant: typing.Optional[types.BadgeVariant] = None
    actions: typing.Optional[typing.List["CardAction"]] = None

class ChatMessage(BaseModel):
    # Single chat message
    role: typing.Optional[types.MessageRole] = None
    content: typing.Optional[str] = None
    timestamp: typing.Optional[str] = None

class ChatRequest(BaseModel):
    # Chat request from extension to backend
    message: typing.Optional[str] = None
    context: typing.Optional["PageContext"] = None
    conversationHistory: typing.Optional[typing.List["ChatMessage"]] = None
    conversationId: typing.Optional[str] = None

class ChatResponse(BaseModel):
    # Chat response from backend to extension
    message: typing.Optional[str] = None
    conversationId: typing.Optional[str] = None
    suggestedActions: typing.List["SuggestedAction"]
    context: typing.Optional["ResolvedContext"] = None
    frontendCommands: typing.Optional[typing.List["FrontendCommand"]] = None

class ClientContext(BaseModel):
    id: typing.Optional[int] = None
    name: typing.Optional[str] = None
    email: typing.Optional[str] = None
    phone: typing.Optional[str] = None
    goals: typing.List[str]
    recentNotes: typing.Optional[str] = None
    lastSessionDate: typing.Optional[str] = None
    nextSessionDate: typing.Optional[str] = None
    totalSessions: typing.Optional[int] = None

class ClientGoal(BaseModel):
    # A client goal
    id: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    title: typing.Optional[str] = None
    description: typing.Optional[str] = None
    category: typing.Optional[types.GoalCategory] = None
    status: typing.Optional[types.GoalStatus] = None
    progress: typing.Optional[int] = None
    targetDate: typing.Optional[str] = None
    completedAt: typing.Optional[str] = None
    createdAt: typing.Optional[str] = None
    updatedAt: typing.Optional[str] = None

class ClientList(BaseModel):
    # List of clients with pagination
    items: typing.List["ClientSummary"]
    total: typing.Optional[int] = None
    page: typing.Optional[int] = None
    pageSize: typing.Optional[int] = None

class ClientNote(BaseModel):
    # Private coach notes about a client
    id: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    content: typing.Optional[str] = None
    createdAt: typing.Optional[str] = None
    updatedAt: typing.Optional[str] = None

class ClientNoteList(BaseModel):
    # List of client notes
    items: typing.List["ClientNote"]
    total: typing.Optional[int] = None

class ClientProfile(BaseModel):
    # Full client profile
    id: typing.Optional[int] = None
    name: typing.Optional[str] = None
    email: typing.Optional[str] = None
    phone: typing.Optional[str] = None
    company: typing.Optional[str] = None
    title: typing.Optional[str] = None
    bio: typing.Optional[str] = None
    values: typing.List[str]
    vision: typing.Optional[str] = None
    overarchingGoals: typing.List[str]
    totalSessions: typing.Optional[int] = None
    completedGoals: typing.Optional[int] = None
    activeGoals: typing.Optional[int] = None
    pendingActions: typing.Optional[int] = None
    lastSessionDate: typing.Optional[str] = None
    nextSessionDate: typing.Optional[str] = None
    coachingStartDate: typing.Optional[str] = None

class ClientStats(BaseModel):
    # Client engagement statistics
    clientId: typing.Optional[int] = None
    totalSessions: typing.Optional[int] = None
    averageSessionDuration: typing.Optional[int] = None
    completedGoals: typing.Optional[int] = None
    activeGoals: typing.Optional[int] = None
    completedActions: typing.Optional[int] = None
    pendingActions: typing.Optional[int] = None
    averageMoodRating: typing.Optional[float] = None
    sessionFrequency: typing.Optional[float] = None
    coachingDurationMonths: typing.Optional[int] = None

class ClientSummary(BaseModel):
    # Lightweight client summary for list views
    id: typing.Optional[int] = None
    name: typing.Optional[str] = None
    email: typing.Optional[str] = None
    company: typing.Optional[str] = None
    totalSessions: typing.Optional[int] = None
    lastSessionDate: typing.Optional[str] = None
    nextSessionDate: typing.Optional[str] = None

class CoacheePreSessionInput(BaseModel):
    # Coachee's pre-session input
    submitted: typing.Optional[bool] = None
    submittedAt: typing.Optional[str] = None
    topics: typing.Optional[typing.List[str]] = None
    updates: typing.Optional[str] = None
    questions: typing.Optional[typing.List[str]] = None
    moodRating: typing.Optional[int] = None

class CommandCenterData(BaseModel):
    # Grouped command center response
    focusNow: typing.List["CommandCenterItem"]
    soon: typing.List["CommandCenterItem"]
    later: typing.List["CommandCenterItem"]
    lastUpdated: typing.Optional[str] = None

class CommandCenterEventPayload(BaseModel):
    # Payload for COMMAND_CENTER_UPDATED event
    focusNowCount: typing.Optional[int] = None
    soonCount: typing.Optional[int] = None
    laterCount: typing.Optional[int] = None
    lastUpdated: typing.Optional[str] = None

class CommandCenterItem(BaseModel):
    # A single command center item
    id: typing.Optional[str] = None
    type: typing.Optional[types.CommandItemType] = None
    clientId: typing.Optional[int] = None
    clientName: typing.Optional[str] = None
    priority: typing.Optional[types.Priority] = None
    priorityReason: typing.Optional[str] = None
    action: typing.Optional[str] = None
    dueDate: typing.Optional[str] = None
    crossDomainContext: typing.Optional[str] = None
    sessionId: typing.Optional[str] = None
    createdAt: typing.Optional[str] = None

class Commitment(BaseModel):
    # A commitment from a previous session
    id: typing.Optional[str] = None
    description: typing.Optional[str] = None
    status: typing.Optional[types.CommitmentStatus] = None
    source: typing.Optional[types.CommitmentSource] = None
    sessionId: typing.Optional[str] = None
    createdAt: typing.Optional[str] = None

class ConnectionPayload(BaseModel):
    # Payload for CONNECTION_ESTABLISHED event
    connectionId: typing.Optional[str] = None
    userId: typing.Optional[int] = None
    capabilities: typing.List[str]

class ContextChangedPayload(BaseModel):
    # Payload for CONTEXT_CHANGED and STATE_UPDATED events
    page: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    clientName: typing.Optional[str] = None
    sessionId: typing.Optional[str] = None
    sessionDate: typing.Optional[str] = None
    availableActions: typing.List[str]
    source: typing.Optional[str] = None

class CorrectionPair(BaseModel):
    # Correction pair for batch analysis
    originalContent: typing.Optional[str] = None
    editedContent: typing.Optional[str] = None
    editType: typing.Optional[types.EditType] = None
    coachFeedback: typing.Optional[types.CoachFeedback] = None
    contentType: typing.Optional[types.VoiceContentType] = None
    timestamp: typing.Optional[str] = None

class CreateGoalRequest(BaseModel):
    # Request to create a new goal
    title: typing.Optional[str] = None
    description: typing.Optional[str] = None
    category: typing.Optional[types.GoalCategory] = None
    targetDate: typing.Optional[str] = None

class CreateResourceRequest(BaseModel):
    # Request to create a new resource
    type: typing.Optional[types.ResourceType] = None
    title: typing.Optional[str] = None
    description: typing.Optional[str] = None
    externalUrl: typing.Optional[str] = None
    tags: typing.List[str]

class CreateScheduledMessageRequest(BaseModel):
    # Request to create a scheduled message
    clientId: typing.Optional[int] = None
    sessionId: typing.Optional[str] = None
    templateId: typing.Optional[str] = None
    channel: typing.Optional[types.MessageChannel] = None
    subject: typing.Optional[str] = None
    body: typing.Optional[str] = None
    scheduledFor: typing.Optional[str] = None
    useAiSuggestion: typing.Optional[bool] = None
    autoApprove: typing.Optional[bool] = None
    transparencyIndicator: typing.Optional[str] = None
    transparencyDisplayName: typing.Optional[str] = None

class CurrentRead(BaseModel):
    # AI's current read/assessment of client
    assessment: typing.Optional[str] = None
    confidence: typing.Optional[float] = None
    lastUpdated: typing.Optional[str] = None

class DashboardData(BaseModel):
    # Full dashboard data response
    upcomingSessions: typing.List["SessionPrepStatus"]
    recentClients: typing.List["RecentClient"]
    pendingActionsCount: typing.Optional[int] = None
    todaySessionsCount: typing.Optional[int] = None
    weekSessionsCount: typing.Optional[int] = None
    lastUpdated: typing.Optional[str] = None

class DashboardPreferences(BaseModel):
    # Dashboard layout preferences
    coachId: typing.Optional[int] = None
    sections: typing.List["DashboardSection"]
    defaultView: typing.Optional[types.DashboardView] = None
    refreshInterval: typing.Optional[int] = None

class DashboardSection(BaseModel):
    # Dashboard section configuration
    id: typing.Optional[str] = None
    title: typing.Optional[str] = None
    priority: typing.Optional[int] = None
    visible: typing.Optional[bool] = None
    collapsed: typing.Optional[bool] = None

class DisclosureConfig(BaseModel):
    # Disclosure configuration
    defaultLevel: typing.Optional[types.DisclosureLevel] = None
    allowToggle: typing.Optional[bool] = None
    expandByDefault: typing.Optional[bool] = None

class EmptyState(BaseModel):
    # Empty state configuration
    icon: typing.Optional[str] = None
    title: typing.Optional[str] = None
    description: typing.Optional[str] = None
    actionLabel: typing.Optional[str] = None
    actionHref: typing.Optional[str] = None

class ErrorPayload(BaseModel):
    # Payload for ERROR event
    code: typing.Optional[str] = None
    message: typing.Optional[str] = None
    details: typing.Dict[str, str]
    retryable: typing.Optional[bool] = None

class EventEnvelope(BaseModel):
    # Event envelope - all WebSocket messages MUST be wrapped in this
    type: typing.Optional[types.EventType] = None
    meta: typing.Optional["EventMeta"] = None
    payload: typing.Dict[str, str]

class EventMeta(BaseModel):
    # Metadata for every event (required for debugging/replay)
    timestamp: typing.Optional[str] = None
    correlationId: typing.Optional[str] = None
    contractsVersion: typing.Optional[str] = None
    actorId: typing.Optional[int] = None
    requestId: typing.Optional[str] = None

class FinalizeNotesRequest(BaseModel):
    # Request to finalize/send session notes
    notesId: typing.Optional[str] = None
    sendToClient: typing.Optional[bool] = None
    personalizedMessage: typing.Optional[str] = None

class FinalizeNotesResponse(BaseModel):
    # Response from finalizing notes
    success: typing.Optional[bool] = None
    status: typing.Optional[types.SessionNotesStatus] = None
    sentAt: typing.Optional[str] = None
    error: typing.Optional[str] = None

class FrontendActionResult(BaseModel):
    # Result reported back by frontend
    actionId: typing.Optional[str] = None
    status: typing.Optional[types.FrontendActionStatus] = None
    success: typing.Optional[bool] = None
    message: typing.Optional[str] = None
    error: typing.Optional["ActionError"] = None
    executedAt: typing.Optional[str] = None

class FrontendCommand(BaseModel):
    # Command sent to frontend via WebSocket
    actionId: typing.Optional[str] = None
    tool: typing.Optional[types.FrontendToolName] = None
    parameters: typing.Dict[str, str]
    timeout: typing.Optional[int] = None
    requiresConfirmation: typing.Optional[bool] = None

class FrontendCommandPayload(BaseModel):
    # Payload for FRONTEND_COMMAND event
    actionId: typing.Optional[str] = None
    tool: typing.Optional[str] = None
    parameters: typing.Dict[str, str]
    timeout: typing.Optional[int] = None
    requiresConfirmation: typing.Optional[bool] = None

class FrontendToolConfig(BaseModel):
    # Tool configuration for admin panel
    tool: typing.Optional[types.FrontendToolName] = None
    requiresConfirmation: typing.Optional[bool] = None
    defaultTimeout: typing.Optional[int] = None

class GenerateNotesRequest(BaseModel):
    # Request to generate session notes
    sessionId: typing.Optional[str] = None
    regenerate: typing.Optional[bool] = None

class GeneratePrepRequest(BaseModel):
    # Request to generate a prep document
    sessionId: typing.Optional[str] = None
    regenerate: typing.Optional[bool] = None

class GoalFilter(BaseModel):
    # Filter options for goals list
    clientId: typing.Optional[int] = None
    category: typing.Optional[types.GoalCategory] = None
    status: typing.Optional[types.GoalStatus] = None
    searchQuery: typing.Optional[str] = None

class GoalList(BaseModel):
    # List of goals with pagination
    items: typing.List["ClientGoal"]
    total: typing.Optional[int] = None
    page: typing.Optional[int] = None
    pageSize: typing.Optional[int] = None

class GoalMilestone(BaseModel):
    # Goal milestone
    id: typing.Optional[str] = None
    goalId: typing.Optional[str] = None
    title: typing.Optional[str] = None
    description: typing.Optional[str] = None
    targetDate: typing.Optional[str] = None
    completed: typing.Optional[bool] = None
    completedAt: typing.Optional[str] = None

class GoalProgressUpdate(BaseModel):
    # Goal progress update
    goalId: typing.Optional[str] = None
    progress: typing.Optional[int] = None
    note: typing.Optional[str] = None
    updatedAt: typing.Optional[str] = None

class GoalResponse(BaseModel):
    # Response containing goal data
    success: typing.Optional[bool] = None
    goal: typing.Optional["ClientGoal"] = None
    error: typing.Optional[str] = None

class GroupedList(BaseModel):
    # Grouped list data
    id: typing.Optional[str] = None
    groups: typing.List["ListGroup"]

class HeartbeatPayload(BaseModel):
    # Payload for HEARTBEAT event
    serverTime: typing.Optional[str] = None
    connectionAge: typing.Optional[int] = None

class InquiriesSection(BaseModel):
    # Inquiries section with questions
    id: typing.Optional[str] = None
    summary: typing.Optional[str] = None
    keyPoints: typing.List["KeyPoint"]
    expanded: typing.Optional[bool] = None
    questions: typing.List["InquiryQuestion"]

class InquiryQuestion(BaseModel):
    # A powerful question explored in the session
    id: typing.Optional[str] = None
    question: typing.Optional[str] = None
    category: typing.Optional[types.InquiryCategory] = None
    answered: typing.Optional[bool] = None

class IntegrationConfig(BaseModel):
    # Configuration for a single integration
    id: typing.Optional[str] = None
    coachId: typing.Optional[int] = None
    type: typing.Optional[types.IntegrationType] = None
    status: typing.Optional[types.IntegrationStatus] = None
    displayName: typing.Optional[str] = None
    accountEmail: typing.Optional[str] = None
    connectedAt: typing.Optional[str] = None
    lastSyncAt: typing.Optional[str] = None
    settings: typing.Dict[str, str]
    error: typing.Optional[str] = None

class IntegrationConnectRequest(BaseModel):
    # Request to initiate an integration connection
    type: typing.Optional[types.IntegrationType] = None
    redirectUrl: typing.Optional[str] = None

class IntegrationConnectResponse(BaseModel):
    # Response with OAuth URL
    success: typing.Optional[bool] = None
    authUrl: typing.Optional[str] = None
    error: typing.Optional[str] = None

class IntegrationDisconnectRequest(BaseModel):
    # Request to disconnect an integration
    integrationId: typing.Optional[str] = None

class IntegrationList(BaseModel):
    # List of coach's integrations
    integrations: typing.List["IntegrationConfig"]
    availableTypes: typing.List[types.IntegrationType]

class InvitationsSection(BaseModel):
    # Invitations section with action items
    id: typing.Optional[str] = None
    summary: typing.Optional[str] = None
    keyPoints: typing.List["KeyPoint"]
    expanded: typing.Optional[bool] = None
    actionItems: typing.List["ActionItem"]

class KeyPoint(BaseModel):
    # A key point within a section
    id: typing.Optional[str] = None
    text: typing.Optional[str] = None
    detail: typing.Optional[str] = None
    quote: typing.Optional["Quote"] = None

class LastSessionRecap(BaseModel):
    # Recap of previous session
    themes: typing.List[str]
    breakthroughs: typing.List[str]
    emotionalMoments: typing.List[str]
    summary: typing.Optional[str] = None
    sessionDate: typing.Optional[str] = None

class LifeContextItem(BaseModel):
    # Recent life context item
    area: typing.Optional[types.LifeContextArea] = None
    summary: typing.Optional[str] = None
    source: typing.Optional[str] = None
    updatedAt: typing.Optional[str] = None

class ListGroup(BaseModel):
    # A group within a list
    id: typing.Optional[str] = None
    title: typing.Optional[str] = None
    items: typing.List["ListItem"]
    collapsible: typing.Optional[bool] = None
    collapsed: typing.Optional[bool] = None

class ListItem(BaseModel):
    # List item data
    id: typing.Optional[str] = None
    primary: typing.Optional[str] = None
    secondary: typing.Optional[str] = None
    meta: typing.Optional[str] = None
    avatar: typing.Optional[str] = None
    selected: typing.Optional[bool] = None
    disabled: typing.Optional[bool] = None

class LoadingState(BaseModel):
    # Loading state configuration
    message: typing.Optional[str] = None
    showProgress: typing.Optional[bool] = None
    progress: typing.Optional[int] = None

class MessagePayload(BaseModel):
    # Payload for MESSAGE_RECEIVED and MESSAGE_SENT events
    conversationId: typing.Optional[str] = None
    role: typing.Optional[str] = None
    content: typing.Optional[str] = None
    timestamp: typing.Optional[str] = None

class NavigationOption(BaseModel):
    # Navigation option for available routes/actions
    label: typing.Optional[str] = None
    route: typing.Optional[str] = None
    icon: typing.Optional[str] = None

class NextSection(BaseModel):
    # Next section with focus areas
    id: typing.Optional[str] = None
    summary: typing.Optional[str] = None
    keyPoints: typing.List["KeyPoint"]
    expanded: typing.Optional[bool] = None
    focusAreas: typing.List[str]
    nextSessionDate: typing.Optional[str] = None

class NorthStarReminder(BaseModel):
    # Client's articulated purpose and direction
    values: typing.List[str]
    vision: typing.Optional[str] = None
    overarchingGoals: typing.List[str]

class ObservationEntry(BaseModel):
    # A single observation entry
    id: typing.Optional[str] = None
    type: typing.Optional[types.ObservationType] = None
    description: typing.Optional[str] = None
    evidence: typing.List[str]
    confidence: typing.Optional[float] = None
    detectedAt: typing.Optional[str] = None
    dismissed: typing.Optional[bool] = None
    dismissedBy: typing.Optional[str] = None
    dismissedAt: typing.Optional[str] = None

class ObservationPayload(BaseModel):
    # Payload for OBSERVATION_DETECTED event
    observationId: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    type: typing.Optional[str] = None
    description: typing.Optional[str] = None
    confidence: typing.Optional[float] = None

class OnboardingEventPayload(BaseModel):
    # Payload for ONBOARDING_* events
    coachId: typing.Optional[int] = None
    phase: typing.Optional[str] = None
    previousPhase: typing.Optional[str] = None
    overallProgress: typing.Optional[float] = None
    action: typing.Optional[str] = None
    timestamp: typing.Optional[str] = None

class OnboardingPhaseProgress(BaseModel):
    # Progress for a single onboarding phase
    phase: typing.Optional[types.OnboardingPhase] = None
    status: typing.Optional[types.PhaseStatus] = None
    startedAt: typing.Optional[str] = None
    completedAt: typing.Optional[str] = None
    skipped: typing.Optional[bool] = None
    skipReason: typing.Optional[str] = None
    data: typing.Dict[str, str]

class OnboardingProgress(BaseModel):
    # Overall onboarding progress
    coachId: typing.Optional[int] = None
    currentPhase: typing.Optional[types.OnboardingPhase] = None
    phases: typing.List["OnboardingPhaseProgress"]
    overallProgress: typing.Optional[float] = None
    startedAt: typing.Optional[str] = None
    completedAt: typing.Optional[str] = None
    estimatedTimeRemaining: typing.Optional[int] = None
    canSkipCurrent: typing.Optional[bool] = None

class OnboardingUpdateRequest(BaseModel):
    # Request to update onboarding progress
    phase: typing.Optional[types.OnboardingPhase] = None
    action: typing.Optional[types.OnboardingAction] = None
    data: typing.Dict[str, str]

class OnboardingUpdateResponse(BaseModel):
    # Response from onboarding update
    success: typing.Optional[bool] = None
    progress: typing.Optional["OnboardingProgress"] = None
    nextPhase: typing.Optional[types.OnboardingPhase] = None
    error: typing.Optional[str] = None

class PageContext(BaseModel):
    # Page context from extension content script
    url: typing.Optional[str] = None
    route: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    sessionId: typing.Optional[str] = None
    pageTitle: typing.Optional[str] = None
    pageData: typing.Dict[str, str]

class PatternEvidence(BaseModel):
    # Evidence supporting a pattern
    sessionId: typing.Optional[str] = None
    sessionDate: typing.Optional[str] = None
    quote: typing.Optional[str] = None
    timestamp: typing.Optional[str] = None

class PatternIntelligence(BaseModel):
    # Detected pattern or theme
    id: typing.Optional[str] = None
    pattern: typing.Optional[str] = None
    frequency: typing.Optional[int] = None
    trend: typing.Optional[types.PatternTrend] = None
    evidence: typing.List["PatternEvidence"]
    lastOccurrence: typing.Optional[str] = None

class PrepDocument(BaseModel):
    # Full T-15 prep document with typed sections
    id: typing.Optional[str] = None
    sessionId: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    clientName: typing.Optional[str] = None
    sessionTitle: typing.Optional[str] = None
    sessionDateTime: typing.Optional[str] = None
    northStarReminder: typing.Optional["NorthStarReminder"] = None
    lastSessionRecap: typing.Optional["LastSessionRecap"] = None
    commitments: typing.List["Commitment"]
    lifeContext: typing.List["LifeContextItem"]
    patternIntelligence: typing.List["PatternIntelligence"]
    suggestedOpeners: typing.List["SuggestedOpener"]
    privateCoachNotes: typing.Optional[str] = None
    betweenSessionIntelligence: typing.List["BetweenSessionEvent"]
    coacheePreSessionInput: typing.Optional["CoacheePreSessionInput"] = None
    generatedAt: typing.Optional[str] = None
    status: typing.Optional[types.PrepStatus] = None

class PrepList(BaseModel):
    # List of preps with pagination
    items: typing.List["PrepSummary"]
    total: typing.Optional[int] = None
    page: typing.Optional[int] = None
    pageSize: typing.Optional[int] = None

class PrepNotificationPayload(BaseModel):
    # Payload for PREP_NOTIFICATION, PREP_READY, PREP_VIEWED events
    sessionId: typing.Optional[str] = None
    clientName: typing.Optional[str] = None
    sessionDateTime: typing.Optional[str] = None
    prepStatus: typing.Optional[str] = None
    minutesUntilSession: typing.Optional[int] = None

class PrepResponse(BaseModel):
    # Response containing generated prep
    success: typing.Optional[bool] = None
    document: typing.Optional["PrepDocument"] = None
    error: typing.Optional[str] = None
    warnings: typing.List[str]
    generationTimeMs: typing.Optional[int] = None

class PrepSummary(BaseModel):
    # Lightweight summary for list views
    id: typing.Optional[str] = None
    sessionId: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    clientName: typing.Optional[str] = None
    sessionDateTime: typing.Optional[str] = None
    status: typing.Optional[types.PrepStatus] = None
    generatedAt: typing.Optional[str] = None

class PrepTemplate(BaseModel):
    # Template for coach's prep preferences
    id: typing.Optional[str] = None
    coachId: typing.Optional[int] = None
    name: typing.Optional[str] = None
    sectionsEnabled: typing.List[types.PrepSectionId]
    defaultExpanded: typing.List[types.PrepSectionId]

class PriorityItemPayload(BaseModel):
    # Payload for PRIORITY_ITEM_* events
    itemId: typing.Optional[str] = None
    type: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    clientName: typing.Optional[str] = None
    priority: typing.Optional[str] = None
    action: typing.Optional[str] = None

class PrivateIntelligence(BaseModel):
    # Complete private intelligence for a client
    clientId: typing.Optional[int] = None
    currentRead: typing.Optional["CurrentRead"] = None
    observations: typing.List["ObservationEntry"]
    coachPrivateNotes: typing.Optional[str] = None
    lastUpdated: typing.Optional[str] = None

class ProfileScrapeRequest(BaseModel):
    # Request to scrape coach profile
    urls: typing.List[str]
    linkedInUrl: typing.Optional[str] = None
    websiteUrl: typing.Optional[str] = None

class ProfileScrapeResponse(BaseModel):
    # Response from profile scraping
    success: typing.Optional[bool] = None
    profiles: typing.List["ScrapedCoachProfile"]
    mergedProfile: typing.Optional["ScrapedCoachProfile"] = None
    error: typing.Optional[str] = None

class Quote(BaseModel):
    # A quote from the session
    text: typing.Optional[str] = None
    timestamp: typing.Optional[str] = None
    videoLink: typing.Optional[str] = None

class RecentClient(BaseModel):
    # Recent client for dashboard display
    id: typing.Optional[int] = None
    name: typing.Optional[str] = None
    firstName: typing.Optional[str] = None
    lastName: typing.Optional[str] = None
    avatarUrl: typing.Optional[str] = None
    lastSessionDate: typing.Optional[str] = None
    nextSessionDate: typing.Optional[str] = None
    recentActivity: typing.Optional[str] = None
    hasPendingPrep: typing.Optional[bool] = None
    pendingActionsCount: typing.Optional[int] = None
    pendingMessages: typing.Optional[int] = None

class ResolvedContext(BaseModel):
    # Resolved context (what the system understood from PageContext)
    clientId: typing.Optional[int] = None
    clientName: typing.Optional[str] = None
    sessionId: typing.Optional[str] = None
    sessionDate: typing.Optional[str] = None
    confidence: typing.Optional[float] = None

class ResourceEventPayload(BaseModel):
    # Payload for RESOURCE_* events
    resourceId: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    type: typing.Optional[str] = None
    title: typing.Optional[str] = None
    action: typing.Optional[str] = None

class ResourceItem(BaseModel):
    # A single resource item
    id: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    coachId: typing.Optional[int] = None
    type: typing.Optional[types.ResourceType] = None
    title: typing.Optional[str] = None
    description: typing.Optional[str] = None
    fileUrl: typing.Optional[str] = None
    externalUrl: typing.Optional[str] = None
    thumbnailUrl: typing.Optional[str] = None
    tags: typing.List[str]
    metadata: typing.Optional["ResourceMetadata"] = None
    createdAt: typing.Optional[str] = None
    updatedAt: typing.Optional[str] = None

class ResourceLink(BaseModel):
    # A resource link shared in the session
    id: typing.Optional[str] = None
    title: typing.Optional[str] = None
    url: typing.Optional[str] = None
    type: typing.Optional[types.ResourceLinkType] = None
    description: typing.Optional[str] = None

class ResourceListData(BaseModel):
    # Paginated resource list
    items: typing.List["ResourceItem"]
    total: typing.Optional[int] = None
    page: typing.Optional[int] = None
    pageSize: typing.Optional[int] = None
    nextPage: typing.Optional[int] = None

class ResourceMetadata(BaseModel):
    # Metadata for a resource item
    fileSize: typing.Optional[int] = None
    mimeType: typing.Optional[str] = None
    originalName: typing.Optional[str] = None
    linkTitle: typing.Optional[str] = None
    linkDescription: typing.Optional[str] = None
    linkImage: typing.Optional[str] = None

class ResourcesSection(BaseModel):
    # Resources section with links
    id: typing.Optional[str] = None
    summary: typing.Optional[str] = None
    keyPoints: typing.List["KeyPoint"]
    expanded: typing.Optional[bool] = None
    links: typing.List["ResourceLink"]

class ScheduledMessage(BaseModel):
    # Full representation of a scheduled message (API response)
    id: typing.Optional[str] = None
    coachId: typing.Optional[int] = None
    coachName: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    clientName: typing.Optional[str] = None
    clientEmail: typing.Optional[str] = None
    sessionId: typing.Optional[str] = None
    sessionDate: typing.Optional[str] = None
    templateUsed: typing.Optional[str] = None
    channel: typing.Optional[types.MessageChannel] = None
    subject: typing.Optional[str] = None
    body: typing.Optional[str] = None
    scheduledFor: typing.Optional[str] = None
    aiSuggestedTime: typing.Optional[str] = None
    aiSuggestionReason: typing.Optional[str] = None
    status: typing.Optional[types.MessageStatus] = None
    approvedAt: typing.Optional[str] = None
    reviewedAt: typing.Optional[str] = None
    sentAt: typing.Optional[str] = None
    cancelledAt: typing.Optional[str] = None
    cancellationReason: typing.Optional[str] = None
    deliveryAttempts: typing.Optional[int] = None
    lastDeliveryError: typing.Optional[str] = None
    externalMessageId: typing.Optional[str] = None
    transparencyIndicator: typing.Optional[str] = None
    transparencyDisplayName: typing.Optional[str] = None
    canEdit: typing.Optional[bool] = None
    canCancel: typing.Optional[bool] = None
    canSend: typing.Optional[bool] = None
    createdAt: typing.Optional[str] = None
    updatedAt: typing.Optional[str] = None

class ScheduledMessageAuditEntry(BaseModel):
    # Audit log entry for message state changes
    id: typing.Optional[str] = None
    messageId: typing.Optional[str] = None
    action: typing.Optional[str] = None
    actorId: typing.Optional[int] = None
    actorName: typing.Optional[str] = None
    details: typing.Dict[str, str]
    createdAt: typing.Optional[str] = None

class ScheduledMessageEventPayload(BaseModel):
    # Payload for SCHEDULED_MESSAGE_* events
    messageId: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    clientName: typing.Optional[str] = None
    channel: typing.Optional[str] = None
    subject: typing.Optional[str] = None
    scheduledFor: typing.Optional[str] = None
    status: typing.Optional[str] = None
    previousStatus: typing.Optional[str] = None

class ScheduledMessageFilter(BaseModel):
    # Filter parameters for listing messages
    status: typing.Optional[types.MessageStatus] = None
    channel: typing.Optional[types.MessageChannel] = None
    clientId: typing.Optional[int] = None
    sessionId: typing.Optional[str] = None
    fromDate: typing.Optional[str] = None
    toDate: typing.Optional[str] = None

class ScheduledMessageList(BaseModel):
    # Paginated list of scheduled messages
    items: typing.List["ScheduledMessage"]
    total: typing.Optional[int] = None
    page: typing.Optional[int] = None
    pageSize: typing.Optional[int] = None
    hasNext: typing.Optional[bool] = None

class ScheduledMessagePreferences(BaseModel):
    # User preferences for scheduled message handling
    preSendReviewEnabled: typing.Optional[bool] = None
    preSendReviewMinutes: typing.Optional[int] = None
    autoCancelIfClientResponds: typing.Optional[bool] = None
    defaultChannel: typing.Optional[types.MessageChannel] = None
    createdAt: typing.Optional[str] = None
    updatedAt: typing.Optional[str] = None

class ScrapedCoachProfile(BaseModel):
    # Scraped coach profile from external sources
    source: typing.Optional[str] = None
    sourceUrl: typing.Optional[str] = None
    name: typing.Optional[str] = None
    title: typing.Optional[str] = None
    bio: typing.Optional[str] = None
    certifications: typing.List[str]
    specialties: typing.List[str]
    yearsExperience: typing.Optional[int] = None
    photoUrl: typing.Optional[str] = None
    contactEmail: typing.Optional[str] = None
    scrapedAt: typing.Optional[str] = None
    confidence: typing.Optional[float] = None

class SessionContext(BaseModel):
    id: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    clientName: typing.Optional[str] = None
    scheduledAt: typing.Optional[str] = None
    status: typing.Optional[str] = None
    t15Summary: typing.Optional[str] = None
    notes: typing.Optional[str] = None
    transcript: typing.Optional[str] = None
    runningNotes: typing.Optional[str] = None

class SessionEventPayload(BaseModel):
    # Payload for SESSION_* events
    sessionId: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    clientName: typing.Optional[str] = None
    status: typing.Optional[str] = None
    scheduledAt: typing.Optional[str] = None

class SessionNoteSection(BaseModel):
    # Base structure for simple sections (recap, observations)
    id: typing.Optional[str] = None
    summary: typing.Optional[str] = None
    keyPoints: typing.List["KeyPoint"]
    expanded: typing.Optional[bool] = None

class SessionNotes(BaseModel):
    # Full session notes document with typed sections
    sessionId: typing.Optional[str] = None
    recap: typing.Optional["SessionNoteSection"] = None
    observations: typing.Optional["SessionNoteSection"] = None
    inquiries: typing.Optional["InquiriesSection"] = None
    invitations: typing.Optional["InvitationsSection"] = None
    resources: typing.Optional["ResourcesSection"] = None
    next: typing.Optional["NextSection"] = None
    voiceConfidence: typing.Optional[float] = None
    generatedAt: typing.Optional[str] = None
    lastEditedAt: typing.Optional[str] = None
    status: typing.Optional[types.SessionNotesStatus] = None

class SessionNotesEventPayload(BaseModel):
    # Payload for SESSION_NOTES_* events
    notesId: typing.Optional[str] = None
    sessionId: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    clientName: typing.Optional[str] = None
    sessionDate: typing.Optional[str] = None
    action: typing.Optional[str] = None
    status: typing.Optional[str] = None
    previousStatus: typing.Optional[str] = None
    sectionsCompleted: typing.Optional[int] = None
    totalSections: typing.Optional[int] = None

class SessionNotesFilter(BaseModel):
    # Filter options for session notes list
    clientId: typing.Optional[int] = None
    status: typing.Optional[types.SessionNotesStatus] = None
    fromDate: typing.Optional[str] = None
    toDate: typing.Optional[str] = None
    searchQuery: typing.Optional[str] = None

class SessionNotesList(BaseModel):
    # List of session notes with pagination
    items: typing.List["SessionNotesSummary"]
    total: typing.Optional[int] = None
    page: typing.Optional[int] = None
    pageSize: typing.Optional[int] = None

class SessionNotesResponse(BaseModel):
    # Response containing generated notes
    success: typing.Optional[bool] = None
    notes: typing.Optional["SessionNotes"] = None
    error: typing.Optional[str] = None
    warnings: typing.List[str]
    generationTimeMs: typing.Optional[int] = None

class SessionNotesSummary(BaseModel):
    # Lightweight summary for list views
    id: typing.Optional[str] = None
    sessionId: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    clientName: typing.Optional[str] = None
    sessionDate: typing.Optional[str] = None
    status: typing.Optional[types.SessionNotesStatus] = None
    summary: typing.Optional[str] = None
    generatedAt: typing.Optional[str] = None

class SessionPrepStatus(BaseModel):
    # Status of session preparation for dashboard display
    sessionId: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    clientName: typing.Optional[str] = None
    sessionDateTime: typing.Optional[str] = None
    sessionTitle: typing.Optional[str] = None
    prepStatus: typing.Optional[types.PrepStatusValue] = None
    timeUntilSession: typing.Optional[int] = None
    needsAttention: typing.Optional[bool] = None
    clientAvatarUrl: typing.Optional[str] = None
    meetLink: typing.Optional[str] = None

class StateHistoryEntry(BaseModel):
    # Historical state entry
    id: typing.Optional[str] = None
    userId: typing.Optional[int] = None
    page: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    sessionId: typing.Optional[str] = None
    source: typing.Optional[types.StateSource] = None
    createdAt: typing.Optional[str] = None

class StateHistoryQuery(BaseModel):
    # Request to query state history
    userId: typing.Optional[int] = None
    fromDate: typing.Optional[str] = None
    toDate: typing.Optional[str] = None
    limit: typing.Optional[int] = None

class StateUpdateRequest(BaseModel):
    # Request to update user's active state
    page: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    sessionId: typing.Optional[str] = None
    availableActions: typing.List[str]
    navigationOptions: typing.List["NavigationOption"]
    source: typing.Optional[types.StateSource] = None

class StateUpdateResponse(BaseModel):
    # Response from state update
    success: typing.Optional[bool] = None
    stateId: typing.Optional[str] = None

class StyleAnalysis(BaseModel):
    # LLM-computed style profile aggregated from correction analysis
    toneProfile: typing.Optional["ToneVector"] = None
    sentencePatterns: typing.List[str]
    transitionPhrases: typing.List[str]
    emotionalRegister: typing.Optional[str] = None
    rhetoricalPatterns: typing.List[str]
    confidence: typing.Optional[float] = None
    sampleCount: typing.Optional[int] = None
    lastUpdated: typing.Optional[str] = None

class StyleAnalysisRequest(BaseModel):
    # Request for batch style analysis
    coachId: typing.Optional[int] = None
    correctionPairs: typing.List["CorrectionPair"]
    existingProfile: typing.Optional["StyleAnalysis"] = None
    includeInsights: typing.Optional[bool] = None

class StyleAnalysisResponse(BaseModel):
    # Response from style analysis
    styleProfile: typing.Optional["StyleAnalysis"] = None
    insights: typing.Optional[typing.List["StyleInsight"]] = None
    voiceMatchConfidence: typing.Optional[float] = None
    improvementSuggestions: typing.List[str]

class StyleDashboardData(BaseModel):
    # Data for the style analysis dashboard
    profile: typing.Optional["VoiceProfileV1"] = None
    trendData: typing.List["StyleTrendPoint"]
    topInsights: typing.List["StyleInsight"]
    recentCorrections: typing.List["VoiceCorrection"]
    improvementAreas: typing.List[str]

class StyleInsight(BaseModel):
    # Human-readable insight derived from style analysis for dashboard display
    category: typing.Optional[str] = None
    insight: typing.Optional[str] = None
    evidence: typing.List[str]
    confidence: typing.Optional[float] = None

class StyleTrendPoint(BaseModel):
    # Single data point for style trend chart
    date: typing.Optional[str] = None
    voiceConfidence: typing.Optional[float] = None
    correctionsCount: typing.Optional[int] = None
    avgMatchScore: typing.Optional[float] = None

class StyleTuning(BaseModel):
    # Coach's manual style tuning adjustments
    toneAdjustments: typing.Optional["ToneVector"] = None
    addPhrases: typing.List[str]
    removePhrases: typing.List[str]
    notes: typing.Optional[str] = None

class SuggestedAction(BaseModel):
    # Suggested action (Phase 2+)
    tool: typing.Optional[types.ToolName] = None
    label: typing.Optional[str] = None
    description: typing.Optional[str] = None
    parameters: typing.Dict[str, str]
    requiresConfirmation: typing.Optional[bool] = None

class SuggestedOpener(BaseModel):
    # AI-generated conversation starter
    question: typing.Optional[str] = None
    rationale: typing.Optional[str] = None
    category: typing.Optional[types.OpenerCategory] = None

class T15PrepEventPayload(BaseModel):
    # Payload for T15_PREP_* events
    prepId: typing.Optional[str] = None
    sessionId: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    clientName: typing.Optional[str] = None
    scheduledAt: typing.Optional[str] = None
    action: typing.Optional[str] = None
    sectionsCompleted: typing.Optional[int] = None
    totalSections: typing.Optional[int] = None
    overallReadiness: typing.Optional[str] = None

class TonePreference(BaseModel):
    # Tone preference configuration
    tone: typing.Optional[str] = None
    weight: typing.Optional[float] = None

class ToneVector(BaseModel):
    # 5-dimensional tone profile for measuring communication style
# Each dimension is computed from analyzing correction patterns
    warmth: typing.Optional[float] = None
    formality: typing.Optional[float] = None
    directness: typing.Optional[float] = None
    empathy: typing.Optional[float] = None
    energy: typing.Optional[float] = None

class ToolDefinition(BaseModel):
    name: typing.Optional[types.ToolName] = None
    description: typing.Optional[str] = None
    parameters: typing.List["ToolParameter"]
    requiresConfirmation: typing.Optional[bool] = None
    outputType: typing.Optional[str] = None

class ToolParameter(BaseModel):
    name: typing.Optional[str] = None
    type: typing.Optional[str] = None
    description: typing.Optional[str] = None
    required: typing.Optional[bool] = None
    default: typing.Optional[str] = None

class TransparentMessage(BaseModel):
    # Message with transparency metadata
    content: typing.Optional[str] = None
    indicator: typing.Optional[types.TransparencyIndicator] = None
    coachName: typing.Optional[str] = None
    approvedAt: typing.Optional[str] = None

class UpdateClientProfileRequest(BaseModel):
    # Request to update client profile
    name: typing.Optional[str] = None
    email: typing.Optional[str] = None
    phone: typing.Optional[str] = None
    company: typing.Optional[str] = None
    title: typing.Optional[str] = None
    bio: typing.Optional[str] = None
    values: typing.Optional[typing.List[str]] = None
    vision: typing.Optional[str] = None
    overarchingGoals: typing.Optional[typing.List[str]] = None

class UpdateClientProfileResponse(BaseModel):
    # Response from profile update
    success: typing.Optional[bool] = None
    profile: typing.Optional["ClientProfile"] = None
    error: typing.Optional[str] = None

class UpdateGoalRequest(BaseModel):
    # Request to update an existing goal
    title: typing.Optional[str] = None
    description: typing.Optional[str] = None
    category: typing.Optional[types.GoalCategory] = None
    status: typing.Optional[types.GoalStatus] = None
    progress: typing.Optional[int] = None
    targetDate: typing.Optional[str] = None

class UpdatePreferencesRequest(BaseModel):
    # Request to update preferences
    preSendReviewEnabled: typing.Optional[bool] = None
    preSendReviewMinutes: typing.Optional[int] = None
    autoCancelIfClientResponds: typing.Optional[bool] = None
    defaultChannel: typing.Optional[types.MessageChannel] = None

class UpdatePrepNotesRequest(BaseModel):
    # Request to update private notes
    privateCoachNotes: typing.Optional[str] = None

class UpdateResourceRequest(BaseModel):
    # Request to update an existing resource
    title: typing.Optional[str] = None
    description: typing.Optional[str] = None
    tags: typing.List[str]
    externalUrl: typing.Optional[str] = None

class UpdateScheduledMessageRequest(BaseModel):
    # Request to update a scheduled message
    subject: typing.Optional[str] = None
    body: typing.Optional[str] = None
    scheduledFor: typing.Optional[str] = None
    channel: typing.Optional[types.MessageChannel] = None

class UpdateSectionRequest(BaseModel):
    # Request to update a specific section
    sectionId: typing.Optional[types.SessionNoteSectionId] = None
    summary: typing.Optional[str] = None
    keyPoints: typing.Optional[typing.List["KeyPoint"]] = None

class UserActiveState(BaseModel):
    # Current user state (broadcast via WebSocket)
    page: typing.Optional[str] = None
    clientId: typing.Optional[int] = None
    clientName: typing.Optional[str] = None
    sessionId: typing.Optional[str] = None
    sessionDate: typing.Optional[str] = None
    availableActions: typing.List[str]
    navigationOptions: typing.List["NavigationOption"]
    source: typing.Optional[types.StateSource] = None
    lastUpdated: typing.Optional[str] = None

class VoiceCorrection(BaseModel):
    # A single voice correction record
    id: typing.Optional[str] = None
    originalContent: typing.Optional[str] = None
    editedContent: typing.Optional[str] = None
    editType: typing.Optional[types.EditType] = None
    coachFeedback: typing.Optional[types.CoachFeedback] = None
    contentType: typing.Optional[types.VoiceContentType] = None
    sessionId: typing.Optional[str] = None
    timestamp: typing.Optional[str] = None

class VoiceCorrectionRequest(BaseModel):
    # Request to submit a voice correction
    sessionId: typing.Optional[str] = None
    originalContent: typing.Optional[str] = None
    editedContent: typing.Optional[str] = None
    editType: typing.Optional[types.EditType] = None
    coachFeedback: typing.Optional[types.CoachFeedback] = None
    contentType: typing.Optional[types.VoiceContentType] = None

class VoiceCorrectionResponse(BaseModel):
    # Response from submitting a voice correction
    success: typing.Optional[bool] = None
    voiceConfidenceAfter: typing.Optional[float] = None
    improvementNote: typing.Optional[str] = None
    correctionId: typing.Optional[str] = None

class VoiceEventPayload(BaseModel):
    # Payload for VOICE_* events
    correctionId: typing.Optional[str] = None
    voiceConfidence: typing.Optional[float] = None
    contentType: typing.Optional[str] = None

class VoiceMatchResult(BaseModel):
    # Result of scoring content against voice profile
    overallScore: typing.Optional[float] = None
    toneScore: typing.Optional[float] = None
    structureScore: typing.Optional[float] = None
    vocabularyScore: typing.Optional[float] = None
    breakdown: typing.Dict[str, float]
    suggestions: typing.List[str]

class VoiceProfile(BaseModel):
    # Coach's voice profile
    coachId: typing.Optional[int] = None
    voiceConfidence: typing.Optional[float] = None
    totalCorrections: typing.Optional[int] = None
    vocabularyPatterns: typing.List[str]
    avoidPatterns: typing.List[str]
    tonePreferences: typing.List["TonePreference"]
    recentEdits: typing.List["VoiceCorrection"]
    lastTrainedAt: typing.Optional[str] = None

class VoiceProfileConfig(BaseModel):
    # Voice profile configuration (for onboarding setup)
    coachId: typing.Optional[int] = None
    minSamplesRequired: typing.Optional[int] = None
    currentSampleCount: typing.Optional[int] = None
    sampleTypes: typing.List[types.VoiceContentType]
    trainingStatus: typing.Optional[types.VoiceTrainingStatus] = None
    estimatedConfidence: typing.Optional[float] = None
    canStartTraining: typing.Optional[bool] = None
    lastUpdated: typing.Optional[str] = None

class VoiceProfileV1(BaseModel):
    # Extended voice profile with v1 style analysis
# Extends the base VoiceProfile with LLM-computed style data
    coachId: typing.Optional[int] = None
    voiceConfidence: typing.Optional[float] = None
    totalCorrections: typing.Optional[int] = None
    vocabularyPatterns: typing.List[str]
    avoidPatterns: typing.List[str]
    tonePreferences: typing.List["TonePreference"]
    recentEdits: typing.List["VoiceCorrection"]
    lastTrainedAt: typing.Optional[str] = None
    styleAnalysis: typing.Optional["StyleAnalysis"] = None
    styleInsights: typing.Optional[typing.List["StyleInsight"]] = None
    analysisVersion: typing.Optional[str] = None
    lastAnalyzedAt: typing.Optional[str] = None

class VoiceSample(BaseModel):
    # A single voice sample for training
    id: typing.Optional[str] = None
    coachId: typing.Optional[int] = None
    type: typing.Optional[types.VoiceSampleType] = None
    content: typing.Optional[str] = None
    context: typing.Optional[str] = None
    isPreferred: typing.Optional[bool] = None
    submittedAt: typing.Optional[str] = None
    processedAt: typing.Optional[str] = None
    processingStatus: typing.Optional[types.VoiceSampleStatus] = None

class VoiceSampleInput(BaseModel):
    # Input for a single voice sample
    type: typing.Optional[types.VoiceSampleType] = None
    content: typing.Optional[str] = None
    context: typing.Optional[str] = None
    isPreferred: typing.Optional[bool] = None

class VoiceSampleSubmitRequest(BaseModel):
    # Request to submit voice samples
    samples: typing.List["VoiceSampleInput"]

class VoiceSampleSubmitResponse(BaseModel):
    # Response from voice sample submission
    success: typing.Optional[bool] = None
    submittedCount: typing.Optional[int] = None
    sampleIds: typing.List[str]
    voiceProfileStatus: typing.Optional[str] = None
    minimumSamplesRequired: typing.Optional[int] = None
    currentSampleCount: typing.Optional[int] = None
    error: typing.Optional[str] = None

class VoiceSamplesPayload(BaseModel):
    # Payload for VOICE_SAMPLES_SUBMITTED event
    coachId: typing.Optional[int] = None
    sampleCount: typing.Optional[int] = None
    totalSamples: typing.Optional[int] = None
    sampleTypes: typing.List[str]
    voiceProfileStatus: typing.Optional[str] = None

# #########################################################################
# Generated type aliases (0)
# #########################################################################
