rigelbar's picture
Add clear slide deck start paths
6d9bd01
Raw
History Blame Contribute Delete
18.9 kB
from __future__ import annotations
from enum import Enum
from typing import Any, Literal
from pydantic import BaseModel, Field
class RubricDimensionScore(BaseModel):
dimension_id: str
label: str
score: int
weight: float = 1.0
rationale: str | None = None
class StageGradeResult(BaseModel):
stage_id: str
artifact_version_id: str | None = None
score: int
passed_threshold: bool
rubric_scores: list[RubricDimensionScore] = Field(default_factory=list)
issue_ids: list[str] = Field(default_factory=list)
recommended_actions: list[str] = Field(default_factory=list)
graded_at: str
grader: Literal["deterministic", "mock_ai", "human", "system"] = "deterministic"
class IssueType(str, Enum):
MISSING_REQUIRED_INPUT = "missing_required_input"
SOURCE_EXTRACTION_FAILED = "source_extraction_failed"
OBJECTIVE_UNCOVERED = "objective_uncovered"
OBJECTIVE_WEAKLY_COVERED = "objective_weakly_covered"
UNSUPPORTED_CLAIM = "unsupported_claim"
TECHNICAL_INACCURACY = "technical_inaccuracy"
TEXT_DENSITY_EXCEEDED = "text_density_exceeded"
COGNITIVE_LOAD_HIGH = "cognitive_load_high"
SPEAKER_NOTES_MISSING = "speaker_notes_missing"
LAYOUT_SCHEMA_INVALID = "layout_schema_invalid"
LAYOUT_SLOT_VIOLATION = "layout_slot_violation"
VISUAL_ASSET_MISSING = "visual_asset_missing"
VISUAL_ASSET_PURPOSE_MISSING = "visual_asset_purpose_missing"
ALT_TEXT_MISSING = "alt_text_missing"
ACCESSIBILITY_CONTRAST_RISK = "accessibility_contrast_risk"
COPYRIGHT_OR_LICENSE_RISK = "copyright_or_license_risk"
RENDER_SAFETY_VIOLATION = "render_safety_violation"
GOOGLE_EXPORT_FAILED = "google_export_failed"
HUMAN_APPROVAL_MISSING = "human_approval_missing"
SCORE_BELOW_THRESHOLD = "score_below_threshold"
STALE_DOWNSTREAM_STAGE = "stale_downstream_stage"
APPROVAL_INVALIDATED = "approval_invalidated"
EXPORT_PREFLIGHT_FAILED = "export_preflight_failed"
class IssueSeverity(str, Enum):
INFO = "info"
MINOR = "minor"
MAJOR = "major"
BLOCKER = "blocker"
class ReviewRole(str, Enum):
SME = "sme"
INSTRUCTIONAL_DESIGNER = "instructional_designer"
VISUAL_DESIGNER = "visual_designer"
PRODUCER = "producer"
INSTRUCTOR = "instructor"
GENERAL_REVIEWER = "general_reviewer"
class ReviewModeConfig(BaseModel):
role: ReviewRole
label: str
description: str | None = None
visible_stage_ids: list[str] = Field(default_factory=list)
focused_issue_types: list[IssueType] = Field(default_factory=list)
focused_rubric_dimensions: list[str] = Field(default_factory=list)
default_sort: Literal["severity", "stage", "slide", "newest", "oldest"] = "severity"
class IssueStatus(str, Enum):
OPEN = "open"
ACKNOWLEDGED = "acknowledged"
IN_PROGRESS = "in_progress"
RESOLVED = "resolved"
WAIVED = "waived"
WONT_FIX = "wont_fix"
class QualityIssue(BaseModel):
issue_id: str
issue_type: IssueType
severity: IssueSeverity
message: str
stage_id: str | None = None
slide_id: str | None = None
objective_id: str | None = None
artifact_version_id: str | None = None
claim_id: str | None = None
suggested_fix: str | None = None
resolved: bool = False
status: IssueStatus = IssueStatus.OPEN
priority: Literal["low", "medium", "high", "critical"] = "medium"
assigned_role: ReviewRole | None = None
assigned_to: str | None = None
resolution_note: str | None = None
waiver_reason: str | None = None
resolved_by: str | None = None
waived_by: str | None = None
waived_at: str | None = None
last_seen_artifact_version_id: str | None = None
created_at: str
resolved_at: str | None = None
class ReviewQueueItem(BaseModel):
queue_item_id: str
issue_id: str
issue_type: IssueType
severity: IssueSeverity
status: IssueStatus
priority: Literal["low", "medium", "high", "critical"]
stage_id: str | None = None
slide_id: str | None = None
objective_id: str | None = None
claim_id: str | None = None
artifact_version_id: str | None = None
assigned_role: ReviewRole | None = None
assigned_to: str | None = None
message: str
suggested_fix_summary: str | None = None
created_at: str
class SuggestedFix(BaseModel):
fix_id: str
issue_ids: list[str] = Field(default_factory=list)
stage_id: str | None = None
slide_ids: list[str] = Field(default_factory=list)
objective_ids: list[str] = Field(default_factory=list)
claim_ids: list[str] = Field(default_factory=list)
fix_type: Literal[
"rewrite_text",
"reduce_text",
"add_example",
"add_speaker_notes",
"support_claim",
"remove_unsupported_claim",
"change_layout",
"add_alt_text",
"add_visual_asset",
"improve_objective_mapping",
"mark_for_human_review",
"other",
] = "other"
description: str
expected_score_delta: dict[str, int] = Field(default_factory=dict)
risk_level: Literal["low", "medium", "high"] = "medium"
requires_human_confirmation: bool = True
class RevisionConstraints(BaseModel):
preserve_slide_order: bool = True
preserve_slide_titles: bool = False
preserve_technical_claims: bool = True
preserve_objective_mappings: bool = True
preserve_visual_assets: bool = False
preserve_layout_ids: bool = False
selected_slide_ids: list[str] = Field(default_factory=list)
allowed_fields: list[str] = Field(default_factory=list)
blocked_fields: list[str] = Field(default_factory=list)
reviewer_instruction: str | None = None
class ProposedChange(BaseModel):
change_id: str
target_type: Literal[
"stage_artifact",
"slide",
"slide_title",
"slide_text",
"speaker_notes",
"layout",
"visual_asset",
"objective_mapping",
"claim",
"metadata",
]
target_id: str
field_path: str | None = None
before: Any | None = None
after: Any | None = None
rationale: str | None = None
issue_ids: list[str] = Field(default_factory=list)
risk_level: Literal["low", "medium", "high"] = "medium"
class ProposedChangeSet(BaseModel):
change_set_id: str
stage_id: str
artifact_version_id: str | None = None
created_at: str
created_by: Literal["mock_ai", "system", "human"] = "mock_ai"
status: Literal["draft", "reviewing", "partially_applied", "applied", "rejected"] = "draft"
constraints: RevisionConstraints = Field(default_factory=RevisionConstraints)
changes: list[ProposedChange] = Field(default_factory=list)
summary: str | None = None
class AIReviewCritique(BaseModel):
critique_id: str
stage_id: str
artifact_version_id: str | None = None
created_at: str
provider: Literal["mock", "system"] = "mock"
issue_ids: list[str] = Field(default_factory=list)
diagnosis: str
proposed_change_set_id: str | None = None
risks: list[str] = Field(default_factory=list)
reviewer_questions: list[str] = Field(default_factory=list)
class ReviewPacket(BaseModel):
packet_id: str
job_id: str
role: ReviewRole | None = None
stage_ids: list[str] = Field(default_factory=list)
slide_ids: list[str] = Field(default_factory=list)
issue_ids: list[str] = Field(default_factory=list)
objective_ids: list[str] = Field(default_factory=list)
artifact_version_ids: list[str] = Field(default_factory=list)
created_at: str
format: Literal["markdown", "json"] = "markdown"
path: str | None = None
summary: str | None = None
class VersionComparisonSummary(BaseModel):
comparison_id: str
previous_artifact_version_id: str
current_artifact_version_id: str
created_at: str
changed_slide_ids: list[str] = Field(default_factory=list)
added_slide_ids: list[str] = Field(default_factory=list)
removed_slide_ids: list[str] = Field(default_factory=list)
changed_titles: list[str] = Field(default_factory=list)
changed_objective_mappings: list[str] = Field(default_factory=list)
changed_claims: list[str] = Field(default_factory=list)
changed_layouts: list[str] = Field(default_factory=list)
changed_visual_assets: list[str] = Field(default_factory=list)
changed_speaker_notes: list[str] = Field(default_factory=list)
summary: str | None = None
diff_text: str | None = None
class ReviewerProductivityMetrics(BaseModel):
job_id: str
total_issues: int
open_issues: int
resolved_issues: int
waived_issues: int
blocker_count: int
major_count: int
issues_by_stage: dict[str, int] = Field(default_factory=dict)
issues_by_role: dict[str, int] = Field(default_factory=dict)
average_score_by_stage: dict[str, int] = Field(default_factory=dict)
candidate_versions_created: int
approvals_invalidated: int
stale_events: int
generated_at: str
class ObjectiveTrace(BaseModel):
objective_id: str
objective_text: str
mapped_slide_ids: list[str] = Field(default_factory=list)
coverage_score: int = 0
coverage_status: Literal["uncovered", "weak", "partial", "strong"] = "uncovered"
evidence: list[str] = Field(default_factory=list)
issue_ids: list[str] = Field(default_factory=list)
class PedagogicalRole(str, Enum):
INTRO = "intro"
MOTIVATION = "motivation"
CONCEPT = "concept"
WORKED_EXAMPLE = "worked_example"
PROCEDURE = "procedure"
COMPARISON = "comparison"
COMMON_MISCONCEPTION = "common_misconception"
KNOWLEDGE_CHECK = "knowledge_check"
DEMO_SETUP = "demo_setup"
DEMO_WALKTHROUGH = "demo_walkthrough"
SUMMARY = "summary"
TRANSITION = "transition"
UNKNOWN = "unknown"
class SpeakerNotes(BaseModel):
slide_id: str
notes_text: str | None = None
instructor_intent: str | None = None
estimated_teaching_time_seconds: int | None = None
possible_student_confusions: list[str] = Field(default_factory=list)
teaching_tips: list[str] = Field(default_factory=list)
class SlideClaim(BaseModel):
claim_id: str
slide_id: str
claim_text: str
source_ids: list[str] = Field(default_factory=list)
source_chunk_ids: list[str] = Field(default_factory=list)
confidence: float = Field(default=1.0, ge=0.0, le=1.0)
review_status: Literal[
"unreviewed",
"supported",
"unsupported",
"needs_human_review",
] = "unreviewed"
issue_ids: list[str] = Field(default_factory=list)
class VisualAsset(BaseModel):
asset_id: str
slide_id: str | None = None
asset_type: Literal[
"generated_image",
"diagram",
"chart",
"icon",
"screenshot",
"placeholder",
]
path_or_url: str | None = None
prompt: str | None = None
purpose: Literal["instructional", "decorative", "background", "unknown"] = "unknown"
alt_text: str | None = None
source: Literal["mock", "generated", "uploaded", "google_drive", "unknown"] = "unknown"
license_status: Literal[
"generated",
"user_provided",
"unknown",
"needs_review",
] = "unknown"
approved_for_export: bool = False
issue_ids: list[str] = Field(default_factory=list)
class LayoutSpec(BaseModel):
slide_id: str
layout_id: str
approved_template_id: str | None = None
slot_assignments: dict[str, Any] = Field(default_factory=dict)
schema_version: str = "1.0"
class ArtifactStatus(str, Enum):
DRAFT = "draft"
CANDIDATE = "candidate"
APPROVED = "approved"
EXPORTED = "exported"
STALE = "stale"
INVALIDATED = "invalidated"
class ArtifactVersion(BaseModel):
artifact_version_id: str
artifact_id: str
stage_id: str
version_number: int
created_at: str
created_by: Literal["system", "human", "ai", "mock"]
content_hash: str
status: ArtifactStatus = ArtifactStatus.DRAFT
parent_artifact_version_ids: list[str] = Field(default_factory=list)
upstream_stage_versions: dict[str, str] = Field(default_factory=dict)
prompt_run_id: str | None = None
is_current: bool = True
metadata: dict[str, Any] = Field(default_factory=dict)
class RequestedChange(BaseModel):
slide_id: str | None = None
stage_id: str | None = None
change_type: Literal[
"add_example",
"reduce_text",
"fix_technical_accuracy",
"improve_layout",
"add_visual",
"remove_visual",
"add_speaker_notes",
"improve_objective_alignment",
"other",
] = "other"
priority: Literal["low", "medium", "high", "blocker"] = "medium"
note: str
class ReviewerNotes(BaseModel):
stage_id: str
artifact_version_id: str | None = None
reviewer_name: str = "human_reviewer"
summary: str | None = None
requested_changes: list[RequestedChange] = Field(default_factory=list)
created_at: str
class PromptRun(BaseModel):
prompt_run_id: str
stage_id: str
artifact_version_id: str | None = None
provider: Literal["mock", "openai", "anthropic", "gemini", "system"] = "mock"
model_name: str | None = None
prompt_template_id: str | None = None
prompt_template_version: str | None = None
rendered_prompt: str | None = None
input_artifact_version_ids: list[str] = Field(default_factory=list)
output_artifact_version_id: str | None = None
settings: dict[str, Any] = Field(default_factory=dict)
created_at: str
class DeckHealthSummary(BaseModel):
job_id: str
deck_title: str | None = None
approved_stage_count: int
total_stage_count: int
stale_stage_count: int
invalidated_approval_count: int
unresolved_blocker_count: int
unresolved_major_issue_count: int
slide_count: int
average_slide_score: int | None = None
objectives_total: int
objectives_strong: int
objectives_partial_or_weak: int
objectives_uncovered: int
unsupported_claim_count: int
can_export: bool
top_blockers: list[str] = Field(default_factory=list)
class SlideQAStatus(BaseModel):
slide_id: str
slide_number: int
title: str | None = None
pedagogical_role: PedagogicalRole = PedagogicalRole.UNKNOWN
objective_ids: list[str] = Field(default_factory=list)
claim_ids: list[str] = Field(default_factory=list)
visual_asset_ids: list[str] = Field(default_factory=list)
layout_id: str | None = None
aggregate_score: int | None = None
technical_score: int | None = None
pedagogical_score: int | None = None
aesthetic_score: int | None = None
issue_ids: list[str] = Field(default_factory=list)
stale: bool = False
status: Literal["draft", "needs_review", "needs_revision", "approved", "stale", "blocked"] = (
"draft"
)
class ExportPreflightReport(BaseModel):
can_export: bool
checked_at: str
blocking_issue_ids: list[str] = Field(default_factory=list)
warning_issue_ids: list[str] = Field(default_factory=list)
summary: str
class StageApproval(BaseModel):
stage_id: str
artifact_version_id: str
reviewer_name: str = "human_reviewer"
reviewer_role: ReviewRole | None = None
approved_at: str
approval_status: Literal["approved", "invalidated", "revoked"] = "approved"
invalidated_at: str | None = None
invalidation_reason: str | None = None
class AuditEvent(BaseModel):
event_id: str
event_type: str
timestamp: str
stage_id: str | None = None
slide_id: str | None = None
objective_id: str | None = None
artifact_version_id: str | None = None
issue_id: str | None = None
claim_id: str | None = None
reason: str | None = None
metadata: dict[str, Any] = Field(default_factory=dict)
class StageState(BaseModel):
stage_id: str
label: str
score: int | None = None
is_stale: bool = False
current_artifact_version_id: str | None = None
grade_result: StageGradeResult | None = None
class Slide(BaseModel):
slide_id: str
slide_number: int
title: str | None = None
visible_text: str = ""
bullet_points: list[str] = Field(default_factory=list)
objective_ids: list[str] = Field(default_factory=list)
pedagogical_role: PedagogicalRole = PedagogicalRole.UNKNOWN
requires_visual: bool = False
speaker_notes: SpeakerNotes | None = None
objective_coverage_scores: dict[str, int] = Field(default_factory=dict)
distinct_concept_count: int | None = None
metadata: dict[str, Any] = Field(default_factory=dict)
class PipelineState(BaseModel):
job_id: str
deck_title: str | None = None
dry_run: bool = True
production_export_requested: bool = False
enable_role_required_approvals: bool = False
source_url: str | None = None
template_url: str | None = None
output_folder_id: str | None = None
mutation_target_url: str | None = None
uploaded_materials: list[dict[str, Any]] = Field(default_factory=list)
unsupported_materials: list[dict[str, Any]] = Field(default_factory=list)
start_mode: Literal["instructions_file", "input_outline", "import_existing_draft", "start_from_zero"] = "instructions_file"
draft_upload_metadata: dict[str, Any] = Field(default_factory=dict)
source_chunks: dict[str, str] = Field(default_factory=dict)
objectives: dict[str, str] = Field(default_factory=dict)
stages: dict[str, StageState] = Field(default_factory=dict)
artifacts: dict[str, ArtifactVersion] = Field(default_factory=dict)
stage_artifact_versions: dict[str, list[str]] = Field(default_factory=dict)
issues: dict[str, QualityIssue] = Field(default_factory=dict)
objective_traces: dict[str, ObjectiveTrace] = Field(default_factory=dict)
slides: dict[str, Slide] = Field(default_factory=dict)
slide_statuses: dict[str, SlideQAStatus] = Field(default_factory=dict)
claims: dict[str, SlideClaim] = Field(default_factory=dict)
visual_assets: dict[str, VisualAsset] = Field(default_factory=dict)
layout_specs: dict[str, LayoutSpec] = Field(default_factory=dict)
approvals: list[StageApproval] = Field(default_factory=list)
reviewer_notes: list[ReviewerNotes] = Field(default_factory=list)
prompt_runs: dict[str, PromptRun] = Field(default_factory=dict)
suggested_fixes: dict[str, SuggestedFix] = Field(default_factory=dict)
critiques: dict[str, AIReviewCritique] = Field(default_factory=dict)
proposed_change_sets: dict[str, ProposedChangeSet] = Field(default_factory=dict)
review_packets: dict[str, ReviewPacket] = Field(default_factory=dict)
version_comparisons: dict[str, VersionComparisonSummary] = Field(default_factory=dict)
audit_events: list[AuditEvent] = Field(default_factory=list)
export_preflight_report: ExportPreflightReport | None = None