agentics-py 0.0.1__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.
- agentics/__init__.py +1 -0
- agentics/abstractions/__init__.py +0 -0
- agentics/abstractions/pydantic_transducer.py +221 -0
- agentics/abstractions/structured_output.py +13 -0
- agentics/core/__init__.py +1 -0
- agentics/core/agentics.py +954 -0
- agentics/core/example.py +0 -0
- agentics/core/globals.py +73 -0
- agentics/core/llm_connections.py +34 -0
- agentics/core/utils.py +437 -0
- agentics/tools/tools.py +72 -0
- agentics_py-0.0.1.dist-info/LICENSE +201 -0
- agentics_py-0.0.1.dist-info/METADATA +156 -0
- agentics_py-0.0.1.dist-info/RECORD +15 -0
- agentics_py-0.0.1.dist-info/WHEEL +4 -0
agentics/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .core import *
|
|
File without changes
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
from collections.abc import Iterable
|
|
5
|
+
from typing import Any, Optional, Type, Union
|
|
6
|
+
|
|
7
|
+
from crewai import Agent, Crew, Process, Task
|
|
8
|
+
from dotenv import load_dotenv
|
|
9
|
+
from loguru import logger
|
|
10
|
+
from openai import AsyncOpenAI
|
|
11
|
+
from pydantic import BaseModel
|
|
12
|
+
|
|
13
|
+
from agentics.core.llm_connections import watsonx_crewai_llm
|
|
14
|
+
from agentics.core.utils import openai_response
|
|
15
|
+
|
|
16
|
+
load_dotenv()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class PydanticTransducerVLLM:
|
|
20
|
+
model_config = {"arbitrary_types_allowed": True}
|
|
21
|
+
llm: AsyncOpenAI
|
|
22
|
+
intensional_definiton: str
|
|
23
|
+
verbose: bool = False
|
|
24
|
+
MAX_CHAR_PROMPT: int = 15000
|
|
25
|
+
|
|
26
|
+
def __init__(
|
|
27
|
+
self,
|
|
28
|
+
atype: Type[BaseModel],
|
|
29
|
+
verbose: bool = False,
|
|
30
|
+
llm=None,
|
|
31
|
+
tools=None,
|
|
32
|
+
intensional_definiton=None,
|
|
33
|
+
**kwargs,
|
|
34
|
+
):
|
|
35
|
+
self.atype = atype
|
|
36
|
+
self.verbose = verbose
|
|
37
|
+
self.llm = llm
|
|
38
|
+
self.tools = tools
|
|
39
|
+
self.intensional_definiton = (
|
|
40
|
+
intensional_definiton
|
|
41
|
+
if intensional_definiton
|
|
42
|
+
else """Generate an object of the specified Pydantic Type from the following input."""
|
|
43
|
+
)
|
|
44
|
+
self.llm_params = {
|
|
45
|
+
"extra_body": {"guided_json": self.atype.model_json_schema()},
|
|
46
|
+
"logprobs": False,
|
|
47
|
+
"n": 1,
|
|
48
|
+
}
|
|
49
|
+
self.llm_params.update(kwargs)
|
|
50
|
+
|
|
51
|
+
async def async_transduce(
|
|
52
|
+
self,
|
|
53
|
+
input: Union[str, list[Any]],
|
|
54
|
+
logprobs: bool = False,
|
|
55
|
+
n_samples: int = 1,
|
|
56
|
+
**kwargs,
|
|
57
|
+
) -> list[list[BaseModel]]:
|
|
58
|
+
|
|
59
|
+
default_user_prompt = "\n".join(
|
|
60
|
+
[
|
|
61
|
+
self.intensional_definiton,
|
|
62
|
+
"Generate an object of the specified Pydantic Type from the following input.\n",
|
|
63
|
+
]
|
|
64
|
+
)
|
|
65
|
+
self.llm_params.update(kwargs)
|
|
66
|
+
if isinstance(input, str):
|
|
67
|
+
result = await openai_response(
|
|
68
|
+
model=os.getenv("VLLM_MODEL_ID"),
|
|
69
|
+
base_url=os.getenv("VLLM_URL"),
|
|
70
|
+
user_prompt=default_user_prompt + str(state),
|
|
71
|
+
**self.llm_params,
|
|
72
|
+
)
|
|
73
|
+
decoded_result = self.atype.model_validate_json(result)
|
|
74
|
+
return decoded_result
|
|
75
|
+
|
|
76
|
+
elif isinstance(input, Iterable) and all(isinstance(i, str) for i in input):
|
|
77
|
+
processes = []
|
|
78
|
+
for state in input:
|
|
79
|
+
corutine = openai_response(
|
|
80
|
+
model=os.getenv("VLLM_MODEL_ID"),
|
|
81
|
+
base_url=os.getenv("VLLM_URL"),
|
|
82
|
+
user_prompt=default_user_prompt + str(state),
|
|
83
|
+
**self.llm_params,
|
|
84
|
+
)
|
|
85
|
+
processes.append(corutine)
|
|
86
|
+
results = await asyncio.wait_for(
|
|
87
|
+
asyncio.gather(*processes, return_exceptions=True), timeout=10000
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
decoded_results = []
|
|
91
|
+
for result in results:
|
|
92
|
+
if issubclass(type(result), Exception):
|
|
93
|
+
if self.verbose:
|
|
94
|
+
logger.debug("Something went wrongs, generating empty states")
|
|
95
|
+
decoded_results.append(self.atype())
|
|
96
|
+
else:
|
|
97
|
+
decoded_results.append(self.atype.model_validate_json(result))
|
|
98
|
+
return decoded_results
|
|
99
|
+
else:
|
|
100
|
+
return NotImplemented
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class PydanticTransducerCrewAI:
|
|
104
|
+
crew: Crew
|
|
105
|
+
llm: Any
|
|
106
|
+
intensional_definiton: str
|
|
107
|
+
verbose: bool = False
|
|
108
|
+
MAX_CHAR_PROMPT: int = 15000
|
|
109
|
+
|
|
110
|
+
def __init__(
|
|
111
|
+
self,
|
|
112
|
+
atype: Type[BaseModel],
|
|
113
|
+
verbose: bool = False,
|
|
114
|
+
llm=None,
|
|
115
|
+
tools=None,
|
|
116
|
+
intensional_definiton=None,
|
|
117
|
+
**kwargs,
|
|
118
|
+
):
|
|
119
|
+
self.atype = atype
|
|
120
|
+
self.llm = llm if llm else watsonx_crewai_llm
|
|
121
|
+
self.intensional_definiton = (
|
|
122
|
+
intensional_definiton
|
|
123
|
+
if intensional_definiton
|
|
124
|
+
else """Generate an object of the specified Pydantic Type from the following input."""
|
|
125
|
+
)
|
|
126
|
+
self.prompt_params = {
|
|
127
|
+
"role": "Task Executor",
|
|
128
|
+
"goal": "You execute tasks",
|
|
129
|
+
"backstory": "You are always faithful and provide only fact based answers.",
|
|
130
|
+
"expected_output": "Described by Pydantic Type",
|
|
131
|
+
}
|
|
132
|
+
self.prompt_params.update(kwargs)
|
|
133
|
+
agent = Agent(
|
|
134
|
+
role=self.prompt_params["role"],
|
|
135
|
+
goal=self.prompt_params["goal"],
|
|
136
|
+
backstory=self.prompt_params["backstory"],
|
|
137
|
+
verbose=verbose,
|
|
138
|
+
max_iter=3,
|
|
139
|
+
llm=self.llm,
|
|
140
|
+
tools=tools if tools else [],
|
|
141
|
+
)
|
|
142
|
+
task = Task(
|
|
143
|
+
description=self.intensional_definiton + " {task_description}",
|
|
144
|
+
expected_output=self.prompt_params["expected_output"],
|
|
145
|
+
output_file="",
|
|
146
|
+
agent=agent,
|
|
147
|
+
output_pydantic=self.atype,
|
|
148
|
+
tools=tools,
|
|
149
|
+
)
|
|
150
|
+
self.crew = Crew(
|
|
151
|
+
agents=[agent],
|
|
152
|
+
tasks=[task],
|
|
153
|
+
process=Process.sequential,
|
|
154
|
+
verbose=verbose,
|
|
155
|
+
manager_llm=self.llm,
|
|
156
|
+
function_calling_llm=self.llm,
|
|
157
|
+
chat_llm=self.llm,
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
async def __kickoff_with_index(self, state, i):
|
|
161
|
+
return (await self.crew.kickoff_async(state), i, state)
|
|
162
|
+
|
|
163
|
+
async def async_transduce(self, input):
|
|
164
|
+
if isinstance(input, str):
|
|
165
|
+
answer = self.crew.kickoff_async({"task_description": input})
|
|
166
|
+
ans = await answer
|
|
167
|
+
return ans.pydantic
|
|
168
|
+
elif isinstance(input, Iterable) and all(isinstance(i, str) for i in input):
|
|
169
|
+
input_states = [
|
|
170
|
+
{"task_description": x[: self.MAX_CHAR_PROMPT]} for x in input
|
|
171
|
+
]
|
|
172
|
+
answer_list = await self.crew.kickoff_for_each_async(input_states)
|
|
173
|
+
|
|
174
|
+
return [x.pydantic for x in answer_list]
|
|
175
|
+
else:
|
|
176
|
+
return NotImplemented
|
|
177
|
+
|
|
178
|
+
def transduce(self, input):
|
|
179
|
+
answer = self.crew.kickoff({"task_description": input})
|
|
180
|
+
return answer.pydantic
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
import asyncio
|
|
184
|
+
|
|
185
|
+
if __name__ == "__main__":
|
|
186
|
+
|
|
187
|
+
class PersonalInformation(BaseModel):
|
|
188
|
+
first_name: Optional[str] = None
|
|
189
|
+
last_name: Optional[str] = None
|
|
190
|
+
year_of_birth: Optional[int] = None
|
|
191
|
+
nationality: Optional[str] = None
|
|
192
|
+
|
|
193
|
+
pt = PydanticTransducerCrewAI(PersonalInformation, llm=None)
|
|
194
|
+
print(
|
|
195
|
+
asyncio.run(
|
|
196
|
+
pt.async_transduce(
|
|
197
|
+
[
|
|
198
|
+
"""Hi , I am John. My father is Dave Smith.
|
|
199
|
+
I was born in April 1977, in British Columbia """,
|
|
200
|
+
"""Hi , I am John. My father is Dave Smith.
|
|
201
|
+
I was born in April 1977, in British Columbia """,
|
|
202
|
+
]
|
|
203
|
+
* 5
|
|
204
|
+
)
|
|
205
|
+
)
|
|
206
|
+
)
|
|
207
|
+
# from agentics.core.llm_connections import vllm_llm
|
|
208
|
+
# pt = PydanticTransducerVLLM(atype=PersonalInformation, llm=vllm_llm)
|
|
209
|
+
# print(
|
|
210
|
+
# asyncio.run(
|
|
211
|
+
# pt.async_transduce(
|
|
212
|
+
# [
|
|
213
|
+
# """Hi , I am John. My father is Dave Smith.
|
|
214
|
+
# I was born in April 1977, in British Columbia """,
|
|
215
|
+
# """Hi , I am John. My father is Dave Smith.
|
|
216
|
+
# I was born in April 1977, in British Columbia """,
|
|
217
|
+
# ]
|
|
218
|
+
# * 10
|
|
219
|
+
# )
|
|
220
|
+
# )
|
|
221
|
+
# )
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from typing import Type
|
|
2
|
+
|
|
3
|
+
from crewai import LLM
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
|
|
6
|
+
from agentics.core.llm_connections import watsonx_crewai_llm
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
async def generate_structured_output(
|
|
10
|
+
prompt: str, output_type: Type[BaseModel], llm: LLM = watsonx_crewai_llm
|
|
11
|
+
):
|
|
12
|
+
structured_llm = llm.with_structured_output(output_type)
|
|
13
|
+
return await structured_llm.ainvoke(prompt)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .agentics import Agentics
|