auto-coder 0.1.326__py3-none-any.whl → 0.1.328__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.326.dist-info → auto_coder-0.1.328.dist-info}/METADATA +1 -1
- {auto_coder-0.1.326.dist-info → auto_coder-0.1.328.dist-info}/RECORD +28 -16
- autocoder/common/__init__.py +5 -0
- autocoder/common/auto_coder_lang.py +16 -0
- autocoder/common/stream_out_type.py +6 -0
- autocoder/common/v2/code_editblock_manager.py +92 -8
- autocoder/compilers/__init__.py +51 -0
- autocoder/compilers/base_compiler.py +107 -0
- autocoder/compilers/compiler_config_api.py +365 -0
- autocoder/compilers/compiler_config_manager.py +305 -0
- autocoder/compilers/compiler_factory.py +271 -0
- autocoder/compilers/java_compiler.py +680 -0
- autocoder/compilers/models.py +210 -0
- autocoder/compilers/provided_compiler.py +343 -0
- autocoder/compilers/python_compiler.py +413 -0
- autocoder/compilers/reactjs_compiler.py +491 -0
- autocoder/compilers/shadow_compiler.py +42 -0
- autocoder/compilers/vue_compiler.py +548 -0
- autocoder/events/event_content.py +29 -0
- autocoder/index/index.py +43 -9
- autocoder/memory/active_context_manager.py +3 -3
- autocoder/memory/active_package.py +2 -2
- autocoder/shadows/shadow_manager.py +251 -4
- autocoder/version.py +1 -1
- {auto_coder-0.1.326.dist-info → auto_coder-0.1.328.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.326.dist-info → auto_coder-0.1.328.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.326.dist-info → auto_coder-0.1.328.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.326.dist-info → auto_coder-0.1.328.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module for compiling/checking Vue.js code.
|
|
3
|
+
This module provides functionality to compile/check Vue.js code using tools like npm and vue-cli.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import json
|
|
8
|
+
import subprocess
|
|
9
|
+
import tempfile
|
|
10
|
+
import time
|
|
11
|
+
import re
|
|
12
|
+
from typing import Dict, List, Any, Optional, Tuple
|
|
13
|
+
|
|
14
|
+
from autocoder.compilers.base_compiler import BaseCompiler
|
|
15
|
+
from autocoder.compilers.models import (
|
|
16
|
+
CompilationError,
|
|
17
|
+
FileCompilationResult,
|
|
18
|
+
ProjectCompilationResult,
|
|
19
|
+
CompilationErrorPosition,
|
|
20
|
+
CompilationErrorSeverity
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
class VueCompiler(BaseCompiler):
|
|
24
|
+
"""
|
|
25
|
+
A class that provides compilation/checking functionality for Vue.js code.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self, verbose: bool = False):
|
|
29
|
+
"""
|
|
30
|
+
Initialize the VueCompiler.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
verbose (bool): Whether to display verbose output.
|
|
34
|
+
"""
|
|
35
|
+
super().__init__(verbose)
|
|
36
|
+
|
|
37
|
+
def get_supported_extensions(self) -> List[str]:
|
|
38
|
+
"""
|
|
39
|
+
Get the list of file extensions supported by this compiler.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
List[str]: List of supported file extensions.
|
|
43
|
+
"""
|
|
44
|
+
return ['.vue', '.js', '.ts']
|
|
45
|
+
|
|
46
|
+
def _check_dependencies(self) -> bool:
|
|
47
|
+
"""
|
|
48
|
+
Check if required dependencies (node, npm) are installed.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
bool: True if all dependencies are available, False otherwise.
|
|
52
|
+
"""
|
|
53
|
+
try:
|
|
54
|
+
# Check if node is installed
|
|
55
|
+
node_process = subprocess.run(
|
|
56
|
+
['node', '--version'],
|
|
57
|
+
stdout=subprocess.PIPE,
|
|
58
|
+
stderr=subprocess.PIPE
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# Check if npm is installed
|
|
62
|
+
npm_process = subprocess.run(
|
|
63
|
+
['npm', '--version'],
|
|
64
|
+
stdout=subprocess.PIPE,
|
|
65
|
+
stderr=subprocess.PIPE
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
return node_process.returncode == 0 and npm_process.returncode == 0
|
|
69
|
+
except (subprocess.SubprocessError, FileNotFoundError):
|
|
70
|
+
return False
|
|
71
|
+
|
|
72
|
+
def _is_vue_project(self, project_path: str) -> bool:
|
|
73
|
+
"""
|
|
74
|
+
Check if a directory is a Vue.js project.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
project_path (str): Path to check.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
bool: True if the directory contains a Vue.js project, False otherwise.
|
|
81
|
+
"""
|
|
82
|
+
# Check for package.json
|
|
83
|
+
package_json_path = os.path.join(project_path, 'package.json')
|
|
84
|
+
if not os.path.exists(package_json_path):
|
|
85
|
+
return False
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
# Read package.json to check for Vue dependency
|
|
89
|
+
with open(package_json_path, 'r') as f:
|
|
90
|
+
package_data = json.load(f)
|
|
91
|
+
|
|
92
|
+
dependencies = package_data.get('dependencies', {})
|
|
93
|
+
dev_dependencies = package_data.get('devDependencies', {})
|
|
94
|
+
|
|
95
|
+
# Check if Vue is a dependency or vue-cli is a dev dependency
|
|
96
|
+
return ('vue' in dependencies or
|
|
97
|
+
'vue' in dev_dependencies or
|
|
98
|
+
'@vue/cli-service' in dev_dependencies)
|
|
99
|
+
except:
|
|
100
|
+
return False
|
|
101
|
+
|
|
102
|
+
def _parse_error_position(self, error_text: str) -> Tuple[int, Optional[int]]:
|
|
103
|
+
"""
|
|
104
|
+
Parse line and column from error text.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
error_text (str): Error text to parse.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
Tuple[int, Optional[int]]: Line and column (if found).
|
|
111
|
+
"""
|
|
112
|
+
# Look for common patterns like "Line X:Y" or "line X, column Y" or "LX:CY"
|
|
113
|
+
patterns = [
|
|
114
|
+
r'[Ll]ine\s+(\d+)(?:[,:]\s*(?:column\s+)?(\d+))?',
|
|
115
|
+
r'[Ll](\d+)(?:[,:]\s*[Cc](\d+))?',
|
|
116
|
+
r'[\(\[](\d+)[,:]\s*(\d+)[\)\]]',
|
|
117
|
+
r'at\s+\w+\s+\(.*?:(\d+)(?::(\d+))?\)'
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
for pattern in patterns:
|
|
121
|
+
match = re.search(pattern, error_text)
|
|
122
|
+
if match:
|
|
123
|
+
line = int(match.group(1))
|
|
124
|
+
column = int(match.group(2)) if match.group(2) else None
|
|
125
|
+
return line, column
|
|
126
|
+
|
|
127
|
+
return 1, None # Default to line 1 if not found
|
|
128
|
+
|
|
129
|
+
def _parse_compilation_error(self, error_text: str, file_path: str) -> CompilationError:
|
|
130
|
+
"""
|
|
131
|
+
Parse a compilation error message and create a CompilationError object.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
error_text (str): Raw error message.
|
|
135
|
+
file_path (str): Path to the file with the error.
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
CompilationError: Parsed error object.
|
|
139
|
+
"""
|
|
140
|
+
line, column = self._parse_error_position(error_text)
|
|
141
|
+
|
|
142
|
+
return CompilationError(
|
|
143
|
+
message=error_text,
|
|
144
|
+
severity=CompilationErrorSeverity.ERROR,
|
|
145
|
+
position=CompilationErrorPosition(
|
|
146
|
+
line=line,
|
|
147
|
+
column=column
|
|
148
|
+
),
|
|
149
|
+
file_path=file_path,
|
|
150
|
+
code="vue-compilation-error"
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
def _check_vue_file_syntax(self, file_path: str) -> Dict[str, Any]:
|
|
154
|
+
"""
|
|
155
|
+
Check syntax of a Vue file using vue-template-compiler and babel.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
file_path (str): Path to the file to check.
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
Dict[str, Any]: Dictionary containing syntax check results.
|
|
162
|
+
"""
|
|
163
|
+
errors = []
|
|
164
|
+
error_count = 0
|
|
165
|
+
warning_count = 0
|
|
166
|
+
|
|
167
|
+
try:
|
|
168
|
+
# Create a temporary directory
|
|
169
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
170
|
+
# Create a minimal package.json for Vue syntax checking
|
|
171
|
+
package_json = {
|
|
172
|
+
"name": "vue-syntax-checker",
|
|
173
|
+
"version": "1.0.0",
|
|
174
|
+
"description": "Temporary package for Vue syntax checking",
|
|
175
|
+
"dependencies": {
|
|
176
|
+
"vue": "^2.6.12",
|
|
177
|
+
"vue-template-compiler": "^2.6.12",
|
|
178
|
+
"@babel/core": "^7.14.0",
|
|
179
|
+
"@babel/preset-env": "^7.14.0"
|
|
180
|
+
},
|
|
181
|
+
"scripts": {
|
|
182
|
+
"check": "node check-vue.js"
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
# Write package.json
|
|
187
|
+
with open(os.path.join(temp_dir, 'package.json'), 'w') as f:
|
|
188
|
+
json.dump(package_json, f)
|
|
189
|
+
|
|
190
|
+
# Create a script to check Vue file syntax
|
|
191
|
+
checker_script = """
|
|
192
|
+
const fs = require('fs');
|
|
193
|
+
const compiler = require('vue-template-compiler');
|
|
194
|
+
const babel = require('@babel/core');
|
|
195
|
+
|
|
196
|
+
const filePath = process.argv[2];
|
|
197
|
+
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
// Parse the Vue file
|
|
201
|
+
const parsed = compiler.parseComponent(fileContent);
|
|
202
|
+
|
|
203
|
+
// Check template syntax
|
|
204
|
+
if (parsed.template) {
|
|
205
|
+
try {
|
|
206
|
+
compiler.compile(parsed.template.content);
|
|
207
|
+
} catch (e) {
|
|
208
|
+
console.error(`Template error: ${e.message}`);
|
|
209
|
+
process.exit(1);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Check script syntax
|
|
214
|
+
if (parsed.script) {
|
|
215
|
+
try {
|
|
216
|
+
babel.transformSync(parsed.script.content, {
|
|
217
|
+
presets: ['@babel/preset-env']
|
|
218
|
+
});
|
|
219
|
+
} catch (e) {
|
|
220
|
+
console.error(`Script error: ${e.message}`);
|
|
221
|
+
process.exit(1);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
console.log('Syntax check passed');
|
|
226
|
+
process.exit(0);
|
|
227
|
+
} catch (e) {
|
|
228
|
+
console.error(`Error parsing Vue file: ${e.message}`);
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
"""
|
|
232
|
+
|
|
233
|
+
# Write the checker script
|
|
234
|
+
with open(os.path.join(temp_dir, 'check-vue.js'), 'w') as f:
|
|
235
|
+
f.write(checker_script)
|
|
236
|
+
|
|
237
|
+
# Install dependencies
|
|
238
|
+
subprocess.run(
|
|
239
|
+
['npm', 'install', '--silent'],
|
|
240
|
+
cwd=temp_dir,
|
|
241
|
+
stdout=subprocess.PIPE,
|
|
242
|
+
stderr=subprocess.PIPE
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
# Run the checker
|
|
246
|
+
cmd = ['node', 'check-vue.js', file_path]
|
|
247
|
+
|
|
248
|
+
process = subprocess.run(
|
|
249
|
+
cmd,
|
|
250
|
+
cwd=temp_dir,
|
|
251
|
+
stdout=subprocess.PIPE,
|
|
252
|
+
stderr=subprocess.PIPE,
|
|
253
|
+
text=True
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
# Check for syntax errors
|
|
257
|
+
if process.returncode != 0:
|
|
258
|
+
for line in process.stderr.splitlines():
|
|
259
|
+
if line.strip():
|
|
260
|
+
error = self._parse_compilation_error(line, file_path)
|
|
261
|
+
errors.append(error)
|
|
262
|
+
error_count += 1
|
|
263
|
+
|
|
264
|
+
except Exception as e:
|
|
265
|
+
errors.append(CompilationError(
|
|
266
|
+
message=f"Error checking syntax: {str(e)}",
|
|
267
|
+
severity=CompilationErrorSeverity.ERROR,
|
|
268
|
+
position=CompilationErrorPosition(line=1),
|
|
269
|
+
file_path=file_path,
|
|
270
|
+
code="syntax-check-error"
|
|
271
|
+
))
|
|
272
|
+
error_count += 1
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
'success': error_count == 0,
|
|
276
|
+
'errors': errors,
|
|
277
|
+
'error_count': error_count,
|
|
278
|
+
'warning_count': warning_count
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
def compile_file(self, file_path: str) -> Dict[str, Any]:
|
|
282
|
+
"""
|
|
283
|
+
Compile (check) a single Vue.js file.
|
|
284
|
+
|
|
285
|
+
Args:
|
|
286
|
+
file_path (str): Path to the file to compile.
|
|
287
|
+
|
|
288
|
+
Returns:
|
|
289
|
+
Dict[str, Any]: Compilation results.
|
|
290
|
+
"""
|
|
291
|
+
if not os.path.exists(file_path):
|
|
292
|
+
return FileCompilationResult(
|
|
293
|
+
file_path=file_path,
|
|
294
|
+
success=False,
|
|
295
|
+
language="vue",
|
|
296
|
+
error_message=f"File not found: {file_path}"
|
|
297
|
+
).model_dump()
|
|
298
|
+
|
|
299
|
+
if not self.is_supported_file(file_path):
|
|
300
|
+
return FileCompilationResult(
|
|
301
|
+
file_path=file_path,
|
|
302
|
+
success=False,
|
|
303
|
+
language="vue",
|
|
304
|
+
error_message=f"Unsupported file type: {file_path}"
|
|
305
|
+
).model_dump()
|
|
306
|
+
|
|
307
|
+
if not self._check_dependencies():
|
|
308
|
+
return FileCompilationResult(
|
|
309
|
+
file_path=file_path,
|
|
310
|
+
success=False,
|
|
311
|
+
language="vue",
|
|
312
|
+
error_message="Node.js and npm are required but not found. Please make sure they are installed."
|
|
313
|
+
).model_dump()
|
|
314
|
+
|
|
315
|
+
start_time = time.time()
|
|
316
|
+
|
|
317
|
+
# Check syntax based on file type
|
|
318
|
+
if file_path.endswith('.vue'):
|
|
319
|
+
syntax_result = self._check_vue_file_syntax(file_path)
|
|
320
|
+
else:
|
|
321
|
+
# For .js and .ts files, reuse the same approach as ReactJS
|
|
322
|
+
from autocoder.compilers.reactjs_compiler import ReactJSCompiler
|
|
323
|
+
reactjs_compiler = ReactJSCompiler(verbose=self.verbose)
|
|
324
|
+
syntax_result = reactjs_compiler._check_file_syntax(file_path)
|
|
325
|
+
|
|
326
|
+
# Calculate execution time
|
|
327
|
+
execution_time_ms = int((time.time() - start_time) * 1000)
|
|
328
|
+
|
|
329
|
+
# Create the result
|
|
330
|
+
result = FileCompilationResult(
|
|
331
|
+
file_path=file_path,
|
|
332
|
+
success=syntax_result['success'],
|
|
333
|
+
language="vue",
|
|
334
|
+
errors=syntax_result['errors'],
|
|
335
|
+
error_count=syntax_result['error_count'],
|
|
336
|
+
warning_count=syntax_result['warning_count'],
|
|
337
|
+
info_count=0,
|
|
338
|
+
execution_time_ms=execution_time_ms
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
return result.model_dump()
|
|
342
|
+
|
|
343
|
+
def compile_project(self, project_path: str) -> Dict[str, Any]:
|
|
344
|
+
"""
|
|
345
|
+
Compile (build) a Vue.js project.
|
|
346
|
+
|
|
347
|
+
Args:
|
|
348
|
+
project_path (str): Path to the project directory.
|
|
349
|
+
|
|
350
|
+
Returns:
|
|
351
|
+
Dict[str, Any]: Compilation results.
|
|
352
|
+
"""
|
|
353
|
+
if not os.path.exists(project_path):
|
|
354
|
+
return ProjectCompilationResult(
|
|
355
|
+
project_path=project_path,
|
|
356
|
+
success=False,
|
|
357
|
+
total_files=0,
|
|
358
|
+
error_message=f"Project directory not found: {project_path}"
|
|
359
|
+
).model_dump()
|
|
360
|
+
|
|
361
|
+
if not self._check_dependencies():
|
|
362
|
+
return ProjectCompilationResult(
|
|
363
|
+
project_path=project_path,
|
|
364
|
+
success=False,
|
|
365
|
+
total_files=0,
|
|
366
|
+
error_message="Node.js and npm are required but not found. Please make sure they are installed."
|
|
367
|
+
).model_dump()
|
|
368
|
+
|
|
369
|
+
if not self._is_vue_project(project_path):
|
|
370
|
+
return ProjectCompilationResult(
|
|
371
|
+
project_path=project_path,
|
|
372
|
+
success=False,
|
|
373
|
+
total_files=0,
|
|
374
|
+
error_message=f"The directory does not appear to be a Vue.js project: {project_path}"
|
|
375
|
+
).model_dump()
|
|
376
|
+
|
|
377
|
+
start_time = time.time()
|
|
378
|
+
|
|
379
|
+
# Run npm build
|
|
380
|
+
cmd = ['npm', 'run', 'build']
|
|
381
|
+
|
|
382
|
+
process = subprocess.run(
|
|
383
|
+
cmd,
|
|
384
|
+
cwd=project_path,
|
|
385
|
+
stdout=subprocess.PIPE,
|
|
386
|
+
stderr=subprocess.PIPE,
|
|
387
|
+
text=True
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
success = process.returncode == 0
|
|
391
|
+
output = process.stdout + process.stderr
|
|
392
|
+
errors = []
|
|
393
|
+
error_count = 0
|
|
394
|
+
warning_count = 0
|
|
395
|
+
file_results = {}
|
|
396
|
+
total_files = 0
|
|
397
|
+
files_with_errors = 0
|
|
398
|
+
|
|
399
|
+
# Find Vue files in the project
|
|
400
|
+
vue_files = []
|
|
401
|
+
for root, _, files in os.walk(project_path):
|
|
402
|
+
for file in files:
|
|
403
|
+
if any(file.endswith(ext) for ext in self.get_supported_extensions()):
|
|
404
|
+
# Skip node_modules directory
|
|
405
|
+
if 'node_modules' not in root:
|
|
406
|
+
file_path = os.path.join(root, file)
|
|
407
|
+
vue_files.append(file_path)
|
|
408
|
+
total_files += 1
|
|
409
|
+
|
|
410
|
+
if not success:
|
|
411
|
+
# Parse build errors
|
|
412
|
+
file_error_map = {} # Maps file paths to errors
|
|
413
|
+
|
|
414
|
+
# Look for error patterns in the output
|
|
415
|
+
# Vue CLI uses webpack, so errors are often similar to webpack errors
|
|
416
|
+
error_blocks = re.split(r'ERROR\s+in\s+|Module build failed|Failed to compile', output)
|
|
417
|
+
|
|
418
|
+
if len(error_blocks) > 1: # If we found error blocks
|
|
419
|
+
for block in error_blocks[1:]: # Skip the first block (before the error)
|
|
420
|
+
# Try to find file path in error block
|
|
421
|
+
file_match = re.search(r'((?:\.\./)*(?:src|components|views|pages).*?\.(?:vue|js|ts))', block)
|
|
422
|
+
if file_match:
|
|
423
|
+
error_file = os.path.join(project_path, file_match.group(1))
|
|
424
|
+
if os.path.exists(error_file):
|
|
425
|
+
error_message = block.strip()
|
|
426
|
+
|
|
427
|
+
if error_file not in file_error_map:
|
|
428
|
+
file_error_map[error_file] = []
|
|
429
|
+
|
|
430
|
+
error = self._parse_compilation_error(error_message, error_file)
|
|
431
|
+
file_error_map[error_file].append(error)
|
|
432
|
+
errors.append(error)
|
|
433
|
+
error_count += 1
|
|
434
|
+
|
|
435
|
+
# If no structured errors found, fall back to checking each file individually
|
|
436
|
+
if not errors:
|
|
437
|
+
for file_path in vue_files:
|
|
438
|
+
file_result = self.compile_file(file_path)
|
|
439
|
+
file_results[file_path] = file_result
|
|
440
|
+
|
|
441
|
+
if not file_result['success']:
|
|
442
|
+
files_with_errors += 1
|
|
443
|
+
|
|
444
|
+
error_count += file_result['error_count']
|
|
445
|
+
warning_count += file_result['warning_count']
|
|
446
|
+
|
|
447
|
+
# Add file errors to the project errors list
|
|
448
|
+
for error in file_result.get('errors', []):
|
|
449
|
+
errors.append(error)
|
|
450
|
+
else:
|
|
451
|
+
# Create file results from the error map
|
|
452
|
+
for file_path in vue_files:
|
|
453
|
+
file_errors = file_error_map.get(file_path, [])
|
|
454
|
+
|
|
455
|
+
file_result = FileCompilationResult(
|
|
456
|
+
file_path=file_path,
|
|
457
|
+
success=len(file_errors) == 0,
|
|
458
|
+
language="vue",
|
|
459
|
+
errors=file_errors,
|
|
460
|
+
error_count=len(file_errors),
|
|
461
|
+
warning_count=0,
|
|
462
|
+
info_count=0
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
file_results[file_path] = file_result.model_dump()
|
|
466
|
+
|
|
467
|
+
if len(file_errors) > 0:
|
|
468
|
+
files_with_errors += 1
|
|
469
|
+
else:
|
|
470
|
+
# If build succeeded, create a success result for each file
|
|
471
|
+
for file_path in vue_files:
|
|
472
|
+
file_result = FileCompilationResult(
|
|
473
|
+
file_path=file_path,
|
|
474
|
+
success=True,
|
|
475
|
+
language="vue",
|
|
476
|
+
errors=[],
|
|
477
|
+
error_count=0,
|
|
478
|
+
warning_count=0,
|
|
479
|
+
info_count=0
|
|
480
|
+
)
|
|
481
|
+
|
|
482
|
+
file_results[file_path] = file_result.model_dump()
|
|
483
|
+
|
|
484
|
+
# Calculate execution time
|
|
485
|
+
execution_time_ms = int((time.time() - start_time) * 1000)
|
|
486
|
+
|
|
487
|
+
# Determine output directory based on Vue.js versions
|
|
488
|
+
output_dir = os.path.join(project_path, 'dist')
|
|
489
|
+
|
|
490
|
+
# Create the project result
|
|
491
|
+
result = ProjectCompilationResult(
|
|
492
|
+
project_path=project_path,
|
|
493
|
+
success=success,
|
|
494
|
+
total_files=total_files,
|
|
495
|
+
files_with_errors=files_with_errors,
|
|
496
|
+
total_errors=error_count,
|
|
497
|
+
total_warnings=warning_count,
|
|
498
|
+
total_infos=0,
|
|
499
|
+
file_results={p: FileCompilationResult(**r) for p, r in file_results.items()},
|
|
500
|
+
output_directory=output_dir if success else None
|
|
501
|
+
)
|
|
502
|
+
|
|
503
|
+
return result.model_dump()
|
|
504
|
+
|
|
505
|
+
def format_compile_result(self, compile_result: Dict[str, Any]) -> str:
|
|
506
|
+
"""
|
|
507
|
+
Format compilation results into a human-readable string.
|
|
508
|
+
|
|
509
|
+
Args:
|
|
510
|
+
compile_result (Dict[str, Any]): The compilation result dictionary.
|
|
511
|
+
|
|
512
|
+
Returns:
|
|
513
|
+
str: A formatted string representation of the compilation results.
|
|
514
|
+
"""
|
|
515
|
+
if 'project_path' in compile_result:
|
|
516
|
+
# This is a project result
|
|
517
|
+
return ProjectCompilationResult(**compile_result).to_str()
|
|
518
|
+
else:
|
|
519
|
+
# This is a file result
|
|
520
|
+
return FileCompilationResult(**compile_result).to_str()
|
|
521
|
+
|
|
522
|
+
def compile_vue_file(file_path: str, verbose: bool = False) -> Dict[str, Any]:
|
|
523
|
+
"""
|
|
524
|
+
Utility function to compile a single Vue.js file.
|
|
525
|
+
|
|
526
|
+
Args:
|
|
527
|
+
file_path (str): Path to the file to compile.
|
|
528
|
+
verbose (bool): Whether to display verbose output.
|
|
529
|
+
|
|
530
|
+
Returns:
|
|
531
|
+
Dict[str, Any]: A dictionary containing compilation results.
|
|
532
|
+
"""
|
|
533
|
+
compiler = VueCompiler(verbose=verbose)
|
|
534
|
+
return compiler.compile_file(file_path)
|
|
535
|
+
|
|
536
|
+
def compile_vue_project(project_path: str, verbose: bool = False) -> Dict[str, Any]:
|
|
537
|
+
"""
|
|
538
|
+
Utility function to compile a Vue.js project.
|
|
539
|
+
|
|
540
|
+
Args:
|
|
541
|
+
project_path (str): Path to the project directory.
|
|
542
|
+
verbose (bool): Whether to display verbose output.
|
|
543
|
+
|
|
544
|
+
Returns:
|
|
545
|
+
Dict[str, Any]: A dictionary containing compilation results.
|
|
546
|
+
"""
|
|
547
|
+
compiler = VueCompiler(verbose=verbose)
|
|
548
|
+
return compiler.compile_project(project_path)
|
|
@@ -119,6 +119,35 @@ class ResultTokenStatContent(BaseModel):
|
|
|
119
119
|
"""转换为JSON字符串"""
|
|
120
120
|
return self.model_dump_json()
|
|
121
121
|
|
|
122
|
+
class IndexBuildStartContent(BaseModel):
|
|
123
|
+
file_number:int = 0
|
|
124
|
+
total_files:int = 0
|
|
125
|
+
|
|
126
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
127
|
+
"""转换为字典"""
|
|
128
|
+
return self.model_dump()
|
|
129
|
+
|
|
130
|
+
def to_json(self) -> str:
|
|
131
|
+
"""转换为JSON字符串"""
|
|
132
|
+
return self.model_dump_json()
|
|
133
|
+
|
|
134
|
+
class IndexBuildEndContent(BaseModel):
|
|
135
|
+
updated_files:int = 0
|
|
136
|
+
removed_files:int = 0
|
|
137
|
+
input_tokens:int = 0
|
|
138
|
+
output_tokens:int = 0
|
|
139
|
+
input_cost:float = 0.0
|
|
140
|
+
output_cost:float = 0.0
|
|
141
|
+
|
|
142
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
143
|
+
"""转换为字典"""
|
|
144
|
+
return self.model_dump()
|
|
145
|
+
|
|
146
|
+
def to_json(self) -> str:
|
|
147
|
+
"""转换为JSON字符串"""
|
|
148
|
+
return self.model_dump_json()
|
|
149
|
+
|
|
150
|
+
|
|
122
151
|
|
|
123
152
|
class ResultCommandPrepareStatContent(BaseModel):
|
|
124
153
|
command:str = ""
|
autocoder/index/index.py
CHANGED
|
@@ -28,7 +28,9 @@ from autocoder.index.types import (
|
|
|
28
28
|
from autocoder.common.global_cancel import global_cancel
|
|
29
29
|
from autocoder.utils.llms import get_llm_names
|
|
30
30
|
from autocoder.rag.token_counter import count_tokens
|
|
31
|
-
|
|
31
|
+
from autocoder.common.stream_out_type import IndexStreamOutType
|
|
32
|
+
from autocoder.events.event_manager_singleton import get_event_manager
|
|
33
|
+
from autocoder.events import event_content as EventContentCreator
|
|
32
34
|
|
|
33
35
|
class IndexManager:
|
|
34
36
|
def __init__(
|
|
@@ -190,7 +192,7 @@ class IndexManager:
|
|
|
190
192
|
{{ code }}
|
|
191
193
|
|
|
192
194
|
## 输出
|
|
193
|
-
"""
|
|
195
|
+
"""
|
|
194
196
|
|
|
195
197
|
@byzerllm.prompt()
|
|
196
198
|
def jsp_get_all_file_symbols(self, path: str, code: str) -> str:
|
|
@@ -224,11 +226,11 @@ class IndexManager:
|
|
|
224
226
|
url : "admWorkingDay!updateAdmWorkingDayList.action", 中,那么对应的为 <ajax method="post" url="admWorkingDay!updateAdmWorkingDayList.action">
|
|
225
227
|
10. 导入语句中需要包含超连接,比如 <a href="admRiskLimits!queryAdmRiskLimitsById.action?admRiskLimits.id=${fn:escapeXml(item.id)}">${fn:escapeXml(item.classification)}, 对应的为 <a href="admRiskLimits!queryAdmRiskLimitsById.action"}
|
|
226
228
|
11. 导入语句中需要包含一些js函数里的值,比如 window.onbeforeunload = function() {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
229
|
+
var actionType = document.ap_ActionPlanForm.action.value;
|
|
230
|
+
if(typeof(window.opener.reloadApCount)!="undefined"&&(actionType&&actionType!='Discard')){
|
|
231
|
+
}
|
|
230
232
|
} 对应为 <window.onbeforeunload url="from 表单名字为ap_ActionPlanForm的action的值">
|
|
231
|
-
|
|
233
|
+
|
|
232
234
|
下面是一段示例:
|
|
233
235
|
|
|
234
236
|
## 输入
|
|
@@ -363,14 +365,14 @@ class IndexManager:
|
|
|
363
365
|
else:
|
|
364
366
|
meta_holder = byzerllm.MetaHolder()
|
|
365
367
|
ext = os.path.splitext(file_path)[1].lower()
|
|
366
|
-
|
|
368
|
+
# 需要有特殊prompt
|
|
367
369
|
if ext == ".jsp":
|
|
368
370
|
symbols = self.jsp_get_all_file_symbols.with_llm(
|
|
369
371
|
self.index_llm).with_meta(meta_holder).run(source.module_name, source_code)
|
|
370
372
|
else:
|
|
371
373
|
symbols = self.get_all_file_symbols.with_llm(
|
|
372
374
|
self.index_llm).with_meta(meta_holder).run(source.module_name, source_code)
|
|
373
|
-
|
|
375
|
+
|
|
374
376
|
time.sleep(self.anti_quota_limit)
|
|
375
377
|
|
|
376
378
|
if meta_holder.get_meta():
|
|
@@ -478,7 +480,8 @@ class IndexManager:
|
|
|
478
480
|
|
|
479
481
|
# 删除被排除的文件
|
|
480
482
|
try:
|
|
481
|
-
exclude_patterns = self.parse_exclude_files(
|
|
483
|
+
exclude_patterns = self.parse_exclude_files(
|
|
484
|
+
self.args.exclude_files)
|
|
482
485
|
for file_path in index_data:
|
|
483
486
|
if self.filter_exclude_files(file_path, exclude_patterns):
|
|
484
487
|
keys_to_remove.append(file_path)
|
|
@@ -546,6 +549,19 @@ class IndexManager:
|
|
|
546
549
|
num_files=num_files
|
|
547
550
|
)
|
|
548
551
|
|
|
552
|
+
get_event_manager(self.args.event_file).write_result(
|
|
553
|
+
EventContentCreator.create_result(
|
|
554
|
+
content=EventContentCreator.IndexBuildStartContent(
|
|
555
|
+
file_number=num_files,
|
|
556
|
+
total_files=total_files
|
|
557
|
+
).to_dict(),
|
|
558
|
+
metadata={
|
|
559
|
+
"stream_out_type": IndexStreamOutType.INDEX_BUILD.value,
|
|
560
|
+
"action_file": self.args.file
|
|
561
|
+
}
|
|
562
|
+
)
|
|
563
|
+
)
|
|
564
|
+
|
|
549
565
|
futures = [
|
|
550
566
|
executor.submit(self.build_index_for_single_source, source)
|
|
551
567
|
for source in wait_to_build_files
|
|
@@ -592,6 +608,24 @@ class IndexManager:
|
|
|
592
608
|
)
|
|
593
609
|
print("")
|
|
594
610
|
|
|
611
|
+
# 记录索引构建完成事件
|
|
612
|
+
get_event_manager(self.args.event_file).write_result(
|
|
613
|
+
EventContentCreator.create_result(
|
|
614
|
+
content=EventContentCreator.IndexBuildEndContent(
|
|
615
|
+
updated_files=len(updated_sources),
|
|
616
|
+
removed_files=len(keys_to_remove),
|
|
617
|
+
input_tokens=total_input_tokens,
|
|
618
|
+
output_tokens=total_output_tokens,
|
|
619
|
+
input_cost=total_input_cost,
|
|
620
|
+
output_cost=total_output_cost
|
|
621
|
+
).to_dict(),
|
|
622
|
+
metadata={}
|
|
623
|
+
).to_dict(),
|
|
624
|
+
metadata={
|
|
625
|
+
"stream_out_type": IndexStreamOutType.INDEX_BUILD.value,
|
|
626
|
+
"action_file": self.args.file
|
|
627
|
+
}
|
|
628
|
+
)
|
|
595
629
|
return index_data
|
|
596
630
|
|
|
597
631
|
def read_index_as_str(self):
|