tools
dsi_search_tools
load_dsi_tool(db_path, run_path='', master_db_folder='')
Load a DSI object from the path and add information to the context for the llm to use.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
db_path
|
str
|
the path to the DSI object to load |
required |
run_path
|
str
|
the path this code is being run from |
''
|
master_db_folder
|
str
|
the folder containing the master database, used to resolve relative paths when loading new databases |
''
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
message indicating success or failure |
Source code in src/ursa/tools/dsi_search_tools.py
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | |
query_dsi_tool(query_str, db_path)
Execute a SQL query on a DSI object
Arg
query_str (str): the SQL query to run on DSI object db_path (str): the absolute path to the DSI database to query
Returns:
| Name | Type | Description |
|---|---|---|
collection |
dict
|
the results of the query |
Source code in src/ursa/tools/dsi_search_tools.py
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | |
feasibility_checker
heuristic_feasibility_check(constraints, variable_name, variable_type, variable_bounds, samples=10000)
A tool for checking feasibility of the constraints.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
constraints
|
Annotated[list[str], "List of strings like 'x0+x1<=5'"]
|
list of strings like 'x0 + x1 <= 5', etc. |
required |
variable_name
|
Annotated[list[str], "List of strings like 'x0', 'x1', etc."]
|
list of strings containing variable names used in constraint expressions. |
required |
variable_type
|
Annotated[list[str], "List of strings like 'real', 'integer', 'boolean', etc."]
|
list of strings like 'real', 'integer', 'boolean', etc. |
required |
variable_bounds
|
Annotated[list[list[float]], "List of (lower bound, upper bound) tuples for x0, x1, ...'"]
|
list of (lower, upper) tuples for x0, x1, etc. |
required |
samples
|
Annotated[int, 'Number of random sample. Default 10000']
|
number of random samples, default value 10000 |
10000
|
Returns:
| Type | Description |
|---|---|
tuple[str]
|
A string indicating whether a feasible solution was found. |
Source code in src/ursa/tools/feasibility_checker.py
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | |
feasibility_tools
Unified feasibility checker with heuristic pre-check and exact auto-routing.
Backends (imported lazily and used only if available): - PySMT (cvc5/msat/yices/z3) for SMT-style logic, disjunctions, and nonlinear constructs. - OR-Tools CP-SAT for strictly linear integer/boolean instances with integer coefficients. - OR-Tools CBC (pywraplp) for linear MILP/LP (mixed real + integer, or pure LP). - SciPy HiGHS (linprog) for pure continuous LP feasibility.
Install any subset you need
pip install pysmt && pysmt-install --cvc5 # or --z3/--msat/--yices pip install ortools pip install scipy pip install numpy
This file exposes a single LangChain tool: feasibility_check_auto.
feasibility_check_auto(constraints, variable_name, variable_type, variable_bounds, prefer_smt_solver='cvc5', heuristic_enabled=True, heuristic_first=True, heuristic_samples=2000, heuristic_seed=None, heuristic_unbounded_radius_real=1000.0, heuristic_unbounded_radius_int=10 ** 6, numeric_tolerance=1e-08)
Unified feasibility checker with heuristic pre-check and exact auto-routing.
Performs an optional randomized feasibility search. If no witness is found (or the heuristic is disabled), the function auto-routes to an exact backend based on the detected problem structure (PySMT for SMT/logic/nonlinear, OR-Tools CP-SAT for linear integer/boolean, OR-Tools CBC for MILP/LP, or SciPy HiGHS for pure LP).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
constraints
|
Annotated[list[str], "Constraint strings like 'x0 + 2*x1 <= 5' or '(x0<=3) | (x1>=2)'"]
|
Constraint strings such as "x0 + 2*x1 <= 5" or "(x0<=3) | (x1>=2)". |
required |
variable_name
|
Annotated[list[str], ['x0', 'x1', ...]]
|
Variable names, e.g., ["x0", "x1"]. |
required |
variable_type
|
Annotated[list[str], ['real' | 'integer' | 'boolean', ...]]
|
Variable types aligned with |
required |
variable_bounds
|
Annotated[list[list[Optional[float]]], '[(low, high), ...] (use None for unbounded)']
|
Per-variable [low, high] bounds aligned with |
required |
prefer_smt_solver
|
Annotated[str, "SMT backend if needed: 'cvc5'|'msat'|'yices'|'z3'"]
|
SMT backend name used by PySMT ("cvc5", "msat", "yices", or "z3"). |
'cvc5'
|
heuristic_enabled
|
Annotated[bool, 'Run a fast randomized search first?']
|
Whether to run the heuristic sampler. |
True
|
heuristic_first
|
Annotated[bool, 'Try heuristic before exact routing']
|
If True, run the heuristic before exact routing; if False, run it after. |
True
|
heuristic_samples
|
Annotated[int, 'Samples for heuristic search']
|
Number of heuristic samples. |
2000
|
heuristic_seed
|
Annotated[Optional[int], 'Seed for reproducibility']
|
Random seed for reproducibility. |
None
|
heuristic_unbounded_radius_real
|
Annotated[float, 'Sampling range for unbounded real vars']
|
Sampling radius for unbounded real variables. |
1000.0
|
heuristic_unbounded_radius_int
|
Annotated[int, 'Sampling range for unbounded integer vars']
|
Sampling radius for unbounded integer variables. |
10 ** 6
|
numeric_tolerance
|
Annotated[float, 'Tolerance for relational checks (Eq/Lt/Le/etc.)']
|
Tolerance used in relational checks (e.g., Eq, Lt, Le). |
1e-08
|
Returns:
| Type | Description |
|---|---|
str
|
A message indicating the chosen backend and the feasibility result. On success, |
str
|
includes an example model (assignment). On infeasibility, includes a short |
str
|
diagnostic or solver status. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If constraints cannot be parsed or an unsupported variable type is provided. |
Source code in src/ursa/tools/feasibility_tools.py
848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 | |
fm_base_tool
TorchModuleTool
Bases: BaseModel, Generic[Input, Output, ModelInput, ModelOutput]
A helper class for exposing a PyTorch model as an MCP tool for inference. Provides default methods for running the following pipeline:
- Preprocess a sequence of
Inputsinto aModelInput - Pass
ModelInputthrough the PyTorch model gettingModelOutput - Postprocess
ModelOutputinto a suitable sequence ofOutputs
Complex models (i.e. multi-GPU) may not be fully supported by this class.
Source code in src/ursa/tools/fm_base_tool.py
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | |
args_schema
instance-attribute
The input schema for the model
batch_size = 1
class-attribute
instance-attribute
Inputs to the model will be batched into set of at most this size
description
instance-attribute
What the foundation model does / how to use it
device = Field(default_factory=default_device)
class-attribute
instance-attribute
The accelerator on which the model is placed
fm
instance-attribute
The underlying PyTorch model used for inference
name = None
class-attribute
instance-attribute
A short name for the foundation model
output_schema
instance-attribute
The output_schema for the model
add_to_fastmcp(server)
Add self as a tool to server
Source code in src/ursa/tools/fm_base_tool.py
166 167 168 169 170 171 172 173 174 175 176 177 | |
from_pretrained(pretrained_model_name_or_path, **kwargs)
classmethod
Instantiate tool from a pretrained checkpoint either on disk, or automatically downloaded from a repository (i.e. HuggingFace)
Source code in src/ursa/tools/fm_base_tool.py
93 94 95 96 97 98 99 100 | |
postprocess(model_output)
Postprocess the model's raw output into a relevant tool output format
Source code in src/ursa/tools/fm_base_tool.py
89 90 91 | |
preprocess(input)
Convert tool input into the form accepted by the model
The input will be of type list[args_schema] with a length
of batch_size
Defaults to torch.data.default_collate
Source code in src/ursa/tools/fm_base_tool.py
74 75 76 77 78 79 80 81 82 83 | |
git_tools
git_add(runtime, repo_path=None, pathspecs=None)
Stage files for commit using git add.
Source code in src/ursa/tools/git_tools.py
153 154 155 156 157 158 159 160 161 162 163 | |
git_commit(runtime, message, repo_path=None)
Create a git commit with the provided message.
Source code in src/ursa/tools/git_tools.py
166 167 168 169 170 171 172 173 174 175 176 | |
git_create_branch(runtime, branch, repo_path=None)
Create a branch without switching to it.
Source code in src/ursa/tools/git_tools.py
198 199 200 201 202 203 204 205 206 207 208 209 | |
git_diff(runtime, repo_path=None, staged=False, pathspecs=None)
Return git diff for a repository inside the workspace.
Source code in src/ursa/tools/git_tools.py
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | |
git_log(runtime, repo_path=None, limit=20)
Return recent git log entries for a repository.
Source code in src/ursa/tools/git_tools.py
126 127 128 129 130 131 132 133 134 135 | |
git_ls_files(runtime, repo_path=None, pathspecs=None)
List tracked files, optionally filtered by pathspecs.
Source code in src/ursa/tools/git_tools.py
138 139 140 141 142 143 144 145 146 147 148 149 150 | |
git_status(runtime, repo_path=None)
Return git status for a repository inside the workspace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
repo_path
|
AsciiStr | None
|
Path to repository relative to workspace. If None, uses workspace root. Recommended to always specify a repo_path to avoid large untracked file lists. |
None
|
Source code in src/ursa/tools/git_tools.py
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | |
git_switch(runtime, branch, repo_path=None, create=False)
Switch branches using git switch (optionally create).
Source code in src/ursa/tools/git_tools.py
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | |
go_tools
go_build(runtime, repo_path=None)
Build a Go module using go build ./...
Source code in src/ursa/tools/go_tools.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | |
go_mod_tidy(runtime, repo_path=None)
Clean up and validate Go module dependencies using go mod tidy.
Source code in src/ursa/tools/go_tools.py
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | |
go_test(runtime, repo_path=None, verbose=True)
Run Go tests using go test ./...
Source code in src/ursa/tools/go_tools.py
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | |
go_vet(runtime, repo_path=None)
Run Go vet for code pattern analysis using go vet ./...
Source code in src/ursa/tools/go_tools.py
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | |
gofmt_files(runtime, paths, repo_path=None)
Format Go files in-place using gofmt.
Source code in src/ursa/tools/go_tools.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | |
golangci_lint(runtime, repo_path=None)
Run golangci-lint on the repository.
Automatically detects and uses .golangci.yml if present, otherwise uses sensible defaults.
Source code in src/ursa/tools/go_tools.py
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | |
read_file_tool
download_file_tool(url, output_path, runtime)
Download a file from a URL and save it locally.
Arg
url (str): a string containing the URL of the file to download. output_path (str): the local path where the file should be saved. Default to '.' for workspace root
Returns: Confirmation message with the saved file path.
Source code in src/ursa/tools/read_file_tool.py
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | |
read_file(filename, runtime)
Read a file from the workspace.
- If filename ends with .pdf, extract text from the PDF.
- If extracted text is very small (likely scanned), optionally run OCR to add a text layer.
- Otherwise read as UTF-8 text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filename
|
str
|
File name relative to the workspace directory. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Extracted text content. |
Source code in src/ursa/tools/read_file_tool.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | |
run_command_tool
run_command(query, runtime)
Execute a shell command in the workspace and return its combined output.
Runs the specified command using subprocess.run in the given workspace directory, captures stdout and stderr, enforces a maximum character budget, and formats both streams into a single string. KeyboardInterrupt during execution is caught and reported.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
AsciiStr
|
The shell command to execute. |
required |
Returns:
| Type | Description |
|---|---|
str
|
A formatted string with "STDOUT:" followed by the truncated stdout and |
str
|
"STDERR:" followed by the truncated stderr. |
Source code in src/ursa/tools/run_command_tool.py
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | |
search_tools
run_arxiv_search(prompt, query, runtime, max_results=3)
Search ArXiv for the first 'max_results' papers and summarize them in the context of the user prompt
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prompt
|
str
|
string describing the information the agent is interested in from arxiv papers |
required |
query
|
str
|
1 and 8 word search query for the Arxiv search API to find papers relevant to the prompt |
required |
max_results
|
int
|
integer number of papers to return (defaults 3). Request fewer if searching for something very specific or a larger number if broadly searching for information. Do not exceeed 10. |
3
|
Source code in src/ursa/tools/search_tools.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | |
run_osti_search(prompt, query, runtime, max_results=3)
Search OSTI.gov for the first 'max_results' papers and summarize them in the context of the user prompt
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prompt
|
str
|
string describing the information the agent is interested in from arxiv papers |
required |
query
|
str
|
1 and 8 word search query for the OSTI.gov search API to find papers relevant to the prompt |
required |
max_results
|
int
|
integer number of papers to return (defaults 3). Request fewer if searching for something very specific or a larger number if broadly searching for information. Do not exceeed 10. |
3
|
Source code in src/ursa/tools/search_tools.py
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | |
run_web_search(prompt, query, runtime, max_results=3)
Search the internet for the first 'max_results' pages and summarize them in the context of the user prompt
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prompt
|
str
|
string describing the information the agent is interested in from websites |
required |
query
|
str
|
1 and 8 word search query for the web search engines to find papers relevant to the prompt |
required |
max_results
|
int
|
integer number of pages to return (defaults 3). Request fewer if searching for something very specific or a larger number if broadly searching for information. Do not exceeed 10. |
3
|
Source code in src/ursa/tools/search_tools.py
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | |
write_code_tool
edit_code(old_code, new_code, filename, runtime, repo_path=None)
Replace the first occurrence of old_code with new_code in filename.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
old_code
|
str
|
Code fragment to search for. |
required |
new_code
|
str
|
Replacement fragment. |
required |
filename
|
AsciiStr
|
Target file inside the workspace. |
required |
repo_path
|
AsciiStr | None
|
Optional repo path - if provided, file must be within this repo. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Success / failure message. |
Source code in src/ursa/tools/write_code_tool.py
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | |
write_code(code, filename, runtime)
Write source code to a file
Records successful file edits to the graph's store
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
code
|
str
|
The source code content to be written to disk. |
required |
filename
|
AsciiStr
|
Name of the target file (including its extension). |
required |
Source code in src/ursa/tools/write_code_tool.py
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | |
write_code_with_repo(code, filename, runtime, repo_path)
Write source code to a file constrained to a repository path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
code
|
str
|
The source code content to be written to disk. |
required |
filename
|
AsciiStr
|
Name of the target file (including its extension). |
required |
repo_path
|
AsciiStr
|
Repo path - file must resolve within this directory. |
required |
Source code in src/ursa/tools/write_code_tool.py
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | |