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.
@@ -6,7 +6,7 @@
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>Vite React App</title>
8
8
  <script type="module" crossorigin src="/assets/main.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/main-edBorJ-r.css">
9
+ <link rel="stylesheet" crossorigin href="/assets/main-D8cC7hK1.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="root"></div>
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: auto_coder_web
3
- Version: 0.1.91
3
+ Version: 0.1.93
4
4
  Summary: auto-coder.web: A Python Project
5
5
  Author: allwefantasy
6
6
  Classifier: Programming Language :: Python :: 3.10
7
7
  Classifier: Programming Language :: Python :: 3.11
8
8
  Classifier: Programming Language :: Python :: 3.12
9
9
  Description-Content-Type: text/markdown
10
- Requires-Dist: auto-coder >=0.1.360
10
+ Requires-Dist: auto-coder >=0.1.362
11
11
  Requires-Dist: aiofiles
12
12
  Requires-Dist: psutil
13
13
  Requires-Dist: watchdog
@@ -1,32 +1,33 @@
1
1
  auto_coder_web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  auto_coder_web/auto_coder_runner_wrapper.py,sha256=CFhhgAkiMQBp56pR8Pz2FiWTv7otO295pAwxIM81VrY,1627
3
- auto_coder_web/file_group.py,sha256=wS52bHDT_gATIrHgVq62Mv1JMLGzdY_AU08iPzw4eLU,2540
4
3
  auto_coder_web/file_manager.py,sha256=eFjmhBtw5PwnGAIQQjusNdo9TU3So-YyRYJXFHK4BjQ,12008
5
4
  auto_coder_web/init_project.py,sha256=udDVjNpIuyJGnEbFfHtbrpLs37QjqE1zOj3VHC6Glf8,1141
6
5
  auto_coder_web/json_file_storage.py,sha256=elthpcdclXITX3jew2EtT-ypyxZzDAzG1U7_k3looHI,1757
7
6
  auto_coder_web/lang.py,sha256=cXypkDesnMwZ0U6D_CZtxhDTAOp__hoJzYTulQ_8xPc,1108
8
- auto_coder_web/proxy.py,sha256=m-J6dtOF0oNnW9BS-Lh6azGZRrvHn1RZ-DEPmZ9NJ3Y,11771
7
+ auto_coder_web/proxy.py,sha256=if9-XT7bxD8dP_ddqQFuxTECr2XZmcmL94m1VrMlpTg,11878
9
8
  auto_coder_web/terminal.py,sha256=jtAH7FaC573cgxc7FnI_mOZ3D2dSCO3PrZN0OehtbNQ,9521
10
9
  auto_coder_web/types.py,sha256=TT-0UruUi67wz7w1DpjFyYeaCnkdKYviJvlpSnrdtD4,1435
11
- auto_coder_web/version.py,sha256=TjC2Yv3b693i4p1zyYBITDCreXfOMw-2BLFwgHmy35U,23
10
+ auto_coder_web/version.py,sha256=9ZJPYemtF-vnUzZtNNDjmi0UnkkMXYvPkfRASPJ5iWc,23
12
11
  auto_coder_web/common_router/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
12
  auto_coder_web/common_router/active_context_router.py,sha256=wbwG-J2iS5uBorN20q2PVoyJCVueECBR66xYjtIEWhM,6228
14
13
  auto_coder_web/common_router/auto_coder_conf_router.py,sha256=oIRZE5OqeSfp-TYkGtX1M1Qd54iBYxftQtDbivdRj1o,1059
