clap-agents 0.2.1__tar.gz → 0.2.2__tar.gz

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.
Files changed (67) hide show
  1. {clap_agents-0.2.1 → clap_agents-0.2.2}/PKG-INFO +1 -1
  2. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/CLAP-TEST-SUITE.py +11 -11
  3. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/local_rag.py +7 -10
  4. clap_agents-0.2.2/examples/mcp_test_suite.py +87 -0
  5. {clap_agents-0.2.1 → clap_agents-0.2.2}/pyproject.toml +1 -1
  6. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/mcp_client/client.py +8 -7
  7. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/vector_stores/chroma_store.py +2 -2
  8. {clap_agents-0.2.1 → clap_agents-0.2.2}/.gitignore +0 -0
  9. {clap_agents-0.2.1 → clap_agents-0.2.2}/GITCLAP.png +0 -0
  10. {clap_agents-0.2.1 → clap_agents-0.2.2}/LICENSE +0 -0
  11. {clap_agents-0.2.1 → clap_agents-0.2.2}/PIP CLAP.png +0 -0
  12. {clap_agents-0.2.1 → clap_agents-0.2.2}/README.md +0 -0
  13. {clap_agents-0.2.1 → clap_agents-0.2.2}/changelog.md +0 -0
  14. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/all_func.py +0 -0
  15. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/document_ingestion.py +0 -0
  16. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/email_test.py +0 -0
  17. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/google_agent.py +0 -0
  18. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/google_mcp.py +0 -0
  19. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/google_team.py +0 -0
  20. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/huge_rag.py +0 -0
  21. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/mcp_team_agent.py +0 -0
  22. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/mcp_test_agent.py +0 -0
  23. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/ollama_test.py +0 -0
  24. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/qdrant_ingestion.py +0 -0
  25. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/rag_all_functionalities.py +0 -0
  26. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/rag_test.py +0 -0
  27. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/react_test.py +0 -0
  28. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/requirements.txt +0 -0
  29. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/scraping_test.py +0 -0
  30. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/simple_react_agent.py +0 -0
  31. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/team_test.py +0 -0
  32. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/test_agent.py +0 -0
  33. {clap_agents-0.2.1 → clap_agents-0.2.2}/examples/tool_agent_rag.py +0 -0
  34. {clap_agents-0.2.1 → clap_agents-0.2.2}/simple2_mcp.py +0 -0
  35. {clap_agents-0.2.1 → clap_agents-0.2.2}/simple_mcp.py +0 -0
  36. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/__init__.py +0 -0
  37. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/embedding/__init__.py +0 -0
  38. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/embedding/base_embedding.py +0 -0
  39. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/embedding/fastembed_embedding.py +0 -0
  40. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/embedding/ollama_embedding.py +0 -0
  41. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/embedding/sentence_transformer_embedding.py +0 -0
  42. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/llm_services/__init__.py +0 -0
  43. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/llm_services/base.py +0 -0
  44. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/llm_services/google_openai_compat_service.py +0 -0
  45. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/llm_services/groq_service.py +0 -0
  46. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/llm_services/ollama_service.py +0 -0
  47. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/mcp_client/__init__.py +0 -0
  48. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/multiagent_pattern/__init__.py +0 -0
  49. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/multiagent_pattern/agent.py +0 -0
  50. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/multiagent_pattern/team.py +0 -0
  51. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/react_pattern/__init__.py +0 -0
  52. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/react_pattern/react_agent.py +0 -0
  53. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/tool_pattern/__init__.py +0 -0
  54. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/tool_pattern/tool.py +0 -0
  55. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/tool_pattern/tool_agent.py +0 -0
  56. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/tools/__init__.py +0 -0
  57. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/tools/email_tools.py +0 -0
  58. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/tools/web_crawler.py +0 -0
  59. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/tools/web_search.py +0 -0
  60. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/utils/__init__.py +0 -0
  61. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/utils/completions.py +0 -0
  62. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/utils/extraction.py +0 -0
  63. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/utils/logging.py +0 -0
  64. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/utils/rag_utils.py +0 -0
  65. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/vector_stores/__init__.py +0 -0
  66. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/vector_stores/base.py +0 -0
  67. {clap_agents-0.2.1 → clap_agents-0.2.2}/src/clap/vector_stores/qdrant_store.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clap-agents
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: A Python framework for building cognitive agentic patterns including ReAct agents, Multi-Agent Teams, native tool calling, and MCP client integration.
5
5
  Project-URL: Homepage, https://github.com/MaitreyaM/CLAP-AGENTS.git
