Standard CLI behavior:
- Up/Down = command history (always)
- Page Up/Down = scroll output (no focus needed)
- Ctrl+Home/End = jump to top/bottom
- Mouse/scrollbar works too
Removed Tab focus switching - not intuitive for CLI users.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use Condition wrapper with try/except to handle case where
self.app doesn't exist yet during key binding setup.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Up/Down move cursor one line (scrolls view)
- Page Up/Down move 20 lines at a time
- Home/End jump to top/bottom
- Keys only active when output buffer is focused (Tab to switch)
- Updated help text with scroll shortcuts
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
FormattedTextControl doesn't support scrolling - always renders from top.
Switch to Buffer + BufferControl which has proper scroll support:
- Output buffer uses read-only Buffer with cursor at end
- Tab/Shift-Tab to switch focus between output and input
- Arrow keys scroll when output is focused
- Scrollbar margin shows position
- Auto-scroll on new content (cursor stays at end)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Window.vertical_scroll is read-only in prompt_toolkit.
Use custom scroll_offset to track position and slice output lines.
- scroll_offset=0 shows newest content (auto-scroll)
- Page Up increases offset (scroll into history)
- Page Down decreases offset (towards newest)
- Home/End jump to top/bottom
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Page Up/Down, Home/End key bindings for manual scrolling
- Track user_scrolled flag to preserve position when user scrolls
- Remove visible_lines limit to show full history
- Auto-scroll to bottom on new content (unless user scrolled up)
- Update help text with scroll shortcuts
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Set vertical_scroll=999999 to always show newest content
- Update scroll position on every invalidate
- Reduced visible_lines to 20 for safety
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use HSplit with filler + output to push content to bottom
- Output window uses dont_extend_height so it only takes needed space
- Empty filler expands to fill remaining space above
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Instead of trying to scroll the window, just display the most
recent lines that fit on screen. Full history is kept but only
the last 50 lines are rendered.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create separate console_registry module to avoid __main__ vs module import issue
- Handler now correctly finds TUI console instance
- Response output should now appear in TUI output area
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove patch_stdout (was buffering until exit)
- Add 100ms refresh loop that periodically invalidates the app
- Ensures output buffer changes are displayed in real-time
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add patch_stdout to capture external prints in TUI mode
- Any stdout from handlers/pump appears in output area, not prompt
- Simplify response handler logic
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add thread-safe invalidation for cross-task updates
- Fix response handler to properly route to TUI output
- Add debug output if console hook fails
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New console features:
- Scrolling output area above separator line
- Status bar with organism name
- Input area at bottom
- Color-coded messages by source
- Command history with up/down arrows
- Graceful fallback to simple mode on unsupported terminals
Usage:
python run_organism.py # TUI mode (or fallback)
python run_organism.py --simple # Force simple mode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Import `complete` not `generate` from agentserver.llm
- Pass `model` parameter required by router
- Return response.content (string) not response object
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Platform architecture for trusted orchestration:
- PromptRegistry: immutable system prompts per agent, loaded at bootstrap
- platform.complete(): assembles LLM calls (prompt + history + user msg)
- Handlers use platform API, cannot see/modify prompts
- organism.yaml now supports prompt field per listener
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Shows last 20 messages from a specific thread or last 5 per thread
when using /monitor *. Color-coded by direction (console=green,
responses=cyan).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- SecureConsole with Argon2id password hashing
- Password stored in ~/.xml-pipeline/console.key
- Protected commands require password re-entry
- Attach/detach model with idle timeout
- Fallback to simple input for incompatible terminals
- @listener message injection into pump
- Boot handler no longer sends to old console
- Response handler prints to stdout with prompt refresh
Dependencies: argon2-cffi, prompt_toolkit
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Handlers now receive payload references directly from the context
buffer slot rather than independent copies. Metadata is derived
via slot_to_handler_metadata() ensuring consistency.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements an observer pattern where agents can register watchers
for conditions on their thread. When the condition is met, the
agent gets "nagged" on subsequent invocations until it explicitly
closes the todo.
Key components:
- TodoRegistry: thread-scoped watcher tracking with eyebrow state
- TodoUntil/TodoComplete payloads and system handlers
- HandlerMetadata.todo_nudge for delivering raised eyebrow notices
- Integration in StreamPump dispatch to check and nudge
Greeter now demonstrates the pattern:
1. Registers watcher for ShoutedResponse from shouter
2. On next invocation, sees nudge and closes completed todos
3. Includes nudge in LLM prompt for awareness
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Major refactor of the message pump architecture:
- Replace bus.py with stream_pump.py using aiostream for composable
stream processing with natural fan-out via flatmap
- Add to_id field to MessageState for explicit routing
- Fix routing to use to_id.class format (e.g., "greeter.greeting")
- Generate XSD schemas from xmlified payload classes
- Fix xmlable imports (absolute -> relative) and parse_element ctx
New features:
- handlers/hello.py: Sample Greeting/GreetingResponse handler
- config/organism.yaml: Sample organism configuration
- 41 tests (31 unit + 10 integration) all passing
Schema changes:
- envelope.xsd: Allow any namespace payloads (##other -> ##any)
Dependencies added to pyproject.toml:
- aiostream>=0.5 (core dependency)
- pyhumps, termcolor (for xmlable)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Minimal, universal base for all capabilities
- Required listens_to class attribute
- Async handle() with convo_id preservation rule
- make_response() helper for thread continuity
- Explicit name, config, per-instance logger
- Clear documentation and NotImplementedError guard
This is the true substrate the entire organism will build on.