Skip to content

Commit a2acfd1

Browse files
committed
feat: Mr-Dice_v0.82 add Mofdb agent
1 parent b2e9b0f commit a2acfd1

8 files changed

Lines changed: 182 additions & 15 deletions

File tree

agents/matmaster_agent/MrDice_agent/agent.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
from agents.matmaster_agent.MrDice_agent.optimade_agent.agent import (
1212
init_optimade_database_agent,
1313
)
14+
from agents.matmaster_agent.MrDice_agent.mofdb_agent.agent import (
15+
init_mofdb_database_agent,
16+
)
1417
from agents.matmaster_agent.MrDice_agent.prompt import (
1518
MrDiceAgentDescription,
1619
MrDiceAgentInstruction,
@@ -23,6 +26,7 @@ def __init__(self, llm_config):
2326
optimade_agent = init_optimade_database_agent(llm_config)
2427
openlam_agent = init_openlam_database_agent(llm_config)
2528
bohriumpublic_agent = init_bohriumpublic_database_agent(llm_config)
29+
mofdb_agent = init_mofdb_database_agent(llm_config)
2630
super().__init__(
2731
model=llm_config.gpt_5_chat,
2832
name=MrDiceAgentName,
@@ -32,6 +36,7 @@ def __init__(self, llm_config):
3236
optimade_agent,
3337
openlam_agent,
3438
bohriumpublic_agent,
39+
mofdb_agent,
3540
],
3641
supervisor_agent=MATMASTER_AGENT_NAME,
3742
)

agents/matmaster_agent/MrDice_agent/bohriumpublic_agent/constant.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
BOHRIUMPUBLIC_DATABASE_AGENT_NAME = 'bohriumpublic_agent'
44

