cnhkmcp 2.1.1__py3-none-any.whl → 2.1.3__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.
Files changed (117) hide show
  1. {cnhkmcp-2.1.1.dist-info → cnhkmcp-2.1.3.dist-info}/METADATA +1 -1
  2. cnhkmcp-2.1.3.dist-info/RECORD +6 -0
  3. cnhkmcp-2.1.3.dist-info/top_level.txt +1 -0
  4. cnhkmcp/__init__.py +0 -125
  5. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/README.md +0 -38
  6. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/ace.log +0 -0
  7. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/config.json +0 -6
  8. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/get_knowledgeBase_tool/ace_lib.py +0 -1510
  9. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/get_knowledgeBase_tool/fetch_all_datasets.py +0 -157
  10. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/get_knowledgeBase_tool/fetch_all_documentation.py +0 -132
  11. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/get_knowledgeBase_tool/fetch_all_operators.py +0 -99
  12. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/get_knowledgeBase_tool/helpful_functions.py +0 -180
  13. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/icon.ico +0 -0
  14. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/icon.png +0 -0
  15. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/knowledge/test.txt +0 -1
  16. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/main.py +0 -576
  17. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/process_knowledge_base.py +0 -280
  18. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/rag_engine.py +0 -356
  19. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/requirements.txt +0 -7
  20. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/run.bat +0 -3
  21. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/vector_db/_manifest.json +0 -326
  22. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/vector_db/_meta.json +0 -1
  23. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/vector_db/be5d957c-b724-46e3-91d1-999e9f5f7d28/index_metadata.pickle +0 -0
  24. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/vector_db/chroma.sqlite3 +0 -0
  25. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242//321/211/320/266/320/246/321/206/320/274/320/261/321/210/342/224/220/320/240/321/210/320/261/320/234/321/206/320/231/320/243/321/205/342/225/235/320/220/321/206/320/230/320/241.py +0 -265
  26. cnhkmcp/untracked/APP/.gitignore +0 -32
  27. cnhkmcp/untracked/APP/MODULAR_STRUCTURE.md +0 -112
  28. cnhkmcp/untracked/APP/README.md +0 -309
  29. cnhkmcp/untracked/APP/Tranformer/Transformer.py +0 -4985
  30. cnhkmcp/untracked/APP/Tranformer/ace.log +0 -0
  31. cnhkmcp/untracked/APP/Tranformer/ace_lib.py +0 -1510
  32. cnhkmcp/untracked/APP/Tranformer/helpful_functions.py +0 -180
  33. cnhkmcp/untracked/APP/Tranformer/output/Alpha_candidates.json +0 -2421
  34. cnhkmcp/untracked/APP/Tranformer/output/Alpha_candidates_/321/207/320/264/342/225/221/321/204/342/225/233/320/233.json +0 -654
  35. cnhkmcp/untracked/APP/Tranformer/output/Alpha_generated_expressions_error.json +0 -1034
  36. cnhkmcp/untracked/APP/Tranformer/output/Alpha_generated_expressions_success.json +0 -444
  37. cnhkmcp/untracked/APP/Tranformer/output/Alpha_generated_expressions_/321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/320/237/320/277/321/207/320/253/342/224/244/321/206/320/236/320/265/321/210/342/225/234/342/225/234/321/205/320/225/320/265Machine_lib.json +0 -22
  38. cnhkmcp/untracked/APP/Tranformer/parsetab.py +0 -60
  39. cnhkmcp/untracked/APP/Tranformer/template_summary.txt +0 -3182
  40. cnhkmcp/untracked/APP/Tranformer/transformer_config.json +0 -7
  41. cnhkmcp/untracked/APP/Tranformer/validator.py +0 -889
  42. cnhkmcp/untracked/APP/ace.log +0 -69
  43. cnhkmcp/untracked/APP/ace_lib.py +0 -1510
  44. cnhkmcp/untracked/APP/blueprints/__init__.py +0 -6
  45. cnhkmcp/untracked/APP/blueprints/feature_engineering.py +0 -347
  46. cnhkmcp/untracked/APP/blueprints/idea_house.py +0 -221
  47. cnhkmcp/untracked/APP/blueprints/inspiration_house.py +0 -432
  48. cnhkmcp/untracked/APP/blueprints/paper_analysis.py +0 -570
  49. cnhkmcp/untracked/APP/custom_templates/templates.json +0 -1257
  50. cnhkmcp/untracked/APP/give_me_idea/BRAIN_Alpha_Template_Expert_SystemPrompt.md +0 -400
  51. cnhkmcp/untracked/APP/give_me_idea/ace_lib.py +0 -1510
  52. cnhkmcp/untracked/APP/give_me_idea/alpha_data_specific_template_master.py +0 -252
  53. cnhkmcp/untracked/APP/give_me_idea/fetch_all_datasets.py +0 -157
  54. cnhkmcp/untracked/APP/give_me_idea/fetch_all_operators.py +0 -99
  55. cnhkmcp/untracked/APP/give_me_idea/helpful_functions.py +0 -180
  56. cnhkmcp/untracked/APP/give_me_idea/what_is_Alpha_template.md +0 -11
  57. cnhkmcp/untracked/APP/helpful_functions.py +0 -180
  58. cnhkmcp/untracked/APP/hkSimulator/ace_lib.py +0 -1497
  59. cnhkmcp/untracked/APP/hkSimulator/autosimulator.py +0 -447
  60. cnhkmcp/untracked/APP/hkSimulator/helpful_functions.py +0 -180
  61. cnhkmcp/untracked/APP/mirror_config.txt +0 -20
  62. cnhkmcp/untracked/APP/operaters.csv +0 -129
  63. cnhkmcp/untracked/APP/requirements.txt +0 -53
  64. cnhkmcp/untracked/APP/run_app.bat +0 -28
  65. cnhkmcp/untracked/APP/run_app.sh +0 -34
  66. cnhkmcp/untracked/APP/setup_tsinghua.bat +0 -39
  67. cnhkmcp/untracked/APP/setup_tsinghua.sh +0 -43
  68. cnhkmcp/untracked/APP/simulator/alpha_submitter.py +0 -404
  69. cnhkmcp/untracked/APP/simulator/simulator_wqb.py +0 -618
  70. cnhkmcp/untracked/APP/ssrn-3332513.pdf +6 -109201
  71. cnhkmcp/untracked/APP/static/brain.js +0 -589
  72. cnhkmcp/untracked/APP/static/decoder.js +0 -1540
  73. cnhkmcp/untracked/APP/static/feature_engineering.js +0 -1729
  74. cnhkmcp/untracked/APP/static/idea_house.js +0 -937
  75. cnhkmcp/untracked/APP/static/inspiration.js +0 -465
  76. cnhkmcp/untracked/APP/static/inspiration_house.js +0 -868
  77. cnhkmcp/untracked/APP/static/paper_analysis.js +0 -390
  78. cnhkmcp/untracked/APP/static/script.js +0 -3082
  79. cnhkmcp/untracked/APP/static/simulator.js +0 -597
  80. cnhkmcp/untracked/APP/static/styles.css +0 -3127
  81. cnhkmcp/untracked/APP/static/usage_widget.js +0 -508
  82. cnhkmcp/untracked/APP/templates/alpha_inspector.html +0 -511
  83. cnhkmcp/untracked/APP/templates/feature_engineering.html +0 -960
  84. cnhkmcp/untracked/APP/templates/idea_house.html +0 -564
  85. cnhkmcp/untracked/APP/templates/index.html +0 -932
  86. cnhkmcp/untracked/APP/templates/inspiration_house.html +0 -861
  87. cnhkmcp/untracked/APP/templates/paper_analysis.html +0 -91
  88. cnhkmcp/untracked/APP/templates/simulator.html +0 -343
  89. cnhkmcp/untracked/APP/templates/transformer_web.html +0 -580
  90. cnhkmcp/untracked/APP/usage.md +0 -351
  91. cnhkmcp/untracked/APP//321/207/342/225/235/320/250/321/205/320/230/320/226/321/204/342/225/225/320/220/321/211/320/221/320/243/321/206/320/261/320/265/ace_lib.py +0 -1510
  92. cnhkmcp/untracked/APP//321/207/342/225/235/320/250/321/205/320/230/320/226/321/204/342/225/225/320/220/321/211/320/221/320/243/321/206/320/261/320/265/brain_alpha_inspector.py +0 -712
  93. cnhkmcp/untracked/APP//321/207/342/225/235/320/250/321/205/320/230/320/226/321/204/342/225/225/320/220/321/211/320/221/320/243/321/206/320/261/320/265/helpful_functions.py +0 -180
  94. cnhkmcp/untracked/APP//321/210/342/224/220/320/240/321/210/320/261/320/234/321/206/320/231/320/243/321/205/342/225/235/320/220/321/206/320/230/320/241.py +0 -2456
  95. cnhkmcp/untracked/arXiv_API_Tool_Manual.md +0 -490
  96. cnhkmcp/untracked/arxiv_api.py +0 -229
  97. cnhkmcp/untracked/forum_functions.py +0 -998
  98. cnhkmcp/untracked/mcp/321/206/320/246/320/227/321/204/342/225/227/342/225/242/321/210/320/276/342/225/221/321/205/320/255/320/253/321/207/320/231/320/2302_/321/205/320/266/320/222/321/206/320/256/320/254/321/205/320/236/320/257/321/207/320/231/320/230/321/205/320/240/320/277/321/205/320/232/320/270/321/204/342/225/225/320/235/321/204/342/225/221/320/226/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270/321/205/342/226/221/342/226/222/321/210/320/277/320/245/321/210/342/224/220/320/251/321/204/342/225/225/320/272/forum_functions.py +0 -407
  99. cnhkmcp/untracked/mcp/321/206/320/246/320/227/321/204/342/225/227/342/225/242/321/210/320/276/342/225/221/321/205/320/255/320/253/321/207/320/231/320/2302_/321/205/320/266/320/222/321/206/320/256/320/254/321/205/320/236/320/257/321/207/320/231/320/230/321/205/320/240/320/277/321/205/320/232/320/270/321/204/342/225/225/320/235/321/204/342/225/221/320/226/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270/321/205/342/226/221/342/226/222/321/210/320/277/320/245/321/210/342/224/220/320/251/321/204/342/225/225/320/272/platform_functions.py +0 -2415
  100. cnhkmcp/untracked/mcp/321/206/320/246/320/227/321/204/342/225/227/342/225/242/321/210/320/276/342/225/221/321/205/320/255/320/253/321/207/320/231/320/2302_/321/205/320/266/320/222/321/206/320/256/320/254/321/205/320/236/320/257/321/207/320/231/320/230/321/205/320/240/320/277/321/205/320/232/320/270/321/204/342/225/225/320/235/321/204/342/225/221/320/226/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270/321/205/342/226/221/342/226/222/321/210/320/277/320/245/321/210/342/224/220/320/251/321/204/342/225/225/320/272/user_config.json +0 -31
  101. cnhkmcp/untracked/mcp/321/206/320/246/320/227/321/204/342/225/227/342/225/242/321/210/320/276/342/225/221/321/205/320/255/320/253/321/207/320/231/320/2302_/321/205/320/266/320/222/321/206/320/256/320/254/321/205/320/236/320/257/321/207/320/231/320/230/321/205/320/240/320/277/321/205/320/232/320/270/321/204/342/225/225/320/235/321/204/342/225/221/320/226/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270/321/205/342/226/221/342/226/222/321/210/320/277/320/245/321/210/342/224/220/320/251/321/204/342/225/225/320/272//321/210/320/276/320/271AI/321/210/320/277/342/225/227/321/210/342/224/220/320/251/321/204/342/225/225/320/272/321/206/320/246/320/227/321/206/320/261/320/263/321/206/320/255/320/265/321/205/320/275/320/266/321/204/342/225/235/320/252/321/204/342/225/225/320/233/321/210/342/225/234/342/225/234/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270.md +0 -101
  102. cnhkmcp/untracked/mcp/321/206/320/246/320/227/321/204/342/225/227/342/225/242/321/210/320/276/342/225/221/321/205/320/255/320/253/321/207/320/231/320/2302_/321/205/320/266/320/222/321/206/320/256/320/254/321/205/320/236/320/257/321/207/320/231/320/230/321/205/320/240/320/277/321/205/320/232/320/270/321/204/342/225/225/320/235/321/204/342/225/221/320/226/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270/321/205/342/226/221/342/226/222/321/210/320/277/320/245/321/210/342/224/220/320/251/321/204/342/225/225/320/272//321/211/320/225/320/235/321/207/342/225/234/320/276/321/205/320/231/320/235/321/210/342/224/220/320/240/321/210/320/261/320/234/321/206/320/230/320/241_/321/205/320/276/320/231/321/210/320/263/320/225/321/205/342/224/220/320/225/321/210/320/266/320/221/321/204/342/225/233/320/255/321/210/342/225/241/320/246/321/205/320/234/320/225.py +0 -190
  103. cnhkmcp/untracked/platform_functions.py +0 -2886
  104. cnhkmcp/untracked/sample_mcp_config.json +0 -11
  105. cnhkmcp/untracked/user_config.json +0 -31
  106. cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/320/237/320/222/321/210/320/220/320/223/321/206/320/246/320/227/321/206/320/261/320/263_BRAIN_Alpha_Test_Requirements_and_Tips.md +0 -202
  107. cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/342/225/226/320/265/321/204/342/225/234/320/254/321/206/342/225/241/320/221_Alpha_explaination_workflow.md +0 -56
  108. cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/342/225/226/320/265/321/204/342/225/234/320/254/321/206/342/225/241/320/221_BRAIN_6_Tips_Datafield_Exploration_Guide.md +0 -194
  109. cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/342/225/226/320/265/321/204/342/225/234/320/254/321/206/342/225/241/320/221_BRAIN_Alpha_Improvement_Workflow.md +0 -101
  110. cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/342/225/226/320/265/321/204/342/225/234/320/254/321/206/342/225/241/320/221_Dataset_Exploration_Expert_Manual.md +0 -436
  111. cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/342/225/226/320/265/321/204/342/225/234/320/254/321/206/342/225/241/320/221_daily_report_workflow.md +0 -128
  112. cnhkmcp/untracked//321/211/320/225/320/235/321/207/342/225/234/320/276/321/205/320/231/320/235/321/210/342/224/220/320/240/321/210/320/261/320/234/321/206/320/230/320/241_/321/205/320/276/320/231/321/210/320/263/320/225/321/205/342/224/220/320/225/321/210/320/266/320/221/321/204/342/225/233/320/255/321/210/342/225/241/320/246/321/205/320/234/320/225.py +0 -190
  113. cnhkmcp-2.1.1.dist-info/RECORD +0 -115
  114. cnhkmcp-2.1.1.dist-info/top_level.txt +0 -1
  115. {cnhkmcp-2.1.1.dist-info → cnhkmcp-2.1.3.dist-info}/WHEEL +0 -0
  116. {cnhkmcp-2.1.1.dist-info → cnhkmcp-2.1.3.dist-info}/entry_points.txt +0 -0
  117. {cnhkmcp-2.1.1.dist-info → cnhkmcp-2.1.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,432 +0,0 @@
1
- from flask import Blueprint, render_template, request, jsonify
2
- import requests
3
- import json
4
- import logging
5
- import threading
6
- from concurrent.futures import ThreadPoolExecutor, as_completed
7
-
8
- inspiration_house_bp = Blueprint('inspiration_house', __name__)
9
-
10
- # Configure logging
11
- logging.basicConfig(level=logging.INFO)
12
- logger = logging.getLogger(__name__)
13
-
14
- @inspiration_house_bp.route('/')
15
- def inspiration_house():
16
- """Main inspiration house page"""
17
- return render_template('inspiration_house.html')
18
-
19
- @inspiration_house_bp.route('/api/test-deepseek', methods=['POST'])
20
- def test_deepseek_api():
21
- """Test API connection for both Deepseek and Kimi"""
22
- try:
23
- api_key = request.headers.get('X-API-Key')
24
- if not api_key:
25
- return jsonify({'success': False, 'error': 'API key is required'}), 400
26
-
27
- data = request.get_json()
28
- provider = data.get('provider', 'deepseek')
29
- model_name = data.get('model_name', 'deepseek-chat')
30
-
31
- # Test API with a simple request
32
- headers = {
33
- 'Authorization': f'Bearer {api_key}',
34
- 'Content-Type': 'application/json'
35
- }
36
-
37
- test_data = {
38
- 'model': model_name,
39
- 'messages': [
40
- {'role': 'user', 'content': 'Hello, this is a test message.'}
41
- ],
42
- 'max_tokens': 10
43
- }
44
-
45
- # Choose API endpoint based on provider
46
- if provider == 'kimi':
47
- # Use the correct Kimi API endpoint that was tested and confirmed working
48
- api_url = 'https://api.moonshot.cn/v1/chat/completions'
49
-
50
- kimi_data = {
51
- 'model': model_name,
52
- 'messages': [
53
- {'role': 'user', 'content': 'Hello, this is a test message.'}
54
- ],
55
- 'max_tokens': 10,
56
- 'stream': False
57
- }
58
-
59
- logger.info(f"Testing Kimi API with correct endpoint: {api_url}")
60
- response = requests.post(api_url, headers=headers, json=kimi_data, timeout=10)
61
- logger.info(f"Kimi response status: {response.status_code}")
62
-
63
- else:
64
- # Default to Deepseek
65
- api_url = 'https://api.deepseek.com/chat/completions'
66
- response = requests.post(api_url, headers=headers, json=test_data, timeout=10)
67
-
68
- if response.status_code == 200:
69
- return jsonify({'success': True, 'message': f'{provider.capitalize()} API connection successful'})
70
- else:
71
- error_detail = response.text
72
- return jsonify({'success': False, 'error': f'API returned status {response.status_code}: {error_detail}'}), 400
73
-
74
- except requests.exceptions.RequestException as e:
75
- logger.error(f"API test error: {str(e)}")
76
- return jsonify({'success': False, 'error': f'Network error: {str(e)}'}), 500
77
- except Exception as e:
78
- logger.error(f"Unexpected error in API test: {str(e)}")
79
- return jsonify({'success': False, 'error': f'Unexpected error: {str(e)}'}), 500
80
-
81
- @inspiration_house_bp.route('/api/evaluate-operator', methods=['POST'])
82
- def evaluate_operator():
83
- """Evaluate a single operator against the research target"""
84
- try:
85
- api_key = request.headers.get('X-API-Key')
86
- if not api_key:
87
- return jsonify({'success': False, 'error': 'API key is required'}), 400
88
-
89
- data = request.get_json()
90
- operator = data.get('operator', {})
91
- research_target = data.get('research_target', '')
92
- current_expression = data.get('current_expression', '')
93
- expression_context = data.get('expression_context', '')
94
- provider = data.get('provider', 'deepseek')
95
- model_name = data.get('model_name', 'deepseek-chat')
96
-
97
- if not operator or not research_target:
98
- return jsonify({'success': False, 'error': 'Operator and research target are required'}), 400
99
-
100
- # Build the evaluation prompt
101
- system_prompt = get_evaluation_system_prompt()
102
- user_prompt = build_evaluation_prompt(operator, research_target, current_expression, expression_context)
103
-
104
- # Make API call based on provider
105
- headers = {
106
- 'Authorization': f'Bearer {api_key}',
107
- 'Content-Type': 'application/json'
108
- }
109
-
110
- if provider == 'kimi':
111
- # Use the correct Kimi API endpoint that was tested and confirmed working
112
- api_url = 'https://api.moonshot.cn/v1/chat/completions'
113
-
114
- api_data = {
115
- 'model': model_name,
116
- 'messages': [
117
- {'role': 'system', 'content': system_prompt},
118
- {'role': 'user', 'content': user_prompt}
119
- ],
120
- 'max_tokens': 4096,
121
- 'temperature': 0.3
122
- }
123
-
124
- response = requests.post(api_url, headers=headers, json=api_data, timeout=30)
125
-
126
- else:
127
- # Deepseek API structure
128
- api_url = 'https://api.deepseek.com/chat/completions'
129
- api_data = {
130
- 'model': model_name,
131
- 'messages': [
132
- {'role': 'system', 'content': system_prompt},
133
- {'role': 'user', 'content': user_prompt}
134
- ],
135
- 'max_tokens': 4096,
136
- 'temperature': 0.3
137
- }
138
- response = requests.post(api_url, headers=headers, json=api_data, timeout=30)
139
-
140
- if response.status_code == 200:
141
- response_data = response.json()
142
-
143
- # Both Kimi and Deepseek use the same OpenAI-compatible response structure
144
- ai_response = response_data['choices'][0]['message']['content']
145
-
146
- # Parse the AI response to extract score and reason
147
- score, reason = parse_evaluation_response(ai_response)
148
-
149
- return jsonify({
150
- 'success': True,
151
- 'score': score,
152
- 'reason': reason,
153
- 'operator': operator.get('name', 'Unknown'),
154
- 'research_target': research_target
155
- })
156
- else:
157
- error_detail = response.text
158
- logger.error(f"{provider.capitalize()} API error: {response.status_code} - {error_detail}")
159
- return jsonify({'success': False, 'error': f'API returned status {response.status_code}: {error_detail}'}), 400
160
-
161
- except requests.exceptions.RequestException as e:
162
- logger.error(f"API request error: {str(e)}")
163
- return jsonify({'success': False, 'error': f'Network error: {str(e)}'}), 500
164
- except Exception as e:
165
- logger.error(f"Unexpected error in operator evaluation: {str(e)}")
166
- return jsonify({'success': False, 'error': f'Unexpected error: {str(e)}'}), 500
167
-
168
- def get_evaluation_system_prompt():
169
- """Get the system prompt for operator evaluation"""
170
- return """You are an expert quantitative researcher and data scientist specializing in financial data analysis and algorithmic trading. Your task is to evaluate how well a specific BRAIN operator could be ADDED to the current expression to help achieve a given quant research target.
171
-
172
- IMPORTANT: You are NOT suggesting replacements for the current expression. You are evaluating how each operator could be COMBINED with or applied AFTER the current expression to move closer to the target.
173
-
174
- Your evaluation should be based on:
175
- 1. How the operator could be applied AFTER the current expression (e.g., ts_rank(current_expression))
176
- 2. The operator's mathematical and statistical properties when combined with the current expression
177
- 3. How this combination would better achieve the stated research target
178
- 4. The synergistic effects of applying this operator to the current expression
179
-
180
- You must provide:
181
- 1. A score from 0-10 (where 10 is perfect synergistic addition to achieve the target)
182
- 2. A clear, concise reason explaining how this operator could be added to improve the current expression
183
-
184
- Scoring Guidelines:
185
- - 8-10: Excellent addition - operator would significantly enhance the current expression for the target
186
- - 6-7: Good addition - operator would meaningfully improve the current expression
187
- - 4-5: Moderate addition - operator could provide some benefit when combined
188
- - 2-3: Weak addition - operator would add little value to the current expression
189
- - 0-1: No value - operator would not help or might even hurt the current expression
190
-
191
- Response Format:
192
- Score: [number from 0-10]
193
- Reason: [provide a detailed explanation of how this operator could be added to the current expression to better achieve the target. Include specific examples of how the combination would work and why it would be effective.]
194
-
195
- Focus on combination effects and how the operator would enhance the current expression rather than replace it. Be thorough in your explanation."""
196
-
197
- def build_evaluation_prompt(operator, research_target, current_expression, expression_context):
198
- """Build the user prompt for operator evaluation"""
199
-
200
- operator_info = f"""
201
- Operator Name: {operator.get('name', 'Unknown')}
202
- Operator Category: {operator.get('category', 'Unknown')}
203
- Operator Description: {operator.get('description', 'No description available')}
204
- """
205
-
206
- context_info = f"""
207
- Research Target: {research_target}
208
- Current Expression: {current_expression if current_expression else 'None provided'}
209
- Expression Context: {expression_context if expression_context else 'None provided'}
210
- """
211
-
212
- return f"""Please evaluate how well this BRAIN operator could be ADDED to the current expression to help achieve the research target.
213
-
214
- {operator_info}
215
-
216
- {context_info}
217
-
218
- IMPORTANT: Consider how this operator could be applied AFTER the current expression (e.g., {operator.get('name', 'operator')}(current_expression)) to enhance the strategy. Do NOT suggest replacing the current expression.
219
-
220
- Think about:
221
- - How would applying this operator to the current expression improve the strategy?
222
- - What synergistic effects would this combination create?
223
- - How would this addition move us closer to the research target?
224
-
225
- Response Format:
226
- Score: [number from 0-10]
227
- Reason: [provide a detailed explanation of how this operator could be added to the current expression to better achieve the target. Include specific examples of how the combination would work and why it would be effective.]"""
228
-
229
- def parse_evaluation_response(response):
230
- """Parse the AI response to extract score and reason"""
231
- try:
232
- lines = response.strip().split('\n')
233
- score = 0
234
- reason = "No reason provided"
235
- in_reason_section = False
236
- reason_lines = []
237
-
238
- for line in lines:
239
- line = line.strip()
240
- if line.lower().startswith('score:'):
241
- try:
242
- score_text = line.split(':', 1)[1].strip()
243
- score = int(score_text)
244
- # Ensure score is within valid range
245
- score = max(0, min(10, score))
246
- except (ValueError, IndexError):
247
- score = 0
248
- elif line.lower().startswith('reason:'):
249
- in_reason_section = True
250
- reason_text = line.split(':', 1)[1].strip()
251
- if reason_text:
252
- reason_lines.append(reason_text)
253
- elif in_reason_section and line:
254
- # Continue collecting reason lines until we hit another section or empty line
255
- if line.lower().startswith(('score:', 'operator:', 'category:')):
256
- break
257
- reason_lines.append(line)
258
-
259
- if reason_lines:
260
- reason = ' '.join(reason_lines)
261
-
262
- return score, reason
263
- except Exception as e:
264
- logger.error(f"Error parsing evaluation response: {str(e)}")
265
- return 0, f"Error parsing response: {str(e)}"
266
-
267
- @inspiration_house_bp.route('/api/batch-evaluate', methods=['POST'])
268
- def batch_evaluate_operators():
269
- """Evaluate multiple operators in parallel"""
270
- try:
271
- api_key = request.headers.get('X-API-Key')
272
- if not api_key:
273
- return jsonify({'success': False, 'error': 'API key is required'}), 400
274
-
275
- data = request.get_json()
276
- operators = data.get('operators', [])
277
- research_target = data.get('research_target', '')
278
- current_expression = data.get('current_expression', '')
279
- expression_context = data.get('expression_context', '')
280
- batch_size = data.get('batch_size', 100) # Get batch size from request
281
- provider = data.get('provider', 'deepseek')
282
- model_name = data.get('model_name', 'deepseek-chat')
283
-
284
- if not operators or not research_target:
285
- return jsonify({'success': False, 'error': 'Operators and research target are required'}), 400
286
-
287
- # Use ThreadPoolExecutor for parallel processing
288
- # Use full parallelization for all providers
289
- max_workers = len(operators)
290
- logger.info(f"Using {max_workers} workers for API evaluation")
291
-
292
- results = []
293
- with ThreadPoolExecutor(max_workers=max_workers) as executor:
294
- # Submit all evaluation tasks
295
- future_to_operator = {
296
- executor.submit(
297
- evaluate_single_operator_async,
298
- api_key,
299
- operator,
300
- research_target,
301
- current_expression,
302
- expression_context,
303
- provider,
304
- model_name
305
- ): operator for operator in operators
306
- }
307
-
308
- # Collect results as they complete
309
- for future in as_completed(future_to_operator):
310
- operator = future_to_operator[future]
311
- try:
312
- result = future.result()
313
- results.append(result)
314
- except Exception as e:
315
- logger.error(f"Error evaluating operator {operator.get('name', 'Unknown')}: {str(e)}")
316
- results.append({
317
- 'operator': operator.get('name', 'Unknown'),
318
- 'category': operator.get('category', 'Unknown'),
319
- 'score': 0,
320
- 'reason': f'Error: {str(e)}',
321
- 'timestamp': None
322
- })
323
-
324
- return jsonify({
325
- 'success': True,
326
- 'results': results,
327
- 'total_evaluated': len(results),
328
- 'workers_used': max_workers,
329
- 'total_operators': len(operators)
330
- })
331
-
332
- except Exception as e:
333
- logger.error(f"Unexpected error in batch evaluation: {str(e)}")
334
- return jsonify({'success': False, 'error': f'Unexpected error: {str(e)}'}), 500
335
-
336
- def evaluate_single_operator_async(api_key, operator, research_target, current_expression, expression_context, provider='deepseek', model_name='deepseek-chat'):
337
- """Evaluate a single operator asynchronously"""
338
- try:
339
- # Build the evaluation prompt
340
- system_prompt = get_evaluation_system_prompt()
341
- user_prompt = build_evaluation_prompt(operator, research_target, current_expression, expression_context)
342
-
343
- # Make API call based on provider
344
- headers = {
345
- 'Authorization': f'Bearer {api_key}',
346
- 'Content-Type': 'application/json'
347
- }
348
-
349
- if provider == 'kimi':
350
- # Use the correct Kimi API endpoint that was tested and confirmed working
351
- api_url = 'https://api.moonshot.cn/v1/chat/completions'
352
-
353
- api_data = {
354
- 'model': model_name,
355
- 'messages': [
356
- {'role': 'system', 'content': system_prompt},
357
- {'role': 'user', 'content': user_prompt}
358
- ],
359
- 'max_tokens': 4096,
360
- 'temperature': 0.3
361
- }
362
-
363
- response = requests.post(api_url, headers=headers, json=api_data, timeout=30)
364
-
365
- else:
366
- # Deepseek API structure
367
- api_url = 'https://api.deepseek.com/chat/completions'
368
- api_data = {
369
- 'model': model_name,
370
- 'messages': [
371
- {'role': 'system', 'content': system_prompt},
372
- {'role': 'user', 'content': user_prompt}
373
- ],
374
- 'max_tokens': 4096,
375
- 'temperature': 0.3
376
- }
377
- response = requests.post(api_url, headers=headers, json=api_data, timeout=30)
378
-
379
- if response.status_code == 200:
380
- response_data = response.json()
381
-
382
- # Both Kimi and Deepseek use the same OpenAI-compatible response structure
383
- ai_response = response_data['choices'][0]['message']['content']
384
-
385
- # Parse the AI response to extract score and reason
386
- score, reason = parse_evaluation_response(ai_response)
387
-
388
- return {
389
- 'operator': operator.get('name', 'Unknown'),
390
- 'category': operator.get('category', 'Unknown'),
391
- 'score': score,
392
- 'reason': reason,
393
- 'timestamp': None
394
- }
395
- else:
396
- error_detail = response.text
397
- logger.error(f"{provider.capitalize()} API error for operator {operator.get('name', 'Unknown')}: {response.status_code} - {error_detail}")
398
- return {
399
- 'operator': operator.get('name', 'Unknown'),
400
- 'category': operator.get('category', 'Unknown'),
401
- 'score': 0,
402
- 'reason': f'API Error: {response.status_code}',
403
- 'timestamp': None
404
- }
405
-
406
- except requests.exceptions.Timeout as e:
407
- logger.error(f"Timeout error evaluating operator {operator.get('name', 'Unknown')}: {str(e)}")
408
- return {
409
- 'operator': operator.get('name', 'Unknown'),
410
- 'category': operator.get('category', 'Unknown'),
411
- 'score': 0,
412
- 'reason': f'API Timeout: Request took too long to complete',
413
- 'timestamp': None
414
- }
415
- except requests.exceptions.RequestException as e:
416
- logger.error(f"Request error evaluating operator {operator.get('name', 'Unknown')}: {str(e)}")
417
- return {
418
- 'operator': operator.get('name', 'Unknown'),
419
- 'category': operator.get('category', 'Unknown'),
420
- 'score': 0,
421
- 'reason': f'Network Error: {str(e)}',
422
- 'timestamp': None
423
- }
424
- except Exception as e:
425
- logger.error(f"Error evaluating operator {operator.get('name', 'Unknown')}: {str(e)}")
426
- return {
427
- 'operator': operator.get('name', 'Unknown'),
428
- 'category': operator.get('category', 'Unknown'),
429
- 'score': 0,
430
- 'reason': f'Error: {str(e)}',
431
- 'timestamp': None
432
- }