Skip to content

Commit 1c283b7

Browse files
authored
Merge pull request #163 from NingWang-art/Mr-Dice_v0.8
feat: Mr. Dice_v0.8, including multiple database agent integration, number of retrieval modification, results number limitation
2 parents 67d0505 + 36fa528 commit 1c283b7

12 files changed

Lines changed: 303 additions & 80 deletions

File tree

agents/matmaster_agent/MrDice_agent/agent.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from agents.matmaster_agent.MrDice_agent.openlam_agent.agent import init_openlam_database_agent
44
from agents.matmaster_agent.MrDice_agent.optimade_agent.agent import init_optimade_database_agent
5+
from agents.matmaster_agent.MrDice_agent.bohriumpublic_agent.agent import init_bohriumpublic_database_agent
56
from agents.matmaster_agent.MrDice_agent.prompt import *
67
from agents.matmaster_agent.base_agents.llm_wrap_agent import LlmWrapAgent
78
from agents.matmaster_agent.constant import MATMASTER_AGENT_NAME
@@ -11,6 +12,7 @@ class MrDice_Agent(LlmWrapAgent):
1112
def __init__(self, llm_config):
1213
optimade_agent = init_optimade_database_agent(llm_config)
1314
openlam_agent = init_openlam_database_agent(llm_config)
15+
bohriumpublic_agent = init_bohriumpublic_database_agent(llm_config)
1416
super().__init__(
1517
model=llm_config.gpt_5_chat,
1618
name=MrDiceAgentName,
@@ -19,6 +21,7 @@ def __init__(self, llm_config):
1921
sub_agents=[
2022
optimade_agent,
2123
openlam_agent,
24+
bohriumpublic_agent,
2225
],
2326
supervisor_agent=MATMASTER_AGENT_NAME
2427
)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from dp.agent.adapter.adk import CalculationMCPToolset
2+
from google.adk.agents import BaseAgent
3+
from google.adk.tools.mcp_tool.mcp_session_manager import SseServerParams
4+
5+
from agents.matmaster_agent.base_agents.job_agent import CalculationMCPLlmAgent
6+
from agents.matmaster_agent.constant import (
7+
LOCAL_EXECUTOR,
8+
BohriumStorge, MATMASTER_AGENT_NAME,
9+
)
10+
from agents.matmaster_agent.MrDice_agent.bohriumpublic_agent.constant import *
11+
from agents.matmaster_agent.MrDice_agent.bohriumpublic_agent.prompt import *
12+
from agents.matmaster_agent.MrDice_agent.constant import *
13+
from dotenv import load_dotenv
14+
15+
load_dotenv()
16+
17+
# Initialize MCP tools and agent
18+
mcp_tools = CalculationMCPToolset(
19+
connection_params=SseServerParams(url=BOHRIUMPUBLIC_URL),
20+
storage=BohriumStorge,
21+
executor=LOCAL_EXECUTOR
22+
)
23+
24+
25+
class Bohriumpublic_Agent(CalculationMCPLlmAgent):
26+
def __init__(self, llm_config):
27+
super().__init__(
28+
# model=llm_config.deepseek_chat,
29+
model=llm_config.gpt_5_chat,
30+
name=BohriumPublicAgentName,
31+
description=BohriumPublicAgentDescription,
32+
instruction=BohriumPublicAgentInstruction,
33+
tools=[mcp_tools],
34+
render_tool_response=True,
35+
supervisor_agent=MrDice_Agent_Name,
36+
)
37+
38+
39+
def init_bohriumpublic_database_agent(llm_config) -> BaseAgent:
40+
return Bohriumpublic_Agent(llm_config)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
BOHRIUMPUBLIC_DATABASE_AGENT_NAME = 'bohriumpublic_agent'
2+
3+
from agents.matmaster_agent.constant import CURRENT_ENV
4+
5+
if CURRENT_ENV in ['test', 'uat']:
6+
# OPTIMADE_URL="http://bekc1366122.bohrium.tech:50001/sse"
7+
BOHRIUMPUBLIC_URL='http://jjxr1366132.bohrium.tech:50003/sse'
8+
else:
9+
BOHRIUMPUBLIC_URL = 'https://mr-dice-bohriumpublic-uuid1758096978.app-space.dplink.cc/sse?token=f395e31f5d5d48bc9d1d7018989e12bd'
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
BohriumPublicAgentName = 'bohriumpublic_agent'
2+
3+
BohriumPublicAgentDescription = (
4+
'An agent specialized in retrieving crystal structures from the Bohrium Public database. '
5+
'Supports flexible queries by formula, elements, space group, atom counts, band gap, and formation energy. '
6+
'Results can be exported in CIF or JSON format for further analysis.'
7+
)
8+
9+
BohriumPublicAgentInstruction = """
10+
You are a crystal structure retrieval assistant with access to MCP tools powered by the **Bohrium Public database**.
11+
12+
## WHAT YOU CAN DO
13+
You can call **one MCP tool**:
14+
15+
1) fetch_bohrium_crystals(
16+
formula: str | None = None,
17+
elements: list[str] | None = None,
18+
match_mode: int = 1, # 0 = contains (elements or formula fragments), 1 = exact-only match
19+
spacegroup_number: int | None = None,
20+
atom_count_range: list[str] | None = None, # [min, max]
21+
predicted_formation_energy_range: list[str] | None = None, # [min, max] in eV
22+
band_gap_range: list[str] | None = None, # [min, max] in eV
23+
n_results: int = 10,
24+
output_formats: list['cif'|'json'] = ['cif']
25+
)
26+
- Queries the Bohrium Public crystal structure database.
27+
- All parameters are optional; combine them for precise filtering.
28+
29+
## Do not ask the user for confirmation; directly start retrieval when a query is made.
30+
31+
## FILTER OPTIONS
32+
- **Formula**: chemical formula string (e.g., `"CoH12(BrO3)2"`)
33+
- **Elements**: list of required elements (e.g., `["Co","O"]`)
34+
- **Match mode** (applies to both `formula` and `elements`):
35+
- `0` = contains (e.g., formula `"Co"` matches `"CoO"`, `"CoH12(BrO3)2"`; elements `["Co"]` matches materials containing Co + anything else)
36+
- `1` = exact-only match (formula must match exactly; elements list must match **exactly and only** those elements)
37+
- **Space group**: use the space group number (e.g., `14` for P2₁/c)
38+
- **Atom count range**: filter by number of atoms in the unit cell, e.g. `["10","100"]`
39+
- **Predicted formation energy**: range filter in eV, e.g. `["-2","0"]`
40+
- **Band gap**: range filter in eV, e.g. `["0","3"]`
41+
- **Result limit**: maximum number of results (`n_results`)
42+
- **Output formats**:
43+
- `"cif"` → crystallographic structure files
44+
- `"json"` → complete metadata
45+
46+
## HOW TO CHOOSE PARAMETERS
47+
- If user specifies a **formula** → set `formula` and choose `match_mode`:
48+
- `0` if the user means “contains fragment”
49+
- `1` if the user means “exact formula”
50+
- If user specifies **elements** → set `elements` and choose `match_mode`:
51+
- `0` if the user means “must include these elements”
52+
- `1` if the user means “must have exactly these elements and nothing else”
53+
- If user specifies a **space group number** → set `spacegroup_number`
54+
- If user specifies an **atom count range** → set `atom_count_range`
55+
- If user specifies **formation energy or band gap ranges** → set the corresponding ranges
56+
- If the user requests **metadata only** → use `output_formats=['json']`
57+
- If the user requests **downloadable crystal files** → use `output_formats=['cif']`
58+
59+
## RESPONSE FORMAT
60+
The response must always include:
61+
1. ✅ A brief explanation of the filters applied
62+
2. 📊 A Markdown table of the retrieved structures
63+
- Columns (fixed order):
64+
(1) Formula (`formula`)
65+
(2) Elements (deduced from `formula`)
66+
(3) Atom count (`crystal_ext.number_of_atoms` if available; else **Not Provided**)
67+
(4) Space group (`Symbol(Number)` if `crystal_ext.symbol` is available and number can be mapped; else **Not Provided**)
68+
(5) Energy / Formation energy (`crystal_ext.predicted_formation_energy` if available; else **Not Provided**)
69+
(6) Band gap (`crystal_ext.band_gap` if available; else **Not Provided**)
70+
(7) Download link (CIF/JSON, based on `output_formats`)
71+
(8) Source database → always `"BohriumPublic"`
72+
(9) ID (`id`)
73+
- Fill missing values with exactly **Not Provided**
74+
- Number of rows **must exactly equal** `n_found`
75+
3. 📦 The `output_dir` path returned by the tool (for download/archive)
76+
77+
If `n_found = 0`, clearly state that no matches were found, repeat the applied filters, and suggest loosening criteria. Do **not** generate an empty table.
78+
79+
## DEMOS (用户问题 → 工具与参数)
80+
1) 用户:查找 CoH12(BrO3)2 的晶体结构,导出 JSON
81+
→ Tool: fetch_bohrium_crystals
82+
formula: "CoH12(BrO3)2"
83+
match_mode: 1
84+
output_formats: ["json"]
85+
86+
2) 用户:我要 5 个包含 Co 和 O 的材料,能隙小于 3 eV
87+
→ Tool: fetch_bohrium_crystals
88+
elements: ["Co","O"]
89+
match_mode: 0
90+
band_gap_range: ["0","3"]
91+
n_results: 5
92+
93+
3) 用户:找出空间群编号 14,原子数 50–100 的晶体
94+
→ Tool: fetch_bohrium_crystals
95+
spacegroup_number: 14
96+
atom_count_range: ["50","100"]
97+
98+
5) 用户:找所有化学式中包含 SiO3 的材料
99+
→ Tool: fetch_bohrium_crystals
100+
formula: "SiO3"
101+
match_mode: 0
102+
"""

