# jacob-sauve/wallflower architecture

> Architecture diagram of the GitHub repository jacob-sauve/wallflower, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/jacob-sauve/wallflower
- Repository: https://github.com/jacob-sauve/wallflower

## Overview

WallFlower is a Streamlit voice-based study tutor: learners upload notes, speak about the material, and receive Socratic prompts. The UI parses uploads and starts a threaded ElevenLabs conversation; recognized speech is sent to the Gemini-backed tutor, whose response is injected into the live conversation. The README describes course-material-aware feedback, but the sampled runtime drops the uploaded context when starting the conversation, so that connection is not shown as working. The implementation details of audio transport are largely delegated to the ElevenLabs SDK.

Main entry points: [`jamesBond_threaded.py`](https://github.com/jacob-sauve/wallflower/blob/main/jamesBond_threaded.py) (Conversation client), [`streamlit_app.py`](https://github.com/jacob-sauve/wallflower/blob/main/streamlit_app.py) (Streamlit UI), [`interaction.py`](https://github.com/jacob-sauve/wallflower/blob/main/interaction.py) (Socratic response generator)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_interface["Learner interface"]
  node_app["Streamlit UI<br/>[streamlit_app.py]"]
  node_file_parser["Notes parser<br/>[interaction.py]"]
end

subgraph group_conversation["Voice conversation"]
  node_session_runner["Session runner"]
  node_conversation_client["Conversation client"]
  node_audio_interface["Audio interface"]
end

subgraph group_tutoring["Socratic tutoring"]
  node_transcript_handler["Transcript handler"]
  node_tutor["Socratic response generator<br/>[interaction.py]"]
end

node_learner(("Learner"))
node_elevenlabs{{"ElevenLabs service"}}
node_openrouter{{"OpenRouter / Gemini"}}

node_learner -->|"uploads notes / starts session"| node_app
node_app -->|"parses upload"| node_file_parser
node_app -->|"starts thread"| node_session_runner
node_session_runner -->|"creates and starts"| node_conversation_client
node_conversation_client -->|"uses audio"| node_audio_interface
node_conversation_client -->|"starts session"| node_elevenlabs
node_elevenlabs -->|"delivers transcript"| node_transcript_handler
node_transcript_handler -->|"requests prompt"| node_tutor
node_tutor -->|"requests completion"| node_openrouter
node_transcript_handler -->|"sends response"| node_conversation_client
node_elevenlabs -->|"plays spoken response"| node_learner

click node_app "https://github.com/jacob-sauve/wallflower/blob/main/streamlit_app.py"
click node_file_parser "https://github.com/jacob-sauve/wallflower/blob/main/interaction.py"
click node_session_runner "https://github.com/jacob-sauve/wallflower/blob/main/jamesBond_threaded.py"
click node_conversation_client "https://github.com/jacob-sauve/wallflower/blob/main/jamesBond_threaded.py"
click node_audio_interface "https://github.com/jacob-sauve/wallflower/blob/main/jamesBond_threaded.py"
click node_transcript_handler "https://github.com/jacob-sauve/wallflower/blob/main/jamesBond_threaded.py"
click node_tutor "https://github.com/jacob-sauve/wallflower/blob/main/interaction.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_file_parser toneBlue
class node_session_runner,node_conversation_client,node_audio_interface toneAmber
class node_transcript_handler,node_tutor,node_openrouter toneMint
class node_learner,node_elevenlabs toneIndigo
```

## Components

### Learner interface

- [Streamlit UI](https://github.com/jacob-sauve/wallflower/blob/main/streamlit_app.py): `streamlit_app.py`
- [Notes parser](https://github.com/jacob-sauve/wallflower/blob/main/interaction.py): `interaction.py`

### Voice conversation

- [Session runner](https://github.com/jacob-sauve/wallflower/blob/main/jamesBond_threaded.py): `jamesBond_threaded.py`
- [Conversation client](https://github.com/jacob-sauve/wallflower/blob/main/jamesBond_threaded.py): `jamesBond_threaded.py`
- [Audio interface](https://github.com/jacob-sauve/wallflower/blob/main/jamesBond_threaded.py): `jamesBond_threaded.py`

### Socratic tutoring

- [Transcript handler](https://github.com/jacob-sauve/wallflower/blob/main/jamesBond_threaded.py): `jamesBond_threaded.py`
- [Socratic response generator](https://github.com/jacob-sauve/wallflower/blob/main/interaction.py): `interaction.py`

### Other components

- **Learner**
- **ElevenLabs service**
- **OpenRouter / Gemini**

## Connections

- Learner → Streamlit UI: uploads notes / starts session
- Streamlit UI → Notes parser: parses upload
- Streamlit UI → Session runner: starts thread
- Session runner → Conversation client: creates and starts
- Conversation client → Audio interface: uses audio
- Conversation client → ElevenLabs service: starts session
- ElevenLabs service → Transcript handler: delivers transcript
- Transcript handler → Socratic response generator: requests prompt
- Socratic response generator → OpenRouter / Gemini: requests completion
- Transcript handler → Conversation client: sends response
- ElevenLabs service → Learner: plays spoken response
