-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture
Architecture — Title: Architecture
# Architecture
## Loader pattern: one shared namespace
`fw.py` isn't where the logic lives — it's just a **loader**. All the real logic sits in `.fw_data/src/`, split into 12 small modules. At runtime, `fw.py` reads each file in a fixed order and `exec()`s it into **one shared namespace** (a `dict`), behaving exactly like one big monolithic file — there's no `import` between modules.
```python
_MODULES = [
"01_ui.py", "01b_aws.py", "01c_anthropic.py", "02_provider.py",
"03_mcp.py", "04_agent_cache.py", "05_session_db.py",
"06_tools_fs.py", "07_tools_more.py", "08_undo_dispatch.py",
"09_api_system.py", "10_main.py",
]
Since all modules share one namespace, a module can use a global defined by a module that loads after it — as long as that global is only read at call time (runtime), not at module-load time (import-time).
Real example from the project:
06_tools_fs.pyuses the variables_large_read_credits,_file_read_time,_recent_writes,_current_sid— all four are defined in07_tools_more.py(which loads after06). It still works correctly because the functions in06are only called after all 11 modules have finished loading.
NameError that only surfaces while the agent is running (not at load time) — very hard to debug without knowing this architecture beforehand.
| File | Role |
|---|---|
01_ui.py |
Terminal UI: gradient banner, braille spinner, context bar, HAS_RICH guard + ANSI fallback |
01b_aws.py |
AWS Bedrock Converse adapter — includes manual binary event-stream parsing |
01c_anthropic.py |
Anthropic Messages API adapter |
02_provider.py |
Provider registry, API config, custom provider wizard |
03_mcp.py |
MCP (Model Context Protocol) integration |
04_agent_cache.py |
Per-tool permissions, file cache, sandbox enforcement |
05_session_db.py |
SQLite session persistence, tool schemas |
06_tools_fs.py |
Filesystem tools: read, write, edit, multiedit, extract, apply_patch, glob, grep
|
07_tools_more.py |
Extended tools: webfetch, websearch, todowrite, todoread, question, lsp
|
08_undo_dispatch.py |
Undo/redo system + subagent dispatch (task) |
09_api_system.py |
API streaming, system prompt, main agentic loop |
10_main.py |
CLI entrypoint, REPL, slash command handling |
Internally, fw.py only "speaks" one format: OpenAI chat-completions. Two adapter modules (01b_aws.py, 01c_anthropic.py) translate both ways to Anthropic Messages API and AWS Bedrock Converse. As a result:
- Every tool, every prompt, the entire agent loop is written once
- It runs identically across all 12 providers
- Bedrock needs extra binary event-stream parsing — fully isolated inside
01b_aws.py
- Simplicity first — minimum code that solves the actual problem; no features/abstractions/flexibility beyond what's asked; no error handling for situations that can't occur. Ask: "Would a senior engineer call this overcomplicated?"
- Edit the right file according to the module map above — don't put logic in the wrong layer.
- Shared globals → declare them in the most appropriate module, don't duplicate.
- New features affecting more than 2 modules → ask first.
- Files over 80 lines use the section marker pattern:
# ##== NAME ==## ...code... # ##== /end NAME ==##
- No emoji in agent output.
- Termux/Android environment:
pip installalways needs--break-system-packages; nosudo.
➡️ See how the 20 tools are organized in Agent Tools.