A local-first desktop assistant with memory, Telegram control, PC automation, and screen vision.
Talk to it in the terminal. Message it from Telegram. Let it open apps, manage tasks, send reminders, read the screen, and interact with your desktop.
| Area | Implemented |
|---|---|
| Agent | LangGraph ReAct agent with tool calling and multi-step execution |
| Interfaces | Terminal chat and Telegram text/voice interface |
| Memory | Long-term memory with per-query memory refresh |
| Productivity | Alarms, reminders, Google Calendar, Google Tasks |
| Communication | Gmail send/read/search, Telegram notifications |
| PC control | Open/close/focus apps, list windows, screenshots, mouse/keyboard, volume, brightness, lock screen |
| Vision | Screen description, text extraction, find-and-click style UI interaction |
| Debugging | Clear tool-call tracing plus JSONL query/result logs |
Phase 1: LangGraph agent foundationPhase 2: Long-term memoryPhase 3: Telegram interface and shared assistant runtimePhase 4: Deterministic Windows PC automationPhase 5: Screen vision and vision-guided mouse automationThis README documents the project as currently implemented through Phase 5.
You type or send a message
|
v
LangGraph agent decides what to do
|
+--> calls tools for apps, tasks, mail, reminders, Telegram, PC control
|
+--> calls vision tools when UI needs to be located on screen
|
v
Tsuzi returns a short assistant response
|
+--> optionally speaks it aloud
+--> logs the full tool trace for debugging
flowchart TD
A[Terminal Input / Telegram Message / Telegram Voice] --> B[LangGraph ReAct Agent]
B --> C[Long-Term Memory]
B --> D[Wrapped Tools]
D --> E[Google Calendar / Tasks / Gmail]
D --> F[Windows Automation]
D --> G[Telegram Bot]
D --> H[Screen Vision]
H --> I[NVIDIA or Ollama Vision Model]
B --> J[Ollama Text Model]
B --> K[TTS Output]
B --> L[Debug Trace Logs]
"open chrome and search for LangGraph"
"what windows are open right now?"
"send me a screenshot on Telegram"
"click the search bar and type github"
"read the text on the current screen"
"set an alarm for 7:00 am called workout"
"add a task to finish the README"
"email me the reminder summary"
set_alarmcreate_calendar_eventget_upcoming_eventsadd_taskget_taskscomplete_tasksend_emailread_emailssearch_emailsopen_appclose_applist_open_windowsfocus_appminimize_alltake_screenshot_toolscreenshot_to_telegramclick_attype_text_toolpress_keyboard_keyhotkey_toolcontrol_volumecontrol_brightnesslock_screen_toolget_pc_statusfind_and_clickfind_and_double_clickfind_and_right_clickfind_and_typewhat_is_on_screenread_text_on_screensrc/
├── main.py # terminal + Telegram runtime
├── graph/
│ └── agent.py # LangGraph agent, prompt flow, debug tracing
├── tools/
│ ├── wrapped_tools.py # tool registry exposed to the agent
│ ├── google/ # Gmail, Calendar, Tasks integration
│ └── pc_automation/ # Windows automation helpers
├── interfaces/
│ └── telegram_bot.py # Telegram bot interface
├── services/
│ └── send_reminder.py # reminder delivery via email + Telegram
├── vision/
│ └── screen_vision.py # screen understanding and element finding
├── memory/
│ └── long_term_memory.py # persistent memory storage
└── utils/
└── config.py # environment-driven configuration
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
requirements.txt is the source of truth for runtime dependencies. The
pyproject.toml file stores project metadata and pytest settings only.
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
Tsuzi can use NVIDIA for cloud vision and keep Ollama as the local fallback.
If VISION_PROVIDER=auto, NVIDIA is used when NVIDIA_API_KEY is set;
otherwise the local Ollama vision path is used.
OLLAMA_MODELqwen/qwen3.5-122b-a10bqwen3.5:4bRotate any NVIDIA key that has been pasted into chat or logs before storing it
in .env.
.envOLLAMA_MODEL=qwen3.5:4b
VISION_PROVIDER=auto
NVIDIA_API_KEY=your_rotated_nvidia_key
# Leave VISION_MODEL unset to use provider-aware defaults, or override it:
# VISION_MODEL=qwen/qwen3.5-122b-a10b
VISION_TEMPERATURE=0.6
VISION_TOP_P=0.95
VISION_MAX_COMPLETION_TOKENS=16384
# Local Ollama fallback settings
VISION_MODEL_HOST=http://localhost:11434
VISION_NUM_GPU=99
DEBUG_MODE=true
TELEGRAM_BOT_TOKEN=your_bot_token
TELEGRAM_ALLOWED_USER_ID=your_numeric_user_id
GMAIL_ADDRESS=you@gmail.com
GMAIL_APP_PASSWORD=your_app_password
REMINDER_EMAIL=you@gmail.com
python -m src.main
Use the safe smoke gate before opening a PR or starting a new phase:
python -m pytest --collect-only -q --no-test-report
python -m pytest -q -m safe_smoke --no-test-report
The safe smoke suite is deterministic and avoids desktop automation, network, Telegram, Google credentials, Ollama calls, and generated test reports.
Backup artifacts should be compared before deletion. During the readiness audit,
flow.ipynb.bak and phase5_plan.md.bak were preserved because they differ from
their originals; future *.bak files are ignored.
Manual/local tests are still useful, but some of them may open apps, alter
desktop state, use network services, or write ignored files under
tests/test_results/. Those tests are marked with side_effect where practical:
python -m pytest
python tests/run_tests.py --quick
For PRs, use the Safe smoke GitHub Actions workflow as the required baseline,
then request CodeRabbit/GitHub review for the stabilization PR.
When DEBUG_MODE=true, Tsuzi prints a concise trace like this:
[debug][terminal_text][a1b2c3d4] Query: open chrome and search for github
[debug][terminal_text][a1b2c3d4] Calling tool: open_app | args: {"app_name":"chrome"}
[debug][terminal_text][a1b2c3d4] Tool result: open_app -> Opened chrome, master.
[debug][terminal_text][a1b2c3d4] Calling tool: find_and_click | args: {"description":"search bar"}
[debug][terminal_text][a1b2c3d4] Final response: Done, master.
Structured query traces are written to:
logs/agent_traces/agent_trace_YYYYMMDD.jsonl
Each record includes:
Phase 5 is implemented as tool-driven vision, not as a raw multimodal chat UI.
VISION_PROVIDER=ollama if screen images must stay local.It gives you a clean ReAct loop, tool calling, per-thread short-term memory, and a structure that can grow into more autonomous flows without rewriting the assistant from scratch.
The agent sees a compact, well-documented tool interface while the real implementation details stay isolated in service and automation modules.
Raw framework traces are noisy. The current debug path is intentionally narrow: show the query, tool calls, tool outputs, final answer, and keep the rest in JSONL logs for later analysis.
The broader roadmap continues beyond this point, but the repository currently reflects completed work through Phase 5. The next layers would build on this base rather than replace it.
MIT
32 commits
Python
100.0%
A local-first desktop assistant with memory, Telegram control, PC automation, and screen vision.
Talk to it in the terminal. Message it from Telegram. Let it open apps, manage tasks, send reminders, read the screen, and interact with your desktop.
| Area | Implemented |
|---|---|
| Agent | LangGraph ReAct agent with tool calling and multi-step execution |
| Interfaces | Terminal chat and Telegram text/voice interface |
| Memory | Long-term memory with per-query memory refresh |
| Productivity | Alarms, reminders, Google Calendar, Google Tasks |
| Communication | Gmail send/read/search, Telegram notifications |
| PC control | Open/close/focus apps, list windows, screenshots, mouse/keyboard, volume, brightness, lock screen |
| Vision | Screen description, text extraction, find-and-click style UI interaction |
| Debugging | Clear tool-call tracing plus JSONL query/result logs |
Phase 1: LangGraph agent foundationPhase 2: Long-term memoryPhase 3: Telegram interface and shared assistant runtimePhase 4: Deterministic Windows PC automationPhase 5: Screen vision and vision-guided mouse automationThis README documents the project as currently implemented through Phase 5.
You type or send a message
|
v
LangGraph agent decides what to do
|
+--> calls tools for apps, tasks, mail, reminders, Telegram, PC control
|
+--> calls vision tools when UI needs to be located on screen
|
v
Tsuzi returns a short assistant response
|
+--> optionally speaks it aloud
+--> logs the full tool trace for debugging
flowchart TD
A[Terminal Input / Telegram Message / Telegram Voice] --> B[LangGraph ReAct Agent]
B --> C[Long-Term Memory]
B --> D[Wrapped Tools]
D --> E[Google Calendar / Tasks / Gmail]
D --> F[Windows Automation]
D --> G[Telegram Bot]
D --> H[Screen Vision]
H --> I[NVIDIA or Ollama Vision Model]
B --> J[Ollama Text Model]
B --> K[TTS Output]
B --> L[Debug Trace Logs]
"open chrome and search for LangGraph"
"what windows are open right now?"
"send me a screenshot on Telegram"
"click the search bar and type github"
"read the text on the current screen"
"set an alarm for 7:00 am called workout"
"add a task to finish the README"
"email me the reminder summary"
set_alarmcreate_calendar_eventget_upcoming_eventsadd_taskget_taskscomplete_tasksend_emailread_emailssearch_emailsopen_appclose_applist_open_windowsfocus_appminimize_alltake_screenshot_toolscreenshot_to_telegramclick_attype_text_toolpress_keyboard_keyhotkey_toolcontrol_volumecontrol_brightnesslock_screen_toolget_pc_statusfind_and_clickfind_and_double_clickfind_and_right_clickfind_and_typewhat_is_on_screenread_text_on_screensrc/
├── main.py # terminal + Telegram runtime
├── graph/
│ └── agent.py # LangGraph agent, prompt flow, debug tracing
├── tools/
│ ├── wrapped_tools.py # tool registry exposed to the agent
│ ├── google/ # Gmail, Calendar, Tasks integration
│ └── pc_automation/ # Windows automation helpers
├── interfaces/
│ └── telegram_bot.py # Telegram bot interface
├── services/
│ └── send_reminder.py # reminder delivery via email + Telegram
├── vision/
│ └── screen_vision.py # screen understanding and element finding
├── memory/
│ └── long_term_memory.py # persistent memory storage
└── utils/
└── config.py # environment-driven configuration
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
requirements.txt is the source of truth for runtime dependencies. The
pyproject.toml file stores project metadata and pytest settings only.
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
Tsuzi can use NVIDIA for cloud vision and keep Ollama as the local fallback.
If VISION_PROVIDER=auto, NVIDIA is used when NVIDIA_API_KEY is set;
otherwise the local Ollama vision path is used.
OLLAMA_MODELqwen/qwen3.5-122b-a10bqwen3.5:4bRotate any NVIDIA key that has been pasted into chat or logs before storing it
in .env.
.envOLLAMA_MODEL=qwen3.5:4b
VISION_PROVIDER=auto
NVIDIA_API_KEY=your_rotated_nvidia_key
# Leave VISION_MODEL unset to use provider-aware defaults, or override it:
# VISION_MODEL=qwen/qwen3.5-122b-a10b
VISION_TEMPERATURE=0.6
VISION_TOP_P=0.95
VISION_MAX_COMPLETION_TOKENS=16384
# Local Ollama fallback settings
VISION_MODEL_HOST=http://localhost:11434
VISION_NUM_GPU=99
DEBUG_MODE=true
TELEGRAM_BOT_TOKEN=your_bot_token
TELEGRAM_ALLOWED_USER_ID=your_numeric_user_id
GMAIL_ADDRESS=you@gmail.com
GMAIL_APP_PASSWORD=your_app_password
REMINDER_EMAIL=you@gmail.com
python -m src.main
Use the safe smoke gate before opening a PR or starting a new phase:
python -m pytest --collect-only -q --no-test-report
python -m pytest -q -m safe_smoke --no-test-report
The safe smoke suite is deterministic and avoids desktop automation, network, Telegram, Google credentials, Ollama calls, and generated test reports.
Backup artifacts should be compared before deletion. During the readiness audit,
flow.ipynb.bak and phase5_plan.md.bak were preserved because they differ from
their originals; future *.bak files are ignored.
Manual/local tests are still useful, but some of them may open apps, alter
desktop state, use network services, or write ignored files under
tests/test_results/. Those tests are marked with side_effect where practical:
python -m pytest
python tests/run_tests.py --quick
For PRs, use the Safe smoke GitHub Actions workflow as the required baseline,
then request CodeRabbit/GitHub review for the stabilization PR.
When DEBUG_MODE=true, Tsuzi prints a concise trace like this:
[debug][terminal_text][a1b2c3d4] Query: open chrome and search for github
[debug][terminal_text][a1b2c3d4] Calling tool: open_app | args: {"app_name":"chrome"}
[debug][terminal_text][a1b2c3d4] Tool result: open_app -> Opened chrome, master.
[debug][terminal_text][a1b2c3d4] Calling tool: find_and_click | args: {"description":"search bar"}
[debug][terminal_text][a1b2c3d4] Final response: Done, master.
Structured query traces are written to:
logs/agent_traces/agent_trace_YYYYMMDD.jsonl
Each record includes:
Phase 5 is implemented as tool-driven vision, not as a raw multimodal chat UI.
VISION_PROVIDER=ollama if screen images must stay local.It gives you a clean ReAct loop, tool calling, per-thread short-term memory, and a structure that can grow into more autonomous flows without rewriting the assistant from scratch.
The agent sees a compact, well-documented tool interface while the real implementation details stay isolated in service and automation modules.
Raw framework traces are noisy. The current debug path is intentionally narrow: show the query, tool calls, tool outputs, final answer, and keep the rest in JSONL logs for later analysis.
The broader roadmap continues beyond this point, but the repository currently reflects completed work through Phase 5. The next layers would build on this base rather than replace it.
MIT
32 commits
Python
100.0%