prompture 0.0.47__py3-none-any.whl → 0.0.47.dev1__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.
@@ -122,17 +122,8 @@ class AsyncOpenRouterDriver(CostMixin, AsyncDriver):
122
122
  "model_name": model,
123
123
  }
124
124
 
125
- message = resp["choices"][0]["message"]
126
- text = message.get("content") or ""
127
- reasoning_content = message.get("reasoning_content")
128
-
129
- if not text and reasoning_content:
130
- text = reasoning_content
131
-
132
- result: dict[str, Any] = {"text": text, "meta": meta}
133
- if reasoning_content is not None:
134
- result["reasoning_content"] = reasoning_content
135
- return result
125
+ text = resp["choices"][0]["message"]["content"]
126
+ return {"text": text, "meta": meta}
136
127
 
137
128
  # ------------------------------------------------------------------
138
129
  # Tool use
@@ -205,23 +196,18 @@ class AsyncOpenRouterDriver(CostMixin, AsyncDriver):
205
196
  args = json.loads(tc["function"]["arguments"])
206
197
  except (json.JSONDecodeError, TypeError):
207
198
  args = {}
208
- tool_calls_out.append(
209
- {
210
- "id": tc["id"],
211
- "name": tc["function"]["name"],
212
- "arguments": args,
213
- }
214
- )
199
+ tool_calls_out.append({
200
+ "id": tc["id"],
201
+ "name": tc["function"]["name"],
202
+ "arguments": args,
203
+ })
215
204
 