15
- auto_coder_web/common_router/chat_list_router.py,sha256=1u_PmcdNSfADaX5-D96_KG0yVxfp6yMej2UKxghh4UA,7975
14
+ auto_coder_web/common_router/chat_list_manager.py,sha256=_0ZO3md0SaW51OnpNzirys9XhbRe_PbLuK7XOhSPPb4,6378
15
+ auto_coder_web/common_router/chat_list_router.py,sha256=p4C6_trEKqvLEP01EEk4GXdQkU22_gHAKfBeaZMqbk8,5717
16
+ auto_coder_web/common_router/chat_session_manager.py,sha256=oMwMaaYWToqn_QJIdFS8QcSaWDdqHhxPMbyQ6tuJUg0,3590
16
17
  auto_coder_web/common_router/compiler_router.py,sha256=nHlD6VdxV9-CLhYZnykmaI8AP1zq2isA-3eD8ckxFHw,3840
17
18
  auto_coder_web/common_router/completions_router.py,sha256=3pHDp2FRlSwasjn1jwrWXhQ6YN_zvRnri2aZpEooCzg,6590
18
- auto_coder_web/common_router/file_group_router.py,sha256=F2zkFNv7IwK6-bDiFuLQ0kcnQOibS66Yn6rXNaPGY0c,7113
19
+ auto_coder_web/common_router/file_group_router.py,sha256=jZ0Qc5pWeFsNa5DZQnGr_IKAEWewqDWlEXiLpZOnZII,8747
19
20
  auto_coder_web/common_router/file_router.py,sha256=orTiG9hn-eEd8i4HhMhbob4SsRbbEsJvOxk7CCbhoQY,10759
20
21
  auto_coder_web/common_router/filecacher.py,sha256=3LgmGUqfjUyfRz2rxWvXsP-ovyjGW-t0Cl49Tibhd0Y,4666
21
22
  auto_coder_web/common_router/model_router.py,sha256=w-t6d6FkfF8sDo_8ZHfclHb50y7pJ9uBWPfCLcxd7Lo,13449
22
23
  auto_coder_web/expert_routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
24
  auto_coder_web/expert_routers/history_router.py,sha256=9NUPlDQJJY5xhGepj38ej3qXAlbaquJDVaSniNhFpqw,12471
24
- auto_coder_web/file_cacher/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- auto_coder_web/file_cacher/filecacher.py,sha256=1VugN4kvANc2CKLqDfRgOmjQ9WGKmG8O95Bx2-n7td4,7255
26
25
  auto_coder_web/routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- auto_coder_web/routers/auto_router.py,sha256=5LuMcbL349YrJXgy53KSUdFZjcpTN2aSGVTj10xOpfw,16593
28
- auto_coder_web/routers/chat_router.py,sha256=Rn5R1RsIbdeZy_5d_pKdvo2WweedVeIEXHc5l8yiY4w,12283
29
- auto_coder_web/routers/coding_router.py,sha256=Rfbo-5x8EZLYtzg66ZzZPFBVUeW48tUz9hnId4w-Rio,14943
26
+ auto_coder_web/routers/auto_router.py,sha256=IzBR_IbslmVUj83eyhVAWUTwd-Rh3QAMo6DethvT3yc,16552
27
+ auto_coder_web/routers/chat_panels_router.py,sha256=3I4M746NCORdpcyk-SuAmBJAKuQeG4FtX7m3FEXrnWM,5417
28
+ auto_coder_web/routers/chat_router.py,sha256=Zxt8lUdLF1EJY1IMHdcS9tvw9ayec8jA-EKloYV3Bqk,16980
29
+ auto_coder_web/routers/code_editor_tabs_router.py,sha256=ogCQUp7YoIYIkphDqCLKdfBGq-HdrfKQvZA8UkArrrc,6168
30
+ auto_coder_web/routers/coding_router.py,sha256=vQX2YQ7VjddUG-OkKPKH-u2ip4ltULE93ldw27HrNsM,14866
30
31
  auto_coder_web/routers/commit_router.py,sha256=MRxL_aJ3YazP6vC5C-bv0x9u3tvecRdGT6I7gHFXl18,26781
31
32
  auto_coder_web/routers/config_router.py,sha256=E3twdQ_b0udO4NqyYL06feuM1KfKcgR7I4te86VstbA,3156
