traia-iatp 0.1.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.
Potentially problematic release.
This version of traia-iatp might be problematic. Click here for more details.
- traia_iatp/README.md +368 -0
- traia_iatp/__init__.py +30 -0
- traia_iatp/cli/__init__.py +5 -0
- traia_iatp/cli/main.py +483 -0
- traia_iatp/client/__init__.py +10 -0
- traia_iatp/client/a2a_client.py +274 -0
- traia_iatp/client/crewai_a2a_tools.py +335 -0
- traia_iatp/client/grpc_a2a_tools.py +349 -0
- traia_iatp/client/root_path_a2a_client.py +1 -0
- traia_iatp/core/__init__.py +43 -0
- traia_iatp/core/models.py +161 -0
- traia_iatp/mcp/__init__.py +15 -0
- traia_iatp/mcp/client.py +201 -0
- traia_iatp/mcp/mcp_agent_template.py +422 -0
- traia_iatp/mcp/templates/Dockerfile.j2 +56 -0
- traia_iatp/mcp/templates/README.md.j2 +212 -0
- traia_iatp/mcp/templates/cursor-rules.md.j2 +326 -0
- traia_iatp/mcp/templates/deployment_params.json.j2 +20 -0
- traia_iatp/mcp/templates/docker-compose.yml.j2 +23 -0
- traia_iatp/mcp/templates/dockerignore.j2 +47 -0
- traia_iatp/mcp/templates/gitignore.j2 +77 -0
- traia_iatp/mcp/templates/mcp_health_check.py.j2 +150 -0
- traia_iatp/mcp/templates/pyproject.toml.j2 +26 -0
- traia_iatp/mcp/templates/run_local_docker.sh.j2 +94 -0
- traia_iatp/mcp/templates/server.py.j2 +240 -0
- traia_iatp/mcp/traia_mcp_adapter.py +381 -0
- traia_iatp/preview_diagrams.html +181 -0
- traia_iatp/registry/__init__.py +26 -0
- traia_iatp/registry/atlas_search_indexes.json +280 -0
- traia_iatp/registry/embeddings.py +298 -0
- traia_iatp/registry/iatp_search_api.py +839 -0
- traia_iatp/registry/mongodb_registry.py +771 -0
- traia_iatp/registry/readmes/ATLAS_SEARCH_INDEXES.md +252 -0
- traia_iatp/registry/readmes/ATLAS_SEARCH_SETUP.md +134 -0
- traia_iatp/registry/readmes/AUTHENTICATION_UPDATE.md +124 -0
- traia_iatp/registry/readmes/EMBEDDINGS_SETUP.md +172 -0
- traia_iatp/registry/readmes/IATP_SEARCH_API_GUIDE.md +257 -0
- traia_iatp/registry/readmes/MONGODB_X509_AUTH.md +208 -0
- traia_iatp/registry/readmes/README.md +251 -0
- traia_iatp/registry/readmes/REFACTORING_SUMMARY.md +191 -0
- traia_iatp/server/__init__.py +15 -0
- traia_iatp/server/a2a_server.py +215 -0
- traia_iatp/server/example_template_usage.py +72 -0
- traia_iatp/server/iatp_server_agent_generator.py +237 -0
- traia_iatp/server/iatp_server_template_generator.py +235 -0
- traia_iatp/server/templates/Dockerfile.j2 +49 -0
- traia_iatp/server/templates/README.md +137 -0
- traia_iatp/server/templates/README.md.j2 +425 -0
- traia_iatp/server/templates/__init__.py +1 -0
- traia_iatp/server/templates/__main__.py.j2 +450 -0
- traia_iatp/server/templates/agent.py.j2 +80 -0
- traia_iatp/server/templates/agent_config.json.j2 +22 -0
- traia_iatp/server/templates/agent_executor.py.j2 +264 -0
- traia_iatp/server/templates/docker-compose.yml.j2 +23 -0
- traia_iatp/server/templates/env.example.j2 +67 -0
- traia_iatp/server/templates/gitignore.j2 +78 -0
- traia_iatp/server/templates/grpc_server.py.j2 +218 -0
- traia_iatp/server/templates/pyproject.toml.j2 +76 -0
- traia_iatp/server/templates/run_local_docker.sh.j2 +103 -0
- traia_iatp/server/templates/server.py.j2 +190 -0
- traia_iatp/special_agencies/__init__.py +4 -0
- traia_iatp/special_agencies/registry_search_agency.py +392 -0
- traia_iatp/utils/__init__.py +10 -0
- traia_iatp/utils/docker_utils.py +251 -0
- traia_iatp/utils/general.py +64 -0
- traia_iatp/utils/iatp_utils.py +126 -0
- traia_iatp-0.1.1.dist-info/METADATA +414 -0
- traia_iatp-0.1.1.dist-info/RECORD +72 -0
- traia_iatp-0.1.1.dist-info/WHEEL +5 -0
- traia_iatp-0.1.1.dist-info/entry_points.txt +2 -0
- traia_iatp-0.1.1.dist-info/licenses/LICENSE +21 -0
- traia_iatp-0.1.1.dist-info/top_level.txt +1 -0
traia_iatp/cli/main.py
ADDED
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
"""IATP CLI interface."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import json
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Optional, List
|
|
7
|
+
import typer
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
from rich.table import Table
|
|
10
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
11
|
+
from pydantic import HttpUrl
|
|
12
|
+
|
|
13
|
+
from ..core.models import MCPServer, MCPServerType, UtilityAgent
|
|
14
|
+
from ..server.iatp_server_agent_generator import IATPServerAgentGenerator
|
|
15
|
+
from ..registry.mongodb_registry import UtilityAgentRegistry, MCPServerRegistry
|
|
16
|
+
from ..utils.docker_utils import use_run_local_docker_script, LocalDockerRunner
|
|
17
|
+
from ..client.a2a_client import create_utility_agency_tools
|
|
18
|
+
from ..mcp.mcp_agent_template import MCPServerConfig
|
|
19
|
+
|
|
20
|
+
app = typer.Typer(
|
|
21
|
+
name="iatp",
|
|
22
|
+
help="Inter Agent Transfer Protocol - Enable AI Agents to utilize other AI Agents as tools"
|
|
23
|
+
)
|
|
24
|
+
console = Console()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@app.command()
|
|
28
|
+
def create_agency(
|
|
29
|
+
name: str = typer.Option(..., "--name", "-n", help="Name of the utility agency"),
|
|
30
|
+
description: str = typer.Option(..., "--description", "-d", help="Description of the agency"),
|
|
31
|
+
mcp_name: str = typer.Option(..., "--mcp-name", help="Name of existing MCP server in registry"),
|
|
32
|
+
output_dir: str = typer.Option("utility_agencies", "--output-dir", "-o", help="Output directory"),
|
|
33
|
+
deploy: bool = typer.Option(False, "--deploy", help="Deploy immediately after creation"),
|
|
34
|
+
port: Optional[int] = typer.Option(None, "--port", "-p", help="Port to deploy on"),
|
|
35
|
+
mongodb_uri: Optional[str] = typer.Option(None, "--mongodb-uri", help="MongoDB URI for registry")
|
|
36
|
+
):
|
|
37
|
+
"""Create a new utility agency from an existing MCP server in the registry."""
|
|
38
|
+
async def _create():
|
|
39
|
+
with Progress(
|
|
40
|
+
SpinnerColumn(),
|
|
41
|
+
TextColumn("[progress.description]{task.description}"),
|
|
42
|
+
console=console
|
|
43
|
+
) as progress:
|
|
44
|
+
task = progress.add_task("Creating utility agency...", total=None)
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
# Look up MCP server in registry
|
|
48
|
+
mcp_registry = MCPServerRegistry(mongodb_uri)
|
|
49
|
+
try:
|
|
50
|
+
mcp_data = await mcp_registry.get_mcp_server(mcp_name)
|
|
51
|
+
|
|
52
|
+
if not mcp_data:
|
|
53
|
+
console.print(f"ā MCP server '{mcp_name}' not found in registry", style="red")
|
|
54
|
+
return None, None
|
|
55
|
+
|
|
56
|
+
# Create MCPServer object from registry data
|
|
57
|
+
mcp_server = MCPServer(
|
|
58
|
+
id=str(mcp_data.get("_id", "")),
|
|
59
|
+
name=mcp_data["name"],
|
|
60
|
+
url=mcp_data["url"],
|
|
61
|
+
description=mcp_data["description"],
|
|
62
|
+
server_type=mcp_data.get("server_type", MCPServerType.STREAMABLE_HTTP),
|
|
63
|
+
capabilities=mcp_data.get("capabilities", []),
|
|
64
|
+
metadata=mcp_data.get("metadata", {})
|
|
65
|
+
)
|
|
66
|
+
finally:
|
|
67
|
+
mcp_registry.close()
|
|
68
|
+
|
|
69
|
+
# Create agency generator
|
|
70
|
+
generator = IATPServerAgentGenerator(output_base_dir=Path(output_dir))
|
|
71
|
+
|
|
72
|
+
# Generate the agency
|
|
73
|
+
agency = generator.generate_agent(
|
|
74
|
+
mcp_server=mcp_server,
|
|
75
|
+
agency_name=name,
|
|
76
|
+
agency_description=description,
|
|
77
|
+
use_simple_server=False # Use modular server for CLI
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
folder_path = agency.code_path
|
|
81
|
+
|
|
82
|
+
progress.update(task, description="Agency created successfully!")
|
|
83
|
+
|
|
84
|
+
console.print(f"\nā
Created utility agency: {agency.name}")
|
|
85
|
+
console.print(f" ID: {agency.id}")
|
|
86
|
+
console.print(f" Status: {agency.status}")
|
|
87
|
+
console.print(f" Folder: {folder_path}")
|
|
88
|
+
console.print(f" MCP Server: {mcp_server.name}")
|
|
89
|
+
console.print(f" Capabilities: {', '.join(agency.capabilities)}")
|
|
90
|
+
|
|
91
|
+
if deploy:
|
|
92
|
+
progress.update(task, description="Deploying agency to Docker...")
|
|
93
|
+
|
|
94
|
+
# Use the docker utilities to run the generated agency
|
|
95
|
+
runner = LocalDockerRunner()
|
|
96
|
+
deployment_info = await runner.run_agent_docker(
|
|
97
|
+
agent_path=Path(folder_path),
|
|
98
|
+
port=port or 8000,
|
|
99
|
+
detached=True
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
if deployment_info["success"]:
|
|
103
|
+
console.print(f"\nš Deployed agency:")
|
|
104
|
+
console.print(f" Base URL: {deployment_info['base_url']}")
|
|
105
|
+
console.print(f" IATP Endpoint: {deployment_info['iatp_endpoint']}")
|
|
106
|
+
console.print(f" Container: {deployment_info['container_name']}")
|
|
107
|
+
console.print(f" Port: {deployment_info['port']}")
|
|
108
|
+
console.print(f"\nš Useful commands:")
|
|
109
|
+
console.print(f" View logs: {deployment_info['logs_command']}")
|
|
110
|
+
console.print(f" Stop: {deployment_info['stop_command']}")
|
|
111
|
+
|
|
112
|
+
# Register the deployed agency if MongoDB is configured
|
|
113
|
+
if mongodb_uri:
|
|
114
|
+
registry = UtilityAgentRegistry(mongodb_uri)
|
|
115
|
+
try:
|
|
116
|
+
await registry.add_utility_agency(
|
|
117
|
+
agency=agency,
|
|
118
|
+
endpoint=deployment_info['iatp_endpoint'],
|
|
119
|
+
tags=["docker", "cli-deployed"]
|
|
120
|
+
)
|
|
121
|
+
console.print(f" ā
Registered in MongoDB")
|
|
122
|
+
finally:
|
|
123
|
+
registry.close()
|
|
124
|
+
else:
|
|
125
|
+
console.print(f"ā Deployment failed", style="red")
|
|
126
|
+
|
|
127
|
+
return agency, folder_path
|
|
128
|
+
|
|
129
|
+
except Exception as e:
|
|
130
|
+
console.print(f"ā Error creating agency: {e}", style="red")
|
|
131
|
+
raise
|
|
132
|
+
|
|
133
|
+
asyncio.run(_create())
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@app.command()
|
|
137
|
+
def register_mcp(
|
|
138
|
+
name: str = typer.Option(..., "--name", "-n", help="Name of the MCP server"),
|
|
139
|
+
url: str = typer.Option(..., "--url", "-u", help="URL of the MCP server"),
|
|
140
|
+
description: str = typer.Option(..., "--description", "-d", help="Description of the MCP server"),
|
|
141
|
+
server_type: str = typer.Option("streamable-http", "--type", "-t", help="Server type (streamable-http only)"),
|
|
142
|
+
capabilities: Optional[List[str]] = typer.Option(None, "--capability", "-c", help="Server capabilities"),
|
|
143
|
+
mongodb_uri: Optional[str] = typer.Option(None, "--mongodb-uri", help="MongoDB URI for registry")
|
|
144
|
+
):
|
|
145
|
+
"""Register an MCP server in the registry."""
|
|
146
|
+
async def _register():
|
|
147
|
+
registry = MCPServerRegistry(mongodb_uri)
|
|
148
|
+
|
|
149
|
+
try:
|
|
150
|
+
# Convert string to enum if necessary
|
|
151
|
+
if server_type == "streamable-http":
|
|
152
|
+
server_type_enum = MCPServerType.STREAMABLE_HTTP
|
|
153
|
+
else:
|
|
154
|
+
server_type_enum = server_type
|
|
155
|
+
|
|
156
|
+
server_id = await registry.add_mcp_server(
|
|
157
|
+
name=name,
|
|
158
|
+
url=url,
|
|
159
|
+
description=description,
|
|
160
|
+
server_type=server_type_enum,
|
|
161
|
+
capabilities=capabilities or []
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
console.print(f"ā
Registered MCP server '{name}' with ID: {server_id}")
|
|
165
|
+
|
|
166
|
+
finally:
|
|
167
|
+
registry.close()
|
|
168
|
+
|
|
169
|
+
asyncio.run(_register())
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
@app.command()
|
|
173
|
+
def list_agencies(
|
|
174
|
+
mongodb_uri: Optional[str] = typer.Option(None, "--mongodb-uri", help="MongoDB URI for registry"),
|
|
175
|
+
active_only: bool = typer.Option(True, "--active-only", help="Show only active agencies")
|
|
176
|
+
):
|
|
177
|
+
"""List all registered utility agencies."""
|
|
178
|
+
async def _list():
|
|
179
|
+
registry = UtilityAgentRegistry(mongodb_uri)
|
|
180
|
+
|
|
181
|
+
try:
|
|
182
|
+
agencies = await registry.query_agencies(active_only=active_only, limit=100)
|
|
183
|
+
|
|
184
|
+
if not agencies:
|
|
185
|
+
console.print("No agencies found.", style="yellow")
|
|
186
|
+
return
|
|
187
|
+
|
|
188
|
+
table = Table(title="Registered Utility Agencies")
|
|
189
|
+
table.add_column("Name", style="cyan")
|
|
190
|
+
table.add_column("ID", style="magenta")
|
|
191
|
+
table.add_column("Endpoint", style="green")
|
|
192
|
+
table.add_column("Capabilities", style="yellow")
|
|
193
|
+
table.add_column("Active", style="blue")
|
|
194
|
+
|
|
195
|
+
for agency in agencies:
|
|
196
|
+
table.add_row(
|
|
197
|
+
agency.name,
|
|
198
|
+
agency.agency_id[:8] + "...",
|
|
199
|
+
str(agency.endpoint),
|
|
200
|
+
", ".join(agency.capabilities[:3]) + ("..." if len(agency.capabilities) > 3 else ""),
|
|
201
|
+
"ā
" if agency.is_active else "ā"
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
console.print(table)
|
|
205
|
+
|
|
206
|
+
finally:
|
|
207
|
+
registry.close()
|
|
208
|
+
|
|
209
|
+
asyncio.run(_list())
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
@app.command()
|
|
213
|
+
def list_mcp_servers(
|
|
214
|
+
mongodb_uri: Optional[str] = typer.Option(None, "--mongodb-uri", help="MongoDB URI for registry"),
|
|
215
|
+
server_type: Optional[str] = typer.Option(None, "--type", "-t", help="Filter by server type")
|
|
216
|
+
):
|
|
217
|
+
"""List all registered MCP servers."""
|
|
218
|
+
async def _list():
|
|
219
|
+
registry = MCPServerRegistry(mongodb_uri)
|
|
220
|
+
|
|
221
|
+
try:
|
|
222
|
+
servers = await registry.query_mcp_servers(server_type=server_type)
|
|
223
|
+
|
|
224
|
+
if not servers:
|
|
225
|
+
console.print("No MCP servers found.", style="yellow")
|
|
226
|
+
return
|
|
227
|
+
|
|
228
|
+
table = Table(title="Registered MCP Servers")
|
|
229
|
+
table.add_column("Name", style="cyan")
|
|
230
|
+
table.add_column("URL", style="green")
|
|
231
|
+
table.add_column("Type", style="yellow")
|
|
232
|
+
table.add_column("Description", style="white")
|
|
233
|
+
table.add_column("Capabilities", style="magenta")
|
|
234
|
+
|
|
235
|
+
for server in servers:
|
|
236
|
+
table.add_row(
|
|
237
|
+
server["name"],
|
|
238
|
+
server["url"],
|
|
239
|
+
server.get("server_type", "streamable-http"),
|
|
240
|
+
server["description"][:40] + "..." if len(server["description"]) > 40 else server["description"],
|
|
241
|
+
", ".join(server.get("capabilities", [])[:3]) + ("..." if len(server.get("capabilities", [])) > 3 else "")
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
console.print(table)
|
|
245
|
+
|
|
246
|
+
finally:
|
|
247
|
+
registry.close()
|
|
248
|
+
|
|
249
|
+
asyncio.run(_list())
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
@app.command()
|
|
253
|
+
def search_agencies(
|
|
254
|
+
query: Optional[str] = typer.Argument(None, help="Search query"),
|
|
255
|
+
tags: Optional[List[str]] = typer.Option(None, "--tag", "-t", help="Filter by tags"),
|
|
256
|
+
capabilities: Optional[List[str]] = typer.Option(None, "--capability", "-c", help="Filter by capabilities"),
|
|
257
|
+
mongodb_uri: Optional[str] = typer.Option(None, "--mongodb-uri", help="MongoDB URI for registry"),
|
|
258
|
+
limit: int = typer.Option(10, "--limit", "-l", help="Maximum number of results")
|
|
259
|
+
):
|
|
260
|
+
"""Search for utility agencies."""
|
|
261
|
+
async def _search():
|
|
262
|
+
registry = UtilityAgentRegistry(mongodb_uri)
|
|
263
|
+
|
|
264
|
+
try:
|
|
265
|
+
agencies = await registry.query_agencies(
|
|
266
|
+
query=query,
|
|
267
|
+
tags=tags,
|
|
268
|
+
capabilities=capabilities,
|
|
269
|
+
active_only=True,
|
|
270
|
+
limit=limit
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
if not agencies:
|
|
274
|
+
console.print("No agencies found matching criteria.", style="yellow")
|
|
275
|
+
return
|
|
276
|
+
|
|
277
|
+
table = Table(title=f"Search Results ({len(agencies)} found)")
|
|
278
|
+
table.add_column("Name", style="cyan")
|
|
279
|
+
table.add_column("Description", style="white")
|
|
280
|
+
table.add_column("Capabilities", style="yellow")
|
|
281
|
+
table.add_column("Tags", style="green")
|
|
282
|
+
|
|
283
|
+
for agency in agencies:
|
|
284
|
+
table.add_row(
|
|
285
|
+
agency.name,
|
|
286
|
+
agency.description[:50] + "..." if len(agency.description) > 50 else agency.description,
|
|
287
|
+
", ".join(agency.capabilities[:3]) + ("..." if len(agency.capabilities) > 3 else ""),
|
|
288
|
+
", ".join(agency.tags[:3]) + ("..." if len(agency.tags) > 3 else "")
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
console.print(table)
|
|
292
|
+
|
|
293
|
+
finally:
|
|
294
|
+
registry.close()
|
|
295
|
+
|
|
296
|
+
asyncio.run(_search())
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
@app.command()
|
|
300
|
+
def deploy(
|
|
301
|
+
agency_path: Path = typer.Argument(..., help="Path to generated agency directory"),
|
|
302
|
+
port: Optional[int] = typer.Option(None, "--port", "-p", help="Port to deploy on"),
|
|
303
|
+
mongodb_uri: Optional[str] = typer.Option(None, "--mongodb-uri", help="MongoDB URI for registry"),
|
|
304
|
+
use_script: bool = typer.Option(False, "--use-script", help="Use the run_local_docker.sh script")
|
|
305
|
+
):
|
|
306
|
+
"""Deploy a utility agency from a generated directory."""
|
|
307
|
+
async def _deploy():
|
|
308
|
+
if not agency_path.exists():
|
|
309
|
+
console.print(f"ā Directory not found: {agency_path}", style="red")
|
|
310
|
+
return
|
|
311
|
+
|
|
312
|
+
# Check if it's a valid agency directory
|
|
313
|
+
required_files = ["Dockerfile", "pyproject.toml"]
|
|
314
|
+
missing_files = [f for f in required_files if not (agency_path / f).exists()]
|
|
315
|
+
if missing_files:
|
|
316
|
+
console.print(f"ā Invalid agency directory. Missing files: {', '.join(missing_files)}", style="red")
|
|
317
|
+
return
|
|
318
|
+
|
|
319
|
+
with Progress(
|
|
320
|
+
SpinnerColumn(),
|
|
321
|
+
TextColumn("[progress.description]{task.description}"),
|
|
322
|
+
console=console
|
|
323
|
+
) as progress:
|
|
324
|
+
task = progress.add_task("Deploying agency...", total=None)
|
|
325
|
+
|
|
326
|
+
try:
|
|
327
|
+
if use_script:
|
|
328
|
+
# Use the generated run_local_docker.sh script
|
|
329
|
+
script_path = agency_path / "run_local_docker.sh"
|
|
330
|
+
if not script_path.exists():
|
|
331
|
+
console.print(f"ā run_local_docker.sh not found in {agency_path}", style="red")
|
|
332
|
+
return
|
|
333
|
+
|
|
334
|
+
progress.update(task, description="Running deployment script...")
|
|
335
|
+
use_run_local_docker_script(str(agency_path))
|
|
336
|
+
|
|
337
|
+
console.print(f"\nš Agency deployed using run_local_docker.sh")
|
|
338
|
+
console.print(f" Check the script output for connection details")
|
|
339
|
+
else:
|
|
340
|
+
# Use LocalDockerRunner
|
|
341
|
+
runner = LocalDockerRunner()
|
|
342
|
+
deployment_info = await runner.run_agent_docker(
|
|
343
|
+
agent_path=agency_path,
|
|
344
|
+
port=port or 8000,
|
|
345
|
+
detached=True
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
if deployment_info["success"]:
|
|
349
|
+
console.print(f"\nš Deployed agency from: {agency_path}")
|
|
350
|
+
console.print(f" Base URL: {deployment_info['base_url']}")
|
|
351
|
+
console.print(f" IATP Endpoint: {deployment_info['iatp_endpoint']}")
|
|
352
|
+
console.print(f" Container: {deployment_info['container_name']}")
|
|
353
|
+
console.print(f" Port: {deployment_info['port']}")
|
|
354
|
+
console.print(f"\nš Useful commands:")
|
|
355
|
+
console.print(f" View logs: {deployment_info['logs_command']}")
|
|
356
|
+
console.print(f" Stop: {deployment_info['stop_command']}")
|
|
357
|
+
|
|
358
|
+
# If MongoDB URI is provided and agent_config.json exists, register it
|
|
359
|
+
if mongodb_uri and (agency_path / "agent_config.json").exists():
|
|
360
|
+
with open(agency_path / "agent_config.json", 'r') as f:
|
|
361
|
+
agency_data = json.load(f)
|
|
362
|
+
|
|
363
|
+
agency = UtilityAgent(**agency_data)
|
|
364
|
+
|
|
365
|
+
registry = UtilityAgentRegistry(mongodb_uri)
|
|
366
|
+
try:
|
|
367
|
+
await registry.add_utility_agency(
|
|
368
|
+
agency=agency,
|
|
369
|
+
endpoint=deployment_info['iatp_endpoint'],
|
|
370
|
+
tags=["docker", "cli-deployed"]
|
|
371
|
+
)
|
|
372
|
+
console.print(f" ā
Registered in MongoDB")
|
|
373
|
+
finally:
|
|
374
|
+
registry.close()
|
|
375
|
+
else:
|
|
376
|
+
console.print(f"ā Deployment failed", style="red")
|
|
377
|
+
|
|
378
|
+
except Exception as e:
|
|
379
|
+
console.print(f"ā Deployment failed: {e}", style="red")
|
|
380
|
+
raise
|
|
381
|
+
|
|
382
|
+
asyncio.run(_deploy())
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
@app.command()
|
|
386
|
+
def find_tools(
|
|
387
|
+
query: Optional[str] = typer.Argument(None, help="Search query for tools"),
|
|
388
|
+
tags: Optional[List[str]] = typer.Option(None, "--tag", "-t", help="Filter by tags"),
|
|
389
|
+
capabilities: Optional[List[str]] = typer.Option(None, "--capability", "-c", help="Filter by capabilities"),
|
|
390
|
+
mongodb_uri: Optional[str] = typer.Option(None, "--mongodb-uri", help="MongoDB URI for registry"),
|
|
391
|
+
output_file: Optional[Path] = typer.Option(None, "--output", "-o", help="Save tools configuration to file")
|
|
392
|
+
):
|
|
393
|
+
"""Find utility agency tools for use in CrewAI."""
|
|
394
|
+
tools = create_utility_agency_tools(
|
|
395
|
+
mongodb_uri=mongodb_uri,
|
|
396
|
+
query=query,
|
|
397
|
+
tags=tags,
|
|
398
|
+
capabilities=capabilities
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
if not tools:
|
|
402
|
+
console.print("No tools found matching criteria.", style="yellow")
|
|
403
|
+
return
|
|
404
|
+
|
|
405
|
+
table = Table(title=f"Available Tools ({len(tools)} found)")
|
|
406
|
+
table.add_column("Tool Name", style="cyan")
|
|
407
|
+
table.add_column("Description", style="white")
|
|
408
|
+
table.add_column("Endpoint", style="green")
|
|
409
|
+
|
|
410
|
+
tools_config = []
|
|
411
|
+
for tool in tools:
|
|
412
|
+
table.add_row(
|
|
413
|
+
tool.name,
|
|
414
|
+
tool.description[:60] + "..." if len(tool.description) > 60 else tool.description,
|
|
415
|
+
tool.endpoint
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
tools_config.append({
|
|
419
|
+
"name": tool.name,
|
|
420
|
+
"description": tool.description,
|
|
421
|
+
"endpoint": tool.endpoint,
|
|
422
|
+
"agency_id": tool.agency_id,
|
|
423
|
+
"capabilities": tool.capabilities
|
|
424
|
+
})
|
|
425
|
+
|
|
426
|
+
console.print(table)
|
|
427
|
+
|
|
428
|
+
if output_file:
|
|
429
|
+
with open(output_file, 'w') as f:
|
|
430
|
+
json.dump(tools_config, f, indent=2)
|
|
431
|
+
console.print(f"\nš¾ Tools configuration saved to: {output_file}", style="green")
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
@app.command()
|
|
435
|
+
def example_crew():
|
|
436
|
+
"""Show an example of how to use utility agencies in a CrewAI crew."""
|
|
437
|
+
example_code = '''
|
|
438
|
+
# Example: Using utility agencies in a CrewAI crew
|
|
439
|
+
|
|
440
|
+
from crewai import Agent, Crew, Task
|
|
441
|
+
from iatp import create_utility_agency_tools
|
|
442
|
+
|
|
443
|
+
# Find and create tools from utility agencies
|
|
444
|
+
tools = create_utility_agency_tools(
|
|
445
|
+
query="weather data analysis", # Search for relevant agencies
|
|
446
|
+
tags=["weather", "api"], # Filter by tags
|
|
447
|
+
capabilities=["forecast"] # Filter by capabilities
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
# Create an agent with utility agency tools
|
|
451
|
+
analyst = Agent(
|
|
452
|
+
role="Data Analyst",
|
|
453
|
+
goal="Analyze weather patterns and provide insights",
|
|
454
|
+
backstory="You are an expert at analyzing weather data and trends.",
|
|
455
|
+
tools=tools, # Use the utility agency tools
|
|
456
|
+
allow_delegation=False,
|
|
457
|
+
verbose=True
|
|
458
|
+
)
|
|
459
|
+
|
|
460
|
+
# Create a task
|
|
461
|
+
analysis_task = Task(
|
|
462
|
+
description="Analyze the weather forecast for New York City for the next week",
|
|
463
|
+
expected_output="A detailed analysis of weather patterns and recommendations",
|
|
464
|
+
agent=analyst
|
|
465
|
+
)
|
|
466
|
+
|
|
467
|
+
# Create and run the crew
|
|
468
|
+
crew = Crew(
|
|
469
|
+
agents=[analyst],
|
|
470
|
+
tasks=[analysis_task],
|
|
471
|
+
verbose=True
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
result = crew.kickoff()
|
|
475
|
+
print(result)
|
|
476
|
+
'''
|
|
477
|
+
|
|
478
|
+
console.print("š Example: Using Utility Agencies in CrewAI\n", style="bold cyan")
|
|
479
|
+
console.print(example_code, style="cyan")
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
if __name__ == "__main__":
|
|
483
|
+
app()
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""IATP client module for A2A integration."""
|
|
2
|
+
|
|
3
|
+
from .a2a_client import UtilityAgencyTool, create_utility_agency_tools
|
|
4
|
+
from .crewai_a2a_tools import A2AToolSchema
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"UtilityAgencyTool",
|
|
8
|
+
"create_utility_agency_tools",
|
|
9
|
+
"A2AToolSchema",
|
|
10
|
+
]
|