euriai 1.0.2__py3-none-any.whl → 1.0.4__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.
euriai/crewai.py CHANGED
@@ -17,7 +17,8 @@ except ImportError:
17
17
  class Task:
18
18
  pass
19
19
  class Process:
20
- pass
20
+ sequential = "sequential"
21
+ parallel = "parallel"
21
22
  class LLM:
22
23
  pass
23
24
 
euriai/euri_embed.py CHANGED
@@ -34,13 +34,29 @@ class EuriaiLlamaIndexEmbedding(BaseEmbedding):
34
34
  response.raise_for_status()
35
35
  return [np.array(obj["embedding"]).tolist() for obj in response.json()["data"]]
36
36
 
37
+ # Abstract methods required by BaseEmbedding (with underscore prefixes)
38
+ def _get_text_embedding(self, text: str) -> List[float]:
39
+ """Get embedding for a single text. Required abstract method."""
40
+ return self._post_embedding([text])[0]
41
+
42
+ def _get_query_embedding(self, query: str) -> List[float]:
43
+ """Get embedding for a query string. Required abstract method."""
44
+ return self._get_text_embedding(query)
45
+
46
+ async def _aget_query_embedding(self, query: str) -> List[float]:
47
+ """Async version of get_query_embedding. Required abstract method."""
48
+ # For now, we don't support async, so we'll use the sync version
49
+ # In a real implementation, you'd want to use aiohttp or similar
50
+ return self._get_query_embedding(query)
51
+
52
+ # Public methods for backward compatibility
37
53
  def get_text_embedding(self, text: str) -> List[float]:
38
54
  """Get embedding for a single text."""
39
- return self._post_embedding([text])[0]
55
+ return self._get_text_embedding(text)
40
56
 
41
57
  def get_query_embedding(self, query: str) -> List[float]:
42
58
  """Get embedding for a query string."""
43
- return self.get_text_embedding(query)
59
+ return self._get_query_embedding(query)
44
60
 
45
61
  def get_text_embeddings(self, texts: List[str]) -> List[List[float]]:
46
62
  """Get embeddings for multiple texts."""
@@ -48,5 +64,4 @@ class EuriaiLlamaIndexEmbedding(BaseEmbedding):
48
64
 
49
65
  async def aget_query_embedding(self, query: str) -> List[float]:
50
66
  """Async version of get_query_embedding."""
51
- # We don't support async, so raise NotImplementedError
52
- raise NotImplementedError("Async embeddings not supported")
67
+ return await self._aget_query_embedding(query)
euriai/langchain.py CHANGED
@@ -482,11 +482,9 @@ class EuriaiChatModel(BaseChatModel):
482
482
  self,
483
483
  schema: Union[Dict, Type[BaseModel]],
484
484
  **kwargs: Any
485
- ) -> "EuriaiChatModel":
485
+ ) -> "EuriaiStructuredChatModel":
486
486
  """Create a version that returns structured output."""
