aiagents4pharma 1.12.0__py3-none-any.whl → 1.13.1__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.
- aiagents4pharma/configs/talk2biomodels/agents/t2b_agent/default.yaml +3 -2
- aiagents4pharma/talk2biomodels/agents/t2b_agent.py +2 -0
- aiagents4pharma/talk2biomodels/states/state_talk2biomodels.py +1 -0
- aiagents4pharma/talk2biomodels/tests/test_langgraph.py +94 -12
- aiagents4pharma/talk2biomodels/tools/__init__.py +1 -0
- aiagents4pharma/talk2biomodels/tools/ask_question.py +32 -19
- aiagents4pharma/talk2biomodels/tools/steady_state.py +208 -0
- {aiagents4pharma-1.12.0.dist-info → aiagents4pharma-1.13.1.dist-info}/METADATA +1 -1
- {aiagents4pharma-1.12.0.dist-info → aiagents4pharma-1.13.1.dist-info}/RECORD +12 -11
- {aiagents4pharma-1.12.0.dist-info → aiagents4pharma-1.13.1.dist-info}/LICENSE +0 -0
- {aiagents4pharma-1.12.0.dist-info → aiagents4pharma-1.13.1.dist-info}/WHEEL +0 -0
- {aiagents4pharma-1.12.0.dist-info → aiagents4pharma-1.13.1.dist-info}/top_level.txt +0 -0
@@ -3,6 +3,7 @@ state_modifier: >
|
|
3
3
|
You are Talk2BioModels agent.
|
4
4
|
If the user asks for the uploaded model,
|
5
5
|
then pass the use_uploaded_model argument
|
6
|
-
as True. If the user asks for simulation
|
7
|
-
|
6
|
+
as True. If the user asks for simulation
|
7
|
+
or steady state, suggest a value for the
|
8
|
+
`simulation_name` or `steadystate_name`
|
8
9
|
argument.
|
@@ -17,6 +17,7 @@ from ..tools.simulate_model import SimulateModelTool
|
|
17
17
|
from ..tools.custom_plotter import CustomPlotterTool
|
18
18
|
from ..tools.ask_question import AskQuestionTool
|
19
19
|
from ..tools.parameter_scan import ParameterScanTool
|
20
|
+
from ..tools.steady_state import SteadyStateTool
|
20
21
|
from ..states.state_talk2biomodels import Talk2Biomodels
|
21
22
|
|
22
23
|
# Initialize logger
|
@@ -42,6 +43,7 @@ def get_app(uniq_id, llm_model='gpt-4o-mini'):
|
|
42
43
|
CustomPlotterTool(),
|
43
44
|
SearchModelsTool(),
|
44
45
|
GetModelInfoTool(),
|
46
|
+
SteadyStateTool(),
|
45
47
|
ParameterScanTool()
|
46
48
|
])
|
47
49
|
|
@@ -98,7 +98,7 @@ def test_simulate_model_tool():
|
|
98
98
|
# Upload a model to the state
|
99
99
|
app.update_state(config,
|
100
100
|
{"sbml_file_path": ["aiagents4pharma/talk2biomodels/tests/BIOMD0000000449_url.xml"]})
|
101
|
-
prompt = "Simulate
|
101
|
+
prompt = "Simulate model 64 and the uploaded model"
|
102
102
|
# Invoke the agent
|
103
103
|
app.invoke(
|
104
104
|
{"messages": [HumanMessage(content=prompt)]},
|
@@ -145,10 +145,9 @@ def test_param_scan_tool():
|
|
145
145
|
app.update_state(config, {"llm_model": "gpt-4o-mini"})
|
146
146
|
prompt = """How will the value of Ab in model 537 change
|
147
147
|
if the param kIL6Rbind is varied from 1 to 100 in steps of 10?
|
148
|
-
Set the initial `DoseQ2W` concentration to 300.
|
149
|
-
|
150
|
-
|
151
|
-
an interval of 2016."""
|
148
|
+
Set the initial `DoseQ2W` concentration to 300. Also, reset
|
149
|
+
the IL6{serum} concentration to 100 every 500 hours and assume
|
150
|
+
that the model is simulated for 2016 hours with an interval of 2016."""
|
152
151
|
# Invoke the agent
|
153
152
|
app.invoke(
|
154
153
|
{"messages": [HumanMessage(content=prompt)]},
|
@@ -181,11 +180,95 @@ def test_param_scan_tool():
|
|
181
180
|
assert any((df["status"] == "success") &
|
182
181
|
(df["name"] == "get_modelinfo"))
|
183
182
|
|
183
|
+
def test_steady_state_tool():
|
184
|
+
'''
|
185
|
+
Test the steady_state tool.
|
186
|
+
'''
|
187
|
+
unique_id = 123
|
188
|
+
app = get_app(unique_id)
|
189
|
+
config = {"configurable": {"thread_id": unique_id}}
|
190
|
+
app.update_state(config, {"llm_model": "gpt-4o-mini"})
|
191
|
+
#########################################################
|
192
|
+
# In this case, we will test if the tool returns an error
|
193
|
+
# when the model does not achieve a steady state. The tool
|
194
|
+
# status should be "error".
|
195
|
+
prompt = """Run a steady state analysis of model 537."""
|
196
|
+
# Invoke the agent
|
197
|
+
app.invoke(
|
198
|
+
{"messages": [HumanMessage(content=prompt)]},
|
199
|
+
config=config
|
200
|
+
)
|
201
|
+
current_state = app.get_state(config)
|
202
|
+
reversed_messages = current_state.values["messages"][::-1]
|
203
|
+
tool_msg_status = None
|
204
|
+
for msg in reversed_messages:
|
205
|
+
# Assert that the status of the
|
206
|
+
# ToolMessage is "error"
|
207
|
+
if isinstance(msg, ToolMessage):
|
208
|
+
# print (msg)
|
209
|
+
tool_msg_status = msg.status
|
210
|
+
break
|
211
|
+
assert tool_msg_status == "error"
|
212
|
+
#########################################################
|
213
|
+
# In this case, we will test if the tool is indeed invoked
|
214
|
+
# successfully
|
215
|
+
prompt = """Run a steady state analysis of model 64.
|
216
|
+
Set the initial concentration of `Pyruvate` to 0.2. The
|
217
|
+
concentration of `NAD` resets to 100 every 2 time units."""
|
218
|
+
# Invoke the agent
|
219
|
+
app.invoke(
|
220
|
+
{"messages": [HumanMessage(content=prompt)]},
|
221
|
+
config=config
|
222
|
+
)
|
223
|
+
# Loop through the reversed messages until a
|
224
|
+
# ToolMessage is found.
|
225
|
+
current_state = app.get_state(config)
|
226
|
+
reversed_messages = current_state.values["messages"][::-1]
|
227
|
+
steady_state_invoked = False
|
228
|
+
for msg in reversed_messages:
|
229
|
+
# Assert that the message is a ToolMessage
|
230
|
+
# and its status is "error"
|
231
|
+
if isinstance(msg, ToolMessage):
|
232
|
+
print (msg)
|
233
|
+
if msg.name == "steady_state" and msg.status != "error":
|
234
|
+
steady_state_invoked = True
|
235
|
+
break
|
236
|
+
assert steady_state_invoked
|
237
|
+
#########################################################
|
238
|
+
# In this case, we will test if the `ask_question` tool is
|
239
|
+
# invoked upon asking a question about the already generated
|
240
|
+
# steady state results
|
241
|
+
prompt = """What is the Phosphoenolpyruvate concentration
|
242
|
+
at the steady state? Show onlyconcentration, rounded to
|
243
|
+
2 decimal places. For example, if the concentration is
|
244
|
+
0.123456, your response should be `0.12`. Do not return
|
245
|
+
any other information."""
|
246
|
+
# Invoke the agent
|
247
|
+
response = app.invoke(
|
248
|
+
{"messages": [HumanMessage(content=prompt)]},
|
249
|
+
config=config
|
250
|
+
)
|
251
|
+
assistant_msg = response["messages"][-1].content
|
252
|
+
current_state = app.get_state(config)
|
253
|
+
reversed_messages = current_state.values["messages"][::-1]
|
254
|
+
# Loop through the reversed messages until a
|
255
|
+
# ToolMessage is found.
|
256
|
+
ask_questool_invoked = False
|
257
|
+
for msg in reversed_messages:
|
258
|
+
# Assert that the message is a ToolMessage
|
259
|
+
# and its status is "error"
|
260
|
+
if isinstance(msg, ToolMessage):
|
261
|
+
if msg.name == "ask_question":
|
262
|
+
ask_questool_invoked = True
|
263
|
+
break
|
264
|
+
assert ask_questool_invoked
|
265
|
+
assert "0.06" in assistant_msg
|
266
|
+
|
184
267
|
def test_integration():
|
185
268
|
'''
|
186
269
|
Test the integration of the tools.
|
187
270
|
'''
|
188
|
-
unique_id =
|
271
|
+
unique_id = 1234567
|
189
272
|
app = get_app(unique_id)
|
190
273
|
config = {"configurable": {"thread_id": unique_id}}
|
191
274
|
app.update_state(config, {"llm_model": "gpt-4o-mini"})
|
@@ -211,10 +294,8 @@ def test_integration():
|
|
211
294
|
##########################################
|
212
295
|
# Update state
|
213
296
|
app.update_state(config, {"llm_model": "gpt-4o-mini"})
|
214
|
-
prompt = "What is the concentration of CRP
|
215
|
-
|
216
|
-
# prompt += "For example, if the concentration is 0.123456, "
|
217
|
-
# prompt += "your response should be `0.1`. Do not return any other information."
|
297
|
+
prompt = """What is the concentration of CRP
|
298
|
+
in serum after 1000 time points?"""
|
218
299
|
# Test the tool get_modelinfo
|
219
300
|
response = app.invoke(
|
220
301
|
{"messages": [HumanMessage(content=prompt)]},
|
@@ -271,8 +352,9 @@ def test_integration():
|
|
271
352
|
# simulation results are available but
|
272
353
|
# the species is not available
|
273
354
|
##########################################
|
274
|
-
prompt = "
|
275
|
-
|
355
|
+
prompt = """Make a custom plot showing the
|
356
|
+
concentration of the species `TP53` over
|
357
|
+
time. Do not show any other species."""
|
276
358
|
# Update state
|
277
359
|
app.update_state(config, {"llm_model": "gpt-4o-mini"}
|
278
360
|
)
|
@@ -5,7 +5,7 @@ Tool for asking a question about the simulation results.
|
|
5
5
|
"""
|
6
6
|
|
7
7
|
import logging
|
8
|
-
from typing import Type, Annotated
|
8
|
+
from typing import Type, Annotated, Literal
|
9
9
|
import pandas as pd
|
10
10
|
from pydantic import BaseModel, Field
|
11
11
|
from langchain_core.tools.base import BaseTool
|
@@ -22,9 +22,12 @@ class AskQuestionInput(BaseModel):
|
|
22
22
|
"""
|
23
23
|
Input schema for the AskQuestion tool.
|
24
24
|
"""
|
25
|
-
question: str = Field(description="question about the simulation results")
|
26
|
-
|
27
|
-
|
25
|
+
question: str = Field(description="question about the simulation and steady state results")
|
26
|
+
experiment_name: str = Field(description="""Name assigned to the simulation
|
27
|
+
or steady state analysis when the tool
|
28
|
+
simulate_model or steady_state is invoked.""")
|
29
|
+
question_context: Literal["simulation", "steady_state"] = Field(
|
30
|
+
description="Context of the question")
|
28
31
|
state: Annotated[dict, InjectedState]
|
29
32
|
|
30
33
|
# Note: It's important that every field has type hints.
|
@@ -32,41 +35,51 @@ class AskQuestionInput(BaseModel):
|
|
32
35
|
# can lead to unexpected behavior.
|
33
36
|
class AskQuestionTool(BaseTool):
|
34
37
|
"""
|
35
|
-
Tool for
|
38
|
+
Tool for asking a question about the simulation or steady state results.
|
36
39
|
"""
|
37
40
|
name: str = "ask_question"
|
38
|
-
description: str = "A tool to ask question about the
|
41
|
+
description: str = """A tool to ask question about the
|
42
|
+
simulation or steady state results."""
|
39
43
|
args_schema: Type[BaseModel] = AskQuestionInput
|
40
44
|
return_direct: bool = False
|
41
45
|
|
42
46
|
def _run(self,
|
43
47
|
question: str,
|
44
|
-
|
48
|
+
experiment_name: str,
|
49
|
+
question_context: Literal["simulation", "steady_state"],
|
45
50
|
state: Annotated[dict, InjectedState]) -> str:
|
46
51
|
"""
|
47
52
|
Run the tool.
|
48
53
|
|
49
54
|
Args:
|
50
|
-
question (str): The question to ask about the simulation results.
|
55
|
+
question (str): The question to ask about the simulation or steady state results.
|
51
56
|
state (dict): The state of the graph.
|
52
|
-
|
57
|
+
experiment_name (str): The name assigned to the simulation or steady state analysis.
|
53
58
|
|
54
59
|
Returns:
|
55
60
|
str: The answer to the question.
|
56
61
|
"""
|
57
62
|
logger.log(logging.INFO,
|
58
|
-
"Calling ask_question tool %s, %s
|
59
|
-
|
60
|
-
|
63
|
+
"Calling ask_question tool %s, %s, %s",
|
64
|
+
question,
|
65
|
+
question_context,
|
66
|
+
experiment_name)
|
67
|
+
# print (f'Calling ask_question tool {question}, {question_context}, {experiment_name}')
|
68
|
+
if question_context == "steady_state":
|
69
|
+
dic_context = state["dic_steady_state_data"]
|
70
|
+
else:
|
71
|
+
dic_context = state["dic_simulated_data"]
|
72
|
+
dic_data = {}
|
73
|
+
for data in dic_context:
|
61
74
|
for key in data:
|
62
|
-
if key not in
|
63
|
-
|
64
|
-
|
65
|
-
# print (
|
66
|
-
|
75
|
+
if key not in dic_data:
|
76
|
+
dic_data[key] = []
|
77
|
+
dic_data[key] += [data[key]]
|
78
|
+
# print (dic_data)
|
79
|
+
df_data = pd.DataFrame.from_dict(dic_data)
|
67
80
|
df = pd.DataFrame(
|
68
|
-
|
69
|
-
|
81
|
+
df_data[df_data['name'] == experiment_name]['data'].iloc[0]
|
82
|
+
)
|
70
83
|
prompt_content = None
|
71
84
|
# if run_manager and 'prompt' in run_manager.metadata:
|
72
85
|
# prompt_content = run_manager.metadata['prompt']
|
@@ -0,0 +1,208 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
|
3
|
+
"""
|
4
|
+
Tool for parameter scan.
|
5
|
+
"""
|
6
|
+
|
7
|
+
import logging
|
8
|
+
from dataclasses import dataclass
|
9
|
+
from typing import Type, Union, List, Annotated
|
10
|
+
import basico
|
11
|
+
from pydantic import BaseModel, Field
|
12
|
+
from langgraph.types import Command
|
13
|
+
from langgraph.prebuilt import InjectedState
|
14
|
+
from langchain_core.tools import BaseTool
|
15
|
+
from langchain_core.messages import ToolMessage
|
16
|
+
from langchain_core.tools.base import InjectedToolCallId
|
17
|
+
from .load_biomodel import ModelData, load_biomodel
|
18
|
+
|
19
|
+
# Initialize logger
|
20
|
+
logging.basicConfig(level=logging.INFO)
|
21
|
+
logger = logging.getLogger(__name__)
|
22
|
+
|
23
|
+
@dataclass
|
24
|
+
class TimeData:
|
25
|
+
"""
|
26
|
+
Dataclass for storing the time data.
|
27
|
+
"""
|
28
|
+
duration: Union[int, float] = 100
|
29
|
+
interval: Union[int, float] = 10
|
30
|
+
|
31
|
+
@dataclass
|
32
|
+
class SpeciesData:
|
33
|
+
"""
|
34
|
+
Dataclass for storing the species data.
|
35
|
+
"""
|
36
|
+
species_name: List[str] = Field(description="species name", default=[])
|
37
|
+
species_concentration: List[Union[int, float]] = Field(
|
38
|
+
description="initial species concentration",
|
39
|
+
default=[])
|
40
|
+
|
41
|
+
@dataclass
|
42
|
+
class TimeSpeciesNameConcentration:
|
43
|
+
"""
|
44
|
+
Dataclass for storing the time, species name, and concentration data.
|
45
|
+
"""
|
46
|
+
time: Union[int, float] = Field(description="time point where the event occurs")
|
47
|
+
species_name: str = Field(description="species name")
|
48
|
+
species_concentration: Union[int, float] = Field(
|
49
|
+
description="species concentration at the time point")
|
50
|
+
|
51
|
+
@dataclass
|
52
|
+
class ReocurringData:
|
53
|
+
"""
|
54
|
+
Dataclass for species that reoccur. In other words, the concentration
|
55
|
+
of the species resets to a certain value after a certain time interval.
|
56
|
+
"""
|
57
|
+
data: List[TimeSpeciesNameConcentration] = Field(
|
58
|
+
description="time, name, and concentration data of species that reoccur",
|
59
|
+
default=[])
|
60
|
+
|
61
|
+
@dataclass
|
62
|
+
class ArgumentData:
|
63
|
+
"""
|
64
|
+
Dataclass for storing the argument data.
|
65
|
+
"""
|
66
|
+
time_data: TimeData = Field(description="time data", default=None)
|
67
|
+
species_data: SpeciesData = Field(
|
68
|
+
description="species name and initial concentration data")
|
69
|
+
reocurring_data: ReocurringData = Field(
|
70
|
+
description="""Concentration and time data of species that reoccur
|
71
|
+
For example, a species whose concentration resets to a certain value
|
72
|
+
after a certain time interval""")
|
73
|
+
steadystate_name: str = Field(
|
74
|
+
description="""An AI assigned `_` separated name of
|
75
|
+
the steady state experiment based on human query""")
|
76
|
+
|
77
|
+
def add_rec_events(model_object, reocurring_data):
|
78
|
+
"""
|
79
|
+
Add reocurring events to the model.
|
80
|
+
"""
|
81
|
+
for row in reocurring_data.data:
|
82
|
+
tp, sn, sc = row.time, row.species_name, row.species_concentration
|
83
|
+
basico.add_event(f'{sn}_{tp}',
|
84
|
+
f'Time > {tp}',
|
85
|
+
[[sn, str(sc)]],
|
86
|
+
model=model_object.copasi_model)
|
87
|
+
|
88
|
+
def run_steady_state(model_object, dic_species_data):
|
89
|
+
"""
|
90
|
+
Run the steady state analysis.
|
91
|
+
|
92
|
+
Args:
|
93
|
+
model_object: The model object.
|
94
|
+
dic_species_data: Dictionary of species data.
|
95
|
+
|
96
|
+
Returns:
|
97
|
+
DataFrame: The results of the steady state analysis.
|
98
|
+
"""
|
99
|
+
# Update the fixed model species and parameters
|
100
|
+
# These are the initial conditions of the model
|
101
|
+
# set by the user
|
102
|
+
model_object.update_parameters(dic_species_data)
|
103
|
+
logger.log(logging.INFO, "Running steady state analysis")
|
104
|
+
# Run the steady state analysis
|
105
|
+
output = basico.task_steadystate.run_steadystate(model=model_object.copasi_model)
|
106
|
+
if output == 0:
|
107
|
+
logger.error("Steady state analysis failed")
|
108
|
+
raise ValueError("A steady state was not found")
|
109
|
+
logger.log(logging.INFO, "Steady state analysis successful")
|
110
|
+
# Store the steady state results in a DataFrame
|
111
|
+
df_steady_state = basico.model_info.get_species(model=model_object.copasi_model)
|
112
|
+
logger.log(logging.INFO, "Steady state results with shape %s", df_steady_state.shape)
|
113
|
+
return df_steady_state
|
114
|
+
|
115
|
+
class SteadyStateInput(BaseModel):
|
116
|
+
"""
|
117
|
+
Input schema for the steady state tool.
|
118
|
+
"""
|
119
|
+
sys_bio_model: ModelData = Field(description="model data",
|
120
|
+
default=None)
|
121
|
+
arg_data: ArgumentData = Field(description=
|
122
|
+
"""time, species, and reocurring data
|
123
|
+
as well as the steady state data""",
|
124
|
+
default=None)
|
125
|
+
tool_call_id: Annotated[str, InjectedToolCallId]
|
126
|
+
state: Annotated[dict, InjectedState]
|
127
|
+
|
128
|
+
# Note: It's important that every field has type hints. BaseTool is a
|
129
|
+
# Pydantic class and not having type hints can lead to unexpected behavior.
|
130
|
+
class SteadyStateTool(BaseTool):
|
131
|
+
"""
|
132
|
+
Tool for steady state analysis.
|
133
|
+
"""
|
134
|
+
name: str = "steady_state"
|
135
|
+
description: str = """A tool to simulate a model and perform
|
136
|
+
steady state analysisto answer questions
|
137
|
+
about the steady state of species."""
|
138
|
+
args_schema: Type[BaseModel] = SteadyStateInput
|
139
|
+
|
140
|
+
def _run(self,
|
141
|
+
tool_call_id: Annotated[str, InjectedToolCallId],
|
142
|
+
state: Annotated[dict, InjectedState],
|
143
|
+
sys_bio_model: ModelData = None,
|
144
|
+
arg_data: ArgumentData = None
|
145
|
+
) -> Command:
|
146
|
+
"""
|
147
|
+
Run the tool.
|
148
|
+
|
149
|
+
Args:
|
150
|
+
tool_call_id (str): The tool call ID. This is injected by the system.
|
151
|
+
state (dict): The state of the tool.
|
152
|
+
sys_bio_model (ModelData): The model data.
|
153
|
+
arg_data (ArgumentData): The argument data.
|
154
|
+
|
155
|
+
Returns:
|
156
|
+
Command: The updated state of the tool.
|
157
|
+
"""
|
158
|
+
logger.log(logging.INFO, "Calling steady_state tool %s, %s",
|
159
|
+
sys_bio_model, arg_data)
|
160
|
+
# print (f'Calling steady_state tool {sys_bio_model}, {arg_data}, {tool_call_id}')
|
161
|
+
sbml_file_path = state['sbml_file_path'][-1] if len(state['sbml_file_path']) > 0 else None
|
162
|
+
model_object = load_biomodel(sys_bio_model,
|
163
|
+
sbml_file_path=sbml_file_path)
|
164
|
+
# Prepare the dictionary of species data
|
165
|
+
# that will be passed to the simulate method
|
166
|
+
# of the BasicoModel class
|
167
|
+
dic_species_data = {}
|
168
|
+
if arg_data:
|
169
|
+
# Prepare the dictionary of species data
|
170
|
+
if arg_data.species_data is not None:
|
171
|
+
dic_species_data = dict(zip(arg_data.species_data.species_name,
|
172
|
+
arg_data.species_data.species_concentration))
|
173
|
+
# Add reocurring events (if any) to the model
|
174
|
+
if arg_data.reocurring_data is not None:
|
175
|
+
add_rec_events(model_object, arg_data.reocurring_data)
|
176
|
+
# Run the parameter scan
|
177
|
+
df_steady_state = run_steady_state(model_object, dic_species_data)
|
178
|
+
# Prepare the dictionary of scanned data
|
179
|
+
# that will be passed to the state of the graph
|
180
|
+
dic_steady_state_data = {
|
181
|
+
'name': arg_data.steadystate_name,
|
182
|
+
'source': sys_bio_model.biomodel_id if sys_bio_model.biomodel_id else 'upload',
|
183
|
+
'tool_call_id': tool_call_id,
|
184
|
+
'data': df_steady_state.to_dict(orient='records')
|
185
|
+
}
|
186
|
+
# Prepare the dictionary of updated state for the model
|
187
|
+
dic_updated_state_for_model = {}
|
188
|
+
for key, value in {
|
189
|
+
"model_id": [sys_bio_model.biomodel_id],
|
190
|
+
"sbml_file_path": [sbml_file_path],
|
191
|
+
"dic_steady_state_data": [dic_steady_state_data]
|
192
|
+
}.items():
|
193
|
+
if value:
|
194
|
+
dic_updated_state_for_model[key] = value
|
195
|
+
# Return the updated state
|
196
|
+
return Command(
|
197
|
+
update=dic_updated_state_for_model|{
|
198
|
+
# Update the message history
|
199
|
+
"messages": [
|
200
|
+
ToolMessage(
|
201
|
+
content=f'''Steady state analysis of
|
202
|
+
{arg_data.steadystate_name}
|
203
|
+
are ready''',
|
204
|
+
tool_call_id=tool_call_id
|
205
|
+
)
|
206
|
+
],
|
207
|
+
}
|
208
|
+
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: aiagents4pharma
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.13.1
|
4
4
|
Summary: AI Agents for drug discovery, drug development, and other pharmaceutical R&D
|
5
5
|
Classifier: Programming Language :: Python :: 3
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
@@ -4,27 +4,28 @@ aiagents4pharma/configs/config.yaml,sha256=8y8uG6Dzx4-9jyb6hZ8r4lOJz5gA_sQhCiSCg
|
|
4
4
|
aiagents4pharma/configs/talk2biomodels/__init__.py,sha256=5ah__-8XyRblwT0U1ByRigNjt_GyCheu7zce4aM-eZE,68
|
5
5
|
aiagents4pharma/configs/talk2biomodels/agents/__init__.py,sha256=_ZoG8snICK2bidWtc2KOGs738LWg9_r66V9mOMnEb-E,71
|
6
6
|
aiagents4pharma/configs/talk2biomodels/agents/t2b_agent/__init__.py,sha256=-fAORvyFmG2iSvFOFDixmt9OTQRR58y89uhhu2EgbA8,46
|
7
|
-
aiagents4pharma/configs/talk2biomodels/agents/t2b_agent/default.yaml,sha256=
|
7
|
+
aiagents4pharma/configs/talk2biomodels/agents/t2b_agent/default.yaml,sha256=Oi89_BbxfQc6SGW1pC-hyZMqOIkiAMOlNwpCa4VCXk0,327
|
8
8
|
aiagents4pharma/talk2biomodels/__init__.py,sha256=qUw3qXrENqSCLIKSLy_qtNPwPDTb1wdZ8fZispcHb3g,141
|
9
9
|
aiagents4pharma/talk2biomodels/agents/__init__.py,sha256=sn5-fREjMdEvb-OUan3iOqrgYGjplNx3J8hYOaW0Po8,128
|
10
|
-
aiagents4pharma/talk2biomodels/agents/t2b_agent.py,sha256=
|
10
|
+
aiagents4pharma/talk2biomodels/agents/t2b_agent.py,sha256=8_2D3uknPjYbzKj7IDhC8xnz_HEvXck0b4RCJxoAxRs,3276
|
11
11
|
aiagents4pharma/talk2biomodels/models/__init__.py,sha256=5fTHHm3PVloYPNKXbgNlcPgv3-u28ZquxGydFYDfhJA,122
|
12
12
|
aiagents4pharma/talk2biomodels/models/basico_model.py,sha256=PH25FTOuUjsmw_UUxoRb-4kptOYpicEn4GqS0phS3nk,4807
|
13
13
|
aiagents4pharma/talk2biomodels/models/sys_bio_model.py,sha256=JeoiGQAvQABHnG0wKR2XBmmxqQdtgO6kxaLDUTUmr1s,2001
|
14
14
|
aiagents4pharma/talk2biomodels/states/__init__.py,sha256=YLg1-N0D9qyRRLRqwqfLCLAqZYDtMVZTfI8Y0b_4tbA,139
|
15
|
-
aiagents4pharma/talk2biomodels/states/state_talk2biomodels.py,sha256=
|
15
|
+
aiagents4pharma/talk2biomodels/states/state_talk2biomodels.py,sha256=XcrCsBbQgc4LCZ7ihpY5tcLQ82Mq17XhRXD1DW8Ep7U,887
|
16
16
|
aiagents4pharma/talk2biomodels/tests/__init__.py,sha256=Jbw5tJxSrjGoaK5IX3pJWDCNzhrVQ10lkYq2oQ_KQD8,45
|
17
17
|
aiagents4pharma/talk2biomodels/tests/test_basico_model.py,sha256=y82fpTJMPHwtXxlle1cGQ_2Bewwpxi0aJSVrVAYLhN0,2060
|
18
|
-
aiagents4pharma/talk2biomodels/tests/test_langgraph.py,sha256=
|
18
|
+
aiagents4pharma/talk2biomodels/tests/test_langgraph.py,sha256=QLAL4nmHrioTD-w-9OE0wQi5JdWJJ59PejNbDzCSvw4,15170
|
19
19
|
aiagents4pharma/talk2biomodels/tests/test_sys_bio_model.py,sha256=HSmBBViMi0jYf4gWX21IbppAfDzG0nr_S3KtKS9fZVQ,2165
|
20
|
-
aiagents4pharma/talk2biomodels/tools/__init__.py,sha256
|
21
|
-
aiagents4pharma/talk2biomodels/tools/ask_question.py,sha256=
|
20
|
+
aiagents4pharma/talk2biomodels/tools/__init__.py,sha256=-Fz3TryG3ZgBMwfF3v2ZMNSM_-g9vywjKBrGJgVQuYY,293
|
21
|
+
aiagents4pharma/talk2biomodels/tools/ask_question.py,sha256=qpltsgyLFFwLYQeapQHASFRDCNiWsJkmTH_sUrfJ_Fg,3708
|
22
22
|
aiagents4pharma/talk2biomodels/tools/custom_plotter.py,sha256=HWwKTX3o4dk0GcRVTO2hPrFSu98mtJ4TKC_hbHXOe1c,4018
|
23
23
|
aiagents4pharma/talk2biomodels/tools/get_modelinfo.py,sha256=qA-4FOI-O728Nmn7s8JJ8HKwxvA9MZbst7NkPKTAMV4,5391
|
24
24
|
aiagents4pharma/talk2biomodels/tools/load_biomodel.py,sha256=pyVzLQoMnuJYEwsjeOlqcUrbU1F1Z-pNlgkhFaoKpy0,689
|
25
25
|
aiagents4pharma/talk2biomodels/tools/parameter_scan.py,sha256=aIyL_m46s3Q74ieJOZjZBM34VCjBKSMpEtckhdZofbE,12139
|
26
26
|
aiagents4pharma/talk2biomodels/tools/search_models.py,sha256=Iq2ddofOOfZYtAurCISq3bAq5rbwB3l_rL1lgEFyFCI,2653
|
27
27
|
aiagents4pharma/talk2biomodels/tools/simulate_model.py,sha256=sWmFVnVvJbdXXTqn_7gQl5UW0tv4FyU5yLXWLweLs_M,7059
|
28
|
+
aiagents4pharma/talk2biomodels/tools/steady_state.py,sha256=itUXFTYO525D695LQlGb1ObwSuvHk0A5mXtgdCproqo,8102
|
28
29
|
aiagents4pharma/talk2cells/__init__.py,sha256=zmOP5RAhabgKIQP-W4P4qKME2tG3fhAXM3MeO5_H8kE,120
|
29
30
|
aiagents4pharma/talk2cells/agents/__init__.py,sha256=38nK2a_lEFRjO3qD6Fo9a3983ZCYat6hmJKWY61y2Mo,128
|
30
31
|
aiagents4pharma/talk2cells/agents/scp_agent.py,sha256=gDMfhUNWHa_XWOqm1Ql6yLAdI_7bnIk5sRYn43H2sYk,3090
|
@@ -76,8 +77,8 @@ aiagents4pharma/talk2knowledgegraphs/utils/embeddings/sentence_transformer.py,sh
|
|
76
77
|
aiagents4pharma/talk2knowledgegraphs/utils/enrichments/__init__.py,sha256=tW426knki2DBIHcWyF_K04iMMdbpIn_e_TpPmTgz2dI,113
|
77
78
|
aiagents4pharma/talk2knowledgegraphs/utils/enrichments/enrichments.py,sha256=Bx8x6zzk5614ApWB90N_iv4_Y_Uq0-KwUeBwYSdQMU4,924
|
78
79
|
aiagents4pharma/talk2knowledgegraphs/utils/enrichments/ollama.py,sha256=8eoxR-VHo0G7ReQIwje7xEhE-SJlHdef7_wJRpnvFIc,4116
|
79
|
-
aiagents4pharma-1.
|
80
|
-
aiagents4pharma-1.
|
81
|
-
aiagents4pharma-1.
|
82
|
-
aiagents4pharma-1.
|
83
|
-
aiagents4pharma-1.
|
80
|
+
aiagents4pharma-1.13.1.dist-info/LICENSE,sha256=IcIbyB1Hyk5ZDah03VNQvJkbNk2hkBCDqQ8qtnCvB4Q,1077
|
81
|
+
aiagents4pharma-1.13.1.dist-info/METADATA,sha256=HCfDwV_-IF_1yQccq0COSwj9C_Hr1wTtETFJOSP44ec,8609
|
82
|
+
aiagents4pharma-1.13.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
83
|
+
aiagents4pharma-1.13.1.dist-info/top_level.txt,sha256=-AH8rMmrSnJtq7HaAObS78UU-cTCwvX660dSxeM7a0A,16
|
84
|
+
aiagents4pharma-1.13.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|