auto-coder-web 0.1.24__py3-none-any.whl → 0.1.25__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.
- auto_coder_web/auto_coder_runner_wrapper.py +7 -0
- auto_coder_web/common_router/__init__.py +0 -0
- auto_coder_web/common_router/auto_coder_conf_router.py +42 -0
- auto_coder_web/common_router/chat_list_router.py +75 -0
- auto_coder_web/common_router/completions_router.py +53 -0
- auto_coder_web/common_router/file_group_router.py +120 -0
- auto_coder_web/common_router/file_router.py +78 -0
- auto_coder_web/proxy.py +22 -472
- auto_coder_web/routers/chat_router.py +330 -0
- auto_coder_web/routers/coding_router.py +330 -0
- auto_coder_web/routers/config_router.py +199 -0
- auto_coder_web/routers/todo_router.py +463 -20
- auto_coder_web/version.py +1 -1
- auto_coder_web/web/asset-manifest.json +6 -6
- auto_coder_web/web/index.html +1 -1
- auto_coder_web/web/static/css/main.95277c5f.css +6 -0
- auto_coder_web/web/static/css/main.95277c5f.css.map +1 -0
- auto_coder_web/web/static/js/main.66c37ccf.js +3 -0
- auto_coder_web/web/static/js/{main.470202a1.js.LICENSE.txt → main.66c37ccf.js.LICENSE.txt} +40 -0
- auto_coder_web/web/static/js/{main.470202a1.js.map → main.66c37ccf.js.map} +1 -1
- {auto_coder_web-0.1.24.dist-info → auto_coder_web-0.1.25.dist-info}/METADATA +1 -1
- {auto_coder_web-0.1.24.dist-info → auto_coder_web-0.1.25.dist-info}/RECORD +27 -16
- {auto_coder_web-0.1.24.dist-info → auto_coder_web-0.1.25.dist-info}/top_level.txt +1 -0
- expert_routers/__init__.py +3 -0
- expert_routers/history_router.py +333 -0
- auto_coder_web/web/static/css/main.770925e5.css +0 -6
- auto_coder_web/web/static/css/main.770925e5.css.map +0 -1
- auto_coder_web/web/static/js/main.470202a1.js +0 -3
- {auto_coder_web-0.1.24.dist-info → auto_coder_web-0.1.25.dist-info}/WHEEL +0 -0
- {auto_coder_web-0.1.24.dist-info → auto_coder_web-0.1.25.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,199 @@
|
|
1
|
+
import os
|
2
|
+
import json
|
3
|
+
import logging
|
4
|
+
import asyncio
|
5
|
+
import aiofiles
|
6
|
+
from fastapi import APIRouter, HTTPException
|
7
|
+
from pydantic import BaseModel, Field
|
8
|
+
from typing import Optional, List, Union, Dict, Any
|
9
|
+
from datetime import datetime
|
10
|
+
from pathlib import Path
|
11
|
+
|
12
|
+
router = APIRouter()
|
13
|
+
|
14
|
+
# 配置存储路径
|
15
|
+
CONFIG_FILE = Path(".auto-coder/auto-coder.web/configs/config.json")
|
16
|
+
|
17
|
+
# 确保目录存在
|
18
|
+
CONFIG_FILE.parent.mkdir(parents=True, exist_ok=True)
|
19
|
+
|
20
|
+
logger = logging.getLogger(__name__)
|
21
|
+
|
22
|
+
# UI 配置模型
|
23
|
+
class UIConfig(BaseModel):
|
24
|
+
mode: str = "agent" # agent/expert
|
25
|
+
theme: str = "dark"
|
26
|
+
language: str = "zh-CN"
|
27
|
+
|
28
|
+
# 编辑器配置模型
|
29
|
+
class EditorConfig(BaseModel):
|
30
|
+
fontSize: int = 14
|
31
|
+
tabSize: int = 2
|
32
|
+
wordWrap: str = "on"
|
33
|
+
|
34
|
+
# 功能配置模型
|
35
|
+
class FeaturesConfig(BaseModel):
|
36
|
+
autoSave: bool = True
|
37
|
+
livePreview: bool = True
|
38
|
+
|
39
|
+
# 配置设置模型
|
40
|
+
class ConfigSettings(BaseModel):
|
41
|
+
ui: UIConfig = Field(default_factory=UIConfig)
|
42
|
+
editor: EditorConfig = Field(default_factory=EditorConfig)
|
43
|
+
features: FeaturesConfig = Field(default_factory=FeaturesConfig)
|
44
|
+
updated_at: str = Field(default_factory=lambda: datetime.now().isoformat())
|
45
|
+
|
46
|
+
# 更新请求模型 - 所有字段都是可选的
|
47
|
+
class UIConfigUpdate(BaseModel):
|
48
|
+
mode: Optional[str] = None
|
49
|
+
theme: Optional[str] = None
|
50
|
+
language: Optional[str] = None
|
51
|
+
|
52
|
+
class EditorConfigUpdate(BaseModel):
|
53
|
+
fontSize: Optional[int] = None
|
54
|
+
tabSize: Optional[int] = None
|
55
|
+
wordWrap: Optional[str] = None
|
56
|
+
|
57
|
+
class FeaturesConfigUpdate(BaseModel):
|
58
|
+
autoSave: Optional[bool] = None
|
59
|
+
livePreview: Optional[bool] = None
|
60
|
+
|
61
|
+
class ConfigUpdateRequest(BaseModel):
|
62
|
+
ui: Optional[UIConfigUpdate] = None
|
63
|
+
editor: Optional[EditorConfigUpdate] = None
|
64
|
+
features: Optional[FeaturesConfigUpdate] = None
|
65
|
+
|
66
|
+
async def load_config() -> ConfigSettings:
|
67
|
+
"""异步加载配置,如果文件不存在则返回默认配置"""
|
68
|
+
if not await asyncio.to_thread(lambda: CONFIG_FILE.exists()):
|
69
|
+
return ConfigSettings()
|
70
|
+
|
71
|
+
try:
|
72
|
+
async with aiofiles.open(CONFIG_FILE, mode='r') as f:
|
73
|
+
content = await f.read()
|
74
|
+
config_data = json.loads(content)
|
75
|
+
return ConfigSettings(**config_data)
|
76
|
+
except (json.JSONDecodeError, FileNotFoundError):
|
77
|
+
logger.error("Failed to parse config.json, returning default config")
|
78
|
+
return ConfigSettings()
|
79
|
+
|
80
|
+
async def save_config(config: ConfigSettings):
|
81
|
+
"""异步保存配置"""
|
82
|
+
async with aiofiles.open(CONFIG_FILE, mode='w') as f:
|
83
|
+
await f.write(json.dumps(config.dict(), indent=2, ensure_ascii=False))
|
84
|
+
|
85
|
+
@router.get("/api/config", response_model=ConfigSettings)
|
86
|
+
async def get_config():
|
87
|
+
"""获取当前所有配置"""
|
88
|
+
return await load_config()
|
89
|
+
|
90
|
+
@router.get("/api/config/ui", response_model=UIConfig)
|
91
|
+
async def get_ui_config():
|
92
|
+
"""获取UI配置"""
|
93
|
+
config = await load_config()
|
94
|
+
return config.ui
|
95
|
+
|
96
|
+
@router.get("/api/config/editor", response_model=EditorConfig)
|
97
|
+
async def get_editor_config():
|
98
|
+
"""获取编辑器配置"""
|
99
|
+
config = await load_config()
|
100
|
+
return config.editor
|
101
|
+
|
102
|
+
@router.get("/api/config/features", response_model=FeaturesConfig)
|
103
|
+
async def get_features_config():
|
104
|
+
"""获取功能配置"""
|
105
|
+
config = await load_config()
|
106
|
+
return config.features
|
107
|
+
|
108
|
+
@router.put("/api/config", response_model=ConfigSettings)
|
109
|
+
async def update_config(request: ConfigUpdateRequest):
|
110
|
+
"""更新配置"""
|
111
|
+
config = await load_config()
|
112
|
+
|
113
|
+
# 更新UI配置
|
114
|
+
if request.ui:
|
115
|
+
ui_update = request.ui.dict(exclude_unset=True)
|
116
|
+
if ui_update:
|
117
|
+
config.ui = UIConfig(**{**config.ui.dict(), **ui_update})
|
118
|
+
|
119
|
+
# 更新编辑器配置
|
120
|
+
if request.editor:
|
121
|
+
editor_update = request.editor.dict(exclude_unset=True)
|
122
|
+
if editor_update:
|
123
|
+
config.editor = EditorConfig(**{**config.editor.dict(), **editor_update})
|
124
|
+
|
125
|
+
# 更新功能配置
|
126
|
+
if request.features:
|
127
|
+
features_update = request.features.dict(exclude_unset=True)
|
128
|
+
if features_update:
|
129
|
+
config.features = FeaturesConfig(**{**config.features.dict(), **features_update})
|
130
|
+
|
131
|
+
# 更新时间戳
|
132
|
+
config.updated_at = datetime.now().isoformat()
|
133
|
+
|
134
|
+
await save_config(config)
|
135
|
+
return config
|
136
|
+
|
137
|
+
@router.put("/api/config/ui", response_model=UIConfig)
|
138
|
+
async def update_ui_config(request: UIConfigUpdate):
|
139
|
+
"""更新UI配置"""
|
140
|
+
config = await load_config()
|
141
|
+
|
142
|
+
# 只更新提供的字段
|
143
|
+
update_data = request.dict(exclude_unset=True)
|
144
|
+
if update_data:
|
145
|
+
config.ui = UIConfig(**{**config.ui.dict(), **update_data})
|
146
|
+
config.updated_at = datetime.now().isoformat()
|
147
|
+
await save_config(config)
|
148
|
+
|
149
|
+
return config.ui
|
150
|
+
|
151
|
+
@router.put("/api/config/editor", response_model=EditorConfig)
|
152
|
+
async def update_editor_config(request: EditorConfigUpdate):
|
153
|
+
"""更新编辑器配置"""
|
154
|
+
config = await load_config()
|
155
|
+
|
156
|
+
# 只更新提供的字段
|
157
|
+
update_data = request.dict(exclude_unset=True)
|
158
|
+
if update_data:
|
159
|
+
config.editor = EditorConfig(**{**config.editor.dict(), **update_data})
|
160
|
+
config.updated_at = datetime.now().isoformat()
|
161
|
+
await save_config(config)
|
162
|
+
|
163
|
+
return config.editor
|
164
|
+
|
165
|
+
@router.put("/api/config/features", response_model=FeaturesConfig)
|
166
|
+
async def update_features_config(request: FeaturesConfigUpdate):
|
167
|
+
"""更新功能配置"""
|
168
|
+
config = await load_config()
|
169
|
+
|
170
|
+
# 只更新提供的字段
|
171
|
+
update_data = request.dict(exclude_unset=True)
|
172
|
+
if update_data:
|
173
|
+
config.features = FeaturesConfig(**{**config.features.dict(), **update_data})
|
174
|
+
config.updated_at = datetime.now().isoformat()
|
175
|
+
await save_config(config)
|
176
|
+
|
177
|
+
return config.features
|
178
|
+
|
179
|
+
# 单个配置项更新端点
|
180
|
+
@router.get("/api/config/ui/mode")
|
181
|
+
async def get_ui_mode():
|
182
|
+
"""获取UI模式配置"""
|
183
|
+
config = await load_config()
|
184
|
+
return {"mode": config.ui.mode}
|
185
|
+
|
186
|
+
@router.put("/api/config/ui/mode")
|
187
|
+
async def update_ui_mode(mode: str):
|
188
|
+
"""更新UI模式配置"""
|
189
|
+
config = await load_config()
|
190
|
+
|
191
|
+
# 验证模式值
|
192
|
+
if mode not in ["agent", "expert"]:
|
193
|
+
raise HTTPException(status_code=400, detail="Mode must be 'agent' or 'expert'")
|
194
|
+
|
195
|
+
config.ui.mode = mode
|
196
|
+
config.updated_at = datetime.now().isoformat()
|
197
|
+
await save_config(config)
|
198
|
+
|
199
|
+
return {"mode": mode}
|