agentic-blocks 0.1.3__py3-none-any.whl → 0.1.5__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.
agentic_blocks/llm.py CHANGED
@@ -22,8 +22,9 @@ def call_llm(
22
22
  tools: Optional[List[Dict[str, Any]]] = None,
23
23
  api_key: Optional[str] = None,
24
24
  model: str = "gpt-4o-mini",
25
+ base_url: Optional[str] = None,
25
26
  **kwargs,
26
- ) -> str:
27
+ ) -> Any:
27
28
  """
28
29
  Call an LLM completion API with the provided messages.
29
30
 
@@ -32,10 +33,11 @@ def call_llm(
32
33
  tools: Optional list of tools in OpenAI function calling format
33
34
  api_key: OpenAI API key (if not provided, loads from .env OPENAI_API_KEY)
34
35
  model: Model name to use for completion
36
+ base_url: Base URL for the API (useful for VLLM or other OpenAI-compatible servers)
35
37
  **kwargs: Additional parameters to pass to OpenAI API
36
38
 
37
39
  Returns:
38
- The assistant's response content as a string
40
+ The complete message object from the OpenAI API response
39
41
 
40
42
  Raises:
41
43
  LLMError: If API call fails or configuration is invalid
@@ -47,13 +49,18 @@ def call_llm(
47
49
  if not api_key:
48
50
  api_key = os.getenv("OPENAI_API_KEY")
49
51
 
50
- if not api_key:
52
+ if not api_key and not base_url:
51
53
  raise LLMError(
52
54
  "OpenAI API key not found. Set OPENAI_API_KEY environment variable or pass api_key parameter."
53
55
  )
54
56
 
55
57
  # Initialize OpenAI client
56
- client = OpenAI(api_key=api_key)
58
+ client_kwargs = {}
59
+ if api_key:
60
+ client_kwargs["api_key"] = api_key
61
+ if base_url:
62
+ client_kwargs["base_url"] = base_url
63
+ client = OpenAI(**client_kwargs)
57
64
 
58
65
  # Handle different message input types
59
66
  if isinstance(messages, Messages):
@@ -79,8 +86,8 @@ def call_llm(
79
86
  # Make completion request
80
87
  response = client.chat.completions.create(**completion_params)
81
88
 
82
- # Extract and return response content
83
- return response.choices[0].message.content or ""
89
+ # Return the complete message object
90
+ return response.choices[0].message
84
91
 
85
92
  except Exception as e:
86
93
  raise LLMError(f"Failed to call LLM API: {e}")
@@ -125,12 +132,17 @@ def example_usage():
125
132
  # Call with Messages object
126
133
  print("Using Messages object:")
127
134
  response1 = call_llm(messages_obj, temperature=0.7)
128
- print(f"Response: {response1}")
135
+ print(f"Response: {response1.content}")
129
136
 
130
137
  # Call with raw message list
131
138
  print("\nUsing raw message list:")
132
139
  response2 = call_llm(messages_list, tools=tools, temperature=0.5)
133
- print(f"Response: {response2}")
140
+ if hasattr(response2, 'tool_calls') and response2.tool_calls:
141
+ print(f"Tool calls requested: {len(response2.tool_calls)}")
142
+ for i, tool_call in enumerate(response2.tool_calls):
143
+ print(f" {i+1}. {tool_call.function.name}({tool_call.function.arguments})")
144
+ else:
145
+ print(f"Response: {response2.content}")
134
146
 
135
147
  except LLMError as e:
136
148
  print(f"Error: {e}")
@@ -16,6 +16,23 @@ from mcp.client.streamable_http import streamablehttp_client
16
16
  logger = logging.getLogger(__name__)
17
17
 
18
18
 
19
+ def handle_jupyter_env():
20
+ """Apply nest_asyncio if running in a Jupyter notebook environment."""
21
+ try:
22
+ # Check if we're in a running event loop (like Jupyter)
23
+ asyncio.get_running_loop()
24
+ try:
25
+ import nest_asyncio
26
+ nest_asyncio.apply()
27
+ except ImportError:
28
+ logger.warning(
29
+ "nest_asyncio not available. Install with: pip install nest-asyncio"
30
+ )
31
+ except RuntimeError:
32
+ # No event loop running, no need for nest_asyncio
33
+ pass
34
+
35
+
19
36
  class MCPEndpointError(Exception):
20
37
  """Exception raised when there's an error connecting to or using an MCP endpoint."""