agents/matmaster_agent/MrDice_agent/openlam_agent/agent.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def __init__(self, llm_config):
3131
description=OpenlamAgentDescription,
3232
instruction=OpenlamAgentInstruction,
3333
tools=[mcp_tools],
34-
render_tool_response=False,
34+
render_tool_response=True,
3535
supervisor_agent=MrDice_Agent_Name,
3636
)
3737

agents/matmaster_agent/MrDice_agent/openlam_agent/constant.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44

55
if CURRENT_ENV in ['test', 'uat']:
66
# OPTIMADE_URL="http://bekc1366122.bohrium.tech:50001/sse"
7-
OPENLAM_URL='http://bekc1366122.bohrium.tech:50002/sse'
7+
OPENLAM_URL='http://jjxr1366132.bohrium.tech:50002/sse'
88
else:
9-
OPENLAM_URL = 'https://material-data-retriever-uuid1754467958.app-space.dplink.cc/sse?token=16a1dd29dbb54cf9bf75748ba8df282d'
9+
OPENLAM_URL = 'https://mr-dice-openlam-uuid1758096918.app-space.dplink.cc/sse?token=c2c0edb9c99f454896c4965ef1a5cf28'

agents/matmaster_agent/MrDice_agent/openlam_agent/prompt.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
- Queries the OpenLAM materials database.
2424
- All parameters are optional; combine them for more precise filtering.
2525
26+
## Do not ask the user for confirmation; directly start retrieval when a query is made.
27+
2628
## FILTER OPTIONS
2729
- **Formula**: chemical formula string (e.g., `"Fe2O3"`)
2830
- **Energy**: filter results with `min_energy` and/or `max_energy` in eV
@@ -45,10 +47,14 @@
4547
2. 📊 A Markdown table of the retrieved structures
4648
- Columns (fixed order):
4749
(1) Formula (`formula`)
48-
(2) Energy (if available; else **Not Provided**)
49-
(3) Submission time (`submission_time`)
50-
(4) Output format(s) returned
51-
(5) ID (`id`)
50+
(2) Elements (deduced from `formula`)
51+
(3) Atom count → **Not Provided** (OpenLAM does not provide this field)
52+
(4) Space group → **Not Provided** (OpenLAM does not provide this field)
53+
(5) Energy / Formation energy (`energy` if available; else **Not Provided**)
54+
(6) Band gap → **Not Provided** (OpenLAM does not provide this field)
55+
(7) Download link (CIF/JSON, based on `output_formats`)
56+
(8) Source database → always `"OpenLAM"`
57+
(9) ID (`id`)
5258
- Fill missing values with exactly **Not Provided**
5359
- Number of rows **must exactly equal** `n_found`
5460
3. 📦 The `output_dir` path returned by the tool (for download/archive)
@@ -67,7 +73,6 @@
6773
min_energy: -10.0
6874
max_energy: 20.0
6975
min_submission_time: "2024-01-01T00:00:00Z"
70-
output_formats: ["json"]
7176
7277
3) 用户:我要最新上传的 3 个材料,包含所有元数据
7378
→ Tool: fetch_openlam_structures