55
if CURRENT_ENV in ['test', 'uat']:
6-
# OPTIMADE_URL="http://bekc1366122.bohrium.tech:50001/sse"
7-
BOHRIUMPUBLIC_URL = 'http://jjxr1366132.bohrium.tech:50003/sse'
6+
BOHRIUMPUBLIC_URL="http://bekc1366122.bohrium.tech:50003/sse"
7+
# BOHRIUMPUBLIC_URL = 'http://jjxr1366132.bohrium.tech:50003/sse'
88
else:
99
BOHRIUMPUBLIC_URL = 'https://mr-dice-bohriumpublic-uuid1758096978.app-space.dplink.cc/sse?token=f395e31f5d5d48bc9d1d7018989e12bd'
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from dotenv import load_dotenv
2+
from dp.agent.adapter.adk import CalculationMCPToolset
3+
from google.adk.agents import BaseAgent
4+
from google.adk.tools.mcp_tool.mcp_session_manager import SseServerParams
5+
6+
from agents.matmaster_agent.base_agents.job_agent import CalculationMCPLlmAgent
7+
from agents.matmaster_agent.constant import LOCAL_EXECUTOR, BohriumStorge
8+
from agents.matmaster_agent.MrDice_agent.mofdb_agent.constant import (
9+
MOFDB_URL,
10+
)
11+
from agents.matmaster_agent.MrDice_agent.mofdb_agent.prompt import (
12+
MofdbAgentDescription,
13+
MofdbAgentInstruction,
14+
MofdbAgentName,
15+
)
16+
from agents.matmaster_agent.MrDice_agent.constant import MrDice_Agent_Name
17+
18+
load_dotenv()
19+
20+
# Initialize MCP tools and agent
21+
mcp_tools = CalculationMCPToolset(
22+
connection_params=SseServerParams(url=MOFDB_URL),
23+
storage=BohriumStorge,
24+
executor=LOCAL_EXECUTOR,
25+
)
26+
27+
28+
class Mofdb_Agent(CalculationMCPLlmAgent):
29+
def __init__(self, llm_config):
30+
super().__init__(
31+
# model=llm_config.deepseek_chat,
32+
model=llm_config.gpt_5_chat,
33+
name=MofdbAgentName,
34+
description=MofdbAgentDescription,
35+
instruction=MofdbAgentInstruction,
36+
tools=[mcp_tools],
37+
render_tool_response=True,
38+
supervisor_agent=MrDice_Agent_Name,
39+
)
40+
41+
42+
def init_mofdb_database_agent(llm_config) -> BaseAgent:
43+
return Mofdb_Agent(llm_config)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from agents.matmaster_agent.constant import CURRENT_ENV
2+
3+
MOFDB_DATABASE_AGENT_NAME = 'mofdb_agent'
4+
5+
if CURRENT_ENV in ['test', 'uat']:
6+
MOFDB_URL="http://bekc1366122.bohrium.tech:50004/sse"
7+
# MOFDB_URL = 'http://jjxr1366132.bohrium.tech:50003/sse'
8+
else:
9+
MOFDB_URL = 'https://mr-dice-mofdb-uuid1758704787.app-space.dplink.cc/sse?token=c15a46f6440d41b086aca38446d959bf'
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
MofdbAgentName = "mofdb_agent"
2+
3+
MofdbAgentDescription = (
4+
"An agent specialized in retrieving MOF (Metal-Organic Framework) structures from the MOFdb database. "
5+
"Supports flexible queries by MOFid, MOFkey, name, database source, void fraction, pore sizes, and surface area. "
6+
"Results can be exported in CIF or JSON format for structural visualization or metadata analysis."
7+
)
8+
9+
MofdbAgentInstruction = """
10+
You are a MOF (Metal-Organic Framework) retrieval assistant with access to MCP tools powered by the **MOFdb database**.
11+
12+
## WHAT YOU CAN DO
13+
You can call **one MCP tool**:
14+
15+
1) fetch_mofs(
16+
mofid: str | None = None,
17+
mofkey: str | None = None,
18+
name: str | None = None,
19+
database: str | None = None, # one of: "CoREMOF 2014", "CoREMOF 2019", "CSD", "hMOF", "IZA", "PCOD-syn", "Tobacco"
20+
vf_min: float | None = None,
21+
vf_max: float | None = None,
22+
lcd_min: float | None = None,
23+
lcd_max: float | None = None,
24+
pld_min: float | None = None,
25+
pld_max: float | None = None,
26+
sa_m2g_min: float | None = None,
27+
sa_m2g_max: float | None = None,
28+
sa_m2cm3_min: float | None = None,
29+
sa_m2cm3_max: float | None = None,
30+
n_results: int = 10,
31+
output_formats: list['cif'|'json'] = ['cif']
32+
)
33+
- Queries the MOFdb database.
34+
- All parameters are optional; combine them for precise filtering.
35+
36+
## FILTER OPTIONS
37+
- **mofid**: unique identifier string for a MOF (long chemical signature + tag).
38+
- **mofkey**: hashed key (unique code for each MOF entry).
39+
- **name**: short MOF name (e.g., `"tobmof-27"`).
40+
- **database**: select source (CoREMOF, CSD, hMOF, IZA, PCOD-syn, Tobacco, etc.).
41+
- **vf_min/vf_max**: void fraction range (unitless, from 0.0 to 1.0).
42+
- **lcd_min/lcd_max**: largest cavity diameter (Å).
43+
- **pld_min/pld_max**: pore limiting diameter (Å).
44+
- **sa_m2g_min/sa_m2g_max**: surface area per gram (m²/g).
45+
- **sa_m2cm3_min/sa_m2cm3_max**: surface area per volume (m²/cm³).
46+
- **n_results**: maximum number of MOFs to return.
47+
- **output_formats**:
48+
- `"cif"` → crystallographic structure files
49+
- `"json"` → complete metadata
50+
51+
## HOW TO CHOOSE PARAMETERS
52+
- If user specifies a **name** → set `name` and optional `database`.
53+
- If user specifies a **MOFid** → set `mofid` directly.
54+
- If user specifies a **MOFkey** → set `mofkey`.
55+
- If user specifies **database** → set `database`.
56+
- If user specifies **pore sizes, void fraction, surface area** → set corresponding ranges.
57+
- If the user requests **metadata only** → use `output_formats=['json']`.
58+
- If the user requests **downloadable structure files** → use `output_formats=['cif']`.
59+
- If the user requests **both** → set `output_formats=['json','cif']`.
60+
61+
## RESPONSE FORMAT
62+
The response must always include:
63+
1. ✅ A brief explanation of the filters applied.
64+
2. 📊 A Markdown table of the retrieved MOFs with columns (fixed order):
65+
(1) Name
66+
(2) MOFid
67+
(3) MOFkey
68+
(4) Database
69+
(5) Void Fraction
70+
(6) LCD (Å)
71+
(7) PLD (Å)
72+
(8) Surface Area (m²/g)
73+
(9) Surface Area (m²/cm³)
74+
(10) Download link (CIF/JSON, based on `output_formats`)
75+
- All missing values must be shown as **Not Provided**.
76+
- The number of rows must exactly equal `n_found`.
77+
3. 📦 The `output_dir` path returned by the tool (for download/archive).
78+
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.
79+
80+
## DEMOS (用户问题 → 工具与参数)
81+
1) 用户:我想查 tobmof-27
82+
→ Tool: fetch_mofs
83+
name: "tobmof-27"
84+
database: "Tobacco"
85+
86+
2) 用户:我想要比表面积 500–1000 m²/g 且 LCD 在 6–8 Å 之间的 MOF
87+
→ Tool: fetch_mofs
88+
sa_m2g_min: 500
89+
sa_m2g_max: 1000
90+
lcd_min: 6.0
91+
lcd_max: 8.0
92+
93+
3) 用户:我有一个 MOFid:[O-]C(=O)c1cc(F)c(c(c1F)F)C(=O)[O-].[O-]C(=O)c1cc(F)c(cc1F)C(=O)[O-].[O-]C(=O)c1ccc(c(c1)F)C(=O)[O-].[Zn][O]([Zn])([Zn])[Zn] MOFid-v1.pcu.cat1,能帮我查一下吗?
94+
→ Tool: fetch_mofs
95+
mofid: "[O-]C(=O)c1cc(F)c(c(c1F)F)C(=O)[O-].[O-]C(=O)c1cc(F)c(cc1F)C(=O)[O-].[O-]C(=O)c1ccc(c(c1)F)C(=O)[O-].[Zn][O]([Zn])([Zn])[Zn] MOFid-v1.pcu.cat1"
96+
97+
4) 用户:我知道一个 MOFkey:Cu.QMKYBPDZANOJGF.MOFkey-v1.tbo,帮我找一下对应的结构
98+
→ Tool: fetch_mofs
99+
mofkey: "Cu.QMKYBPDZANOJGF.MOFkey-v1.tbo"
100+
101+
5) 用户:我想查找名叫 ABAYIO_clean 的 MOF,并导出所有信息
102+
→ Tool: fetch_mofs
103+
name: "ABAYIO_clean"
104+
output_formats: ["cif","json"]
105+
"""