21
38
 
@@ -77,6 +94,7 @@ class MCPClient:
77
94
  Raises:
78
95
  MCPEndpointError: If connection or listing fails
79
96
  """
97
+ handle_jupyter_env()
80
98
  return asyncio.run(self.list_tools_async())
81
99
 
82
100
  async def list_tools_async(self) -> List[Dict[str, Any]]:
@@ -158,6 +176,7 @@ class MCPClient:
158
176
  Raises:
159
177
  MCPEndpointError: If connection or tool call fails
160
178
  """
179
+ handle_jupyter_env()
161
180
  return asyncio.run(self.call_tool_async(tool_name, arguments))
162
181
 
163
182
  async def call_tool_async(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentic-blocks
3
- Version: 0.1.3
3
+ Version: 0.1.5
4
4
  Summary: Simple building blocks for agentic AI systems with MCP client and conversation management
5
5
  Author-email: Magnus Bjelkenhed <bjelkenhed@gmail.com>
6
6
  License: MIT
@@ -0,0 +1,9 @@
1
+ agentic_blocks/__init__.py,sha256=LJy2tzTwX9ZjPw8dqkXOWiude7ZDDIaBIvaLC8U4d_Y,435
2
+ agentic_blocks/llm.py,sha256=EetJFAUMAvRYFExjZrVCyeewhqhtnE7o3PvlW9NgKHw,4584
3
+ agentic_blocks/mcp_client.py,sha256=15mIN_Qw0OVNJAvfgO3jVZS4-AU4TtvEQSFDlL9ruqA,9773
4
+ agentic_blocks/messages.py,sha256=rwcb_goGwfPiDIzl6Up46pAl-5Kw5aFb0uqd6pQtJPY,8162
5
+ agentic_blocks-0.1.5.dist-info/licenses/LICENSE,sha256=r4IcBaAjTv3-yfjXgDPuRD953Qci0Y0nQn5JfHwLyBY,1073
6
+ agentic_blocks-0.1.5.dist-info/METADATA,sha256=zHSVjhDqcM2pnKhX_r_0x6iRNqbBHt-Xc-G2hI4PTx8,9445
7
+ agentic_blocks-0.1.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
+ agentic_blocks-0.1.5.dist-info/top_level.txt,sha256=-1a4RAemqicXLU1rRzw4QHV3KlNeQDNxVs3m2gAT238,15
9
+ agentic_blocks-0.1.5.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- agentic_blocks/__init__.py,sha256=LJy2tzTwX9ZjPw8dqkXOWiude7ZDDIaBIvaLC8U4d_Y,435
2
- agentic_blocks/llm.py,sha256=Rbh0rYDeVyo3S7hRG6tiIfALjchd64zTNz3Q465LUZs,3964
3
- agentic_blocks/mcp_client.py,sha256=WsEdgzXw8bM76iJWD5BzoJF7MK9wXcUUd5T0TUAWusw,9175
4
- agentic_blocks/messages.py,sha256=rwcb_goGwfPiDIzl6Up46pAl-5Kw5aFb0uqd6pQtJPY,8162
5
- agentic_blocks-0.1.3.dist-info/licenses/LICENSE,sha256=r4IcBaAjTv3-yfjXgDPuRD953Qci0Y0nQn5JfHwLyBY,1073
6
- agentic_blocks-0.1.3.dist-info/METADATA,sha256=Vyggnjbzq4el1dJP82dUjTKeTj1A8Ap-HXZvUlDNVs4,9445
7
- agentic_blocks-0.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
- agentic_blocks-0.1.3.dist-info/top_level.txt,sha256=-1a4RAemqicXLU1rRzw4QHV3KlNeQDNxVs3m2gAT238,15
9
- agentic_blocks-0.1.3.dist-info/RECORD,,