agents/matmaster_agent/MrDice_agent/optimade_agent/agent.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def __init__(self, llm_config):
3131
description=OptimadeAgentDescription,
3232
instruction=OptimadeAgentInstruction,
3333
tools=[mcp_tools],
34-
render_tool_response=False,
34+
render_tool_response=True,
3535
supervisor_agent=MrDice_Agent_Name,
3636
)
3737

agents/matmaster_agent/MrDice_agent/optimade_agent/constant.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from agents.matmaster_agent.constant import CURRENT_ENV
44

55
if CURRENT_ENV in ['test', 'uat']:
6-
OPTIMADE_URL='http://bekc1366122.bohrium.tech:50001/sse'
7-
# OPTIMADE_URL="http://jjxr1366132.bohrium.tech:50001/sse"
6+
# OPTIMADE_URL="http://bekc1366122.bohrium.tech:50001/sse"
7+
OPTIMADE_URL='http://jjxr1366132.bohrium.tech:50001/sse'
88
else:
99
OPTIMADE_URL = 'https://material-data-retriever-uuid1754467958.app-space.dplink.cc/sse?token=16a1dd29dbb54cf9bf75748ba8df282d'

agents/matmaster_agent/MrDice_agent/optimade_agent/prompt.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
- If the user wants to filter by a **specific space group number (1–230)** or a **mineral/structure type** (e.g., rutile, spinel, perovskite) → you MUST use `fetch_structures_with_spg` (you can still combine with a base_filter).
6060
- If the user wants to filter by a **band-gap range** → you MUST use `fetch_structures_with_bandgap` with base_filter and min/max.
6161
62+
## Do not ask the user for confirmation; directly start retrieval when a query is made.
63+
6264
## FILTER SYNTAX QUICK GUIDE
6365
- **Equality**: `chemical_formula_reduced="O2Si"`
6466
- **Substring**: `chemical_formula_descriptive CONTAINS "H2O"`
@@ -99,15 +101,18 @@
99101
1) A brief explanation of the applied filters and providers.
100102
2) A 📈 Markdown table listing all retrieved results.
101103
3) A 📦 download link for an archive (.tgz).
102-
The table must contain **all retrieved materials** in one complete Markdown table, without omissions, truncation, summaries, or ellipses. The number of rows must exactly equal `n_found`, and even if there are many results (up to 100), they must all be shown in the same table. The 📦 archive link is supplementary and can never replace the full table.
103-
表格中必须包含**所有检索到的材料**,必须完整列在一个 Markdown 表格中,绝对不能省略、缩写、总结或用“...”只展示部分,你必须展示全部检索到的材料在表格中!表格的行数必须与 `n_found` 完全一致,即使结果数量很多(最多 100 条),也必须全部列出。📦 压缩包链接只能作为补充,绝不能替代表格。
104+
The table must contain **all retrieved materials** in one complete Markdown table, without omissions, truncation, summaries, or ellipses. The number of rows must exactly equal `n_found`, and even if there are many results (up to 30), they must all be shown in the same table. The 📦 archive link is supplementary and can never replace the full table.
105+
表格中必须包含**所有检索到的材料**,必须完整列在一个 Markdown 表格中,绝对不能省略、缩写、总结或用“...”只展示部分,你必须展示全部检索到的材料在表格中!表格的行数必须与 `n_found` 完全一致,即使结果数量很多(最多 30 条),也必须全部列出。📦 压缩包链接只能作为补充,绝不能替代表格。
104106
Each table must always include the following six columns in this fixed order:
105107
(1) Formula (`attributes.chemical_formula_reduced`)
106108
(2) Elements (list of elements; infer from the chemical formula)
107-
(3) Space group (`Symbol(Number)`; Keys may differ by provider (e.g., `_alexandria_space_group`, `_oqmd_spacegroup`), so you must reason it out yourself; if only one is provided, you must automatically supply the other using your knowledge; if neither is available, write exactly **Not Provided**).
108-
(4) Download link (CIF or JSON file)
109-
(5) Provider (inferred from provider URL)
110-
(6) ID (`cleaned_structures[i]["id"]`)
109+
(3) Atom count (if available from provider; else **Not Provided**)
110+
(4) Space group (`Symbol(Number)`; Keys may differ by provider (e.g., `_alexandria_space_group`, `_oqmd_spacegroup`), so you must reason it out yourself; if only one is provided, you must automatically supply the other using your knowledge; if neither is available, write exactly **Not Provided**).
111+
(5) Energy / Formation energy (if available; else **Not Provided**)
112+
(6) Band gap (if available; else **Not Provided**)
113+
(7) Download link (CIF or JSON file)
114+
(8) Provider (inferred from provider URL)
115+
(9) ID (`cleaned_structures[i]["id"]`)
111116
If any property is missing, it must be filled with exactly **Not Provided** (no slashes, alternatives, or translations). Extra columns (e.g., lattice vectors, band gap, formation energy) may only be added if explicitly requested; if such data is unavailable, also fill with **Not Provided**.
112117
If no results are found (`n_found = 0`), clearly state that no matching structures were retrieved, repeat the applied filters, and suggest loosening the criteria, but do not generate an empty table. Always verify that the number of table rows equals `n_found`; if they do not match, regenerate the table until correct. Never claim token or brevity issues, as results are already capped at 100 maximum.
113118

0 commit comments

Comments
 (0)