auto-coder 0.1.255__py3-none-any.whl → 0.1.256__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.255.dist-info → auto_coder-0.1.256.dist-info}/METADATA +2 -2
- {auto_coder-0.1.255.dist-info → auto_coder-0.1.256.dist-info}/RECORD +22 -22
- autocoder/auto_coder.py +14 -0
- autocoder/common/auto_coder_lang.py +8 -8
- autocoder/common/code_auto_generate.py +23 -3
- autocoder/common/code_auto_generate_diff.py +22 -3
- autocoder/common/code_auto_generate_editblock.py +24 -2
- autocoder/common/code_auto_generate_strict_diff.py +23 -4
- autocoder/common/code_modification_ranker.py +39 -3
- autocoder/dispacher/actions/action.py +22 -12
- autocoder/dispacher/actions/plugins/action_regex_project.py +4 -0
- autocoder/index/filter/quick_filter.py +175 -65
- autocoder/models.py +30 -6
- autocoder/pyproject/__init__.py +1 -0
- autocoder/suffixproject/__init__.py +1 -0
- autocoder/tsproject/__init__.py +1 -0
- autocoder/utils/llms.py +27 -0
- autocoder/version.py +1 -1
- {auto_coder-0.1.255.dist-info → auto_coder-0.1.256.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.255.dist-info → auto_coder-0.1.256.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.255.dist-info → auto_coder-0.1.256.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.255.dist-info → auto_coder-0.1.256.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: auto-coder
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.256
|
|
4
4
|
Summary: AutoCoder: AutoCoder
|
|
5
5
|
Author: allwefantasy
|
|
6
6
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
@@ -26,7 +26,7 @@ Requires-Dist: tabulate
|
|
|
26
26
|
Requires-Dist: jupyter-client
|
|
27
27
|
Requires-Dist: prompt-toolkit
|
|
28
28
|
Requires-Dist: tokenizers
|
|
29
|
-
Requires-Dist: byzerllm[saas] >=0.1.
|
|
29
|
+
Requires-Dist: byzerllm[saas] >=0.1.164
|
|
30
30
|
Requires-Dist: patch
|
|
31
31
|
Requires-Dist: diff-match-patch
|
|
32
32
|
Requires-Dist: GitPython
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
autocoder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
autocoder/auto_coder.py,sha256=
|
|
2
|
+
autocoder/auto_coder.py,sha256=obRx5lFu8P4M5mmLA717lwMso7Ei3Kx3i9kG7I_xrRY,65654
|
|
3
3
|
autocoder/auto_coder_lang.py,sha256=Rtupq6N3_HT7JRhDKdgCBcwRaiAnyCOR_Gsp4jUomrI,3229
|
|
4
4
|
autocoder/auto_coder_rag.py,sha256=DDAmqw36CO6phtdQuN8LYIbIR3YGdoZw5-pG0LjVxMc,29063
|
|
5
5
|
autocoder/auto_coder_rag_client_mcp.py,sha256=WV7j5JUiQge0x4-B7Hp5-pSAFXLbvLpzQMcCovbauIM,6276
|
|
@@ -10,8 +10,8 @@ autocoder/chat_auto_coder.py,sha256=a1YEp6OPMzpLbRpr2hrbzF6pRnhVPTVxyZfBiQHFPIw,
|
|
|
10
10
|
autocoder/chat_auto_coder_lang.py,sha256=1cJrjFGrcOQnuP2LdZpgGDSX4CNaIYI7KZGvEEtj6_Q,18242
|
|
11
11
|
autocoder/command_args.py,sha256=9aYJ-AmPxP1sQh6ciw04FWHjSn31f2W9afXFwo8wgx4,30441
|
|
12
12
|
autocoder/lang.py,sha256=U6AjVV8Rs1uLyjFCZ8sT6WWuNUxMBqkXXIOs4S120uk,14511
|
|
13
|
-
autocoder/models.py,sha256=
|
|
14
|
-
autocoder/version.py,sha256=
|
|
13
|
+
autocoder/models.py,sha256=xwWPcegwx945g433UZXna-7HBdnHWCq8oEfHm-HKIDQ,8651
|
|
14
|
+
autocoder/version.py,sha256=Mlq4zYTZeRq2mquyM-8m1qr6sjxAHZpSDVyjrKqhayc,23
|
|
15
15
|
autocoder/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
16
|
autocoder/agent/auto_demand_organizer.py,sha256=NWSAEsEk94vT3lGjfo25kKLMwYdPcpy9e-i21txPasQ,6942
|
|
17
17
|
autocoder/agent/auto_filegroup.py,sha256=CW7bqp0FW1GIEMnl-blyAc2UGT7O9Mom0q66ITz1ckM,6635
|
|
@@ -29,20 +29,20 @@ autocoder/common/__init__.py,sha256=6maackdzrYnUPvpgVPl92JdMOnw7X4n3EnEQA9OnLGE,
|
|
|
29
29
|
autocoder/common/anything2images.py,sha256=0ILBbWzY02M-CiWB-vzuomb_J1hVdxRcenAfIrAXq9M,25283
|
|
30
30
|
autocoder/common/anything2img.py,sha256=4TREa-sOA-iargieUy7MpyCYVUE-9Mmq0wJtwomPqnE,7662
|
|
31
31
|
autocoder/common/audio.py,sha256=Kn9nWKQddWnUrAz0a_ZUgjcu4VUU_IcZBigT7n3N3qc,7439
|
|
32
|
-
autocoder/common/auto_coder_lang.py,sha256=
|
|
32
|
+
autocoder/common/auto_coder_lang.py,sha256=x9Zjwvu9OZJjTmswwyimlMb1pvngUAF9_3oNQQut2i4,17634
|
|
33
33
|
autocoder/common/buildin_tokenizer.py,sha256=L7d5t39ZFvUd6EoMPXUhYK1toD0FHlRH1jtjKRGokWU,1236
|
|
34
34
|
autocoder/common/chunk_validation.py,sha256=BrR_ZWavW8IANuueEE7hS8NFAwEvm8TX34WnPx_1hs8,3030
|
|
35
35
|
autocoder/common/cleaner.py,sha256=NU72i8C6o9m0vXExab7nao5bstBUsfJFcj11cXa9l4U,1089
|
|
36
36
|
autocoder/common/code_auto_execute.py,sha256=4KXGmiGObr_B1d6tzV9dwS6MifCSc3Gm4j2d6ildBXQ,6867
|
|
37
|
-
autocoder/common/code_auto_generate.py,sha256=
|
|
38
|
-
autocoder/common/code_auto_generate_diff.py,sha256=
|
|
39
|
-
autocoder/common/code_auto_generate_editblock.py,sha256=
|
|
40
|
-
autocoder/common/code_auto_generate_strict_diff.py,sha256=
|
|
37
|
+
autocoder/common/code_auto_generate.py,sha256=E8r3VI88hPBPhU5t56qnmeL_fWtCWX1CJvaOachGa2Y,12014
|
|
38
|
+
autocoder/common/code_auto_generate_diff.py,sha256=dmMgN1yIOjJfiYFnzXZuktVFdj4_XR_Tavwx_ysm53U,17846
|
|
39
|
+
autocoder/common/code_auto_generate_editblock.py,sha256=NI_dFwy1VhvdjvARb04-B1AGfgW9z4P1BfWMm-blnaU,19447
|
|
40
|
+
autocoder/common/code_auto_generate_strict_diff.py,sha256=uf5P5B8ly0MP3jCK2PaYJiPLktd1cRRPouwkkaf-DfY,16457
|
|
41
41
|
autocoder/common/code_auto_merge.py,sha256=-ksBjj4ZVcbY_tVH4JLXAMSRtsgaSxrSZ5-MOl9cAgE,7354
|
|
42
42
|
autocoder/common/code_auto_merge_diff.py,sha256=qpEuHJEgX6sWK7EDFEKqcYkyI28wOyM4pytyl8BLohY,15350
|
|
43
43
|
autocoder/common/code_auto_merge_editblock.py,sha256=sxgYMLMACRwJvw-bABkdDHezPelsDFrOCpGuhtT5Dzs,17504
|
|
44
44
|
autocoder/common/code_auto_merge_strict_diff.py,sha256=P0nKNkBrFMybTSZ7kOdA_JixoVmLCZIhAP5q7ILJ9j0,9538
|
|
45
|
-
autocoder/common/code_modification_ranker.py,sha256=
|
|
45
|
+
autocoder/common/code_modification_ranker.py,sha256=oG9rCekGsYwE9gNdkIKQ6uKt6uaXpwrC17-FV5Wo-fQ,8187
|
|
46
46
|
autocoder/common/command_completer.py,sha256=IShrZJSpR-Q_MCj_aCVdVyscLYDKj5ZQK357QBcQ_oQ,9420
|
|
47
47
|
autocoder/common/command_generator.py,sha256=-hmbD_AnCa5HxL4BznuEfYAf_l8AxU5fAG5F0sM_fuE,2116
|
|
48
48
|
autocoder/common/command_templates.py,sha256=mnB3n8i0yjH1mqzyClEg8Wpr9VbZV44kxky66Zu6OJY,8557
|
|
@@ -76,10 +76,10 @@ autocoder/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
76
76
|
autocoder/db/store.py,sha256=tFT66bP2ZKIqZip-uhLkHRSLaaOAUUDZfozJwcqix3c,1908
|
|
77
77
|
autocoder/dispacher/__init__.py,sha256=YoA64dIxnx4jcE1pwSfg81sjkQtjDkhddkfac1-cMWo,1230
|
|
78
78
|
autocoder/dispacher/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
79
|
-
autocoder/dispacher/actions/action.py,sha256=
|
|
79
|
+
autocoder/dispacher/actions/action.py,sha256=sfh3pCasy622Jm0_AIKU7xtR-tqY2tS2_9YJsEd0FJY,22753
|
|
80
80
|
autocoder/dispacher/actions/copilot.py,sha256=iMh4ckj9hO5Q-iemF3CStXd7DatWai7Eci5zOlKxK9c,13072
|
|
81
81
|
autocoder/dispacher/actions/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
82
|
-
autocoder/dispacher/actions/plugins/action_regex_project.py,sha256=
|
|
82
|
+
autocoder/dispacher/actions/plugins/action_regex_project.py,sha256=22EZL3mLFxgsEZ8ymPCGvaHCJFnrW6C_prp1ykYCuEY,6335
|
|
83
83
|
autocoder/dispacher/actions/plugins/action_translate.py,sha256=nVAtRSQpdGNmZxg1R_9zXG3AuTv3CHf2v7ODgj8u65c,7727
|
|
84
84
|
autocoder/index/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
85
85
|
autocoder/index/entry.py,sha256=1KIGPCtxQN0OdErAco9OmGTd5hB8WJTpWGrxsGLsTcE,12634
|
|
@@ -89,8 +89,8 @@ autocoder/index/symbols_utils.py,sha256=CjcjUVajmJZB75Ty3a7kMv1BZphrm-tIBAdOJv6u
|
|
|
89
89
|
autocoder/index/types.py,sha256=a2s_KV5FJlq7jqA2ELSo9E1sjuLwDB-JJYMhSpzBAhU,596
|
|
90
90
|
autocoder/index/filter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
91
91
|
autocoder/index/filter/normal_filter.py,sha256=APu34iSvWhtlLtWgkj8N3Vo4oW1TegtZQq2bwDX_cs4,8031
|
|
92
|
-
autocoder/index/filter/quick_filter.py,sha256=
|
|
93
|
-
autocoder/pyproject/__init__.py,sha256=
|
|
92
|
+
autocoder/index/filter/quick_filter.py,sha256=5toipv7XwLsmG_UaqrElpGNjKXq_0bcvFr8W80vT44g,15206
|
|
93
|
+
autocoder/pyproject/__init__.py,sha256=bRuGxFV4QyE85xVjDzeMFmlLVqGbbcFs09FI15Uss4Q,14423
|
|
94
94
|
autocoder/rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
95
95
|
autocoder/rag/api_server.py,sha256=dRbhAZVRAOlZ64Cnxf4_rKb4iJwHnrWS9Zr67IVORw0,7288
|
|
96
96
|
autocoder/rag/doc_filter.py,sha256=ZCixxUXNBbz6UiGbgXvbDWdn5moLac3HnZEphpasTDc,6579
|
|
@@ -124,14 +124,14 @@ autocoder/rag/stream_event/event_writer.py,sha256=l7kq_LnDDE8E5dZ-73C7J2MgzSL7Wr
|
|
|
124
124
|
autocoder/rag/stream_event/types.py,sha256=rtLwOE8rShmi1dJdxyBpAV5ZjLBGG9vptMiSzMxGuIA,318
|
|
125
125
|
autocoder/regex_project/__init__.py,sha256=EBZeCL5ORyD_9_5u_UuG4s7XtpXOu0y1sWDmxWFtufE,6781
|
|
126
126
|
autocoder/regexproject/__init__.py,sha256=cEr-ZOaQjLD5sx7T7F2DhD5ips03HcJ02rded9EpSXc,9693
|
|
127
|
-
autocoder/suffixproject/__init__.py,sha256=
|
|
128
|
-
autocoder/tsproject/__init__.py,sha256=
|
|
127
|
+
autocoder/suffixproject/__init__.py,sha256=2dxh8vizDLiSqGpCx-V2VQ6cOfRZGxJMgosjwSlAsQM,11078
|
|
128
|
+
autocoder/tsproject/__init__.py,sha256=zGVSrxFo15Nh8GcSXHwdk4Fr-W7Bdb6IwVUX46PZKy4,11771
|
|
129
129
|
autocoder/utils/__init__.py,sha256=KtcGElFNBgZPF7dEL8zF9JpXkCAjoyDrzaREJBhJrcs,994
|
|
130
130
|
autocoder/utils/_markitdown.py,sha256=RU88qn4eZfYIy0GDrPxlI8oYXIypbi63VRJjdlnE0VU,47431
|
|
131
131
|
autocoder/utils/coder.py,sha256=rK8e0svQBe0NOP26dIGToUXgha_hUDgxlWoC_p_r7oc,5698
|
|
132
132
|
autocoder/utils/conversation_store.py,sha256=sz-hhY7sttPAUOAQU6Pze-5zJc3j0_Emj22dM_0l5ro,1161
|
|
133
133
|
autocoder/utils/llm_client_interceptors.py,sha256=FEHNXoFZlCjAHQcjPRyX8FOMjo6rPXpO2AJ2zn2KTTo,901
|
|
134
|
-
autocoder/utils/llms.py,sha256=
|
|
134
|
+
autocoder/utils/llms.py,sha256=HM5K_v4AcuWo65lgcp66DEqaU9-fjoT7mcI1iv2Fopg,3839
|
|
135
135
|
autocoder/utils/log_capture.py,sha256=I-bsJFLWoGUiX-GKoZsH9kWJCKSV7ZlUnRt7jh-fOL0,1548
|
|
136
136
|
autocoder/utils/multi_turn.py,sha256=unK9OpqVRbK6uIcTKXgggX2wNmyj7s5eyEAQ2xUwHoM,88
|
|
137
137
|
autocoder/utils/operate_config_api.py,sha256=99YAKsuUFLPwrRvj0CJal_bAPgyiXWMma6ZKMU56thw,5790
|
|
@@ -146,9 +146,9 @@ autocoder/utils/types.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
146
146
|
autocoder/utils/auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
147
147
|
autocoder/utils/auto_coder_utils/chat_stream_out.py,sha256=xWXqICANbDOovH4wcFW1eSI7lB7TjXbk1mSU4bTKEW4,11434
|
|
148
148
|
autocoder/utils/chat_auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
149
|
-
auto_coder-0.1.
|
|
150
|
-
auto_coder-0.1.
|
|
151
|
-
auto_coder-0.1.
|
|
152
|
-
auto_coder-0.1.
|
|
153
|
-
auto_coder-0.1.
|
|
154
|
-
auto_coder-0.1.
|
|
149
|
+
auto_coder-0.1.256.dist-info/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
150
|
+
auto_coder-0.1.256.dist-info/METADATA,sha256=NrC0Y2oSS6lDTeKbXKk3F1QnZ7_3Kie7pho_i7JhwJk,2616
|
|
151
|
+
auto_coder-0.1.256.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
152
|
+
auto_coder-0.1.256.dist-info/entry_points.txt,sha256=0nzHtHH4pNcM7xq4EBA2toS28Qelrvcbrr59GqD_0Ak,350
|
|
153
|
+
auto_coder-0.1.256.dist-info/top_level.txt,sha256=Jqc0_uJSw2GwoFQAa9iJxYns-2mWla-9ok_Y3Gcznjk,10
|
|
154
|
+
auto_coder-0.1.256.dist-info/RECORD,,
|
autocoder/auto_coder.py
CHANGED
|
@@ -1389,11 +1389,25 @@ def main(input_args: Optional[List[str]] = None):
|
|
|
1389
1389
|
elapsed_time = time.time() - start_time
|
|
1390
1390
|
printer = Printer()
|
|
1391
1391
|
speed = last_meta.generated_tokens_count / elapsed_time
|
|
1392
|
+
|
|
1393
|
+
# Get model info for pricing
|
|
1394
|
+
from autocoder.utils import llms as llm_utils
|
|
1395
|
+
model_info = llm_utils.get_model_info(model_name, args.product_mode) or {}
|
|
1396
|
+
input_price = model_info.get("input_price", 0.0) if model_info else 0.0
|
|
1397
|
+
output_price = model_info.get("output_price", 0.0) if model_info else 0.0
|
|
1398
|
+
|
|
1399
|
+
# Calculate costs
|
|
1400
|
+
input_cost = (last_meta.input_tokens_count * input_price) / 1000000 # Convert to millions
|
|
1401
|
+
output_cost = (last_meta.generated_tokens_count * output_price) / 1000000 # Convert to millions
|
|
1402
|
+
|
|
1392
1403
|
printer.print_in_terminal("stream_out_stats",
|
|
1404
|
+
model_name=model_name,
|
|
1393
1405
|
elapsed_time=elapsed_time,
|
|
1394
1406
|
first_token_time=last_meta.first_token_time,
|
|
1395
1407
|
input_tokens=last_meta.input_tokens_count,
|
|
1396
1408
|
output_tokens=last_meta.generated_tokens_count,
|
|
1409
|
+
input_cost=round(input_cost, 4),
|
|
1410
|
+
output_cost=round(output_cost, 4),
|
|
1397
1411
|
speed=round(speed, 2))
|
|
1398
1412
|
|
|
1399
1413
|
chat_history["ask_conversation"].append(
|
|
@@ -57,7 +57,7 @@ MESSAGES = {
|
|
|
57
57
|
"Paste the answer to the input box below, use '/break' to exit, '/clear' to clear the screen, '/eof' to submit."
|
|
58
58
|
),
|
|
59
59
|
"code_generation_start": "Auto generate the code...",
|
|
60
|
-
"code_generation_complete": "Code generation completed in {{ duration }} seconds, input_tokens_count: {{ input_tokens }}, generated_tokens_count: {{ output_tokens }}, speed: {{ speed }} tokens/s",
|
|
60
|
+
"code_generation_complete": "{{ model_names}} Code generation completed in {{ duration }} seconds, input_tokens_count: {{ input_tokens }}, generated_tokens_count: {{ output_tokens }}, input_cost: {{ input_cost }}, output_cost: {{ output_cost }}, speed: {{ speed }} tokens/s",
|
|
61
61
|
"code_merge_start": "Auto merge the code...",
|
|
62
62
|
"code_execution_warning": "Content(send to model) is {{ content_length }} tokens (you may collect too much files), which is larger than the maximum input length {{ max_length }}",
|
|
63
63
|
"quick_filter_start": "{{ model_name }} Starting filter context(quick_filter)...",
|
|
@@ -75,12 +75,12 @@ MESSAGES = {
|
|
|
75
75
|
"ranking_start": "Start ranking {{ count }} candidates using model {{ model_name }}",
|
|
76
76
|
"ranking_failed_request": "Ranking request failed: {{ error }}",
|
|
77
77
|
"ranking_all_failed": "All ranking requests failed",
|
|
78
|
-
"ranking_complete": "Ranking completed in {{ elapsed }}s, total voters: {{ total_tasks }}, best candidate index: {{ best_candidate }}, scores: {{ scores }}, input_tokens: {{ input_tokens }}, output_tokens: {{ output_tokens }}",
|
|
78
|
+
"ranking_complete": "{{ model_names }} Ranking completed in {{ elapsed }}s, total voters: {{ total_tasks }}, best candidate index: {{ best_candidate }}, scores: {{ scores }}, input_tokens: {{ input_tokens }}, output_tokens: {{ output_tokens }}, input_cost: {{ input_cost }}, output_cost: {{ output_cost }}",
|
|
79
79
|
"ranking_process_failed": "Ranking process failed: {{ error }}",
|
|
80
80
|
"ranking_failed": "Ranking failed in {{ elapsed }}s, using original order",
|
|
81
81
|
"begin_index_source_code": "🚀 Begin to index source code in {{ source_dir }}",
|
|
82
|
-
"stream_out_stats": "
|
|
83
|
-
"quick_filter_stats": "快速过滤器完成,耗时 {{ elapsed_time }} 秒,输入token数: {{ input_tokens }}, 输出token数: {{ output_tokens }}",
|
|
82
|
+
"stream_out_stats": "Model: {{ model_name }}, Total time: {{ elapsed_time }} seconds, First token time: {{ first_token_time }} seconds, Speed: {{ speed }} tokens/s, Input tokens: {{ input_tokens }}, Output tokens: {{ output_tokens }}, Input cost: {{ input_cost }}, Output cost: {{ output_cost }}",
|
|
83
|
+
"quick_filter_stats": "{{ model_names }} 快速过滤器完成,耗时 {{ elapsed_time }} 秒,输入token数: {{ input_tokens }}, 输出token数: {{ output_tokens }}, 输入成本: {{ input_cost }}, 输出成本: {{ output_cost }}",
|
|
84
84
|
"upsert_file": "✅ Updated file: {{ file_path }}",
|
|
85
85
|
"unmerged_blocks_title": "Unmerged Blocks",
|
|
86
86
|
"quick_filter_title": "{{ model_name }} is analyzing how to filter context...",
|
|
@@ -150,7 +150,7 @@ MESSAGES = {
|
|
|
150
150
|
"将获得答案黏贴到下面的输入框,换行后,使用 '/break' 退出,'/clear' 清屏,'/eof' 提交。"
|
|
151
151
|
),
|
|
152
152
|
"code_generation_start": "正在自动生成代码...",
|
|
153
|
-
"code_generation_complete": "代码生成完成,耗时 {{ duration }} 秒,输入token数: {{ input_tokens }}, 输出token数: {{ output_tokens }}, 速度: {{ speed }} tokens/秒",
|
|
153
|
+
"code_generation_complete": "{{ model_names}} 代码生成完成,耗时 {{ duration }} 秒,输入token数: {{ input_tokens }}, 输出token数: {{ output_tokens }}, 输入成本: {{ input_cost }}, 输出成本: {{ output_cost }}, 速度: {{ speed }} tokens/秒",
|
|
154
154
|
"code_merge_start": "正在自动合并代码...",
|
|
155
155
|
"code_execution_warning": "发送给模型的内容长度为 {{ content_length }} tokens(您可能收集了太多文件),超过了最大输入长度 {{ max_length }}",
|
|
156
156
|
"quick_filter_start": "{{ model_name }} 开始查找上下文(quick_filter)...",
|
|
@@ -179,11 +179,11 @@ MESSAGES = {
|
|
|
179
179
|
"ranking_start": "开始对 {{ count }} 个候选项进行排序,使用模型 {{ model_name }} 打分",
|
|
180
180
|
"ranking_failed_request": "排序请求失败: {{ error }}",
|
|
181
181
|
"ranking_all_failed": "所有排序请求都失败",
|
|
182
|
-
"ranking_complete": "排序完成,耗时 {{ elapsed }} 秒,总投票数: {{ total_tasks }},最佳候选索引: {{ best_candidate }},得分: {{ scores }},输入token数: {{ input_tokens }},输出token数: {{ output_tokens }}",
|
|
182
|
+
"ranking_complete": "{{ model_names }} 排序完成,耗时 {{ elapsed }} 秒,总投票数: {{ total_tasks }},最佳候选索引: {{ best_candidate }},得分: {{ scores }},输入token数: {{ input_tokens }},输出token数: {{ output_tokens }} 输入成本: {{ input_cost }}, 输出成本: {{ output_cost }}",
|
|
183
183
|
"ranking_process_failed": "排序过程失败: {{ error }}",
|
|
184
184
|
"ranking_failed": "排序失败,耗时 {{ elapsed }} 秒,使用原始顺序",
|
|
185
|
-
"stream_out_stats": "
|
|
186
|
-
"quick_filter_stats": "Quick filter completed in {{ elapsed_time }} seconds, input tokens: {{ input_tokens }}, output tokens: {{ output_tokens }}",
|
|
185
|
+
"stream_out_stats": "模型: {{ model_name }},总耗时 {{ elapsed_time }} 秒,首token时间: {{ first_token_time }} 秒, 速度: {{ speed }} tokens/秒, 输入token数: {{ input_tokens }}, 输出token数: {{ output_tokens }}, 输入成本: {{ input_cost }}, 输出成本: {{ output_cost }}",
|
|
186
|
+
"quick_filter_stats": "{{ model_names }} Quick filter completed in {{ elapsed_time }} seconds, input tokens: {{ input_tokens }}, output tokens: {{ output_tokens }}, input cost: {{ input_cost }}, output cost: {{ output_cost }}",
|
|
187
187
|
"quick_filter_title": "{{ model_name }} 正在分析如何筛选上下文...",
|
|
188
188
|
"quick_filter_failed": "❌ 快速过滤器失败: {{ error }}. ",
|
|
189
189
|
"estimated_chat_input_tokens": "对话输入token预估为: {{ estimated_input_tokens }}",
|
|
@@ -10,6 +10,7 @@ from autocoder.common.utils_code_auto_generate import chat_with_continue
|
|
|
10
10
|
import json
|
|
11
11
|
from autocoder.common.printer import Printer
|
|
12
12
|
from autocoder.rag.token_counter import count_tokens
|
|
13
|
+
from autocoder.utils import llms as llm_utils
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
class CodeAutoGenerate:
|
|
@@ -193,6 +194,9 @@ class CodeAutoGenerate:
|
|
|
193
194
|
results = []
|
|
194
195
|
input_tokens_count = 0
|
|
195
196
|
generated_tokens_count = 0
|
|
197
|
+
input_tokens_cost = 0
|
|
198
|
+
generated_tokens_cost = 0
|
|
199
|
+
model_names = []
|
|
196
200
|
|
|
197
201
|
printer = Printer()
|
|
198
202
|
estimated_input_tokens = count_tokens(json.dumps(conversations, ensure_ascii=False))
|
|
@@ -206,13 +210,27 @@ class CodeAutoGenerate:
|
|
|
206
210
|
futures = []
|
|
207
211
|
for llm in self.llms:
|
|
208
212
|
for _ in range(self.generate_times_same_model):
|
|
209
|
-
|
|
210
|
-
|
|
213
|
+
|
|
214
|
+
model_names_list = llm_utils.get_llm_names(llm)
|
|
215
|
+
model_name = None
|
|
216
|
+
if model_names_list:
|
|
217
|
+
model_name = model_names_list[0]
|
|
218
|
+
|
|
219
|
+
for _ in range(self.generate_times_same_model):
|
|
220
|
+
model_names.append(model_name)
|
|
221
|
+
futures.append(executor.submit(
|
|
222
|
+
chat_with_continue, llm=llm, conversations=conversations, llm_config=llm_config))
|
|
223
|
+
|
|
211
224
|
temp_results = [future.result() for future in futures]
|
|
212
225
|
for result in temp_results:
|
|
213
226
|
results.append(result.content)
|
|
214
227
|
input_tokens_count += result.input_tokens_count
|
|
215
228
|
generated_tokens_count += result.generated_tokens_count
|
|
229
|
+
model_info = llm_utils.get_model_info(model_name, self.args.product_mode)
|
|
230
|
+
input_cost = model_info.get("input_price", 0) if model_info else 0
|
|
231
|
+
output_cost = model_info.get("output_price", 0) if model_info else 0
|
|
232
|
+
input_tokens_cost += input_cost * result.input_tokens_count / 1000000
|
|
233
|
+
generated_tokens_cost += output_cost * result.generated_tokens_count / 1000000
|
|
216
234
|
|
|
217
235
|
for result in results:
|
|
218
236
|
conversations_list.append(
|
|
@@ -227,7 +245,9 @@ class CodeAutoGenerate:
|
|
|
227
245
|
|
|
228
246
|
statistics = {
|
|
229
247
|
"input_tokens_count": input_tokens_count,
|
|
230
|
-
"generated_tokens_count": generated_tokens_count
|
|
248
|
+
"generated_tokens_count": generated_tokens_count,
|
|
249
|
+
"input_tokens_cost": input_tokens_cost,
|
|
250
|
+
"generated_tokens_cost": generated_tokens_cost
|
|
231
251
|
}
|
|
232
252
|
|
|
233
253
|
if self.args.request_id and not self.args.skip_events:
|
|
@@ -9,6 +9,7 @@ import json
|
|
|
9
9
|
from autocoder.common.utils_code_auto_generate import chat_with_continue
|
|
10
10
|
from autocoder.common.printer import Printer
|
|
11
11
|
from autocoder.rag.token_counter import count_tokens
|
|
12
|
+
from autocoder.utils import llms as llm_utils
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
class CodeAutoGenerateDiff:
|
|
@@ -341,6 +342,9 @@ class CodeAutoGenerateDiff:
|
|
|
341
342
|
results = []
|
|
342
343
|
input_tokens_count = 0
|
|
343
344
|
generated_tokens_count = 0
|
|
345
|
+
input_tokens_cost = 0
|
|
346
|
+
generated_tokens_cost = 0
|
|
347
|
+
model_names = []
|
|
344
348
|
|
|
345
349
|
printer = Printer()
|
|
346
350
|
estimated_input_tokens = count_tokens(json.dumps(conversations, ensure_ascii=False))
|
|
@@ -354,13 +358,26 @@ class CodeAutoGenerateDiff:
|
|
|
354
358
|
futures = []
|
|
355
359
|
for llm in self.llms:
|
|
356
360
|
for _ in range(self.generate_times_same_model):
|
|
357
|
-
|
|
358
|
-
|
|
361
|
+
model_names_list = llm_utils.get_llm_names(llm)
|
|
362
|
+
model_name = None
|
|
363
|
+
if model_names_list:
|
|
364
|
+
model_name = model_names_list[0]
|
|
365
|
+
|
|
366
|
+
for _ in range(self.generate_times_same_model):
|
|
367
|
+
model_names.append(model_name)
|
|
368
|
+
futures.append(executor.submit(
|
|
369
|
+
chat_with_continue, llm=llm, conversations=conversations, llm_config=llm_config))
|
|
370
|
+
|
|
359
371
|
temp_results = [future.result() for future in futures]
|
|
360
372
|
for result in temp_results:
|
|
361
373
|
results.append(result.content)
|
|
362
374
|
input_tokens_count += result.input_tokens_count
|
|
363
375
|
generated_tokens_count += result.generated_tokens_count
|
|
376
|
+
model_info = llm_utils.get_model_info(model_name, self.args.product_mode)
|
|
377
|
+
input_cost = model_info.get("input_price",0) if model_info else 0
|
|
378
|
+
output_cost = model_info.get("output_price",0) if model_info else 0
|
|
379
|
+
input_tokens_cost += input_cost * result.input_tokens_count / 1000000
|
|
380
|
+
generated_tokens_cost += output_cost * result.generated_tokens_count / 1000000
|
|
364
381
|
|
|
365
382
|
for result in results:
|
|
366
383
|
conversations_list.append(
|
|
@@ -376,7 +393,9 @@ class CodeAutoGenerateDiff:
|
|
|
376
393
|
|
|
377
394
|
statistics = {
|
|
378
395
|
"input_tokens_count": input_tokens_count,
|
|
379
|
-
"generated_tokens_count": generated_tokens_count
|
|
396
|
+
"generated_tokens_count": generated_tokens_count,
|
|
397
|
+
"input_tokens_cost": input_tokens_cost,
|
|
398
|
+
"generated_tokens_cost": generated_tokens_cost
|
|
380
399
|
}
|
|
381
400
|
|
|
382
401
|
if self.args.request_id and not self.args.skip_events:
|
|
@@ -13,6 +13,7 @@ from concurrent.futures import ThreadPoolExecutor
|
|
|
13
13
|
from autocoder.common.utils_code_auto_generate import chat_with_continue
|
|
14
14
|
from autocoder.common.printer import Printer
|
|
15
15
|
from autocoder.rag.token_counter import count_tokens
|
|
16
|
+
from autocoder.utils import llms as llm_utils
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
class CodeAutoGenerateEditBlock:
|
|
@@ -424,6 +425,11 @@ class CodeAutoGenerateEditBlock:
|
|
|
424
425
|
input_tokens_count = 0
|
|
425
426
|
generated_tokens_count = 0
|
|
426
427
|
|
|
428
|
+
input_tokens_cost = 0
|
|
429
|
+
generated_tokens_cost = 0
|
|
430
|
+
|
|
431
|
+
model_names = []
|
|
432
|
+
|
|
427
433
|
printer = Printer()
|
|
428
434
|
estimated_input_tokens = count_tokens(
|
|
429
435
|
json.dumps(conversations, ensure_ascii=False))
|
|
@@ -437,14 +443,28 @@ class CodeAutoGenerateEditBlock:
|
|
|
437
443
|
with ThreadPoolExecutor(max_workers=len(self.llms) * self.generate_times_same_model) as executor:
|
|
438
444
|
futures = []
|
|
439
445
|
for llm in self.llms:
|
|
446
|
+
|
|
447
|
+
model_names_list = llm_utils.get_llm_names(llm)
|
|
448
|
+
model_name = None
|
|
449
|
+
if model_names_list:
|
|
450
|
+
model_name = model_names_list[0]
|
|
451
|
+
|
|
440
452
|
for _ in range(self.generate_times_same_model):
|
|
453
|
+
model_names.append(model_name)
|
|
441
454
|
futures.append(executor.submit(
|
|
442
455
|
chat_with_continue, llm=llm, conversations=conversations, llm_config=llm_config))
|
|
456
|
+
|
|
443
457
|
temp_results = [future.result() for future in futures]
|
|
444
|
-
|
|
458
|
+
|
|
459
|
+
for result,model_name in zip(temp_results,model_names):
|
|
445
460
|
results.append(result.content)
|
|
446
461
|
input_tokens_count += result.input_tokens_count
|
|
447
462
|
generated_tokens_count += result.generated_tokens_count
|
|
463
|
+
model_info = llm_utils.get_model_info(model_name,self.args.product_mode)
|
|
464
|
+
input_cost = model_info.get("input_price", 0) if model_info else 0
|
|
465
|
+
output_cost = model_info.get("output_price", 0) if model_info else 0
|
|
466
|
+
input_tokens_cost += input_cost * result.input_tokens_count / 1000000
|
|
467
|
+
generated_tokens_cost += output_cost * result.generated_tokens_count / 1000000
|
|
448
468
|
|
|
449
469
|
for result in results:
|
|
450
470
|
conversations_list.append(
|
|
@@ -461,7 +481,9 @@ class CodeAutoGenerateEditBlock:
|
|
|
461
481
|
|
|
462
482
|
statistics = {
|
|
463
483
|
"input_tokens_count": input_tokens_count,
|
|
464
|
-
"generated_tokens_count": generated_tokens_count
|
|
484
|
+
"generated_tokens_count": generated_tokens_count,
|
|
485
|
+
"input_tokens_cost": input_tokens_cost,
|
|
486
|
+
"generated_tokens_cost": generated_tokens_cost
|
|
465
487
|
}
|
|
466
488
|
|
|
467
489
|
if self.args.request_id and not self.args.skip_events:
|
|
@@ -9,6 +9,7 @@ import json
|
|
|
9
9
|
from autocoder.common.utils_code_auto_generate import chat_with_continue
|
|
10
10
|
from autocoder.common.printer import Printer
|
|
11
11
|
from autocoder.rag.token_counter import count_tokens
|
|
12
|
+
from autocoder.utils import llms as llm_utils
|
|
12
13
|
|
|
13
14
|
class CodeAutoGenerateStrictDiff:
|
|
14
15
|
def __init__(
|
|
@@ -311,6 +312,9 @@ class CodeAutoGenerateStrictDiff:
|
|
|
311
312
|
results = []
|
|
312
313
|
input_tokens_count = 0
|
|
313
314
|
generated_tokens_count = 0
|
|
315
|
+
input_tokens_cost = 0
|
|
316
|
+
generated_tokens_cost = 0
|
|
317
|
+
model_names = []
|
|
314
318
|
|
|
315
319
|
printer = Printer()
|
|
316
320
|
estimated_input_tokens = count_tokens(json.dumps(conversations, ensure_ascii=False))
|
|
@@ -324,14 +328,27 @@ class CodeAutoGenerateStrictDiff:
|
|
|
324
328
|
futures = []
|
|
325
329
|
for llm in self.llms:
|
|
326
330
|
for _ in range(self.generate_times_same_model):
|
|
327
|
-
|
|
328
|
-
|
|
331
|
+
|
|
332
|
+
model_names_list = llm_utils.get_llm_names(llm)
|
|
333
|
+
model_name = None
|
|
334
|
+
if model_names_list:
|
|
335
|
+
model_name = model_names_list[0]
|
|
336
|
+
|
|
337
|
+
for _ in range(self.generate_times_same_model):
|
|
338
|
+
model_names.append(model_name)
|
|
339
|
+
futures.append(executor.submit(
|
|
340
|
+
chat_with_continue, llm=llm, conversations=conversations, llm_config=llm_config))
|
|
341
|
+
|
|
329
342
|
temp_results = [future.result() for future in futures]
|
|
330
343
|
for result in temp_results:
|
|
331
344
|
results.append(result.content)
|
|
332
345
|
input_tokens_count += result.input_tokens_count
|
|
333
346
|
generated_tokens_count += result.generated_tokens_count
|
|
334
|
-
|
|
347
|
+
model_info = llm_utils.get_model_info(model_name, self.args.product_mode)
|
|
348
|
+
input_cost = model_info.get("input_price", 0) if model_info else 0
|
|
349
|
+
output_cost = model_info.get("output_price", 0) if model_info else 0
|
|
350
|
+
input_tokens_cost += input_cost * result.input_tokens_count / 1000000
|
|
351
|
+
generated_tokens_cost += output_cost * result.generated_tokens_count / 1000000
|
|
335
352
|
for result in results:
|
|
336
353
|
conversations_list.append(
|
|
337
354
|
conversations + [{"role": "assistant", "content": result}])
|
|
@@ -345,7 +362,9 @@ class CodeAutoGenerateStrictDiff:
|
|
|
345
362
|
|
|
346
363
|
statistics = {
|
|
347
364
|
"input_tokens_count": input_tokens_count,
|
|
348
|
-
"generated_tokens_count": generated_tokens_count
|
|
365
|
+
"generated_tokens_count": generated_tokens_count,
|
|
366
|
+
"input_tokens_cost": input_tokens_cost,
|
|
367
|
+
"generated_tokens_cost": generated_tokens_cost
|
|
349
368
|
}
|
|
350
369
|
|
|
351
370
|
if self.args.request_id and not self.args.skip_events:
|
|
@@ -8,8 +8,8 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
|
8
8
|
import traceback
|
|
9
9
|
from autocoder.common.utils_code_auto_generate import chat_with_continue
|
|
10
10
|
from byzerllm.utils.str2model import to_model
|
|
11
|
+
from autocoder.utils.llms import get_llm_names, get_model_info
|
|
11
12
|
|
|
12
|
-
from autocoder.utils.llms import get_llm_names
|
|
13
13
|
class RankResult(BaseModel):
|
|
14
14
|
rank_result: List[int]
|
|
15
15
|
|
|
@@ -97,13 +97,42 @@ class CodeModificationRanker:
|
|
|
97
97
|
|
|
98
98
|
# Collect all results
|
|
99
99
|
results = []
|
|
100
|
-
|
|
100
|
+
# 获取模型名称列表
|
|
101
|
+
model_names = []
|
|
102
|
+
for llm in self.llms:
|
|
103
|
+
# 获取当前llm实例对应的模型名称
|
|
104
|
+
names = get_llm_names(llm)
|
|
105
|
+
model_names.extend(names)
|
|
106
|
+
|
|
107
|
+
# 获取模型价格信息
|
|
108
|
+
model_info_map = {}
|
|
109
|
+
for name in model_names:
|
|
110
|
+
# 第二个参数是产品模式,从args中获取
|
|
111
|
+
info = get_model_info(name, self.args.product_mode)
|
|
112
|
+
if info:
|
|
113
|
+
model_info_map[name] = {
|
|
114
|
+
"input_cost": info.get("input_price", 0.0), # 每百万tokens成本
|
|
115
|
+
"output_cost": info.get("output_price", 0.0) # 每百万tokens成本
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
# 计算总成本
|
|
119
|
+
total_input_cost = 0.0
|
|
120
|
+
total_output_cost = 0.0
|
|
121
|
+
|
|
122
|
+
for future, model_name in zip(futures, model_names):
|
|
101
123
|
try:
|
|
102
124
|
result = future.result()
|
|
103
125
|
input_tokens_count += result.input_tokens_count
|
|
104
126
|
generated_tokens_count += result.generated_tokens_count
|
|
105
127
|
v = to_model(result.content,RankResult)
|
|
106
128
|
results.append(v.rank_result)
|
|
129
|
+
|
|
130
|
+
# 计算成本
|
|
131
|
+
info = model_info_map.get(model_name, {})
|
|
132
|
+
# 计算公式:token数 * 单价 / 1000000
|
|
133
|
+
total_input_cost += (result.input_tokens_count * info.get("input_cost", 0.0)) / 1000000
|
|
134
|
+
total_output_cost += (result.generated_tokens_count * info.get("output_cost", 0.0)) / 1000000
|
|
135
|
+
|
|
107
136
|
except Exception as e:
|
|
108
137
|
self.printer.print_in_terminal(
|
|
109
138
|
"ranking_failed_request", style="yellow", error=str(e))
|
|
@@ -113,6 +142,10 @@ class CodeModificationRanker:
|
|
|
113
142
|
raise Exception(
|
|
114
143
|
self.printer.get_message_from_key("ranking_all_failed"))
|
|
115
144
|
|
|
145
|
+
# 四舍五入到4位小数
|
|
146
|
+
total_input_cost = round(total_input_cost, 4)
|
|
147
|
+
total_output_cost = round(total_output_cost, 4)
|
|
148
|
+
|
|
116
149
|
# Calculate scores for each candidate
|
|
117
150
|
candidate_scores = defaultdict(float)
|
|
118
151
|
for rank_result in results:
|
|
@@ -137,7 +170,10 @@ class CodeModificationRanker:
|
|
|
137
170
|
best_candidate=sorted_candidates[0],
|
|
138
171
|
scores=score_details,
|
|
139
172
|
input_tokens=input_tokens_count,
|
|
140
|
-
output_tokens=generated_tokens_count
|
|
173
|
+
output_tokens=generated_tokens_count,
|
|
174
|
+
input_cost=total_input_cost,
|
|
175
|
+
output_cost=total_output_cost,
|
|
176
|
+
model_names=", ".join(model_names)
|
|
141
177
|
)
|
|
142
178
|
|
|
143
179
|
rerank_contents = [generate_result.contents[i]
|
|
@@ -125,13 +125,17 @@ class ActionTSProject(BaseAction):
|
|
|
125
125
|
query=args.query, source_content=content
|
|
126
126
|
)
|
|
127
127
|
elapsed_time = time.time() - start_time
|
|
128
|
-
speed = generate_result.metadata.get('generated_tokens_count', 0) / elapsed_time if elapsed_time > 0 else 0
|
|
129
|
-
|
|
128
|
+
speed = generate_result.metadata.get('generated_tokens_count', 0) / elapsed_time if elapsed_time > 0 else 0
|
|
129
|
+
input_tokens_cost = generate_result.metadata.get('input_tokens_cost', 0)
|
|
130
|
+
generated_tokens_cost = generate_result.metadata.get('generated_tokens_cost', 0)
|
|
131
|
+
model_names = ",".join(get_llm_names(generate.llms))
|
|
130
132
|
self.printer.print_in_terminal(
|
|
131
133
|
"code_generation_complete",
|
|
132
134
|
duration=elapsed_time,
|
|
133
135
|
input_tokens=generate_result.metadata.get('input_tokens_count', 0),
|
|
134
136
|
output_tokens=generate_result.metadata.get('generated_tokens_count', 0),
|
|
137
|
+
input_cost=input_tokens_cost,
|
|
138
|
+
output_cost=generated_tokens_cost,
|
|
135
139
|
speed=round(speed, 2),
|
|
136
140
|
model_names=model_names
|
|
137
141
|
)
|
|
@@ -221,12 +225,16 @@ class ActionPyScriptProject(BaseAction):
|
|
|
221
225
|
|
|
222
226
|
elapsed_time = time.time() - start_time
|
|
223
227
|
speed = generate_result.metadata.get('generated_tokens_count', 0) / elapsed_time if elapsed_time > 0 else 0
|
|
224
|
-
model_names = ",".join(get_llm_names(
|
|
228
|
+
model_names = ",".join(get_llm_names(generate.llms))
|
|
229
|
+
input_tokens_cost = generate_result.metadata.get('input_tokens_cost', 0)
|
|
230
|
+
generated_tokens_cost = generate_result.metadata.get('generated_tokens_cost', 0)
|
|
225
231
|
self.printer.print_in_terminal(
|
|
226
232
|
"code_generation_complete",
|
|
227
233
|
duration=elapsed_time,
|
|
228
234
|
input_tokens=generate_result.metadata.get('input_tokens_count', 0),
|
|
229
235
|
output_tokens=generate_result.metadata.get('generated_tokens_count', 0),
|
|
236
|
+
input_cost=input_tokens_cost,
|
|
237
|
+
output_cost=generated_tokens_cost,
|
|
230
238
|
speed=round(speed, 2),
|
|
231
239
|
model_names=model_names
|
|
232
240
|
)
|
|
@@ -264,13 +272,7 @@ class ActionPyScriptProject(BaseAction):
|
|
|
264
272
|
model=self.llm.default_model_name,
|
|
265
273
|
)
|
|
266
274
|
|
|
267
|
-
end_time = time.time()
|
|
268
|
-
self.printer.print_in_terminal(
|
|
269
|
-
"code_generation_complete",
|
|
270
|
-
duration=end_time - start_time,
|
|
271
|
-
input_tokens=generate_result.metadata.get('input_tokens_count', 0),
|
|
272
|
-
output_tokens=generate_result.metadata.get('generated_tokens_count', 0)
|
|
273
|
-
)
|
|
275
|
+
end_time = time.time()
|
|
274
276
|
with open(self.args.target_file, "w") as file:
|
|
275
277
|
file.write(content)
|
|
276
278
|
|
|
@@ -348,12 +350,16 @@ class ActionPyProject(BaseAction):
|
|
|
348
350
|
)
|
|
349
351
|
elapsed_time = time.time() - start_time
|
|
350
352
|
speed = generate_result.metadata.get('generated_tokens_count', 0) / elapsed_time if elapsed_time > 0 else 0
|
|
351
|
-
model_names = ",".join(get_llm_names(
|
|
353
|
+
model_names = ",".join(get_llm_names(generate.llms))
|
|
354
|
+
input_tokens_cost = generate_result.metadata.get('input_tokens_cost', 0)
|
|
355
|
+
generated_tokens_cost = generate_result.metadata.get('generated_tokens_cost', 0)
|
|
352
356
|
self.printer.print_in_terminal(
|
|
353
357
|
"code_generation_complete",
|
|
354
358
|
duration=elapsed_time,
|
|
355
359
|
input_tokens=generate_result.metadata.get('input_tokens_count', 0),
|
|
356
360
|
output_tokens=generate_result.metadata.get('generated_tokens_count', 0),
|
|
361
|
+
input_cost=input_tokens_cost,
|
|
362
|
+
output_cost=generated_tokens_cost,
|
|
357
363
|
speed=round(speed, 2),
|
|
358
364
|
model_names=model_names
|
|
359
365
|
)
|
|
@@ -458,12 +464,16 @@ class ActionSuffixProject(BaseAction):
|
|
|
458
464
|
|
|
459
465
|
elapsed_time = time.time() - start_time
|
|
460
466
|
speed = generate_result.metadata.get('generated_tokens_count', 0) / elapsed_time if elapsed_time > 0 else 0
|
|
461
|
-
model_names = ",".join(get_llm_names(
|
|
467
|
+
model_names = ",".join(get_llm_names(generate.llms))
|
|
468
|
+
input_tokens_cost = generate_result.metadata.get('input_tokens_cost', 0)
|
|
469
|
+
generated_tokens_cost = generate_result.metadata.get('generated_tokens_cost', 0)
|
|
462
470
|
self.printer.print_in_terminal(
|
|
463
471
|
"code_generation_complete",
|
|
464
472
|
duration=elapsed_time,
|
|
465
473
|
input_tokens=generate_result.metadata.get('input_tokens_count', 0),
|
|
466
474
|
output_tokens=generate_result.metadata.get('generated_tokens_count', 0),
|
|
475
|
+
input_cost=input_tokens_cost,
|
|
476
|
+
output_cost=generated_tokens_cost,
|
|
467
477
|
speed=round(speed, 2),
|
|
468
478
|
model_names=model_names
|
|
469
479
|
)
|
|
@@ -88,11 +88,15 @@ class ActionRegexProject:
|
|
|
88
88
|
elapsed_time = time.time() - start_time
|
|
89
89
|
speed = generate_result.metadata.get('generated_tokens_count', 0) / elapsed_time if elapsed_time > 0 else 0
|
|
90
90
|
model_names = ",".join(get_llm_names(self.llm))
|
|
91
|
+
input_tokens_cost = generate_result.metadata.get('input_tokens_cost', 0)
|
|
92
|
+
generated_tokens_cost = generate_result.metadata.get('generated_tokens_cost', 0)
|
|
91
93
|
self.printer.print_in_terminal(
|
|
92
94
|
"code_generation_complete",
|
|
93
95
|
duration=elapsed_time,
|
|
94
96
|
input_tokens=generate_result.metadata.get('input_tokens_count', 0),
|
|
95
97
|
output_tokens=generate_result.metadata.get('generated_tokens_count', 0),
|
|
98
|
+
input_cost=input_tokens_cost,
|
|
99
|
+
output_cost=generated_tokens_cost,
|
|
96
100
|
speed=round(speed, 2),
|
|
97
101
|
model_names=model_names
|
|
98
102
|
)
|
|
@@ -4,21 +4,21 @@ from autocoder.utils.auto_coder_utils.chat_stream_out import stream_out
|
|
|
4
4
|
from autocoder.common.utils_code_auto_generate import stream_chat_with_continue
|
|
5
5
|
from byzerllm.utils.str2model import to_model
|
|
6
6
|
from autocoder.index.types import IndexItem
|
|
7
|
-
from autocoder.common import AutoCoderArgs,SourceCode
|
|
7
|
+
from autocoder.common import AutoCoderArgs, SourceCode
|
|
8
8
|
import byzerllm
|
|
9
9
|
import time
|
|
10
10
|
from autocoder.index.index import IndexManager
|
|
11
11
|
from autocoder.index.types import (
|
|
12
12
|
IndexItem,
|
|
13
|
-
TargetFile,
|
|
13
|
+
TargetFile,
|
|
14
14
|
FileNumberList
|
|
15
15
|
)
|
|
16
16
|
from autocoder.rag.token_counter import count_tokens
|
|
17
17
|
from autocoder.common.printer import Printer
|
|
18
18
|
from concurrent.futures import ThreadPoolExecutor
|
|
19
|
-
import
|
|
19
|
+
from byzerllm import MetaHolder
|
|
20
20
|
|
|
21
|
-
from autocoder.utils.llms import get_llm_names
|
|
21
|
+
from autocoder.utils.llms import get_llm_names, get_model_info
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
def get_file_path(file_path):
|
|
@@ -32,8 +32,9 @@ class QuickFilterResult(BaseModel):
|
|
|
32
32
|
has_error: bool
|
|
33
33
|
error_message: Optional[str] = None
|
|
34
34
|
|
|
35
|
+
|
|
35
36
|
class QuickFilter():
|
|
36
|
-
def __init__(self, index_manager: IndexManager,stats:Dict[str,Any],sources:List[SourceCode]):
|
|
37
|
+
def __init__(self, index_manager: IndexManager, stats: Dict[str, Any], sources: List[SourceCode]):
|
|
37
38
|
self.index_manager = index_manager
|
|
38
39
|
self.args = index_manager.args
|
|
39
40
|
self.stats = stats
|
|
@@ -41,72 +42,142 @@ class QuickFilter():
|
|
|
41
42
|
self.printer = Printer()
|
|
42
43
|
self.max_tokens = self.args.index_filter_model_max_input_length
|
|
43
44
|
|
|
44
|
-
|
|
45
45
|
def big_filter(self, index_items: List[IndexItem],) -> QuickFilterResult:
|
|
46
46
|
chunks = []
|
|
47
47
|
current_chunk = []
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
# 将 index_items 切分成多个 chunks,第一个chunk尽可能接近max_tokens
|
|
50
50
|
for item in index_items:
|
|
51
51
|
# 使用 quick_filter_files.prompt 生成文本再统计
|
|
52
52
|
temp_chunk = current_chunk + [item]
|
|
53
|
-
prompt_text = self.quick_filter_files.prompt(
|
|
54
|
-
|
|
53
|
+
prompt_text = self.quick_filter_files.prompt(
|
|
54
|
+
temp_chunk, self.args.query)
|
|
55
|
+
temp_size = count_tokens(prompt_text)
|
|
55
56
|
# 如果当前chunk为空,或者添加item后不超过max_tokens,就添加到当前chunk
|
|
56
57
|
if not current_chunk or temp_size <= self.max_tokens:
|
|
57
|
-
current_chunk.append(item)
|
|
58
|
+
current_chunk.append(item)
|
|
58
59
|
else:
|
|
59
60
|
# 当前chunk已满,创建新chunk
|
|
60
61
|
chunks.append(current_chunk)
|
|
61
|
-
current_chunk = [item]
|
|
62
|
-
|
|
62
|
+
current_chunk = [item]
|
|
63
|
+
|
|
63
64
|
if current_chunk:
|
|
64
65
|
chunks.append(current_chunk)
|
|
65
|
-
|
|
66
|
-
tokens_len = count_tokens(
|
|
66
|
+
|
|
67
|
+
tokens_len = count_tokens(
|
|
68
|
+
self.quick_filter_files.prompt(index_items, self.args.query))
|
|
67
69
|
self.printer.print_in_terminal(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
"quick_filter_too_long",
|
|
71
|
+
style="yellow",
|
|
72
|
+
tokens_len=tokens_len,
|
|
73
|
+
max_tokens=self.max_tokens,
|
|
74
|
+
split_size=len(chunks)
|
|
75
|
+
)
|
|
74
76
|
|
|
75
77
|
def process_chunk(chunk_index: int, chunk: List[IndexItem]) -> QuickFilterResult:
|
|
76
78
|
try:
|
|
77
|
-
|
|
79
|
+
# 获取模型名称列表
|
|
80
|
+
model_names = get_llm_names(
|
|
81
|
+
self.index_manager.index_filter_llm)
|
|
82
|
+
model_name = ",".join(model_names)
|
|
78
83
|
files: Dict[str, TargetFile] = {}
|
|
79
|
-
|
|
84
|
+
|
|
85
|
+
# 获取模型价格信息
|
|
86
|
+
model_info_map = {}
|
|
87
|
+
for name in model_names:
|
|
88
|
+
# 第二个参数是产品模式,从args中获取
|
|
89
|
+
info = get_model_info(name, self.args.product_mode)
|
|
90
|
+
if info:
|
|
91
|
+
model_info_map[name] = {
|
|
92
|
+
# 每百万tokens成本
|
|
93
|
+
"input_price": info.get("input_price", 0.0),
|
|
94
|
+
# 每百万tokens成本
|
|
95
|
+
"output_price": info.get("output_price", 0.0)
|
|
96
|
+
}
|
|
97
|
+
|
|
80
98
|
if chunk_index == 0:
|
|
81
99
|
# 第一个chunk使用流式输出
|
|
82
100
|
stream_generator = stream_chat_with_continue(
|
|
83
101
|
self.index_manager.index_filter_llm,
|
|
84
|
-
[{"role": "user", "content": self.quick_filter_files.prompt(
|
|
102
|
+
[{"role": "user", "content": self.quick_filter_files.prompt(
|
|
103
|
+
chunk, self.args.query)}],
|
|
85
104
|
{}
|
|
86
105
|
)
|
|
87
|
-
full_response,
|
|
106
|
+
full_response, last_meta = stream_out(
|
|
88
107
|
stream_generator,
|
|
89
108
|
model_name=model_name,
|
|
90
|
-
title=self.printer.get_message_from_key_with_format(
|
|
109
|
+
title=self.printer.get_message_from_key_with_format(
|
|
110
|
+
"quick_filter_title", model_name=model_name),
|
|
91
111
|
args=self.args
|
|
92
112
|
)
|
|
93
113
|
file_number_list = to_model(full_response, FileNumberList)
|
|
114
|
+
|
|
115
|
+
# 计算总成本
|
|
116
|
+
total_input_cost = 0.0
|
|
117
|
+
total_output_cost = 0.0
|
|
118
|
+
|
|
119
|
+
for name in model_names:
|
|
120
|
+
info = model_info_map.get(name, {})
|
|
121
|
+
# 计算公式:token数 * 单价 / 1000000
|
|
122
|
+
total_input_cost += (last_meta.input_tokens_count *
|
|
123
|
+
info.get("input_price", 0.0)) / 1000000
|
|
124
|
+
total_output_cost += (last_meta.generated_tokens_count *
|
|
125
|
+
info.get("output_price", 0.0)) / 1000000
|
|
126
|
+
|
|
127
|
+
# 四舍五入到4位小数
|
|
128
|
+
total_input_cost = round(total_input_cost, 4)
|
|
129
|
+
total_output_cost = round(total_output_cost, 4)
|
|
130
|
+
|
|
131
|
+
# 打印 token 统计信息和成本
|
|
132
|
+
self.printer.print_in_terminal(
|
|
133
|
+
"quick_filter_stats",
|
|
134
|
+
style="blue",
|
|
135
|
+
input_tokens=last_meta.input_tokens_count,
|
|
136
|
+
output_tokens=last_meta.generated_tokens_count,
|
|
137
|
+
input_cost=total_input_cost,
|
|
138
|
+
output_cost=total_output_cost,
|
|
139
|
+
model_names=model_name
|
|
140
|
+
)
|
|
94
141
|
else:
|
|
95
142
|
# 其他chunks直接使用with_llm
|
|
96
|
-
|
|
97
|
-
|
|
143
|
+
meta_holder = MetaHolder()
|
|
144
|
+
start_time = time.monotonic()
|
|
145
|
+
file_number_list = self.quick_filter_files.with_llm(self.index_manager.index_filter_llm).with_meta(
|
|
146
|
+
meta_holder).with_return_type(FileNumberList).run(chunk, self.args.query)
|
|
147
|
+
end_time = time.monotonic()
|
|
148
|
+
|
|
149
|
+
total_input_cost = 0.0
|
|
150
|
+
total_output_cost = 0.0
|
|
151
|
+
if meta_holder.get_meta():
|
|
152
|
+
meta_dict = meta_holder.get_meta()
|
|
153
|
+
total_input_cost = meta_dict.get("input_tokens_count", 0) * model_info_map.get(model_name, {}).get("input_price", 0.0) / 1000000
|
|
154
|
+
total_output_cost = meta_dict.get("generated_tokens_count", 0) * model_info_map.get(model_name, {}).get("output_price", 0.0) / 1000000
|
|
155
|
+
|
|
156
|
+
self.printer.print_in_terminal(
|
|
157
|
+
"quick_filter_stats",
|
|
158
|
+
style="blue",
|
|
159
|
+
input_tokens=meta_dict.get("input_tokens_count", 0),
|
|
160
|
+
output_tokens=meta_dict.get("generated_tokens_count", 0),
|
|
161
|
+
input_cost=total_input_cost,
|
|
162
|
+
output_cost=total_output_cost,
|
|
163
|
+
model_names=model_name,
|
|
164
|
+
elapsed_time=f"{end_time - start_time:.2f}"
|
|
165
|
+
)
|
|
166
|
+
|
|
98
167
|
if file_number_list:
|
|
99
168
|
for file_number in file_number_list.file_list:
|
|
100
|
-
file_path = get_file_path(
|
|
169
|
+
file_path = get_file_path(
|
|
170
|
+
chunk[file_number].module_name)
|
|
101
171
|
files[file_path] = TargetFile(
|
|
102
172
|
file_path=chunk[file_number].module_name,
|
|
103
|
-
reason=self.printer.get_message_from_key(
|
|
173
|
+
reason=self.printer.get_message_from_key(
|
|
174
|
+
"quick_filter_reason")
|
|
104
175
|
)
|
|
105
176
|
return QuickFilterResult(
|
|
106
177
|
files=files,
|
|
107
178
|
has_error=False
|
|
108
179
|
)
|
|
109
|
-
|
|
180
|
+
|
|
110
181
|
except Exception as e:
|
|
111
182
|
self.printer.print_in_terminal(
|
|
112
183
|
"quick_filter_failed",
|
|
@@ -123,25 +194,25 @@ class QuickFilter():
|
|
|
123
194
|
if chunks:
|
|
124
195
|
with ThreadPoolExecutor() as executor:
|
|
125
196
|
# 提交所有chunks到线程池并收集结果
|
|
126
|
-
futures = [executor.submit(process_chunk, i, chunk)
|
|
127
|
-
|
|
128
|
-
|
|
197
|
+
futures = [executor.submit(process_chunk, i, chunk)
|
|
198
|
+
for i, chunk in enumerate(chunks)]
|
|
199
|
+
|
|
129
200
|
# 等待所有任务完成并收集结果
|
|
130
201
|
for future in futures:
|
|
131
202
|
results.append(future.result())
|
|
132
|
-
|
|
203
|
+
|
|
133
204
|
# 合并所有结果
|
|
134
205
|
final_files: Dict[str, TargetFile] = {}
|
|
135
206
|
has_error = False
|
|
136
207
|
error_messages: List[str] = []
|
|
137
|
-
|
|
208
|
+
|
|
138
209
|
for result in results:
|
|
139
210
|
if result.has_error:
|
|
140
211
|
has_error = True
|
|
141
212
|
if result.error_message:
|
|
142
213
|
error_messages.append(result.error_message)
|
|
143
214
|
final_files.update(result.files)
|
|
144
|
-
|
|
215
|
+
|
|
145
216
|
return QuickFilterResult(
|
|
146
217
|
files=final_files,
|
|
147
218
|
has_error=has_error,
|
|
@@ -149,7 +220,7 @@ class QuickFilter():
|
|
|
149
220
|
)
|
|
150
221
|
|
|
151
222
|
@byzerllm.prompt()
|
|
152
|
-
def quick_filter_files(self,file_meta_list:List[IndexItem],query:str) -> str:
|
|
223
|
+
def quick_filter_files(self, file_meta_list: List[IndexItem], query: str) -> str:
|
|
153
224
|
'''
|
|
154
225
|
当用户提一个需求的时候,我们需要找到相关的文件,然后阅读这些文件,并且修改其中部分文件。
|
|
155
226
|
现在,给定下面的索引文件:
|
|
@@ -160,7 +231,7 @@ class QuickFilter():
|
|
|
160
231
|
|
|
161
232
|
索引文件包含文件序号(##[]括起来的部分),文件路径,文件符号信息等。
|
|
162
233
|
下面是用户的查询需求:
|
|
163
|
-
|
|
234
|
+
|
|
164
235
|
<query>
|
|
165
236
|
{{ query }}
|
|
166
237
|
</query>
|
|
@@ -182,63 +253,101 @@ class QuickFilter():
|
|
|
182
253
|
2. 如果 query 里是一段历史对话,那么对话里的内容提及的文件路径必须要返回。
|
|
183
254
|
3. json格式数据不允许有注释
|
|
184
255
|
'''
|
|
185
|
-
file_meta_str = "\n".join(
|
|
256
|
+
file_meta_str = "\n".join(
|
|
257
|
+
[f"##[{index}]{item.module_name}\n{item.symbols}" for index, item in enumerate(file_meta_list)])
|
|
186
258
|
context = {
|
|
187
259
|
"content": file_meta_str,
|
|
188
260
|
"query": query
|
|
189
261
|
}
|
|
190
|
-
return context
|
|
262
|
+
return context
|
|
191
263
|
|
|
192
264
|
def filter(self, index_items: List[IndexItem], query: str) -> QuickFilterResult:
|
|
193
265
|
final_files: Dict[str, TargetFile] = {}
|
|
194
|
-
start_time = time.monotonic()
|
|
266
|
+
start_time = time.monotonic()
|
|
267
|
+
|
|
268
|
+
prompt_str = self.quick_filter_files.prompt(index_items, query)
|
|
269
|
+
|
|
270
|
+
tokens_len = count_tokens(prompt_str)
|
|
195
271
|
|
|
196
|
-
prompt_str = self.quick_filter_files.prompt(index_items,query)
|
|
197
|
-
|
|
198
|
-
tokens_len = count_tokens(prompt_str)
|
|
199
|
-
|
|
200
272
|
# Print current index size
|
|
201
273
|
self.printer.print_in_terminal(
|
|
202
274
|
"quick_filter_tokens_len",
|
|
203
275
|
style="blue",
|
|
204
276
|
tokens_len=tokens_len
|
|
205
277
|
)
|
|
206
|
-
|
|
207
|
-
if tokens_len > self.max_tokens:
|
|
278
|
+
|
|
279
|
+
if tokens_len > self.max_tokens:
|
|
208
280
|
return self.big_filter(index_items)
|
|
209
|
-
|
|
281
|
+
|
|
210
282
|
try:
|
|
211
|
-
|
|
212
|
-
|
|
283
|
+
# 获取模型名称
|
|
284
|
+
model_names = get_llm_names(self.index_manager.index_filter_llm)
|
|
285
|
+
model_name = ",".join(model_names)
|
|
286
|
+
|
|
287
|
+
# 获取模型价格信息
|
|
288
|
+
model_info_map = {}
|
|
289
|
+
for name in model_names:
|
|
290
|
+
# 第二个参数是产品模式,从args中获取
|
|
291
|
+
info = get_model_info(name, self.args.product_mode)
|
|
292
|
+
if info:
|
|
293
|
+
model_info_map[name] = {
|
|
294
|
+
# 每百万tokens成本
|
|
295
|
+
"input_price": info.get("input_price", 0.0),
|
|
296
|
+
# 每百万tokens成本
|
|
297
|
+
"output_price": info.get("output_price", 0.0)
|
|
298
|
+
}
|
|
299
|
+
|
|
213
300
|
# 渲染 Prompt 模板
|
|
214
|
-
query = self.quick_filter_files.prompt(
|
|
215
|
-
|
|
301
|
+
query = self.quick_filter_files.prompt(
|
|
302
|
+
index_items, self.args.query)
|
|
303
|
+
|
|
216
304
|
# 使用流式输出处理
|
|
217
305
|
stream_generator = stream_chat_with_continue(
|
|
218
306
|
self.index_manager.index_filter_llm,
|
|
219
307
|
[{"role": "user", "content": query}],
|
|
220
308
|
{}
|
|
221
309
|
)
|
|
222
|
-
|
|
310
|
+
|
|
223
311
|
# 获取完整响应
|
|
224
312
|
full_response, last_meta = stream_out(
|
|
225
313
|
stream_generator,
|
|
226
314
|
model_name=model_name,
|
|
227
|
-
title=self.printer.get_message_from_key_with_format(
|
|
315
|
+
title=self.printer.get_message_from_key_with_format(
|
|
316
|
+
"quick_filter_title", model_name=model_name),
|
|
228
317
|
args=self.args
|
|
229
|
-
)
|
|
318
|
+
)
|
|
230
319
|
# 解析结果
|
|
231
320
|
file_number_list = to_model(full_response, FileNumberList)
|
|
232
|
-
end_time = time.monotonic()
|
|
233
|
-
|
|
321
|
+
end_time = time.monotonic()
|
|
322
|
+
|
|
323
|
+
# 计算总成本
|
|
324
|
+
total_input_cost = 0.0
|
|
325
|
+
total_output_cost = 0.0
|
|
326
|
+
|
|
327
|
+
for name in model_names:
|
|
328
|
+
info = model_info_map.get(name, {})
|
|
329
|
+
# 计算公式:token数 * 单价 / 1000000
|
|
330
|
+
total_input_cost += (last_meta.input_tokens_count *
|
|
331
|
+
info.get("input_price", 0.0)) / 1000000
|
|
332
|
+
total_output_cost += (last_meta.generated_tokens_count *
|
|
333
|
+
info.get("output_price", 0.0)) / 1000000
|
|
334
|
+
|
|
335
|
+
# 四舍五入到4位小数
|
|
336
|
+
total_input_cost = round(total_input_cost, 4)
|
|
337
|
+
total_output_cost = round(total_output_cost, 4)
|
|
338
|
+
|
|
339
|
+
# 打印 token 统计信息和成本
|
|
234
340
|
self.printer.print_in_terminal(
|
|
235
|
-
"quick_filter_stats",
|
|
341
|
+
"quick_filter_stats",
|
|
236
342
|
style="blue",
|
|
237
343
|
elapsed_time=f"{end_time - start_time:.2f}",
|
|
238
344
|
input_tokens=last_meta.input_tokens_count,
|
|
239
|
-
output_tokens=last_meta.generated_tokens_count
|
|
345
|
+
output_tokens=last_meta.generated_tokens_count,
|
|
346
|
+
input_cost=total_input_cost,
|
|
347
|
+
output_cost=total_output_cost,
|
|
348
|
+
model_names=model_name
|
|
240
349
|
)
|
|
241
|
-
|
|
350
|
+
|
|
242
351
|
except Exception as e:
|
|
243
352
|
self.printer.print_in_terminal(
|
|
244
353
|
"quick_filter_failed",
|
|
@@ -250,16 +359,17 @@ class QuickFilter():
|
|
|
250
359
|
has_error=True,
|
|
251
360
|
error_message=str(e)
|
|
252
361
|
)
|
|
253
|
-
|
|
362
|
+
|
|
254
363
|
if file_number_list:
|
|
255
364
|
for file_number in file_number_list.file_list:
|
|
256
365
|
final_files[get_file_path(index_items[file_number].module_name)] = TargetFile(
|
|
257
366
|
file_path=index_items[file_number].module_name,
|
|
258
|
-
reason=self.printer.get_message_from_key(
|
|
367
|
+
reason=self.printer.get_message_from_key(
|
|
368
|
+
"quick_filter_reason")
|
|
259
369
|
)
|
|
260
|
-
end_time = time.monotonic()
|
|
261
|
-
self.stats["timings"]["quick_filter"] = end_time - start_time
|
|
370
|
+
end_time = time.monotonic()
|
|
371
|
+
self.stats["timings"]["quick_filter"] = end_time - start_time
|
|
262
372
|
return QuickFilterResult(
|
|
263
373
|
files=final_files,
|
|
264
374
|
has_error=False
|
|
265
|
-
)
|
|
375
|
+
)
|
autocoder/models.py
CHANGED
|
@@ -127,11 +127,23 @@ def update_model_input_price(name: str, price: float) -> bool:
|
|
|
127
127
|
"""更新模型输入价格
|
|
128
128
|
|
|
129
129
|
Args:
|
|
130
|
-
name:
|
|
131
|
-
price
|
|
130
|
+
name (str): 要更新的模型名称,必须与models.json中的记录匹配
|
|
131
|
+
price (float): 新的输入价格,单位:美元/百万tokens。必须大于等于0
|
|
132
132
|
|
|
133
133
|
Returns:
|
|
134
|
-
bool:
|
|
134
|
+
bool: 是否成功找到并更新了模型价格
|
|
135
|
+
|
|
136
|
+
Raises:
|
|
137
|
+
ValueError: 如果price为负数时抛出
|
|
138
|
+
|
|
139
|
+
Example:
|
|
140
|
+
>>> update_model_input_price("gpt-4", 3.0)
|
|
141
|
+
True
|
|
142
|
+
|
|
143
|
+
Notes:
|
|
144
|
+
1. 价格设置后会立即生效并保存到models.json
|
|
145
|
+
2. 实际费用计算时会按实际使用量精确到小数点后6位
|
|
146
|
+
3. 设置价格为0表示该模型当前不可用
|
|
135
147
|
"""
|
|
136
148
|
if price < 0:
|
|
137
149
|
raise ValueError("Price cannot be negative")
|
|
@@ -151,11 +163,23 @@ def update_model_output_price(name: str, price: float) -> bool:
|
|
|
151
163
|
"""更新模型输出价格
|
|
152
164
|
|
|
153
165
|
Args:
|
|
154
|
-
name:
|
|
155
|
-
price
|
|
166
|
+
name (str): 要更新的模型名称,必须与models.json中的记录匹配
|
|
167
|
+
price (float): 新的输出价格,单位:美元/百万tokens。必须大于等于0
|
|
156
168
|
|
|
157
169
|
Returns:
|
|
158
|
-
bool:
|
|
170
|
+
bool: 是否成功找到并更新了模型价格
|
|
171
|
+
|
|
172
|
+
Raises:
|
|
173
|
+
ValueError: 如果price为负数时抛出
|
|
174
|
+
|
|
175
|
+
Example:
|
|
176
|
+
>>> update_model_output_price("gpt-4", 6.0)
|
|
177
|
+
True
|
|
178
|
+
|
|
179
|
+
Notes:
|
|
180
|
+
1. 输出价格通常比输入价格高30%-50%
|
|
181
|
+
2. 对于按token计费的API,实际收费按(input_tokens * input_price + output_tokens * output_price)计算
|
|
182
|
+
3. 价格变更会影响所有依赖模型计费的功能(如成本预测、用量监控等)
|
|
159
183
|
"""
|
|
160
184
|
if price < 0:
|
|
161
185
|
raise ValueError("Price cannot be negative")
|
autocoder/pyproject/__init__.py
CHANGED
autocoder/tsproject/__init__.py
CHANGED
autocoder/utils/llms.py
CHANGED
|
@@ -3,9 +3,15 @@ from typing import Union,Optional
|
|
|
3
3
|
|
|
4
4
|
def get_llm_names(llm: Union[byzerllm.ByzerLLM, byzerllm.SimpleByzerLLM,str],target_model_type:Optional[str]=None):
|
|
5
5
|
if target_model_type is None:
|
|
6
|
+
if isinstance(llm,list):
|
|
7
|
+
return [_llm.default_model_name for _llm in llm]
|
|
6
8
|
return [llm.default_model_name for llm in [llm] if llm.default_model_name]
|
|
9
|
+
|
|
7
10
|
llms = llm.get_sub_client(target_model_type)
|
|
11
|
+
|
|
8
12
|
if llms is None:
|
|
13
|
+
if isinstance(llm,list):
|
|
14
|
+
return [_llm.default_model_name for _llm in llm]
|
|
9
15
|
return [llm.default_model_name for llm in [llm] if llm.default_model_name]
|
|
10
16
|
elif isinstance(llms, list):
|
|
11
17
|
return [llm.default_model_name for llm in llms if llm.default_model_name]
|
|
@@ -14,6 +20,27 @@ def get_llm_names(llm: Union[byzerllm.ByzerLLM, byzerllm.SimpleByzerLLM,str],tar
|
|
|
14
20
|
else:
|
|
15
21
|
return [llm.default_model_name for llm in [llms] if llm.default_model_name]
|
|
16
22
|
|
|
23
|
+
def get_model_info(model_names: str, product_mode: str):
|
|
24
|
+
from autocoder import models as models_module
|
|
25
|
+
def get_model_by_name(model_name: str):
|
|
26
|
+
try:
|
|
27
|
+
return models_module.get_model_by_name(model_name)
|
|
28
|
+
except Exception as e:
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
if product_mode == "pro":
|
|
32
|
+
return None
|
|
33
|
+
|
|
34
|
+
if product_mode == "lite":
|
|
35
|
+
if "," in model_names:
|
|
36
|
+
# Multiple code models specified
|
|
37
|
+
model_names = model_names.split(",")
|
|
38
|
+
for _, model_name in enumerate(model_names):
|
|
39
|
+
return get_model_by_name(model_name)
|
|
40
|
+
else:
|
|
41
|
+
# Single code model
|
|
42
|
+
return get_model_by_name(model_names)
|
|
43
|
+
|
|
17
44
|
def get_single_llm(model_names: str, product_mode: str):
|
|
18
45
|
from autocoder import models as models_module
|
|
19
46
|
if product_mode == "pro":
|
autocoder/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.1.
|
|
1
|
+
__version__ = "0.1.256"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|