216
- result: dict[str, Any] = {
205
+ return {
217
206
  "text": text,
218
207
  "meta": meta,
219
208
  "tool_calls": tool_calls_out,
220
209
  "stop_reason": stop_reason,
221
210
  }
222
- if choice["message"].get("reasoning_content") is not None:
223
- result["reasoning_content"] = choice["message"]["reasoning_content"]
224
- return result
225
211
 
226
212
  # ------------------------------------------------------------------
227
213
  # Streaming
@@ -252,25 +238,21 @@ class AsyncOpenRouterDriver(CostMixin, AsyncDriver):
252
238
  data["temperature"] = opts["temperature"]
253
239
 
254
240
  full_text = ""
255
- full_reasoning = ""
256
241
  prompt_tokens = 0
257
242
  completion_tokens = 0
258
243
 
259
- async with (
260
- httpx.AsyncClient() as client,
261
- client.stream(
262
- "POST",
263
- f"{self.base_url}/chat/completions",
264
- headers=self.headers,
265
- json=data,
266
- timeout=120,
267
- ) as response,
268
- ):
244
+ async with httpx.AsyncClient() as client, client.stream(
245
+ "POST",
246
+ f"{self.base_url}/chat/completions",
247
+ headers=self.headers,
248
+ json=data,
249
+ timeout=120,
250
+ ) as response:
269
251
  response.raise_for_status()
270
252
  async for line in response.aiter_lines():
271
253
  if not line or not line.startswith("data: "):
272
254
  continue
273
- payload = line[len("data: ") :]
255
+ payload = line[len("data: "):]
274
256
  if payload.strip() == "[DONE]":
275
257
  break
276
258
  try:
@@ -288,11 +270,6 @@ class AsyncOpenRouterDriver(CostMixin, AsyncDriver):
288
270
  if choices:
289
271
  delta = choices[0].get("delta", {})
290
272
  content = delta.get("content", "")
291
- reasoning_chunk = delta.get("reasoning_content") or ""
292
- if reasoning_chunk:
293
- full_reasoning += reasoning_chunk
294
- if not content and reasoning_chunk:
295
- content = reasoning_chunk
296
273
  if content:
297
274
  full_text += content
298
275
  yield {"type": "delta", "text": content}
@@ -300,7 +277,7 @@ class AsyncOpenRouterDriver(CostMixin, AsyncDriver):
300
277
  total_tokens = prompt_tokens + completion_tokens
301
278
  total_cost = self._calculate_cost("openrouter", model, prompt_tokens, completion_tokens)
302
279
 
303
- done_chunk: dict[str, Any] = {
280
+ yield {
304
281
  "type": "done",
305
282
  "text": full_text,
306
283
  "meta": {
@@ -312,6 +289,3 @@ class AsyncOpenRouterDriver(CostMixin, AsyncDriver):
312
289
  "model_name": model,
313
290
  },
314
291
  }
315
- if full_reasoning:
316
- done_chunk["reasoning_content"] = full_reasoning
317
- yield done_chunk
@@ -154,17 +154,8 @@ class GrokDriver(CostMixin, Driver):
154
154
  "model_name": model,
155
155
  }
156
156
 
157
- message = resp["choices"][0]["message"]
158
- text = message.get("content") or ""
159
- reasoning_content = message.get("reasoning_content")
160
-
161
- if not text and reasoning_content:
162
- text = reasoning_content
163
-
164
- result: dict[str, Any] = {"text": text, "meta": meta}
165
- if reasoning_content is not None:
166
- result["reasoning_content"] = reasoning_content
167
- return result
157
+ text = resp["choices"][0]["message"]["content"]
158
+ return {"text": text, "meta": meta}
168
159
 
169
160
  # ------------------------------------------------------------------
170
161
  # Tool use
@@ -236,20 +227,15 @@ class GrokDriver(CostMixin, Driver):
236
227
  args = json.loads(tc["function"]["arguments"])
237
228
  except (json.JSONDecodeError, TypeError):
238
229
  args = {}
239
- tool_calls_out.append(
240
- {
241
- "id": tc["id"],
242
- "name": tc["function"]["name"],
243
- "arguments": args,
244
- }
245
- )
246
-
247
- result: dict[str, Any] = {
230
+ tool_calls_out.append({
231
+ "id": tc["id"],
232
+ "name": tc["function"]["name"],
233
+ "arguments": args,
234
+ })
235
+
236
+ return {
248
237
  "text": text,
249
238
  "meta": meta,
250
239
  "tool_calls": tool_calls_out,
251
240
  "stop_reason": stop_reason,
252
241
  }
253
- if choice["message"].get("reasoning_content") is not None:
254
- result["reasoning_content"] = choice["message"]["reasoning_content"]
255
- return result
@@ -122,16 +122,8 @@ class GroqDriver(CostMixin, Driver):
122
122
  }
123
123
 
124
124
  # Extract generated text
125
- text = resp.choices[0].message.content or ""
126
- reasoning_content = getattr(resp.choices[0].message, "reasoning_content", None)
127
-
128
- if not text and reasoning_content:
129
- text = reasoning_content
130
-
131
- result: dict[str, Any] = {"text": text, "meta": meta}
132
- if reasoning_content is not None:
133
- result["reasoning_content"] = reasoning_content
134
- return result
125
+ text = resp.choices[0].message.content
126
+ return {"text": text, "meta": meta}
135
127
 
136
128
  # ------------------------------------------------------------------
137
129
  # Tool use
@@ -194,21 +186,15 @@ class GroqDriver(CostMixin, Driver):
194
186
  args = json.loads(tc.function.arguments)
195
187
  except (json.JSONDecodeError, TypeError):
196
188
  args = {}
197
- tool_calls_out.append(
198
- {
199
- "id": tc.id,
200
- "name": tc.function.name,
201
- "arguments": args,
202
- }
203
- )
204
-
205
- result: dict[str, Any] = {
189
+ tool_calls_out.append({
190
+ "id": tc.id,
191
+ "name": tc.function.name,
192
+ "arguments": args,
193
+ })
194
+
195
+ return {
206
196
  "text": text,
207
197
  "meta": meta,
208
198
  "tool_calls": tool_calls_out,
209
199
  "stop_reason": stop_reason,
210
200
  }
211
- reasoning_content = getattr(choice.message, "reasoning_content", None)
212
- if reasoning_content is not None:
213
- result["reasoning_content"] = reasoning_content
214
- return result
@@ -123,13 +123,7 @@ class LMStudioDriver(Driver):
123
123
  raise RuntimeError(f"LM Studio request failed: {e}") from e
124
124
 
125
125
  # Extract text
126
- message = response_data["choices"][0]["message"]
127
- text = message.get("content") or ""
128
- reasoning_content = message.get("reasoning_content")
129
-
130
- # Reasoning models (e.g. DeepSeek R1) may return content in reasoning_content
131
- if not text and reasoning_content:
132
- text = reasoning_content
126
+ text = response_data["choices"][0]["message"]["content"]
133
127
 
134
128
  # Meta info
135
129
  usage = response_data.get("usage", {})
@@ -146,10 +140,7 @@ class LMStudioDriver(Driver):
146
140
  "model_name": merged_options.get("model", self.model),
147
141
  }
148
142
 
149
- result: dict[str, Any] = {"text": text, "meta": meta}
150
- if reasoning_content is not None:
151
- result["reasoning_content"] = reasoning_content
152
- return result
143
+ return {"text": text, "meta": meta}
153
144
 
154
145
  # -- Model management (LM Studio 0.4.0+) ----------------------------------
155
146
 
@@ -228,11 +228,10 @@ class MoonshotDriver(CostMixin, Driver):
228
228
 
229
229
  message = resp["choices"][0]["message"]
230
230
  text = message.get("content") or ""
231
- reasoning_content = message.get("reasoning_content")
232
231
 
233
232
  # Reasoning models may return content in reasoning_content when content is empty
234
- if not text and reasoning_content:
235
- text = reasoning_content
233
+ if not text and message.get("reasoning_content"):
234
+ text = message["reasoning_content"]
236
235
 
237
236
  # Structured output fallback: if we used json_schema mode and got an
238
237
  # empty response, retry with json_object mode and schema in the prompt.
@@ -276,9 +275,8 @@ class MoonshotDriver(CostMixin, Driver):
276
275
  resp = fb_resp
277
276
  fb_message = fb_resp["choices"][0]["message"]
278
277
  text = fb_message.get("content") or ""
279
- reasoning_content = fb_message.get("reasoning_content")
280
- if not text and reasoning_content:
281
- text = reasoning_content
278
+ if not text and fb_message.get("reasoning_content"):
279
+ text = fb_message["reasoning_content"]
282
280
 
283
281
  total_cost = self._calculate_cost("moonshot", model, prompt_tokens, completion_tokens)
284
282
 
@@ -291,10 +289,7 @@ class MoonshotDriver(CostMixin, Driver):
291
289
  "model_name": model,
292
290
  }