6
6
  Project-URL: Repository, https://github.com/MaitreyaM/CLAP-AGENTS.git
@@ -253,17 +253,17 @@ async def main():
253
253
 
254
254
  fast_ef: Optional[FastEmbedEmbeddings] = None
255
255
  # FE_KNOWN_DIMS is imported at the top
256
- # try:
257
- # if FASTEMBED_MODEL in FE_KNOWN_DIMS:
258
- # fast_ef = FastEmbedEmbeddings(model_name=FASTEMBED_MODEL)
259
- # else:
260
- # print(f"Warning: FastEmbed model '{FASTEMBED_MODEL}' not in FE_KNOWN_DIMS. FastEmbed RAG will be skipped.")
261
- # except NameError: # If FastEmbedEmbeddings or FE_KNOWN_DIMS not defined due to import error
262
- # print("FastEmbedEmbeddings or its KNOWN_DIMS not available.")
263
- # except Exception as e:
264
- # print(f"Could not initialize FastEmbedEmbeddings: {e}")
265
- # if fast_ef: print("FastEmbedEmbeddings initialized (RAG tests may be commented out).")
266
- print("INFO: FastEmbed RAG tests are currently commented out to save time.")
256
+ try:
257
+ if FASTEMBED_MODEL in FE_KNOWN_DIMS:
258
+ fast_ef = FastEmbedEmbeddings(model_name=FASTEMBED_MODEL)
259
+ else:
260
+ print(f"Warning: FastEmbed model '{FASTEMBED_MODEL}' not in FE_KNOWN_DIMS. FastEmbed RAG will be skipped.")
261
+ except NameError: # If FastEmbedEmbeddings or FE_KNOWN_DIMS not defined due to import error
262
+ print("FastEmbedEmbeddings or its KNOWN_DIMS not available.")
263
+ except Exception as e:
264
+ print(f"Could not initialize FastEmbedEmbeddings: {e}")
265
+ if fast_ef: print("FastEmbedEmbeddings initialized (RAG tests may be commented out).")
266
+ # print("INFO: FastEmbed RAG tests are currently commented out to save time.")
267
267
 
268
268
 
269
269
  mcp_manager = get_mcp_manager()
@@ -7,19 +7,19 @@ import uuid
7
7
  from clap import Agent
8
8
  from clap.vector_stores.qdrant_store import QdrantStore
9
9
  from clap.utils.rag_utils import load_pdf_file, chunk_text_by_fixed_size
10
- from clap.llm_services.ollama_llm_service import OllamaOpenAICompatService
10
+ from clap.llm_services.ollama_service import OllamaOpenAICompatService
11
11
  from clap.embedding.ollama_embedding import OllamaEmbeddings, KNOWN_OLLAMA_EMBEDDING_DIMENSIONS
12
12
  from qdrant_client import models as qdrant_models
13
13
 
14
14
  load_dotenv()
15
15
 
16
- PDF_PATH = "/Users/maitreyamishra/PROJECTS/Cognitive-Layer/examples/Hands_On_ML.pdf" # Ensure this PDF exists
16
+ PDF_PATH = "/Users/maitreyamishra/PROJECTS/Cognitive-Layer/examples/handsonml.pdf"
17
17
  DB_PATH = "./ollama_rag_qdrant_minimal_db"
18
18
  COLLECTION_NAME = "ml_book_ollama_minimal"
19
19
  CHUNK_SIZE, CHUNK_OVERLAP = 500, 50
20
20
  OLLAMA_HOST = "http://localhost:11434"
21
- OLLAMA_LLM_MODEL = "llama3.2:latest" # Ensure pulled: ollama pull llama3
22
- OLLAMA_EMBED_MODEL = "nomic-embed-text" # Ensure pulled: ollama pull nomic-embed-text
21
+ OLLAMA_LLM_MODEL = "llama3.2:latest"
22
+ OLLAMA_EMBED_MODEL = "nomic-embed-text"
23
23
 
24
24
  async def run_minimal_ollama_rag():
25
25
  start_time = time.time()
