◆ Assort Design
01

LangGraph Pipeline

graph_v2.md

Node flow — v3 ML-first routing with tool steps

%%{init: {"flowchart": {"curve": "basis", "nodeSpacing": 40, "rankSpacing": 50}, "themeVariables": {"fontFamily": "Inter, ui-sans-serif, system-ui", "fontSize": "12px"}}}%% flowchart TD subgraph Routing route_source{ML model available?} ml_router[ml_router] llm_router[llm_router] route_audience[route_audience] end subgraph Generation specialist_generate[specialist_generate] evaluate[evaluate] end subgraph Tools tool_citation[tool_citation] tool_risk[tool_risk] tool_gate[tool_gate] end subgraph Persistence persist_attempt[persist_attempt] decision{pass?} revise[revise] persist_results[persist_results] end route_source -->|yes| ml_router route_source -->|no| llm_router ml_router --> route_audience llm_router --> route_audience route_audience --> specialist_generate specialist_generate --> evaluate evaluate --> tool_citation tool_citation --> tool_risk tool_risk --> tool_gate tool_gate --> persist_attempt persist_attempt --> decision decision -->|revise| revise decision -->|persist_results| persist_results revise --> specialist_generate persist_results --> END classDef llm fill:#E8F1FF,stroke:#4C6FFF,stroke-width:1px,color:#1E2A5A; classDef ml fill:#E7FAF7,stroke:#20B2AA,stroke-width:1px,color:#0D3B3A; classDef tool fill:#FFF6E5,stroke:#F4A340,stroke-width:1px,color:#6A3B00; classDef persist fill:#E9F9EE,stroke:#3CB371,stroke-width:1px,color:#114B2F; classDef control fill:#F2F2F2,stroke:#888,stroke-width:1px,color:#333; class route_audience,specialist_generate,evaluate llm; class tool_citation,tool_risk,tool_gate tool; class persist_attempt,persist_results persist; class ml_router ml; class llm_router llm; class route_source,decision,revise control; subgraph Legend legend_ml[ML step] legend_llm[LLM step] legend_tool[Tool step] legend_persist[Persistence] legend_control[Decision/control] end class legend_ml ml; class legend_llm llm; class legend_tool tool; class legend_persist persist; class legend_control control;

ML router or LLM router → route_audiencespecialist_generateevaluate → tool nodes → persist_attempt — branches to revise (retry loop) or persist_results (done)

02

LLM Call Flow

llm_file_visual.md

Flow: Check mock → (mock result) OR (OpenAI call → extract text → parse JSON) → dict

flowchart TD A[route_audience / generate_content / evaluate_content] --> B{is_mock_mode?} B -- Yes --> M1["_mock_route / _mock_generate / _mock_evaluate"] M1 --> R1[Return deterministic JSON dict] B -- No --> C["_call_llm_json"] C --> D[get_client] D --> E{OPENAI_API_KEY set?} E -- No --> X[RuntimeError: client not available] E -- Yes --> F["OpenAI Responses API: responses.create"] F --> G["_extract_text"] G --> H["_parse_json"] H --> R2[Return JSON dict]

Mock mode activates when OPENAI_API_KEY is absent. Real mode calls the OpenAI Responses API and parses the JSON reply.

03

Agent Profiles Loader

config_file_visual.md

Flow: Getter → load → validate → cache

flowchart TD A["get_audience_profile(audience)"] --> B["load_profiles()"] B --> C{_PROFILES is None?} C -- No --> D[Return cached _PROFILES] C -- Yes --> E["Build path: module_dir/agent_profiles.yaml"] E --> F{File exists?} F -- No --> G[FileNotFoundError] F -- Yes --> H["yaml.safe_load()"] H --> I{Top-level is dict?} I -- No --> J[ValueError] I -- Yes --> K["_validate_profiles(data)"] K --> L["_PROFILES = data (cache)"] L --> M[Return _PROFILES] M --> N[Look up profiles.audiences] N --> O{audience key exists?} O -- No --> P[ValueError: show available keys] O -- Yes --> Q["Return audiences[audience]"]

