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.
- prompture/_version.py +2 -2
- prompture/async_conversation.py +2 -87
- prompture/conversation.py +2 -87
- prompture/drivers/async_grok_driver.py +9 -23
- prompture/drivers/async_groq_driver.py +9 -23
- prompture/drivers/async_lmstudio_driver.py +2 -10
- prompture/drivers/async_moonshot_driver.py +12 -32
- prompture/drivers/async_openrouter_driver.py +17 -43
- prompture/drivers/grok_driver.py +9 -23
- prompture/drivers/groq_driver.py +9 -23
- prompture/drivers/lmstudio_driver.py +2 -11
- prompture/drivers/moonshot_driver.py +12 -32
- prompture/drivers/openrouter_driver.py +10 -34
- prompture/tools_schema.py +0 -22
- {prompture-0.0.47.dist-info → prompture-0.0.47.dev1.dist-info}/METADATA +2 -35
- {prompture-0.0.47.dist-info → prompture-0.0.47.dev1.dist-info}/RECORD +20 -21
- prompture/simulated_tools.py +0 -115
- {prompture-0.0.47.dist-info → prompture-0.0.47.dev1.dist-info}/WHEEL +0 -0
- {prompture-0.0.47.dist-info → prompture-0.0.47.dev1.dist-info}/entry_points.txt +0 -0
- {prompture-0.0.47.dist-info → prompture-0.0.47.dev1.dist-info}/licenses/LICENSE +0 -0
- {prompture-0.0.47.dist-info → prompture-0.0.47.dev1.dist-info}/top_level.txt +0 -0
prompture/simulated_tools.py
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
"""Prompt-based tool calling for drivers without native tool use support.
|
|
2
|
-
|
|
3
|
-
When a driver lacks ``supports_tool_use`` the conversation classes can
|
|
4
|
-
fall back to *simulated* tool calling: the available tools are described
|
|
5
|
-
in the system prompt, the model is asked to respond with a structured
|
|
6
|
-
JSON object (either a tool call or a final answer), and Prompture
|
|
7
|
-
parses + dispatches accordingly.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
from __future__ import annotations
|
|
11
|
-
|
|
12
|
-
import json
|
|
13
|
-
import logging
|
|
14
|
-
from typing import Any
|
|
15
|
-
|
|
16
|
-
from .tools import clean_json_text
|
|
17
|
-
from .tools_schema import ToolRegistry
|
|
18
|
-
|
|
19
|
-
logger = logging.getLogger("prompture.simulated_tools")
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def build_tool_prompt(tools: ToolRegistry) -> str:
|
|
23
|
-
"""Build a plain-text prompt section describing all registered tools.
|
|
24
|
-
|
|
25
|
-
The returned string should be appended to the system prompt so the
|
|
26
|
-
model knows which tools are available and how to call them.
|
|
27
|
-
"""
|
|
28
|
-
lines = [
|
|
29
|
-
"You have access to the following tools:",
|
|
30
|
-
"",
|
|
31
|
-
tools.to_prompt_format(),
|
|
32
|
-
"",
|
|
33
|
-
"To use a tool, respond with ONLY a JSON object in this exact format:",
|
|
34
|
-
'{"type": "tool_call", "name": "<tool_name>", "arguments": {<args>}}',
|
|
35
|
-
"",
|
|
36
|
-
"When you have the final answer (after using tools or if no tool is needed), "
|
|
37
|
-
"respond with ONLY a JSON object in this format:",
|
|
38
|
-
'{"type": "final_answer", "content": "<your answer>"}',
|
|
39
|
-
"",
|
|
40
|
-
"IMPORTANT: Your entire response must be a single JSON object. "
|
|
41
|
-
"Do not include any other text, markdown, or explanation outside the JSON.",
|
|
42
|
-
]
|
|
43
|
-
return "\n".join(lines)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def parse_simulated_response(text: str, tools: ToolRegistry) -> dict[str, Any]:
|
|
47
|
-
"""Parse the model's response into a tool call or final answer dict.
|
|
48
|
-
|
|
49
|
-
Returns one of:
|
|
50
|
-
- ``{"type": "tool_call", "name": str, "arguments": dict}``
|
|
51
|
-
- ``{"type": "final_answer", "content": str}``
|
|
52
|
-
"""
|
|
53
|
-
cleaned = clean_json_text(text).strip()
|
|
54
|
-
|
|
55
|
-
# Try JSON parse
|
|
56
|
-
try:
|
|
57
|
-
obj = json.loads(cleaned)
|
|
58
|
-
except (json.JSONDecodeError, ValueError):
|
|
59
|
-
# Non-JSON text → treat as final answer
|
|
60
|
-
logger.debug("Response is not valid JSON, treating as final answer")
|
|
61
|
-
return {"type": "final_answer", "content": text.strip()}
|
|
62
|
-
|
|
63
|
-
if not isinstance(obj, dict):
|
|
64
|
-
return {"type": "final_answer", "content": text.strip()}
|
|
65
|
-
|
|
66
|
-
# Explicit type discriminator
|
|
67
|
-
resp_type = obj.get("type")
|
|
68
|
-
|
|
69
|
-
if resp_type == "tool_call":
|
|
70
|
-
return {
|
|
71
|
-
"type": "tool_call",
|
|
72
|
-
"name": obj.get("name", ""),
|
|
73
|
-
"arguments": obj.get("arguments", {}),
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if resp_type == "final_answer":
|
|
77
|
-
return {
|
|
78
|
-
"type": "final_answer",
|
|
79
|
-
"content": obj.get("content", ""),
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
# Infer type from keys when "type" is missing
|
|
83
|
-
if "name" in obj and "arguments" in obj:
|
|
84
|
-
logger.debug("Inferred tool_call from keys (no 'type' field)")
|
|
85
|
-
return {
|
|
86
|
-
"type": "tool_call",
|
|
87
|
-
"name": obj["name"],
|
|
88
|
-
"arguments": obj.get("arguments", {}),
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if "content" in obj:
|
|
92
|
-
logger.debug("Inferred final_answer from keys (no 'type' field)")
|
|
93
|
-
return {
|
|
94
|
-
"type": "final_answer",
|
|
95
|
-
"content": obj["content"],
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
# Unrecognised JSON structure → final answer with the raw text
|
|
99
|
-
return {"type": "final_answer", "content": text.strip()}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
def format_tool_result(tool_name: str, result: Any) -> str:
|
|
103
|
-
"""Format a tool execution result as a user message for the next round."""
|
|
104
|
-
if isinstance(result, str):
|
|
105
|
-
result_str = result
|
|
106
|
-
else:
|
|
107
|
-
try:
|
|
108
|
-
result_str = json.dumps(result)
|
|
109
|
-
except (TypeError, ValueError):
|
|
110
|
-
result_str = str(result)
|
|
111
|
-
|
|
112
|
-
return (
|
|
113
|
-
f"Tool '{tool_name}' returned:\n{result_str}\n\n"
|
|
114
|
-
"Continue using the JSON format. Either call another tool or provide your final answer."
|
|
115
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|