95 lines
3.7 KiB
Python

"""Centralised session-state initialisation for the Streamlit app.
All keys used throughout the app are declared here with their default values.
Calling init_state() at the top of app.py ensures every key exists before any
page tries to read it, preventing KeyError on the first load.
"""
import streamlit as st
from backend.managers.chat_manager import ChatManager
def init_state():
# Sidebar state initialization
# last_selected tracks the previously clicked tree node to detect new clicks
if "last_selected" not in st.session_state:
st.session_state.last_selected = None
# Absolute path and workspace-relative path of the currently highlighted folder
if "selected_folder" not in st.session_state:
st.session_state.selected_folder = None
if "selected_folder_rel" not in st.session_state:
st.session_state.selected_folder_rel = None
# Chat manager (persists across reruns)
# ChatManager keeps the full conversation history in memory across reruns
if "chat_manager" not in st.session_state:
st.session_state.chat_manager = ChatManager()
# Editor state initialization
# List of absolute file paths that are currently open as tabs
if "open_files" not in st.session_state:
"""A list of currently open file paths - absolute paths only. The order determines the tab order in the UI.
Format: [ "path/to/file1.py", "path/to/file2.js", ... ]
"""
st.session_state.open_files = []
# Dict mapping file path → current editor content (may be unsaved)
if "files_content" not in st.session_state:
"""A dictionary mapping file paths to their current content in the editor.
Format: { "path/to/file.py": "file content as string", ... }
"""
st.session_state.files_content = {}
# Absolute path of the file whose tab is currently active
if "active_file" not in st.session_state:
"""The currently active file in the editor (absolute path in string e.g. "/workspace/path/to/file.py").
Should be one of the paths in open_files or None if no file is open."""
st.session_state.active_file = None
# Index of the active tab (used by st.tabs)
if "active_tab" not in st.session_state:
st.session_state.active_tab = 0
if "is_editing" not in st.session_state:
st.session_state.is_editing = False
if "code_suggestions" not in st.session_state:
st.session_state.code_suggestions = []
# Output dict from the last code run: {stdout, stderr, return_code}
if "code_execution_output" not in st.session_state:
st.session_state.code_execution_output = ""
# Chat state initialization
# Flat list of {"role": ..., "content": ...} dicts shown as chat bubbles
if "chat_history" not in st.session_state:
st.session_state.chat_history = []
# Agent Mode state
# Whether the UI is currently in Agent Mode (vs normal chat)
if "agent_mode" not in st.session_state:
st.session_state.agent_mode = False
# The live CodingAgent instance while a task is running
if "coding_agent" not in st.session_state:
st.session_state.coding_agent = None
# Current status of the agent: "idle" | "waiting_approval" | "done"
if "agent_status" not in st.session_state:
st.session_state.agent_status = "idle"
# List of completed steps shown in the collapsible Agent Log
if "agent_log" not in st.session_state:
st.session_state.agent_log = []
# The action the agent proposed but has not yet been approved or rejected
if "agent_pending_action" not in st.session_state:
st.session_state.agent_pending_action = None
if __name__ == "__main__":
init_state()