auto-coder-web 0.1.91__py3-none-any.whl → 0.1.93__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,6 +16,10 @@ from byzerllm.utils.langutil import asyncfy_with_semaphore
16
16
  from autocoder.common.global_cancel import global_cancel, CancelRequestedException
17
17
  from loguru import logger
18
18
  import byzerllm
19
+ # 导入聊天会话和聊天列表管理器
20
+ from auto_coder_web.common_router.chat_session_manager import read_session_name_sync
21
+ from auto_coder_web.common_router.chat_list_manager import get_chat_list_sync
22
+
19
23
  router = APIRouter()
20
24
 
21
25
  # 创建线程池
@@ -25,6 +29,7 @@ class AutoCommandRequest(BaseModel):
25
29
  command: str
26
30
  include_conversation_history: bool = True
27
31
  buildin_conversation_history: bool = False
32
+ panel_id: Optional[str] = None
28
33
 
29
34
  class EventPollRequest(BaseModel):
30
35
  event_file_id:str
@@ -102,40 +107,39 @@ async def auto_command(request: AutoCommandRequest, project_path: str = Depends(
102
107
 
103
108
  if request.include_conversation_history:
104
109
  # 获取当前会话名称
105
- current_session_file = os.path.join(project_path, ".auto-coder", "auto-coder.web", "current-session.json")
110
+ panel_id = request.panel_id or ""
106
111
  current_session_name = ""
107
- if os.path.exists(current_session_file):
108
- try:
109
- with open(current_session_file, 'r',encoding="utf-8") as f:
110
- session_data = json.load(f)
111
- current_session_name = session_data.get("session_name", "")
112
- except Exception as e:
113
- logger.error(f"Error reading current session: {str(e)}")
114
- logger.exception(e)
112
+ try:
113
+ # 使用chat_session_manager模块获取当前会话名称
114
+ # 使用同步版本的函数,避免在线程中使用asyncio.run
115
+ current_session_name = read_session_name_sync(project_path, panel_id)
116
+ except Exception as e:
117
+ logger.error(f"Error reading current session: {str(e)}")
118
+ logger.exception(e)
115
119
 
116
120
  # 获取历史消息
117
121
  messages = []
118
122
  if current_session_name:
119
- chat_list_file = os.path.join(project_path, ".auto-coder", "auto-coder.web", "chat-lists", f"{current_session_name}.json")
120
- logger.info(f"loading chat history from {chat_list_file}")
121
- if os.path.exists(chat_list_file):
122
- try:
123
- with open(chat_list_file, 'r', encoding="utf-8") as f:
124
- chat_data = json.load(f)
125
- # 从聊天历史中提取消息
126
- for msg in chat_data.get("messages", []):
127
- # if msg.get("metadata",{}).get("stream_out_type","") == "/agent/edit":
128
- # messages.append(msg)
129
- # continue
130
-
131
- # if msg.get("type","") not in ["USER_RESPONSE","RESULT","COMPLETION"]:
132
- # continue
133
- if msg.get("contentType","") in ["token_stat"]:
134
- continue
135
- messages.append(msg)
136
- except Exception as e:
137
- logger.error(f"Error reading chat history: {str(e)}")
138
- logger.exception(e)
123
+ try:
124
+ # 使用chat_list_manager模块获取聊天列表内容
125
+ logger.info(f"Loading chat history for session: {current_session_name}")
126
+ # 使用同步版本的函数,避免在线程中使用asyncio.run
127
+ chat_data = get_chat_list_sync(project_path, current_session_name)
128
+
129
+ # 从聊天历史中提取消息
130
+ for msg in chat_data.get("messages", []):
131
+ # if msg.get("metadata",{}).get("stream_out_type","") == "/agent/edit":
132
+ # messages.append(msg)
133
+ # continue
134
+
135
+ # if msg.get("type","") not in ["USER_RESPONSE","RESULT","COMPLETION"]:
136
+ # continue
137
+ if msg.get("contentType","") in ["token_stat"]:
138
+ continue
139
+ messages.append(msg)
140
+ except Exception as e:
141
+ logger.error(f"Error reading chat history: {str(e)}")
142
+ logger.exception(e)
139
143
 
140
144
  if messages:
141
145
  # 调用coding_prompt生成包含历史消息的提示
@@ -0,0 +1,159 @@
1
+ import os
2
+ import json
3
+ import aiofiles
4
+ from fastapi import APIRouter, HTTPException, Request, Depends
5
+ from pydantic import BaseModel
6
+ from pathlib import Path
7
+ from typing import List, Optional
8
+
9
+ router = APIRouter()
10
+
11
+ # 定义数据模型
12
+ class ChatTab(BaseModel):
13
+ id: str
14
+ name: str
15
+
16
+ class ChatPanelsConfig(BaseModel):
17
+ tabs: List[ChatTab] = [
18
+ ChatTab(id="main", name="主线面板"),
19
+ ChatTab(id="secondary", name="支线面板")
20
+ ]
21
+ activeTabId: str = "main"
22
+
23
+ async def get_project_path(request: Request) -> str:
24
+ """从FastAPI请求上下文中获取项目路径"""
25
+ return request.app.state.project_path
26
+
27
+ async def get_config_path(project_path: str) -> Path:
28
+ """获取聊天面板配置文件路径"""
29
+ config_path = Path(project_path) / ".auto-coder" / "auto-coder.web" / "chat_panels.json"
30
+ config_path.parent.mkdir(parents=True, exist_ok=True)
31
+ return config_path
32
+
33
+ async def load_config(config_path: Path) -> ChatPanelsConfig:
34
+ """加载聊天面板配置"""
35
+ if not config_path.exists():
36
+ return ChatPanelsConfig()
37
+
38
+ try:
39
+ async with aiofiles.open(config_path, mode='r', encoding='utf-8') as f:
40
+ content = await f.read()
41
+ config_data = json.loads(content)
42
+ return ChatPanelsConfig(**config_data)
43
+ except FileNotFoundError:
44
+ return ChatPanelsConfig()
45
+ except json.JSONDecodeError:
46
+ # 处理配置文件损坏或为空的情况
47
+ return ChatPanelsConfig()
48
+
49
+ async def save_config(config: ChatPanelsConfig, config_path: Path):
50
+ """保存聊天面板配置"""
51
+ async with aiofiles.open(config_path, mode='w', encoding='utf-8') as f:
52
+ await f.write(json.dumps(config.dict(), indent=2, ensure_ascii=False))
53
+
54
+ # 获取所有聊天标签页
55
+ @router.get("/api/chat/panels")
56
+ async def get_chat_panels(request: Request):
57
+ """获取所有聊天标签页配置"""
58
+ project_path = await get_project_path(request)
59
+ config_path = await get_config_path(project_path)
60
+ config = await load_config(config_path)
61
+ return config.dict()
62
+
63
+ # 更新聊天标签页列表
64
+ @router.put("/api/chat/panels/tabs")
65
+ async def update_chat_tabs(
66
+ tabs: List[ChatTab],
67
+ request: Request
68
+ ):
69
+ """更新聊天标签页列表"""
70
+ if not tabs:
71
+ raise HTTPException(status_code=400, detail="聊天标签页列表不能为空")
72
+
73
+ project_path = await get_project_path(request)
74
+ config_path = await get_config_path(project_path)
75
+ config = await load_config(config_path)
76
+ config.tabs = tabs
77
+
78
+ # 如果当前活跃标签不在新列表中,设置为第一个标签
79
+ tab_ids = [tab.id for tab in tabs]
80
+ if config.activeTabId not in tab_ids and tab_ids:
81
+ config.activeTabId = tab_ids[0]
82
+
83
+ await save_config(config, config_path)
84
+ return config.dict()
85
+
86
+ # 更新当前活跃标签
87
+ @router.put("/api/chat/panels/active-tab")
88
+ async def update_active_tab(
89
+ active_tab: dict,
90
+ request: Request
91
+ ):
92
+ """更新当前活跃的聊天标签页"""
93
+ tab_id = active_tab.get("id")
94
+ if not tab_id:
95
+ raise HTTPException(status_code=400, detail="必须提供标签页ID")
96
+
97
+ project_path = await get_project_path(request)
98
+ config_path = await get_config_path(project_path)
99
+ config = await load_config(config_path)
100
+
101
+ # 确保指定的标签页存在
102
+ tab_ids = [tab.id for tab in config.tabs]
103
+ if tab_id not in tab_ids:
104
+ raise HTTPException(status_code=404, detail=f"标签页ID '{tab_id}' 不存在")
105
+
106
+ config.activeTabId = tab_id
107
+ await save_config(config, config_path)
108
+ return {"activeTabId": tab_id}
109
+
110
+ # 添加新标签页
111
+ @router.post("/api/chat/panels/tabs")
112
+ async def add_chat_tab(
113
+ tab: ChatTab,
114
+ request: Request
115
+ ):
116
+ """添加新的聊天标签页"""
117
+ if not tab.id or not tab.name:
118
+ raise HTTPException(status_code=400, detail="标签页必须包含ID和名称")
119
+
120
+ project_path = await get_project_path(request)
121
+ config_path = await get_config_path(project_path)
122
+ config = await load_config(config_path)
123
+
124
+ # 检查ID是否已存在
125
+ if any(existing_tab.id == tab.id for existing_tab in config.tabs):
126
+ raise HTTPException(status_code=400, detail=f"标签页ID '{tab.id}' 已存在")
127
+
128
+ config.tabs.append(tab)
129
+ await save_config(config, config_path)
130
+ return tab.dict()
131
+
132
+ # 删除标签页
133
+ @router.delete("/api/chat/panels/tabs/{tab_id}")
134
+ async def delete_chat_tab(
135
+ tab_id: str,
136
+ request: Request
137
+ ):
138
+ """删除指定的聊天标签页"""
139
+ project_path = await get_project_path(request)
140
+ config_path = await get_config_path(project_path)
141
+ config = await load_config(config_path)
142
+
143
+ # 确保至少保留一个标签页
144
+ if len(config.tabs) <= 1:
145
+ raise HTTPException(status_code=400, detail="必须至少保留一个聊天标签页")
146
+
147
+ # 查找并删除标签页
148
+ initial_length = len(config.tabs)
149
+ config.tabs = [tab for tab in config.tabs if tab.id != tab_id]
150
+
151
+ if len(config.tabs) == initial_length:
152
+ raise HTTPException(status_code=404, detail=f"标签页ID '{tab_id}' 不存在")
153
+
154
+ # 如果删除的是当前活跃标签,切换到第一个标签
155
+ if config.activeTabId == tab_id:
156
+ config.activeTabId = config.tabs[0].id
157
+
158
+ await save_config(config, config_path)
159
+ return {"success": True, "activeTabId": config.activeTabId}
@@ -15,6 +15,10 @@ from autocoder.events.event_types import EventType
15
15
  from byzerllm.utils.langutil import asyncfy_with_semaphore
16
16
  from autocoder.common.global_cancel import global_cancel, CancelRequestedException
17
17
  from loguru import logger
18
+ import byzerllm
19
+ # 导入聊天会话和聊天列表管理器
20
+ from auto_coder_web.common_router.chat_session_manager import read_session_name_sync
21
+ from auto_coder_web.common_router.chat_list_manager import get_chat_list_sync
18
22
 
19
23
  router = APIRouter()
20
24
 
@@ -23,6 +27,7 @@ cancel_thread_pool = ThreadPoolExecutor(max_workers=5)
23
27
 
24
28
  class ChatCommandRequest(BaseModel):
25
29
  command: str
30
+ panel_id: Optional[str] = None
26
31
 
27
32
  class EventPollRequest(BaseModel):
28
33
  event_file_id: str
@@ -42,6 +47,10 @@ class TaskHistoryRequest(BaseModel):
42
47
  class CancelTaskRequest(BaseModel):
43
48
  event_file_id: str
44
49
 
50
+ class ChatResetRequest(BaseModel):
51
+ session_id: str
52
+ panel_id: Optional[str] = "main"
53
+
45
54
  async def get_project_path(request: Request) -> str:
46
55
  """
47
56
  从FastAPI请求上下文中获取项目路径
@@ -54,6 +63,25 @@ def ensure_task_dir(project_path: str) -> str:
54
63
  os.makedirs(task_dir, exist_ok=True)
55
64
  return task_dir
56
65
 
66
+ @byzerllm.prompt()
67
+ def chat_prompt(messages: List[Dict[str, Any]], request: ChatCommandRequest):
68
+ '''
69
+ 下面是我们已经产生的一个消息列表,其中 USER_RESPONSE 表示用户的输入,其他都是你的输出:
70
+ <messages>
71
+ {% for message in messages %}
72
+ <message>
73
+ <type>{{ message.type }}</type>
74
+ <content>{{ message.content }}</content>
75
+ </message>
76
+ {% endfor %}
77
+ </messages>
78
+
79
+ 下面是用户的最新需求:
80
+ <request>
81
+ {{ request.command }}
82
+ </request>
83
+ '''
84
+
57
85
  @router.post("/api/chat-command")
58
86
  async def chat_command(request: ChatCommandRequest, project_path: str = Depends(get_project_path)):
59
87
  """
@@ -71,8 +99,45 @@ async def chat_command(request: ChatCommandRequest, project_path: str = Depends(
71
99
  wrapper.configure_wrapper(f"event_file:{event_file}")
72
100
  global_cancel.register_token(event_file)
73
101
 
102
+ # 获取当前会话名称
103
+ panel_id = request.panel_id or ""
104
+ try:
105
+ # 使用同步版本的会话管理函数,传递panel_id参数
106
+ current_session_name = read_session_name_sync(project_path, panel_id)
107
+ except Exception as e:
108
+ logger.error(f"Error reading current session: {str(e)}")
109
+ current_session_name = ""
110
+
111
+ # 获取历史消息
112
+ messages = []
113
+ if current_session_name:
114
+ try:
115
+ # 使用同步版本的聊天列表管理函数
116
+ logger.info(f"Loading chat history for session: {current_session_name}")
117
+ chat_data = get_chat_list_sync(project_path, current_session_name)
118
+
119
+ # 从聊天历史中提取消息
120
+ for msg in chat_data.get("messages", []):
121
+ # 只保留用户和中间结果信息
122
+ if msg.get("type","") not in ["USER_RESPONSE","RESULT"]:
123
+ continue
124
+
125
+ if msg.get("contentType","") in ["token_stat"]:
126
+ continue
127
+
128
+ messages.append(msg)
129
+ except Exception as e:
130
+ logger.error(f"Error reading chat history: {str(e)}")
131
+
132
+ # 构建提示信息
133
+ prompt_text = request.command
134
+ if messages:
135
+ # 调用chat_prompt生成包含历史消息的提示
136
+ prompt_text = chat_prompt.prompt(messages, request)
137
+
74
138
  # 调用chat方法
75
- result = wrapper.chat_wrapper(request.command)
139
+ logger.info(f"Prompt text: {prompt_text}")
140
+ result = wrapper.chat_wrapper(prompt_text)
76
141
  get_event_manager(event_file).write_completion(
77
142
  EventContentCreator.create_completion(
78
143
  "200", "completed", result).to_dict()
@@ -289,6 +354,60 @@ async def get_task_detail(task_id: str, project_path: str = Depends(get_project_
289
354
  raise HTTPException(
290
355
  status_code=500, detail=f"Failed to get task detail: {str(e)}")
291
356
 
357
+ @router.post("/api/chat/reset")
358
+ async def reset_chat(request: ChatResetRequest, project_path: str = Depends(get_project_path)):
359
+ """
360
+ 重置聊天会话
361
+
362
+ 通过AutoCoderRunnerWrapper调用chat方法,执行/new命令重置会话
363
+ 在单独的线程中运行,并返回一个唯一的UUID
364
+
365
+ Args:
366
+ request: 包含session_id和panel_id的请求对象
367
+ project_path: 项目路径
368
+
369
+ Returns:
370
+ 重置操作的结果
371
+ """
372
+ # 生成事件文件路径
373
+ event_file, file_id = gengerate_event_file_path()
374
+
375
+ # 定义在线程中运行的函数
376
+ def run_reset_in_thread():
377
+ try:
378
+ # 加载tokenizer
379
+ from autocoder.auto_coder_runner import load_tokenizer
380
+ load_tokenizer()
381
+
382
+ # 创建AutoCoderRunnerWrapper实例
383
+ wrapper = AutoCoderRunnerWrapper(project_path)
384
+ wrapper.configure_wrapper(f"event_file:{event_file}")
385
+ global_cancel.register_token(event_file)
386
+
387
+ # 调用chat方法,执行/new命令
388
+ result = wrapper.chat_wrapper("/new")
389
+
390
+ # 写入完成事件
391
+ get_event_manager(event_file).write_completion(
392
+ EventContentCreator.create_completion(
393
+ "200", "reset_completed", result).to_dict()
394
+ )
395
+ logger.info(f"Chat reset (event file id: {file_id}) completed successfully")
396
+ except Exception as e:
397
+ logger.error(f"Error resetting chat {file_id}: {str(e)}")
398
+ logger.exception(e)
399
+ get_event_manager(event_file).write_error(
400
+ EventContentCreator.create_error(error_code="500", error_message=str(e), details={}).to_dict()
401
+ )
402
+
403
+ # 创建并启动线程
404
+ thread = Thread(target=run_reset_in_thread)
405
+ thread.daemon = True # 设置为守护线程
406
+ thread.start()
407
+
408
+ logger.info(f"Started chat reset {file_id} in background thread")
409
+ return {"event_file_id": file_id, "session_id": request.session_id}
410
+
292
411
  @router.post("/api/chat-command/cancel")
293
412
  async def cancel_task(request: CancelTaskRequest, project_path: str = Depends(get_project_path)):
294
413
  """
@@ -0,0 +1,191 @@
1
+ import os
2
+ import json
3
+ import aiofiles
4
+ from fastapi import APIRouter, HTTPException, Request, Depends
5
+ from pydantic import BaseModel
6
+ from pathlib import Path
7
+ from typing import List, Optional
8
+
9
+ router = APIRouter()
10
+
11
+ # 定义数据模型
12
+ class EditorTab(BaseModel):
13
+ path: str
14
+ label: str
15
+ isActive: bool = False
16
+
17
+ class EditorTabsConfig(BaseModel):
18
+ tabs: List[EditorTab] = []
19
+ activeTabPath: Optional[str] = None
20
+
21
+ async def get_project_path(request: Request) -> str:
22
+ """从FastAPI请求上下文中获取项目路径"""
23
+ return request.app.state.project_path
24
+
25
+ async def get_config_path(project_path: str) -> Path:
26
+ """获取代码编辑器标签页配置文件路径"""
27
+ config_path = Path(project_path) / ".auto-coder" / "auto-coder.web" / "editor_tabs.json"
28
+ config_path.parent.mkdir(parents=True, exist_ok=True)
29
+ return config_path
30
+
31
+ async def load_config(config_path: Path) -> EditorTabsConfig:
32
+ """加载代码编辑器标签页配置"""
33
+ if not config_path.exists():
34
+ return EditorTabsConfig()
35
+
36
+ try:
37
+ async with aiofiles.open(config_path, mode='r', encoding='utf-8') as f:
38
+ content = await f.read()
39
+ config_data = json.loads(content)
40
+ return EditorTabsConfig(**config_data)
41
+ except FileNotFoundError:
42
+ return EditorTabsConfig()
43
+ except json.JSONDecodeError:
44
+ # 处理配置文件损坏或为空的情况
45
+ return EditorTabsConfig()
46
+
47
+ async def save_config(config: EditorTabsConfig, config_path: Path):
48
+ """保存代码编辑器标签页配置"""
49
+ async with aiofiles.open(config_path, mode='w', encoding='utf-8') as f:
50
+ await f.write(json.dumps(config.dict(), indent=2, ensure_ascii=False))
51
+
52
+ # 获取所有编辑器标签页
53
+ @router.get("/api/editor/tabs")
54
+ async def get_editor_tabs(request: Request):
55
+ """获取所有代码编辑器标签页配置"""
56
+ project_path = await get_project_path(request)
57
+ config_path = await get_config_path(project_path)
58
+ config = await load_config(config_path)
59
+ return config.dict()
60
+
61
+ # 更新编辑器标签页列表
62
+ @router.put("/api/editor/tabs")
63
+ async def update_editor_tabs(
64
+ tabs: List[EditorTab],
65
+ request: Request
66
+ ):
67
+ """更新代码编辑器标签页列表"""
68
+ project_path = await get_project_path(request)
69
+ config_path = await get_config_path(project_path)
70
+ config = await load_config(config_path)
71
+
72
+ config.tabs = tabs
73
+
74
+ # 更新活跃标签
75
+ active_tabs = [tab for tab in tabs if tab.isActive]
76
+ if active_tabs:
77
+ config.activeTabPath = active_tabs[0].path
78
+ elif tabs:
79
+ config.activeTabPath = tabs[0].path
80
+ else:
81
+ config.activeTabPath = None
82
+
83
+ await save_config(config, config_path)
84
+ return config.dict()
85
+
86
+ # 更新当前活跃标签
87
+ @router.put("/api/editor/active-tab")
88
+ async def update_active_tab(
89
+ active_tab: dict,
90
+ request: Request
91
+ ):
92
+ """更新当前活跃的代码编辑器标签页"""
93
+ tab_path = active_tab.get("path")
94
+ if not tab_path:
95
+ raise HTTPException(status_code=400, detail="必须提供标签页路径")
96
+
97
+ project_path = await get_project_path(request)
98
+ config_path = await get_config_path(project_path)
99
+ config = await load_config(config_path)
100
+
101
+ # 确保指定的标签页存在
102
+ tab_paths = [tab.path for tab in config.tabs]
103
+ if tab_path not in tab_paths:
104
+ # 如果标签不存在,添加一个新标签
105
+ new_tab = EditorTab(
106
+ path=tab_path,
107
+ label=tab_path.split('/')[-1],
108
+ isActive=True
109
+ )
110
+ config.tabs.append(new_tab)
111
+ else:
112
+ # 更新标签的活跃状态
113
+ config.tabs = [
114
+ EditorTab(
115
+ path=tab.path,
116
+ label=tab.label,
117
+ isActive=(tab.path == tab_path)
118
+ )
119
+ for tab in config.tabs
120
+ ]
121
+
122
+ config.activeTabPath = tab_path
123
+ await save_config(config, config_path)
124
+ return {"activeTabPath": tab_path}
125
+
126
+ # 添加新标签页
127
+ @router.post("/api/editor/tabs")
128
+ async def add_editor_tab(
129
+ tab: EditorTab,
130
+ request: Request
131
+ ):
132
+ """添加新的代码编辑器标签页"""
133
+ if not tab.path:
134
+ raise HTTPException(status_code=400, detail="标签页必须包含路径")
135
+
136
+ project_path = await get_project_path(request)
137
+ config_path = await get_config_path(project_path)
138
+ config = await load_config(config_path)
139
+
140
+ # 检查路径是否已存在
141
+ existing_paths = [existing_tab.path for existing_tab in config.tabs]
142
+ if tab.path in existing_paths:
143
+ # 如果标签已存在,只更新活跃状态
144
+ config.tabs = [
145
+ EditorTab(
146
+ path=t.path,
147
+ label=t.label,
148
+ isActive=(t.path == tab.path)
149
+ )
150
+ for t in config.tabs
151
+ ]
152
+ else:
153
+ # 添加新标签并设置为活跃
154
+ for t in config.tabs:
155
+ t.isActive = False
156
+ config.tabs.append(tab)
157
+
158
+ if tab.isActive:
159
+ config.activeTabPath = tab.path
160
+
161
+ await save_config(config, config_path)
162
+ return tab.dict()
163
+
164
+ # 删除标签页
165
+ @router.delete("/api/editor/tabs/{tab_path}")
166
+ async def delete_editor_tab(
167
+ tab_path: str,
168
+ request: Request
169
+ ):
170
+ """删除指定的代码编辑器标签页"""
171
+ project_path = await get_project_path(request)
172
+ config_path = await get_config_path(project_path)
173
+ config = await load_config(config_path)
174
+
175
+ # 查找并删除标签页
176
+ initial_length = len(config.tabs)
177
+ config.tabs = [tab for tab in config.tabs if tab.path != tab_path]
178
+
179
+ if len(config.tabs) == initial_length:
180
+ raise HTTPException(status_code=404, detail=f"标签页路径 '{tab_path}' 不存在")
181
+
182
+ # 如果删除的是当前活跃标签,切换到第一个标签
183
+ if config.activeTabPath == tab_path:
184
+ if config.tabs:
185
+ config.activeTabPath = config.tabs[0].path
186
+ config.tabs[0].isActive = True
187
+ else:
188
+ config.activeTabPath = None
189
+
190
+ await save_config(config, config_path)
191
+ return {"success": True, "activeTabPath": config.activeTabPath}
@@ -16,6 +16,9 @@ from byzerllm.utils.langutil import asyncfy_with_semaphore
16
16
  from autocoder.common.global_cancel import global_cancel, CancelRequestedException
17
17
  from loguru import logger
18
18
  import byzerllm
19
+ # 导入聊天会话和聊天列表管理器
20
+ from auto_coder_web.common_router.chat_session_manager import read_session_name_sync
21
+ from auto_coder_web.common_router.chat_list_manager import get_chat_list_sync
19
22
 
20
23
  router = APIRouter()
21
24
 
@@ -24,6 +27,7 @@ cancel_thread_pool = ThreadPoolExecutor(max_workers=5)
24
27
 
25
28
  class CodingCommandRequest(BaseModel):
26
29
  command: str
30
+ panel_id: Optional[str] = None
27
31
 
28
32
  class EventPollRequest(BaseModel):
29
33
  event_file_id: str
@@ -92,36 +96,34 @@ async def coding_command(request: CodingCommandRequest, project_path: str = Depe
92
96
  global_cancel.register_token(event_file)
93
97
 
94
98
  # 获取当前会话名称
95
- current_session_file = os.path.join(project_path, ".auto-coder", "auto-coder.web", "current-session.json")
96
- current_session_name = ""
97
- if os.path.exists(current_session_file):
98
- try:
99
- with open(current_session_file, 'r',encoding="utf-8") as f:
100
- session_data = json.load(f)
101
- current_session_name = session_data.get("session_name", "")
102
- except Exception as e:
103
- logger.error(f"Error reading current session: {str(e)}")
99
+ panel_id = request.panel_id or ""
100
+ try:
101
+ # 使用同步版本的会话管理函数,传递panel_id参数
102
+ current_session_name = read_session_name_sync(project_path, panel_id)
103
+ except Exception as e:
104
+ logger.error(f"Error reading current session: {str(e)}")
105
+ current_session_name = ""
104
106
 
105
107
  # 获取历史消息
106
108
  messages = []
107
109
  if current_session_name:
108
- chat_list_file = os.path.join(project_path, ".auto-coder", "auto-coder.web", "chat-lists", f"{current_session_name}.json")
109
- if os.path.exists(chat_list_file):
110
- try:
111
- with open(chat_list_file, 'r', encoding="utf-8") as f:
112
- chat_data = json.load(f)
113
- # 从聊天历史中提取消息
114
- for msg in chat_data.get("messages", []):
115
- # 只保留用户和中间结果信息
116
- if msg.get("type","") not in ["USER_RESPONSE","RESULT"]:
117
- continue
118
-
119
- if msg.get("contentType","") in ["token_stat"]:
120
- continue
121
-
122
- messages.append(msg)
123
- except Exception as e:
124
- logger.error(f"Error reading chat history: {str(e)}")
110
+ try:
111
+ # 使用同步版本的聊天列表管理函数
112
+ logger.info(f"Loading chat history for session: {current_session_name}")
113
+ chat_data = get_chat_list_sync(project_path, current_session_name)
114
+
115
+ # 从聊天历史中提取消息
116
+ for msg in chat_data.get("messages", []):
117
+ # 只保留用户和中间结果信息
118
+ if msg.get("type","") not in ["USER_RESPONSE","RESULT"]:
119
+ continue
120
+
121
+ if msg.get("contentType","") in ["token_stat"]:
122
+ continue
123
+
124
+ messages.append(msg)
125
+ except Exception as e:
126
+ logger.error(f"Error reading chat history: {str(e)}")
125
127
 
126
128
  # 构建提示信息
127
129
  prompt_text = request.command