Profiles are loaded once from disk and cached in _PROFILES. Subsequent calls skip the file read entirely.

04

Agent Profiles Data Structure

config_file_dataShape_visual.md

YAML Configuration Schema

agent_profiles.yaml (top-level dict)
├── audiences (dict, required, non-empty)
│   ├── <audience_name_1> (dict)
│   │   ├── display_name       (string, required)
│   │   ├── system_prompt      (string, required)
│   │   ├── required_sections  (list[string], required)
│   │   └── default_max_words  (int > 0, required)
│   └── <audience_name_2> ...
│
├── routing (dict, required)
│   ├── auto_router_prompt           (string, required)
│   ├── low_confidence_threshold     (number 0..1, required)
│   ├── ml_router_threshold          (number 0..1, optional)
│   ├── ml_router_margin             (number 0..1, optional)
│   └── ml_router_min_samples        (int >= 1, optional)
│
├── evaluation (dict, required)
│   └── evaluator_prompt   (string, required)
│
└── generation (dict, required)
    └── prompt   (string, required)

All top-level keys are required. audiences must contain at least one named entry. The routing section supports optional ml_router_* keys for the ML-first routing path.

01

Entity Relationship Diagram

db_schema_visual_v2.md

PK = Primary Key  |  FK = Foreign Key