487
- # This would need to be implemented with proper schema validation
488
- # For now, return self with structured output enabled
489
- return self.__class__(
487
+ return EuriaiStructuredChatModel(
490
488
  api_key=self.api_key,
491
489
  model=self.model,
492
490
  temperature=self.temperature,
@@ -497,11 +495,136 @@ class EuriaiChatModel(BaseChatModel):
497
495
  streaming=self.streaming,
498
496
  supports_function_calling=self.supports_function_calling,
499
497
  supports_structured_output=True,
500
- _structured_output_schema=schema,
498
+ schema=schema,
501
499
  **kwargs
502
500
  )
503
501
 
504
502
 
503
+ class EuriaiStructuredChatModel(EuriaiChatModel):
504
+ """
505
+ EuriaiChatModel with structured output support.
506
+
507
+ This class extends EuriaiChatModel to parse responses into structured Pydantic models.
508
+ """
509
+
510
+ def __init__(self, schema: Union[Dict, Type[BaseModel]], **kwargs):
511
+ # Initialize the parent class first
512
+ super().__init__(**kwargs)
513
+
514
+ # Store schema in private attributes to avoid Pydantic conflicts
515
+ self._output_schema = schema
516
+ self._schema_name = getattr(schema, '__name__', 'OutputSchema')
517
+
518
+ @property
519
+ def schema(self):
520
+ """Get the output schema."""
521
+ return self._output_schema
522
+
523
+ @property
524
+ def schema_name(self):
525
+ """Get the schema name."""
526
+ return self._schema_name
527
+
528
+ def _get_json_schema(self) -> Dict[str, Any]:
529
+ """Generate JSON schema from the Pydantic model."""
530
+ if hasattr(self.schema, 'model_json_schema'):
531
+ # Pydantic v2
532
+ return self.schema.model_json_schema()
533
+ elif hasattr(self.schema, 'schema'):
534
+ # Pydantic v1
535
+ return self.schema.schema()
536
+ else:
537
+ # Dictionary schema
538
+ return self.schema
539
+
540
+ def _create_structured_prompt(self, original_prompt: str) -> str:
541
+ """Create a prompt that requests structured JSON output."""
542
+ json_schema = self._get_json_schema()
543
+
544
+ structured_prompt = f"""{original_prompt}
545
+
546
+ Please respond with a valid JSON object that matches this exact schema:
547
+ ```json
548
+ {json.dumps(json_schema, indent=2)}
549
+ ```
550
+
551
+ Your response must be valid JSON that can be parsed. Do not include any other text outside the JSON object."""
552
+
553
+ return structured_prompt
554
+
555
+ def _parse_structured_response(self, response_content: str) -> Any:
556
+ """Parse the response content into the structured format."""
557
+ try:
558
+ # Try to find JSON in the response
559
+ response_content = response_content.strip()
560
+
561
+ # Handle cases where the response might have extra text
562
+ if '```json' in response_content:
563
+ # Extract JSON from code block
564
+ start = response_content.find('```json') + 7
565
+ end = response_content.find('```', start)
566
+ if end == -1:
567
+ end = len(response_content)
568
+ json_str = response_content[start:end].strip()
569
+ elif response_content.startswith('{') and response_content.endswith('}'):
570
+ # Response is already JSON
571
+ json_str = response_content
572
+ else:
573
+ # Try to find JSON object in the response
574
+ import re
575
+ json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
576
+ if json_match:
577
+ json_str = json_match.group(0)
578
+ else:
579
+ raise ValueError("No JSON object found in response")
580
+
581
+ # Parse JSON
582
+ parsed_data = json.loads(json_str)
583
+
584
+ # Convert to Pydantic model if schema is a BaseModel
585
+ if hasattr(self.schema, 'model_validate'):
586
+ # Pydantic v2
587
+ return self.schema.model_validate(parsed_data)
588
+ elif hasattr(self.schema, 'parse_obj'):
589
+ # Pydantic v1
590
+ return self.schema.parse_obj(parsed_data)
591
+ else:
592
+ # Dictionary schema - return parsed data
593
+ return parsed_data
594
+
595
+ except Exception as e:
596
+ # Fallback: return raw response if parsing fails
597
+ raise ValueError(f"Failed to parse structured output: {e}\nResponse: {response_content}")
598
+
599
+ def _messages_to_prompt(self, messages: List[BaseMessage]) -> str:
600
+ """Convert LangChain messages to a single prompt string with structured output instructions."""
601
+ # Get the original prompt
602
+ original_prompt = super()._messages_to_prompt(messages)
603
+
604
+ # Add structured output instructions
605
+ return self._create_structured_prompt(original_prompt)
606
+
607
+ def invoke(self, input, config=None, **kwargs):
608
+ """Invoke the model and return structured output."""
609
+ # Get the regular AI message response
610
+ response = super().invoke(input, config, **kwargs)
611
+
612
+ # Parse the response content into structured format
613
+ structured_result = self._parse_structured_response(response.content)
614
+
615
+ return structured_result
616
+
617
+ async def ainvoke(self, input, config=None, **kwargs):
618
+ """Async invoke the model and return structured output."""
619
+ # Get the regular AI message response
620
+ response = await super().ainvoke(input, config, **kwargs)
621
+
622
+ # Parse the response content into structured format
623
+ structured_result = self._parse_structured_response(response.content)
624
+
625
+ return structured_result
626
+
627
+
505
628
  class EuriaiEmbeddings(Embeddings):
506
629
  """
507
630
  Enhanced LangChain Embeddings implementation using Euri API.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: euriai
3
- Version: 1.0.2
3
+ Version: 1.0.4
4
4
  Summary: Python client for Euri API (euron.one) with CLI, LangChain, and LlamaIndex integration
5
5
  Author: Euri
6
6
  Author-email: tech@euron.one
@@ -52,10 +52,44 @@ Dynamic: summary
52
52
 
53
53
  ## 🔧 Installation
54
54
 
55
+ ### Basic Installation
55
56
  ```bash
56
57
  pip install euriai
57
58
  ```
58
59
 
60
+ ### Framework-Specific Installation
61
+ For framework integrations, install the specific extras you need:
62
+
63
+ ```bash
64
+ # For LangChain integration
65
+ pip install euriai[langchain]
66
+
67
+ # For LlamaIndex integration
68
+ pip install euriai[llama-index]
69
+
70
+ # For LangGraph integration
71
+ pip install euriai[langgraph]
72
+
73
+ # For CrewAI integration
74
+ pip install euriai[crewai]
75
+
76
+ # For AutoGen integration
77
+ pip install euriai[autogen]
78
+
79
+ # For SmolAgents integration
80
+ pip install euriai[smolagents]
81
+
82
+ # Install multiple frameworks
83
+ pip install euriai[langchain,llama-index,langgraph]
84
+
85
+ # Install all frameworks
86
+ pip install euriai[langchain,llama-index,langgraph,crewai,autogen,smolagents]
87
+ ```
88
+
89
+ > **Note**: The n8n integration only requires the base installation as it uses standard HTTP requests.
90
+
91
+ ---
92
+
59
93
  ## 🚀 Python Usage
60
94
 
61
95
  ### Text Generation
@@ -107,16 +141,20 @@ List all supported model IDs with recommended use-cases and temperature/token ad
107
141
  euriai --models
108
142
  ```
109
143
 
110
- ## 🤖 LangChain Integration
144
+ ## 🤖 Framework Integrations
111
145
 
112
- ### Text Generation
146
+ ### LangChain Integration
147
+
148
+ **Installation**: `pip install euriai[langchain]`
149
+
150
+ #### Text Generation
113
151
 
114
152
  Use Euriai with LangChain directly:
115
153
 
116
154
  ```python
117
- from euriai import EuriaiLangChainLLM
155
+ from euriai import EuriaiChatModel
118
156
 
119
- llm = EuriaiLangChainLLM(
157
+ llm = EuriaiChatModel(
120
158
  api_key="your_api_key",
121
159
  model="gpt-4.1-nano",
122
160
  temperature=0.7,
@@ -126,66 +164,25 @@ llm = EuriaiLangChainLLM(
126
164
  print(llm.invoke("Write a poem about time travel."))
127
165
  ```
128
166
 
129
- ### Embeddings
167
+ #### Embeddings
130
168
 
131
169
  Use Euriai embeddings with LangChain:
132
170
 
133
171
  ```python
134
- from euriai.langchain_embed import EuriaiEmbeddings
172
+ from euriai import EuriaiEmbeddings
135
173
 
136
174
  embedding_model = EuriaiEmbeddings(api_key="your_key")
137
175
  print(embedding_model.embed_query("What's AI?")[:5]) # Print first 5 dimensions
138
176
  ```
139
177
 
140
- ## Usage Examples
141
-
142
- ### CrewAI Integration
143
- ```python
144
- from euriai import EuriaiCrewAI
145
-
146
- # Example: Create a crew from YAML config files
147
- crew = EuriaiCrewAI.from_yaml('agents.yaml', 'tasks.yaml')
148
- result = crew.run(inputs={"topic": "AI in Healthcare"})
149
- print(result)
150
-
151
- # Or programmatically
152
- crew = EuriaiCrewAI()
153
- crew.add_agent("researcher", {
154
- "role": "Researcher",
155
- "goal": "Find information about {topic}",
156
- "llm": "openai/gpt-4o"
157
- })
158
- crew.add_task("research_task", {
159
- "description": "Research the topic {topic}",
160
- "agent": "researcher"
161
- })
162
- crew.build_crew()
163
- result = crew.run(inputs={"topic": "AI in Healthcare"})
164
- print(result)
165
- ```
166
-
167
- ### AutoGen Integration
168
- ```python
169
- from euriai import EuriaiAutoGen
178
+ ### LlamaIndex Integration
170
179
 
171
- autogen = EuriaiAutoGen()
172
- # Add an agent (see AutoGen docs for agent config details)
173
- agent = autogen.add_agent({
174
- "name": "assistant",
175
- "llm_config": {"api_key": "YOUR_OPENAI_KEY", "model": "gpt-4o"}
176
- })
177
- # Run a chat
178
- response = autogen.run_chat("Hello, what is the weather today?")
179
- print(response)
180
- # Access chat history
181
- print(autogen.get_history())
182
- ```
180
+ **Installation**: `pip install euriai[llama-index]`
183
181
 
184
- ### LlamaIndex Integration
185
182
  ```python
186
183
  from euriai import EuriaiLlamaIndex
187
184
 
188
- llama = EuriaiLlamaIndex()
185
+ llama = EuriaiLlamaIndex(api_key="your_api_key")
189
186
  llama.add_documents([
190
187
  "Abraham Lincoln was the 16th President of the United States.",
191
188
  "He led the country during the American Civil War."
@@ -196,6 +193,9 @@ print(response)
196
193
  ```
197
194
 
198
195
  ### LangGraph Integration
196
+
197
+ **Installation**: `pip install euriai[langgraph]`
198
+
199
199
  ```python
200
200
  from euriai import EuriaiLangGraph
201
201
 
@@ -210,27 +210,67 @@ def farewell_node(state):
210
210
  return state
211
211
 
212
212
  # Create the graph
213
- graph = EuriaiLangGraph()
213
+ graph = EuriaiLangGraph(api_key="your_api_key")
214
214
  graph.add_node("greet", greet_node)
215
215
  graph.add_node("farewell", farewell_node)
216
216
  graph.add_edge("greet", "farewell")
217
- graph.set_state({"name": "Alice"})
218
- result = graph.run()
217
+ graph.set_entry_point("greet")
218
+ graph.set_finish_point("farewell")
219
+ result = graph.run({"name": "Alice"})
219
220
  print(result)
220
221
  ```
221
222
 
222
- ---
223
+ ### CrewAI Integration
223
224
 
224
- ## 2. **SmolAgents Integration**
225
+ **Installation**: `pip install euriai[crewai]`
226
+
227
+ ```python
228
+ from euriai import EuriaiCrewAI
229
+
230
+ # Example: Create a crew from YAML config files
231
+ crew = EuriaiCrewAI(api_key="your_api_key")
232
+ crew.add_agent("researcher", {
233
+ "role": "Researcher",
234
+ "goal": "Find information about {topic}",
235
+ "backstory": "You are an expert researcher"
236
+ })
237
+ crew.add_task("research_task", {
238
+ "description": "Research the topic {topic}",
239
+ "agent": "researcher"
240
+ })
241
+ crew.build_crew()
242
+ result = crew.run(inputs={"topic": "AI in Healthcare"})
243
+ print(result)
244
+ ```
245
+
246
+ ### AutoGen Integration
247
+
248
+ **Installation**: `pip install euriai[autogen]`
249
+
250
+ ```python
251
+ from euriai import EuriaiAutoGen
252
+
253
+ autogen = EuriaiAutoGen(api_key="your_api_key")
254
+ # Add an agent (see AutoGen docs for agent config details)
255
+ agent = autogen.create_assistant_agent(
256
+ name="assistant",
257
+ system_message="You are a helpful assistant",
258
+ model="gpt-4.1-nano"
259
+ )
260
+ # Run a chat
261
+ response = autogen.initiate_chat(agent, message="Hello, what is the weather today?")
262
+ print(response)
263
+ ```
264
+
265
+ ### SmolAgents Integration
266
+
267
+ **Installation**: `pip install euriai[smolagents]`
225
268
 
226
269
  ```python
227
270
  from euriai import EuriaiSmolAgent
228
271
 
229
272
  # Define a tool using the @tool decorator
230
- try:
231
- from smolagents import tool
232
- except ImportError:
233
- raise ImportError("Please install smolagents: pip install smolagents")
273
+ from smolagents import tool
234
274
 
235
275
  @tool
236
276
  def add(a: int, b: int) -> int:
@@ -238,14 +278,14 @@ def add(a: int, b: int) -> int:
238
278
  return a + b
239
279
 
240
280
  # Create the agent with the tool
241
- agent = EuriaiSmolAgent(tools=[add])
281
+ agent = EuriaiSmolAgent(api_key="your_api_key", tools=[add])
242
282
  response = agent.run("What is 2 + 3?")
243
283
  print(response)
244
284
  ```
245
285
 
246
- ---
286
+ ### n8n Integration
247
287
 
248
- ## 3. **n8n Integration**
288
+ **Installation**: Basic installation only (`pip install euriai`)
249
289
 
250
290
  ```python
251
291
  from euriai import EuriaiN8N
@@ -262,8 +302,17 @@ print(result)
262
302
 
263
303
  ---
264
304
 
265
- **You can copy-paste these code blocks into your client documentation or UI for user reference.**
266
- If you want advanced examples (e.g., multi-tool SmolAgents, LangGraph with more nodes, or n8n with authentication), just let me know!
305
+ ## 🔍 Framework Status
306
+
307
+ | Framework | Status | Installation Command | Notes |
308
+ |-----------|--------|---------------------|-------|
309
+ | LangChain | ✅ Working | `pip install euriai[langchain]` | Full compatibility |
310
+ | LlamaIndex | ✅ Working | `pip install euriai[llama-index]` | Full compatibility |
311
+ | n8n | ✅ Working | `pip install euriai` | No extra dependencies |
312
+ | LangGraph | ⚠️ Requires Install | `pip install euriai[langgraph]` | Install required |
313
+ | CrewAI | ⚠️ Requires Install | `pip install euriai[crewai]` | Install required |
314
+ | AutoGen | ⚠️ Requires Install | `pip install euriai[autogen]` | Install required |
315
+ | SmolAgents | ⚠️ Requires Install | `pip install euriai[smolagents]` | Install required |
267
316
 
268
317
  ## 📘 Documentation
269
318
 
@@ -2,17 +2,17 @@ euriai/__init__.py,sha256=WE4zl0HNxDm4zwR3d0uRyjl3fjcD_pccKvPsbtuDysw,916
2
2
  euriai/autogen.py,sha256=4YAHrY65YYOKVsBjQa9G8pr-_Xxss1uR08qLAFzo7Rk,16023
3
3
  euriai/cli.py,sha256=hF1wiiL2QQSfWf8WlLQyNVDBd4YkbiwmMSoPxVbyPTM,3290
4
4
  euriai/client.py,sha256=L-o6hv9N3md-l-hz-kz5nYVaaZqnrREZlo_0jguhF7E,4066
5
- euriai/crewai.py,sha256=eeDfZQC9LtEePSnaj94DA0Kcb8Ayq0Gn_eDSQwbcMBU,7543
5
+ euriai/crewai.py,sha256=nfMMOOhKiCIc2v42nj2Zf9rP0U5m4GrfK_6zkXL77gw,7594
6
6
  euriai/embedding.py,sha256=uP66Ph1k9Ou6J5RAkztJxlfyj0S0MESOvZ4ulhnVo-o,1270
7
7
  euriai/euri_chat.py,sha256=DEAiet1ReRwB4ljkPYaTl1Nb5uc20-JF-3PQjGQZXk4,3567
8
- euriai/euri_embed.py,sha256=VE-RLUb5bYnEFA_dxFkj2c3Jr_SYyJKPmFOzsDOR0Ys,2137
9
- euriai/langchain.py,sha256=K8yJdkB9sUiLQj1kt_IJ_cNBWLEimo7xNgGedmdkdsc,30109
8
+ euriai/euri_embed.py,sha256=g7zs1G-ZBDJjOGJtkkfIcV4LPtRcm9wpVWmrfMGn5EM,2919
9
+ euriai/langchain.py,sha256=gVF9eh21RC1WtDn7SQoEREUDqOObm5IRx6BFZtB5xcc,34968
10
10
  euriai/langgraph.py,sha256=sw9e-PnfwAwmp_tUCnAGIUB78GyJsMkAzxOGvFUafiM,34128
11
11
  euriai/llamaindex.py,sha256=c-ujod2bjL6QIvfAyuIxm1SvSCS00URFElYybKQ5Ew0,26551
12
12
  euriai/n8n.py,sha256=hjkckqyW_hZNL78UkBCof1WvKCKCIjwdvZdAgx6NrB8,3764
13
13
  euriai/smolagents.py,sha256=xlixGx2IWzAPTpSJGsYIK2L-SHGY9Mw1-8GbwVsEYtU,28507
14
- euriai-1.0.2.dist-info/METADATA,sha256=S9UtbT2UjLIHakIbQlJDfR3EZv2p-PFsjq_mzvSlJ-U,6881
15
- euriai-1.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
- euriai-1.0.2.dist-info/entry_points.txt,sha256=9OkET8KIGcsjQn8UlnpPKRT75s2KW34jq1__1SXtpMA,43
17
- euriai-1.0.2.dist-info/top_level.txt,sha256=TG1htJ8cuD62MXn-NJ7DVF21QHY16w6M_QgfF_Er_EQ,7
18
- euriai-1.0.2.dist-info/RECORD,,
14
+ euriai-1.0.4.dist-info/METADATA,sha256=W-vrzgWEy1eDQLuzM31kI278KnEl6rVP81LBwPN1Db8,8417
15
+ euriai-1.0.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
+ euriai-1.0.4.dist-info/entry_points.txt,sha256=9OkET8KIGcsjQn8UlnpPKRT75s2KW34jq1__1SXtpMA,43
17
+ euriai-1.0.4.dist-info/top_level.txt,sha256=TG1htJ8cuD62MXn-NJ7DVF21QHY16w6M_QgfF_Er_EQ,7
18
+ euriai-1.0.4.dist-info/RECORD,,
File without changes