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 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