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,868 +0,0 @@
1
- // Inspiration House JavaScript
2
-
3
- // Store API key and state in session storage
4
- let apiKey = sessionStorage.getItem('deepseekApiKey');
5
- let modelProvider = sessionStorage.getItem('inspirationHouseProvider') || 'deepseek';
6
- let modelName = sessionStorage.getItem('inspirationHouseModelName') || 'deepseek-chat';
7
- let researchTarget = sessionStorage.getItem('inspirationHouseTarget') || '';
8
- let currentExpression = sessionStorage.getItem('inspirationHouseExpression') || '';
9
- let expressionContext = sessionStorage.getItem('inspirationHouseContext') || '';
10
- let evaluationResults = JSON.parse(sessionStorage.getItem('inspirationHouseResults')) || [];
11
- let operatorsList = JSON.parse(sessionStorage.getItem('brainOperators')) || [];
12
- let isEvaluating = false;
13
- let evaluationProgress = 0;
14
- let totalOperators = 0;
15
- let batchSize = parseInt(sessionStorage.getItem('inspirationHouseBatchSize')) || 100; // Configurable batch size
16
-
17
- // DOM Elements
18
- const modelProviderSelect = document.getElementById('modelProvider');
19
- const apiKeyInput = document.getElementById('apiKey');
20
- const modelNameInput = document.getElementById('modelName');
21
- const batchSizeInput = document.getElementById('batchSize');
22
- const saveApiKeyBtn = document.getElementById('saveApiKey');
23
- const apiConfigSection = document.getElementById('apiConfigSection');
24
- const showApiConfigSection = document.getElementById('showApiConfigSection');
25
- const showApiConfigBtn = document.getElementById('showApiConfig');
26
- const editTargetBtn = document.getElementById('editTarget');
27
- const targetDisplay = document.getElementById('targetDisplay');
28
- const targetText = document.getElementById('targetText');
29
- const targetInputGroup = document.getElementById('targetInputGroup');
30
- const researchTargetInput = document.getElementById('researchTarget');
31
- const saveTargetBtn = document.getElementById('saveTarget');
32
- const cancelTargetBtn = document.getElementById('cancelTarget');
33
- const currentExpressionInput = document.getElementById('currentExpression');
34
- const expressionContextInput = document.getElementById('expressionContext');
35
- const loadFromBRAINBtn = document.getElementById('loadFromBRAIN');
36
- const startEvaluationBtn = document.getElementById('startEvaluation');
37
- const refreshEvaluationBtn = document.getElementById('refreshEvaluation');
38
- const exportResultsBtn = document.getElementById('exportResults');
39
- const clearResultsBtn = document.getElementById('clearResults');
40
- const evaluationTableBody = document.getElementById('evaluationTableBody');
41
- const progressSection = document.getElementById('progressSection');
42
- const progressFill = document.getElementById('progressFill');
43
- const progressText = document.getElementById('progressText');
44
- const progressCount = document.getElementById('progressCount');
45
- const summaryStats = document.getElementById('summaryStats');
46
- const highScoreCount = document.getElementById('highScoreCount');
47
- const mediumScoreCount = document.getElementById('mediumScoreCount');
48
- const lowScoreCount = document.getElementById('lowScoreCount');
49
- const totalEvaluated = document.getElementById('totalEvaluated');
50
- const minScoreFilter = document.getElementById('minScoreFilter');
51
- const maxScoreFilter = document.getElementById('maxScoreFilter');
52
- const minScoreValue = document.getElementById('minScoreValue');
53
- const maxScoreValue = document.getElementById('maxScoreValue');
54
- const showHighScores = document.getElementById('showHighScores');
55
- const showMediumScores = document.getElementById('showMediumScores');
56
- const showLowScores = document.getElementById('showLowScores');
57
- const exportHighScoresBtn = document.getElementById('exportHighScores');
58
- const exportAllResultsBtn = document.getElementById('exportAllResults');
59
- const exportCSVBtn = document.getElementById('exportCSV');
60
- const currentBatchSizeSpan = document.getElementById('currentBatchSize');
61
-
62
- // Initialize API key if exists
63
- if (apiKey) {
64
- apiKeyInput.value = apiKey;
65
- }
66
-
67
- // Initialize model provider and name
68
- modelProviderSelect.value = modelProvider;
69
- modelNameInput.value = modelName;
70
-
71
- // Initialize batch size
72
- batchSizeInput.value = batchSize;
73
- currentBatchSizeSpan.textContent = operatorsList.length;
74
-
75
- // Update model name placeholder based on provider
76
- function updateModelNamePlaceholder() {
77
- const provider = modelProviderSelect.value;
78
- if (provider === 'kimi') {
79
- modelNameInput.placeholder = 'e.g., kimi-k2-0711-preview';
80
- if (modelNameInput.value === 'deepseek-chat') {
81
- modelNameInput.value = 'kimi-k2-0711-preview';
82
- }
83
- } else {
84
- modelNameInput.placeholder = 'e.g., deepseek-chat, deepseek-coder';
85
- if (modelNameInput.value === 'kimi-k2-0711-preview') {
86
- modelNameInput.value = 'deepseek-chat';
87
- }
88
- }
89
- }
90
-
91
- // Model provider change handler
92
- modelProviderSelect.addEventListener('change', () => {
93
- modelProvider = modelProviderSelect.value;
94
- sessionStorage.setItem('inspirationHouseProvider', modelProvider);
95
- updateModelNamePlaceholder();
96
- });
97
-
98
- // Model name change handler
99
- modelNameInput.addEventListener('input', () => {
100
- modelName = modelNameInput.value;
101
- sessionStorage.setItem('inspirationHouseModelName', modelName);
102
- });
103
-
104
- // Save batch size when changed
105
- batchSizeInput.addEventListener('change', () => {
106
- batchSize = parseInt(batchSizeInput.value) || 100;
107
- sessionStorage.setItem('inspirationHouseBatchSize', batchSize.toString());
108
- console.log(`Batch size updated to: ${batchSize}`);
109
- });
110
-
111
- // Initialize placeholder on page load
112
- updateModelNamePlaceholder();
113
-
114
- // Check if API is already configured and hide config section if so
115
- function checkApiConfigStatus() {
116
- if (apiKey && modelProvider && modelName) {
117
- apiConfigSection.style.display = 'none';
118
- showApiConfigSection.style.display = 'block';
119
- } else {
120
- apiConfigSection.style.display = 'block';
121
- showApiConfigSection.style.display = 'none';
122
- }
123
- }
124
-
125
- // Show API Config button event listener
126
- showApiConfigBtn.addEventListener('click', () => {
127
- apiConfigSection.style.display = 'block';
128
- showApiConfigSection.style.display = 'none';
129
- });
130
-
131
- // Load existing state on page load
132
- window.addEventListener('DOMContentLoaded', () => {
133
- console.log('Loading Inspiration House state...');
134
- console.log('Research target:', researchTarget);
135
- console.log('Current expression:', currentExpression);
136
- console.log('Evaluation results:', evaluationResults);
137
- console.log('Operators list length:', operatorsList.length);
138
-
139
- // Check API config status
140
- checkApiConfigStatus();
141
-
142
- // Load saved state
143
- if (researchTarget) {
144
- targetText.textContent = researchTarget;
145
- }
146
-
147
- if (currentExpression) {
148
- currentExpressionInput.value = currentExpression;
149
- }
150
-
151
- if (expressionContext) {
152
- expressionContextInput.value = expressionContext;
153
- }
154
-
155
- // Check for operators in sessionStorage (from brain.js)
156
- refreshOperatorsFromSessionStorage();
157
-
158
- // Update operator count display
159
- currentBatchSizeSpan.textContent = operatorsList.length;
160
-
161
- // Load operators if not already loaded
162
- if (operatorsList.length === 0) {
163
- loadOperatorsFromBRAIN();
164
- }
165
-
166
- // Add a fallback message if no operators are available
167
- if (operatorsList.length === 0) {
168
- console.log('No operators loaded yet. Will load when BRAIN is connected.');
169
- }
170
-
171
- // Display existing results
172
- if (evaluationResults.length > 0) {
173
- displayEvaluationResults();
174
- updateSummaryStats();
175
- }
176
-
177
- // Setup filter event listeners
178
- setupFilters();
179
- });
180
-
181
- // Function to refresh operators from sessionStorage (called after BRAIN login)
182
- function refreshOperatorsFromSessionStorage() {
183
- const storedOperators = sessionStorage.getItem('brainOperators');
184
- if (storedOperators) {
185
- try {
186
- operatorsList = JSON.parse(storedOperators);
187
- currentBatchSizeSpan.textContent = operatorsList.length;
188
- console.log(`Refreshed ${operatorsList.length} operators from sessionStorage`);
189
- } catch (error) {
190
- console.error('Error parsing operators from sessionStorage:', error);
191
- }
192
- }
193
- }
194
-
195
- // Save API Key and Test Connection
196
- saveApiKeyBtn.addEventListener('click', async () => {
197
- const newApiKey = apiKeyInput.value.trim();
198
- const newProvider = modelProviderSelect.value;
199
- const newModelName = modelNameInput.value.trim();
200
-
201
- if (!newApiKey) {
202
- showNotification('Please enter a valid API key', 'error');
203
- return;
204
- }
205
-
206
- if (!newModelName) {
207
- showNotification('Please enter a model name', 'error');
208
- return;
209
- }
210
-
211
- try {
212
- showLoading('Testing API connection...');
213
-
214
- const response = await fetch('/inspiration-house/api/test-deepseek', {
215
- method: 'POST',
216
- headers: {
217
- 'X-API-Key': newApiKey,
218
- 'Content-Type': 'application/json'
219
- },
220
- body: JSON.stringify({
221
- provider: newProvider,
222
- model_name: newModelName
223
- })
224
- });
225
-
226
- const data = await response.json();
227
-
228
- if (response.ok && data.success) {
229
- sessionStorage.setItem('deepseekApiKey', newApiKey);
230
- sessionStorage.setItem('inspirationHouseProvider', newProvider);
231
- sessionStorage.setItem('inspirationHouseModelName', newModelName);
232
- apiKey = newApiKey;
233
- modelProvider = newProvider;
234
- modelName = newModelName;
235
- showNotification(`${newProvider.charAt(0).toUpperCase() + newProvider.slice(1)} API connection successful`, 'success');
236
-
237
- // Hide API config section after successful configuration
238
- apiConfigSection.style.display = 'none';
239
- showApiConfigSection.style.display = 'block';
240
- } else {
241
- showNotification(`API Error: ${data.error || 'Unknown error'}`, 'error');
242
- console.error('API Error Details:', data);
243
-
244
- // Provide specific guidance for Kimi API issues
245
- if (newProvider === 'kimi' && data.error) {
246
- console.log('Kimi API troubleshooting tips:');
247
- console.log('1. Make sure you have a valid Kimi API key');
248
- console.log('2. Check if your Kimi account has API access enabled');
249
- console.log('3. Verify the model name is correct (e.g., kimi-k2-0711-preview)');
250
- console.log('4. Ensure you have sufficient API credits/quota');
251
- }
252
- }
253
- } catch (error) {
254
- showNotification('Error testing API connection: ' + error.message, 'error');
255
- console.error('API Test Error:', error);
256
- } finally {
257
- hideLoading();
258
- }
259
- });
260
-
261
- // Target Management
262
- editTargetBtn.addEventListener('click', () => {
263
- targetDisplay.style.display = 'none';
264
- targetInputGroup.style.display = 'block';
265
- researchTargetInput.value = researchTarget;
266
- researchTargetInput.focus();
267
- });
268
-
269
- saveTargetBtn.addEventListener('click', () => {
270
- const newTarget = researchTargetInput.value.trim();
271
- if (!newTarget) {
272
- showNotification('Please enter a research target', 'error');
273
- return;
274
- }
275
-
276
- researchTarget = newTarget;
277
- targetText.textContent = researchTarget;
278
- sessionStorage.setItem('inspirationHouseTarget', researchTarget);
279
-
280
- targetDisplay.style.display = 'block';
281
- targetInputGroup.style.display = 'none';
282
-
283
- showNotification('Research target saved successfully', 'success');
284
- });
285
-
286
- cancelTargetBtn.addEventListener('click', () => {
287
- targetDisplay.style.display = 'block';
288
- targetInputGroup.style.display = 'none';
289
- researchTargetInput.value = researchTarget;
290
- });
291
-
292
- // Expression Management
293
- currentExpressionInput.addEventListener('input', () => {
294
- currentExpression = currentExpressionInput.value;
295
- sessionStorage.setItem('inspirationHouseExpression', currentExpression);
296
- });
297
-
298
- expressionContextInput.addEventListener('input', () => {
299
- expressionContext = expressionContextInput.value;
300
- sessionStorage.setItem('inspirationHouseContext', expressionContext);
301
- });
302
-
303
- // Load from BRAIN
304
- loadFromBRAINBtn.addEventListener('click', () => {
305
- if (!sessionStorage.getItem('brain_session_id')) {
306
- // Use the same login modal as the main page
307
- if (window.brainAPI && window.brainAPI.openBrainLoginModal) {
308
- window.brainAPI.openBrainLoginModal();
309
- } else {
310
- showNotification('BRAIN login not available. Please go to the main page to connect to BRAIN.', 'error');
311
- return;
312
- }
313
-
314
- // Set up a listener for when operators are loaded (after successful login)
315
- const checkOperatorsInterval = setInterval(() => {
316
- const storedOperators = sessionStorage.getItem('brainOperators');
317
- if (storedOperators) {
318
- clearInterval(checkOperatorsInterval);
319
- refreshOperatorsFromSessionStorage();
320
- showNotification(`Loaded ${operatorsList.length} operators from BRAIN`, 'success');
321
- }
322
- }, 1000);
323
-
324
- // Stop checking after 30 seconds
325
- setTimeout(() => {
326
- clearInterval(checkOperatorsInterval);
327
- }, 30000);
328
- } else {
329
- // Load current expression from BRAIN (placeholder for now)
330
- showNotification('Loading from BRAIN...', 'warning');
331
- // TODO: Implement BRAIN expression loading
332
- }
333
- });
334
-
335
- // Start AI Evaluation
336
- startEvaluationBtn.addEventListener('click', async () => {
337
- if (!apiKey) {
338
- showNotification('Please configure your Deepseek API key first', 'error');
339
- return;
340
- }
341
-
342
- if (!researchTarget) {
343
- showNotification('Please set a research target first', 'error');
344
- return;
345
- }
346
-
347
- if (!currentExpression) {
348
- showNotification('Please enter your current expression', 'error');
349
- return;
350
- }
351
-
352
- if (operatorsList.length === 0) {
353
- showNotification('No operators available. Please connect to BRAIN first to load operators.', 'warning');
354
- return;
355
- }
356
-
357
- if (isEvaluating) {
358
- showNotification('Evaluation already in progress', 'warning');
359
- return;
360
- }
361
-
362
- try {
363
- isEvaluating = true;
364
- startEvaluationBtn.disabled = true;
365
- startEvaluationBtn.textContent = 'Evaluating...';
366
-
367
- showProgressSection();
368
- evaluationResults = [];
369
-
370
- // Update progress to show batch processing
371
- progressText.textContent = `Evaluating ${totalOperators} operators with batch size ${batchSize}...`;
372
- progressCount.textContent = `0 / ${totalOperators}`;
373
- progressFill.style.width = '0%';
374
- progressFill.textContent = 'Starting...';
375
-
376
- await evaluateAllOperators();
377
-
378
- // Update progress to show completion
379
- progressFill.style.width = '100%';
380
- progressFill.textContent = '100%';
381
- progressCount.textContent = `${totalOperators} / ${totalOperators}`;
382
- progressText.textContent = 'Evaluation completed!';
383
-
384
- showNotification('Evaluation completed successfully', 'success');
385
- } catch (error) {
386
- showNotification('Error during evaluation: ' + error.message, 'error');
387
- console.error('Evaluation Error:', error);
388
- } finally {
389
- isEvaluating = false;
390
- startEvaluationBtn.disabled = false;
391
- startEvaluationBtn.textContent = 'Start AI Evaluation';
392
- hideProgressSection();
393
- }
394
- });
395
-
396
- // Evaluate all operators using multithreading
397
- async function evaluateAllOperators() {
398
- totalOperators = operatorsList.length;
399
- evaluationProgress = 0;
400
-
401
- console.log(`Starting evaluation of ${totalOperators} operators with ${totalOperators} workers...`);
402
-
403
- // Use the new batch evaluation endpoint for better performance
404
- try {
405
- const response = await fetch('/inspiration-house/api/batch-evaluate', {
406
- method: 'POST',
407
- headers: {
408
- 'X-API-Key': apiKey,
409
- 'Content-Type': 'application/json'
410
- },
411
- body: JSON.stringify({
412
- operators: operatorsList,
413
- research_target: researchTarget,
414
- current_expression: currentExpression,
415
- expression_context: expressionContext,
416
- batch_size: batchSize,
417
- provider: modelProvider,
418
- model_name: modelName
419
- })
420
- });
421
-
422
- const data = await response.json();
423
-
424
- if (response.ok && data.success) {
425
- evaluationResults = data.results;
426
- console.log(`Batch evaluation completed. Processed ${evaluationResults.length} operators with ${data.workers_used} workers`);
427
- showNotification(`Evaluation completed! Processed ${evaluationResults.length} operators using ${data.workers_used} parallel workers`, 'success');
428
- } else {
429
- console.error('Batch evaluation failed:', data.error);
430
- showNotification(`Evaluation failed: ${data.error}`, 'error');
431
- return;
432
- }
433
- } catch (error) {
434
- console.error('Error in batch evaluation:', error);
435
- showNotification(`Evaluation error: ${error.message}`, 'error');
436
- return;
437
- }
438
-
439
- // Save results
440
- saveEvaluationResults();
441
-
442
- // Display results
443
- displayEvaluationResults();
444
- updateSummaryStats();
445
-
446
- console.log(`Evaluation completed. Processed ${evaluationResults.length} operators.`);
447
- }
448
-
449
- // Evaluate a single operator
450
- async function evaluateSingleOperator(operator) {
451
- try {
452
- const response = await fetch('/inspiration-house/api/evaluate-operator', {
453
- method: 'POST',
454
- headers: {
455
- 'X-API-Key': apiKey,
456
- 'Content-Type': 'application/json'
457
- },
458
- body: JSON.stringify({
459
- operator: operator,
460
- research_target: researchTarget,
461
- current_expression: currentExpression,
462
- expression_context: expressionContext,
463
- provider: modelProvider,
464
- model_name: modelName
465
- })
466
- });
467
-
468
- const data = await response.json();
469
-
470
- if (response.ok && data.success) {
471
- return {
472
- operator: operator.name,
473
- category: operator.category || 'Unknown',
474
- score: data.score,
475
- reason: data.reason,
476
- timestamp: new Date().toISOString()
477
- };
478
- } else {
479
- console.error(`API Error for operator ${operator.name}:`, data.error);
480
- return {
481
- operator: operator.name,
482
- category: operator.category || 'Unknown',
483
- score: 0,
484
- reason: `Error: ${data.error || 'Unknown error'}`,
485
- timestamp: new Date().toISOString()
486
- };
487
- }
488
- } catch (error) {
489
- console.error(`Network error for operator ${operator.name}:`, error);
490
- return {
491
- operator: operator.name,
492
- category: operator.category || 'Unknown',
493
- score: 0,
494
- reason: `Network error: ${error.message}`,
495
- timestamp: new Date().toISOString()
496
- };
497
- }
498
- }
499
-
500
- // Load operators from BRAIN
501
- async function loadOperatorsFromBRAIN() {
502
- try {
503
- const response = await fetch('/api/operators');
504
- const data = await response.json();
505
-
506
- if (response.ok && Array.isArray(data)) {
507
- operatorsList = data;
508
- sessionStorage.setItem('brainOperators', JSON.stringify(operatorsList));
509
- currentBatchSizeSpan.textContent = operatorsList.length;
510
- console.log(`Loaded ${operatorsList.length} operators from BRAIN`);
511
- showNotification(`Loaded ${operatorsList.length} operators from BRAIN`, 'success');
512
- } else {
513
- console.error('Failed to load operators:', data.error);
514
- if (data.error && data.error.includes('Invalid or expired session')) {
515
- showNotification('Please connect to BRAIN first to load operators', 'warning');
516
- } else {
517
- showNotification('Failed to load operators from BRAIN', 'error');
518
- }
519
- }
520
- } catch (error) {
521
- console.error('Error loading operators:', error);
522
- showNotification('Error connecting to BRAIN API', 'error');
523
- }
524
- }
525
-
526
- // Convert markdown to HTML for better display
527
- function convertMarkdownToHTML(text) {
528
- if (!text) return '';
529
-
530
- return text
531
- // Bold text: **text** -> <strong>text</strong>
532
- .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
533
- // Italic text: *text* -> <em>text</em>
534
- .replace(/\*(.*?)\*/g, '<em>$1</em>')
535
- // Code: `text` -> <code>text</code>
536
- .replace(/`(.*?)`/g, '<code>$1</code>')
537
- // Headers: ### text -> <h4>text</h4>
538
- .replace(/^### (.+)$/gm, '<h4>$1</h4>')
539
- .replace(/^## (.+)$/gm, '<h3>$1</h3>')
540
- .replace(/^# (.+)$/gm, '<h2>$1</h2>')
541
- // Lists: - item -> <li>item</li>
542
- .replace(/^- (.+)$/gm, '<li>$1</li>')
543
- // Numbered lists: 1. item -> <li>item</li>
544
- .replace(/^(\d+)\. (.+)$/gm, '<li>$2</li>')
545
- // Line breaks: \n -> <br>
546
- .replace(/\n/g, '<br>')
547
- // Escape HTML characters
548
- .replace(/&/g, '&amp;')
549
- .replace(/</g, '&lt;')
550
- .replace(/>/g, '&gt;')
551
- // Restore our HTML tags
552
- .replace(/&lt;strong&gt;/g, '<strong>')
553
- .replace(/&lt;\/strong&gt;/g, '</strong>')
554
- .replace(/&lt;em&gt;/g, '<em>')
555
- .replace(/&lt;\/em&gt;/g, '</em>')
556
- .replace(/&lt;code&gt;/g, '<code>')
557
- .replace(/&lt;\/code&gt;/g, '</code>')
558
- .replace(/&lt;br&gt;/g, '<br>')
559
- .replace(/&lt;h[234]&gt;/g, '<$1>')
560
- .replace(/&lt;\/h[234]&gt;/g, '</$1>')
561
- .replace(/&lt;li&gt;/g, '<li>')
562
- .replace(/&lt;\/li&gt;/g, '</li>');
563
- }
564
-
565
- // Display evaluation results
566
- function displayEvaluationResults() {
567
- if (evaluationResults.length === 0) {
568
- evaluationTableBody.innerHTML = `
569
- <tr>
570
- <td colspan="5" style="text-align: center; color: #7f8c8d; font-style: italic; padding: 40px;">
571
- No evaluations yet. Set your target and expression, then click "Start AI Evaluation".
572
- </td>
573
- </tr>
574
- `;
575
- return;
576
- }
577
-
578
- // Apply filters
579
- const filteredResults = applyFilters(evaluationResults);
580
-
581
- // Sort by score (highest first)
582
- filteredResults.sort((a, b) => b.score - a.score);
583
-
584
- evaluationTableBody.innerHTML = filteredResults.map(result => {
585
- // Find the operator details from the operators list
586
- const operatorDetails = operatorsList.find(op => op.name === result.operator);
587
- const description = operatorDetails ? operatorDetails.description || '' : '';
588
- const definition = operatorDetails ? operatorDetails.definition || '' : '';
589
-
590
- return `
591
- <tr>
592
- <td>
593
- <div class="operator-name">${result.operator}</div>
594
- <div class="operator-category">${result.category}</div>
595
- ${description ? `<div class="operator-description">${convertMarkdownToHTML(description)}</div>` : ''}
596
- ${definition ? `<div class="operator-definition"><strong>Definition:</strong> ${convertMarkdownToHTML(definition)}</div>` : ''}
597
- </td>
598
- <td>${result.category}</td>
599
- <td class="score-cell ${getScoreClass(result.score)}">${result.score}/10</td>
600
- <td>
601
- <div class="reason-text">${convertMarkdownToHTML(result.reason)}</div>
602
- </td>
603
- <td>
604
- <button class="btn btn-small" onclick="reevaluateOperator('${result.operator}')">Re-evaluate</button>
605
- </td>
606
- </tr>
607
- `;
608
- }).join('');
609
- }
610
-
611
- // Apply filters to results
612
- function applyFilters(results) {
613
- const minScore = parseInt(minScoreFilter.value);
614
- const maxScore = parseInt(maxScoreFilter.value);
615
-
616
- return results.filter(result => {
617
- const score = result.score;
618
-
619
- // Score range filter
620
- if (score < minScore || score > maxScore) {
621
- return false;
622
- }
623
-
624
- // Score category filters
625
- if (score >= 8 && !showHighScores.checked) return false;
626
- if (score >= 4 && score < 8 && !showMediumScores.checked) return false;
627
- if (score < 4 && !showLowScores.checked) return false;
628
-
629
- return true;
630
- });
631
- }
632
-
633
- // Get CSS class for score
634
- function getScoreClass(score) {
635
- if (score >= 8) return 'score-high';
636
- if (score >= 4) return 'score-medium';
637
- return 'score-low';
638
- }
639
-
640
- // Setup filter event listeners
641
- function setupFilters() {
642
- minScoreFilter.addEventListener('input', () => {
643
- minScoreValue.textContent = minScoreFilter.value;
644
- displayEvaluationResults();
645
- });
646
-
647
- maxScoreFilter.addEventListener('input', () => {
648
- maxScoreValue.textContent = maxScoreFilter.value;
649
- displayEvaluationResults();
650
- });
651
-
652
- showHighScores.addEventListener('change', displayEvaluationResults);
653
- showMediumScores.addEventListener('change', displayEvaluationResults);
654
- showLowScores.addEventListener('change', displayEvaluationResults);
655
- }
656
-
657
- // Update progress display
658
- function updateProgress() {
659
- const percentage = Math.round((evaluationProgress / totalOperators) * 100);
660
- progressFill.style.width = `${percentage}%`;
661
- progressFill.textContent = `${percentage}%`;
662
- progressCount.textContent = `${evaluationProgress} / ${totalOperators}`;
663
- progressText.textContent = `Evaluating operators with ${totalOperators} parallel workers... (${percentage}% complete)`;
664
- }
665
-
666
- // Show/hide progress section
667
- function showProgressSection() {
668
- progressSection.style.display = 'block';
669
- }
670
-
671
- function hideProgressSection() {
672
- progressSection.style.display = 'none';
673
- }
674
-
675
- // Update summary statistics
676
- function updateSummaryStats() {
677
- if (evaluationResults.length === 0) {
678
- summaryStats.style.display = 'none';
679
- return;
680
- }
681
-
682
- const highScores = evaluationResults.filter(r => r.score >= 8).length;
683
- const mediumScores = evaluationResults.filter(r => r.score >= 4 && r.score < 8).length;
684
- const lowScores = evaluationResults.filter(r => r.score < 4).length;
685
-
686
- highScoreCount.textContent = highScores;
687
- mediumScoreCount.textContent = mediumScores;
688
- lowScoreCount.textContent = lowScores;
689
- totalEvaluated.textContent = evaluationResults.length;
690
-
691
- summaryStats.style.display = 'grid';
692
- }
693
-
694
- // Save evaluation results
695
- function saveEvaluationResults() {
696
- sessionStorage.setItem('inspirationHouseResults', JSON.stringify(evaluationResults));
697
- }
698
-
699
- // Refresh evaluation results
700
- refreshEvaluationBtn.addEventListener('click', () => {
701
- displayEvaluationResults();
702
- updateSummaryStats();
703
- });
704
-
705
- // Clear results
706
- clearResultsBtn.addEventListener('click', () => {
707
- if (confirm('Are you sure you want to clear all evaluation results?')) {
708
- evaluationResults = [];
709
- sessionStorage.removeItem('inspirationHouseResults');
710
- displayEvaluationResults();
711
- updateSummaryStats();
712
- showNotification('Results cleared', 'success');
713
- }
714
- });
715
-
716
- // Export functions
717
- exportResultsBtn.addEventListener('click', () => {
718
- exportResults('all');
719
- });
720
-
721
- exportHighScoresBtn.addEventListener('click', () => {
722
- exportResults('high');
723
- });
724
-
725
- exportAllResultsBtn.addEventListener('click', () => {
726
- exportResults('all');
727
- });
728
-
729
- exportCSVBtn.addEventListener('click', () => {
730
- exportResults('csv');
731
- });
732
-
733
- function exportResults(type) {
734
- let dataToExport = evaluationResults;
735
-
736
- if (type === 'high') {
737
- dataToExport = evaluationResults.filter(r => r.score >= 8);
738
- }
739
-
740
- if (dataToExport.length === 0) {
741
- showNotification('No results to export', 'warning');
742
- return;
743
- }
744
-
745
- if (type === 'csv') {
746
- exportAsCSV(dataToExport);
747
- } else {
748
- exportAsJSON(dataToExport);
749
- }
750
- }
751
-
752
- function exportAsJSON(data) {
753
- const exportData = {
754
- timestamp: new Date().toISOString(),
755
- research_target: researchTarget,
756
- current_expression: currentExpression,
757
- expression_context: expressionContext,
758
- results: data
759
- };
760
-
761
- const blob = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });
762
- const url = URL.createObjectURL(blob);
763
- const a = document.createElement('a');
764
- a.href = url;
765
- a.download = `inspiration_house_results_${new Date().toISOString().split('T')[0]}.json`;
766
- document.body.appendChild(a);
767
- a.click();
768
- document.body.removeChild(a);
769
- URL.revokeObjectURL(url);
770
-
771
- showNotification('Results exported as JSON', 'success');
772
- }
773
-
774
- function exportAsCSV(data) {
775
- const headers = ['Operator', 'Category', 'Score', 'Reason', 'Timestamp'];
776
- const csvContent = [
777
- headers.join(','),
778
- ...data.map(result => [
779
- `"${result.operator}"`,
780
- `"${result.category}"`,
781
- result.score,
782
- `"${result.reason.replace(/"/g, '""')}"`,
783
- `"${result.timestamp}"`
784
- ].join(','))
785
- ].join('\n');
786
-
787
- const blob = new Blob([csvContent], { type: 'text/csv' });
788
- const url = URL.createObjectURL(blob);
789
- const a = document.createElement('a');
790
- a.href = url;
791
- a.download = `inspiration_house_results_${new Date().toISOString().split('T')[0]}.csv`;
792
- document.body.appendChild(a);
793
- a.click();
794
- document.body.removeChild(a);
795
- URL.revokeObjectURL(url);
796
-
797
- showNotification('Results exported as CSV', 'success');
798
- }
799
-
800
- // Re-evaluate a single operator
801
- async function reevaluateOperator(operatorName) {
802
- const operator = operatorsList.find(op => op.name === operatorName);
803
- if (!operator) {
804
- showNotification('Operator not found', 'error');
805
- return;
806
- }
807
-
808
- try {
809
- showLoading(`Re-evaluating ${operatorName}...`);
810
-
811
- const result = await evaluateSingleOperator(operator);
812
-
813
- // Update existing result
814
- const index = evaluationResults.findIndex(r => r.operator === operatorName);
815
- if (index !== -1) {
816
- evaluationResults[index] = result;
817
- } else {
818
- evaluationResults.push(result);
819
- }
820
-
821
- saveEvaluationResults();
822
- displayEvaluationResults();
823
- updateSummaryStats();
824
-
825
- showNotification(`${operatorName} re-evaluated successfully`, 'success');
826
- } catch (error) {
827
- showNotification(`Error re-evaluating ${operatorName}: ${error.message}`, 'error');
828
- } finally {
829
- hideLoading();
830
- }
831
- }
832
-
833
- // Make function global
834
- window.reevaluateOperator = reevaluateOperator;
835
-
836
- // Utility Functions
837
- function showNotification(message, type) {
838
- const notification = document.createElement('div');
839
- notification.className = `notification ${type}`;
840
- notification.textContent = message;
841
- document.body.appendChild(notification);
842
-
843
- setTimeout(() => {
844
- notification.remove();
845
- }, 8000);
846
- }
847
-
848
- let loadingElement = null;
849
-
850
- function showLoading(message) {
851
- loadingElement = document.createElement('div');
852
- loadingElement.className = 'loading-overlay';
853
- loadingElement.innerHTML = `
854
- <div class="loading-spinner"></div>
855
- <div class="loading-message">${message}</div>
856
- `;
857
- document.body.appendChild(loadingElement);
858
- }
859
-
860
- function hideLoading() {
861
- if (loadingElement) {
862
- loadingElement.remove();
863
- loadingElement = null;
864
- }
865
- }
866
-
867
- // BRAIN Login Modal Functions are now handled by brain.js
868
- // The modal and authentication functions are accessed via window.brainAPI