ursa-ai 0.5.0__py3-none-any.whl → 0.6.0rc2__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.

Potentially problematic release.


This version of ursa-ai might be problematic. Click here for more details.

@@ -0,0 +1,142 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import uuid
5
+ from typing import Any, Callable, Dict, Iterable, List, Union
6
+
7
+ from langchain_core.messages import AIMessage, BaseMessage, ToolMessage
8
+ from langchain_core.runnables import Runnable
9
+
10
+
11
+ # --- if you already have your own versions, reuse them ---
12
+ def _parse_args(v: Any) -> Dict[str, Any]:
13
+ if v is None:
14
+ return {}
15
+ if isinstance(v, dict):
16
+ return v
17
+ if isinstance(v, str):
18
+ try:
19
+ return json.loads(v)
20
+ except Exception:
21
+ return {"_raw": v}
22
+ return {"_raw": v}
23
+
24
+
25
+ def extract_tool_calls(msg: AIMessage) -> List[Dict[str, Any]]:
26
+ # Prefer normalized field
27
+ if msg.tool_calls:
28
+ out = []
29
+ for tc in msg.tool_calls:
30
+ name = getattr(tc, "name", None) or tc.get("name")
31
+ args = getattr(tc, "args", None) or tc.get("args")
32
+ call_id = getattr(tc, "id", None) or tc.get("id")
33
+ out.append({"name": name, "args": _parse_args(args), "id": call_id})
34
+ return out
35
+
36
+ # Fallbacks (OpenAI raw payloads)
37
+ ak = msg.additional_kwargs or {}
38
+ if ak.get("tool_calls"):
39
+ out = []
40
+ for tc in ak["tool_calls"]:
41
+ fn = tc.get("function", {}) or {}
42
+ out.append({
43
+ "name": fn.get("name"),
44
+ "args": _parse_args(fn.get("arguments")),
45
+ "id": tc.get("id"),
46
+ })
47
+ return out
48
+
49
+ if ak.get("function_call"):
50
+ fn = ak["function_call"]
51
+ return [
52
+ {
53
+ "name": fn.get("name"),
54
+ "args": _parse_args(fn.get("arguments")),
55
+ "id": None,
56
+ }
57
+ ]
58
+ return []
59
+
60
+
61
+ # -----------------------------------------------------------------------------
62
+
63
+
64
+ ToolRegistry = Dict[str, Union[Runnable, Callable[..., Any]]]
65
+
66
+
67
+ def _stringify_output(x: Any) -> str:
68
+ if isinstance(x, str):
69
+ return x
70
+ try:
71
+ return json.dumps(x, ensure_ascii=False)
72
+ except Exception:
73
+ return str(x)
74
+
75
+
76
+ def _invoke_tool(
77
+ tool: Union[Runnable, Callable[..., Any]], args: Dict[str, Any]
78
+ ) -> Any:
79
+ # Runnable (LangChain tools & chains)
80
+ if isinstance(tool, Runnable):
81
+ return tool.invoke(args)
82
+ # Plain callable
83
+ try:
84
+ return tool(**args)
85
+ except TypeError:
86
+ # Some tools expect a single positional payload
87
+ return tool(args)
88
+
89
+
90
+ def run_tool_calls(
91
+ ai_msg: AIMessage,
92
+ tools: Union[ToolRegistry, Iterable[Union[Runnable, Callable[..., Any]]]],
93
+ ) -> List[BaseMessage]:
94
+ """
95
+ Args:
96
+ ai_msg: The LLM's AIMessage containing tool calls.
97
+ tools: Either a dict {name: tool} or an iterable of tools (must have `.name`
98
+ for mapping). Each tool can be a Runnable or a plain callable.
99
+
100
+ Returns:
101
+ out: list[BaseMessage] to feed back to the model
102
+ """
103
+ # Build a name->tool map
104
+ if isinstance(tools, dict):
105
+ registry: ToolRegistry = tools # type: ignore
106
+ else:
107
+ registry = {}
108
+ for t in tools:
109
+ name = getattr(t, "name", None) or getattr(t, "__name__", None)
110
+ if not name:
111
+ raise ValueError(f"Tool {t!r} has no discoverable name.")
112
+ registry[name] = t # type: ignore
113
+
114
+ calls = extract_tool_calls(ai_msg)
115
+
116
+ if not calls:
117
+ return []
118
+
119
+ out: List[BaseMessage] = []
120
+ for call in calls:
121
+ name = call.get("name")
122
+ args = call.get("args", {}) or {}
123
+ call_id = call.get("id") or f"call_{uuid.uuid4().hex}"
124
+
125
+ # 1) the AIMessage that generated the call
126
+ out.append(ai_msg)
127
+
128
+ # 2) the ToolMessage with the execution result (or error)
129
+ if name not in registry:
130
+ content = f"ERROR: unknown tool '{name}'."
131
+ else:
132
+ try:
133
+ result = _invoke_tool(registry[name], args)
134
+ content = _stringify_output(result)
135
+ except Exception as e:
136
+ content = f"ERROR: {type(e).__name__}: {e}"
137
+
138
+ out.append(
139
+ ToolMessage(content=content, tool_call_id=call_id, name=name)
140
+ )
141
+
142
+ return out
@@ -0,0 +1,78 @@
1
+ from typing import Any, List, Literal, Optional, TypedDict
2
+
3
+
4
+ class DecisionVariableType(TypedDict):
5
+ name: str # decision variable name
6
+ type: Literal[
7
+ "continuous",
8
+ "integer",
9
+ "logical",
10
+ "infinite-dimensional",
11
+ "finite-dimensional",
12
+ ] # decision variable type
13
+ domain: str # allowable values of variable
14
+ description: str # natural language description
15
+
16
+
17
+ class ParameterType(TypedDict):
18
+ name: str # parameter name
19
+ value: Optional[Any] # parameter value; None
20
+ description: str # natural language description
21
+ is_user_supplied: bool # 1 if user supplied parameter
22
+
23
+
24
+ class ObjectiveType(TypedDict):
25
+ sense: Literal["minimize", "maximize"] # objective sense
26
+ expression_nl: str # sympy-representable mathematical expression
27
+ tags: List[
28
+ Literal["linear", "quadratic", "nonlinear", "convex", "nonconvex"]
29
+ ] # objective type
30
+
31
+
32
+ class ConstraintType(TypedDict):
33
+ name: str # constraint name
34
+ expression_nl: str # sympy-representable mathematical expression
35
+ tags: List[
36
+ Literal[
37
+ "linear",
38
+ "integer",
39
+ "nonlinear",
40
+ "equality",
41
+ "inequality",
42
+ "infinite-dimensional",
43
+ "finite-dimensional",
44
+ ]
45
+ ] # constraint type
46
+
47
+
48
+ class NotesType(TypedDict):
49
+ verifier: str # problem verification status and explanation
50
+ feasibility: str # problem feasibility status
51
+ user: str # notes to user
52
+ assumptions: str # assumptions made during formulation
53
+
54
+
55
+ class ProblemSpec(TypedDict):
56
+ title: str # name of the problem
57
+ description_nl: str # natural language description
58
+ decision_variables: List[
59
+ DecisionVariableType
60
+ ] # list of all decision variables
61
+ parameters: List[ParameterType] # list of all parameters
62
+ objective: ObjectiveType # structred objective function details
63
+ constraints: List[ConstraintType] # structured constraint details
64
+ problem_class: Optional[str] # optimization problem class
65
+ latex: Optional[str] # latex formulation of the problem
66
+ status: Literal["DRAFT", "VERIFIED", "ERROR"] # problem status
67
+ notes: NotesType # structured notes data
68
+
69
+
70
+ class SolverSpec(TypedDict):
71
+ solver: str # name of the solver, replace with Literal["Gurobi","Ipopt",...] to restrict solvers
72
+ library: str # library or relevant packages for the solver
73
+ algorithm: Optional[str] # algorithm used to solve the problem
74
+ license: Optional[
75
+ str
76
+ ] # License status of the solver (open-source, commercial,etc.)
77
+ parameters: Optional[List[dict]] # other parameters relevant to the problem
78
+ notes: Optional[str] # justifying the choice of solver
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ursa-ai
3
- Version: 0.5.0
3
+ Version: 0.6.0rc2
4
4
  Summary: Agents for science at LANL
