auto-coder 0.1.316__py3-none-any.whl → 0.1.317__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.
Potentially problematic release.
This version of auto-coder might be problematic. Click here for more details.
- {auto_coder-0.1.316.dist-info → auto_coder-0.1.317.dist-info}/METADATA +1 -1
- {auto_coder-0.1.316.dist-info → auto_coder-0.1.317.dist-info}/RECORD +41 -20
- autocoder/auto_coder_runner.py +1 -2
- autocoder/common/__init__.py +3 -0
- autocoder/common/auto_coder_lang.py +24 -0
- autocoder/common/code_auto_merge_editblock.py +2 -42
- autocoder/common/git_utils.py +2 -2
- autocoder/common/token_cost_caculate.py +103 -42
- autocoder/common/v2/__init__.py +0 -0
- autocoder/common/v2/code_auto_generate.py +199 -0
- autocoder/common/v2/code_auto_generate_diff.py +361 -0
- autocoder/common/v2/code_auto_generate_editblock.py +380 -0
- autocoder/common/v2/code_auto_generate_strict_diff.py +269 -0
- autocoder/common/v2/code_auto_merge.py +211 -0
- autocoder/common/v2/code_auto_merge_diff.py +354 -0
- autocoder/common/v2/code_auto_merge_editblock.py +523 -0
- autocoder/common/v2/code_auto_merge_strict_diff.py +259 -0
- autocoder/common/v2/code_diff_manager.py +266 -0
- autocoder/common/v2/code_editblock_manager.py +275 -0
- autocoder/common/v2/code_manager.py +238 -0
- autocoder/common/v2/code_strict_diff_manager.py +241 -0
- autocoder/dispacher/actions/action.py +16 -0
- autocoder/dispacher/actions/plugins/action_regex_project.py +6 -0
- autocoder/events/event_manager_singleton.py +2 -2
- autocoder/helper/__init__.py +0 -0
- autocoder/helper/project_creator.py +570 -0
- autocoder/linters/linter_factory.py +44 -25
- autocoder/linters/models.py +220 -0
- autocoder/linters/python_linter.py +1 -7
- autocoder/linters/reactjs_linter.py +580 -0
- autocoder/linters/shadow_linter.py +390 -0
- autocoder/linters/vue_linter.py +576 -0
- autocoder/memory/active_context_manager.py +0 -4
- autocoder/memory/active_package.py +12 -12
- autocoder/shadows/__init__.py +0 -0
- autocoder/shadows/shadow_manager.py +235 -0
- autocoder/version.py +1 -1
- {auto_coder-0.1.316.dist-info → auto_coder-0.1.317.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.316.dist-info → auto_coder-0.1.317.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.316.dist-info → auto_coder-0.1.317.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.316.dist-info → auto_coder-0.1.317.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
ProjectCreator 类:用于创建示例项目的工具类
|
|
6
|
+
可以灵活配置项目结构、文件内容和 Git 初始化选项
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
import shutil
|
|
11
|
+
import git
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Dict, List, Optional, Any
|
|
14
|
+
from abc import ABC, abstractmethod
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class FileCreator(ABC):
|
|
18
|
+
"""
|
|
19
|
+
文件创建抽象基类,定义了创建项目文件的接口
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
@abstractmethod
|
|
23
|
+
def create_files(self, project_dir: str) -> None:
|
|
24
|
+
"""
|
|
25
|
+
在项目目录中创建必要的文件
|
|
26
|
+
|
|
27
|
+
参数:
|
|
28
|
+
project_dir: 项目目录路径
|
|
29
|
+
"""
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
@abstractmethod
|
|
33
|
+
def get_file_paths(self, project_dir: str) -> List[str]:
|
|
34
|
+
"""
|
|
35
|
+
获取创建的文件路径列表,用于配置文件中引用
|
|
36
|
+
|
|
37
|
+
参数:
|
|
38
|
+
project_dir: 项目目录路径
|
|
39
|
+
|
|
40
|
+
返回:
|
|
41
|
+
List[str]: 文件路径的列表
|
|
42
|
+
"""
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
@abstractmethod
|
|
47
|
+
def project_type(self) -> str:
|
|
48
|
+
"""返回项目类型标识"""
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class PythonFileCreator(FileCreator):
|
|
53
|
+
"""
|
|
54
|
+
Python 计算器项目文件创建器
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
def create_files(self, project_dir: str) -> None:
|
|
58
|
+
"""创建 Python 项目文件"""
|
|
59
|
+
# 创建计算器文件
|
|
60
|
+
self._create_calculator_file(project_dir)
|
|
61
|
+
# 创建主程序文件
|
|
62
|
+
self._create_main_file(project_dir)
|
|
63
|
+
|
|
64
|
+
def get_file_paths(self, project_dir: str) -> List[str]:
|
|
65
|
+
"""获取 Python 项目的主要文件路径"""
|
|
66
|
+
abs_project_dir = os.path.abspath(project_dir)
|
|
67
|
+
return [
|
|
68
|
+
os.path.join(abs_project_dir, "calculator.py"),
|
|
69
|
+
os.path.join(abs_project_dir, "main.py")
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def project_type(self) -> str:
|
|
74
|
+
"""返回项目类型"""
|
|
75
|
+
return "py"
|
|
76
|
+
|
|
77
|
+
def _create_calculator_file(self, project_dir: str) -> None:
|
|
78
|
+
"""创建计算器示例文件"""
|
|
79
|
+
calculator_path = os.path.join(project_dir, "calculator.py")
|
|
80
|
+
calculator_content = """
|
|
81
|
+
class Calculator:
|
|
82
|
+
def __init__(self):
|
|
83
|
+
self.history = []
|
|
84
|
+
|
|
85
|
+
def add(self, a, b):
|
|
86
|
+
'''加法函数'''
|
|
87
|
+
result = a + b
|
|
88
|
+
self.history.append(f"{a} + {b} = {result}")
|
|
89
|
+
return result
|
|
90
|
+
|
|
91
|
+
def subtract(self, a, b):
|
|
92
|
+
'''减法函数'''
|
|
93
|
+
result = a - b
|
|
94
|
+
self.history.append(f"{a} - {b} = {result}")
|
|
95
|
+
return result
|
|
96
|
+
|
|
97
|
+
def clear_history(self):
|
|
98
|
+
'''清除历史记录'''
|
|
99
|
+
self.history = []
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
with open(calculator_path, "w", encoding="utf-8") as f:
|
|
103
|
+
f.write(calculator_content)
|
|
104
|
+
|
|
105
|
+
def _create_main_file(self, project_dir: str) -> None:
|
|
106
|
+
"""创建主程序文件"""
|
|
107
|
+
main_path = os.path.join(project_dir, "main.py")
|
|
108
|
+
main_content = """
|
|
109
|
+
from calculator import Calculator
|
|
110
|
+
from abc import ABC, abstractmethod
|
|
111
|
+
def main():
|
|
112
|
+
calc = Calculator()
|
|
113
|
+
|
|
114
|
+
# 进行一些计算
|
|
115
|
+
print(calc.add(5, 3))
|
|
116
|
+
print(calc.subtract(10, 4))
|
|
117
|
+
|
|
118
|
+
# 打印历史记录
|
|
119
|
+
print("计算历史:")
|
|
120
|
+
for item in calc.history:
|
|
121
|
+
print(item)
|
|
122
|
+
|
|
123
|
+
if __name__ == "__main__":
|
|
124
|
+
main()
|
|
125
|
+
"""
|
|
126
|
+
|
|
127
|
+
with open(main_path, "w", encoding="utf-8") as f:
|
|
128
|
+
f.write(main_content)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class ReactJSFileCreator(FileCreator):
|
|
132
|
+
"""
|
|
133
|
+
React TypeScript 计算器项目文件创建器
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
def create_files(self, project_dir: str) -> None:
|
|
137
|
+
"""创建 React TypeScript 项目文件"""
|
|
138
|
+
# 创建 package.json
|
|
139
|
+
self._create_package_json(project_dir)
|
|
140
|
+
# 创建 index.html
|
|
141
|
+
self._create_index_html(project_dir)
|
|
142
|
+
# 创建 src 目录
|
|
143
|
+
src_dir = os.path.join(project_dir, "src")
|
|
144
|
+
os.makedirs(src_dir, exist_ok=True)
|
|
145
|
+
# 创建 App.tsx 和 Calculator.tsx 组件
|
|
146
|
+
self._create_app_tsx(src_dir)
|
|
147
|
+
self._create_calculator_component(src_dir)
|
|
148
|
+
self._create_index_tsx(src_dir)
|
|
149
|
+
# 创建 tsconfig.json
|
|
150
|
+
self._create_tsconfig_json(project_dir)
|
|
151
|
+
|
|
152
|
+
def get_file_paths(self, project_dir: str) -> List[str]:
|
|
153
|
+
"""获取 React TypeScript 项目的主要文件路径"""
|
|
154
|
+
abs_project_dir = os.path.abspath(project_dir)
|
|
155
|
+
return [
|
|
156
|
+
os.path.join(abs_project_dir, "package.json"),
|
|
157
|
+
os.path.join(abs_project_dir, "tsconfig.json"),
|
|
158
|
+
os.path.join(abs_project_dir, "src", "App.tsx"),
|
|
159
|
+
os.path.join(abs_project_dir, "src", "Calculator.tsx"),
|
|
160
|
+
os.path.join(abs_project_dir, "src", "index.tsx")
|
|
161
|
+
]
|
|
162
|
+
|
|
163
|
+
@property
|
|
164
|
+
def project_type(self) -> str:
|
|
165
|
+
"""返回项目类型"""
|
|
166
|
+
return "tsx"
|
|
167
|
+
|
|
168
|
+
def _create_index_html(self, project_dir: str) -> None:
|
|
169
|
+
"""创建 index.html 文件"""
|
|
170
|
+
index_html_path = os.path.join(project_dir, "public", "index.html")
|
|
171
|
+
os.makedirs(os.path.dirname(index_html_path), exist_ok=True)
|
|
172
|
+
index_html_content = """<!DOCTYPE html>
|
|
173
|
+
<html lang="en">
|
|
174
|
+
<head>
|
|
175
|
+
<meta charset="utf-8" />
|
|
176
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
177
|
+
<meta name="theme-color" content="#000000" />
|
|
178
|
+
<meta name="description" content="React Calculator App" />
|
|
179
|
+
<title>React Calculator</title>
|
|
180
|
+
</head>
|
|
181
|
+
<body>
|
|
182
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
183
|
+
<div id="root"></div>
|
|
184
|
+
</body>
|
|
185
|
+
</html>"""
|
|
186
|
+
with open(index_html_path, "w", encoding="utf-8") as f:
|
|
187
|
+
f.write(index_html_content)
|
|
188
|
+
|
|
189
|
+
def _create_package_json(self, project_dir: str) -> None:
|
|
190
|
+
"""创建 package.json 文件"""
|
|
191
|
+
package_path = os.path.join(project_dir, "package.json")
|
|
192
|
+
package_content = """{
|
|
193
|
+
"name": "calculator-app",
|
|
194
|
+
"version": "0.1.0",
|
|
195
|
+
"private": true,
|
|
196
|
+
"dependencies": {
|
|
197
|
+
"react": "^18.2.0",
|
|
198
|
+
"react-dom": "^18.2.0",
|
|
199
|
+
"react-scripts": "5.0.1",
|
|
200
|
+
"@types/node": "^16.18.0",
|
|
201
|
+
"@types/react": "^18.2.0",
|
|
202
|
+
"@types/react-dom": "^18.2.0",
|
|
203
|
+
"typescript": "^4.9.5"
|
|
204
|
+
},
|
|
205
|
+
"scripts": {
|
|
206
|
+
"start": "react-scripts start",
|
|
207
|
+
"build": "react-scripts build",
|
|
208
|
+
"test": "react-scripts test",
|
|
209
|
+
"eject": "react-scripts eject"
|
|
210
|
+
},
|
|
211
|
+
"eslintConfig": {
|
|
212
|
+
"extends": [
|
|
213
|
+
"react-app",
|
|
214
|
+
"react-app/jest"
|
|
215
|
+
]
|
|
216
|
+
},
|
|
217
|
+
"browserslist": {
|
|
218
|
+
"production": [
|
|
219
|
+
">0.2%",
|
|
220
|
+
"not dead",
|
|
221
|
+
"not op_mini all"
|
|
222
|
+
],
|
|
223
|
+
"development": [
|
|
224
|
+
"last 1 chrome version",
|
|
225
|
+
"last 1 firefox version",
|
|
226
|
+
"last 1 safari version"
|
|
227
|
+
]
|
|
228
|
+
}
|
|
229
|
+
}"""
|
|
230
|
+
with open(package_path, "w", encoding="utf-8") as f:
|
|
231
|
+
f.write(package_content)
|
|
232
|
+
|
|
233
|
+
def _create_tsconfig_json(self, project_dir: str) -> None:
|
|
234
|
+
"""创建 tsconfig.json 文件"""
|
|
235
|
+
tsconfig_path = os.path.join(project_dir, "tsconfig.json")
|
|
236
|
+
tsconfig_content = """{
|
|
237
|
+
"compilerOptions": {
|
|
238
|
+
"target": "es5",
|
|
239
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
240
|
+
"allowJs": true,
|
|
241
|
+
"skipLibCheck": true,
|
|
242
|
+
"esModuleInterop": true,
|
|
243
|
+
"allowSyntheticDefaultImports": true,
|
|
244
|
+
"strict": true,
|
|
245
|
+
"forceConsistentCasingInFileNames": true,
|
|
246
|
+
"noFallthroughCasesInSwitch": true,
|
|
247
|
+
"module": "esnext",
|
|
248
|
+
"moduleResolution": "node",
|
|
249
|
+
"resolveJsonModule": true,
|
|
250
|
+
"isolatedModules": true,
|
|
251
|
+
"noEmit": true,
|
|
252
|
+
"jsx": "react-jsx"
|
|
253
|
+
},
|
|
254
|
+
"include": ["src"]
|
|
255
|
+
}"""
|
|
256
|
+
with open(tsconfig_path, "w", encoding="utf-8") as f:
|
|
257
|
+
f.write(tsconfig_content)
|
|
258
|
+
|
|
259
|
+
def _create_app_tsx(self, src_dir: str) -> None:
|
|
260
|
+
"""创建 App.tsx 文件"""
|
|
261
|
+
app_path = os.path.join(src_dir, "App.tsx")
|
|
262
|
+
app_content = """import React from 'react';
|
|
263
|
+
import Calculator from './Calculator';
|
|
264
|
+
|
|
265
|
+
const App: React.FC = () => {
|
|
266
|
+
return (
|
|
267
|
+
<div className="App">
|
|
268
|
+
<header className="App-header">
|
|
269
|
+
<h1>React Calculator</h1>
|
|
270
|
+
</header>
|
|
271
|
+
<main>
|
|
272
|
+
<Calculator />
|
|
273
|
+
</main>
|
|
274
|
+
</div>
|
|
275
|
+
);
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
export default App;"""
|
|
279
|
+
with open(app_path, "w", encoding="utf-8") as f:
|
|
280
|
+
f.write(app_content)
|
|
281
|
+
|
|
282
|
+
def _create_calculator_component(self, src_dir: str) -> None:
|
|
283
|
+
"""创建 Calculator.tsx 组件"""
|
|
284
|
+
calculator_path = os.path.join(src_dir, "Calculator.tsx")
|
|
285
|
+
calculator_content = """import React, { useState } from 'react';
|
|
286
|
+
|
|
287
|
+
interface CalculatorProps {}
|
|
288
|
+
|
|
289
|
+
const Calculator: React.FC<CalculatorProps> = () => {
|
|
290
|
+
const [display, setDisplay] = useState<string>('0');
|
|
291
|
+
const [equation, setEquation] = useState<string>('');
|
|
292
|
+
|
|
293
|
+
const handleNumber = (num: string) => {
|
|
294
|
+
if (display === '0') {
|
|
295
|
+
setDisplay(num);
|
|
296
|
+
} else {
|
|
297
|
+
setDisplay(display + num);
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
const handleOperator = (operator: string) => {
|
|
302
|
+
setEquation(display + ' ' + operator + ' ');
|
|
303
|
+
setDisplay('0');
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
const handleEqual = () => {
|
|
307
|
+
try {
|
|
308
|
+
const result = eval(equation + display);
|
|
309
|
+
setDisplay(result.toString());
|
|
310
|
+
setEquation('');
|
|
311
|
+
} catch (error) {
|
|
312
|
+
setDisplay('Error');
|
|
313
|
+
setEquation('');
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
const handleClear = () => {
|
|
318
|
+
setDisplay('0');
|
|
319
|
+
setEquation('');
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
return (
|
|
323
|
+
<div className="calculator">
|
|
324
|
+
<div className="display">
|
|
325
|
+
<div className="equation">{equation}</div>
|
|
326
|
+
<div className="current">{display}</div>
|
|
327
|
+
</div>
|
|
328
|
+
<div className="buttons">
|
|
329
|
+
<button onClick={handleClear}>C</button>
|
|
330
|
+
<button onClick={() => handleOperator('/')}>/</button>
|
|
331
|
+
<button onClick={() => handleOperator('*')}>×</button>
|
|
332
|
+
<button onClick={() => handleNumber('7')}>7</button>
|
|
333
|
+
<button onClick={() => handleNumber('8')}>8</button>
|
|
334
|
+
<button onClick={() => handleNumber('9')}>9</button>
|
|
335
|
+
<button onClick={() => handleOperator('-')}>-</button>
|
|
336
|
+
<button onClick={() => handleNumber('4')}>4</button>
|
|
337
|
+
<button onClick={() => handleNumber('5')}>5</button>
|
|
338
|
+
<button onClick={() => handleNumber('6')}>6</button>
|
|
339
|
+
<button onClick={() => handleOperator('+')}>+</button>
|
|
340
|
+
<button onClick={() => handleNumber('1')}>1</button>
|
|
341
|
+
<button onClick={() => handleNumber('2')}>2</button>
|
|
342
|
+
<button onClick={() => handleNumber('3')}>3</button>
|
|
343
|
+
<button onClick={handleEqual}>=</button>
|
|
344
|
+
<button onClick={() => handleNumber('0')}>0</button>
|
|
345
|
+
<button onClick={() => handleNumber('.')}>.</button>
|
|
346
|
+
</div>
|
|
347
|
+
</div>
|
|
348
|
+
);
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
export default Calculator;"""
|
|
352
|
+
with open(calculator_path, "w", encoding="utf-8") as f:
|
|
353
|
+
f.write(calculator_content)
|
|
354
|
+
|
|
355
|
+
def _create_index_tsx(self, src_dir: str) -> None:
|
|
356
|
+
"""创建 index.tsx 文件"""
|
|
357
|
+
index_path = os.path.join(src_dir, "index.tsx")
|
|
358
|
+
index_content = """import React from 'react';
|
|
359
|
+
import ReactDOM from 'react-dom/client';
|
|
360
|
+
import App from './App';
|
|
361
|
+
|
|
362
|
+
const root = ReactDOM.createRoot(
|
|
363
|
+
document.getElementById('root') as HTMLElement
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
root.render(
|
|
367
|
+
<React.StrictMode>
|
|
368
|
+
<App />
|
|
369
|
+
</React.StrictMode>
|
|
370
|
+
);"""
|
|
371
|
+
with open(index_path, "w", encoding="utf-8") as f:
|
|
372
|
+
f.write(index_content)
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
class FileCreatorFactory:
|
|
376
|
+
"""
|
|
377
|
+
文件创建器工厂类,根据项目类型返回对应的文件创建器
|
|
378
|
+
"""
|
|
379
|
+
|
|
380
|
+
@staticmethod
|
|
381
|
+
def get_creator(project_type: str) -> FileCreator:
|
|
382
|
+
"""
|
|
383
|
+
获取指定类型的文件创建器
|
|
384
|
+
|
|
385
|
+
参数:
|
|
386
|
+
project_type: 项目类型,支持 'python'/'py' 或 'react'/'js'
|
|
387
|
+
|
|
388
|
+
返回:
|
|
389
|
+
FileCreator: 对应的文件创建器实例
|
|
390
|
+
|
|
391
|
+
异常:
|
|
392
|
+
ValueError: 不支持的项目类型
|
|
393
|
+
"""
|
|
394
|
+
project_type = project_type.lower()
|
|
395
|
+
|
|
396
|
+
if project_type in ('python', 'py'):
|
|
397
|
+
return PythonFileCreator()
|
|
398
|
+
elif project_type in ('react', 'reactjs', 'js'):
|
|
399
|
+
return ReactJSFileCreator()
|
|
400
|
+
else:
|
|
401
|
+
raise ValueError(f"不支持的项目类型: {project_type}")
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
class ProjectCreator:
|
|
405
|
+
"""
|
|
406
|
+
创建示例项目的工具类,支持自定义项目结构和内容
|
|
407
|
+
"""
|
|
408
|
+
|
|
409
|
+
def __init__(
|
|
410
|
+
self,
|
|
411
|
+
project_name: str = "test_project",
|
|
412
|
+
project_type: str = "python",
|
|
413
|
+
git_init: bool = True,
|
|
414
|
+
git_user_email: str = "example@example.com",
|
|
415
|
+
git_user_name: str = "Example User",
|
|
416
|
+
create_actions: bool = True,
|
|
417
|
+
query: str = "给计算器添加乘法和除法功能",
|
|
418
|
+
model: str = "v3_chat",
|
|
419
|
+
product_mode: str = "lite"
|
|
420
|
+
):
|
|
421
|
+
"""
|
|
422
|
+
初始化项目创建器
|
|
423
|
+
|
|
424
|
+
参数:
|
|
425
|
+
project_name: 项目名称和目录名
|
|
426
|
+
project_type: 项目类型,支持 'python'/'py' 或 'react'/'js'
|
|
427
|
+
git_init: 是否初始化 Git 仓库
|
|
428
|
+
git_user_email: Git 用户邮箱
|
|
429
|
+
git_user_name: Git 用户名
|
|
430
|
+
create_actions: 是否创建 actions 目录和配置文件
|
|
431
|
+
query: 默认查询内容
|
|
432
|
+
model: 使用的模型名称
|
|
433
|
+
product_mode: 模型的产品模式
|
|
434
|
+
"""
|
|
435
|
+
self.project_name = project_name
|
|
436
|
+
self.git_init = git_init
|
|
437
|
+
self.git_user_email = git_user_email
|
|
438
|
+
self.git_user_name = git_user_name
|
|
439
|
+
self.create_actions = create_actions
|
|
440
|
+
self.query = query
|
|
441
|
+
self.model = model
|
|
442
|
+
self.product_mode = product_mode
|
|
443
|
+
|
|
444
|
+
# 使用工厂获取文件创建器
|
|
445
|
+
self.file_creator = FileCreatorFactory.get_creator(project_type)
|
|
446
|
+
|
|
447
|
+
def create_project(self) -> str:
|
|
448
|
+
"""
|
|
449
|
+
创建一个示例项目目录和文件
|
|
450
|
+
|
|
451
|
+
返回:
|
|
452
|
+
str: 项目目录的绝对路径
|
|
453
|
+
"""
|
|
454
|
+
# 创建项目目录
|
|
455
|
+
project_dir = self.project_name
|
|
456
|
+
if os.path.exists(project_dir):
|
|
457
|
+
shutil.rmtree(project_dir)
|
|
458
|
+
os.makedirs(project_dir)
|
|
459
|
+
|
|
460
|
+
# 使用文件创建器创建项目文件
|
|
461
|
+
self.file_creator.create_files(project_dir)
|
|
462
|
+
|
|
463
|
+
# 创建配置文件
|
|
464
|
+
if self.create_actions:
|
|
465
|
+
self._create_actions_files(project_dir)
|
|
466
|
+
|
|
467
|
+
# 初始化 Git 仓库
|
|
468
|
+
if self.git_init:
|
|
469
|
+
self._init_git_repo(project_dir)
|
|
470
|
+
|
|
471
|
+
return os.path.abspath(project_dir)
|
|
472
|
+
|
|
473
|
+
def _create_actions_files(self, project_dir: str) -> None:
|
|
474
|
+
"""创建 actions 目录和配置文件"""
|
|
475
|
+
# 创建 actions 目录
|
|
476
|
+
actions_dir = os.path.join(project_dir, "actions")
|
|
477
|
+
os.makedirs(actions_dir, exist_ok=True)
|
|
478
|
+
|
|
479
|
+
# 创建 base 目录
|
|
480
|
+
base_dir = os.path.join(actions_dir, "base")
|
|
481
|
+
os.makedirs(base_dir, exist_ok=True)
|
|
482
|
+
|
|
483
|
+
# 创建 base.yml 文件
|
|
484
|
+
self._create_base_yml(project_dir, base_dir)
|
|
485
|
+
|
|
486
|
+
# 创建 chat_action.yml 文件
|
|
487
|
+
self._create_chat_action_yml(project_dir, actions_dir)
|
|
488
|
+
|
|
489
|
+
def _create_base_yml(self, project_dir: str, base_dir: str) -> None:
|
|
490
|
+
"""创建 base.yml 配置文件"""
|
|
491
|
+
base_yml_path = os.path.join(base_dir, "base.yml")
|
|
492
|
+
abs_project_dir = os.path.abspath(project_dir)
|
|
493
|
+
base_yml_content = f"""source_dir: {abs_project_dir}
|
|
494
|
+
target_file: {os.path.join(abs_project_dir, "output.txt")}
|
|
495
|
+
project_type: {self.file_creator.project_type}
|
|
496
|
+
|
|
497
|
+
model: {self.model}
|
|
498
|
+
index_model: {self.model}
|
|
499
|
+
|
|
500
|
+
index_filter_level: 1
|
|
501
|
+
index_model_max_input_length: 100000
|
|
502
|
+
model_max_input_length: 120000
|
|
503
|
+
index_filter_workers: 100
|
|
504
|
+
index_build_workers: 100
|
|
505
|
+
|
|
506
|
+
skip_build_index: false
|
|
507
|
+
execute: true
|
|
508
|
+
enable_multi_round_generate: false
|
|
509
|
+
auto_merge: editblock
|
|
510
|
+
human_as_model: false
|
|
511
|
+
"""
|
|
512
|
+
|
|
513
|
+
with open(base_yml_path, "w", encoding="utf-8") as f:
|
|
514
|
+
f.write(base_yml_content)
|
|
515
|
+
|
|
516
|
+
def _create_chat_action_yml(self, project_dir: str, actions_dir: str) -> None:
|
|
517
|
+
"""创建 chat_action.yml 配置文件"""
|
|
518
|
+
chat_action_path = os.path.join(actions_dir, "000000000001_chat_action.yml")
|
|
519
|
+
|
|
520
|
+
# 获取文件路径列表
|
|
521
|
+
file_paths = self.file_creator.get_file_paths(project_dir)
|
|
522
|
+
file_urls = "\n".join([f"- {path}" for path in file_paths])
|
|
523
|
+
|
|
524
|
+
chat_action_content = f"""add_updated_urls: []
|
|
525
|
+
auto_merge: editblock
|
|
526
|
+
chat_model: {self.model}
|
|
527
|
+
code_model: {self.model}
|
|
528
|
+
enable_active_context: true
|
|
529
|
+
enable_global_memory: false
|
|
530
|
+
enable_task_history: true
|
|
531
|
+
generate_times_same_model: 1
|
|
532
|
+
human_as_model: false
|
|
533
|
+
include_file:
|
|
534
|
+
- ./base/base.yml
|
|
535
|
+
include_project_structure: true
|
|
536
|
+
model: {self.model}
|
|
537
|
+
product_mode: {self.product_mode}
|
|
538
|
+
query: '{self.query}'
|
|
539
|
+
silence: false
|
|
540
|
+
skip_build_index: true
|
|
541
|
+
skip_confirm: true
|
|
542
|
+
skip_filter_index: false
|
|
543
|
+
urls:
|
|
544
|
+
{file_urls}
|
|
545
|
+
"""
|
|
546
|
+
|
|
547
|
+
with open(chat_action_path, "w", encoding="utf-8") as f:
|
|
548
|
+
f.write(chat_action_content)
|
|
549
|
+
|
|
550
|
+
def _init_git_repo(self, project_dir: str) -> None:
|
|
551
|
+
"""初始化 Git 仓库"""
|
|
552
|
+
try:
|
|
553
|
+
# 初始化 Git 仓库
|
|
554
|
+
repo = git.Repo.init(project_dir)
|
|
555
|
+
|
|
556
|
+
# 设置用户信息
|
|
557
|
+
config_writer = repo.config_writer()
|
|
558
|
+
config_writer.set_value("user", "email", self.git_user_email)
|
|
559
|
+
config_writer.set_value("user", "name", self.git_user_name)
|
|
560
|
+
config_writer.release()
|
|
561
|
+
|
|
562
|
+
# 添加所有文件
|
|
563
|
+
repo.git.add(A=True)
|
|
564
|
+
|
|
565
|
+
# 提交
|
|
566
|
+
repo.index.commit("Initial commit")
|
|
567
|
+
|
|
568
|
+
print("Git 仓库初始化成功")
|
|
569
|
+
except Exception as e:
|
|
570
|
+
print(f"Git 初始化失败: {e}")
|