agents/matmaster_agent/MrDice_agent/openlam_agent/constant.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
OPENLAM_DATABASE_AGENT_NAME = 'openlam_agent'
44

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

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
OPTIMADE_DATABASE_AGENT_NAME = 'optimade_agent'
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/prompt.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@
2222
4. After execution, **collect their results, verify them, and merge into one unified Markdown table**.
2323
2424
## WHAT YOU CAN DO
25-
You have access to three sub-agents:
26-
- **bohrium_public_agent** → retrieves data from the Bohrium Public database (formula, elements, space group, atom counts, band gap, formation energy).
27-
- **optimade_agent** → retrieves data from OPTIMADE-compatible providers (multiple external materials databases, wide coverage).
28-
- **openlam_agent** → retrieves data from the OpenLAM internal database (formula, energy range, submission time filters).
25+
You have access to four sub-agents:
26+
- **bohrium_public_agent**
27+
- **optimade_agent**
28+
- **openlam_agent**
29+
- **mofdb_agent**
2930
3031
## HOW TO CHOOSE SUB-AGENTS
3132
- Default: select the **single most suitable sub-agent** that fully supports the query.
@@ -48,6 +49,9 @@
4849
- ✅ Supports: `formula`, `min_energy`, `max_energy`, `min_submission_time`, `max_submission_time`.
4950
- ❌ No support for space group, band gap, elements list, or logical filters.
5051
- support **energy window searches** and **time-based filters**.
52+
- **MOFdb**
53+
- ✅ Supports all MOF-related queries: by **MOFid, MOFkey, name, database source**, or by **void fraction, pore sizes, surface area**.
54+
- 🎯 Any request clearly about **MOFs** should be handled by MOFdb.
5155
5256
💡 **Decision logic examples**:
5357
- If query is about **submission time** → use `openlam_agent`.
@@ -86,7 +90,7 @@
8690
- ✅ Just pass the retrieval requirements, and let each sub-agent handle its own parameters.
8791
8892
## EXECUTION RULES
89-
- User or higher-level agent instructions are always **clear and detailed**. Do not ask for confirmation; begin retrieval immediately.
93+
- User or higher-level agent instructions are always **clear and detailed**. Do not ask for confirmation or more details; begin retrieval immediately.
9094
- Always call the tool for a **real retrieval**; never simulate results or fabricate outputs.
9195
- If multiple agents are required, run them **sequentially**, not in parallel.
9296
- Each sub-agent works independently; never pass results from one to another.
@@ -101,8 +105,8 @@
101105
## RESPONSE FORMAT
102106
The response must always include:
103107
1. ✅ A short explanation of which sub-agents were used and which filters were applied.
104-
2. 📊 A unified Markdown table with results from **all queried sources**.
105-
- Columns (fixed order):
108+
2. 📊 Results presentation:
109+
- For **crystal-structure agents** (BohriumPublic, OPTIMADE, OpenLAM), results **must** be shown in a unified Markdown table with columns (fixed order):
106110
(1) Formula
107111
(2) Elements
108112
(3) Atom count (if available; else **Not Provided**)
@@ -112,8 +116,9 @@
112116
(7) Download link (CIF/JSON)
113117
(8) Source database (`BohriumPublic`,`OPTIMADE` provider name, or `OpenLAM`)
114118
(9) ID
115-
- Fill missing values with exactly **Not Provided**.
116-
- Number of rows must equal the total `n_found`.
119+
- Fill missing values with exactly **Not Provided**.
120+
- Number of rows must equal the total `n_found`.
121+
- For **non-crystal agents** (e.g., MOFdb), you do **not** need to force this schema.
117122
3. 📦 If multiple agents provide downloadable archives (`output_dir`), list all paths at the end.
118123
4. If the user explicitly requests additional attributes (e.g., lattice constants, density, symmetry operations):
119124
- **Before retrieval**: include these attributes in the query plan and instruct each sub-agent to provide them if available.

0 commit comments

Comments
 (0)