5
5
  Author-email: Mike Grosskopf <mikegros@lanl.gov>, Nathan Debardeleben <ndebard@lanl.gov>, Rahul Somasundaram <rsomasundaram@lanl.gov>, Isaac Michaud <imichaud@lanl.gov>, Avanish Mishra <avanish@lanl.gov>, Arthur Lui <alui@lanl.gov>, Russell Bent <rbent@lanl.gov>, Earl Lawrence <earl@lanl.gov>
6
6
  License-Expression: BSD-3-Clause
@@ -38,8 +38,7 @@ Requires-Dist: langchain-anthropic<0.4,>=0.3.19
38
38
  Requires-Dist: langgraph-checkpoint-sqlite<3.0,>=2.0.10
39
39
  Requires-Dist: langchain-ollama<0.4,>=0.3.6
40
40
  Requires-Dist: ddgs>=9.5.5
41
- Requires-Dist: atomman>=1.5.2
42
- Requires-Dist: trafilatura>=1.6.1
41
+ Requires-Dist: typer>=0.16.1
43
42
  Dynamic: license-file
44
43
 
45
44
  # URSA - The Universal Research and Scientific Agent
@@ -81,7 +80,68 @@ Documentation for combining agents:
81
80
  - [ArXiv -> Execution for Materials](docs/combining_arxiv_and_execution.md)
