175 lines
7.2 KiB
Markdown
175 lines
7.2 KiB
Markdown
# Componenti, moduli e flussi
|
|
|
|
Questa pagina completa la [panoramica dell'architettura](overview.md) con la struttura dei moduli e i flussi che attraversano ThothII. I diagrammi descrivono il codice corrente, non un'architettura futura.
|
|
|
|
## Moduli e dipendenze
|
|
|
|
Il frontend comunica con il backend tramite REST e SSE. Il backend non possiede la persistenza delle sessioni: avvia Pi, invoca la CLI `tht` e inoltra gli eventi. L'harness contiene il workflow, la CLI Python e gli adattatori verso DWH e vector store.
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
FE["frontend/\nReact + Vite"] -->|REST + SSE| BE["backend/\nFastify + TypeScript"]
|
|
BE -->|RPC stdin/stdout| PI["Pi\n--mode rpc"]
|
|
BE -->|subprocess\nJSON stdout| THT["harness/tht\nCLI Python"]
|
|
PI --> EXT["harness/.pi/extensions/\ntht-gate.js"]
|
|
EXT --> SKILL["harness/.pi/skills/\ntht-sessione"]
|
|
EXT --> THT
|
|
THT --> FS["Sessioni e artefatti\nworkspace repository"]
|
|
THT --> DWH["DWH\nread-only"]
|
|
THT --> VDB["Qdrant / vector store"]
|
|
BE --> CFG["settings.json\nworkspace registry"]
|
|
FE -.->|renderizza widget| EXT
|
|
```
|
|
|
|
Dipendenze principali:
|
|
|
|
| Modulo | Dipende da | Responsabilità |
|
|
| --- | --- | --- |
|
|
| `frontend/` | API REST e SSE del backend | UI, widget di gate e transcript in memoria |
|
|
| `backend/src/` | Pi, `tht`, configurazione e workspace registry | Trasporto, lifecycle delle sessioni e API |
|
|
| `harness/.pi/` | Pi e `tht phase` | Orchestrazione del workflow e gate human-in-the-loop |
|
|
| `harness/tht/` | filesystem, DWH e vector store | Persistenza, CLI, evidence, schema e preprocessing |
|
|
| workspace repository | `source/`, `curated/`, manifest e artefatti | Sorgente versionata delle evidence e output di sessione |
|
|
|
|
## Sequenza di una sessione
|
|
|
|
Il percorso principale parte da una domanda dell'utente e termina con un evento SSE. Le decisioni del revisore rientrano nello stesso canale e vengono persistite dall'harness.
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
actor U as Utente o revisore
|
|
participant FE as Frontend
|
|
participant BE as Backend
|
|
participant PI as Pi RPC
|
|
participant THT as CLI tht
|
|
participant WS as Workspace
|
|
participant DWH as DWH
|
|
|
|
U->>FE: Invia domanda o decisione di gate
|
|
FE->>BE: POST session / risposta widget
|
|
BE->>PI: RPC input o prompt di resume
|
|
PI->>THT: phase/session/evidence commands
|
|
THT->>WS: Legge e scrive artefatti di fase
|
|
THT->>DWH: Introspezione o query read-only
|
|
DWH-->>THT: Schema, risultati o diagnostica
|
|
THT-->>PI: JSON e stato della fase
|
|
PI-->>BE: Eventi RPC e widget descriptor
|
|
BE-->>FE: SSE text_delta, info, ui_request
|
|
FE-->>U: Testo, artefatto o richiesta di revisione
|
|
```
|
|
|
|
Il backend usa `ThtRunner` per i subprocess della CLI, `PiProcessManager` per un processo Pi per sessione, `SessionBridge` per adattare gli eventi RPC e `SseHub` per distribuirli ai client.
|
|
|
|
## Classi principali del backend
|
|
|
|
Il diagramma mostra le classi che compongono il ponte tra browser, Pi e `tht`. Le route Fastify ricevono le richieste e delegano a questi servizi.
|
|
|
|
```mermaid
|
|
classDiagram
|
|
class ThtRunner {
|
|
+buildArgv(command, args) string[]
|
|
+run(args) Promise~ThtResult~
|
|
+sessionShow(id) Promise~unknown~
|
|
}
|
|
class PiProcessManager {
|
|
-runtimes Map
|
|
+spawnFor(sessionId, mode) SessionRuntime
|
|
+resume(sessionId, tht) Promise~SessionRuntime~
|
|
+stop(sessionId) Promise~void~
|
|
}
|
|
class SessionBridge {
|
|
+handleRpcEvent(event) ClientEvent
|
|
+handleUiResponse(response) Promise~void~
|
|
}
|
|
class SseHub {
|
|
+subscribe(sessionId) AsyncIterable
|
|
+publish(sessionId, event) void
|
|
+close(sessionId) void
|
|
}
|
|
class SessionRoutes {
|
|
+createSession(request) Response
|
|
+resumeSession(id) Response
|
|
+postInput(id, input) Response
|
|
}
|
|
class WorkspaceRegistry {
|
|
+list() Workspace[]
|
|
+resolve(id) Workspace
|
|
}
|
|
class SettingsStore {
|
|
+get() Settings
|
|
+update(patch) Settings
|
|
}
|
|
class App {
|
|
+buildApp() FastifyInstance
|
|
}
|
|
|
|
App --> SessionRoutes
|
|
App --> WorkspaceRegistry
|
|
App --> SettingsStore
|
|
SessionRoutes --> PiProcessManager
|
|
SessionRoutes --> ThtRunner
|
|
SessionRoutes --> SseHub
|
|
PiProcessManager --> SessionBridge
|
|
PiProcessManager --> ThtRunner
|
|
SessionBridge --> SseHub
|
|
```
|
|
|
|
## Moduli Python della CLI `tht`
|
|
|
|
La CLI è composta da comandi Typer e da moduli di dominio. `cli/` traduce gli argomenti in operazioni; `evidence/`, `session/`, `db/`, `adapters/` e gli altri package contengono la logica applicativa.
|
|
|
|
```mermaid
|
|
flowchart TB
|
|
MAIN["tht/cli/__init__.py"] --> CMD["tht/cli/*_cmd.py"]
|
|
CMD --> CONFIG["config.py\nworkspace.py\npaths.py"]
|
|
CMD --> SESSION["session_cmd.py\nsession/"]
|
|
CMD --> EVIDENCE["evidence_cmd.py\nevidence/"]
|
|
CMD --> PRE["preprocess_cmd.py\nevidence/corpus/"]
|
|
CMD --> PHASE["phase_cmd.py\nphase.py\nworkflow.py"]
|
|
CMD --> SQL["sql_cmd.py\ndb/\nrest/"]
|
|
EVIDENCE --> ACQ["evidence/acquisition.py\nadapters/ filesystem/http/s3"]
|
|
EVIDENCE --> CANON["evidence/canonical.py\ncontracts.py\nmodel.py"]
|
|
EVIDENCE --> AUTHOR["evidence/authoring.py"]
|
|
PRE --> PIPE["evidence/corpus/pipeline.py\nchunk.py normalize.py store.py"]
|
|
PRE --> VECTOR["adapters/vector/qdrant.py"]
|
|
PRE --> DWH["jobs/dwh_pipeline.py\nadapters/dwh/"]
|
|
SESSION --> REPO["session/filesystem_repository.py\npostgres_repository.py"]
|
|
PHASE --> LEDGER["decisions.py\nreview_decisions"]
|
|
```
|
|
|
|
Il comando di operatore `tht` in `tools/tht/` è distinto dalla CLI Python dell'harness. Il primo gestisce installazione, lifecycle, autenticazione e workspace; il secondo esegue il workflow e le operazioni sui dati.
|
|
|
|
## Workflow a otto fasi e gate
|
|
|
|
La fonte di verità è `harness/workflow.yaml`. La fase corrente si calcola dal decision ledger, non da un campo aggiornato manualmente.
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
F1["F1\nChiarimento"] --> F2["F2\nMemoria"]
|
|
F2 --> F3["F3\nRiscrittura"]
|
|
F3 --> F4["F4\nSchema linking\nreviewer_decide"]
|
|
F4 --> F5["F5\nSintesi"]
|
|
F5 --> F6["F6\nCTE\nauto o skip"]
|
|
F6 --> F7["F7\nSQL finale\nreviewer_confirm"]
|
|
F7 --> F8["F8\nDatamart\nreviewer_decide"]
|
|
F1 -.->|reviewer_confirm| F1
|
|
F3 -.->|reviewer_confirm| F3
|
|
F4 -.->|decisioni su tabelle, colonne, evidence| F4
|
|
F6 -.->|cte_approved o cte_rejected| F6
|
|
F7 -.->|sql_approved o sql_rejected| F7
|
|
F8 -.->|datamart_requested o declined| F8
|
|
```
|
|
|
|
| Fase | Nome | Avanzamento | Artefatti principali |
|
|
| --- | --- | --- | --- |
|
|
| F1 | chiarimento | `kind:phase` | decisioni di chiarimento |
|
|
| F2 | memoria | automatico se vuota | decisioni memoria |
|
|
| F3 | riscrittura | `kind:phase` | `question.md` |
|
|
| F4 | schema linking | `reviewer_decide` | `schema_linking.json` |
|
|
| F5 | sintesi | `kind:phase` | verifica dello schema linking |
|
|
| F6 | CTE | automatico, oppure skip | `cte_plan.json`, `ctes/`, `cte_tests.json` |
|
|
| F7 | SQL finale | `kind:phase` dopo `sql_approved` | `sql_final.sql` |
|
|
| F8 | datamart | `reviewer_decide` | decisione su richiesta o rifiuto |
|
|
|
|
Un `reviewer_select` con decisione incorporata può confermare direttamente. Un `reviewer_decide` registra le scelte multiple. Un `reviewer_confirm` conferma un artefatto o la chiusura della fase. Il modello propone; il revisore decide e il ledger registrato è la fonte dello stato.
|