@@ -51,24 +51,21 @@ async def run_minimal_ollama_rag():
51
51
  ollama_llm_service = OllamaOpenAICompatService(default_model=OLLAMA_LLM_MODEL, base_url=f"{OLLAMA_HOST}/v1")
52
52
  rag_agent = Agent(
53
53
  name="OllamaMinimalExpert", backstory="Answer from book context.",
54
- task_description="What are Generative Adversarial Networks?", # Will be overwritten
54
+ task_description="What are Generative Adversarial Networks?", # can be overwritten
55
55
  llm_service=ollama_llm_service, model=OLLAMA_LLM_MODEL, vector_store=vector_store
56
56
  )
57
57
 
58
58
  user_query = "Explain Generative Adversarial Networks (GANs) based on the book."
59
- print(f"\nUser Query: {user_query}")
60
59
  rag_agent.task_description = user_query
61
60
 
62
61
  query_start = time.time()
63
62
  result = await rag_agent.run()
64
63
  print(f"Query Took: {time.time() - query_start:.2f}s")
65
- print("\n--- Agent Answer ---")
66
64
  print(result.get("output", "No answer."))
67
65
 
68
66
  await vector_store.close()
69
67
  await ollama_llm_service.close()
70
68
  print(f"\nTotal Test Took: {time.time() - start_time:.2f}s")
71
69
 
72
- if __name__ == "__main__":
73
- print(f"Ensure Ollama server (models: {OLLAMA_LLM_MODEL}, {OLLAMA_EMBED_MODEL}) is running.")
74
- asyncio.run(run_minimal_ollama_rag())
70
+
71
+ asyncio.run(run_minimal_ollama_rag())
@@ -0,0 +1,87 @@
1
+ import asyncio
2
+ import os
3
+ from dotenv import load_dotenv
4
+ from typing import Optional
5
+
6
+ from pydantic import HttpUrl
7
+
8
+
9
+ from clap import MCPClientManager, SseServerConfig
10
+
11
+ load_dotenv()
12
+
13
+ def print_header(title: str):
14
+ print(f"\n{'='*10} {title.upper()} {'='*10}")
15
+
16
+ async def run_mcp_test_cycle(
17
+ manager: MCPClientManager,
18
+ server_name: str,
19
+ tool_to_call: Optional[str] = None,
20
+ tool_args: Optional[dict] = None
21
+ ):
22
+ print_header(f"TEST CYCLE FOR {server_name.upper()}")
23
+ try:
24
+ print(f"Attempting to list tools from '{server_name}'...")
25
+ tools = await manager.list_remote_tools(server_name)
26
+ print(f"Found tools on '{server_name}': {[t.name for t in tools] if tools else 'None'}")
27
+
28
+ if tool_to_call and tool_args:
29
+ if any(t.name == tool_to_call for t in tools):
30
+ print(f"Attempting to call tool '{tool_to_call}' on '{server_name}' with args: {tool_args}...")
31
+ result = await manager.call_remote_tool(server_name, tool_to_call, tool_args)
32
+ print(f"Result from '{tool_to_call}' on '{server_name}': {result}")
33
+ else:
34
+ print(f"Tool '{tool_to_call}' not found on server '{server_name}'.")
35
+
36
+ except RuntimeError as e:
37
+ print(f"RuntimeError during {server_name} cycle: {e}")
38
+ except Exception as e:
39
+ print(f"Unexpected error during {server_name} cycle: {type(e).__name__} - {e}")
40
+
41
+
42
+ async def main():
43
+ print("MCP Robustness Test: Starting...")
44
+ print("Ensure MCP servers ('adder_server' on 8000, 'subtract_server' on 8001) are running.")
45
+
46
+ mcp_server_configs = {
47
+ "adder_server": SseServerConfig(url=HttpUrl("http://localhost:8000")),
48
+ "subtract_server": SseServerConfig(url=HttpUrl("http://localhost:8001")),
49
+ "non_existent_server": SseServerConfig(url=HttpUrl("http://localhost:8009")) # To test connection error
50
+ }
51
+ manager: Optional[MCPClientManager] = None
52
+
53
+ try:
54
+ manager = MCPClientManager(server_configs=mcp_server_configs)
55
+ print("MCPClientManager initialized.")
56
+
57
+ await run_mcp_test_cycle(manager, "adder_server", tool_to_call="add", tool_args={"a": 10, "b": 5})
58
+
59
+ print_header("SIMULATING AN EXTERNAL ERROR")
60
+ try:
61
+
62
+ print("Raising a simulated application error...")
63
+ raise ValueError("Simulated application error after first MCP interaction.")
64
+ except ValueError as app_error:
65
+ print(f"Caught simulated application error: {app_error}")
66
+ print("Proceeding to test other MCP operations and cleanup...")
67
+
68
+ await run_mcp_test_cycle(manager, "subtract_server", tool_to_call="sub", tool_args={"a": 20, "b": 3})
69
+
70
+ await run_mcp_test_cycle(manager, "non_existent_server")
71
+
72
+
73
+ except Exception as e:
74
+ print(f"Critical error in main test execution: {type(e).__name__} - {e}")
75
+ finally:
76
+ if manager:
77
+ print_header("FINAL MCP CLEANUP")
78
+ print("Calling manager.disconnect_all()...")
79
+ await manager.disconnect_all()
80
+ print("manager.disconnect_all() completed.")
81
+ else:
82
+ print("MCPClientManager was not initialized.")
83
+
84
+ print("\nMCP Robustness Test: Finished.")
85
+
86
+ if __name__ == "__main__":
87
+ asyncio.run(main())
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "clap-agents"
9
- version = "0.2.1"
9
+ version = "0.2.2"
10
10
  description = "A Python framework for building cognitive agentic patterns including ReAct agents, Multi-Agent Teams, native tool calling, and MCP client integration."
