fmtr.tools 1.0.52__py3-none-any.whl → 1.0.54__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.

Potentially problematic release.


This version of fmtr.tools might be problematic. Click here for more details.

@@ -1,14 +1,100 @@
1
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
2
7
 
8
+ from fmtr.tools import environment_tools as env
9
+ from fmtr.tools.config import ToolsConfig
3
10
 
4
- class Agent(pydantic_ai.Agent):
5
- """
11
+ pydantic_ai.Agent.instrument_all()
6
12
 
7
- Agent stub
13
+ class Task:
14
+ """
8
15
 
9
- TODO base class is marked `@final`, so is it safe to subclass?
16
+ Linear task definition, as Agent configuration and typing, plus state history.
10
17
 
11
18
  """
12
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
13
97
 
14
- Agent.instrument_all()
98
+ task = TaskTest()
99
+ result = asyncio.run(task.run('Hello! What is your name?'))
100
+ result
fmtr/tools/config.py CHANGED
@@ -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
  """
@@ -1,4 +1,7 @@
1
1
  import pandas as pd
2
2
 
3
- DataFrame = pd.DataFrame
3
+ Table = DataFrame = pd.DataFrame
4
4
  Series = pd.Series
5
+
6
+ CONCAT_HORIZONTALLY = 1
7
+ CONCAT_VERTICALLY = 0
fmtr/tools/version CHANGED
@@ -1 +1 @@
1
- 1.0.52
1
+ 1.0.54
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fmtr.tools
3
- Version: 1.0.52
3
+ Version: 1.0.54
4
4
  Summary: Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML
5
5
  Home-page: https://github.com/fmtr/fmtr.tools
6
6
  Author: Frontmatter
@@ -3,13 +3,13 @@ fmtr/tools/api_tools.py,sha256=u5YEdKyKto8MKY8legULLU7xeJ7lY2Bgyaep_xa8iZg,2089
3
3
  fmtr/tools/async_tools.py,sha256=ewz757WcveQJd-G5SVr2JDOQVbdLGecCgl-tsBGVZz4,284
4
4
  fmtr/tools/augmentation_tools.py,sha256=-6ESbO4CDlKqVOV1J1V6qBeoBMzbFIinkDHRHnCBej0,55
5
5
  fmtr/tools/caching_tools.py,sha256=UOCYUNvLQ-NofR_dhqBmZF96-HRPf4At5MmxVk3gAIk,2943
6
- fmtr/tools/config.py,sha256=C_UwYyUi0-pPl9yRhbzOy79EmDm4K1jI4iFHw5xSD5k,919
6
+ fmtr/tools/config.py,sha256=3jHO3KhRlzJUCdQmJ_j1DFzep00MSD5qTJHfK6i3FZA,1057
7
7
  fmtr/tools/config_tools.py,sha256=27PbPYj90ClIW4QcRoUoiFM3SbWeMIIZsZR32IPU4V8,805
8
8
  fmtr/tools/console_script_tools.py,sha256=Jcmm4WPhCQdPZfd468xD0epkt29sgcPROwKu79V_ehg,203
9
- fmtr/tools/data_modelling_tools.py,sha256=_WBcinjzg1JSMgYiloDMLo4f-lGjl4g1zPq9J4Vqkyg,1567
9
+ fmtr/tools/data_modelling_tools.py,sha256=0BFm-F_cYzVTxftWQwORkPd0FM2BTLVh9-s0-rTTFoo,1744
10
10
  fmtr/tools/dataclass_tools.py,sha256=0Gt6KeLhtPgubo_2tYkIVqB8oQ91Qzag8OAGZDdjvMU,1209
11
11
  fmtr/tools/datatype_tools.py,sha256=3P4AWIFGkJ-UqvXlj0Jc9IvkIIgTOE9jRrOk3NVbpH8,1508
12
- fmtr/tools/debugging_tools.py,sha256=bqzluVhxl0uDz5Uim9NMLe5EoGDw7abgBlEAE3osFMs,1070
12
+ fmtr/tools/debugging_tools.py,sha256=SUub3Ycp9k5TVx7CI_bah6fgdPr03VrpAvaCUc8eICs,959
13
13
  fmtr/tools/docker_tools.py,sha256=rdaZje2xhlmnfQqZnR7IHgRdWncTLjrJcViUTt5oEwk,617
14
14
  fmtr/tools/environment_tools.py,sha256=34NKG-BJrobYyJeM3FH3VE6G1rv6kQ41bvTxkEYfNi8,1850
15
15
  fmtr/tools/function_tools.py,sha256=_oW3-HZXMst2pcU-I-U7KTMmzo0g9MIQKmX-c2_NEoE,858
@@ -38,16 +38,16 @@ fmtr/tools/profiling_tools.py,sha256=jpXVjaNKPydTasEQVNXvxzGtMhXPit08AnJddkU8uIc
38
38
  fmtr/tools/random_tools.py,sha256=4VlQdk5THbR8ka4pZaLbk_ZO_4yy6PF_lHZes_rgenY,2223
39
39
  fmtr/tools/semantic_tools.py,sha256=cxY9NSAHWj4nEc6Oj4qA1omR3dWbl2OuH7_PkINc6_E,1386
40
40
  fmtr/tools/spaces_tools.py,sha256=D_he3mve6DruB3OPS6QyzqD05ChHnRTb4buViKPe7To,1099
