deepcode-hku 1.0.7__tar.gz → 1.0.8__tar.gz
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.
- {deepcode_hku-1.0.7/deepcode_hku.egg-info → deepcode_hku-1.0.8}/PKG-INFO +26 -1
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/README.md +24 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/__init__.py +1 -1
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8/deepcode_hku.egg-info}/PKG-INFO +26 -1
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/deepcode_hku.egg-info/requires.txt +1 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/mcp_agent.config.yaml +33 -20
- deepcode_hku-1.0.8/mcp_agent.secrets.yaml +7 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/requirements.txt +1 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/utils/llm_utils.py +74 -23
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/workflows/agents/memory_agent_concise.py +51 -2
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/workflows/agents/memory_agent_concise_index.py +51 -2
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/workflows/agents/memory_agent_concise_multi.py +50 -1
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/workflows/code_implementation_workflow.py +292 -17
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/workflows/code_implementation_workflow_index.py +278 -14
- deepcode_hku-1.0.7/mcp_agent.secrets.yaml +0 -9
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/.pre-commit-config.yaml +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/LICENSE +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/MANIFEST.in +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/cli/__init__.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/cli/cli_app.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/cli/cli_interface.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/cli/cli_launcher.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/cli/main_cli.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/cli/workflows/__init__.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/cli/workflows/cli_workflow_adapter.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/deepcode.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/deepcode_hku.egg-info/SOURCES.txt +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/deepcode_hku.egg-info/dependency_links.txt +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/deepcode_hku.egg-info/entry_points.txt +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/deepcode_hku.egg-info/top_level.txt +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/prompts/code_prompts.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/schema/mcp-agent.config.schema.json +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/setup.cfg +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/setup.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/tools/__init__.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/tools/bocha_search_server.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/tools/code_implementation_server.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/tools/code_indexer.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/tools/code_reference_indexer.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/tools/command_executor.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/tools/document_segmentation_server.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/tools/git_command.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/tools/pdf_converter.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/tools/pdf_downloader.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/tools/pdf_utils.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/ui/__init__.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/ui/app.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/ui/components.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/ui/handlers.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/ui/layout.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/ui/streamlit_app.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/ui/styles.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/utils/__init__.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/utils/cli_interface.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/utils/cross_platform_file_handler.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/utils/dialogue_logger.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/utils/file_processor.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/utils/simple_llm_logger.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/workflows/__init__.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/workflows/agent_orchestration_engine.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/workflows/agents/__init__.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/workflows/agents/code_implementation_agent.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/workflows/agents/document_segmentation_agent.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/workflows/agents/requirement_analysis_agent.py +0 -0
- {deepcode_hku-1.0.7 → deepcode_hku-1.0.8}/workflows/codebase_index_workflow.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepcode-hku
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.8
|
|
4
4
|
Summary: AI Research Engine - Transform research papers into working code automatically
|
|
5
5
|
Home-page: https://github.com/HKUDS/DeepCode
|
|
6
6
|
Author: DeepCodeTeam
|
|
@@ -24,6 +24,7 @@ Requires-Dist: aiohttp>=3.8.0
|
|
|
24
24
|
Requires-Dist: anthropic
|
|
25
25
|
Requires-Dist: asyncio-mqtt
|
|
26
26
|
Requires-Dist: docling
|
|
27
|
+
Requires-Dist: google-genai
|
|
27
28
|
Requires-Dist: mcp-agent
|
|
28
29
|
Requires-Dist: mcp-server-git
|
|
29
30
|
Requires-Dist: nest_asyncio
|
|
@@ -587,6 +588,14 @@ curl -O https://raw.githubusercontent.com/HKUDS/DeepCode/main/mcp_agent.secrets.
|
|
|
587
588
|
# Edit mcp_agent.secrets.yaml with your API keys and base_url:
|
|
588
589
|
# - openai: api_key, base_url (for OpenAI/custom endpoints)
|
|
589
590
|
# - anthropic: api_key (for Claude models)
|
|
591
|
+
# - google: api_key (for Gemini models)
|
|
592
|
+
|
|
593
|
+
# 🤖 Select your preferred LLM provider (optional)
|
|
594
|
+
# Edit mcp_agent.config.yaml to choose your LLM (line ~106):
|
|
595
|
+
# - llm_provider: "google" # Use Google Gemini models
|
|
596
|
+
# - llm_provider: "anthropic" # Use Anthropic Claude models
|
|
597
|
+
# - llm_provider: "openai" # Use OpenAI/compatible models
|
|
598
|
+
# Note: If not set or unavailable, will automatically fallback to first available provider
|
|
590
599
|
|
|
591
600
|
# 🔑 Configure search API keys for web search (optional)
|
|
592
601
|
# Edit mcp_agent.config.yaml to set your API keys:
|
|
@@ -623,6 +632,14 @@ uv pip install -r requirements.txt
|
|
|
623
632
|
# Edit mcp_agent.secrets.yaml with your API keys and base_url:
|
|
624
633
|
# - openai: api_key, base_url (for OpenAI/custom endpoints)
|
|
625
634
|
# - anthropic: api_key (for Claude models)
|
|
635
|
+
# - google: api_key (for Gemini models)
|
|
636
|
+
|
|
637
|
+
# 🤖 Select your preferred LLM provider (optional)
|
|
638
|
+
# Edit mcp_agent.config.yaml to choose your LLM (line ~106):
|
|
639
|
+
# - llm_provider: "google" # Use Google Gemini models
|
|
640
|
+
# - llm_provider: "anthropic" # Use Anthropic Claude models
|
|
641
|
+
# - llm_provider: "openai" # Use OpenAI/compatible models
|
|
642
|
+
# Note: If not set or unavailable, will automatically fallback to first available provider
|
|
626
643
|
|
|
627
644
|
# 🔑 Configure search API keys for web search (optional)
|
|
628
645
|
# Edit mcp_agent.config.yaml to set your API keys:
|
|
@@ -649,6 +666,14 @@ pip install -r requirements.txt
|
|
|
649
666
|
# Edit mcp_agent.secrets.yaml with your API keys and base_url:
|
|
650
667
|
# - openai: api_key, base_url (for OpenAI/custom endpoints)
|
|
651
668
|
# - anthropic: api_key (for Claude models)
|
|
669
|
+
# - google: api_key (for Gemini models)
|
|
670
|
+
|
|
671
|
+
# 🤖 Select your preferred LLM provider (optional)
|
|
672
|
+
# Edit mcp_agent.config.yaml to choose your LLM (line ~106):
|
|
673
|
+
# - llm_provider: "google" # Use Google Gemini models
|
|
674
|
+
# - llm_provider: "anthropic" # Use Anthropic Claude models
|
|
675
|
+
# - llm_provider: "openai" # Use OpenAI/compatible models
|
|
676
|
+
# Note: If not set or unavailable, will automatically fallback to first available provider
|
|
652
677
|
|
|
653
678
|
# 🔑 Configure search API keys for web search (optional)
|
|
654
679
|
# Edit mcp_agent.config.yaml to set your API keys:
|
|
@@ -542,6 +542,14 @@ curl -O https://raw.githubusercontent.com/HKUDS/DeepCode/main/mcp_agent.secrets.
|
|
|
542
542
|
# Edit mcp_agent.secrets.yaml with your API keys and base_url:
|
|
543
543
|
# - openai: api_key, base_url (for OpenAI/custom endpoints)
|
|
544
544
|
# - anthropic: api_key (for Claude models)
|
|
545
|
+
# - google: api_key (for Gemini models)
|
|
546
|
+
|
|
547
|
+
# 🤖 Select your preferred LLM provider (optional)
|
|
548
|
+
# Edit mcp_agent.config.yaml to choose your LLM (line ~106):
|
|
549
|
+
# - llm_provider: "google" # Use Google Gemini models
|
|
550
|
+
# - llm_provider: "anthropic" # Use Anthropic Claude models
|
|
551
|
+
# - llm_provider: "openai" # Use OpenAI/compatible models
|
|
552
|
+
# Note: If not set or unavailable, will automatically fallback to first available provider
|
|
545
553
|
|
|
546
554
|
# 🔑 Configure search API keys for web search (optional)
|
|
547
555
|
# Edit mcp_agent.config.yaml to set your API keys:
|
|
@@ -578,6 +586,14 @@ uv pip install -r requirements.txt
|
|
|
578
586
|
# Edit mcp_agent.secrets.yaml with your API keys and base_url:
|
|
579
587
|
# - openai: api_key, base_url (for OpenAI/custom endpoints)
|
|
580
588
|
# - anthropic: api_key (for Claude models)
|
|
589
|
+
# - google: api_key (for Gemini models)
|
|
590
|
+
|
|
591
|
+
# 🤖 Select your preferred LLM provider (optional)
|
|
592
|
+
# Edit mcp_agent.config.yaml to choose your LLM (line ~106):
|
|
593
|
+
# - llm_provider: "google" # Use Google Gemini models
|
|
594
|
+
# - llm_provider: "anthropic" # Use Anthropic Claude models
|
|
595
|
+
# - llm_provider: "openai" # Use OpenAI/compatible models
|
|
596
|
+
# Note: If not set or unavailable, will automatically fallback to first available provider
|
|
581
597
|
|
|
582
598
|
# 🔑 Configure search API keys for web search (optional)
|
|
583
599
|
# Edit mcp_agent.config.yaml to set your API keys:
|
|
@@ -604,6 +620,14 @@ pip install -r requirements.txt
|
|
|
604
620
|
# Edit mcp_agent.secrets.yaml with your API keys and base_url:
|
|
605
621
|
# - openai: api_key, base_url (for OpenAI/custom endpoints)
|
|
606
622
|
# - anthropic: api_key (for Claude models)
|
|
623
|
+
# - google: api_key (for Gemini models)
|
|
624
|
+
|
|
625
|
+
# 🤖 Select your preferred LLM provider (optional)
|
|
626
|
+
# Edit mcp_agent.config.yaml to choose your LLM (line ~106):
|
|
627
|
+
# - llm_provider: "google" # Use Google Gemini models
|
|
628
|
+
# - llm_provider: "anthropic" # Use Anthropic Claude models
|
|
629
|
+
# - llm_provider: "openai" # Use OpenAI/compatible models
|
|
630
|
+
# Note: If not set or unavailable, will automatically fallback to first available provider
|
|
607
631
|
|
|
608
632
|
# 🔑 Configure search API keys for web search (optional)
|
|
609
633
|
# Edit mcp_agent.config.yaml to set your API keys:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepcode-hku
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.8
|
|
4
4
|
Summary: AI Research Engine - Transform research papers into working code automatically
|
|
5
5
|
Home-page: https://github.com/HKUDS/DeepCode
|
|
6
6
|
Author: DeepCodeTeam
|
|
@@ -24,6 +24,7 @@ Requires-Dist: aiohttp>=3.8.0
|
|
|
24
24
|
Requires-Dist: anthropic
|
|
25
25
|
Requires-Dist: asyncio-mqtt
|
|
26
26
|
Requires-Dist: docling
|
|
27
|
+
Requires-Dist: google-genai
|
|
27
28
|
Requires-Dist: mcp-agent
|
|
28
29
|
Requires-Dist: mcp-server-git
|
|
29
30
|
Requires-Dist: nest_asyncio
|
|
@@ -587,6 +588,14 @@ curl -O https://raw.githubusercontent.com/HKUDS/DeepCode/main/mcp_agent.secrets.
|
|
|
587
588
|
# Edit mcp_agent.secrets.yaml with your API keys and base_url:
|
|
588
589
|
# - openai: api_key, base_url (for OpenAI/custom endpoints)
|
|
589
590
|
# - anthropic: api_key (for Claude models)
|
|
591
|
+
# - google: api_key (for Gemini models)
|
|
592
|
+
|
|
593
|
+
# 🤖 Select your preferred LLM provider (optional)
|
|
594
|
+
# Edit mcp_agent.config.yaml to choose your LLM (line ~106):
|
|
595
|
+
# - llm_provider: "google" # Use Google Gemini models
|
|
596
|
+
# - llm_provider: "anthropic" # Use Anthropic Claude models
|
|
597
|
+
# - llm_provider: "openai" # Use OpenAI/compatible models
|
|
598
|
+
# Note: If not set or unavailable, will automatically fallback to first available provider
|
|
590
599
|
|
|
591
600
|
# 🔑 Configure search API keys for web search (optional)
|
|
592
601
|
# Edit mcp_agent.config.yaml to set your API keys:
|
|
@@ -623,6 +632,14 @@ uv pip install -r requirements.txt
|
|
|
623
632
|
# Edit mcp_agent.secrets.yaml with your API keys and base_url:
|
|
624
633
|
# - openai: api_key, base_url (for OpenAI/custom endpoints)
|
|
625
634
|
# - anthropic: api_key (for Claude models)
|
|
635
|
+
# - google: api_key (for Gemini models)
|
|
636
|
+
|
|
637
|
+
# 🤖 Select your preferred LLM provider (optional)
|
|
638
|
+
# Edit mcp_agent.config.yaml to choose your LLM (line ~106):
|
|
639
|
+
# - llm_provider: "google" # Use Google Gemini models
|
|
640
|
+
# - llm_provider: "anthropic" # Use Anthropic Claude models
|
|
641
|
+
# - llm_provider: "openai" # Use OpenAI/compatible models
|
|
642
|
+
# Note: If not set or unavailable, will automatically fallback to first available provider
|
|
626
643
|
|
|
627
644
|
# 🔑 Configure search API keys for web search (optional)
|
|
628
645
|
# Edit mcp_agent.config.yaml to set your API keys:
|
|
@@ -649,6 +666,14 @@ pip install -r requirements.txt
|
|
|
649
666
|
# Edit mcp_agent.secrets.yaml with your API keys and base_url:
|
|
650
667
|
# - openai: api_key, base_url (for OpenAI/custom endpoints)
|
|
651
668
|
# - anthropic: api_key (for Claude models)
|
|
669
|
+
# - google: api_key (for Gemini models)
|
|
670
|
+
|
|
671
|
+
# 🤖 Select your preferred LLM provider (optional)
|
|
672
|
+
# Edit mcp_agent.config.yaml to choose your LLM (line ~106):
|
|
673
|
+
# - llm_provider: "google" # Use Google Gemini models
|
|
674
|
+
# - llm_provider: "anthropic" # Use Anthropic Claude models
|
|
675
|
+
# - llm_provider: "openai" # Use OpenAI/compatible models
|
|
676
|
+
# Note: If not set or unavailable, will automatically fallback to first available provider
|
|
652
677
|
|
|
653
678
|
# 🔑 Configure search API keys for web search (optional)
|
|
654
679
|
# Edit mcp_agent.config.yaml to set your API keys:
|
|
@@ -26,32 +26,32 @@ mcp:
|
|
|
26
26
|
PYTHONPATH: .
|
|
27
27
|
brave:
|
|
28
28
|
# macos and linux should use this
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
args:
|
|
30
|
+
- -y
|
|
31
|
+
- '@modelcontextprotocol/server-brave-search'
|
|
32
|
+
command: npx
|
|
33
33
|
|
|
34
34
|
# windows should use this
|
|
35
|
-
args:
|
|
36
|
-
# please use the correct path for your system
|
|
37
|
-
- C:/Users/LEGION/AppData/Roaming/npm/node_modules/@modelcontextprotocol/server-brave-search/dist/index.js
|
|
38
|
-
command: node
|
|
35
|
+
# args:
|
|
36
|
+
# # please use the correct path for your system
|
|
37
|
+
# - C:/Users/LEGION/AppData/Roaming/npm/node_modules/@modelcontextprotocol/server-brave-search/dist/index.js
|
|
38
|
+
# command: node
|
|
39
39
|
env:
|
|
40
40
|
BRAVE_API_KEY: ''
|
|
41
41
|
filesystem:
|
|
42
42
|
# macos and linux should use this
|
|
43
|
-
# args:
|
|
44
|
-
# - -y
|
|
45
|
-
# - '@modelcontextprotocol/server-filesystem'
|
|
46
|
-
# - .
|
|
47
|
-
# command: npx
|
|
48
|
-
|
|
49
|
-
# windows should use this
|
|
50
43
|
args:
|
|
51
|
-
|
|
52
|
-
-
|
|
44
|
+
- -y
|
|
45
|
+
- '@modelcontextprotocol/server-filesystem'
|
|
53
46
|
- .
|
|
54
|
-
command:
|
|
47
|
+
command: npx
|
|
48
|
+
|
|
49
|
+
# windows should use this
|
|
50
|
+
# args:
|
|
51
|
+
# # please use the correct path for your system
|
|
52
|
+
# - C:/Users/LEGION/AppData/Roaming/npm/node_modules/@modelcontextprotocol/server-filesystem/dist/index.js
|
|
53
|
+
# - .
|
|
54
|
+
# command: node
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
code-implementation:
|
|
@@ -100,14 +100,27 @@ mcp:
|
|
|
100
100
|
command: python
|
|
101
101
|
env:
|
|
102
102
|
PYTHONPATH: .
|
|
103
|
+
# LLM Provider Priority (选择使用哪个LLM / Choose which LLM to use)
|
|
104
|
+
# Options: "anthropic", "google", "openai"
|
|
105
|
+
# If not set or provider unavailable, will fallback to first available provider
|
|
106
|
+
llm_provider: "google" # 设置为 "google", "anthropic", 或 "openai"
|
|
107
|
+
|
|
103
108
|
openai:
|
|
104
109
|
base_max_tokens: 40000
|
|
105
110
|
# default_model: google/gemini-2.5-pro
|
|
106
|
-
|
|
111
|
+
default_model: anthropic/claude-sonnet-4.5
|
|
107
112
|
# default_model: openai/gpt-oss-120b
|
|
108
113
|
# default_model: deepseek/deepseek-v3.2-exp
|
|
109
114
|
# default_model: moonshotai/kimi-k2-thinking
|
|
110
|
-
|
|
115
|
+
reasoning_effort: low # Only for thinking models
|
|
111
116
|
max_tokens_policy: adaptive
|
|
112
117
|
retry_max_tokens: 32768
|
|
118
|
+
|
|
119
|
+
# Configuration for Google AI (Gemini)
|
|
120
|
+
google:
|
|
121
|
+
default_model: "gemini-3-pro-preview"
|
|
122
|
+
|
|
123
|
+
anthropic:
|
|
124
|
+
default_model: "claude-sonnet-4.5"
|
|
125
|
+
|
|
113
126
|
planning_mode: traditional
|
|
@@ -12,40 +12,77 @@ from typing import Any, Type, Dict, Tuple
|
|
|
12
12
|
# Import LLM classes
|
|
13
13
|
from mcp_agent.workflows.llm.augmented_llm_anthropic import AnthropicAugmentedLLM
|
|
14
14
|
from mcp_agent.workflows.llm.augmented_llm_openai import OpenAIAugmentedLLM
|
|
15
|
+
from mcp_agent.workflows.llm.augmented_llm_google import GoogleAugmentedLLM
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
def get_preferred_llm_class(config_path: str = "mcp_agent.secrets.yaml") -> Type[Any]:
|
|
18
19
|
"""
|
|
19
|
-
|
|
20
|
+
Select the LLM class based on user preference and API key availability.
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
Priority:
|
|
23
|
+
1. Check mcp_agent.config.yaml for llm_provider preference
|
|
24
|
+
2. Verify the preferred provider has API key
|
|
25
|
+
3. Fallback to first available provider
|
|
23
26
|
|
|
24
27
|
Args:
|
|
25
|
-
config_path: Path to the YAML configuration file
|
|
28
|
+
config_path: Path to the secrets YAML configuration file
|
|
26
29
|
|
|
27
30
|
Returns:
|
|
28
31
|
class: The preferred LLM class
|
|
29
32
|
"""
|
|
30
33
|
try:
|
|
31
|
-
#
|
|
32
|
-
if os.path.exists(config_path):
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
# Read API keys from secrets file
|
|
35
|
+
if not os.path.exists(config_path):
|
|
36
|
+
print(f"🤖 Config file {config_path} not found, using OpenAIAugmentedLLM")
|
|
37
|
+
return OpenAIAugmentedLLM
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
with open(config_path, "r", encoding="utf-8") as f:
|
|
40
|
+
secrets = yaml.safe_load(f)
|
|
41
|
+
|
|
42
|
+
# Get API keys
|
|
43
|
+
anthropic_key = secrets.get("anthropic", {}).get("api_key", "").strip()
|
|
44
|
+
google_key = secrets.get("google", {}).get("api_key", "").strip()
|
|
45
|
+
openai_key = secrets.get("openai", {}).get("api_key", "").strip()
|
|
46
|
+
|
|
47
|
+
# Read user preference from main config
|
|
48
|
+
main_config_path = "mcp_agent.config.yaml"
|
|
49
|
+
preferred_provider = None
|
|
50
|
+
if os.path.exists(main_config_path):
|
|
51
|
+
with open(main_config_path, "r", encoding="utf-8") as f:
|
|
52
|
+
main_config = yaml.safe_load(f)
|
|
53
|
+
preferred_provider = main_config.get("llm_provider", "").strip().lower()
|
|
54
|
+
|
|
55
|
+
# Map of providers to their classes and keys
|
|
56
|
+
provider_map = {
|
|
57
|
+
"anthropic": (
|
|
58
|
+
AnthropicAugmentedLLM,
|
|
59
|
+
anthropic_key,
|
|
60
|
+
"AnthropicAugmentedLLM",
|
|
61
|
+
),
|
|
62
|
+
"google": (GoogleAugmentedLLM, google_key, "GoogleAugmentedLLM"),
|
|
63
|
+
"openai": (OpenAIAugmentedLLM, openai_key, "OpenAIAugmentedLLM"),
|
|
64
|
+
}
|
|
39
65
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
66
|
+
# Try user's preferred provider first
|
|
67
|
+
if preferred_provider and preferred_provider in provider_map:
|
|
68
|
+
llm_class, api_key, class_name = provider_map[preferred_provider]
|
|
69
|
+
if api_key:
|
|
70
|
+
print(f"🤖 Using {class_name} (user preference: {preferred_provider})")
|
|
71
|
+
return llm_class
|
|
43
72
|
else:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
73
|
+
print(
|
|
74
|
+
f"⚠️ Preferred provider '{preferred_provider}' has no API key, checking alternatives..."
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Fallback: try providers in order of availability
|
|
78
|
+
for provider, (llm_class, api_key, class_name) in provider_map.items():
|
|
79
|
+
if api_key:
|
|
80
|
+
print(f"🤖 Using {class_name} ({provider} API key found)")
|
|
81
|
+
return llm_class
|
|
82
|
+
|
|
83
|
+
# No API keys found
|
|
84
|
+
print("⚠️ No API keys configured, falling back to OpenAIAugmentedLLM")
|
|
85
|
+
return OpenAIAugmentedLLM
|
|
49
86
|
|
|
50
87
|
except Exception as e:
|
|
51
88
|
print(f"🤖 Error reading config file {config_path}: {e}")
|
|
@@ -101,7 +138,7 @@ def get_default_models(config_path: str = "mcp_agent.config.yaml"):
|
|
|
101
138
|
config_path: Path to the configuration file
|
|
102
139
|
|
|
103
140
|
Returns:
|
|
104
|
-
dict: Dictionary with 'anthropic' and '
|
|
141
|
+
dict: Dictionary with 'anthropic', 'openai', and 'google' default models
|
|
105
142
|
"""
|
|
106
143
|
try:
|
|
107
144
|
if os.path.exists(config_path):
|
|
@@ -111,20 +148,34 @@ def get_default_models(config_path: str = "mcp_agent.config.yaml"):
|
|
|
111
148
|
# Handle null values in config sections
|
|
112
149
|
anthropic_config = config.get("anthropic") or {}
|
|
113
150
|
openai_config = config.get("openai") or {}
|
|
151
|
+
google_config = config.get("google") or {}
|
|
114
152
|
|
|
115
153
|
anthropic_model = anthropic_config.get(
|
|
116
154
|
"default_model", "claude-sonnet-4-20250514"
|
|
117
155
|
)
|
|
118
156
|
openai_model = openai_config.get("default_model", "o3-mini")
|
|
157
|
+
google_model = google_config.get("default_model", "gemini-2.0-flash")
|
|
119
158
|
|
|
120
|
-
return {
|
|
159
|
+
return {
|
|
160
|
+
"anthropic": anthropic_model,
|
|
161
|
+
"openai": openai_model,
|
|
162
|
+
"google": google_model,
|
|
163
|
+
}
|
|
121
164
|
else:
|
|
122
165
|
print(f"Config file {config_path} not found, using default models")
|
|
123
|
-
return {
|
|
166
|
+
return {
|
|
167
|
+
"anthropic": "claude-sonnet-4-20250514",
|
|
168
|
+
"openai": "o3-mini",
|
|
169
|
+
"google": "gemini-2.0-flash",
|
|
170
|
+
}
|
|
124
171
|
|
|
125
172
|
except Exception as e:
|
|
126
173
|
print(f"❌Error reading config file {config_path}: {e}")
|
|
127
|
-
return {
|
|
174
|
+
return {
|
|
175
|
+
"anthropic": "claude-sonnet-4-20250514",
|
|
176
|
+
"openai": "o3-mini",
|
|
177
|
+
"google": "gemini-2.0-flash",
|
|
178
|
+
}
|
|
128
179
|
|
|
129
180
|
|
|
130
181
|
def get_document_segmentation_config(
|
|
@@ -63,8 +63,9 @@ class ConciseMemoryAgent:
|
|
|
63
63
|
|
|
64
64
|
# Store default models configuration
|
|
65
65
|
self.default_models = default_models or {
|
|
66
|
-
"anthropic": "
|
|
67
|
-
"openai": "
|
|
66
|
+
"anthropic": "claude-sonnet-4-20250514",
|
|
67
|
+
"openai": "o3-mini",
|
|
68
|
+
"google": "gemini-2.0-flash",
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
# Memory state tracking - new logic: trigger after each write_file
|
|
@@ -1422,6 +1423,54 @@ class ConciseMemoryAgent:
|
|
|
1422
1423
|
self.logger.warning("OpenAI response is empty or malformed")
|
|
1423
1424
|
return {"content": ""}
|
|
1424
1425
|
|
|
1426
|
+
elif client_type == "google":
|
|
1427
|
+
from google.genai import types
|
|
1428
|
+
|
|
1429
|
+
# Convert messages to Gemini format
|
|
1430
|
+
system_instruction = "You are an expert code implementation summarizer. Create structured summaries of implemented code files that preserve essential information about functions, dependencies, and implementation approaches."
|
|
1431
|
+
|
|
1432
|
+
gemini_messages = []
|
|
1433
|
+
for msg in summary_messages:
|
|
1434
|
+
role = msg.get("role", "user")
|
|
1435
|
+
content = msg.get("content", "")
|
|
1436
|
+
|
|
1437
|
+
# Convert role names: "assistant" -> "model"
|
|
1438
|
+
if role == "assistant":
|
|
1439
|
+
role = "model"
|
|
1440
|
+
elif role not in ["user", "model"]:
|
|
1441
|
+
role = "user"
|
|
1442
|
+
|
|
1443
|
+
gemini_messages.append(
|
|
1444
|
+
types.Content(role=role, parts=[types.Part.from_text(text=content)])
|
|
1445
|
+
)
|
|
1446
|
+
|
|
1447
|
+
config = types.GenerateContentConfig(
|
|
1448
|
+
max_output_tokens=5000,
|
|
1449
|
+
temperature=0.2,
|
|
1450
|
+
system_instruction=system_instruction,
|
|
1451
|
+
)
|
|
1452
|
+
|
|
1453
|
+
response = await client.aio.models.generate_content(
|
|
1454
|
+
model=self.default_models.get("google", "gemini-2.0-flash"),
|
|
1455
|
+
contents=gemini_messages,
|
|
1456
|
+
config=config,
|
|
1457
|
+
)
|
|
1458
|
+
|
|
1459
|
+
# Extract content from Gemini response
|
|
1460
|
+
content = ""
|
|
1461
|
+
if response and hasattr(response, "candidates") and response.candidates:
|
|
1462
|
+
candidate = response.candidates[0]
|
|
1463
|
+
if hasattr(candidate, "content") and candidate.content:
|
|
1464
|
+
if hasattr(candidate.content, "parts") and candidate.content.parts:
|
|
1465
|
+
for part in candidate.content.parts:
|
|
1466
|
+
if hasattr(part, "text") and part.text:
|
|
1467
|
+
content += part.text
|
|
1468
|
+
|
|
1469
|
+
if not content:
|
|
1470
|
+
self.logger.warning("Google response is empty or malformed")
|
|
1471
|
+
|
|
1472
|
+
return {"content": content}
|
|
1473
|
+
|
|
1425
1474
|
else:
|
|
1426
1475
|
raise ValueError(f"Unsupported client type: {client_type}")
|
|
1427
1476
|
|
|
@@ -63,8 +63,9 @@ class ConciseMemoryAgent:
|
|
|
63
63
|
|
|
64
64
|
# Store default models configuration
|
|
65
65
|
self.default_models = default_models or {
|
|
66
|
-
"anthropic": "
|
|
67
|
-
"openai": "
|
|
66
|
+
"anthropic": "claude-sonnet-4-20250514",
|
|
67
|
+
"openai": "o3-mini",
|
|
68
|
+
"google": "gemini-2.0-flash",
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
# Memory state tracking - new logic: trigger after each write_file
|
|
@@ -1422,6 +1423,54 @@ class ConciseMemoryAgent:
|
|
|
1422
1423
|
self.logger.warning("OpenAI response is empty or malformed")
|
|
1423
1424
|
return {"content": ""}
|
|
1424
1425
|
|
|
1426
|
+
elif client_type == "google":
|
|
1427
|
+
from google.genai import types
|
|
1428
|
+
|
|
1429
|
+
# Convert messages to Gemini format
|
|
1430
|
+
system_instruction = "You are an expert code implementation summarizer. Create structured summaries of implemented code files that preserve essential information about functions, dependencies, and implementation approaches."
|
|
1431
|
+
|
|
1432
|
+
gemini_messages = []
|
|
1433
|
+
for msg in summary_messages:
|
|
1434
|
+
role = msg.get("role", "user")
|
|
1435
|
+
content = msg.get("content", "")
|
|
1436
|
+
|
|
1437
|
+
# Convert role names: "assistant" -> "model"
|
|
1438
|
+
if role == "assistant":
|
|
1439
|
+
role = "model"
|
|
1440
|
+
elif role not in ["user", "model"]:
|
|
1441
|
+
role = "user"
|
|
1442
|
+
|
|
1443
|
+
gemini_messages.append(
|
|
1444
|
+
types.Content(role=role, parts=[types.Part.from_text(text=content)])
|
|
1445
|
+
)
|
|
1446
|
+
|
|
1447
|
+
config = types.GenerateContentConfig(
|
|
1448
|
+
max_output_tokens=5000,
|
|
1449
|
+
temperature=0.2,
|
|
1450
|
+
system_instruction=system_instruction,
|
|
1451
|
+
)
|
|
1452
|
+
|
|
1453
|
+
response = await client.aio.models.generate_content(
|
|
1454
|
+
model=self.default_models.get("google", "gemini-2.0-flash"),
|
|
1455
|
+
contents=gemini_messages,
|
|
1456
|
+
config=config,
|
|
1457
|
+
)
|
|
1458
|
+
|
|
1459
|
+
# Extract content from Gemini response
|
|
1460
|
+
content = ""
|
|
1461
|
+
if response and hasattr(response, "candidates") and response.candidates:
|
|
1462
|
+
candidate = response.candidates[0]
|
|
1463
|
+
if hasattr(candidate, "content") and candidate.content:
|
|
1464
|
+
if hasattr(candidate.content, "parts") and candidate.content.parts:
|
|
1465
|
+
for part in candidate.content.parts:
|
|
1466
|
+
if hasattr(part, "text") and part.text:
|
|
1467
|
+
content += part.text
|
|
1468
|
+
|
|
1469
|
+
if not content:
|
|
1470
|
+
self.logger.warning("Google response is empty or malformed")
|
|
1471
|
+
|
|
1472
|
+
return {"content": content}
|
|
1473
|
+
|
|
1425
1474
|
else:
|
|
1426
1475
|
raise ValueError(f"Unsupported client type: {client_type}")
|
|
1427
1476
|
|
|
@@ -70,7 +70,8 @@ class ConciseMemoryAgent:
|
|
|
70
70
|
# Store default models configuration
|
|
71
71
|
self.default_models = default_models or {
|
|
72
72
|
"anthropic": "claude-sonnet-4-20250514",
|
|
73
|
-
"openai": "
|
|
73
|
+
"openai": "o3-mini",
|
|
74
|
+
"google": "gemini-2.0-flash",
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
# Memory state tracking - new logic: trigger after each write_multiple_files
|
|
@@ -657,6 +658,54 @@ class ConciseMemoryAgent:
|
|
|
657
658
|
|
|
658
659
|
return {"content": response.choices[0].message.content or ""}
|
|
659
660
|
|
|
661
|
+
elif client_type == "google":
|
|
662
|
+
from google.genai import types
|
|
663
|
+
|
|
664
|
+
# Convert messages to Gemini format
|
|
665
|
+
system_instruction = "You are an expert code implementation summarizer. Create structured summaries of implemented code files that preserve essential information about functions, dependencies, and implementation approaches."
|
|
666
|
+
|
|
667
|
+
gemini_messages = []
|
|
668
|
+
for msg in summary_messages:
|
|
669
|
+
role = msg.get("role", "user")
|
|
670
|
+
content = msg.get("content", "")
|
|
671
|
+
|
|
672
|
+
# Convert role names: "assistant" -> "model"
|
|
673
|
+
if role == "assistant":
|
|
674
|
+
role = "model"
|
|
675
|
+
elif role not in ["user", "model"]:
|
|
676
|
+
role = "user"
|
|
677
|
+
|
|
678
|
+
gemini_messages.append(
|
|
679
|
+
types.Content(role=role, parts=[types.Part.from_text(text=content)])
|
|
680
|
+
)
|
|
681
|
+
|
|
682
|
+
config = types.GenerateContentConfig(
|
|
683
|
+
max_output_tokens=8000, # Increased for multi-file support
|
|
684
|
+
temperature=0.2,
|
|
685
|
+
system_instruction=system_instruction,
|
|
686
|
+
)
|
|
687
|
+
|
|
688
|
+
response = await client.aio.models.generate_content(
|
|
689
|
+
model=self.default_models.get("google", "gemini-2.0-flash"),
|
|
690
|
+
contents=gemini_messages,
|
|
691
|
+
config=config,
|
|
692
|
+
)
|
|
693
|
+
|
|
694
|
+
# Extract content from Gemini response
|
|
695
|
+
content = ""
|
|
696
|
+
if response and hasattr(response, "candidates") and response.candidates:
|
|
697
|
+
candidate = response.candidates[0]
|
|
698
|
+
if hasattr(candidate, "content") and candidate.content:
|
|
699
|
+
if hasattr(candidate.content, "parts") and candidate.content.parts:
|
|
700
|
+
for part in candidate.content.parts:
|
|
701
|
+
if hasattr(part, "text") and part.text:
|
|
702
|
+
content += part.text
|
|
703
|
+
|
|
704
|
+
if not content:
|
|
705
|
+
self.logger.warning("Google response is empty or malformed")
|
|
706
|
+
|
|
707
|
+
return {"content": content}
|
|
708
|
+
|
|
660
709
|
else:
|
|
661
710
|
raise ValueError(f"Unsupported client type: {client_type}")
|
|
662
711
|
|