PlanOpticon

Source Blame History 314 lines
b2df90e… leo 1 """Pydantic data models for PlanOpticon output."""
b2df90e… leo 2
b2df90e… leo 3 from datetime import datetime
b2df90e… leo 4 from enum import Enum
0981a08… noreply 5 from typing import Any, Dict, List, Optional, Protocol, runtime_checkable
b2df90e… leo 6
b2df90e… leo 7 from pydantic import BaseModel, Field
0981a08… noreply 8
0981a08… noreply 9
0981a08… noreply 10 @runtime_checkable
0981a08… noreply 11 class ProgressCallback(Protocol):
0981a08… noreply 12 """Optional callback for pipeline progress updates."""
0981a08… noreply 13
0981a08… noreply 14 def on_step_start(self, step: str, index: int, total: int) -> None: ...
0981a08… noreply 15 def on_step_complete(self, step: str, index: int, total: int) -> None: ...
0981a08… noreply 16 def on_progress(self, step: str, percent: float, message: str = "") -> None: ...
829e24a… leo 17
829e24a… leo 18
b2df90e… leo 19 class DiagramType(str, Enum):
b2df90e… leo 20 """Types of visual content detected in video frames."""
829e24a… leo 21
b2df90e… leo 22 flowchart = "flowchart"
b2df90e… leo 23 sequence = "sequence"
b2df90e… leo 24 architecture = "architecture"
b2df90e… leo 25 whiteboard = "whiteboard"
b2df90e… leo 26 chart = "chart"
b2df90e… leo 27 table = "table"
b2df90e… leo 28 slide = "slide"
b2df90e… leo 29 screenshot = "screenshot"
b2df90e… leo 30 unknown = "unknown"
b2df90e… leo 31
b2df90e… leo 32
b2df90e… leo 33 class OutputFormat(str, Enum):
b2df90e… leo 34 """Available output formats."""
829e24a… leo 35
b2df90e… leo 36 markdown = "markdown"
b2df90e… leo 37 json = "json"
b2df90e… leo 38 html = "html"
b2df90e… leo 39 pdf = "pdf"
54d5d79… noreply 40 pptx = "pptx"
b2df90e… leo 41 svg = "svg"
b2df90e… leo 42 png = "png"
b2df90e… leo 43
b2df90e… leo 44
b2df90e… leo 45 class TranscriptSegment(BaseModel):
b2df90e… leo 46 """A single segment of transcribed audio."""
829e24a… leo 47
b2df90e… leo 48 start: float = Field(description="Start time in seconds")
b2df90e… leo 49 end: float = Field(description="End time in seconds")
b2df90e… leo 50 text: str = Field(description="Transcribed text")
b2df90e… leo 51 speaker: Optional[str] = Field(default=None, description="Speaker identifier")
b2df90e… leo 52 confidence: Optional[float] = Field(default=None, description="Transcription confidence 0-1")
b2df90e… leo 53
b2df90e… leo 54
b2df90e… leo 55 class ActionItem(BaseModel):
b2df90e… leo 56 """An action item extracted from content."""
829e24a… leo 57
b2df90e… leo 58 action: str = Field(description="The action to be taken")
b2df90e… leo 59 assignee: Optional[str] = Field(default=None, description="Person responsible")
b2df90e… leo 60 deadline: Optional[str] = Field(default=None, description="Deadline or timeframe")
b2df90e… leo 61 priority: Optional[str] = Field(default=None, description="Priority level")
b2df90e… leo 62 context: Optional[str] = Field(default=None, description="Additional context")
829e24a… leo 63 source: Optional[str] = Field(
829e24a… leo 64 default=None, description="Where this was found (transcript/diagram)"
829e24a… leo 65 )
b2df90e… leo 66
b2df90e… leo 67
b2df90e… leo 68 class KeyPoint(BaseModel):
b2df90e… leo 69 """A key point extracted from content."""
829e24a… leo 70
b2df90e… leo 71 point: str = Field(description="The key point")
b2df90e… leo 72 topic: Optional[str] = Field(default=None, description="Topic or category")
b2df90e… leo 73 details: Optional[str] = Field(default=None, description="Supporting details")
b2df90e… leo 74 timestamp: Optional[float] = Field(default=None, description="Timestamp in video (seconds)")
b2df90e… leo 75 source: Optional[str] = Field(default=None, description="Where this was found")
829e24a… leo 76 related_diagrams: List[int] = Field(
829e24a… leo 77 default_factory=list, description="Indices of related diagrams"
829e24a… leo 78 )
b2df90e… leo 79
b2df90e… leo 80
b2df90e… leo 81 class DiagramResult(BaseModel):
b2df90e… leo 82 """Result from diagram extraction and analysis."""
829e24a… leo 83
b2df90e… leo 84 frame_index: int = Field(description="Index of the source frame")
b2df90e… leo 85 timestamp: Optional[float] = Field(default=None, description="Timestamp in video (seconds)")
b2df90e… leo 86 diagram_type: DiagramType = Field(default=DiagramType.unknown, description="Type of diagram")
b2df90e… leo 87 confidence: float = Field(default=0.0, description="Detection confidence 0-1")
b2df90e… leo 88 description: Optional[str] = Field(default=None, description="Description of the diagram")
b2df90e… leo 89 text_content: Optional[str] = Field(default=None, description="Text visible in the diagram")
b2df90e… leo 90 elements: List[str] = Field(default_factory=list, description="Identified elements")
b2df90e… leo 91 relationships: List[str] = Field(default_factory=list, description="Identified relationships")
b2df90e… leo 92 mermaid: Optional[str] = Field(default=None, description="Mermaid syntax representation")
b2df90e… leo 93 chart_data: Optional[Dict[str, Any]] = Field(
829e24a… leo 94 default=None, description="Chart data for reproduction (labels, values, chart_type)"
b2df90e… leo 95 )
b2df90e… leo 96 image_path: Optional[str] = Field(default=None, description="Relative path to original frame")
b2df90e… leo 97 svg_path: Optional[str] = Field(default=None, description="Relative path to rendered SVG")
b2df90e… leo 98 png_path: Optional[str] = Field(default=None, description="Relative path to rendered PNG")
b2df90e… leo 99 mermaid_path: Optional[str] = Field(default=None, description="Relative path to mermaid source")
b2df90e… leo 100
b2df90e… leo 101
b2df90e… leo 102 class ScreenCapture(BaseModel):
2a1b11a… noreply 103 """A screen capture with knowledge extraction from shared content."""
829e24a… leo 104
b2df90e… leo 105 frame_index: int = Field(description="Index of the source frame")
b2df90e… leo 106 timestamp: Optional[float] = Field(default=None, description="Timestamp in video (seconds)")
b2df90e… leo 107 caption: Optional[str] = Field(default=None, description="Brief description of the content")
b2df90e… leo 108 image_path: Optional[str] = Field(default=None, description="Relative path to screenshot")
829e24a… leo 109 confidence: float = Field(
829e24a… leo 110 default=0.0, description="Detection confidence that triggered fallback"
2a1b11a… noreply 111 )
2a1b11a… noreply 112 content_type: Optional[str] = Field(
2a1b11a… noreply 113 default=None,
2a1b11a… noreply 114 description="Content type: slide, code, document, terminal, browser, chat, other",
2a1b11a… noreply 115 )
2a1b11a… noreply 116 text_content: Optional[str] = Field(
2a1b11a… noreply 117 default=None, description="All visible text extracted from the screenshot"
2a1b11a… noreply 118 )
2a1b11a… noreply 119 entities: List[str] = Field(
2a1b11a… noreply 120 default_factory=list, description="Entities identified in the screenshot"
2a1b11a… noreply 121 )
2a1b11a… noreply 122 topics: List[str] = Field(
2a1b11a… noreply 123 default_factory=list, description="Topics or concepts visible in the screenshot"
0981a08… noreply 124 )
0981a08… noreply 125
0981a08… noreply 126
0981a08… noreply 127 class SourceRecord(BaseModel):
0981a08… noreply 128 """A content source registered in the knowledge graph for provenance tracking."""
0981a08… noreply 129
0981a08… noreply 130 source_id: str = Field(description="Unique identifier for this source")
0981a08… noreply 131 source_type: str = Field(description="Source type: video, document, url, api, manual")
0981a08… noreply 132 title: str = Field(description="Human-readable title")
0981a08… noreply 133 path: Optional[str] = Field(default=None, description="Local file path")
0981a08… noreply 134 url: Optional[str] = Field(default=None, description="URL if applicable")
0981a08… noreply 135 mime_type: Optional[str] = Field(default=None, description="MIME type of the source")
0981a08… noreply 136 ingested_at: str = Field(
0981a08… noreply 137 default_factory=lambda: datetime.now().isoformat(),
0981a08… noreply 138 description="ISO format ingestion timestamp",
0981a08… noreply 139 )
0981a08… noreply 140 metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional source metadata")
b2df90e… leo 141
b2df90e… leo 142
b2df90e… leo 143 class Entity(BaseModel):
b2df90e… leo 144 """An entity in the knowledge graph."""
829e24a… leo 145
b2df90e… leo 146 name: str = Field(description="Entity name")
b2df90e… leo 147 type: str = Field(default="concept", description="Entity type (person, concept, time, diagram)")
b2df90e… leo 148 descriptions: List[str] = Field(default_factory=list, description="Descriptions of this entity")
829e24a… leo 149 source: Optional[str] = Field(
829e24a… leo 150 default=None, description="Source attribution (transcript/diagram/both)"
829e24a… leo 151 )
b2df90e… leo 152 occurrences: List[Dict[str, Any]] = Field(
829e24a… leo 153 default_factory=list, description="List of occurrences with source, timestamp, text"
b2df90e… leo 154 )
b2df90e… leo 155
b2df90e… leo 156
b2df90e… leo 157 class Relationship(BaseModel):
b2df90e… leo 158 """A relationship between entities in the knowledge graph."""
829e24a… leo 159
b2df90e… leo 160 source: str = Field(description="Source entity name")
b2df90e… leo 161 target: str = Field(description="Target entity name")
b2df90e… leo 162 type: str = Field(default="related_to", description="Relationship type")
b2df90e… leo 163 content_source: Optional[str] = Field(default=None, description="Content source identifier")
b2df90e… leo 164 timestamp: Optional[float] = Field(default=None, description="Timestamp in seconds")
b2df90e… leo 165
b2df90e… leo 166
b2df90e… leo 167 class KnowledgeGraphData(BaseModel):
b2df90e… leo 168 """Serializable knowledge graph data."""
829e24a… leo 169
b2df90e… leo 170 nodes: List[Entity] = Field(default_factory=list, description="Graph nodes/entities")
829e24a… leo 171 relationships: List[Relationship] = Field(
829e24a… leo 172 default_factory=list, description="Graph relationships"
829e24a… leo 173 )
0981a08… noreply 174 sources: List[SourceRecord] = Field(
0981a08… noreply 175 default_factory=list, description="Content sources for provenance tracking"
0981a08… noreply 176 )
0981a08… noreply 177
0981a08… noreply 178
0981a08… noreply 179 class PlanningEntityType(str, Enum):
0981a08… noreply 180 """Types of entities in a planning taxonomy."""
0981a08… noreply 181
0981a08… noreply 182 GOAL = "goal"
0981a08… noreply 183 REQUIREMENT = "requirement"
0981a08… noreply 184 CONSTRAINT = "constraint"
0981a08… noreply 185 DECISION = "decision"
0981a08… noreply 186 RISK = "risk"
0981a08… noreply 187 ASSUMPTION = "assumption"
0981a08… noreply 188 DEPENDENCY = "dependency"
0981a08… noreply 189 MILESTONE = "milestone"
0981a08… noreply 190 TASK = "task"
0981a08… noreply 191 FEATURE = "feature"
0981a08… noreply 192
0981a08… noreply 193
0981a08… noreply 194 class PlanningEntity(BaseModel):
0981a08… noreply 195 """An entity classified for planning purposes."""
0981a08… noreply 196
0981a08… noreply 197 name: str
0981a08… noreply 198 planning_type: PlanningEntityType
0981a08… noreply 199 description: str = ""
0981a08… noreply 200 priority: Optional[str] = None # "high", "medium", "low"
0981a08… noreply 201 status: Optional[str] = None # "identified", "confirmed", "resolved"
0981a08… noreply 202 source_entities: List[str] = Field(default_factory=list)
0981a08… noreply 203 metadata: Dict[str, Any] = Field(default_factory=dict)
0981a08… noreply 204
0981a08… noreply 205
0981a08… noreply 206 class PlanningRelationshipType(str, Enum):
0981a08… noreply 207 """Relationship types within a planning taxonomy."""
0981a08… noreply 208
0981a08… noreply 209 REQUIRES = "requires"
0981a08… noreply 210 BLOCKED_BY = "blocked_by"
0981a08… noreply 211 HAS_RISK = "has_risk"
0981a08… noreply 212 DEPENDS_ON = "depends_on"
0981a08… noreply 213 ADDRESSES = "addresses"
0981a08… noreply 214 HAS_TRADEOFF = "has_tradeoff"
0981a08… noreply 215 DELIVERS = "delivers"
0981a08… noreply 216 IMPLEMENTS = "implements"
0981a08… noreply 217 PARENT_OF = "parent_of"
b2df90e… leo 218
b2df90e… leo 219
b2df90e… leo 220 class ProcessingStats(BaseModel):
b2df90e… leo 221 """Statistics about a processing run."""
829e24a… leo 222
b2df90e… leo 223 start_time: Optional[str] = Field(default=None, description="ISO format start time")
b2df90e… leo 224 end_time: Optional[str] = Field(default=None, description="ISO format end time")
b2df90e… leo 225 duration_seconds: Optional[float] = Field(default=None, description="Total processing time")
b2df90e… leo 226 frames_extracted: int = Field(default=0)
287a3bb… leo 227 people_frames_filtered: int = Field(default=0)
b2df90e… leo 228 diagrams_detected: int = Field(default=0)
b2df90e… leo 229 screen_captures: int = Field(default=0)
b2df90e… leo 230 transcript_duration_seconds: Optional[float] = Field(default=None)
b2df90e… leo 231 models_used: Dict[str, str] = Field(
829e24a… leo 232 default_factory=dict, description="Map of task to model used (e.g. vision: gpt-4o)"
b2df90e… leo 233 )
b2df90e… leo 234
b2df90e… leo 235
b2df90e… leo 236 class VideoMetadata(BaseModel):
b2df90e… leo 237 """Metadata about the source video."""
829e24a… leo 238
b2df90e… leo 239 title: str = Field(description="Video title")
b2df90e… leo 240 source_path: Optional[str] = Field(default=None, description="Original video file path")
b2df90e… leo 241 duration_seconds: Optional[float] = Field(default=None, description="Video duration")
b2df90e… leo 242 resolution: Optional[str] = Field(default=None, description="Video resolution (e.g. 1920x1080)")
b2df90e… leo 243 processed_at: str = Field(
b2df90e… leo 244 default_factory=lambda: datetime.now().isoformat(),
829e24a… leo 245 description="ISO format processing timestamp",
b2df90e… leo 246 )
b2df90e… leo 247
b2df90e… leo 248
b2df90e… leo 249 class VideoManifest(BaseModel):
b2df90e… leo 250 """Manifest for a single video processing run - the single source of truth."""
829e24a… leo 251
b2df90e… leo 252 version: str = Field(default="1.0", description="Manifest schema version")
b2df90e… leo 253 video: VideoMetadata = Field(description="Source video metadata")
b2df90e… leo 254 stats: ProcessingStats = Field(default_factory=ProcessingStats)
b2df90e… leo 255
b2df90e… leo 256 # Relative paths to output files
b2df90e… leo 257 transcript_json: Optional[str] = Field(default=None)
b2df90e… leo 258 transcript_txt: Optional[str] = Field(default=None)
b2df90e… leo 259 transcript_srt: Optional[str] = Field(default=None)
b2df90e… leo 260 analysis_md: Optional[str] = Field(default=None)
b2df90e… leo 261 analysis_html: Optional[str] = Field(default=None)
b2df90e… leo 262 analysis_pdf: Optional[str] = Field(default=None)
b2df90e… leo 263 knowledge_graph_json: Optional[str] = Field(default=None)
0ad36b7… noreply 264 knowledge_graph_db: Optional[str] = Field(default=None)
b2df90e… leo 265 key_points_json: Optional[str] = Field(default=None)
b2df90e… leo 266 action_items_json: Optional[str] = Field(default=None)
b2df90e… leo 267
b2df90e… leo 268 # Inline structured data
b2df90e… leo 269 key_points: List[KeyPoint] = Field(default_factory=list)
b2df90e… leo 270 action_items: List[ActionItem] = Field(default_factory=list)
b2df90e… leo 271 diagrams: List[DiagramResult] = Field(default_factory=list)
b2df90e… leo 272 screen_captures: List[ScreenCapture] = Field(default_factory=list)
b2df90e… leo 273
b2df90e… leo 274 # Frame paths
829e24a… leo 275 frame_paths: List[str] = Field(
829e24a… leo 276 default_factory=list, description="Relative paths to extracted frames"
829e24a… leo 277 )
b2df90e… leo 278
b2df90e… leo 279
b2df90e… leo 280 class BatchVideoEntry(BaseModel):
b2df90e… leo 281 """Summary of a single video within a batch."""
829e24a… leo 282
b2df90e… leo 283 video_name: str
b2df90e… leo 284 manifest_path: str = Field(description="Relative path to video manifest")
b2df90e… leo 285 status: str = Field(default="pending", description="pending/completed/failed")
b2df90e… leo 286 error: Optional[str] = Field(default=None, description="Error message if failed")
b2df90e… leo 287 diagrams_count: int = Field(default=0)
b2df90e… leo 288 action_items_count: int = Field(default=0)
b2df90e… leo 289 key_points_count: int = Field(default=0)
b2df90e… leo 290 duration_seconds: Optional[float] = Field(default=None)
b2df90e… leo 291
b2df90e… leo 292
b2df90e… leo 293 class BatchManifest(BaseModel):
b2df90e… leo 294 """Manifest for a batch processing run."""
829e24a… leo 295
b2df90e… leo 296 version: str = Field(default="1.0")
b2df90e… leo 297 title: str = Field(default="Batch Processing Results")
829e24a… leo 298 processed_at: str = Field(default_factory=lambda: datetime.now().isoformat())
b2df90e… leo 299 stats: ProcessingStats = Field(default_factory=ProcessingStats)
b2df90e… leo 300
b2df90e… leo 301 videos: List[BatchVideoEntry] = Field(default_factory=list)
b2df90e… leo 302
b2df90e… leo 303 # Aggregated counts
b2df90e… leo 304 total_videos: int = Field(default=0)
b2df90e… leo 305 completed_videos: int = Field(default=0)
b2df90e… leo 306 failed_videos: int = Field(default=0)
b2df90e… leo 307 total_diagrams: int = Field(default=0)
b2df90e… leo 308 total_action_items: int = Field(default=0)
b2df90e… leo 309 total_key_points: int = Field(default=0)
b2df90e… leo 310
b2df90e… leo 311 # Batch-level output paths (relative)
b2df90e… leo 312 batch_summary_md: Optional[str] = Field(default=None)
b2df90e… leo 313 merged_knowledge_graph_json: Optional[str] = Field(default=None)
0ad36b7… noreply 314 merged_knowledge_graph_db: Optional[str] = Field(default=None)

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button