-
Notifications
You must be signed in to change notification settings - Fork 0
packages coding agent interactive mode
Active contributors: Mario Zechner, kt, Armin Ronacher
Interactive mode is the terminal chat UI for Prime Agent. It renders the conversation, the prompt editor, tool output, and the working indicator on top of the @earendil-works/pi-tui rendering engine, and drives the session exclusively through the AgentConnection seam (packages/coding-agent/src/modes/agent-connection/types.ts). It works identically against an in-process runtime (InProcessAgentConnection) and the background daemon (DaemonAgentConnection); process-local extension surfaces degrade gracefully on daemon transports via tryExtensionSurface and AgentConnectionUnsupportedError. All the code lives under packages/coding-agent/src/modes/interactive/.
packages/coding-agent/src/modes/interactive/
agent-activity.ts # Derives the live working state (waiting/thinking/writing/...)
auth-flows.ts # Provider login/logout dialogs and OAuth selectors
feature-hints.ts # Rotating feature hint deck
heartbeat-scope.ts # Heartbeat scope helpers
image-markers.ts # Image content markers for the transcript
interactive-mode-services.ts # Client-local services (settings, registry, themes)
interactive-mode.ts # InteractiveMode: the full terminal UI (~9800 lines)
onboarding.ts # First-run onboarding decision (prime cli splash, missing auth)
prompt-stash-state.ts # Draft prompt stash/restore (Ctrl+S)
resume-hint.ts # Hint shown on startup about resume
components/ # All TUI components (57 files, see below)
theme/ # Theme registry, editor theme, code highlighter
The components/ directory holds every UI piece: agent-message.ts and assistant-message.ts (message renderers), bash-execution.ts (the ! / !! shell runner), config-selector.ts and configuration-menu.ts (the config command and settings tabs), context-tree-format.ts, conversation-components.ts, custom-editor.ts (the default editor), custom-message.ts, countdown-timer.ts, bordered-loader.ts, centered-overlay.ts, collapsible-error.ts, compaction-outcome-message.ts, compaction-summary-message.ts, branch-summary-message.ts, plus tool-execution.ts, ipython-cell.ts, login-dialog.ts, oauth-selector.ts, model-selector.ts, settings-selector.ts, tree-selector.ts, footer.ts, and many more (see components/index.ts).
| Type | Path | One-line description |
|---|---|---|
InteractiveMode |
packages/coding-agent/src/modes/interactive/interactive-mode.ts |
The terminal chat UI: renders the conversation, editor, queue, and side questions |
AgentConnection |
packages/coding-agent/src/modes/agent-connection/types.ts |
The typed client seam InteractiveMode consumes; never touches session internals |
AgentActivityTracker |
packages/coding-agent/src/modes/interactive/agent-activity.ts |
Turns the event stream into a live working state and output-token count |
ProviderAuthFlows |
packages/coding-agent/src/modes/interactive/auth-flows.ts |
Runs the /login provider selector and OAuth/API-key dialogs |
InteractiveModeUiServices |
packages/coding-agent/src/modes/interactive/interactive-mode-services.ts |
Client-local settings, model registry, and theme access, separate from AgentConnection
|
CustomEditor |
packages/coding-agent/src/modes/interactive/components/custom-editor.ts |
Default editor component implementing EditorComponent from packages/tui/src/editor-component.ts
|
KeybindingsManager |
packages/coding-agent/src/core/keybindings.ts |
App + TUI keybinding definitions, user overrides from ~/.prime/agent/keybindings.json
|
ClientPromptStashStore |
packages/coding-agent/src/modes/interactive/prompt-stash-state.ts |
Durable draft stash/restore for prompts |
main.ts constructs InteractiveMode with an AgentConnection plus InteractiveModeUiServices. In-process sessions pass InProcessAgentConnection and bindLocalSessionExtensions: true; daemon-backed interactive sessions pass DaemonAgentConnection and bindLocalSessionExtensions: false. The UI subscribes to session events through the connection, renders them with the TUI, and sends every user action back through agentConnection.prompt (with streamingBehavior: "steer" | "followUp" and queueIfBusy).
graph TD
A[InteractiveMode.run] --> B[TUI engine (packages/tui)]
B --> C[CustomEditor / EditorComponent]
C -->|submit| D{queue behavior}
D -->|Enter| E[steer: after current turn's tools]
D -->|Alt+Enter| F[follow-up: after all work]
E --> G[AgentConnection.prompt]
F --> G
G --> H{connection type}
H -->|InProcessAgentConnection| I[AgentSessionRuntime in-process]
H -->|DaemonAgentConnection| J[DaemonClient to daemon worker]
I -->|session events| K[event loop]
J -->|session_event stream| K
K --> L[AgentActivityTracker]
K --> M[message / tool / compaction components]
K --> N[tryExtensionSurface fallback]
The editor interface is EditorComponent in packages/tui/src/editor-component.ts; interactive mode's default implementation is CustomEditor in packages/coding-agent/src/modes/interactive/components/custom-editor.ts. It supports @ file reference completion, path completion, multi-line input, pasted images, !command / !!command shell execution (rendered by bash-execution.ts), and Ctrl+G to open the external $VISUAL/$EDITOR. Extensions can replace it through the editor factory on the process-local extension surface.
Typing / opens command completion driven by packages/coding-agent/src/core/slash-commands.ts (BUILTIN_SLASH_COMMANDS); the full catalog is on the slash commands page. Keybindings are defined in packages/coding-agent/src/core/keybindings.ts (app-level app.* plus TUI_KEYBINDINGS from packages/tui), are remappable in ~/.prime/agent/keybindings.json, and are never hardcoded per the repo convention. Examples: Ctrl+C interrupt/exit, Escape clears, Ctrl+L model selector, Ctrl+T thinking toggle, Ctrl+O tool output, Alt+Enter follow-up queue, Alt+Up dequeue, Ctrl+S prompt stash, Ctrl+G external editor.
While the agent is working, Enter queues a steering message (delivered after the current assistant turn finishes its tool calls) and Alt+Enter queues a follow-up (delivered after all work completes). Both are AgentConnection prompts with streamingBehavior set; queue state is tracked locally in connectionQueue and echoed by session_action_update events from the connection, and delivery modes are configurable via steeringMode / followUpMode settings. Queued messages can be pulled back into the editor with Alt+Up.
/login runs ProviderAuthFlows.runLogin (auth-flows.ts). It lists providers by category (OAuth subscription providers, built-in API-key providers, and service credentials such as web search), shows OAuthSelectorComponent or LoginDialogComponent, and writes credentials to auth.json (getAuthPath() in packages/coding-agent/src/config.ts). MCP integrations authenticate through runMcpLogin as mcp:<server> service credentials. The same flows are reused by the agents view, and hosts get onAuthChanged / onLoginCompleted hooks.
The AgentConnection.extensions sub-interface (argument completions, diagnostics, keyboard shortcuts, message/tool renderers, editor replacement) is permanently process-local. Daemon adapters throw AgentConnectionUnsupportedError from those members. Interactive mode wraps every extension read in tryExtensionSurface / tryExtensionSurfaceAsync, which catch AgentConnectionUnsupportedError and fall back to safe defaults, so interactive startup and chat work unchanged over the daemon. Extension UI dialogs on the daemon travel as extension_ui_request events handled by the interactive mode, mirroring the extension_ui client capability.
-
main.tsbuilds the connection (InProcessAgentConnectionorDaemonAgentConnectionviacreateDaemonClientConnection) and the UI services, then runsInteractiveMode. The agents view (packages/coding-agent/src/modes/agents-view/) reusesInteractiveModefor per-session chat and the same auth flows. - Everything interactive reads and writes the session through
AgentConnection; the daemon adapter (packages/coding-agent/src/modes/agent-connection/daemon-agent-connection.ts) maps it onto the daemon protocol. - The TUI engine, editor, and rendering primitives come from
packages/tui; themes and the code highlighter come frompackages/coding-agent/src/modes/interactive/theme/.
- Add a new chat UI feature: touch
interactive-mode.tsand a component underpackages/coding-agent/src/modes/interactive/components/, keeping all session access onAgentConnection. - Add a keybinding: extend
KEYBINDINGSinpackages/coding-agent/src/core/keybindings.ts(defaults belong there, not inmatchesKeycall sites). - Add an auth provider or login flow: extend
auth-flows.tsand the selectors incomponents/. - Change how the connection degrades: update
tryExtensionSurfaceininteractive-mode.tsand theAgentConnectionUnsupportedErrorcontract inpackages/coding-agent/src/modes/agent-connection/.
| File | Why it matters |
|---|---|
packages/coding-agent/src/modes/interactive/interactive-mode.ts |
The whole terminal UI |
packages/coding-agent/src/modes/agent-connection/types.ts |
The AgentConnection contract interactive mode depends on |
packages/coding-agent/src/modes/interactive/auth-flows.ts |
Login/logout and provider selection |
packages/coding-agent/src/modes/interactive/agent-activity.ts |
Live working state and token counting |
packages/coding-agent/src/modes/interactive/components/custom-editor.ts |
Default prompt editor |
packages/coding-agent/src/core/keybindings.ts |
Keybinding definitions and user overrides |
packages/coding-agent/src/core/slash-commands.ts |
Built-in slash command catalog |
- CLI : how interactive mode is launched and selected
- Daemon : the daemon transport and attach/reconnect
- Package overview : SDK surface and package layout
- Terminal UI : the rendering engine underneath
- Slash commands : the full command catalog
- Architecture : the connection seam