Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 26 additions & 17 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,32 @@ Agents can respond with just `PASS` if they genuinely have nothing meaningful to
Beyond the configured turn interval, the `needs_human_input()` method performs an additional check: if the **last agent message explicitly addresses the user by name**, the HITL prompt fires immediately. This ensures the conversation never inadvertently "speaks for" the human participant.

**Decision Flow:**
```
generate_next_turn()
Orchestrator due? → speak (or PASS → skip)
_forced_next_agent set? → use it, clear it
session_type = DYNAMIC?
→ @mention in last message? → forced agent
→ Score all agents by expertise → pick best
→ fallback: round robin
agent.generate_response()
response == "PASS"? → skip, return {skipped: True}
append to history with timestamp, return turn_data
```mermaid
flowchart TD

A[generate_next_turn()] --> B{Orchestrator due?}
B -->|Yes| C[Speak or PASS]
C -->|Speak| EndOrch[Append to history & return turn]
C -->|PASS| D

B -->|No| D{_forced_next_agent set?}
D -->|Yes| E[Use forced agent & clear flag] --> L
D -->|No| F{session_type = DYNAMIC?}

F -->|No| K[Fallback: round robin / argumentative] --> L
F -->|Yes| G{@mention in last message?}

G -->|Yes| H[Use mentioned agent] --> L
G -->|No| I[Score agents by expertise]

I --> J{Top score > 0?}
J -->|Yes| Best[Pick best matching agent] --> L
J -->|No| K

L[agent.generate_response()] --> M{response == PASS?}

M -->|Yes| N[Skip turn, return skipped: True]
M -->|No| O[Append to history with timestamp] --> P[Return turn_data]
```

## Custom Model Integrations (Bring Your Own Code)
Expand Down
Loading