82
81
  - [ArXiv -> Execution for Neutron Star Properties](docs/combining_arxiv_and_execution_neutronStar.md)
83
82
 
84
- # Sandboxing
83
+
84
+ ## Command line usage
85
+
86
+ You can install `ursa` as a command line app with `pip install`; or with `uv` via
87
+
88
+ ```bash
89
+ uv tool install ursa-ai
90
+ ```
91
+
92
+ To use the command line app, run
93
+
94
+ ```
95
+ ursa run
96
+ ```
97
+
98
+ This will start a REPL in your terminal.
99
+
100
+ ```
101
+ __ ________________ _
102
+ / / / / ___/ ___/ __ `/
103
+ / /_/ / / (__ ) /_/ /
104
+ \__,_/_/ /____/\__,_/
105
+
106
+ For help, type: ? or help. Exit with Ctrl+d.
107
+ ursa>
108
+ ```
109
+
110
+ Within the REPL, you can get help by typing `?` or `help`.
111
+
112
+ You can chat with an LLM by simply typing into the terminal.
113
+
114
+ ```
115
+ ursa> How are you?
116
+ Thanks for asking! I’m doing well. How are you today? What can I help you with?
117
+ ```
118
+
119
+ You can run various agents by typing the name of the agent. For example,
120
+
121
+ ```
122
+ ursa> plan
123
+ Enter your prompt for Planning Agent: Write a python script to do linear regression using only numpy.
124
+ ```
125
+
126
+ If you run subsequent agents, the last output will be appended to the prompt for the next agent.
127
+
128
+ So, to run the Planning Agent followed by the Execution Agent:
129
+ ```
130
+ ursa> plan
131
+ Enter your prompt for Planning Agent: Write a python script to do linear regression using only numpy.
132
+
133
+ ...
134
+
135
+ ursa> execute
136
+ Enter your prompt for Execution Agent: Execute the plan.
137
+ ```
138
+
139
+ You can get a list of available command line options via
140
+ ```
141
+ ursa run --help
142
+ ```
143
+
144
+ ## Sandboxing
85
145
  The Execution Agent is allowed to run system commands and write/run code. Being able to execute arbitrary system commands or write
86
146
  and execute code has the potential to cause problems like:
87
147
  - Damage code or data on the computer
@@ -98,6 +158,65 @@ Some suggestions for sandboxing the agent:
98
158
 
99
159
  You have a duty for ensuring that you use URSA responsibly.
100
160
 
161
+ ## Container image
162
+
163
+ To enable limited sandboxing insofar as containerization does this, you can run
164
+ the following commands:
165
+
166
+ ### Docker
167
+
168
+ ```shell
169
+ # Build a local container using the Docker runtime
170
+ docker buildx build --progress=plain -t ursa .
171
+
172
+ # Run included example
173
+ docker run -e "OPENAI_API_KEY"=$OPENAI_API_KEY ursa \
174
+ bash -c "uv run python examples/single_agent_examples/execution_agnet/integer_sum.py"
175
+
176
+ # Run script from host system
177
+ mkdir -p scripts
178
+ echo "import ursa; print('Hello from ursa')" > scripts/my_script.py
179
+ docker run -e "OPENAI_API_KEY"=$OPENAI_API_KEY \
180
+ --mount type=bind,src=$PWD/scripts,dst=/mnt/workspace \
181
+ ursa \
182
+ bash -c "uv run /mnt/workspace/my_script.py"
183
+ ```
184
+
185
+ ### Charliecloud
186
+
187
+ [Charliecloud](https://charliecloud.io/) is a rootless alternative to docker
188
+ that is sometimes preferred on HPC. The following commands replicate the
189
+ behaviors above for docker.
190
+
191
+ ```shell
192
+ # Build a local container using the Docker runtime
193
+ ch-image build -t ursa
194
+
195
+ # Convert image to sqfs, for use on another system
196
+ ch-convert ursa ursa.sqfs
197
+
198
+ # Run included example (if wanted, replace ursa with /path/to/ursa.sqfs)
199
+ ch-run -W ursa \
200
+ --unset-env="*" \
201
+ --set-env \
202
+ --set-env="OPENAI_API_KEY"=$OPENAI_API_KEY \
203
+ --cd /app \
204
+ -- bash -c \
205
+ "uv run python examples/single_agent_examples/execution_agnet/integer_sum.py"
206
+
207
+ # Run script from host system (if wanted, replace ursa with /path/to/ursa.sqfs)
208
+ mkdir -p scripts
209
+ echo "import ursa; print('Hello from ursa')" > scripts/my_script.py
210
+ ch-run -W ursa \
211
+ --unset-env="*" \
212
+ --set-env \
213
+ --set-env="OPENAI_API_KEY"=$OPENAI_API_KEY \
214
+ --bind ${PWD}/scripts:/mnt/workspace \
215
+ --cd /app \
216
+ -- bash -c \
217
+ "uv run python /mnt/workspace/integer_sum.py"
218
+ ```
219
+
101
220
  ## Development Dependencies
102
221
 
103
222
  * [`uv`](https://docs.astral.sh/uv/)
@@ -0,0 +1,39 @@
1
+ ursa/agents/__init__.py,sha256=u5ClncJ-w4nIJLQJTOC-NBv6Hu4pXxALgZJJxDt3tZw,1202
2
+ ursa/agents/arxiv_agent.py,sha256=naXZuPd3tHuyjqoldsN1gJXWcGB6GJaEdtEzfP1JO1w,14570
3
+ ursa/agents/base.py,sha256=XZ62XhF-GdMykdUyiMuxqQwt41hrryaK9aBhgIFJMMQ,14482
4
+ ursa/agents/code_review_agent.py,sha256=aUDq5gT-jdl9Qs-Wewj2oz1d60xov9sN-DOYRfGNTU0,11550
5
+ ursa/agents/execution_agent.py,sha256=gMQsiNoj8feG3kalcVs39AV58GXrfvq6jff3m2ecyyw,17923
6
+ ursa/agents/hypothesizer_agent.py,sha256=2jSOHkR8MjNhS5HMeOhZCkhT4wGDLNBs-aLgQhYBHr4,23124
7
+ ursa/agents/lammps_agent.py,sha256=z7RbZwk70aC31CyagXk3LyPhtU4IInUMMa1v8r2qji4,14774
8
+ ursa/agents/mp_agent.py,sha256=HvD4JC9OuGeEicW3mKZBQmQ1yn0HVB03118E1urXwx4,6833
9
+ ursa/agents/optimization_agent.py,sha256=E2Egh_xi1vwRaAAn7qZJsBRCWgUN6cH2HFJYX6LHOJA,13932
10
+ ursa/agents/planning_agent.py,sha256=9XwwmcEtNHW8xd4osljawp1V0X4y9t3R6ncHrsPo1eo,6489
11
+ ursa/agents/rag_agent.py,sha256=kc7ZYWxgWNh-LbMpREaJY90IVbs2SKPrXdCutxrEdT0,10099
12
+ ursa/agents/recall_agent.py,sha256=MoS0FaQFAb14DeYSCo6sYKNTjvE_u-egTOvuXSTXLpk,1693
13
+ ursa/agents/websearch_agent.py,sha256=7d9EL9r2vqlJHwU1nOeV_moc0p4Jxbfz2awOMrKsf0k,7759
14
+ ursa/cli/__init__.py,sha256=YYh7E1Ce3fcJaYn1XP19U1d9iHG1INfnMQ6gAhtARKM,3879
15
+ ursa/cli/hitl.py,sha256=NIKr72fIdwXE_g6KtRc6c94zSRvft2Ptyi4F0UPSBI8,14695
16
+ ursa/observability/pricing.py,sha256=wNe51EcYjk3KDSuU8rv_vjOPlGZB3We_dQrVBcPXdWA,10551
17
+ ursa/observability/timing.py,sha256=yQX5ZtkxRBH_1V61KjWmEBph02DOeZuP-v0-OtJNffQ,48612
18
+ ursa/prompt_library/code_review_prompts.py,sha256=-HuhwW9W_p2LDn44bXLntxLADHCOyl-2KIXxRHto66w,2444
19
+ ursa/prompt_library/execution_prompts.py,sha256=bJpRPBW-6d41amqC5DXqcIwsoOPpMvY7ZMNGVsJWgII,2388
20
+ ursa/prompt_library/hypothesizer_prompts.py,sha256=ieupOF5tUy_u8actOjPbK-y5Qkrgw6EYxAfw6RXBebs,762
21
+ ursa/prompt_library/literature_prompts.py,sha256=zhBiN3Q-1Z2hp-hkXXp0T8Ipc-6YUM9gw85DjNu1F6I,421
22
+ ursa/prompt_library/optimization_prompts.py,sha256=n3fNBsG0hmggAMPb5R7t2lyxBLQt1E_udXM0bAl8Jz4,7929
23
+ ursa/prompt_library/planning_prompts.py,sha256=C8IfVc3ny_5-03bJZop2Yax7wfqS_UIdUGsTZSNQRC0,3534
24
+ ursa/prompt_library/websearch_prompts.py,sha256=n4DJaYn_lIYAVtdy00CCJjT-dLWhn2JNipYqMJAotdY,8846
25
+ ursa/tools/feasibility_checker.py,sha256=Tboc_3vDx8Pb-cs56SfiXOsayLz8AkXyicfz6puKZ_U,4172
26
+ ursa/tools/feasibility_tools.py,sha256=Drr3L238hzXieNIzQ0UNfrn66mZon7YnM_diSgU9KQw,36921
27
+ ursa/tools/run_command.py,sha256=sQRuHtRyJYWEyL9dpW_Ukc-xQ5vmKKJK1i_6z3uKEfA,690
28
+ ursa/tools/write_code.py,sha256=DtCsUMZegYm0mk-HMPG5Zo3Ba1gbGfnXHsv1NZTdDs8,1220
29
+ ursa/util/diff_renderer.py,sha256=1L1q2qWWb8gLhR532-LgJn2TrqXDx0gUpPVOWD_sqeU,4086
30
+ ursa/util/helperFunctions.py,sha256=cs-pQEcXyOr4nb5FoH9Ssg3hktycEapW07-MKJcUNOA,4122
31
+ ursa/util/memory_logger.py,sha256=GiKYbQBpxlNRLKyqKFJyrbSbVCkXpRB7Yr5so43tUAw,6097
32
+ ursa/util/optimization_schema.py,sha256=b2wO0BjCIgQb15Q3adDu-ZyG3dfncme9OGQw6FmDGDc,2731
33
+ ursa/util/parse.py,sha256=M0cjyQWmjatxX4WbVmDRUiirTLyW-t_Aemlrlrsc5nA,2811
34
+ ursa_ai-0.6.0rc2.dist-info/licenses/LICENSE,sha256=4Vr6_u2zTHIUvYjoOBg9ztDbfpV3hyCFv3mTCS87gYU,1482
35
+ ursa_ai-0.6.0rc2.dist-info/METADATA,sha256=hUWCbZpoP9UfpE-LUhzy6RPsMtByjobHcakecXF1R7A,9888
36
+ ursa_ai-0.6.0rc2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
+ ursa_ai-0.6.0rc2.dist-info/entry_points.txt,sha256=B0bbgM-NcAqLujZ1lfmChJZpQMYQDYFJck4moU89Y4E,39
38
+ ursa_ai-0.6.0rc2.dist-info/top_level.txt,sha256=OjA1gRYSUAeiXGnpqPC8iOOGfcjFO1IlP848qMnYSdY,5
39
+ ursa_ai-0.6.0rc2.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ ursa = ursa.cli:main
@@ -1,28 +0,0 @@
1
- ursa/agents/__init__.py,sha256=u5ClncJ-w4nIJLQJTOC-NBv6Hu4pXxALgZJJxDt3tZw,1202
2
- ursa/agents/arxiv_agent.py,sha256=kiRPshNI-fR-uEFZGp6dyfQ38sIFFb6rUiiNVw3lAXc,13494
3
- ursa/agents/base.py,sha256=uFhRLVzqhFbTZVA7IePKbUi03ATCXuvga7rzwaHy1B0,1321
4
- ursa/agents/code_review_agent.py,sha256=aUDq5gT-jdl9Qs-Wewj2oz1d60xov9sN-DOYRfGNTU0,11550
5
- ursa/agents/execution_agent.py,sha256=okVTsZhG0S92evHtmxge3Ymq3pH0QLYY2VqzO39WG5Y,16581
6
- ursa/agents/hypothesizer_agent.py,sha256=pUwFDWGBJAqL7CDXxWYJrQrknC3DgRe82Poc_Q_OSMg,23193
7
- ursa/agents/lammps_agent.py,sha256=16eKOtAXEm-clnIZcfEaoxQONqbUJm_1dZhZhm2C2uM,14099
8
- ursa/agents/mp_agent.py,sha256=UyJSheMGHZpWQJL3EgYgPPqArfv6F8sndN05q4CPtyo,6015
9
- ursa/agents/planning_agent.py,sha256=ayyNDQifPvYtQ-JYnFk3TaXWZcd_6k8qUheJGariqG8,5574
10
- ursa/agents/rag_agent.py,sha256=kEL5F3lZeSKtdXXyUWlXJYYwP2ZNQ1Hz9IWl6pzQnlY,9409
11
- ursa/agents/recall_agent.py,sha256=bQk7ZJtiO5pj89A50OBDzAJ4G2F7ZdsMwmKnp1WWR7g,813
12
- ursa/agents/websearch_agent.py,sha256=rCv4AWbqe5Us4FmuypM6jptri21nKoNg044ncsu9u3E,8014
13
- ursa/prompt_library/code_review_prompts.py,sha256=-HuhwW9W_p2LDn44bXLntxLADHCOyl-2KIXxRHto66w,2444
14
- ursa/prompt_library/execution_prompts.py,sha256=JBBmzVV0605uwFXNv0pxH0fXHqtmOgcDzabjpq3wt2A,2153
15
- ursa/prompt_library/hypothesizer_prompts.py,sha256=ieupOF5tUy_u8actOjPbK-y5Qkrgw6EYxAfw6RXBebs,762
16
- ursa/prompt_library/literature_prompts.py,sha256=zhBiN3Q-1Z2hp-hkXXp0T8Ipc-6YUM9gw85DjNu1F6I,421
17
- ursa/prompt_library/planning_prompts.py,sha256=C8IfVc3ny_5-03bJZop2Yax7wfqS_UIdUGsTZSNQRC0,3534
18
- ursa/prompt_library/websearch_prompts.py,sha256=n4DJaYn_lIYAVtdy00CCJjT-dLWhn2JNipYqMJAotdY,8846
19
- ursa/tools/run_command.py,sha256=sQRuHtRyJYWEyL9dpW_Ukc-xQ5vmKKJK1i_6z3uKEfA,690
20
- ursa/tools/write_code.py,sha256=DtCsUMZegYm0mk-HMPG5Zo3Ba1gbGfnXHsv1NZTdDs8,1220
21
- ursa/util/diff_renderer.py,sha256=1L1q2qWWb8gLhR532-LgJn2TrqXDx0gUpPVOWD_sqeU,4086
22
- ursa/util/memory_logger.py,sha256=GiKYbQBpxlNRLKyqKFJyrbSbVCkXpRB7Yr5so43tUAw,6097
23
- ursa/util/parse.py,sha256=M0cjyQWmjatxX4WbVmDRUiirTLyW-t_Aemlrlrsc5nA,2811
24
- ursa_ai-0.5.0.dist-info/licenses/LICENSE,sha256=4Vr6_u2zTHIUvYjoOBg9ztDbfpV3hyCFv3mTCS87gYU,1482
25
- ursa_ai-0.5.0.dist-info/METADATA,sha256=Um85Xzvs6LSGUg9X0tWitsLVwYqYgMJ0I3EhYzK8oIE,6898
26
- ursa_ai-0.5.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
- ursa_ai-0.5.0.dist-info/top_level.txt,sha256=OjA1gRYSUAeiXGnpqPC8iOOGfcjFO1IlP848qMnYSdY,5
28
- ursa_ai-0.5.0.dist-info/RECORD,,