41
- fmtr/tools/string_tools.py,sha256=9zsqShVf1VUfD7hsJBYcuk43L3qCKm1eVwGBn1-wK9Q,3458
42
- fmtr/tools/tabular_tools.py,sha256=L0yNsU_c8dGTmsUlMFERfTt2a3aZv_pKr2YQc7C9OvA,65
41
+ fmtr/tools/string_tools.py,sha256=Q2vv7kuGVMaQlNSUxJYhex6WUQHDus40ht0PGImPjNQ,3879
42
+ fmtr/tools/tabular_tools.py,sha256=tpIpZzYku1HcJrHZJL6BC39LmN3WUWVhFbK2N7nDVmE,120
43
43
  fmtr/tools/tokenization_tools.py,sha256=9FP5vgPufWv0XA961eVKObFll0d_2mM0W3ut3rtZyeo,4329
44
44
  fmtr/tools/tools.py,sha256=xnfUrOnrT4OxFYez6vV5tAhydzCICJFiGVnviiZDEQo,796
45
45
  fmtr/tools/unicode_tools.py,sha256=yS_9wpu8ogNoiIL7s1G_8bETFFO_YQlo4LNPv1NLDeY,52
46
- fmtr/tools/version,sha256=i4u89BEwbqIVnTb0hUzHQcR-YHQap8bHT6kp89Df7fM,6
46
+ fmtr/tools/version,sha256=sOToo55hxhnwyn90ru8LQoJIOtiDp6Wvn8_KEB9wC0w,6
47
47
  fmtr/tools/version_tools.py,sha256=axzzHBS9V1n6YuSacsDKG3VfAvRqR8qr6aENCibR8vs,1248
48
48
  fmtr/tools/yaml_tools.py,sha256=Ol43ZwbnSXGnn1K98Uxx61KPGSqfC4axE-X2q1LKMwk,349
49
49
  fmtr/tools/ai_tools/__init__.py,sha256=JZrLuOFNV1A3wvJgonxOgz_4WS-7MfCuowGWA5uYCjs,372
50
- fmtr/tools/ai_tools/agentic_tools.py,sha256=nAMVwk-3UR9B3n0Sgdp1HQVzsEC-5N7m7-sYFOwMLi0,179
50
+ fmtr/tools/ai_tools/agentic_tools.py,sha256=Y4MhkGqQ9wL1gFXAsaaO8BIYS1mncVcUPsH-iZ0-UY8,2760
51
51
  fmtr/tools/ai_tools/inference_tools.py,sha256=yF8Oxph0L8W2CnK_o-MVztBhWVwBpgOEkx9_m3uqQww,11840
52
52
  fmtr/tools/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
53
  fmtr/tools/tests/conftest.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -57,9 +57,9 @@ fmtr/tools/tests/test_environment.py,sha256=iHaiMQfECYZPkPKwfuIZV9uHuWe3aE-p_dN_
57
57
  fmtr/tools/tests/test_json.py,sha256=IeSP4ziPvRcmS8kq7k9tHonC9rN5YYq9GSNT2ul6Msk,287
58
58
  fmtr/tools/tests/test_path.py,sha256=AkZQa6_8BQ-VaCyL_J-iKmdf2ZaM-xFYR37Kun3k4_g,2188
59
59
  fmtr/tools/tests/test_yaml.py,sha256=jc0TwwKu9eC0LvFGNMERdgBue591xwLxYXFbtsRwXVM,287
60
- fmtr.tools-1.0.52.dist-info/LICENSE,sha256=FW9aa6vVN5IjRQWLT43hs4_koYSmpcbIovlKeAJ0_cI,10757
61
- fmtr.tools-1.0.52.dist-info/METADATA,sha256=Ly7sdNl6-LSCnxaoQtCbxzQEqrcIbKNCh00WCatIWt4,13978
62
- fmtr.tools-1.0.52.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
63
- fmtr.tools-1.0.52.dist-info/entry_points.txt,sha256=Zmeyls-zo5S99SlKUmsy9ULUNmk-4B9WQCEjuPIH0Yw,142
64
- fmtr.tools-1.0.52.dist-info/top_level.txt,sha256=t5341a8ii3n4RFizwTeXGmcq_pf4GqL1h9ylE5LIWRk,12
65
- fmtr.tools-1.0.52.dist-info/RECORD,,
60
+ fmtr.tools-1.0.54.dist-info/LICENSE,sha256=FW9aa6vVN5IjRQWLT43hs4_koYSmpcbIovlKeAJ0_cI,10757
61
+ fmtr.tools-1.0.54.dist-info/METADATA,sha256=ZDGuHZCut80jtW-g5xM65BhSvakwjiW8NEkhjWmGZsg,13978
62
+ fmtr.tools-1.0.54.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
63
+ fmtr.tools-1.0.54.dist-info/entry_points.txt,sha256=Zmeyls-zo5S99SlKUmsy9ULUNmk-4B9WQCEjuPIH0Yw,142
64
+ fmtr.tools-1.0.54.dist-info/top_level.txt,sha256=t5341a8ii3n4RFizwTeXGmcq_pf4GqL1h9ylE5LIWRk,12
65
+ fmtr.tools-1.0.54.dist-info/RECORD,,