293
291
 
294
- result: dict[str, Any] = {"text": text, "meta": meta}
295
- if reasoning_content is not None:
296
- result["reasoning_content"] = reasoning_content
297
- return result
292
+ return {"text": text, "meta": meta}
298
293
 
299
294
  # ------------------------------------------------------------------
300
295
  # Tool use
@@ -369,12 +364,11 @@ class MoonshotDriver(CostMixin, Driver):
369
364
  }
370
365
 
371
366
  choice = resp["choices"][0]
372
- message = choice["message"]
373
- text = message.get("content") or ""
367
+ text = choice["message"].get("content") or ""
374
368
  stop_reason = choice.get("finish_reason")
375
369
 
376
370
  tool_calls_out: list[dict[str, Any]] = []
377
- for tc in message.get("tool_calls", []):
371
+ for tc in choice["message"].get("tool_calls", []):
378
372
  try:
379
373
  args = json.loads(tc["function"]["arguments"])
380
374
  except (json.JSONDecodeError, TypeError):
@@ -387,21 +381,13 @@ class MoonshotDriver(CostMixin, Driver):
387
381
  }
388
382
  )
389
383
 
390
- result: dict[str, Any] = {
384
+ return {
391
385
  "text": text,
392
386
  "meta": meta,
393
387
  "tool_calls": tool_calls_out,
394
388
  "stop_reason": stop_reason,
395
389
  }
396
390
 
397
- # Preserve reasoning_content for reasoning models so the
398
- # conversation loop can include it when sending the assistant
399
- # message back (Moonshot requires it on subsequent requests).
400
- if message.get("reasoning_content") is not None:
401
- result["reasoning_content"] = message["reasoning_content"]
402
-
403
- return result
404
-
405
391
  # ------------------------------------------------------------------
406
392
  # Streaming
407
393
  # ------------------------------------------------------------------
@@ -444,7 +430,6 @@ class MoonshotDriver(CostMixin, Driver):
444
430
  response.raise_for_status()
445
431
 
446
432
  full_text = ""
447
- full_reasoning = ""
448
433
  prompt_tokens = 0
449
434
  completion_tokens = 0
450
435
 
@@ -468,11 +453,9 @@ class MoonshotDriver(CostMixin, Driver):
468
453
  if choices:
469
454
  delta = choices[0].get("delta", {})
470
455
  content = delta.get("content") or ""
471
- reasoning_chunk = delta.get("reasoning_content") or ""
472
- if reasoning_chunk:
473
- full_reasoning += reasoning_chunk
474
- if not content and reasoning_chunk:
475
- content = reasoning_chunk
456
+ # Reasoning models stream thinking via reasoning_content
457
+ if not content:
458
+ content = delta.get("reasoning_content") or ""
476
459
  if content:
477
460
  full_text += content
478
461
  yield {"type": "delta", "text": content}
@@ -480,7 +463,7 @@ class MoonshotDriver(CostMixin, Driver):
480
463
  total_tokens = prompt_tokens + completion_tokens
481
464
  total_cost = self._calculate_cost("moonshot", model, prompt_tokens, completion_tokens)
482
465
 
483
- done_chunk: dict[str, Any] = {
466
+ yield {
484
467
  "type": "done",
485
468
  "text": full_text,
486
469
  "meta": {
@@ -492,6 +475,3 @@ class MoonshotDriver(CostMixin, Driver):
492
475
  "model_name": model,
493
476
  },
494
477
  }
495
- if full_reasoning:
496
- done_chunk["reasoning_content"] = full_reasoning
497
- yield done_chunk
@@ -181,18 +181,8 @@ class OpenRouterDriver(CostMixin, Driver):
181
181
  "model_name": model,
182
182
  }
183
183
 
184
- message = resp["choices"][0]["message"]
185
- text = message.get("content") or ""
186
- reasoning_content = message.get("reasoning_content")
187
-
188
- # Reasoning models may return content in reasoning_content when content is empty
189
- if not text and reasoning_content:
190
- text = reasoning_content
191
-
192
- result: dict[str, Any] = {"text": text, "meta": meta}
193
- if reasoning_content is not None:
194
- result["reasoning_content"] = reasoning_content
195
- return result
184
+ text = resp["choices"][0]["message"]["content"]
185
+ return {"text": text, "meta": meta}
196
186
 
197
187
  # ------------------------------------------------------------------
198
188
  # Tool use
@@ -267,23 +257,18 @@ class OpenRouterDriver(CostMixin, Driver):
267
257
  args = json.loads(tc["function"]["arguments"])
268
258
  except (json.JSONDecodeError, TypeError):
269
259
  args = {}
270
- tool_calls_out.append(
271
- {
272
- "id": tc["id"],
273
- "name": tc["function"]["name"],
274
- "arguments": args,
275
- }
276
- )
260
+ tool_calls_out.append({
261
+ "id": tc["id"],
262
+ "name": tc["function"]["name"],
263
+ "arguments": args,
264
+ })
277
265
 
278
- result: dict[str, Any] = {
266
+ return {
279
267
  "text": text,
280
268
  "meta": meta,
281
269
  "tool_calls": tool_calls_out,
282
270
  "stop_reason": stop_reason,
283
271
  }
284
- if choice["message"].get("reasoning_content") is not None:
285
- result["reasoning_content"] = choice["message"]["reasoning_content"]
286
- return result
287
272
 
288
273
  # ------------------------------------------------------------------
289
274
  # Streaming
@@ -326,14 +311,13 @@ class OpenRouterDriver(CostMixin, Driver):
326
311
  response.raise_for_status()
327
312
 
328
313
  full_text = ""
329
- full_reasoning = ""
330
314
  prompt_tokens = 0
331
315
  completion_tokens = 0
332
316
 
333
317
  for line in response.iter_lines(decode_unicode=True):
334
318
  if not line or not line.startswith("data: "):
335
319
  continue
336
- payload = line[len("data: ") :]
320
+ payload = line[len("data: "):]
337
321
  if payload.strip() == "[DONE]":
338
322
  break
339
323
  try:
@@ -351,11 +335,6 @@ class OpenRouterDriver(CostMixin, Driver):
351
335
  if choices:
352
336
  delta = choices[0].get("delta", {})
353
337
  content = delta.get("content", "")
354
- reasoning_chunk = delta.get("reasoning_content") or ""
355
- if reasoning_chunk:
356
- full_reasoning += reasoning_chunk
357
- if not content and reasoning_chunk:
358
- content = reasoning_chunk
359
338
  if content:
360
339
  full_text += content
361
340
  yield {"type": "delta", "text": content}
@@ -363,7 +342,7 @@ class OpenRouterDriver(CostMixin, Driver):
363
342
  total_tokens = prompt_tokens + completion_tokens
364
343
  total_cost = self._calculate_cost("openrouter", model, prompt_tokens, completion_tokens)
365
344
 
366
- done_chunk: dict[str, Any] = {
345
+ yield {
367
346
  "type": "done",
368
347
  "text": full_text,
369
348
  "meta": {
@@ -375,6 +354,3 @@ class OpenRouterDriver(CostMixin, Driver):
375
354
  "model_name": model,
376
355
  },
377
356
  }
378
- if full_reasoning:
379
- done_chunk["reasoning_content"] = full_reasoning
380
- yield done_chunk
prompture/tools_schema.py CHANGED
@@ -109,24 +109,6 @@ class ToolDefinition:
109
109
  "input_schema": self.parameters,
110
110
  }
111
111
 
112
- def to_prompt_format(self) -> str:
113
- """Plain-text description suitable for prompt-based tool calling."""
114
- lines = [f"Tool: {self.name}", f" Description: {self.description}", " Parameters:"]
115
- props = self.parameters.get("properties", {})
116
- required = set(self.parameters.get("required", []))
117
- if not props:
118
- lines.append(" (none)")
119
- else:
120
- for pname, pschema in props.items():
121
- ptype = pschema.get("type", "string")
122
- req_label = "required" if pname in required else "optional"
123
- desc = pschema.get("description", "")
124
- line = f" - {pname} ({ptype}, {req_label})"
125
- if desc:
126
- line += f": {desc}"
127
- lines.append(line)
128
- return "\n".join(lines)
129
-
130
112
 
131
113
  def tool_from_function(
132
114
  fn: Callable[..., Any], *, name: str | None = None, description: str | None = None
@@ -262,10 +244,6 @@ class ToolRegistry:
262
244
  def to_anthropic_format(self) -> list[dict[str, Any]]:
263
245
  return [td.to_anthropic_format() for td in self._tools.values()]
264
246
 
265
- def to_prompt_format(self) -> str:
266
- """Join all tool descriptions into a single plain-text block."""
267
- return "\n\n".join(td.to_prompt_format() for td in self._tools.values())
268
-
269
247
  # ------------------------------------------------------------------
270
248
  # Execution
271
249
  # ------------------------------------------------------------------
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: prompture
3
- Version: 0.0.47
3
+ Version: 0.0.47.dev1
4
4
  Summary: Ask LLMs to return structured JSON and run cross-model tests. API-first.
5
5
  Author-email: Juan Denis <juan@vene.co>
6
6
  License-Expression: MIT
@@ -83,7 +83,7 @@ print(person.name) # Maria
83
83
  - **Stepwise extraction** — Per-field prompts with smart type coercion (shorthand numbers, multilingual booleans, dates)
84
84
  - **Field registry** — 50+ predefined extraction fields with template variables and Pydantic integration
85
85
  - **Conversations** — Stateful multi-turn sessions with sync and async support
86
- - **Tool use** — Function calling and streaming across supported providers, with automatic prompt-based simulation for models without native tool support
86
+ - **Tool use** — Function calling and streaming across supported providers
87
87
  - **Caching** — Built-in response cache with memory, SQLite, and Redis backends
88
88
  - **Plugin system** — Register custom drivers via entry points
89
89
  - **Usage tracking** — Token counts and cost calculation on every call
@@ -296,39 +296,6 @@ response = conv.send("What is the capital of France?")
296
296
  follow_up = conv.send("What about Germany?") # retains context
297
297
  ```
298
298
 
299
- ### Tool Use
300
-
301
- Register Python functions as tools the LLM can call during a conversation:
302
-
303
- ```python
304
- from prompture import Conversation, ToolRegistry
305
-
306
- registry = ToolRegistry()
307
-
308
- @registry.tool
309
- def get_weather(city: str, units: str = "celsius") -> str:
310
- """Get the current weather for a city."""
311
- return f"Weather in {city}: 22 {units}"
312
-
313
- conv = Conversation("openai/gpt-4", tools=registry)
314
- result = conv.ask("What's the weather in London?")
315
- ```
316
-
317
- For models without native function calling (Ollama, LM Studio, etc.), Prompture automatically simulates tool use by describing tools in the prompt and parsing structured JSON responses:
318
-
319
- ```python
320
- # Auto-detect: uses native tool calling if available, simulation otherwise
321
- conv = Conversation("ollama/llama3.1:8b", tools=registry, simulated_tools="auto")
322
-
323
- # Force simulation even on capable models
324
- conv = Conversation("openai/gpt-4", tools=registry, simulated_tools=True)
325
-
326
- # Disable tool use entirely
327
- conv = Conversation("openai/gpt-4", tools=registry, simulated_tools=False)
328
- ```
329
-
330
- The simulation loop describes tools in the system prompt, asks the model to respond with JSON (`tool_call` or `final_answer`), executes tools, and feeds results back — all transparent to the caller.
331
-
332
299
  ### Model Discovery
333
300
 
334
301
  Auto-detect available models from configured providers:
@@ -1,16 +1,16 @@
1
1
  prompture/__init__.py,sha256=cJnkefDpiyFbU77juw4tXPdKJQWoJ-c6XBFt2v-e5Q4,7455
2
- prompture/_version.py,sha256=ToAw384WWguTEmRR8YKQKk9ZB9M3thyPsfPaIkOPqog,706
2
+ prompture/_version.py,sha256=m4L2kLiZktyjsO5dlv6VYgYlU0JGlYNdugMyoHzVbXk,719
3
3
  prompture/agent.py,sha256=-8qdo_Lz20GGssCe5B_QPxb5Kct71YtKHh5vZgrSYik,34748
4
4
  prompture/agent_types.py,sha256=Icl16PQI-ThGLMFCU43adtQA6cqETbsPn4KssKBI4xc,4664
5
5
  prompture/async_agent.py,sha256=_6_IRb-LGzZxGxfPVy43SIWByUoQfN-5XnUWahVP6r8,33110
6
- prompture/async_conversation.py,sha256=tzOy2jiCOVkRHIJ9H6VeRwwcUtbjF33--igdxMC6F7s,34811
6
+ prompture/async_conversation.py,sha256=m9sdKBu1wxo5veGwO6g6Zvf1sBzpuxP-mSIEeNKlBjQ,31155
7
7
  prompture/async_core.py,sha256=hbRXLvsBJv3JAnUwGZbazsL6x022FrsJU6swmZolgxY,29745
8
8
  prompture/async_driver.py,sha256=4VQ9Q_tI6Ufw6W1CYJ5j8hVtgVdqFGuk6e2tLaSceWE,8581
9
9
  prompture/async_groups.py,sha256=pceKrt0UayQjMLFs1dFGoxOHpgD948aEjIY61r608C4,22459
10
10
  prompture/cache.py,sha256=4dfQDMsEZ9JMQDXLOkiugPmmMJQIfKVE8rTAKDH4oL8,14401
11
11
  prompture/callbacks.py,sha256=JPDqWGzPIzv44l54ocmezlYVBnbKPDEEXRrLdluWGAo,1731
12
12
  prompture/cli.py,sha256=tNiIddRmgC1BomjY5O1VVVAwvqHVzF8IHmQrM-cG2wQ,2902
13
- prompture/conversation.py,sha256=uxstayJjgY6a39DtU0YxQl0Dt3JBo2UVCyMPJW95MNI,36428
13
+ prompture/conversation.py,sha256=kBflwh7Qmw1I_jcUGyV36oskdVz4SYDSw_dCjemRRRc,32756
14
14
  prompture/core.py,sha256=5FHwX7fNPwFHMbFCMvV-RH7LpPpTToLAmcyDnKbrN0E,57202
15
15
  prompture/cost_mixin.py,sha256=Qx7gPgPsWgTHiaFeI7q_p9cfe95ccjgN8Mi56d_AVX0,4563
16
16
  prompture/discovery.py,sha256=K-svbO-qJraHinCbFVS64vEo5McWX5pURv26ZMmuL6U,10295
@@ -29,9 +29,8 @@ prompture/serialization.py,sha256=m4cdAQJspitMcfwRgecElkY2SBt3BjEwubbhS3W-0s0,74
29
29
  prompture/server.py,sha256=W6Kn6Et8nG5twXjD2wKn_N9yplGjz5Z-2naeI_UPd1Y,6198
30
30
  prompture/session.py,sha256=FldK3cKq_jO0-beukVOhIiwsYWb6U_lLBlAERx95aaM,3821
31
31
  prompture/settings.py,sha256=2cTuko8PLhq0SbBMtqmjBgzl9jv6SgoXeaUEhmm4G4Y,2562
32
- prompture/simulated_tools.py,sha256=oL6W6hAEKXZHBfb8b-UDPfm3V4nSqXu7eG8IpvwtqKg,3901
33
32
  prompture/tools.py,sha256=PmFbGHTWYWahpJOG6BLlM0Y-EG6S37IFW57C-8GdsXo,36449
34
- prompture/tools_schema.py,sha256=wuVfPyCKVWlhUDRsXWArtGpxkQRqNWyKeLJuXn_6X8k,8986
33
+ prompture/tools_schema.py,sha256=c1ag6kyIGgZxWbZRsaHl72cAelb34J_JomyW1h5Atw0,7964
35
34
  prompture/validator.py,sha256=FY_VjIVEbjG2nwzh-r6l23Kt3UzaLyCis8_pZMNGHBA,993
36
35
  prompture/aio/__init__.py,sha256=bKqTu4Jxld16aP_7SP9wU5au45UBIb041ORo4E4HzVo,1810
37
36
  prompture/drivers/__init__.py,sha256=r8wBYGKD7C7v4CqcyRNoaITzGVyxasoiAU6jBYsPZio,8178
@@ -40,31 +39,31 @@ prompture/drivers/async_airllm_driver.py,sha256=1hIWLXfyyIg9tXaOE22tLJvFyNwHnOi1
40
39
  prompture/drivers/async_azure_driver.py,sha256=s__y_EGQkK7UZjxiyF08uql8F09cnbJ0q7aFuxzreIw,7328
41
40
  prompture/drivers/async_claude_driver.py,sha256=oawbFVVMtRlikQOmu3jRjbdpoeu95JqTF1YHLKO3ybE,10576
42
41
  prompture/drivers/async_google_driver.py,sha256=LTUgCXJjzuTDGzsCsmY2-xH2KdTLJD7htwO49ZNFOdE,13711
43
- prompture/drivers/async_grok_driver.py,sha256=lj160GHARe0fqTms4ovWhkpgt0idsGt55xnuc6JlH1w,7413
44
- prompture/drivers/async_groq_driver.py,sha256=5G0rXAEAmsLNftI9YfGAh4E8X3B4Hb6_0cXBhf9LZMk,6348
42
+ prompture/drivers/async_grok_driver.py,sha256=4oOGT4SzsheulU_QK0ZSqj4-THrFAOCeZwIqIslnW14,6858
43
+ prompture/drivers/async_groq_driver.py,sha256=iORpf0wcqPfS4zKCg4BTWpQCoHV2klkQVTQ1W-jhjUE,5755
45
44
  prompture/drivers/async_hugging_driver.py,sha256=IblxqU6TpNUiigZ0BCgNkAgzpUr2FtPHJOZnOZMnHF0,2152
46
- prompture/drivers/async_lmstudio_driver.py,sha256=4bz8NFFiZiFFkzlYDcS7abnwmEbbvbKb-CQhHeTGlU8,6102
45
+ prompture/drivers/async_lmstudio_driver.py,sha256=rPn2qVPm6UE2APzAn7ZHYTELUwr0dQMi8XHv6gAhyH8,5782
47
46
  prompture/drivers/async_local_http_driver.py,sha256=qoigIf-w3_c2dbVdM6m1e2RMAWP4Gk4VzVs5hM3lPvQ,1609
48
47
  prompture/drivers/async_modelscope_driver.py,sha256=wzHYGLf9qE9KXRFZYtN1hZS10Bw1m1Wy6HcmyUD67HM,10170
49
- prompture/drivers/async_moonshot_driver.py,sha256=a9gr3T_4NiDFd7foM1mSHJRvXYb43iqqJnQ0FVRyI2E,15669
48
+ prompture/drivers/async_moonshot_driver.py,sha256=Jl6rGlW3SsneFfmBiDo0RBZQN5c3-08kwax369me01E,14798
50
49
  prompture/drivers/async_ollama_driver.py,sha256=pFtCvh5bHe_qwGy-jIJbyG_zmnPbNbagJCGxCTJMdPU,8244
51
50
  prompture/drivers/async_openai_driver.py,sha256=COa_JE-AgKowKJpmRnfDJp4RSQKZel_7WswxOzvLksM,9044
52
- prompture/drivers/async_openrouter_driver.py,sha256=N7s72HuXHLs_RWmJO9P3pCayWE98ommfqVeAfru8Bl0,11758
51
+ prompture/drivers/async_openrouter_driver.py,sha256=GnOMY67CCV3HV83lCC-CxcngwrUnuc7G-AX7fb1DYpg,10698
53
52
  prompture/drivers/async_registry.py,sha256=JFEnXNPm-8AAUCiNLoKuYBSCYEK-4BmAen5t55QrMvg,5223
54
53
  prompture/drivers/async_zai_driver.py,sha256=zXHxske1CtK8dDTGY-D_kiyZZ_NfceNTJlyTpKn0R4c,10727
55
54
  prompture/drivers/azure_driver.py,sha256=gQFffA29gOr-GZ25fNXTokV8-mEmffeV9CT_UBZ3yXc,8565
56
55
  prompture/drivers/claude_driver.py,sha256=C8Av3DXP2x3f35jEv8BRwEM_4vh0cfmLsy3t5dsR6aM,11837
57
56
  prompture/drivers/google_driver.py,sha256=Zck5VUsW37kDgohXz3cUWRmZ88OfhmTpVD-qzAVMp-8,16318
58
- prompture/drivers/grok_driver.py,sha256=fxl5Gx9acFq7BlOh_N9U66oJvG3y8YX4QuSAgZWHJmU,8963
59
- prompture/drivers/groq_driver.py,sha256=7YEok1BQlsDZGkA-l9yrjTDapqIWX3yq_Ctgbhu8jSI,7490
57
+ prompture/drivers/grok_driver.py,sha256=mNfPgOsJR53_5Ep6aYnfKGy7lnZMqN8bxrqKep4CiF0,8408
58
+ prompture/drivers/groq_driver.py,sha256=olr1t7V71ET8Z-7VyRwb75_iYEiZg8-n5qs1edZ2erw,6897
60
59
  prompture/drivers/hugging_driver.py,sha256=gZir3XnM77VfYIdnu3S1pRftlZJM6G3L8bgGn5esg-Q,2346
61
- prompture/drivers/lmstudio_driver.py,sha256=nZ5SvBC0kTDNDzsupIW_H7YK92dcYta_xSPUNs52gyM,7154
60
+ prompture/drivers/lmstudio_driver.py,sha256=9ZnJ1l5LuWAjkH2WKfFjZprNMVIXoSC7qXDNDTxm-tA,6748
62
61
  prompture/drivers/local_http_driver.py,sha256=QJgEf9kAmy8YZ5fb8FHnWuhoDoZYNd8at4jegzNVJH0,1658
63
62
  prompture/drivers/modelscope_driver.py,sha256=yTxTG7j5f7zz4CjbrV8J0VKeoBmxv69F40bfp8nq6AE,10651
64
- prompture/drivers/moonshot_driver.py,sha256=cm1XpU6EPFjcZaneXjfetRNSUxN9daP6hkJ1y99kqLI,19123
63
+ prompture/drivers/moonshot_driver.py,sha256=MtlvtUUwE4WtzCKo_pJJ5wATB-h2GU4zY9jbGo3a_-g,18264
65
64
  prompture/drivers/ollama_driver.py,sha256=SJtMRtAr8geUB4y5GIZxPr-RJ0C3q7yqigYei2b4luM,13710
66
65
  prompture/drivers/openai_driver.py,sha256=DqdMhxF8M2HdOY5vfsFrz0h23lqBoQlbxV3xUdHvZho,10548
67
- prompture/drivers/openrouter_driver.py,sha256=m2I5E9L5YYE_bV8PruKnAwjL63SIFEXevN_ThUzxQaA,13657
66
+ prompture/drivers/openrouter_driver.py,sha256=DaG1H99s8GaOgJXZK4TP28HM7U4wiLu9wHXzWZleW_U,12589
68
67
  prompture/drivers/registry.py,sha256=Dg_5w9alnIPKhOnsR9Xspuf5T7roBGu0r_L2Cf-UhXs,9926
69
68
  prompture/drivers/vision_helpers.py,sha256=l5iYXHJLR_vLFvqDPPPK1QqK7YPKh5GwocpbSyt0R04,5403
70
69
  prompture/drivers/zai_driver.py,sha256=Wkur0HfwKJt8ugYErpvz1Gy6e9an8vt4R7U3i6HWV_s,11038
@@ -77,9 +76,9 @@ prompture/scaffold/templates/env.example.j2,sha256=eESKr1KWgyrczO6d-nwAhQwSpf_G-
77
76
  prompture/scaffold/templates/main.py.j2,sha256=TEgc5OvsZOEX0JthkSW1NI_yLwgoeVN_x97Ibg-vyWY,2632
78
77
  prompture/scaffold/templates/models.py.j2,sha256=JrZ99GCVK6TKWapskVRSwCssGrTu5cGZ_r46fOhY2GE,858
79
78
  prompture/scaffold/templates/requirements.txt.j2,sha256=m3S5fi1hq9KG9l_9j317rjwWww0a43WMKd8VnUWv2A4,102
80
- prompture-0.0.47.dist-info/licenses/LICENSE,sha256=0HgDepH7aaHNFhHF-iXuW6_GqDfYPnVkjtiCAZ4yS8I,1060
81
- prompture-0.0.47.dist-info/METADATA,sha256=MY7C3DjGuhpY6ZlPEmg-58aSmJ4RdZ4WRuYtXiWFinM,12148
82
- prompture-0.0.47.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
83
- prompture-0.0.47.dist-info/entry_points.txt,sha256=AFPG3lJR86g4IJMoWQUW5Ph7G6MLNWG3A2u2Tp9zkp8,48
84
- prompture-0.0.47.dist-info/top_level.txt,sha256=to86zq_kjfdoLeAxQNr420UWqT0WzkKoZ509J7Qr2t4,10
85
- prompture-0.0.47.dist-info/RECORD,,
79
+ prompture-0.0.47.dev1.dist-info/licenses/LICENSE,sha256=0HgDepH7aaHNFhHF-iXuW6_GqDfYPnVkjtiCAZ4yS8I,1060
80
+ prompture-0.0.47.dev1.dist-info/METADATA,sha256=gxnbPKPzC1F715GdpLjy6LchTZ3mlQTQHrjnoGUibDQ,10842
81
+ prompture-0.0.47.dev1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
82
+ prompture-0.0.47.dev1.dist-info/entry_points.txt,sha256=AFPG3lJR86g4IJMoWQUW5Ph7G6MLNWG3A2u2Tp9zkp8,48
83
+ prompture-0.0.47.dev1.dist-info/top_level.txt,sha256=to86zq_kjfdoLeAxQNr420UWqT0WzkKoZ509J7Qr2t4,10
84
+ prompture-0.0.47.dev1.dist-info/RECORD,,