32
33
  auto_coder_web/routers/direct_chat_router.py,sha256=tS8g4yZjmC2LjdLMQkq8KaCDJmyEuWidGRqIii-Hq1o,1265
@@ -40,7 +41,7 @@ auto_coder_web/routers/todo_router.py,sha256=IkQurQTw0Xk9P8yEtY_iie1z5ZK3CzDQE_N
40
41
  auto_coder_web/routers/upload_router.py,sha256=HdQIl3ICcT3EB2kwryTbF-PItWV-Gugses7Y0Eaw2WQ,1798
41
42
  auto_coder_web/web/bridge.js,sha256=us40dbuGHa2_zBBVBCa_GznOvpuZNDObViksMeoQch0,7364
42
43
  auto_coder_web/web/favicon.ico,sha256=PRD32mxgMXg0AIFmjErFs66XQ8qaJiqw_NMS-7n0i90,3870
43
- auto_coder_web/web/index.html,sha256=GQUu0CqHi3YrlCshb0f0zaqayHk7K7FjrDocaAuz9U0,410
44
+ auto_coder_web/web/index.html,sha256=WScQCWe648qOft38Bcydg94SPqSdX4HL2eUWyz-Bs8Y,410
44
45
  auto_coder_web/web/logo192.png,sha256=w4Y5bscNs2CAdbX7-qxKscyqhroFpoqzk-xVHrZsPgA,5347
45
46
  auto_coder_web/web/logo512.png,sha256=nqT02nBQwMxAiSb2o5wlNiTpursdQ8eXfNghRFpgtGE,9664
46
47
  auto_coder_web/web/manifest.json,sha256=ULPYw5A68_eNhxuUVXqxT045yhkurKPSz6hjyGcnmhQ,492
@@ -85,8 +86,8 @@ auto_coder_web/web/assets/lexon-YWi4-JPR.js,sha256=l9pURhF6kU3UKzKOIIQprnjMAXzdI
85
86
  auto_coder_web/web/assets/liquid-CPaH0eVF.js,sha256=uXE_OsLEw3W8B-ReZOUwybkJu3J6se8VlGWx0MFpx7g,4208
86
87
  auto_coder_web/web/assets/lua-nf6ki56Z.js,sha256=O3vMsGoiFHDMGSxTP1bHnDnRPebfmFnC7kf8-ovGkO8,2369
87
88
  auto_coder_web/web/assets/m3-Cpb6xl2v.js,sha256=PmotBCyVZvUGHh9t9juODmjXptTEP5K6bnPj2WgYO6c,3063
88
- auto_coder_web/web/assets/main-edBorJ-r.css,sha256=2EjqbJmBx8v_d7KU5EIUMrfTMTQz5suqTLPWurl1k7A,242355
89
- auto_coder_web/web/assets/main.js,sha256=fDwvJo1irB5jj9vJ14mFvsoBZykt8nP1BkBZg2iw68A,6654044
89
+ auto_coder_web/web/assets/main-D8cC7hK1.css,sha256=WawWwZrOFXdkI61Qln2UMzryDj2lQGXjHqvz7t3rHeU,242684
90
+ auto_coder_web/web/assets/main.js,sha256=D6nSIwZ3pwKgrSE12s0bQkuU3oXdpO76jW3wvEETUSg,6673763
90
91
  auto_coder_web/web/assets/markdown-DSZPf7rp.js,sha256=3ZMgfYxjKX9U8l6GFCNrO28Hj7JU-4rKrEqXIezyqT4,4034
91
92
  auto_coder_web/web/assets/mdx-DRx1b0qs.js,sha256=awzor_jnBNHRhTxk3_jcpGXsNUFbi9Ow0OIqWYq4CQA,5113
92
93
  auto_coder_web/web/assets/mips-B_c3zf-v.js,sha256=L4uNgcwtDWPbyL0qnO-2w9x2PdI02UJcc8yQrYnHahA,2825
