improvments
This commit is contained in:
parent
3891007fb2
commit
efdd9351b3
@ -39,7 +39,7 @@ def main():
|
||||
"""
|
||||
<style>
|
||||
.block-container { padding-top: 1rem; }
|
||||
[data-testid="stSidebarContent"] { padding-top: 0rem; margin-top: -2rem; }
|
||||
[data-testid="stSidebarContent"] { padding-top: 1rem; }
|
||||
</style>
|
||||
""",
|
||||
unsafe_allow_html=True,
|
||||
|
||||
@ -1,18 +1,17 @@
|
||||
"""Chat view — renders both the normal chat interface and the Coding Agent mode."""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import streamlit as st
|
||||
from backend.managers.chat_manager import ChatManager
|
||||
from backend.managers.system_prompter import SystemPrompter
|
||||
from backend.managers.search_manager import SearchManager
|
||||
from backend.agent.coding_agent import CodingAgent
|
||||
|
||||
from backend.managers.debug_logger import get_logger
|
||||
logger = get_logger(__name__)
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
# ── Agent Mode helpers ────────────────────────────────────────────────────────
|
||||
@ -377,6 +376,32 @@ def render_normal_chat():
|
||||
user sends a message, they are prepended to that message as a context block.
|
||||
"""
|
||||
logger.info("Chat mode")
|
||||
chat_manager: ChatManager = st.session_state.chat_manager
|
||||
|
||||
# Apply model/token overrides from the Settings panel before any API call.
|
||||
if st.session_state.get("selected_model"):
|
||||
chat_manager.model = st.session_state.selected_model
|
||||
if "chat_max_tokens" in st.session_state:
|
||||
chat_manager.max_tokens = st.session_state.chat_max_tokens
|
||||
|
||||
# Consume a debug message forwarded from the editor's "Debug with AI" button.
|
||||
pending_debug = st.session_state.pop("pending_debug_message", None)
|
||||
if pending_debug:
|
||||
if not chat_manager.get_history():
|
||||
system_prompt = SystemPrompter.generate_prompt(_build_file_context())
|
||||
chat_manager.add_message("system", system_prompt)
|
||||
with st.spinner("Sending debug info to AI..."):
|
||||
try:
|
||||
ai_response = chat_manager.send_message(pending_debug)
|
||||
except Exception as e:
|
||||
ai_response = f"Error: {e}"
|
||||
st.session_state.chat_history.append({"role": "user", "content": pending_debug})
|
||||
st.session_state.chat_history.append(
|
||||
{"role": "assistant", "content": ai_response}
|
||||
)
|
||||
st.rerun()
|
||||
return
|
||||
|
||||
# Replay the conversation history as chat bubbles (skip system messages).
|
||||
for message in st.session_state.chat_history:
|
||||
if message["role"] == "system":
|
||||
@ -430,7 +455,6 @@ def render_normal_chat():
|
||||
return
|
||||
|
||||
# ── Normal chat message ───────────────────────────────────────────────
|
||||
chat_manager = st.session_state.chat_manager
|
||||
search_results = st.session_state.get("search_results", [])
|
||||
|
||||
# 5g — System-prompt logic: inject on first message, update on file change.
|
||||
@ -473,8 +497,8 @@ def render_normal_chat():
|
||||
if st.button("🗑️ Clear Chat"):
|
||||
_clear_chat_dialog()
|
||||
|
||||
# REVIEW: duplicate widget key — "agent_mode" toggle is already rendered inside render_agent_mode();
|
||||
# having two st.toggle calls with the same key on the same page will raise a DuplicateWidgetID error.
|
||||
# Toggle to switch to Agent Mode (render_normal_chat and render_agent_mode are
|
||||
# mutually exclusive, so the same key here causes no DuplicateWidgetID conflict).
|
||||
st.toggle("Agent Mode", key="agent_mode")
|
||||
|
||||
# 5h — Settings expander: file context toggle, model, token limit, custom prompt.
|
||||
|
||||
@ -126,7 +126,7 @@ def run_active_file():
|
||||
except SyntaxError as e:
|
||||
result = {"stdout": "", "stderr": str(e), "return_code": -1, "ast_error": True}
|
||||
st.session_state.exec_results[active_file] = result
|
||||
debug_logger.log_error(f"Syntax error: {e}")
|
||||
logger.error("Syntax error: %s", e)
|
||||
return result
|
||||
|
||||
with st.spinner(f"Running {Path(active_file).name}..."):
|
||||
|
||||
@ -253,14 +253,29 @@ def build_arborist_tree(tree, parent_path=Path()):
|
||||
|
||||
|
||||
def render_filetree_arborist(tree):
|
||||
"""Render the interactive file tree and return the currently selected node dict."""
|
||||
"""Render the interactive file tree and return the currently selected node dict.
|
||||
|
||||
Passes the active file's relative path as ``selection`` so the tree always
|
||||
highlights whichever file is currently open in the editor, even when the
|
||||
user switches tabs instead of clicking the tree.
|
||||
"""
|
||||
data = build_arborist_tree(tree)
|
||||
|
||||
# Compute the node-ID of the currently active file (posix relative path)
|
||||
# so the tree highlights it regardless of how the tab was opened.
|
||||
active_selection = None
|
||||
active_file = st.session_state.get("active_file")
|
||||
if active_file:
|
||||
try:
|
||||
active_selection = str(Path(active_file).relative_to(fm.base_path).as_posix())
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
selected = tree_view(
|
||||
data=data,
|
||||
icons={"open": "📂", "closed": "📁"},
|
||||
height=400,
|
||||
selection=None,
|
||||
selection=active_selection,
|
||||
select_internal_nodes=True, # allow clicking folder names, not just files
|
||||
open_by_default=True
|
||||
)
|
||||
|
||||
@ -78,6 +78,10 @@ def init_state():
|
||||
if "code_execution_output" not in st.session_state:
|
||||
st.session_state.code_execution_output = ""
|
||||
|
||||
# Per-file execution results: {file_path: {stdout, stderr, return_code, ast_error}}
|
||||
if "exec_results" not in st.session_state:
|
||||
st.session_state.exec_results = {}
|
||||
|
||||
# ── Chat state ────────────────────────────────────────────────────────────
|
||||
|
||||
# Flat list of {"role": ..., "content": ...} dicts rendered as chat bubbles.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user