erDiagram Document { int id PK text content text source_type text source_url datetime created_at } Job { int id PK int document_id FK text selected_audience text audience float routing_confidence text routing_candidates_json text routing_reasons_json text routing_source text router_version text status int attempt_count int max_words int max_retries datetime created_at } JobAttempt { int id PK int job_id FK int attempt_no text audience text agent_used text generated_one_line_summary text generated_tags_json text generated_clues_json text generated_bullets_json text generated_mindmap text evaluator_json bool passed datetime created_at } Tag { int id PK text name } DocumentTag { int document_id PK int tag_id PK } DocumentClue { int id PK int document_id FK text clue_text datetime created_at } TagAlias { int id PK text alias text canonical datetime created_at } DocumentTagSummary { int id PK int document_id FK int job_id FK text domain text canonical_tags_json datetime created_at } DocumentClaim { int id PK int document_id FK int job_id FK text claim_text text quote_text int source_start int source_end float confidence datetime created_at } DocumentRiskFlag { int id PK int document_id FK int job_id FK text severity text category text text_span text suggested_fix datetime created_at } Document ||--o{ Job : "has" Job ||--o{ JobAttempt : "has" Document ||--o{ DocumentClue : "has" DocumentTag }o--|| Document : "" DocumentTag }o--|| Tag : "" Document ||--o{ DocumentTagSummary : "summaries" Job ||--o{ DocumentTagSummary : "summaries" Document ||--o{ DocumentClaim : "citations" Job ||--o{ DocumentClaim : "citations" Document ||--o{ DocumentRiskFlag : "risk flags" Job ||--o{ DocumentRiskFlag : "risk flags"
02

Table & Relationship Tree

db_schema_visual_v2.md

Full column & FK reference

Tables & Relationships
│
├── Document                   Core content record
│   ├── id (PK)
│   ├── content
│   ├── source_type
│   ├── source_url
│   └── created_at
│       │
│       ├──< Job                One document → many jobs
│       │     ├── id (PK)
│       │     ├── document_id (FK → Document.id)  [indexed]
│       │     ├── selected_audience
│       │     ├── audience
│       │     ├── routing_confidence
│       │     ├── routing_candidates_json
│       │     ├── routing_reasons_json
│       │     ├── routing_source
│       │     ├── router_version
│       │     ├── status
│       │     ├── attempt_count
│       │     ├── max_words
│       │     ├── max_retries
│       │     └── created_at
│       │           │
│       │           └──< JobAttempt      One job → many attempts
│       │                 ├── id (PK)
│       │                 ├── job_id (FK → Job.id)  [indexed]
│       │                 ├── attempt_no
│       │                 ├── audience
│       │                 ├── agent_used
│       │                 ├── generated_one_line_summary
│       │                 ├── generated_tags_json
│       │                 ├── generated_clues_json
│       │                 ├── generated_bullets_json
│       │                 ├── generated_mindmap
│       │                 ├── evaluator_json
│       │                 ├── passed
│       │                 └── created_at
│       │
│       ├──< DocumentClue       One document → many clues
│       │     ├── id (PK)
│       │     ├── document_id (FK → Document.id)  [indexed]
│       │     ├── clue_text
│       │     └── created_at
│       │
│       ├──< DocumentTagSummary  One document → many tag summaries
│       │     ├── id (PK)
│       │     ├── document_id (FK → Document.id)  [indexed]
│       │     ├── job_id (FK → Job.id)            [indexed]
│       │     ├── domain                          [indexed]
│       │     ├── canonical_tags_json
│       │     └── created_at
│       │
│       ├──< DocumentClaim       One document → many citation claims
│       │     ├── id (PK)
│       │     ├── document_id (FK → Document.id)  [indexed]
│       │     ├── job_id (FK → Job.id)            [indexed]
│       │     ├── claim_text
│       │     ├── quote_text
│       │     ├── source_start
│       │     ├── source_end
│       │     ├── confidence
│       │     └── created_at
│       │
│       ├──< DocumentRiskFlag    One document → many risk flags
│       │     ├── id (PK)
│       │     ├── document_id (FK → Document.id)  [indexed]
│       │     ├── job_id (FK → Job.id)            [indexed]
│       │     ├── severity
│       │     ├── category
│       │     ├── text_span
│       │     ├── suggested_fix
│       │     └── created_at
│       │
│       └──< DocumentTag        Join table (many-to-many)
│             ├── document_id (PK, FK → Document.id)  [indexed]
│             └── tag_id (PK, FK → Tag.id)            [indexed]
│
├── Tag                         Global tag registry
│   ├── id (PK)
│   └── name  [unique, indexed]
│
└── TagAlias                    Tag normalization map
    ├── id (PK)
    ├── alias     [unique, indexed]
    ├── canonical [indexed]
    └── created_at

└──< denotes a one-to-many relationship from parent to child

03

Indexes

db_schema_visual_v2.md

All DB indexes and their purpose

Index Name Table Column(s) Notes
ix_job_document_id job document_id FK lookup
ix_jobattempt_job_id jobattempt job_id FK lookup
ix_documentclue_document_id documentclue document_id FK lookup
ix_documenttag_document_id documenttag document_id FK lookup
ix_documenttag_tag_id documenttag tag_id FK lookup
ix_tagalias_alias tagalias alias FK lookup
ix_tagalias_canonical tagalias canonical FK lookup
ix_doc_tag_summary_doc documenttagsummary document_id FK lookup
ix_doc_tag_summary_job documenttagsummary job_id FK lookup
ix_doc_tag_summary_domain documenttagsummary domain Filter/sort
ix_doc_claim_doc documentclaim document_id FK lookup
ix_doc_claim_job documentclaim job_id FK lookup
ix_doc_risk_doc documentriskflag document_id FK lookup
ix_doc_risk_job documentriskflag job_id FK lookup
(auto) tag name unique constraint
(auto) tagalias alias unique constraint
04

Job Status Flow

db_schema_visual_v2.md

Lifecycle: pending → running → completed / failed

stateDiagram-v2 [*] --> pending pending --> running running --> completed running --> failed failed --> running : retry (attempt_count < max_retries) failed --> [*] completed --> [*]

Jobs retry up to max_retries (default 2) before permanently staying in failed.

Zoom 100%