@@ -240,8 +241,8 @@ auto_coder_web/web/monaco-editor/min/vs/language/typescript/tsWorker.js,sha256=_
240
241
  auto_coder_web/web/sounds/ding-dong.wav,sha256=BveDrGCyt_YMHaJwFJ80L5NfbUF5cl5QjzR-SRehxTk,35324
241
242
  auto_coder_web/web/sounds/gentle-notification.wav,sha256=bzd0MwECdrjmNz7mbqv_y03S7WwD3G6agbIh1rWJ9cQ,72124
242
243
  auto_coder_web/web/sounds/soft-chime.wav,sha256=Akpw7_rHLnX3rE13dRYpyZbmQFLGtp8P53LCdAkT9sA,40364
243
- auto_coder_web-0.1.91.dist-info/METADATA,sha256=T41zjYVFgapvfT84hY-Lq0Gww3vnxMz09LCNFTCLi7k,1435
244
- auto_coder_web-0.1.91.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
245
- auto_coder_web-0.1.91.dist-info/entry_points.txt,sha256=oh8kd1ZecWDgdv-bIj_ru3phvl4scuxwXl9DK0Khltg,61
246
- auto_coder_web-0.1.91.dist-info/top_level.txt,sha256=UCzEw494Im0KvR-FTYf2jh-okqHvLsC_0JLOrQZoSpg,15
247
- auto_coder_web-0.1.91.dist-info/RECORD,,
244
+ auto_coder_web-0.1.93.dist-info/METADATA,sha256=OFvZ7kkbyQglKhbE1zhh82Cza_KsJn4X438ZWh5l4W8,1435
245
+ auto_coder_web-0.1.93.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
246
+ auto_coder_web-0.1.93.dist-info/entry_points.txt,sha256=oh8kd1ZecWDgdv-bIj_ru3phvl4scuxwXl9DK0Khltg,61
247
+ auto_coder_web-0.1.93.dist-info/top_level.txt,sha256=UCzEw494Im0KvR-FTYf2jh-okqHvLsC_0JLOrQZoSpg,15
248
+ auto_coder_web-0.1.93.dist-info/RECORD,,
File without changes
@@ -1,195 +0,0 @@
1
- import os
2
- import json
3
- import threading
4
- import time
5
- from watchdog.observers import Observer
6
- from watchdog.events import FileSystemEventHandler
7
- from pydantic import BaseModel
8
-
9
- class FileCacheResult(BaseModel):
10
- miss: bool
11
- files: list[str]
12
-
13
- class FileCacheHandler(FileSystemEventHandler):
14
- def __init__(self, cacher):
15
- super().__init__()
16
- self.cacher = cacher
17
-
18
- def on_created(self, event):
19
- if not event.is_directory:
20
- self.cacher._update_file(event.src_path)
21
-
22
- def on_modified(self, event):
23
- if not event.is_directory:
24
- self.cacher._update_file(event.src_path)
25
-
26
- def on_deleted(self, event):
27
- if not event.is_directory:
28
- self.cacher._remove_file(event.src_path)
29
-
30
- def on_moved(self, event):
31
- if not event.is_directory:
32
- self.cacher._remove_file(event.src_path)
33
- self.cacher._update_file(event.dest_path)
34
-
35
-
36
- class FileCacher:
37
- def __init__(self, project_path):
38
- self.project_path = project_path
39
- self.index_file = os.path.join(
40
- project_path, ".auto-coder", "cache", "file_cache.json")
41
- self.file_info = {} # key: absolute path, value: metadata dict
42
- self.ready = False
43
- self.lock = threading.RLock()
44
- self.observer = None
45
-
46
- def start(self):
47
- """启动缓存构建和监控"""
48
- # 启动索引构建线程
49
- t = threading.Thread(target=self._build_cache_thread, daemon=True)
50
- t.start()
51
-
52
- def _build_cache_thread(self):
53
- """后台构建索引并启动watchdog监控"""
54
- try:
55
- self._build_cache()
56
- finally:
57
- self.ready = True
58
- self._save_cache()
59
- self._start_watchdog()
60
-
61
- def _build_cache(self):
62
- """遍历项目目录,构建初始缓存"""
63
- exclude_dirs = {".git", "node_modules", "dist",
64
- "build", "__pycache__", ".venv", ".auto-coder"}
65
- for root, dirs, files in os.walk(self.project_path, followlinks=True):
66
- # 过滤目录
67
- dirs[:] = [
68
- d for d in dirs if d not in exclude_dirs and not d.startswith('.')]
69
- for f in files:
70
- abs_path = os.path.join(root, f)
71
- self._update_file(abs_path)
72
-
73
- def _update_file(self, abs_path):
74
- """添加或更新单个文件的缓存信息"""
75
- try:
76
- if not os.path.isfile(abs_path):
77
- return
78
- stat = os.stat(abs_path)
79
- rel_path = os.path.relpath(abs_path, self.project_path)
80
- with self.lock:
81
- self.file_info[rel_path] = {
82
- "mtime": stat.st_mtime,
83
- "size": stat.st_size,
84
- "abs_path": abs_path,
85
- "name": os.path.basename(abs_path),
86
- }
87
- except Exception:
88
- pass # ignore errors
89
-
90
- def _remove_file(self, abs_path):
91
- try:
92
- rel_path = os.path.relpath(abs_path, self.project_path)
93
- with self.lock:
94
- if rel_path in self.file_info:
95
- del self.file_info[rel_path]
96
- except Exception:
97
- pass
98
-
99
- def _start_watchdog(self):
100
- """启动watchdog监控项目目录变更"""
101
- event_handler = FileCacheHandler(self)
102
- self.observer = Observer()
103
- self.observer.schedule(
104
- event_handler, self.project_path, recursive=True)
105
- self.observer.daemon = True
106
- self.observer.start()
107
-
108
- def stop(self):
109
- """停止监控"""
110
- if self.observer:
111
- self.observer.stop()
112
- self.observer.join()
113
-
114
- def _save_cache(self):
115
- """将缓存写入磁盘"""
116
- try:
117
- cache_dir = os.path.dirname(self.index_file)
118
- os.makedirs(cache_dir, exist_ok=True)
119
- with open(self.index_file, 'w', encoding='utf-8') as f:
120
- json.dump(self.file_info, f)
121
- except Exception:
122
- pass
123
-
124
- def load_cache(self):
125
- """尝试加载磁盘缓存"""
126
- try:
127
- if os.path.exists(self.index_file):
128
- with open(self.index_file, 'r', encoding='utf-8') as f:
129
- self.file_info = json.load(f)
130
- self.ready = True
131
- except Exception:
132
- pass
133
-
134
- def search_files(self, patterns):
135
- """
136
- 根据模式列表查找匹配文件
137
- :param patterns: list[str]
138
- :return: FileCacheResult(miss=True/False, files=List[str])
139
- """
140
- if not self.ready:
141
- # 索引未准备好,返回 miss = True,空文件列表
142
- return self.FileCacheResult(miss=True, files=[])
143
-
144
- matched = set()
145
- default_exclude_dirs = [".git", "node_modules", "dist", "build", "__pycache__", ".venv", ".auto-coder"]
146
- project_root = self.project_path
147
-
148
- def should_exclude_path(path: str) -> bool:
149
- """检查路径是否应该被排除(路径中包含排除目录或以.开头的目录/文件)"""
150
- # 处理相对/绝对路径
151
- rel_path = path
152
- if os.path.isabs(path):
153
- try:
154
- rel_path = os.path.relpath(path, project_root)
155
- except ValueError:
156
- rel_path = path
157
-
158
- # 检查文件或目录本身是否以.开头
159
- if os.path.basename(rel_path).startswith('.'):
160
- return True
161
-
162
- # 检查路径中是否包含排除目录
163
- path_parts = rel_path.split(os.sep)
164
- return any(part in default_exclude_dirs or part.startswith('.') for part in path_parts)
165
-
166
- with self.lock:
167
- # 如果没有提供有效模式,返回过滤后的缓存列表
168
- if not patterns or (len(patterns) == 1 and patterns[0] == ""):
169
- for rel_path, info in self.file_info.items():
170
- abs_path = info.get("abs_path", "")
171
- if not should_exclude_path(rel_path):
172
- matched.add(rel_path)
173
- return self.FileCacheResult(miss=False, files=list(matched))
174
-
175
- for pattern in patterns:
176
- # 1. 在缓存中匹配文件名
177
- for rel_path, info in self.file_info.items():
178
- filename = info.get("name", "")
179
- abs_path = info.get("abs_path", "")
180
- if should_exclude_path(rel_path):
181
- continue
182
- if pattern in filename:
183
- matched.add(rel_path)
184
-
185
- # 2. 如果pattern本身是存在的文件路径(绝对或相对)
186
- abs_pattern_path = pattern
187
- if not os.path.isabs(abs_pattern_path):
188
- abs_pattern_path = os.path.join(project_root, pattern)
189
- if os.path.exists(abs_pattern_path) and os.path.isfile(abs_pattern_path) and not should_exclude_path(abs_pattern_path):
190
- try:
191
- rel_p = os.path.relpath(abs_pattern_path, project_root)
192
- matched.add(rel_p)
193
- except:
194
- matched.add(abs_pattern_path)
195
- return self.FileCacheResult(miss=False, files=list(matched))
@@ -1,69 +0,0 @@
1
- from fastapi import HTTPException
2
- from typing import List, Dict, Optional
3
- import os
4
- from .auto_coder_runner import AutoCoderRunner
5
-
6
- class FileGroupManager:
7
- def __init__(self,auto_coder_runner: AutoCoderRunner):
8
- self.runner = auto_coder_runner
9
-
10
- async def create_group(self, name: str, description: str) -> Dict:
11
- group = self.runner.add_group(name,description=description)
12
- if group is None:
13
- raise HTTPException(status_code=400, detail="Group already exists")
14
- return {
15
- "name": name,
16
- "description": description,
17
- "files": []
18
- }
19
-
20
- async def switch_groups(self, group_names: List[str]) -> Dict:
21
- result = self.runner.switch_groups(group_names)
22
- if result is None:
23
- raise HTTPException(status_code=404, detail="Group not found")
24
- return result
25
-
26
- async def delete_group(self, name: str) -> None:
27
- result = self.runner.remove_group(name)
28
- if result is None:
29
- raise HTTPException(status_code=404, detail="Group not found")
30
-
31
- async def add_files_to_group(self, group_name: str, files: List[str]) -> Dict:
32
- result = self.runner.add_files_to_group(group_name, files)
33
- if result is None:
34
- raise HTTPException(status_code=404, detail="Group not found")
35
- return {
36
- "name": group_name,
37
- "files": result.get("files", [])
38
- }
39
-
40
- async def remove_files_from_group(self, group_name: str, files: List[str]) -> Dict:
41
- result = self.runner.remove_files_from_group(group_name, files)
42
- if result is None:
43
- raise HTTPException(status_code=404, detail="Group not found")
44
- return {
45
- "name": group_name,
46
- "files": result.get("files", [])
47
- }
48
-
49
- async def get_groups(self) -> List[Dict]:
50
- groups = self.runner.get_groups()
51
- if not groups:
52
- return []
53
- return [
54
- {
55
- "name": group_name,
56
- "files": self.runner.get_files_in_group(group_name).get("files", []),
57
- "description": self.runner.get_group_description(group_name)
58
- }
59
- for group_name in groups.get("groups", [])
60
- ]
61
-
62
- async def get_group(self, name: str) -> Optional[Dict]:
63
- files = self.runner.get_files_in_group(name)
64
- if files is None:
65
- return None
66
- return {
67
- "name": name,
68
- "files": files.get("files", [])
69
- }