11
11
  readme = "README.md"
12
12
  requires-python = ">=3.10"
@@ -113,14 +113,16 @@ class MCPClientManager:
113
113
  await exit_stack.aclose()
114
114
  print(f"{Fore.GREEN}Disconnected from MCP server: {server_name}{Fore.RESET}")
115
115
 
116
+
116
117
  async def disconnect_all(self):
117
- """Disconnects from all currently connected servers."""
118
118
  server_names = list(self.sessions.keys())
119
- print(f"{Fore.YELLOW}Disconnecting from all servers: {server_names}{Fore.RESET}")
120
-
121
- tasks = [self.disconnect(name) for name in server_names]
122
- await asyncio.gather(*tasks, return_exceptions=True)
123
- print(f"{Fore.GREEN}Finished disconnecting all servers.{Fore.RESET}")
119
+ print(f"{Fore.YELLOW}MCPClientManager: Disconnecting from all servers ({len(server_names)})...{Fore.RESET}")
120
+ for name in server_names:
121
+ try:
122
+ await self.disconnect(name)
123
+ except Exception as e:
124
+ print(f"{Fore.RED}MCPClientManager: Error during disconnect of '{name}': {e}{Fore.RESET}")
125
+ print(f"{Fore.GREEN}MCPClientManager: Finished disconnecting all servers.{Fore.RESET}")
124
126
 
125
127
  async def list_remote_tools(self, server_name: str) -> List[types.Tool]:
126
128
  """
@@ -192,4 +194,3 @@ class MCPClientManager:
192
194
  except Exception as e:
193
195
  print(f"{Fore.RED}Error calling tool '{tool_name}' on server '{server_name}': {e}{Fore.RESET}")
194
196
  raise RuntimeError(f"Failed to call tool '{tool_name}' on '{server_name}'.") from e
195
-
@@ -1,6 +1,6 @@
1
1
  import json
2
2
  import functools
3
- from typing import Any, Dict, List, Optional, cast
3
+ from typing import Any, Dict, List, Optional, cast, Callable, Coroutine
4
4
  import asyncio
5
5
  import anyio
6
6
 
@@ -38,7 +38,7 @@ from clap.embedding.base_embedding import EmbeddingFunctionInterface as ClapEFIn
38
38
 
39
39
  class _AsyncEFWrapperForChroma:
40
40
  """Wraps an async CLAP EmbeddingFunctionInterface to be callable synchronously by Chroma."""
41
- def __init__(self, async_ef_call: asyncio.coroutine, loop: asyncio.AbstractEventLoop):
41
+ def __init__(self, async_ef_call: Callable[..., Coroutine[Any, Any, Embeddings]], loop: asyncio.AbstractEventLoop):
42
42
  self._async_ef_call = async_ef_call
43
43
  self._loop = loop
44
44
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes