fmtr.tools 1.0.52__tar.gz → 1.0.54__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.
Potentially problematic release.
This version of fmtr.tools might be problematic. Click here for more details.
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/PKG-INFO +1 -1
- fmtr.tools-1.0.54/fmtr/tools/ai_tools/agentic_tools.py +100 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/config.py +5 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/data_modelling_tools.py +9 -1
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/debugging_tools.py +0 -9
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/string_tools.py +17 -1
- fmtr.tools-1.0.54/fmtr/tools/tabular_tools.py +7 -0
- fmtr.tools-1.0.54/fmtr/tools/version +1 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr.tools.egg-info/PKG-INFO +1 -1
- fmtr.tools-1.0.52/fmtr/tools/ai_tools/agentic_tools.py +0 -14
- fmtr.tools-1.0.52/fmtr/tools/tabular_tools.py +0 -4
- fmtr.tools-1.0.52/fmtr/tools/version +0 -1
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/LICENSE +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/README.md +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/__init__.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/ai_tools/__init__.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/ai_tools/inference_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/api_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/async_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/augmentation_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/caching_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/config_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/console_script_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/dataclass_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/datatype_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/docker_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/environment_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/function_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/google_api_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/hash_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/hfh_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/html_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/import_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/inspection_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/interface_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/iterator_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/json_fix_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/json_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/logging_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/merging_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/metric_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/name_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/netrc_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/openai_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/parallel_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/path_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/pdf_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/platform_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/process_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/profiling_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/random_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/semantic_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/spaces_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/tests/__init__.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/tests/conftest.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/tests/helpers.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/tests/test_datatype.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/tests/test_environment.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/tests/test_json.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/tests/test_path.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/tests/test_yaml.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/tokenization_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/unicode_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/version_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr/tools/yaml_tools.py +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr.tools.egg-info/SOURCES.txt +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr.tools.egg-info/dependency_links.txt +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr.tools.egg-info/entry_points.txt +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr.tools.egg-info/requires.txt +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/fmtr.tools.egg-info/top_level.txt +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/setup.cfg +0 -0
- {fmtr.tools-1.0.52 → fmtr.tools-1.0.54}/setup.py +0 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import pydantic_ai
|
|
2
|
+
from pydantic_ai import RunContext
|
|
3
|
+
from pydantic_ai.agent import AgentRunResult, Agent
|
|
4
|
+
from pydantic_ai.messages import ModelRequest, RetryPromptPart
|
|
5
|
+
from pydantic_ai.models.openai import OpenAIModel
|
|
6
|
+
from pydantic_ai.providers.openai import OpenAIProvider
|
|
7
|
+
|
|
8
|
+
from fmtr.tools import environment_tools as env
|
|
9
|
+
from fmtr.tools.config import ToolsConfig
|
|
10
|
+
|
|
11
|
+
pydantic_ai.Agent.instrument_all()
|
|
12
|
+
|
|
13
|
+
class Task:
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
Linear task definition, as Agent configuration and typing, plus state history.
|
|
17
|
+
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
PROVIDER = OpenAIProvider(api_key=env.get(ToolsConfig.FMTR_OPENAI_API_KEY_KEY))
|
|
21
|
+
|
|
22
|
+
API_HOST_FMTR = env.get(ToolsConfig.FMTR_AI_HOST_KEY, ToolsConfig.FMTR_AI_HOST_DEFAULT)
|
|
23
|
+
API_URL_FMTR = f'https://{API_HOST_FMTR}/v1'
|
|
24
|
+
PROVIDER_FMTR = OpenAIProvider(base_url=API_URL_FMTR)
|
|
25
|
+
|
|
26
|
+
MODEL_ID = 'gpt-4o'
|
|
27
|
+
SYSTEM_PROMPT = None
|
|
28
|
+
DEPS_TYPE = str
|
|
29
|
+
RESULT_TYPE = str
|
|
30
|
+
RESULT_RETRIES = 5
|
|
31
|
+
|
|
32
|
+
def __init__(self, *args, **kwargs):
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
Configure Agent
|
|
36
|
+
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
self.model = OpenAIModel(self.MODEL_ID, provider=self.PROVIDER)
|
|
40
|
+
self.agent = Agent(
|
|
41
|
+
*args,
|
|
42
|
+
model=self.model,
|
|
43
|
+
system_prompt=self.SYSTEM_PROMPT or [],
|
|
44
|
+
deps_type=self.DEPS_TYPE,
|
|
45
|
+
result_type=self.RESULT_TYPE,
|
|
46
|
+
result_retries=self.RESULT_RETRIES,
|
|
47
|
+
**kwargs
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
self.agent.output_validator(self.validate)
|
|
51
|
+
self.history = []
|
|
52
|
+
|
|
53
|
+
async def run(self, *args, **kwargs) -> AgentRunResult[RESULT_TYPE]:
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
Run Agent storing history
|
|
57
|
+
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
result = await self.agent.run(*args, message_history=self.history, **kwargs)
|
|
61
|
+
self.history = result.all_messages()
|
|
62
|
+
return result
|
|
63
|
+
|
|
64
|
+
async def revert(self, msg, deps):
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
Post-hoc, user-initiated tool retry.
|
|
68
|
+
|
|
69
|
+
"""
|
|
70
|
+
msg_final = self.history.pop(-1)
|
|
71
|
+
tool_return_part = msg_final.parts[0]
|
|
72
|
+
|
|
73
|
+
retry_prompt = RetryPromptPart(content=msg, tool_name=tool_return_part.tool_name, tool_call_id=tool_return_part.tool_call_id, timestamp=tool_return_part.timestamp, part_kind='retry-prompt')
|
|
74
|
+
retry_request = ModelRequest(parts=[retry_prompt], instructions=msg_final.instructions, kind='request')
|
|
75
|
+
|
|
76
|
+
self.history.append(retry_request)
|
|
77
|
+
|
|
78
|
+
result = await Task.run(self, deps=deps)
|
|
79
|
+
return result
|
|
80
|
+
|
|
81
|
+
async def validate(self, ctx: RunContext[DEPS_TYPE], output: RESULT_TYPE) -> RESULT_TYPE:
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
Dummy validator
|
|
85
|
+
|
|
86
|
+
"""
|
|
87
|
+
return output
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class TaskTest(Task):
|
|
91
|
+
PROVIDER = Task.PROVIDER_FMTR
|
|
92
|
+
MODEL_ID = 'mixtral:8x7b'
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
if __name__ == '__main__':
|
|
96
|
+
import asyncio
|
|
97
|
+
|
|
98
|
+
task = TaskTest()
|
|
99
|
+
result = asyncio.run(task.run('Hello! What is your name?'))
|
|
100
|
+
result
|
|
@@ -24,3 +24,8 @@ class ToolsConfig(ConfigClass):
|
|
|
24
24
|
FMTR_REMOTE_DEBUG_HOST_DEFAULT = 'ws.lan'
|
|
25
25
|
FMTR_REMOTE_DEBUG_PORT_DEFAULT = 5679
|
|
26
26
|
FMTR_REMOTE_DEBUG_ENABLED_KEY = 'FMTR_REMOTE_DEBUG_ENABLED'
|
|
27
|
+
|
|
28
|
+
FMTR_OPENAI_API_KEY_KEY = 'FMTR_OPENAI_API_KEY'
|
|
29
|
+
|
|
30
|
+
FMTR_AI_HOST_KEY = 'FMTR_URL_HOST'
|
|
31
|
+
FMTR_AI_HOST_DEFAULT = 'ai.gex.fmtr.dev'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from pydantic import BaseModel, RootModel
|
|
1
|
+
from pydantic import BaseModel, RootModel, ConfigDict
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
def to_df(*objs, name_value='value'):
|
|
@@ -23,6 +23,14 @@ def to_df(*objs, name_value='value'):
|
|
|
23
23
|
return df
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
class MixinArbitraryTypes:
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
Convenience for when non-serializable types are needed
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
33
|
+
|
|
26
34
|
class MixinFromJson:
|
|
27
35
|
|
|
28
36
|
@classmethod
|
|
@@ -29,12 +29,3 @@ def trace(is_debug=None, host=None, port=None, stdoutToServer=True, stderrToServ
|
|
|
29
29
|
logger.info(msg)
|
|
30
30
|
|
|
31
31
|
pydevd_pycharm.settrace(host, port=port, stdoutToServer=stdoutToServer, stderrToServer=stderrToServer, **kwargs)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def test(**kwargs):
|
|
35
|
-
"""
|
|
36
|
-
|
|
37
|
-
Test debugger connection
|
|
38
|
-
|
|
39
|
-
"""
|
|
40
|
-
return trace(is_debug=True, **kwargs)
|
|
@@ -129,7 +129,8 @@ class Mask:
|
|
|
129
129
|
"""
|
|
130
130
|
|
|
131
131
|
def __init__(self, mask: str):
|
|
132
|
-
self.mask = mask
|
|
132
|
+
self.mask = trim(mask)
|
|
133
|
+
self.mask_data = parse_string(self.mask)
|
|
133
134
|
self.kwargs = {}
|
|
134
135
|
self.args = []
|
|
135
136
|
|
|
@@ -147,6 +148,21 @@ class Mask:
|
|
|
147
148
|
except (KeyError, IndexError):
|
|
148
149
|
return self
|
|
149
150
|
|
|
151
|
+
def __str__(self):
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
Force string output, leaving any unfilled slots as-is.
|
|
155
|
+
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
fills = {}
|
|
159
|
+
|
|
160
|
+
for seg in self.mask_data:
|
|
161
|
+
if seg.field_name:
|
|
162
|
+
fill = self.kwargs.get(seg.field_name, f'{{{seg.field_name}}}')
|
|
163
|
+
fills[seg.field_name] = fill
|
|
164
|
+
|
|
165
|
+
return self.mask.format(**fills)
|
|
150
166
|
|
|
151
167
|
def trim(text: str) -> str:
|
|
152
168
|
"""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.0.54
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1.0.52
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|