prompture 0.0.29.dev8__py3-none-any.whl → 0.0.35__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.
Files changed (67) hide show
  1. prompture/__init__.py +146 -23
  2. prompture/_version.py +34 -0
  3. prompture/aio/__init__.py +74 -0
  4. prompture/async_conversation.py +607 -0
  5. prompture/async_core.py +803 -0
  6. prompture/async_driver.py +169 -0
  7. prompture/cache.py +469 -0
  8. prompture/callbacks.py +55 -0
  9. prompture/cli.py +63 -4
  10. prompture/conversation.py +631 -0
  11. prompture/core.py +876 -263
  12. prompture/cost_mixin.py +51 -0
  13. prompture/discovery.py +164 -0
  14. prompture/driver.py +168 -5
  15. prompture/drivers/__init__.py +173 -69
  16. prompture/drivers/airllm_driver.py +109 -0
  17. prompture/drivers/async_airllm_driver.py +26 -0
  18. prompture/drivers/async_azure_driver.py +117 -0
  19. prompture/drivers/async_claude_driver.py +107 -0
  20. prompture/drivers/async_google_driver.py +132 -0
  21. prompture/drivers/async_grok_driver.py +91 -0
  22. prompture/drivers/async_groq_driver.py +84 -0
  23. prompture/drivers/async_hugging_driver.py +61 -0
  24. prompture/drivers/async_lmstudio_driver.py +79 -0
  25. prompture/drivers/async_local_http_driver.py +44 -0
  26. prompture/drivers/async_ollama_driver.py +125 -0
  27. prompture/drivers/async_openai_driver.py +96 -0
  28. prompture/drivers/async_openrouter_driver.py +96 -0
  29. prompture/drivers/async_registry.py +129 -0
  30. prompture/drivers/azure_driver.py +36 -9
  31. prompture/drivers/claude_driver.py +251 -34
  32. prompture/drivers/google_driver.py +107 -38
  33. prompture/drivers/grok_driver.py +29 -32
  34. prompture/drivers/groq_driver.py +27 -26
  35. prompture/drivers/hugging_driver.py +6 -6
  36. prompture/drivers/lmstudio_driver.py +26 -13
  37. prompture/drivers/local_http_driver.py +6 -6
  38. prompture/drivers/ollama_driver.py +157 -23
  39. prompture/drivers/openai_driver.py +178 -9
  40. prompture/drivers/openrouter_driver.py +31 -25
  41. prompture/drivers/registry.py +306 -0
  42. prompture/field_definitions.py +106 -96
  43. prompture/logging.py +80 -0
  44. prompture/model_rates.py +217 -0
  45. prompture/runner.py +49 -47
  46. prompture/scaffold/__init__.py +1 -0
  47. prompture/scaffold/generator.py +84 -0
  48. prompture/scaffold/templates/Dockerfile.j2 +12 -0
  49. prompture/scaffold/templates/README.md.j2 +41 -0
  50. prompture/scaffold/templates/config.py.j2 +21 -0
  51. prompture/scaffold/templates/env.example.j2 +8 -0
  52. prompture/scaffold/templates/main.py.j2 +86 -0
  53. prompture/scaffold/templates/models.py.j2 +40 -0
  54. prompture/scaffold/templates/requirements.txt.j2 +5 -0
  55. prompture/server.py +183 -0
  56. prompture/session.py +117 -0
  57. prompture/settings.py +18 -1
  58. prompture/tools.py +219 -267
  59. prompture/tools_schema.py +254 -0
  60. prompture/validator.py +3 -3
  61. {prompture-0.0.29.dev8.dist-info → prompture-0.0.35.dist-info}/METADATA +117 -21
  62. prompture-0.0.35.dist-info/RECORD +66 -0
  63. {prompture-0.0.29.dev8.dist-info → prompture-0.0.35.dist-info}/WHEEL +1 -1
  64. prompture-0.0.29.dev8.dist-info/RECORD +0 -27
  65. {prompture-0.0.29.dev8.dist-info → prompture-0.0.35.dist-info}/entry_points.txt +0 -0
  66. {prompture-0.0.29.dev8.dist-info → prompture-0.0.35.dist-info}/licenses/LICENSE +0 -0
  67. {prompture-0.0.29.dev8.dist-info → prompture-0.0.35.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,254 @@
1
+ """Function calling / tool use support for Prompture.
2
+
3
+ Provides :class:`ToolDefinition` for describing callable tools,
4
+ :class:`ToolRegistry` for managing a collection of tools, and
5
+ :func:`tool_from_function` to auto-generate tool schemas from type hints.
6
+
7
+ Example::
8
+
9
+ from prompture import ToolRegistry
10
+
11
+ registry = ToolRegistry()
12
+
13
+ @registry.tool
14
+ def get_weather(city: str, units: str = "celsius") -> str:
15
+ \"\"\"Get the current weather for a city.\"\"\"
16
+ return f"Weather in {city}: 22 {units}"
17
+
18
+ # Or register explicitly
19
+ registry.register(get_weather)
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ import inspect
25
+ import logging
26
+ from dataclasses import dataclass, field
27
+ from typing import Any, Callable, get_type_hints
28
+
29
+ logger = logging.getLogger("prompture.tools_schema")
30
+
31
+ # Mapping from Python types to JSON Schema types
32
+ _TYPE_MAP: dict[type, str] = {
33
+ str: "string",
34
+ int: "integer",
35
+ float: "number",
36
+ bool: "boolean",
37
+ list: "array",
38
+ dict: "object",
39
+ }
40
+
41
+
42
+ def _python_type_to_json_schema(annotation: Any) -> dict[str, Any]:
43
+ """Convert a Python type annotation to a JSON Schema snippet."""
44
+ if annotation is inspect.Parameter.empty or annotation is None:
45
+ return {"type": "string"}
46
+
47
+ # Handle Optional[X] (Union[X, None])
48
+ origin = getattr(annotation, "__origin__", None)
49
+ args = getattr(annotation, "__args__", ())
50
+
51
+ if origin is type(None):
52
+ return {"type": "string"}
53
+
54
+ # Union types (Optional)
55
+ if origin is not None and hasattr(origin, "__name__") and origin.__name__ == "Union":
56
+ non_none = [a for a in args if a is not type(None)]
57
+ if len(non_none) == 1:
58
+ return _python_type_to_json_schema(non_none[0])
59
+
60
+ # list[X]
61
+ if origin is list and args:
62
+ return {"type": "array", "items": _python_type_to_json_schema(args[0])}
63
+
64
+ # dict[str, X]
65
+ if origin is dict:
66
+ return {"type": "object"}
67
+
68
+ # Simple types
69
+ json_type = _TYPE_MAP.get(annotation, "string")
70
+ return {"type": json_type}
71
+
72
+
73
+ @dataclass
74
+ class ToolDefinition:
75
+ """Describes a single callable tool the LLM can invoke.
76
+
77
+ Attributes:
78
+ name: Unique tool identifier.
79
+ description: Human-readable description shown to the LLM.
80
+ parameters: JSON Schema describing the function parameters.
81
+ function: The Python callable to execute.
82
+ """
83
+
84
+ name: str
85
+ description: str
86
+ parameters: dict[str, Any]
87
+ function: Callable[..., Any]
88
+
89
+ # ------------------------------------------------------------------
90
+ # Serialisation helpers
91
+ # ------------------------------------------------------------------
92
+
93
+ def to_openai_format(self) -> dict[str, Any]:
94
+ """Serialise to OpenAI ``tools`` array element format."""
95
+ return {
96
+ "type": "function",
97
+ "function": {
98
+ "name": self.name,
99
+ "description": self.description,
100
+ "parameters": self.parameters,
101
+ },
102
+ }
103
+
104
+ def to_anthropic_format(self) -> dict[str, Any]:
105
+ """Serialise to Anthropic ``tools`` array element format."""
106
+ return {
107
+ "name": self.name,
108
+ "description": self.description,
109
+ "input_schema": self.parameters,
110
+ }
111
+
112
+
113
+ def tool_from_function(fn: Callable[..., Any], *, name: str | None = None, description: str | None = None) -> ToolDefinition:
114
+ """Build a :class:`ToolDefinition` by inspecting *fn*'s signature and docstring.
115
+
116
+ Parameters:
117
+ fn: The callable to wrap.
118
+ name: Override the tool name (defaults to ``fn.__name__``).
119
+ description: Override the description (defaults to the first line of the docstring).
120
+ """
121
+ tool_name = name or fn.__name__
122
+ tool_desc = description or (inspect.getdoc(fn) or "").split("\n")[0] or f"Call {tool_name}"
123
+
124
+ sig = inspect.signature(fn)
125
+ try:
126
+ hints = get_type_hints(fn)
127
+ except Exception:
128
+ hints = {}
129
+
130
+ properties: dict[str, Any] = {}
131
+ required: list[str] = []
132
+
133
+ for param_name, param in sig.parameters.items():
134
+ if param_name == "self":
135
+ continue
136
+ annotation = hints.get(param_name, param.annotation)
137
+ prop = _python_type_to_json_schema(annotation)
138
+
139
+ # Use parameter name as description fallback
140
+ prop.setdefault("description", f"Parameter: {param_name}")
141
+
142
+ properties[param_name] = prop
143
+
144
+ if param.default is inspect.Parameter.empty:
145
+ required.append(param_name)
146
+
147
+ parameters: dict[str, Any] = {
148
+ "type": "object",
149
+ "properties": properties,
150
+ }
151
+ if required:
152
+ parameters["required"] = required
153
+
154
+ return ToolDefinition(
155
+ name=tool_name,
156
+ description=tool_desc,
157
+ parameters=parameters,
158
+ function=fn,
159
+ )
160
+
161
+
162
+ @dataclass
163
+ class ToolRegistry:
164
+ """A collection of :class:`ToolDefinition` instances.
165
+
166
+ Supports decorator-based and explicit registration::
167
+
168
+ registry = ToolRegistry()
169
+
170
+ @registry.tool
171
+ def my_func(x: int) -> str:
172
+ ...
173
+
174
+ registry.register(another_func)
175
+ """
176
+
177
+ _tools: dict[str, ToolDefinition] = field(default_factory=dict)
178
+
179
+ # ------------------------------------------------------------------
180
+ # Registration
181
+ # ------------------------------------------------------------------
182
+
183
+ def register(
184
+ self,
185
+ fn: Callable[..., Any],
186
+ *,
187
+ name: str | None = None,
188
+ description: str | None = None,
189
+ ) -> ToolDefinition:
190
+ """Register *fn* as a tool and return the :class:`ToolDefinition`."""
191
+ td = tool_from_function(fn, name=name, description=description)
192
+ self._tools[td.name] = td
193
+ return td
194
+
195
+ def tool(self, fn: Callable[..., Any]) -> Callable[..., Any]:
196
+ """Decorator to register a function as a tool.
197
+
198
+ Returns the original function unchanged so it remains callable.
199
+ """
200
+ self.register(fn)
201
+ return fn
202
+
203
+ def add(self, tool_def: ToolDefinition) -> None:
204
+ """Add a pre-built :class:`ToolDefinition`."""
205
+ self._tools[tool_def.name] = tool_def
206
+
207
+ # ------------------------------------------------------------------
208
+ # Lookup
209
+ # ------------------------------------------------------------------
210
+
211
+ def get(self, name: str) -> ToolDefinition | None:
212
+ return self._tools.get(name)
213
+
214
+ def __contains__(self, name: str) -> bool:
215
+ return name in self._tools
216
+
217
+ def __len__(self) -> int:
218
+ return len(self._tools)
219
+
220
+ def __bool__(self) -> bool:
221
+ return bool(self._tools)
222
+
223
+ @property
224
+ def names(self) -> list[str]:
225
+ return list(self._tools.keys())
226
+
227
+ @property
228
+ def definitions(self) -> list[ToolDefinition]:
229
+ return list(self._tools.values())
230
+
231
+ # ------------------------------------------------------------------
232
+ # Serialisation
233
+ # ------------------------------------------------------------------
234
+
235
+ def to_openai_format(self) -> list[dict[str, Any]]:
236
+ return [td.to_openai_format() for td in self._tools.values()]
237
+
238
+ def to_anthropic_format(self) -> list[dict[str, Any]]:
239
+ return [td.to_anthropic_format() for td in self._tools.values()]
240
+
241
+ # ------------------------------------------------------------------
242
+ # Execution
243
+ # ------------------------------------------------------------------
244
+
245
+ def execute(self, name: str, arguments: dict[str, Any]) -> Any:
246
+ """Execute a registered tool by name with the given arguments.
247
+
248
+ Raises:
249
+ KeyError: If no tool with *name* is registered.
250
+ """
251
+ td = self._tools.get(name)
252
+ if td is None:
253
+ raise KeyError(f"Tool not registered: {name!r}")
254
+ return td.function(**arguments)
prompture/validator.py CHANGED
@@ -1,5 +1,5 @@
1
1
  import json
2
- from typing import Any, Dict
2
+ from typing import Any
3
3
 
4
4
  try:
5
5
  import jsonschema
@@ -7,7 +7,7 @@ except Exception:
7
7
  jsonschema = None
8
8
 
9
9
 
10
- def validate_against_schema(instance_json: str, schema: Dict[str,Any]) -> Dict[str,Any]:
10
+ def validate_against_schema(instance_json: str, schema: dict[str, Any]) -> dict[str, Any]:
11
11
  """Valida el JSON (string) contra un JSON Schema.
12
12
  Devuelve dict con ok: bool y detalles.
13
13
  """
@@ -28,4 +28,4 @@ def validate_against_schema(instance_json: str, schema: Dict[str,Any]) -> Dict[s
28
28
  jsonschema.validate(instance=data, schema=schema)
29
29
  return {"ok": True, "data": data}
30
30
  except jsonschema.ValidationError as e:
31
- return {"ok": False, "error": str(e), "data": data}
31
+ return {"ok": False, "error": str(e), "data": data}
@@ -1,12 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: prompture
3
- Version: 0.0.29.dev8
3
+ Version: 0.0.35
4
4
  Summary: Ask LLMs to return structured JSON and run cross-model tests. API-first.
5
- Home-page: https://github.com/jhd3197/prompture
6
- Author: Juan Denis
7
- Author-email: juan@vene.co
5
+ Author-email: Juan Denis <juan@vene.co>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/jhd3197/prompture
8
8
  Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
9
  Classifier: Operating System :: OS Independent
11
10
  Requires-Python: >=3.9
12
11
  Description-Content-Type: text/markdown
@@ -18,26 +17,33 @@ Requires-Dist: groq>=0.4.0
18
17
  Requires-Dist: httpx>=0.25.0
19
18
  Requires-Dist: jsonschema>=4.0
20
19
  Requires-Dist: openai>=1.0.0
20
+ Requires-Dist: pandas>=1.3.0
21
21
  Requires-Dist: pydantic>=1.10
22
22
  Requires-Dist: pydantic-settings>=2.0
23
23
  Requires-Dist: python-dotenv>=0.19.0
24
+ Requires-Dist: python-toon>=0.1.0
24
25
  Requires-Dist: requests>=2.28
25
26
  Requires-Dist: python-dateutil>=2.9.0
26
27
  Requires-Dist: tukuy>=0.0.6
27
28
  Requires-Dist: pyyaml>=6.0
28
29
  Provides-Extra: test
29
30
  Requires-Dist: pytest>=7.0; extra == "test"
30
- Dynamic: author
31
- Dynamic: author-email
32
- Dynamic: classifier
33
- Dynamic: description
34
- Dynamic: description-content-type
35
- Dynamic: home-page
31
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "test"
32
+ Provides-Extra: dev
33
+ Requires-Dist: pytest>=7.0; extra == "dev"
34
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
35
+ Requires-Dist: ruff>=0.8.0; extra == "dev"
36
+ Provides-Extra: airllm
37
+ Requires-Dist: airllm>=2.8.0; extra == "airllm"
38
+ Provides-Extra: redis
39
+ Requires-Dist: redis>=4.0; extra == "redis"
40
+ Provides-Extra: serve
41
+ Requires-Dist: fastapi>=0.100; extra == "serve"
42
+ Requires-Dist: uvicorn[standard]>=0.20; extra == "serve"
43
+ Requires-Dist: sse-starlette>=1.6; extra == "serve"
44
+ Provides-Extra: scaffold
45
+ Requires-Dist: jinja2>=3.0; extra == "scaffold"
36
46
  Dynamic: license-file
37
- Dynamic: provides-extra
38
- Dynamic: requires-dist
39
- Dynamic: requires-python
40
- Dynamic: summary
41
47
 
42
48
  # Prompture
43
49
 
@@ -53,12 +59,13 @@ Dynamic: summary
53
59
  ## ✨ Features
54
60
 
55
61
  - ✅ **Structured output** → JSON schema enforcement, or direct **Pydantic** instances
62
+ - ✅ **TOON input conversion** → 45-60% token savings for structured data analysis with `extract_from_data()` and `extract_from_pandas()`
56
63
  - ✅ **Stepwise extraction** → Per-field prompts, with smart type conversion (incl. shorthand numbers)
57
64
  - ✅ **Multi-driver** → OpenAI, Azure, Claude, Ollama, LM Studio, Google, Groq, OpenRouter, Grok, HTTP, Mock, HuggingFace (via `get_driver()`)
58
65
  - ✅ **Usage & cost** → Token + $ tracking on every call (`usage` from driver meta)
59
66
  - ✅ **AI cleanup** → Optional LLM pass to fix malformed JSON
60
67
  - ✅ **Batch testing** → Define suites and compare models (spec-driven)
61
-
68
+ - 🧪 **Experimental TOON output** → Request Token-Oriented Object Notation when you need ultra-compact text
62
69
  <br>
63
70
 
64
71
  > [!TIP]
@@ -118,6 +125,25 @@ export LMSTUDIO_ENDPOINT=...
118
125
 
119
126
  ---
120
127
 
128
+ ## 🔍 Model Discovery
129
+
130
+ Prompture can auto-detect available models from your configured environment. This is especially useful for local setups (like Ollama) or when you want to see which models are available to your application.
131
+
132
+ ```python
133
+ from prompture import get_available_models
134
+
135
+ # Returns a list of strings like ["openai/gpt-4o", "ollama/llama3:latest", ...]
136
+ models = get_available_models()
137
+
138
+ for model in models:
139
+ print(f"Found: {model}")
140
+ ```
141
+
142
+ - **Static Drivers** (OpenAI, Claude, Azure, etc.): Returns models listed in the driver's `MODEL_PRICING` configuration if the driver is configured (API key present).
143
+ - **Dynamic Drivers** (Ollama): Queries the local endpoint (e.g., `http://localhost:11434/api/tags`) to fetch currently installed models.
144
+
145
+ ---
146
+
121
147
  ## Quickstart: Pydantic in one line (auto driver)
122
148
 
123
149
  Use `extract_with_model` for a single LLM call that fills your Pydantic model.
@@ -144,6 +170,55 @@ print(person.dict())
144
170
 
145
171
  **Why start here?** It's fast (one call), cost-efficient, and returns a validated Pydantic instance.
146
172
 
173
+
174
+ ## 🚀 TOON Input Conversion: 45-60% Token Savings
175
+
176
+ Analyze structured data with automatic TOON (Token-Oriented Object Notation) conversion for massive token savings.
177
+
178
+ ```python
179
+ from prompture import extract_from_data, extract_from_pandas
180
+
181
+ # Your product data
182
+ products = [
183
+ {"id": 1, "name": "Laptop", "price": 999.99, "rating": 4.5},
184
+ {"id": 2, "name": "Book", "price": 19.99, "rating": 4.2},
185
+ {"id": 3, "name": "Headphones", "price": 149.99, "rating": 4.7}
186
+ ]
187
+
188
+ # Ask questions about your data - automatically uses TOON format for 60%+ token savings
189
+ result = extract_from_data(
190
+ data=products,
191
+ question="What is the average price and highest rated product?",
192
+ json_schema={
193
+ "type": "object",
194
+ "properties": {
195
+ "average_price": {"type": "number"},
196
+ "highest_rated": {"type": "string"}
197
+ }
198
+ },
199
+ model_name="openai/gpt-4"
200
+ )
201
+
202
+ print(result["json_object"])
203
+ # {"average_price": 389.96, "highest_rated": "Headphones"}
204
+
205
+ print(f"Token savings: {result['token_savings']['percentage_saved']}%")
206
+ # Token savings: 62.3%
207
+
208
+ # Works with Pandas DataFrames too!
209
+ import pandas as pd
210
+ df = pd.DataFrame(products)
211
+ result = extract_from_pandas(df=df, question="...", json_schema=schema, model_name="openai/gpt-4")
212
+ ```
213
+
214
+ **Preview token savings without LLM calls:**
215
+ ```bash
216
+ python examples/token_comparison_utility.py
217
+ ```
218
+
219
+ > **Note:** Both `python-toon` and `pandas` are now included by default when you install Prompture!
220
+
221
+ ---
147
222
  ---
148
223
 
149
224
  ## 📋 Field Definitions
@@ -238,6 +313,25 @@ resp2 = extract_and_jsonify(
238
313
  print(resp2["json_object"], resp2["usage"])
239
314
  ```
240
315
 
316
+ ### Experimental TOON output
317
+
318
+ Prompture can ask for TOON (Token-Oriented Object Notation) instead of JSON by setting `output_format="toon"` on `ask_for_json`, `extract_and_jsonify`, `manual_extract_and_jsonify`, or `extract_with_model`. The LLM is still instructed to return JSON (for reliability); Prompture parses it and emits a TOON string via `python-toon`.
319
+
320
+ ```python
321
+ result = extract_and_jsonify(
322
+ text="Alice Johnson is a 30-year-old data scientist...",
323
+ json_schema=schema,
324
+ model_name="lmstudio/deepseek/deepseek-r1-0528-qwen3-8b",
325
+ output_format="toon",
326
+ )
327
+ print(result["toon_string"]) # TOON text generated locally
328
+ print(result["json_object"]) # regular dict parsed from the JSON response
329
+ # result["json_string"] still contains the original JSON text
330
+ ```
331
+
332
+ > [!IMPORTANT]
333
+ > TOON output is **experimental**. General-purpose models often emit more verbose completions when asked for TOON, so total token usage can increase (see `toon_token_analysis.md`). Treat it as an opt-in mode until TOON-aware fine-tunes or adapters are available.
334
+
241
335
  ### Return shape (JSON helpers)
242
336
 
243
337
  ```python
@@ -292,12 +386,15 @@ print(res["usage"]) # includes per-field usage and totals
292
386
 
293
387
  ## Manual control with logging
294
388
 
295
- `manual_extract_and_jsonify` is like `extract_and_jsonify` but adds structured debug logging.
389
+ `manual_extract_and_jsonify` is like `extract_and_jsonify` but lets you provide your own driver.
390
+ Enable library logging via Python's standard `logging` module:
296
391
 
297
392
  ```python
298
- from prompture import manual_extract_and_jsonify
393
+ import logging
394
+ from prompture import manual_extract_and_jsonify, configure_logging
299
395
  from prompture.drivers import get_driver
300
- from prompture.tools import LogLevel
396
+
397
+ configure_logging(logging.DEBUG) # see internal debug output
301
398
 
302
399
  driver = get_driver("ollama")
303
400
  res = manual_extract_and_jsonify(
@@ -310,7 +407,6 @@ res = manual_extract_and_jsonify(
310
407
  },
311
408
  model_name="llama3.1:8b",
312
409
  options={"temperature": 0.2},
313
- verbose_level=LogLevel.DEBUG # TRACE for full prompts/results
314
410
  )
315
411
  print(res["json_object"])
316
412
  ```
@@ -359,7 +455,7 @@ This example script compares multiple Ollama models on a complex task of extract
359
455
  * Add `description` to schema fields (or Pydantic field metadata) for better extractions.
360
456
  * Start with **one-shot Pydantic**; switch specific fields to **stepwise** if they’re noisy.
361
457
  * Track usage/cost before scaling; tweak `temperature` in `options` if consistency wobbles.
362
- * Use `verbose_level=TRACE` in dev to see prompts/results and tighten your specs.
458
+ * Use `configure_logging(logging.DEBUG)` in dev to see internal debug output and tighten your specs.
363
459
 
364
460
  ---
365
461
 
@@ -0,0 +1,66 @@
1
+ prompture/__init__.py,sha256=IzJ-QVN9MYX0VMjPEqsulDDDBvHKQpR9GtBYptSmRBg,4690
2
+ prompture/_version.py,sha256=w77E3DIE0tp22UaCyYn9461JfWMpEPhsv91t-4n4Bjw,706
3
+ prompture/async_conversation.py,sha256=i-cbV4WfPxU6m-SgeC7X-xl_Hg20B6zK-U4CJjeLFIA,23529
4
+ prompture/async_core.py,sha256=s8G0nGUGR1Bf_BQG9_FcQRpveSnJKkEwcWNfbAJaSkg,29208
5
+ prompture/async_driver.py,sha256=tyk8qc7VjMCyfP9MBAG15-EXa2kBM3tVhpJABGWAgFU,6075
6
+ prompture/cache.py,sha256=4dfQDMsEZ9JMQDXLOkiugPmmMJQIfKVE8rTAKDH4oL8,14401
7
+ prompture/callbacks.py,sha256=JPDqWGzPIzv44l54ocmezlYVBnbKPDEEXRrLdluWGAo,1731
8
+ prompture/cli.py,sha256=tNiIddRmgC1BomjY5O1VVVAwvqHVzF8IHmQrM-cG2wQ,2902
9
+ prompture/conversation.py,sha256=Kwz0iCQX8-bpxXVEX6SwNqbjFKj-NMGxxx6w7AfuqV8,24475
10
+ prompture/core.py,sha256=V__4YAt42WKf7CNiFRiET1oT2GFFIElOLFFF7mSFx-o,55735
11
+ prompture/cost_mixin.py,sha256=_spz84i8Qsplh6V3GkWyXXSUE4EwGy2IsbcsU2LEBxs,1918
12
+ prompture/discovery.py,sha256=_mSeeIQfRl3pHDPm84Mc2LDcOSwfkUanITXWeRPfv5E,7116
13
+ prompture/driver.py,sha256=3rLu-QZJBaOE2JwfRDt5xWDHuD5NdMBLfiYq4lMYyWs,7157
14
+ prompture/field_definitions.py,sha256=PLvxq2ot-ngJ8JbWkkZ-XLtM1wvjUQ3TL01vSEo-a6E,21368
15
+ prompture/logging.py,sha256=SkFO26_56Zai05vW8kTq3jvJudfLG2ipI5qNHaXKH3g,2574
16
+ prompture/model_rates.py,sha256=qtZUjsCVskA9LyG73JklG_kjKJHABA6ldBmBX0UzlSQ,6415
17
+ prompture/runner.py,sha256=lHe2L2jqY1pDXoKNPJALN9lAm-Q8QOY8C8gw-vM9VrM,4213
18
+ prompture/server.py,sha256=W6Kn6Et8nG5twXjD2wKn_N9yplGjz5Z-2naeI_UPd1Y,6198
19
+ prompture/session.py,sha256=FldK3cKq_jO0-beukVOhIiwsYWb6U_lLBlAERx95aaM,3821
20
+ prompture/settings.py,sha256=o-zsYpxRvSg-ICGWqqVNEoJG23GCMBLlkC7RPXpouSw,1976
21
+ prompture/tools.py,sha256=PmFbGHTWYWahpJOG6BLlM0Y-EG6S37IFW57C-8GdsXo,36449
22
+ prompture/tools_schema.py,sha256=JVc0dxC4aIHIUlgE8yFCcn1gPzJ3unTMVmZ8Ec04aD0,7764
23
+ prompture/validator.py,sha256=FY_VjIVEbjG2nwzh-r6l23Kt3UzaLyCis8_pZMNGHBA,993
24
+ prompture/aio/__init__.py,sha256=bKqTu4Jxld16aP_7SP9wU5au45UBIb041ORo4E4HzVo,1810
25
+ prompture/drivers/__init__.py,sha256=yj-z7_RMbfxP8zaKjQFZFcxGdf8Q2_KNQ6RTo7SPEpQ,6984
26
+ prompture/drivers/airllm_driver.py,sha256=SaTh7e7Plvuct_TfRqQvsJsKHvvM_3iVqhBtlciM-Kw,3858
27
+ prompture/drivers/async_airllm_driver.py,sha256=1hIWLXfyyIg9tXaOE22tLJvFyNwHnOi1M5BIKnV8ysk,908
28
+ prompture/drivers/async_azure_driver.py,sha256=vRp1PlOB87OLUbEZJEp7En3tvadG956Q6AV2o9UmyLA,4196
29
+ prompture/drivers/async_claude_driver.py,sha256=w9HRE7njh1N9BzX4QtsrUnMakKBb-nykBkvTwLmoFnw,3825
30
+ prompture/drivers/async_google_driver.py,sha256=qKMl6R60xBPQpsjCd9acXiXphVE5QxKbPSjxal7Sq2U,5656
31
+ prompture/drivers/async_grok_driver.py,sha256=yQgdBHiyyweueWDKChm9HnWzvbtWz60SNATsRKQY-RQ,3279
32
+ prompture/drivers/async_groq_driver.py,sha256=iShPE_YbR3oObHD3joFJDSmFeyCmaisLl7nwILbVux4,2808
33
+ prompture/drivers/async_hugging_driver.py,sha256=IblxqU6TpNUiigZ0BCgNkAgzpUr2FtPHJOZnOZMnHF0,2152
34
+ prompture/drivers/async_lmstudio_driver.py,sha256=7iQ-Fqezlpj4O13QC9oPjylGCINU5KvSRkwL52_2Cf0,2810
35
+ prompture/drivers/async_local_http_driver.py,sha256=qoigIf-w3_c2dbVdM6m1e2RMAWP4Gk4VzVs5hM3lPvQ,1609
36
+ prompture/drivers/async_ollama_driver.py,sha256=vRd2VIl412d6WVSo8vmZg0GBYUo7gBj-S2_55PpUWbk,4511
37
+ prompture/drivers/async_openai_driver.py,sha256=jHtSA_MeeIwGeE9o9F1ZsKTNgGGA7xF3WbGZgD8ACEU,3305
38
+ prompture/drivers/async_openrouter_driver.py,sha256=OKL4MfRAopXaMevf6A6WcAytyvWr0tWO_BmshdI0fSY,3516
39
+ prompture/drivers/async_registry.py,sha256=gJDr60688MZx9rbP-I8Um1gLeDwfRynv5SHsYjHjEGk,4263
40
+ prompture/drivers/azure_driver.py,sha256=4IAzdKqcORgVEDUj6itkVmJUg1ayo4HXSfqLKzIGnlM,5460
41
+ prompture/drivers/claude_driver.py,sha256=mZE3flcZImNCpMl803hLDd5KrkbYZt4VFQvF1ezs9qU,11269
42
+ prompture/drivers/google_driver.py,sha256=Ysa1ZZEAPEKHCJFCBiJtB4K-sGvsYti4hGBv_85nowY,8454
43
+ prompture/drivers/grok_driver.py,sha256=_ZQfmE4NfzHTj-nTEtBkWFbypjCF_4aWFODAaxxEjog,5027
44
+ prompture/drivers/groq_driver.py,sha256=QfMhzKDhTQyU7yG0oayCojunaKPdxrxzYo-u87_uN18,3928
45
+ prompture/drivers/hugging_driver.py,sha256=gZir3XnM77VfYIdnu3S1pRftlZJM6G3L8bgGn5esg-Q,2346
46
+ prompture/drivers/lmstudio_driver.py,sha256=AuhmKS4DBvxEPSfjL-uN7wnAyFWoB7Wjk1o0Oscan4I,4010
47
+ prompture/drivers/local_http_driver.py,sha256=QJgEf9kAmy8YZ5fb8FHnWuhoDoZYNd8at4jegzNVJH0,1658
48
+ prompture/drivers/ollama_driver.py,sha256=o44HCKbljLRN6TCMylj0X4RjvtI_VaZdoDZXsLQBkH4,9577
49
+ prompture/drivers/openai_driver.py,sha256=Dg0YiduDSyTiLMG4F9YuWKB0vbzVuOYOog5CpWgbxxo,9897
50
+ prompture/drivers/openrouter_driver.py,sha256=WH48KEkafuxFX6b55FzwT57tUlmbwYlHSeNsIxWvM4o,5141
51
+ prompture/drivers/registry.py,sha256=Dg_5w9alnIPKhOnsR9Xspuf5T7roBGu0r_L2Cf-UhXs,9926
52
+ prompture/scaffold/__init__.py,sha256=aitUxBV0MpjC7Od3iG8WUzcC7tGPXSt3oMzUBX8UDwQ,60
53
+ prompture/scaffold/generator.py,sha256=5QTHdWEXB7ADqOttfU7NgoxuaofNQnObzzI7NIPWFgo,2387
54
+ prompture/scaffold/templates/Dockerfile.j2,sha256=ukox6eVzQMVw-hAaFmNRL5HTrXw2Z0RB6g-vvbMVeu8,207
55
+ prompture/scaffold/templates/README.md.j2,sha256=xFgKnEP_JmLiiwD1QahNWdyKC85smyhOiIBCmN2U3y0,935
56
+ prompture/scaffold/templates/config.py.j2,sha256=q1LOnLlGzgJHPQz5geZ2AvrB-DskkLzay_CSj26hthE,529
57
+ prompture/scaffold/templates/env.example.j2,sha256=eESKr1KWgyrczO6d-nwAhQwSpf_G-T6P9gmHMhR9Sqc,246
58
+ prompture/scaffold/templates/main.py.j2,sha256=TEgc5OvsZOEX0JthkSW1NI_yLwgoeVN_x97Ibg-vyWY,2632
59
+ prompture/scaffold/templates/models.py.j2,sha256=JrZ99GCVK6TKWapskVRSwCssGrTu5cGZ_r46fOhY2GE,858
60
+ prompture/scaffold/templates/requirements.txt.j2,sha256=m3S5fi1hq9KG9l_9j317rjwWww0a43WMKd8VnUWv2A4,102
61
+ prompture-0.0.35.dist-info/licenses/LICENSE,sha256=0HgDepH7aaHNFhHF-iXuW6_GqDfYPnVkjtiCAZ4yS8I,1060
62
+ prompture-0.0.35.dist-info/METADATA,sha256=UZZi4UWdcyxEwwdZDeM_8A6bTRobx3zd8R0T0-mjQ1Y,18478
63
+ prompture-0.0.35.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
64
+ prompture-0.0.35.dist-info/entry_points.txt,sha256=AFPG3lJR86g4IJMoWQUW5Ph7G6MLNWG3A2u2Tp9zkp8,48
65
+ prompture-0.0.35.dist-info/top_level.txt,sha256=to86zq_kjfdoLeAxQNr420UWqT0WzkKoZ509J7Qr2t4,10
66
+ prompture-0.0.35.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,27 +0,0 @@
1
- prompture/__init__.py,sha256=bZb1qaYkFU8nDXwNsUTwXyawK55lUhbw2EteimolZuk,1870
2
- prompture/cli.py,sha256=vA86GNjtKSHz8eRMl5YDaT9HHIWuhkeJtfx8jqTaqtM,809
3
- prompture/core.py,sha256=aqhYIRlt39awsiDP16gg3cCS_Fua3JhW3eFqWOnWoVQ,35962
4
- prompture/driver.py,sha256=w8pdXHujImIGF3ee8rkG8f6-UD0h2jLHhucSPInRrYI,989
5
- prompture/field_definitions.py,sha256=6kDMYNedccTK5l2L_I8_NI3_av-iYHqGPwkKDy8214c,21731
6
- prompture/runner.py,sha256=5xwal3iBQQj4_q7l3Rjr0e3RrUMJPaPDLiEchO0mmHo,4192
7
- prompture/settings.py,sha256=vHRkBAZNP6yRsI2Sm4FMa_FCw0Zxy2VX97ooiVYWvks,1500
8
- prompture/tools.py,sha256=yULrVyhyE-rQF7Mvwe4zNFbB-hSDGGSOr7mCVxM0I60,38965
9
- prompture/validator.py,sha256=oLzVsNveHuF-N_uOd11_uDa9Q5rFyo0wrk_l1N4zqDk,996
10
- prompture/drivers/__init__.py,sha256=IQ7DsWC_FP45h2CprWRhQ7lKi3-9ZO6CgweNX6IxTUA,3896
11
- prompture/drivers/azure_driver.py,sha256=GROhK3hqMfMurnEgpAawa1DPS-FhOU0YQcgy9SNGTzM,4622
12
- prompture/drivers/claude_driver.py,sha256=ZEHQNqNThLZ0p-WmGVuKiNyiudGYGP07xIzbgZhLY1g,3293
13
- prompture/drivers/google_driver.py,sha256=SOo02nJuNJiOE_pcGCo-LAmz7DA9pOazSOqI29K99zo,4771
14
- prompture/drivers/grok_driver.py,sha256=Xp6L75oL3dN8St8_m46C_5bM8FcaIdNKUASAt9kZ39w,5003
15
- prompture/drivers/groq_driver.py,sha256=91WGXP8G5dO0beuFO8FehZszlDC_X9hv_yPzQRGmcqw,3920
16
- prompture/drivers/hugging_driver.py,sha256=rngz7hIR7l-9M_xe4EjWPaBqdyPFHdQsqnDDy9gm5So,2357
17
- prompture/drivers/lmstudio_driver.py,sha256=Umy1kT211TAxxSPyQrtZnIGIZgqFeSV87FLTiPFF0CY,3455
18
- prompture/drivers/local_http_driver.py,sha256=S2diikvtQOQHF7fB07zU2X0QWkej4Of__rJgaU2C6FI,1669
19
- prompture/drivers/ollama_driver.py,sha256=fq_eFgwmCT3SK1D-ICHjxLjcm_An0suwkFIWC38xsS0,4681
20
- prompture/drivers/openai_driver.py,sha256=9q9OjQslquRFvIl1Hd9JVmFFFVh6OBIWrFulw1mkYWg,3976
21
- prompture/drivers/openrouter_driver.py,sha256=GKvLOFDhsyopH-k3iaD3VWllm7xbGuopRSA02MfCKoM,5031
22
- prompture-0.0.29.dev8.dist-info/licenses/LICENSE,sha256=0HgDepH7aaHNFhHF-iXuW6_GqDfYPnVkjtiCAZ4yS8I,1060
23
- prompture-0.0.29.dev8.dist-info/METADATA,sha256=zb5atZWplRLdhVAKLHHv3Mt0BLPFRZn--q7qFv_TnMs,14432
24
- prompture-0.0.29.dev8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
- prompture-0.0.29.dev8.dist-info/entry_points.txt,sha256=AFPG3lJR86g4IJMoWQUW5Ph7G6MLNWG3A2u2Tp9zkp8,48
26
- prompture-0.0.29.dev8.dist-info/top_level.txt,sha256=to86zq_kjfdoLeAxQNr420UWqT0WzkKoZ509J7Qr2t4,10
27
- prompture-0.0.29.dev8.dist-info/RECORD,,