ldbg 0.1.0__tar.gz
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.
- ldbg-0.1.0/.gitignore +12 -0
- ldbg-0.1.0/.python-version +1 -0
- ldbg-0.1.0/PKG-INFO +117 -0
- ldbg-0.1.0/README.md +108 -0
- ldbg-0.1.0/pyproject.toml +23 -0
- ldbg-0.1.0/src/ldbg/__init__.py +3 -0
- ldbg-0.1.0/src/ldbg/ldbg.py +303 -0
- ldbg-0.1.0/src/ldbg/py.typed +0 -0
- ldbg-0.1.0/tests/test_ldbg.py +140 -0
- ldbg-0.1.0/uv.lock +535 -0
ldbg-0.1.0/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.12
|
ldbg-0.1.0/PKG-INFO
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: ldbg
|
3
|
+
Version: 0.1.0
|
4
|
+
Summary: Add your description here
|
5
|
+
Author-email: Arthur Masson <arthur.masson@inria.fr>
|
6
|
+
Requires-Python: >=3.12
|
7
|
+
Requires-Dist: openai>=1.107.3
|
8
|
+
Description-Content-Type: text/markdown
|
9
|
+
|
10
|
+
# llm-debug
|
11
|
+
|
12
|
+
### A Minimal Python Library to debug with LLMs
|
13
|
+
|
14
|
+
Use natural-language prompts while debugging. Prompts are augmented with your current stack, variables, and source context.
|
15
|
+
|
16
|
+
DO NOT USE THIS LIBRARY
|
17
|
+
|
18
|
+
> “AI everywhere is rocket engines on a skateboard: a thrill that ends in wreckage. The planet pays in energy and emissions, and we pay in something subtler — the slow atrophy of our own intelligence, left idle while the machines do the heavy lifting.” ChatGPT
|
19
|
+
|
20
|
+
## Features
|
21
|
+
|
22
|
+
- 🐍 Generate Python debug commands from natural-language instructions.
|
23
|
+
- 🔍 Context-aware: prompt auto-includes call stack, local/global variable previews, current function - source, and nearby code.
|
24
|
+
- ⚡ Works like an AI-augmented pdb: just ask what you want to inspect.
|
25
|
+
- 🤖 Supports OpenRouter
|
26
|
+
|
27
|
+
## Installation
|
28
|
+
|
29
|
+
`pip install ldbg`
|
30
|
+
|
31
|
+
## Quick Start
|
32
|
+
|
33
|
+
### Example Session
|
34
|
+
|
35
|
+
```python
|
36
|
+
|
37
|
+
>>> unknown_data = np.arange(9)
|
38
|
+
>>> example_dict = {"a": 1, "b": [1, 2, 3]}
|
39
|
+
>>> example_numbers = list(range(10))
|
40
|
+
>>> import ldbg
|
41
|
+
>>> ldbg.gc("describe unknown_data")
|
42
|
+
The model "gpt-5-mini-2025-08-07" says:
|
43
|
+
|
44
|
+
unknown_data is an numpy array which can be described with the following pandas code:
|
45
|
+
|
46
|
+
```code block 1
|
47
|
+
pandas.DataFrame(unknown_data).describe()
|
48
|
+
```
|
49
|
+
|
50
|
+
Note: you can use numpy.set_printoptions (or a library like numpyprint) to pretty print your array:
|
51
|
+
|
52
|
+
```code block 2
|
53
|
+
with np.printoptions(precision=2, suppress=True, threshold=5):
|
54
|
+
unknown_data
|
55
|
+
```
|
56
|
+
|
57
|
+
Would you like to execute the following code block:
|
58
|
+
pandas.DataFrame(unknown_data).describe()
|
59
|
+
(y/n)
|
60
|
+
```
|
61
|
+
|
62
|
+
User enters y:
|
63
|
+
```
|
64
|
+
0
|
65
|
+
count 9.000000
|
66
|
+
mean 4.000000
|
67
|
+
std 2.738613
|
68
|
+
min 0.000000
|
69
|
+
25% 2.000000
|
70
|
+
50% 4.000000
|
71
|
+
75% 6.000000
|
72
|
+
max 8.000000
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
Would you like to execute the following code block:
|
77
|
+
with np.printoptions(precision=2, suppress=True, threshold=5):
|
78
|
+
unknown_data
|
79
|
+
(y/n)
|
80
|
+
```
|
81
|
+
|
82
|
+
User enters n and continues:
|
83
|
+
|
84
|
+
```python
|
85
|
+
>>> ldbg.gc("plot example_numbers as a bar chart")
|
86
|
+
The model "gpt-5-mini-2025-08-07" says:
|
87
|
+
|
88
|
+
```
|
89
|
+
import matplotlib.pyplot as plt
|
90
|
+
plt.bar(range(len(numbers)), numbers)
|
91
|
+
plt.show()
|
92
|
+
```
|
93
|
+
|
94
|
+
Would you like to execute the following code block:
|
95
|
+
...
|
96
|
+
```
|
97
|
+
|
98
|
+
### Example natural-language prompts
|
99
|
+
|
100
|
+
- "Describe my numpy arrays"
|
101
|
+
- "plot my_data['b'] as a histogram"
|
102
|
+
- "give me an example pandas dataframe about employees"
|
103
|
+
- "generate a 3x10x12 numpy array which will be used as an example image"
|
104
|
+
- "convert this Pillow image to grayscale"
|
105
|
+
- "open this 'image.ome.tiff' with bioio"
|
106
|
+
|
107
|
+
## Configuration
|
108
|
+
|
109
|
+
By default, llm-debug uses the OpenAI client. So it reads the [OPENAI_API_KEY environment variable](https://platform.openai.com/docs/quickstart).
|
110
|
+
|
111
|
+
To use OpenRouter instead, define the `OPENROUTER_API_KEY` environment variable:
|
112
|
+
|
113
|
+
`export OPENROUTER_API_KEY="your_api_key_here"`
|
114
|
+
|
115
|
+
## License
|
116
|
+
|
117
|
+
MIT License.
|
ldbg-0.1.0/README.md
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
# llm-debug
|
2
|
+
|
3
|
+
### A Minimal Python Library to debug with LLMs
|
4
|
+
|
5
|
+
Use natural-language prompts while debugging. Prompts are augmented with your current stack, variables, and source context.
|
6
|
+
|
7
|
+
DO NOT USE THIS LIBRARY
|
8
|
+
|
9
|
+
> “AI everywhere is rocket engines on a skateboard: a thrill that ends in wreckage. The planet pays in energy and emissions, and we pay in something subtler — the slow atrophy of our own intelligence, left idle while the machines do the heavy lifting.” ChatGPT
|
10
|
+
|
11
|
+
## Features
|
12
|
+
|
13
|
+
- 🐍 Generate Python debug commands from natural-language instructions.
|
14
|
+
- 🔍 Context-aware: prompt auto-includes call stack, local/global variable previews, current function - source, and nearby code.
|
15
|
+
- ⚡ Works like an AI-augmented pdb: just ask what you want to inspect.
|
16
|
+
- 🤖 Supports OpenRouter
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
`pip install ldbg`
|
21
|
+
|
22
|
+
## Quick Start
|
23
|
+
|
24
|
+
### Example Session
|
25
|
+
|
26
|
+
```python
|
27
|
+
|
28
|
+
>>> unknown_data = np.arange(9)
|
29
|
+
>>> example_dict = {"a": 1, "b": [1, 2, 3]}
|
30
|
+
>>> example_numbers = list(range(10))
|
31
|
+
>>> import ldbg
|
32
|
+
>>> ldbg.gc("describe unknown_data")
|
33
|
+
The model "gpt-5-mini-2025-08-07" says:
|
34
|
+
|
35
|
+
unknown_data is an numpy array which can be described with the following pandas code:
|
36
|
+
|
37
|
+
```code block 1
|
38
|
+
pandas.DataFrame(unknown_data).describe()
|
39
|
+
```
|
40
|
+
|
41
|
+
Note: you can use numpy.set_printoptions (or a library like numpyprint) to pretty print your array:
|
42
|
+
|
43
|
+
```code block 2
|
44
|
+
with np.printoptions(precision=2, suppress=True, threshold=5):
|
45
|
+
unknown_data
|
46
|
+
```
|
47
|
+
|
48
|
+
Would you like to execute the following code block:
|
49
|
+
pandas.DataFrame(unknown_data).describe()
|
50
|
+
(y/n)
|
51
|
+
```
|
52
|
+
|
53
|
+
User enters y:
|
54
|
+
```
|
55
|
+
0
|
56
|
+
count 9.000000
|
57
|
+
mean 4.000000
|
58
|
+
std 2.738613
|
59
|
+
min 0.000000
|
60
|
+
25% 2.000000
|
61
|
+
50% 4.000000
|
62
|
+
75% 6.000000
|
63
|
+
max 8.000000
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
Would you like to execute the following code block:
|
68
|
+
with np.printoptions(precision=2, suppress=True, threshold=5):
|
69
|
+
unknown_data
|
70
|
+
(y/n)
|
71
|
+
```
|
72
|
+
|
73
|
+
User enters n and continues:
|
74
|
+
|
75
|
+
```python
|
76
|
+
>>> ldbg.gc("plot example_numbers as a bar chart")
|
77
|
+
The model "gpt-5-mini-2025-08-07" says:
|
78
|
+
|
79
|
+
```
|
80
|
+
import matplotlib.pyplot as plt
|
81
|
+
plt.bar(range(len(numbers)), numbers)
|
82
|
+
plt.show()
|
83
|
+
```
|
84
|
+
|
85
|
+
Would you like to execute the following code block:
|
86
|
+
...
|
87
|
+
```
|
88
|
+
|
89
|
+
### Example natural-language prompts
|
90
|
+
|
91
|
+
- "Describe my numpy arrays"
|
92
|
+
- "plot my_data['b'] as a histogram"
|
93
|
+
- "give me an example pandas dataframe about employees"
|
94
|
+
- "generate a 3x10x12 numpy array which will be used as an example image"
|
95
|
+
- "convert this Pillow image to grayscale"
|
96
|
+
- "open this 'image.ome.tiff' with bioio"
|
97
|
+
|
98
|
+
## Configuration
|
99
|
+
|
100
|
+
By default, llm-debug uses the OpenAI client. So it reads the [OPENAI_API_KEY environment variable](https://platform.openai.com/docs/quickstart).
|
101
|
+
|
102
|
+
To use OpenRouter instead, define the `OPENROUTER_API_KEY` environment variable:
|
103
|
+
|
104
|
+
`export OPENROUTER_API_KEY="your_api_key_here"`
|
105
|
+
|
106
|
+
## License
|
107
|
+
|
108
|
+
MIT License.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
[project]
|
2
|
+
name = "ldbg"
|
3
|
+
version = "0.1.0"
|
4
|
+
description = "Add your description here"
|
5
|
+
readme = "README.md"
|
6
|
+
authors = [
|
7
|
+
{ name = "Arthur Masson", email = "arthur.masson@inria.fr" }
|
8
|
+
]
|
9
|
+
requires-python = ">=3.12"
|
10
|
+
dependencies = [
|
11
|
+
"openai>=1.107.3",
|
12
|
+
]
|
13
|
+
|
14
|
+
[build-system]
|
15
|
+
requires = ["hatchling"]
|
16
|
+
build-backend = "hatchling.build"
|
17
|
+
|
18
|
+
[dependency-groups]
|
19
|
+
dev = [
|
20
|
+
"ipython>=9.5.0",
|
21
|
+
"pytest>=8.4.2",
|
22
|
+
"ruff>=0.14.0",
|
23
|
+
]
|
@@ -0,0 +1,303 @@
|
|
1
|
+
import inspect
|
2
|
+
import re
|
3
|
+
import textwrap
|
4
|
+
import traceback
|
5
|
+
import linecache
|
6
|
+
import os
|
7
|
+
import pprint
|
8
|
+
from types import FrameType
|
9
|
+
from typing import cast
|
10
|
+
|
11
|
+
from openai import OpenAI
|
12
|
+
|
13
|
+
LENGTH_MAX = 10000
|
14
|
+
CODE_BLOCK_REGEX = r"```(?:[\w+-]*)\n(.*?)```"
|
15
|
+
|
16
|
+
if "OPENROUTER_API_KEY" in os.environ:
|
17
|
+
client = OpenAI(
|
18
|
+
base_url="https://openrouter.ai/api/v1",
|
19
|
+
api_key=os.environ["OPENROUTER_API_KEY"],
|
20
|
+
)
|
21
|
+
else:
|
22
|
+
client = OpenAI()
|
23
|
+
|
24
|
+
|
25
|
+
def extract_code_blocks(markdown_text: str):
|
26
|
+
pattern = re.compile(CODE_BLOCK_REGEX, re.DOTALL)
|
27
|
+
return pattern.findall(markdown_text)
|
28
|
+
|
29
|
+
|
30
|
+
def execute_code_block(code: str):
|
31
|
+
exec(code, {})
|
32
|
+
|
33
|
+
|
34
|
+
def execute_blocks(markdown_text: str | None) -> None:
|
35
|
+
"""
|
36
|
+
Extract the code blocks in the markdown and ask user if he wants to execute them
|
37
|
+
"""
|
38
|
+
if markdown_text is None:
|
39
|
+
return
|
40
|
+
blocks = extract_code_blocks(markdown_text)
|
41
|
+
for block in blocks:
|
42
|
+
print("Would you like to execute the following code block:")
|
43
|
+
print(textwrap.indent(block, " "))
|
44
|
+
confirm = input("(y/n)").lower()
|
45
|
+
if confirm.lower() in ["yes", "y"]:
|
46
|
+
execute_code_block(block)
|
47
|
+
|
48
|
+
|
49
|
+
def generate_commands(
|
50
|
+
prompt: str,
|
51
|
+
frame=None,
|
52
|
+
model="gpt-5-mini-2025-08-07",
|
53
|
+
print_prompt=True,
|
54
|
+
length_max=LENGTH_MAX,
|
55
|
+
context="",
|
56
|
+
):
|
57
|
+
"""
|
58
|
+
Generate Python debug help based on natural-language instructions.
|
59
|
+
|
60
|
+
Includes:
|
61
|
+
- Call stack / traceback
|
62
|
+
- Current function’s source
|
63
|
+
- Surrounding source lines (like ipdb 'll')
|
64
|
+
|
65
|
+
Example:
|
66
|
+
|
67
|
+
>>> import ldbg
|
68
|
+
>>> ldbg.generate_commands("describe unknown_data")
|
69
|
+
The model "gpt-5-mini-2025-08-07" answered:
|
70
|
+
|
71
|
+
unknown_data is an numpy array which can be described with the following pandas code:
|
72
|
+
|
73
|
+
```
|
74
|
+
pandas.DataFrame(unknown_data).describe()
|
75
|
+
```
|
76
|
+
|
77
|
+
Note: you can use numpy.set_printoptions (or a library like numpyprint) to pretty print your array:
|
78
|
+
|
79
|
+
```
|
80
|
+
with np.printoptions(precision=2, suppress=True, threshold=5):
|
81
|
+
unknown_data
|
82
|
+
```
|
83
|
+
|
84
|
+
Would you like to execute the following code block:
|
85
|
+
pandas.DataFrame(unknown_data).describe()
|
86
|
+
(y/n)?
|
87
|
+
|
88
|
+
|
89
|
+
<<< user enters y
|
90
|
+
0
|
91
|
+
count 9.000000
|
92
|
+
mean 4.000000
|
93
|
+
std 2.738613
|
94
|
+
min 0.000000
|
95
|
+
25% 2.000000
|
96
|
+
50% 4.000000
|
97
|
+
75% 6.000000
|
98
|
+
max 8.000000
|
99
|
+
|
100
|
+
|
101
|
+
Would you like to execute the following code block:
|
102
|
+
with np.printoptions(precision=2, suppress=True, threshold=5):
|
103
|
+
unknown_data
|
104
|
+
(y/n)?
|
105
|
+
|
106
|
+
<<< user enters n
|
107
|
+
"""
|
108
|
+
if frame is None:
|
109
|
+
frame = cast(FrameType, inspect.currentframe().f_back) # type: ignore
|
110
|
+
|
111
|
+
# Locals & globals preview
|
112
|
+
locals_preview = pprint.pformat(frame.f_locals)[
|
113
|
+
:length_max
|
114
|
+
] # {k: type(v).__name__ for k, v in frame.f_locals.items()}
|
115
|
+
globals_preview = pprint.pformat(frame.f_globals)[
|
116
|
+
:length_max
|
117
|
+
] # {k: type(v).__name__ for k, v in frame.f_globals.items()}
|
118
|
+
|
119
|
+
# Traceback / call stack
|
120
|
+
stack_summary = traceback.format_stack(frame)
|
121
|
+
stack_text = "".join(stack_summary[-15:]) # limit to avoid overload
|
122
|
+
|
123
|
+
# Current function source
|
124
|
+
try:
|
125
|
+
source_lines, start_line = inspect.getsourcelines(frame)
|
126
|
+
func_source = "".join(source_lines)
|
127
|
+
except (OSError, TypeError):
|
128
|
+
func_source = "<source unavailable>"
|
129
|
+
|
130
|
+
# Context like ipdb 'll'
|
131
|
+
filename = frame.f_code.co_filename
|
132
|
+
lineno = frame.f_lineno
|
133
|
+
start_context = max(lineno - 10, 1)
|
134
|
+
context_lines = []
|
135
|
+
for i in range(start_context, lineno + 10):
|
136
|
+
line = linecache.getline(filename, i)
|
137
|
+
if line:
|
138
|
+
context_lines.append(f"{i:4d}: {line}")
|
139
|
+
context_text = "".join(context_lines)
|
140
|
+
|
141
|
+
# ldbg.generate_commands({prompt}, model={model}, code_only={code_only}, print_prompt={print_prompt}, print_answer={print_answer}, length_max={length_max})
|
142
|
+
context = textwrap.dedent(f"""
|
143
|
+
You are a Python debugging assistant.
|
144
|
+
The user is paused inside a Python script.
|
145
|
+
|
146
|
+
The user just ran `import ldbg; ldbg.gc({prompt}, model={model})` to ask you some help (gc stands for generate commands).
|
147
|
+
|
148
|
+
Local variables and their types (`locals = pprint.pformat(inspect.currentframe().f_locals)[:length_max]`):
|
149
|
+
{locals_preview}
|
150
|
+
|
151
|
+
Global variables and their types (`globals = pprint.pformat(inspect.currentframe().f_globals)[:length_max]`):
|
152
|
+
{globals_preview}
|
153
|
+
|
154
|
+
Current call stack (traceback):
|
155
|
+
{stack_text}
|
156
|
+
|
157
|
+
Current function source:
|
158
|
+
{func_source}
|
159
|
+
|
160
|
+
Nearby code (like ipdb 'll'):
|
161
|
+
{context_text}
|
162
|
+
|
163
|
+
Additional context:
|
164
|
+
{context}
|
165
|
+
|
166
|
+
If you need more context, a more detailed view of the local variables or the content of a source file,
|
167
|
+
tell the user the commands he should run to print the details you need.
|
168
|
+
|
169
|
+
For example, if you need to know more details about the local variables, tell him:
|
170
|
+
|
171
|
+
I need more context to help you.
|
172
|
+
Could you execute the following commands to give me more context? They will provide the details I need to help you.
|
173
|
+
|
174
|
+
```
|
175
|
+
import inspect
|
176
|
+
frame = inspect.currentframe()
|
177
|
+
# Get frame.f_locals with a depth of 2
|
178
|
+
local_variables = pprint.pformat(frame.f_locals, depth=2)
|
179
|
+
```
|
180
|
+
|
181
|
+
Then you can ask me again:
|
182
|
+
```
|
183
|
+
ldbg.gc({prompt}, model={model}, context = f"local variables are: {{local_variables:.50000}}")
|
184
|
+
```
|
185
|
+
|
186
|
+
Another example, if you need to know the content of some source files:
|
187
|
+
|
188
|
+
I need more context to help you.
|
189
|
+
Could you execute the following commands to give me more context? They will provide the details I need to help you.
|
190
|
+
|
191
|
+
```
|
192
|
+
# Get the content of important.py
|
193
|
+
import_file_path = list(Path().glob('**/important.py'))[0]
|
194
|
+
|
195
|
+
with open(import_file_path) as f:
|
196
|
+
important_content = f.read()
|
197
|
+
|
198
|
+
# Find the lines surrounding the class ImportantClass in very_large_script.py
|
199
|
+
search = "class ImportantClass"
|
200
|
+
with open('path/to/important/very_large_script.py') as f:
|
201
|
+
lines = f.readlines()
|
202
|
+
|
203
|
+
# Find the 0-based index of the first matching line
|
204
|
+
idx = next(i for i, line in enumerate(lines) if search in line)
|
205
|
+
|
206
|
+
# Calculate start and end indices
|
207
|
+
start = max(0, idx - 10)
|
208
|
+
end = min(len(lines), idx + 10 + 1)
|
209
|
+
|
210
|
+
# Get the surrounding lines
|
211
|
+
script_content = []
|
212
|
+
for i, line in enumerate(lines[start:end]):
|
213
|
+
script_content.append(f"{{start + i + 1:04d}}: {{line.rstrip()}}")
|
214
|
+
```
|
215
|
+
|
216
|
+
Then you can ask me again:
|
217
|
+
```
|
218
|
+
ldbg.gc({prompt}, model={model}, context=f"important.py: {{important_content:.50000}}, very_large_script.py (lines {{start}} to {{end}}): {{script_content:.50000}}")
|
219
|
+
```
|
220
|
+
|
221
|
+
You can also ask for help in multiple steps:
|
222
|
+
|
223
|
+
Could you execute the following commands to give me more context?
|
224
|
+
This will tell me all the source files in the current working directory.
|
225
|
+
|
226
|
+
```
|
227
|
+
import pathlib
|
228
|
+
EXCLUDED = {{".venv", ".pixi"}}
|
229
|
+
python_files = [str(p) for p in pathlib.Path('.').rglob('*.py') if not any(part in EXCLUDED for part in p.parts)]
|
230
|
+
```
|
231
|
+
|
232
|
+
Then you can ask me again:
|
233
|
+
```
|
234
|
+
ldbg.gc({prompt}, model={model}, context=f"the python files are: {{python_files:.50000}}")
|
235
|
+
```
|
236
|
+
|
237
|
+
And then I will know more about the project, and I might ask you to execute more commands
|
238
|
+
(for example to read some important files) to get all the context I need.
|
239
|
+
|
240
|
+
The length of your context window is limited and you perform better with focused questions and context.
|
241
|
+
Thus, when you ask the user to execute commands and send you more information,
|
242
|
+
always make sure to be precise so that you get a response of reasonable length.
|
243
|
+
For example, if you need some information in a huge file,
|
244
|
+
provide commands to extract exactly what you need instead of reading the entire file.
|
245
|
+
If you need a specific value deep in the locals values, get `frame.f_locals["deep_object"].deep_dict["deep_attribute"]["sub_attribute"]["etc"]`
|
246
|
+
instead of getting the entire locals with a large depth as in `local_variables = pprint.pformat(frame.f_locals, depth=10)`.
|
247
|
+
|
248
|
+
Cap the length of the responses to avoid reaching the maximum prompt length (which would result in a failure).
|
249
|
+
|
250
|
+
The user is a developer, you can also ask him details about the context in natural language.
|
251
|
+
|
252
|
+
If you have all the context you need, just provide a useful answer.
|
253
|
+
For example, if the user asks "describe unknown_data", you could answer:
|
254
|
+
|
255
|
+
`unknown_data` is an numpy array which can be described with the following pandas code:
|
256
|
+
|
257
|
+
```
|
258
|
+
pandas.DataFrame(unknown_data).describe()
|
259
|
+
```
|
260
|
+
|
261
|
+
You could also use numpy.set_printoptions (or a library like numpyprint) to pretty print your array:
|
262
|
+
|
263
|
+
```
|
264
|
+
with np.printoptions(precision=2, suppress=True, threshold=5):
|
265
|
+
unknown_data
|
266
|
+
```
|
267
|
+
|
268
|
+
Always put the code to execute in triple backticks code blocks.
|
269
|
+
Provide relatively short and concise answers.
|
270
|
+
""")
|
271
|
+
|
272
|
+
if print_prompt:
|
273
|
+
print("System prompt:")
|
274
|
+
print(context)
|
275
|
+
print("\nUser prompt:")
|
276
|
+
print(prompt)
|
277
|
+
|
278
|
+
resp = client.chat.completions.create(
|
279
|
+
model=model,
|
280
|
+
messages=[
|
281
|
+
{"role": "system", "content": context},
|
282
|
+
{"role": "user", "content": prompt},
|
283
|
+
],
|
284
|
+
temperature=1,
|
285
|
+
)
|
286
|
+
|
287
|
+
response = resp.choices[0].message.content
|
288
|
+
|
289
|
+
if print_prompt:
|
290
|
+
print("\n\n\n")
|
291
|
+
|
292
|
+
if response is None:
|
293
|
+
return
|
294
|
+
|
295
|
+
print(f"Model {model} says:")
|
296
|
+
print(textwrap.indent(response, " "))
|
297
|
+
|
298
|
+
execute_blocks(response)
|
299
|
+
|
300
|
+
return
|
301
|
+
|
302
|
+
|
303
|
+
gc = generate_commands
|
File without changes
|
@@ -0,0 +1,140 @@
|
|
1
|
+
import inspect
|
2
|
+
import builtins
|
3
|
+
import types
|
4
|
+
|
5
|
+
import ldbg.ldbg as ldbg
|
6
|
+
|
7
|
+
|
8
|
+
def test_extract_code_blocks_single_block():
|
9
|
+
md = "Here is some text\n```python\nprint('hello')\n```\nmore text"
|
10
|
+
blocks = ldbg.extract_code_blocks(md)
|
11
|
+
assert blocks == ["print('hello')\n"]
|
12
|
+
|
13
|
+
|
14
|
+
def test_extract_code_blocks_multiple_blocks():
|
15
|
+
md = "```\na=1\n```\ntext\n```py\nb=2\n```"
|
16
|
+
blocks = ldbg.extract_code_blocks(md)
|
17
|
+
assert blocks == ["a=1\n", "b=2\n"]
|
18
|
+
|
19
|
+
|
20
|
+
def test_execute_code_block_prints_output(capsys):
|
21
|
+
# execute_code_block uses exec(..., {}) so it runs in an empty namespace.
|
22
|
+
ldbg.execute_code_block("print('hi from code block')")
|
23
|
+
captured = capsys.readouterr()
|
24
|
+
assert "hi from code block" in captured.out
|
25
|
+
|
26
|
+
|
27
|
+
def test_execute_blocks_none_does_nothing(capsys):
|
28
|
+
# Should not raise and should not print anything
|
29
|
+
ldbg.execute_blocks(None)
|
30
|
+
captured = capsys.readouterr()
|
31
|
+
assert captured.out == ""
|
32
|
+
|
33
|
+
|
34
|
+
def test_execute_blocks_user_confirms_exec(monkeypatch, capsys):
|
35
|
+
# Provide markdown with a single code block.
|
36
|
+
md = "Some text\n```\nprint('ran')\n```\n"
|
37
|
+
# Simulate user input 'y'
|
38
|
+
monkeypatch.setattr(builtins, "input", lambda prompt="": "y")
|
39
|
+
executed = {"called": False, "code": None}
|
40
|
+
|
41
|
+
def fake_exec_block(code):
|
42
|
+
executed["called"] = True
|
43
|
+
executed["code"] = code
|
44
|
+
|
45
|
+
monkeypatch.setattr(ldbg, "execute_code_block", fake_exec_block)
|
46
|
+
|
47
|
+
ldbg.execute_blocks(md)
|
48
|
+
|
49
|
+
captured = capsys.readouterr()
|
50
|
+
# We expect to have been prompted and the code executed
|
51
|
+
assert "Would you like to execute the following code block:" in captured.out
|
52
|
+
assert executed["called"] is True
|
53
|
+
assert "print('ran')" in executed["code"]
|
54
|
+
|
55
|
+
|
56
|
+
def test_execute_blocks_user_declines(monkeypatch, capsys):
|
57
|
+
md = "```\nprint('should_not_run')\n```"
|
58
|
+
# Simulate user input 'n'
|
59
|
+
monkeypatch.setattr(builtins, "input", lambda prompt="": "n")
|
60
|
+
executed = {"called": False}
|
61
|
+
|
62
|
+
monkeypatch.setattr(
|
63
|
+
ldbg, "execute_code_block", lambda code: executed.update(called=True)
|
64
|
+
)
|
65
|
+
|
66
|
+
ldbg.execute_blocks(md)
|
67
|
+
captured = capsys.readouterr()
|
68
|
+
assert "Would you like to execute the following code block:" in captured.out
|
69
|
+
assert executed.get("called") is not True
|
70
|
+
|
71
|
+
|
72
|
+
def test_generate_commands_calls_api_and_forwards_response(monkeypatch, capsys):
|
73
|
+
"""
|
74
|
+
Ensure generate_commands:
|
75
|
+
- prints the system/user prompts when print_prompt=True
|
76
|
+
- calls the client.chat.completions.create API
|
77
|
+
- prints the model response and passes it to execute_blocks
|
78
|
+
"""
|
79
|
+
# Create a fake response text that contains a code block
|
80
|
+
fake_response_text = (
|
81
|
+
"Here is a suggestion:\n\n```python\nprint('from model')\n```\n"
|
82
|
+
"And a closing line."
|
83
|
+
)
|
84
|
+
|
85
|
+
# Spy object to verify execute_blocks received the model response
|
86
|
+
called = {"create_called": False, "passed_response": None}
|
87
|
+
|
88
|
+
def fake_create(*args, **kwargs):
|
89
|
+
called["create_called"] = True
|
90
|
+
# Build an object with the expected shape: .choices[0].message.content
|
91
|
+
msg = types.SimpleNamespace(content=fake_response_text)
|
92
|
+
choice = types.SimpleNamespace(message=msg)
|
93
|
+
return types.SimpleNamespace(choices=[choice])
|
94
|
+
|
95
|
+
# Patch the chain client.chat.completions.create
|
96
|
+
monkeypatch.setattr(ldbg.client.chat.completions, "create", fake_create)
|
97
|
+
|
98
|
+
# Patch execute_blocks to capture what is passed
|
99
|
+
def fake_execute_blocks(resp_text):
|
100
|
+
called["passed_response"] = resp_text
|
101
|
+
|
102
|
+
monkeypatch.setattr(ldbg, "execute_blocks", fake_execute_blocks)
|
103
|
+
|
104
|
+
# Call generate_commands from a real frame (the test's current frame) to let it build context
|
105
|
+
frame = inspect.currentframe()
|
106
|
+
# Run function
|
107
|
+
ldbg.generate_commands("describe unknown_data", frame=frame, print_prompt=True)
|
108
|
+
|
109
|
+
captured = capsys.readouterr()
|
110
|
+
# Confirm we printed the System prompt and User prompt
|
111
|
+
assert "System prompt:" in captured.out
|
112
|
+
assert "User prompt:" in captured.out
|
113
|
+
|
114
|
+
# Confirm the API stub was called and execute_blocks got the model response
|
115
|
+
assert called["create_called"] is True
|
116
|
+
assert called["passed_response"] == fake_response_text
|
117
|
+
|
118
|
+
|
119
|
+
def test_generate_commands_handles_none_response(monkeypatch, capsys):
|
120
|
+
"""
|
121
|
+
If the API returns a response object with None content, generate_commands should return gracefully.
|
122
|
+
"""
|
123
|
+
|
124
|
+
def fake_create_none(*args, **kwargs):
|
125
|
+
msg = types.SimpleNamespace(content=None)
|
126
|
+
choice = types.SimpleNamespace(message=msg)
|
127
|
+
return types.SimpleNamespace(choices=[choice])
|
128
|
+
|
129
|
+
monkeypatch.setattr(ldbg.client.chat.completions, "create", fake_create_none)
|
130
|
+
# Patch execute_blocks to ensure it would not be called when response is None
|
131
|
+
monkeypatch.setattr(
|
132
|
+
ldbg,
|
133
|
+
"execute_blocks",
|
134
|
+
lambda t: (_ for _ in ()).throw(AssertionError("should not be called")),
|
135
|
+
)
|
136
|
+
|
137
|
+
# Call - should not raise
|
138
|
+
ldbg.generate_commands(
|
139
|
+
"any prompt", frame=inspect.currentframe(), print_prompt=False
|
140
|
+
)
|
ldbg-0.1.0/uv.lock
ADDED
@@ -0,0 +1,535 @@
|
|
1
|
+
version = 1
|
2
|
+
revision = 3
|
3
|
+
requires-python = ">=3.12"
|
4
|
+
|
5
|
+
[[package]]
|
6
|
+
name = "annotated-types"
|
7
|
+
version = "0.7.0"
|
8
|
+
source = { registry = "https://pypi.org/simple" }
|
9
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" }
|
10
|
+
wheels = [
|
11
|
+
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
|
12
|
+
]
|
13
|
+
|
14
|
+
[[package]]
|
15
|
+
name = "anyio"
|
16
|
+
version = "4.11.0"
|
17
|
+
source = { registry = "https://pypi.org/simple" }
|
18
|
+
dependencies = [
|
19
|
+
{ name = "idna" },
|
20
|
+
{ name = "sniffio" },
|
21
|
+
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
22
|
+
]
|
23
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4", size = 219094, upload-time = "2025-09-23T09:19:12.58Z" }
|
24
|
+
wheels = [
|
25
|
+
{ url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc", size = 109097, upload-time = "2025-09-23T09:19:10.601Z" },
|
26
|
+
]
|
27
|
+
|
28
|
+
[[package]]
|
29
|
+
name = "asttokens"
|
30
|
+
version = "3.0.0"
|
31
|
+
source = { registry = "https://pypi.org/simple" }
|
32
|
+
sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978, upload-time = "2024-11-30T04:30:14.439Z" }
|
33
|
+
wheels = [
|
34
|
+
{ url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918, upload-time = "2024-11-30T04:30:10.946Z" },
|
35
|
+
]
|
36
|
+
|
37
|
+
[[package]]
|
38
|
+
name = "certifi"
|
39
|
+
version = "2025.10.5"
|
40
|
+
source = { registry = "https://pypi.org/simple" }
|
41
|
+
sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" }
|
42
|
+
wheels = [
|
43
|
+
{ url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" },
|
44
|
+
]
|
45
|
+
|
46
|
+
[[package]]
|
47
|
+
name = "colorama"
|
48
|
+
version = "0.4.6"
|
49
|
+
source = { registry = "https://pypi.org/simple" }
|
50
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
51
|
+
wheels = [
|
52
|
+
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
53
|
+
]
|
54
|
+
|
55
|
+
[[package]]
|
56
|
+
name = "decorator"
|
57
|
+
version = "5.2.1"
|
58
|
+
source = { registry = "https://pypi.org/simple" }
|
59
|
+
sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711, upload-time = "2025-02-24T04:41:34.073Z" }
|
60
|
+
wheels = [
|
61
|
+
{ url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" },
|
62
|
+
]
|
63
|
+
|
64
|
+
[[package]]
|
65
|
+
name = "distro"
|
66
|
+
version = "1.9.0"
|
67
|
+
source = { registry = "https://pypi.org/simple" }
|
68
|
+
sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" }
|
69
|
+
wheels = [
|
70
|
+
{ url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" },
|
71
|
+
]
|
72
|
+
|
73
|
+
[[package]]
|
74
|
+
name = "executing"
|
75
|
+
version = "2.2.1"
|
76
|
+
source = { registry = "https://pypi.org/simple" }
|
77
|
+
sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488, upload-time = "2025-09-01T09:48:10.866Z" }
|
78
|
+
wheels = [
|
79
|
+
{ url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317, upload-time = "2025-09-01T09:48:08.5Z" },
|
80
|
+
]
|
81
|
+
|
82
|
+
[[package]]
|
83
|
+
name = "h11"
|
84
|
+
version = "0.16.0"
|
85
|
+
source = { registry = "https://pypi.org/simple" }
|
86
|
+
sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" }
|
87
|
+
wheels = [
|
88
|
+
{ url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
|
89
|
+
]
|
90
|
+
|
91
|
+
[[package]]
|
92
|
+
name = "httpcore"
|
93
|
+
version = "1.0.9"
|
94
|
+
source = { registry = "https://pypi.org/simple" }
|
95
|
+
dependencies = [
|
96
|
+
{ name = "certifi" },
|
97
|
+
{ name = "h11" },
|
98
|
+
]
|
99
|
+
sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" }
|
100
|
+
wheels = [
|
101
|
+
{ url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" },
|
102
|
+
]
|
103
|
+
|
104
|
+
[[package]]
|
105
|
+
name = "httpx"
|
106
|
+
version = "0.28.1"
|
107
|
+
source = { registry = "https://pypi.org/simple" }
|
108
|
+
dependencies = [
|
109
|
+
{ name = "anyio" },
|
110
|
+
{ name = "certifi" },
|
111
|
+
{ name = "httpcore" },
|
112
|
+
{ name = "idna" },
|
113
|
+
]
|
114
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" }
|
115
|
+
wheels = [
|
116
|
+
{ url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" },
|
117
|
+
]
|
118
|
+
|
119
|
+
[[package]]
|
120
|
+
name = "idna"
|
121
|
+
version = "3.10"
|
122
|
+
source = { registry = "https://pypi.org/simple" }
|
123
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" }
|
124
|
+
wheels = [
|
125
|
+
{ url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" },
|
126
|
+
]
|
127
|
+
|
128
|
+
[[package]]
|
129
|
+
name = "iniconfig"
|
130
|
+
version = "2.1.0"
|
131
|
+
source = { registry = "https://pypi.org/simple" }
|
132
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" }
|
133
|
+
wheels = [
|
134
|
+
{ url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" },
|
135
|
+
]
|
136
|
+
|
137
|
+
[[package]]
|
138
|
+
name = "ipython"
|
139
|
+
version = "9.6.0"
|
140
|
+
source = { registry = "https://pypi.org/simple" }
|
141
|
+
dependencies = [
|
142
|
+
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
143
|
+
{ name = "decorator" },
|
144
|
+
{ name = "ipython-pygments-lexers" },
|
145
|
+
{ name = "jedi" },
|
146
|
+
{ name = "matplotlib-inline" },
|
147
|
+
{ name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
|
148
|
+
{ name = "prompt-toolkit" },
|
149
|
+
{ name = "pygments" },
|
150
|
+
{ name = "stack-data" },
|
151
|
+
{ name = "traitlets" },
|
152
|
+
]
|
153
|
+
sdist = { url = "https://files.pythonhosted.org/packages/2a/34/29b18c62e39ee2f7a6a3bba7efd952729d8aadd45ca17efc34453b717665/ipython-9.6.0.tar.gz", hash = "sha256:5603d6d5d356378be5043e69441a072b50a5b33b4503428c77b04cb8ce7bc731", size = 4396932, upload-time = "2025-09-29T10:55:53.948Z" }
|
154
|
+
wheels = [
|
155
|
+
{ url = "https://files.pythonhosted.org/packages/48/c5/d5e07995077e48220269c28a221e168c91123ad5ceee44d548f54a057fc0/ipython-9.6.0-py3-none-any.whl", hash = "sha256:5f77efafc886d2f023442479b8149e7d86547ad0a979e9da9f045d252f648196", size = 616170, upload-time = "2025-09-29T10:55:47.676Z" },
|
156
|
+
]
|
157
|
+
|
158
|
+
[[package]]
|
159
|
+
name = "ipython-pygments-lexers"
|
160
|
+
version = "1.1.1"
|
161
|
+
source = { registry = "https://pypi.org/simple" }
|
162
|
+
dependencies = [
|
163
|
+
{ name = "pygments" },
|
164
|
+
]
|
165
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" }
|
166
|
+
wheels = [
|
167
|
+
{ url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" },
|
168
|
+
]
|
169
|
+
|
170
|
+
[[package]]
|
171
|
+
name = "jedi"
|
172
|
+
version = "0.19.2"
|
173
|
+
source = { registry = "https://pypi.org/simple" }
|
174
|
+
dependencies = [
|
175
|
+
{ name = "parso" },
|
176
|
+
]
|
177
|
+
sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287, upload-time = "2024-11-11T01:41:42.873Z" }
|
178
|
+
wheels = [
|
179
|
+
{ url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278, upload-time = "2024-11-11T01:41:40.175Z" },
|
180
|
+
]
|
181
|
+
|
182
|
+
[[package]]
|
183
|
+
name = "jiter"
|
184
|
+
version = "0.11.0"
|
185
|
+
source = { registry = "https://pypi.org/simple" }
|
186
|
+
sdist = { url = "https://files.pythonhosted.org/packages/9d/c0/a3bb4cc13aced219dd18191ea66e874266bd8aa7b96744e495e1c733aa2d/jiter-0.11.0.tar.gz", hash = "sha256:1d9637eaf8c1d6a63d6562f2a6e5ab3af946c66037eb1b894e8fad75422266e4", size = 167094, upload-time = "2025-09-15T09:20:38.212Z" }
|
187
|
+
wheels = [
|
188
|
+
{ url = "https://files.pythonhosted.org/packages/ba/b5/3009b112b8f673e568ef79af9863d8309a15f0a8cdcc06ed6092051f377e/jiter-0.11.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:2fb7b377688cc3850bbe5c192a6bd493562a0bc50cbc8b047316428fbae00ada", size = 305510, upload-time = "2025-09-15T09:19:25.893Z" },
|
189
|
+
{ url = "https://files.pythonhosted.org/packages/fe/82/15514244e03b9e71e086bbe2a6de3e4616b48f07d5f834200c873956fb8c/jiter-0.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a1b7cbe3f25bd0d8abb468ba4302a5d45617ee61b2a7a638f63fee1dc086be99", size = 316521, upload-time = "2025-09-15T09:19:27.525Z" },
|
190
|
+
{ url = "https://files.pythonhosted.org/packages/92/94/7a2e905f40ad2d6d660e00b68d818f9e29fb87ffe82774f06191e93cbe4a/jiter-0.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0a7f0ec81d5b7588c5cade1eb1925b91436ae6726dc2df2348524aeabad5de6", size = 338214, upload-time = "2025-09-15T09:19:28.727Z" },
|
191
|
+
{ url = "https://files.pythonhosted.org/packages/a8/9c/5791ed5bdc76f12110158d3316a7a3ec0b1413d018b41c5ed399549d3ad5/jiter-0.11.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07630bb46ea2a6b9c6ed986c6e17e35b26148cce2c535454b26ee3f0e8dcaba1", size = 361280, upload-time = "2025-09-15T09:19:30.013Z" },
|
192
|
+
{ url = "https://files.pythonhosted.org/packages/d4/7f/b7d82d77ff0d2cb06424141000176b53a9e6b16a1125525bb51ea4990c2e/jiter-0.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7764f27d28cd4a9cbc61704dfcd80c903ce3aad106a37902d3270cd6673d17f4", size = 487895, upload-time = "2025-09-15T09:19:31.424Z" },
|
193
|
+
{ url = "https://files.pythonhosted.org/packages/42/44/10a1475d46f1fc1fd5cc2e82c58e7bca0ce5852208e0fa5df2f949353321/jiter-0.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d4a6c4a737d486f77f842aeb22807edecb4a9417e6700c7b981e16d34ba7c72", size = 378421, upload-time = "2025-09-15T09:19:32.746Z" },
|
194
|
+
{ url = "https://files.pythonhosted.org/packages/9a/5f/0dc34563d8164d31d07bc09d141d3da08157a68dcd1f9b886fa4e917805b/jiter-0.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf408d2a0abd919b60de8c2e7bc5eeab72d4dafd18784152acc7c9adc3291591", size = 347932, upload-time = "2025-09-15T09:19:34.612Z" },
|
195
|
+
{ url = "https://files.pythonhosted.org/packages/f7/de/b68f32a4fcb7b4a682b37c73a0e5dae32180140cd1caf11aef6ad40ddbf2/jiter-0.11.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cdef53eda7d18e799625023e1e250dbc18fbc275153039b873ec74d7e8883e09", size = 386959, upload-time = "2025-09-15T09:19:35.994Z" },
|
196
|
+
{ url = "https://files.pythonhosted.org/packages/76/0a/c08c92e713b6e28972a846a81ce374883dac2f78ec6f39a0dad9f2339c3a/jiter-0.11.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:53933a38ef7b551dd9c7f1064f9d7bb235bb3168d0fa5f14f0798d1b7ea0d9c5", size = 517187, upload-time = "2025-09-15T09:19:37.426Z" },
|
197
|
+
{ url = "https://files.pythonhosted.org/packages/89/b5/4a283bec43b15aad54fcae18d951f06a2ec3f78db5708d3b59a48e9c3fbd/jiter-0.11.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:11840d2324c9ab5162fc1abba23bc922124fedcff0d7b7f85fffa291e2f69206", size = 509461, upload-time = "2025-09-15T09:19:38.761Z" },
|
198
|
+
{ url = "https://files.pythonhosted.org/packages/34/a5/f8bad793010534ea73c985caaeef8cc22dfb1fedb15220ecdf15c623c07a/jiter-0.11.0-cp312-cp312-win32.whl", hash = "sha256:4f01a744d24a5f2bb4a11657a1b27b61dc038ae2e674621a74020406e08f749b", size = 206664, upload-time = "2025-09-15T09:19:40.096Z" },
|
199
|
+
{ url = "https://files.pythonhosted.org/packages/ed/42/5823ec2b1469395a160b4bf5f14326b4a098f3b6898fbd327366789fa5d3/jiter-0.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:29fff31190ab3a26de026da2f187814f4b9c6695361e20a9ac2123e4d4378a4c", size = 203520, upload-time = "2025-09-15T09:19:41.798Z" },
|
200
|
+
{ url = "https://files.pythonhosted.org/packages/97/c4/d530e514d0f4f29b2b68145e7b389cbc7cac7f9c8c23df43b04d3d10fa3e/jiter-0.11.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:4441a91b80a80249f9a6452c14b2c24708f139f64de959943dfeaa6cb915e8eb", size = 305021, upload-time = "2025-09-15T09:19:43.523Z" },
|
201
|
+
{ url = "https://files.pythonhosted.org/packages/7a/77/796a19c567c5734cbfc736a6f987affc0d5f240af8e12063c0fb93990ffa/jiter-0.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ff85fc6d2a431251ad82dbd1ea953affb5a60376b62e7d6809c5cd058bb39471", size = 314384, upload-time = "2025-09-15T09:19:44.849Z" },
|
202
|
+
{ url = "https://files.pythonhosted.org/packages/14/9c/824334de0b037b91b6f3fa9fe5a191c83977c7ec4abe17795d3cb6d174cf/jiter-0.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5e86126d64706fd28dfc46f910d496923c6f95b395138c02d0e252947f452bd", size = 337389, upload-time = "2025-09-15T09:19:46.094Z" },
|
203
|
+
{ url = "https://files.pythonhosted.org/packages/a2/95/ed4feab69e6cf9b2176ea29d4ef9d01a01db210a3a2c8a31a44ecdc68c38/jiter-0.11.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4ad8bd82165961867a10f52010590ce0b7a8c53da5ddd8bbb62fef68c181b921", size = 360519, upload-time = "2025-09-15T09:19:47.494Z" },
|
204
|
+
{ url = "https://files.pythonhosted.org/packages/b5/0c/2ad00f38d3e583caba3909d95b7da1c3a7cd82c0aa81ff4317a8016fb581/jiter-0.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b42c2cd74273455ce439fd9528db0c6e84b5623cb74572305bdd9f2f2961d3df", size = 487198, upload-time = "2025-09-15T09:19:49.116Z" },
|
205
|
+
{ url = "https://files.pythonhosted.org/packages/ea/8b/919b64cf3499b79bdfba6036da7b0cac5d62d5c75a28fb45bad7819e22f0/jiter-0.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0062dab98172dd0599fcdbf90214d0dcde070b1ff38a00cc1b90e111f071982", size = 377835, upload-time = "2025-09-15T09:19:50.468Z" },
|
206
|
+
{ url = "https://files.pythonhosted.org/packages/29/7f/8ebe15b6e0a8026b0d286c083b553779b4dd63db35b43a3f171b544de91d/jiter-0.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb948402821bc76d1f6ef0f9e19b816f9b09f8577844ba7140f0b6afe994bc64", size = 347655, upload-time = "2025-09-15T09:19:51.726Z" },
|
207
|
+
{ url = "https://files.pythonhosted.org/packages/8e/64/332127cef7e94ac75719dda07b9a472af6158ba819088d87f17f3226a769/jiter-0.11.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:25a5b1110cca7329fd0daf5060faa1234be5c11e988948e4f1a1923b6a457fe1", size = 386135, upload-time = "2025-09-15T09:19:53.075Z" },
|
208
|
+
{ url = "https://files.pythonhosted.org/packages/20/c8/557b63527442f84c14774159948262a9d4fabb0d61166f11568f22fc60d2/jiter-0.11.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:bf11807e802a214daf6c485037778843fadd3e2ec29377ae17e0706ec1a25758", size = 516063, upload-time = "2025-09-15T09:19:54.447Z" },
|
209
|
+
{ url = "https://files.pythonhosted.org/packages/86/13/4164c819df4a43cdc8047f9a42880f0ceef5afeb22e8b9675c0528ebdccd/jiter-0.11.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:dbb57da40631c267861dd0090461222060960012d70fd6e4c799b0f62d0ba166", size = 508139, upload-time = "2025-09-15T09:19:55.764Z" },
|
210
|
+
{ url = "https://files.pythonhosted.org/packages/fa/70/6e06929b401b331d41ddb4afb9f91cd1168218e3371972f0afa51c9f3c31/jiter-0.11.0-cp313-cp313-win32.whl", hash = "sha256:8e36924dad32c48d3c5e188d169e71dc6e84d6cb8dedefea089de5739d1d2f80", size = 206369, upload-time = "2025-09-15T09:19:57.048Z" },
|
211
|
+
{ url = "https://files.pythonhosted.org/packages/f4/0d/8185b8e15de6dce24f6afae63380e16377dd75686d56007baa4f29723ea1/jiter-0.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:452d13e4fd59698408087235259cebe67d9d49173b4dacb3e8d35ce4acf385d6", size = 202538, upload-time = "2025-09-15T09:19:58.35Z" },
|
212
|
+
{ url = "https://files.pythonhosted.org/packages/13/3a/d61707803260d59520721fa326babfae25e9573a88d8b7b9cb54c5423a59/jiter-0.11.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:089f9df9f69532d1339e83142438668f52c97cd22ee2d1195551c2b1a9e6cf33", size = 313737, upload-time = "2025-09-15T09:19:59.638Z" },
|
213
|
+
{ url = "https://files.pythonhosted.org/packages/cd/cc/c9f0eec5d00f2a1da89f6bdfac12b8afdf8d5ad974184863c75060026457/jiter-0.11.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29ed1fe69a8c69bf0f2a962d8d706c7b89b50f1332cd6b9fbda014f60bd03a03", size = 346183, upload-time = "2025-09-15T09:20:01.442Z" },
|
214
|
+
{ url = "https://files.pythonhosted.org/packages/a6/87/fc632776344e7aabbab05a95a0075476f418c5d29ab0f2eec672b7a1f0ac/jiter-0.11.0-cp313-cp313t-win_amd64.whl", hash = "sha256:a4d71d7ea6ea8786291423fe209acf6f8d398a0759d03e7f24094acb8ab686ba", size = 204225, upload-time = "2025-09-15T09:20:03.102Z" },
|
215
|
+
{ url = "https://files.pythonhosted.org/packages/ee/3b/e7f45be7d3969bdf2e3cd4b816a7a1d272507cd0edd2d6dc4b07514f2d9a/jiter-0.11.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:9a6dff27eca70930bdbe4cbb7c1a4ba8526e13b63dc808c0670083d2d51a4a72", size = 304414, upload-time = "2025-09-15T09:20:04.357Z" },
|
216
|
+
{ url = "https://files.pythonhosted.org/packages/06/32/13e8e0d152631fcc1907ceb4943711471be70496d14888ec6e92034e2caf/jiter-0.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b1ae2a7593a62132c7d4c2abbee80bbbb94fdc6d157e2c6cc966250c564ef774", size = 314223, upload-time = "2025-09-15T09:20:05.631Z" },
|
217
|
+
{ url = "https://files.pythonhosted.org/packages/0c/7e/abedd5b5a20ca083f778d96bba0d2366567fcecb0e6e34ff42640d5d7a18/jiter-0.11.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b13a431dba4b059e9e43019d3022346d009baf5066c24dcdea321a303cde9f0", size = 337306, upload-time = "2025-09-15T09:20:06.917Z" },
|
218
|
+
{ url = "https://files.pythonhosted.org/packages/ac/e2/30d59bdc1204c86aa975ec72c48c482fee6633120ee9c3ab755e4dfefea8/jiter-0.11.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:af62e84ca3889604ebb645df3b0a3f3bcf6b92babbff642bd214616f57abb93a", size = 360565, upload-time = "2025-09-15T09:20:08.283Z" },
|
219
|
+
{ url = "https://files.pythonhosted.org/packages/fe/88/567288e0d2ed9fa8f7a3b425fdaf2cb82b998633c24fe0d98f5417321aa8/jiter-0.11.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6f3b32bb723246e6b351aecace52aba78adb8eeb4b2391630322dc30ff6c773", size = 486465, upload-time = "2025-09-15T09:20:09.613Z" },
|
220
|
+
{ url = "https://files.pythonhosted.org/packages/18/6e/7b72d09273214cadd15970e91dd5ed9634bee605176107db21e1e4205eb1/jiter-0.11.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:adcab442f4a099a358a7f562eaa54ed6456fb866e922c6545a717be51dbed7d7", size = 377581, upload-time = "2025-09-15T09:20:10.884Z" },
|
221
|
+
{ url = "https://files.pythonhosted.org/packages/58/52/4db456319f9d14deed325f70102577492e9d7e87cf7097bda9769a1fcacb/jiter-0.11.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9967c2ab338ee2b2c0102fd379ec2693c496abf71ffd47e4d791d1f593b68e2", size = 347102, upload-time = "2025-09-15T09:20:12.175Z" },
|
222
|
+
{ url = "https://files.pythonhosted.org/packages/ce/b4/433d5703c38b26083aec7a733eb5be96f9c6085d0e270a87ca6482cbf049/jiter-0.11.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e7d0bed3b187af8b47a981d9742ddfc1d9b252a7235471ad6078e7e4e5fe75c2", size = 386477, upload-time = "2025-09-15T09:20:13.428Z" },
|
223
|
+
{ url = "https://files.pythonhosted.org/packages/c8/7a/a60bfd9c55b55b07c5c441c5085f06420b6d493ce9db28d069cc5b45d9f3/jiter-0.11.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:f6fe0283e903ebc55f1a6cc569b8c1f3bf4abd026fed85e3ff8598a9e6f982f0", size = 516004, upload-time = "2025-09-15T09:20:14.848Z" },
|
224
|
+
{ url = "https://files.pythonhosted.org/packages/2e/46/f8363e5ecc179b4ed0ca6cb0a6d3bfc266078578c71ff30642ea2ce2f203/jiter-0.11.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:4ee5821e3d66606b29ae5b497230b304f1376f38137d69e35f8d2bd5f310ff73", size = 507855, upload-time = "2025-09-15T09:20:16.176Z" },
|
225
|
+
{ url = "https://files.pythonhosted.org/packages/90/33/396083357d51d7ff0f9805852c288af47480d30dd31d8abc74909b020761/jiter-0.11.0-cp314-cp314-win32.whl", hash = "sha256:c2d13ba7567ca8799f17c76ed56b1d49be30df996eb7fa33e46b62800562a5e2", size = 205802, upload-time = "2025-09-15T09:20:17.661Z" },
|
226
|
+
{ url = "https://files.pythonhosted.org/packages/e7/ab/eb06ca556b2551d41de7d03bf2ee24285fa3d0c58c5f8d95c64c9c3281b1/jiter-0.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fb4790497369d134a07fc763cc88888c46f734abdd66f9fdf7865038bf3a8f40", size = 313405, upload-time = "2025-09-15T09:20:18.918Z" },
|
227
|
+
{ url = "https://files.pythonhosted.org/packages/af/22/7ab7b4ec3a1c1f03aef376af11d23b05abcca3fb31fbca1e7557053b1ba2/jiter-0.11.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e2bbf24f16ba5ad4441a9845e40e4ea0cb9eed00e76ba94050664ef53ef4406", size = 347102, upload-time = "2025-09-15T09:20:20.16Z" },
|
228
|
+
]
|
229
|
+
|
230
|
+
[[package]]
|
231
|
+
name = "ldbg"
|
232
|
+
version = "0.1.0"
|
233
|
+
source = { editable = "." }
|
234
|
+
dependencies = [
|
235
|
+
{ name = "openai" },
|
236
|
+
]
|
237
|
+
|
238
|
+
[package.dev-dependencies]
|
239
|
+
dev = [
|
240
|
+
{ name = "ipython" },
|
241
|
+
{ name = "pytest" },
|
242
|
+
{ name = "ruff" },
|
243
|
+
]
|
244
|
+
|
245
|
+
[package.metadata]
|
246
|
+
requires-dist = [{ name = "openai", specifier = ">=1.107.3" }]
|
247
|
+
|
248
|
+
[package.metadata.requires-dev]
|
249
|
+
dev = [
|
250
|
+
{ name = "ipython", specifier = ">=9.5.0" },
|
251
|
+
{ name = "pytest", specifier = ">=8.4.2" },
|
252
|
+
{ name = "ruff", specifier = ">=0.14.0" },
|
253
|
+
]
|
254
|
+
|
255
|
+
[[package]]
|
256
|
+
name = "matplotlib-inline"
|
257
|
+
version = "0.1.7"
|
258
|
+
source = { registry = "https://pypi.org/simple" }
|
259
|
+
dependencies = [
|
260
|
+
{ name = "traitlets" },
|
261
|
+
]
|
262
|
+
sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159, upload-time = "2024-04-15T13:44:44.803Z" }
|
263
|
+
wheels = [
|
264
|
+
{ url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899, upload-time = "2024-04-15T13:44:43.265Z" },
|
265
|
+
]
|
266
|
+
|
267
|
+
[[package]]
|
268
|
+
name = "openai"
|
269
|
+
version = "2.1.0"
|
270
|
+
source = { registry = "https://pypi.org/simple" }
|
271
|
+
dependencies = [
|
272
|
+
{ name = "anyio" },
|
273
|
+
{ name = "distro" },
|
274
|
+
{ name = "httpx" },
|
275
|
+
{ name = "jiter" },
|
276
|
+
{ name = "pydantic" },
|
277
|
+
{ name = "sniffio" },
|
278
|
+
{ name = "tqdm" },
|
279
|
+
{ name = "typing-extensions" },
|
280
|
+
]
|
281
|
+
sdist = { url = "https://files.pythonhosted.org/packages/1a/dd/4d4d46a06943e37c95b6e388237e1e38d1e9aab264ff070f86345d60b7a4/openai-2.1.0.tar.gz", hash = "sha256:47f3463a5047340a989b4c0cd5378054acfca966ff61a96553b22f098e3270a2", size = 572998, upload-time = "2025-10-02T20:43:15.385Z" }
|
282
|
+
wheels = [
|
283
|
+
{ url = "https://files.pythonhosted.org/packages/68/83/88f64fc8f037885efa8a629d1215f5bc1f037453bab4d4f823b5533319eb/openai-2.1.0-py3-none-any.whl", hash = "sha256:33172e8c06a4576144ba4137a493807a9ca427421dcabc54ad3aa656daf757d3", size = 964939, upload-time = "2025-10-02T20:43:13.568Z" },
|
284
|
+
]
|
285
|
+
|
286
|
+
[[package]]
|
287
|
+
name = "packaging"
|
288
|
+
version = "25.0"
|
289
|
+
source = { registry = "https://pypi.org/simple" }
|
290
|
+
sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" }
|
291
|
+
wheels = [
|
292
|
+
{ url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" },
|
293
|
+
]
|
294
|
+
|
295
|
+
[[package]]
|
296
|
+
name = "parso"
|
297
|
+
version = "0.8.5"
|
298
|
+
source = { registry = "https://pypi.org/simple" }
|
299
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d4/de/53e0bcf53d13e005bd8c92e7855142494f41171b34c2536b86187474184d/parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a", size = 401205, upload-time = "2025-08-23T15:15:28.028Z" }
|
300
|
+
wheels = [
|
301
|
+
{ url = "https://files.pythonhosted.org/packages/16/32/f8e3c85d1d5250232a5d3477a2a28cc291968ff175caeadaf3cc19ce0e4a/parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887", size = 106668, upload-time = "2025-08-23T15:15:25.663Z" },
|
302
|
+
]
|
303
|
+
|
304
|
+
[[package]]
|
305
|
+
name = "pexpect"
|
306
|
+
version = "4.9.0"
|
307
|
+
source = { registry = "https://pypi.org/simple" }
|
308
|
+
dependencies = [
|
309
|
+
{ name = "ptyprocess" },
|
310
|
+
]
|
311
|
+
sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" }
|
312
|
+
wheels = [
|
313
|
+
{ url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" },
|
314
|
+
]
|
315
|
+
|
316
|
+
[[package]]
|
317
|
+
name = "pluggy"
|
318
|
+
version = "1.6.0"
|
319
|
+
source = { registry = "https://pypi.org/simple" }
|
320
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" }
|
321
|
+
wheels = [
|
322
|
+
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
|
323
|
+
]
|
324
|
+
|
325
|
+
[[package]]
|
326
|
+
name = "prompt-toolkit"
|
327
|
+
version = "3.0.52"
|
328
|
+
source = { registry = "https://pypi.org/simple" }
|
329
|
+
dependencies = [
|
330
|
+
{ name = "wcwidth" },
|
331
|
+
]
|
332
|
+
sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" }
|
333
|
+
wheels = [
|
334
|
+
{ url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" },
|
335
|
+
]
|
336
|
+
|
337
|
+
[[package]]
|
338
|
+
name = "ptyprocess"
|
339
|
+
version = "0.7.0"
|
340
|
+
source = { registry = "https://pypi.org/simple" }
|
341
|
+
sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" }
|
342
|
+
wheels = [
|
343
|
+
{ url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" },
|
344
|
+
]
|
345
|
+
|
346
|
+
[[package]]
|
347
|
+
name = "pure-eval"
|
348
|
+
version = "0.2.3"
|
349
|
+
source = { registry = "https://pypi.org/simple" }
|
350
|
+
sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752, upload-time = "2024-07-21T12:58:21.801Z" }
|
351
|
+
wheels = [
|
352
|
+
{ url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" },
|
353
|
+
]
|
354
|
+
|
355
|
+
[[package]]
|
356
|
+
name = "pydantic"
|
357
|
+
version = "2.11.10"
|
358
|
+
source = { registry = "https://pypi.org/simple" }
|
359
|
+
dependencies = [
|
360
|
+
{ name = "annotated-types" },
|
361
|
+
{ name = "pydantic-core" },
|
362
|
+
{ name = "typing-extensions" },
|
363
|
+
{ name = "typing-inspection" },
|
364
|
+
]
|
365
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ae/54/ecab642b3bed45f7d5f59b38443dcb36ef50f85af192e6ece103dbfe9587/pydantic-2.11.10.tar.gz", hash = "sha256:dc280f0982fbda6c38fada4e476dc0a4f3aeaf9c6ad4c28df68a666ec3c61423", size = 788494, upload-time = "2025-10-04T10:40:41.338Z" }
|
366
|
+
wheels = [
|
367
|
+
{ url = "https://files.pythonhosted.org/packages/bd/1f/73c53fcbfb0b5a78f91176df41945ca466e71e9d9d836e5c522abda39ee7/pydantic-2.11.10-py3-none-any.whl", hash = "sha256:802a655709d49bd004c31e865ef37da30b540786a46bfce02333e0e24b5fe29a", size = 444823, upload-time = "2025-10-04T10:40:39.055Z" },
|
368
|
+
]
|
369
|
+
|
370
|
+
[[package]]
|
371
|
+
name = "pydantic-core"
|
372
|
+
version = "2.33.2"
|
373
|
+
source = { registry = "https://pypi.org/simple" }
|
374
|
+
dependencies = [
|
375
|
+
{ name = "typing-extensions" },
|
376
|
+
]
|
377
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" }
|
378
|
+
wheels = [
|
379
|
+
{ url = "https://files.pythonhosted.org/packages/18/8a/2b41c97f554ec8c71f2a8a5f85cb56a8b0956addfe8b0efb5b3d77e8bdc3/pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc", size = 2009000, upload-time = "2025-04-23T18:31:25.863Z" },
|
380
|
+
{ url = "https://files.pythonhosted.org/packages/a1/02/6224312aacb3c8ecbaa959897af57181fb6cf3a3d7917fd44d0f2917e6f2/pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7", size = 1847996, upload-time = "2025-04-23T18:31:27.341Z" },
|
381
|
+
{ url = "https://files.pythonhosted.org/packages/d6/46/6dcdf084a523dbe0a0be59d054734b86a981726f221f4562aed313dbcb49/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025", size = 1880957, upload-time = "2025-04-23T18:31:28.956Z" },
|
382
|
+
{ url = "https://files.pythonhosted.org/packages/ec/6b/1ec2c03837ac00886ba8160ce041ce4e325b41d06a034adbef11339ae422/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011", size = 1964199, upload-time = "2025-04-23T18:31:31.025Z" },
|
383
|
+
{ url = "https://files.pythonhosted.org/packages/2d/1d/6bf34d6adb9debd9136bd197ca72642203ce9aaaa85cfcbfcf20f9696e83/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f", size = 2120296, upload-time = "2025-04-23T18:31:32.514Z" },
|
384
|
+
{ url = "https://files.pythonhosted.org/packages/e0/94/2bd0aaf5a591e974b32a9f7123f16637776c304471a0ab33cf263cf5591a/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88", size = 2676109, upload-time = "2025-04-23T18:31:33.958Z" },
|
385
|
+
{ url = "https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1", size = 2002028, upload-time = "2025-04-23T18:31:39.095Z" },
|
386
|
+
{ url = "https://files.pythonhosted.org/packages/cb/d5/7bb781bf2748ce3d03af04d5c969fa1308880e1dca35a9bd94e1a96a922e/pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b", size = 2100044, upload-time = "2025-04-23T18:31:41.034Z" },
|
387
|
+
{ url = "https://files.pythonhosted.org/packages/fe/36/def5e53e1eb0ad896785702a5bbfd25eed546cdcf4087ad285021a90ed53/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1", size = 2058881, upload-time = "2025-04-23T18:31:42.757Z" },
|
388
|
+
{ url = "https://files.pythonhosted.org/packages/01/6c/57f8d70b2ee57fc3dc8b9610315949837fa8c11d86927b9bb044f8705419/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6", size = 2227034, upload-time = "2025-04-23T18:31:44.304Z" },
|
389
|
+
{ url = "https://files.pythonhosted.org/packages/27/b9/9c17f0396a82b3d5cbea4c24d742083422639e7bb1d5bf600e12cb176a13/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea", size = 2234187, upload-time = "2025-04-23T18:31:45.891Z" },
|
390
|
+
{ url = "https://files.pythonhosted.org/packages/b0/6a/adf5734ffd52bf86d865093ad70b2ce543415e0e356f6cacabbc0d9ad910/pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290", size = 1892628, upload-time = "2025-04-23T18:31:47.819Z" },
|
391
|
+
{ url = "https://files.pythonhosted.org/packages/43/e4/5479fecb3606c1368d496a825d8411e126133c41224c1e7238be58b87d7e/pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2", size = 1955866, upload-time = "2025-04-23T18:31:49.635Z" },
|
392
|
+
{ url = "https://files.pythonhosted.org/packages/0d/24/8b11e8b3e2be9dd82df4b11408a67c61bb4dc4f8e11b5b0fc888b38118b5/pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab", size = 1888894, upload-time = "2025-04-23T18:31:51.609Z" },
|
393
|
+
{ url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload-time = "2025-04-23T18:31:53.175Z" },
|
394
|
+
{ url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload-time = "2025-04-23T18:31:54.79Z" },
|
395
|
+
{ url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload-time = "2025-04-23T18:31:57.393Z" },
|
396
|
+
{ url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859, upload-time = "2025-04-23T18:31:59.065Z" },
|
397
|
+
{ url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810, upload-time = "2025-04-23T18:32:00.78Z" },
|
398
|
+
{ url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498, upload-time = "2025-04-23T18:32:02.418Z" },
|
399
|
+
{ url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611, upload-time = "2025-04-23T18:32:04.152Z" },
|
400
|
+
{ url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924, upload-time = "2025-04-23T18:32:06.129Z" },
|
401
|
+
{ url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196, upload-time = "2025-04-23T18:32:08.178Z" },
|
402
|
+
{ url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389, upload-time = "2025-04-23T18:32:10.242Z" },
|
403
|
+
{ url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223, upload-time = "2025-04-23T18:32:12.382Z" },
|
404
|
+
{ url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473, upload-time = "2025-04-23T18:32:14.034Z" },
|
405
|
+
{ url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269, upload-time = "2025-04-23T18:32:15.783Z" },
|
406
|
+
{ url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921, upload-time = "2025-04-23T18:32:18.473Z" },
|
407
|
+
{ url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" },
|
408
|
+
{ url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" },
|
409
|
+
{ url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" },
|
410
|
+
]
|
411
|
+
|
412
|
+
[[package]]
|
413
|
+
name = "pygments"
|
414
|
+
version = "2.19.2"
|
415
|
+
source = { registry = "https://pypi.org/simple" }
|
416
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" }
|
417
|
+
wheels = [
|
418
|
+
{ url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" },
|
419
|
+
]
|
420
|
+
|
421
|
+
[[package]]
|
422
|
+
name = "pytest"
|
423
|
+
version = "8.4.2"
|
424
|
+
source = { registry = "https://pypi.org/simple" }
|
425
|
+
dependencies = [
|
426
|
+
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
427
|
+
{ name = "iniconfig" },
|
428
|
+
{ name = "packaging" },
|
429
|
+
{ name = "pluggy" },
|
430
|
+
{ name = "pygments" },
|
431
|
+
]
|
432
|
+
sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" }
|
433
|
+
wheels = [
|
434
|
+
{ url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" },
|
435
|
+
]
|
436
|
+
|
437
|
+
[[package]]
|
438
|
+
name = "ruff"
|
439
|
+
version = "0.14.0"
|
440
|
+
source = { registry = "https://pypi.org/simple" }
|
441
|
+
sdist = { url = "https://files.pythonhosted.org/packages/41/b9/9bd84453ed6dd04688de9b3f3a4146a1698e8faae2ceeccce4e14c67ae17/ruff-0.14.0.tar.gz", hash = "sha256:62ec8969b7510f77945df916de15da55311fade8d6050995ff7f680afe582c57", size = 5452071, upload-time = "2025-10-07T18:21:55.763Z" }
|
442
|
+
wheels = [
|
443
|
+
{ url = "https://files.pythonhosted.org/packages/3a/4e/79d463a5f80654e93fa653ebfb98e0becc3f0e7cf6219c9ddedf1e197072/ruff-0.14.0-py3-none-linux_armv6l.whl", hash = "sha256:58e15bffa7054299becf4bab8a1187062c6f8cafbe9f6e39e0d5aface455d6b3", size = 12494532, upload-time = "2025-10-07T18:21:00.373Z" },
|
444
|
+
{ url = "https://files.pythonhosted.org/packages/ee/40/e2392f445ed8e02aa6105d49db4bfff01957379064c30f4811c3bf38aece/ruff-0.14.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:838d1b065f4df676b7c9957992f2304e41ead7a50a568185efd404297d5701e8", size = 13160768, upload-time = "2025-10-07T18:21:04.73Z" },
|
445
|
+
{ url = "https://files.pythonhosted.org/packages/75/da/2a656ea7c6b9bd14c7209918268dd40e1e6cea65f4bb9880eaaa43b055cd/ruff-0.14.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:703799d059ba50f745605b04638fa7e9682cc3da084b2092feee63500ff3d9b8", size = 12363376, upload-time = "2025-10-07T18:21:07.833Z" },
|
446
|
+
{ url = "https://files.pythonhosted.org/packages/42/e2/1ffef5a1875add82416ff388fcb7ea8b22a53be67a638487937aea81af27/ruff-0.14.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ba9a8925e90f861502f7d974cc60e18ca29c72bb0ee8bfeabb6ade35a3abde7", size = 12608055, upload-time = "2025-10-07T18:21:10.72Z" },
|
447
|
+
{ url = "https://files.pythonhosted.org/packages/4a/32/986725199d7cee510d9f1dfdf95bf1efc5fa9dd714d0d85c1fb1f6be3bc3/ruff-0.14.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e41f785498bd200ffc276eb9e1570c019c1d907b07cfb081092c8ad51975bbe7", size = 12318544, upload-time = "2025-10-07T18:21:13.741Z" },
|
448
|
+
{ url = "https://files.pythonhosted.org/packages/9a/ed/4969cefd53315164c94eaf4da7cfba1f267dc275b0abdd593d11c90829a3/ruff-0.14.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30a58c087aef4584c193aebf2700f0fbcfc1e77b89c7385e3139956fa90434e2", size = 14001280, upload-time = "2025-10-07T18:21:16.411Z" },
|
449
|
+
{ url = "https://files.pythonhosted.org/packages/ab/ad/96c1fc9f8854c37681c9613d825925c7f24ca1acfc62a4eb3896b50bacd2/ruff-0.14.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f8d07350bc7af0a5ce8812b7d5c1a7293cf02476752f23fdfc500d24b79b783c", size = 15027286, upload-time = "2025-10-07T18:21:19.577Z" },
|
450
|
+
{ url = "https://files.pythonhosted.org/packages/b3/00/1426978f97df4fe331074baf69615f579dc4e7c37bb4c6f57c2aad80c87f/ruff-0.14.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eec3bbbf3a7d5482b5c1f42d5fc972774d71d107d447919fca620b0be3e3b75e", size = 14451506, upload-time = "2025-10-07T18:21:22.779Z" },
|
451
|
+
{ url = "https://files.pythonhosted.org/packages/58/d5/9c1cea6e493c0cf0647674cca26b579ea9d2a213b74b5c195fbeb9678e15/ruff-0.14.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16b68e183a0e28e5c176d51004aaa40559e8f90065a10a559176713fcf435206", size = 13437384, upload-time = "2025-10-07T18:21:25.758Z" },
|
452
|
+
{ url = "https://files.pythonhosted.org/packages/29/b4/4cd6a4331e999fc05d9d77729c95503f99eae3ba1160469f2b64866964e3/ruff-0.14.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb732d17db2e945cfcbbc52af0143eda1da36ca8ae25083dd4f66f1542fdf82e", size = 13447976, upload-time = "2025-10-07T18:21:28.83Z" },
|
453
|
+
{ url = "https://files.pythonhosted.org/packages/3b/c0/ac42f546d07e4f49f62332576cb845d45c67cf5610d1851254e341d563b6/ruff-0.14.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:c958f66ab884b7873e72df38dcabee03d556a8f2ee1b8538ee1c2bbd619883dd", size = 13682850, upload-time = "2025-10-07T18:21:31.842Z" },
|
454
|
+
{ url = "https://files.pythonhosted.org/packages/5f/c4/4b0c9bcadd45b4c29fe1af9c5d1dc0ca87b4021665dfbe1c4688d407aa20/ruff-0.14.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7eb0499a2e01f6e0c285afc5bac43ab380cbfc17cd43a2e1dd10ec97d6f2c42d", size = 12449825, upload-time = "2025-10-07T18:21:35.074Z" },
|
455
|
+
{ url = "https://files.pythonhosted.org/packages/4b/a8/e2e76288e6c16540fa820d148d83e55f15e994d852485f221b9524514730/ruff-0.14.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4c63b2d99fafa05efca0ab198fd48fa6030d57e4423df3f18e03aa62518c565f", size = 12272599, upload-time = "2025-10-07T18:21:38.08Z" },
|
456
|
+
{ url = "https://files.pythonhosted.org/packages/18/14/e2815d8eff847391af632b22422b8207704222ff575dec8d044f9ab779b2/ruff-0.14.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:668fce701b7a222f3f5327f86909db2bbe99c30877c8001ff934c5413812ac02", size = 13193828, upload-time = "2025-10-07T18:21:41.216Z" },
|
457
|
+
{ url = "https://files.pythonhosted.org/packages/44/c6/61ccc2987cf0aecc588ff8f3212dea64840770e60d78f5606cd7dc34de32/ruff-0.14.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a86bf575e05cb68dcb34e4c7dfe1064d44d3f0c04bbc0491949092192b515296", size = 13628617, upload-time = "2025-10-07T18:21:44.04Z" },
|
458
|
+
{ url = "https://files.pythonhosted.org/packages/73/e6/03b882225a1b0627e75339b420883dc3c90707a8917d2284abef7a58d317/ruff-0.14.0-py3-none-win32.whl", hash = "sha256:7450a243d7125d1c032cb4b93d9625dea46c8c42b4f06c6b709baac168e10543", size = 12367872, upload-time = "2025-10-07T18:21:46.67Z" },
|
459
|
+
{ url = "https://files.pythonhosted.org/packages/41/77/56cf9cf01ea0bfcc662de72540812e5ba8e9563f33ef3d37ab2174892c47/ruff-0.14.0-py3-none-win_amd64.whl", hash = "sha256:ea95da28cd874c4d9c922b39381cbd69cb7e7b49c21b8152b014bd4f52acddc2", size = 13464628, upload-time = "2025-10-07T18:21:50.318Z" },
|
460
|
+
{ url = "https://files.pythonhosted.org/packages/c6/2a/65880dfd0e13f7f13a775998f34703674a4554906167dce02daf7865b954/ruff-0.14.0-py3-none-win_arm64.whl", hash = "sha256:f42c9495f5c13ff841b1da4cb3c2a42075409592825dada7c5885c2c844ac730", size = 12565142, upload-time = "2025-10-07T18:21:53.577Z" },
|
461
|
+
]
|
462
|
+
|
463
|
+
[[package]]
|
464
|
+
name = "sniffio"
|
465
|
+
version = "1.3.1"
|
466
|
+
source = { registry = "https://pypi.org/simple" }
|
467
|
+
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" }
|
468
|
+
wheels = [
|
469
|
+
{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" },
|
470
|
+
]
|
471
|
+
|
472
|
+
[[package]]
|
473
|
+
name = "stack-data"
|
474
|
+
version = "0.6.3"
|
475
|
+
source = { registry = "https://pypi.org/simple" }
|
476
|
+
dependencies = [
|
477
|
+
{ name = "asttokens" },
|
478
|
+
{ name = "executing" },
|
479
|
+
{ name = "pure-eval" },
|
480
|
+
]
|
481
|
+
sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" }
|
482
|
+
wheels = [
|
483
|
+
{ url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" },
|
484
|
+
]
|
485
|
+
|
486
|
+
[[package]]
|
487
|
+
name = "tqdm"
|
488
|
+
version = "4.67.1"
|
489
|
+
source = { registry = "https://pypi.org/simple" }
|
490
|
+
dependencies = [
|
491
|
+
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
492
|
+
]
|
493
|
+
sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" }
|
494
|
+
wheels = [
|
495
|
+
{ url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" },
|
496
|
+
]
|
497
|
+
|
498
|
+
[[package]]
|
499
|
+
name = "traitlets"
|
500
|
+
version = "5.14.3"
|
501
|
+
source = { registry = "https://pypi.org/simple" }
|
502
|
+
sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621, upload-time = "2024-04-19T11:11:49.746Z" }
|
503
|
+
wheels = [
|
504
|
+
{ url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" },
|
505
|
+
]
|
506
|
+
|
507
|
+
[[package]]
|
508
|
+
name = "typing-extensions"
|
509
|
+
version = "4.15.0"
|
510
|
+
source = { registry = "https://pypi.org/simple" }
|
511
|
+
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
|
512
|
+
wheels = [
|
513
|
+
{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
|
514
|
+
]
|
515
|
+
|
516
|
+
[[package]]
|
517
|
+
name = "typing-inspection"
|
518
|
+
version = "0.4.2"
|
519
|
+
source = { registry = "https://pypi.org/simple" }
|
520
|
+
dependencies = [
|
521
|
+
{ name = "typing-extensions" },
|
522
|
+
]
|
523
|
+
sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" }
|
524
|
+
wheels = [
|
525
|
+
{ url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" },
|
526
|
+
]
|
527
|
+
|
528
|
+
[[package]]
|
529
|
+
name = "wcwidth"
|
530
|
+
version = "0.2.14"
|
531
|
+
source = { registry = "https://pypi.org/simple" }
|
532
|
+
sdist = { url = "https://files.pythonhosted.org/packages/24/30/6b0809f4510673dc723187aeaf24c7f5459922d01e2f794277a3dfb90345/wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605", size = 102293, upload-time = "2025-09-22T16:29:53.023Z" }
|
533
|
+
wheels = [
|
534
|
+
{ url = "https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1", size = 37286, upload-time = "2025-09-22T16:29:51.641Z" },
|
535
|
+
]
|