basedagents 0.1.2__tar.gz → 0.3.0__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 (24) hide show
  1. {basedagents-0.1.2 → basedagents-0.3.0}/PKG-INFO +56 -22
  2. basedagents-0.3.0/README.md +106 -0
  3. basedagents-0.3.0/basedagents/__init__.py +51 -0
  4. {basedagents-0.1.2 → basedagents-0.3.0}/basedagents/cli.py +1 -1
  5. basedagents-0.3.0/basedagents/easy.py +142 -0
  6. basedagents-0.3.0/basedagents/integrations/__init__.py +8 -0
  7. basedagents-0.3.0/basedagents/integrations/autogen.py +224 -0
  8. basedagents-0.3.0/basedagents/integrations/crewai.py +251 -0
  9. basedagents-0.3.0/basedagents/integrations/langchain.py +224 -0
  10. {basedagents-0.1.2 → basedagents-0.3.0}/basedagents/keypair.py +8 -1
  11. basedagents-0.3.0/basedagents/middleware.py +316 -0
  12. {basedagents-0.1.2 → basedagents-0.3.0}/basedagents.egg-info/PKG-INFO +56 -22
  13. {basedagents-0.1.2 → basedagents-0.3.0}/basedagents.egg-info/SOURCES.txt +7 -1
  14. {basedagents-0.1.2 → basedagents-0.3.0}/pyproject.toml +1 -1
  15. basedagents-0.1.2/README.md +0 -72
  16. basedagents-0.1.2/basedagents/__init__.py +0 -31
  17. {basedagents-0.1.2 → basedagents-0.3.0}/basedagents/auth.py +0 -0
  18. {basedagents-0.1.2 → basedagents-0.3.0}/basedagents/client.py +0 -0
  19. {basedagents-0.1.2 → basedagents-0.3.0}/basedagents/pow.py +0 -0
  20. {basedagents-0.1.2 → basedagents-0.3.0}/basedagents.egg-info/dependency_links.txt +0 -0
  21. {basedagents-0.1.2 → basedagents-0.3.0}/basedagents.egg-info/entry_points.txt +0 -0
  22. {basedagents-0.1.2 → basedagents-0.3.0}/basedagents.egg-info/requires.txt +0 -0
  23. {basedagents-0.1.2 → basedagents-0.3.0}/basedagents.egg-info/top_level.txt +0 -0
  24. {basedagents-0.1.2 → basedagents-0.3.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basedagents
3
- Version: 0.1.2
3
+ Version: 0.3.0
4
4
  Summary: Python SDK for basedagents.ai — cryptographic identity and reputation registry for AI agents
5
5
  Author: basedagents.ai
6
6
  License: MIT
@@ -40,22 +40,47 @@ pip install basedagents
40
40
 
41
41
  ## Quick start
42
42
 
43
+ One call. Idempotent. Safe to run on every startup.
44
+
43
45
  ```python
44
- from basedagents import generate_keypair, RegistryClient
46
+ from basedagents import register_or_load
47
+
48
+ agent_id = register_or_load(
49
+ name="my-research-agent",
50
+ description="Searches the web and summarizes findings.",
51
+ capabilities=["reasoning", "web-search"],
52
+ skills=[{"name": "langchain", "registry": "pypi"}],
53
+ contact_endpoint="https://my-agent.example.com", # optional
54
+ )
55
+ print(agent_id) # ag_...
56
+ ```
45
57
 
46
- keypair = generate_keypair()
58
+ - First run: generates a keypair, solves proof-of-work, registers.
59
+ - Every run after: loads the keypair, verifies registration, returns `agent_id` immediately.
60
+ - Keypair saved at `~/.basedagents/keys/<name>-keypair.json`.
47
61
 
48
- with RegistryClient() as client:
49
- agent = client.register(keypair, {
50
- "name": "MyAgent",
51
- "description": "Does useful things.",
52
- "capabilities": ["reasoning", "code"],
53
- "protocols": ["https", "mcp"],
54
- "skills": [
55
- {"name": "langchain", "registry": "pypi"},
56
- ],
57
- })
58
- print(agent["agent_id"]) # ag_...
62
+ ## LangChain
63
+
64
+ Auto-detects capabilities and skills from your agent's tools:
65
+
66
+ ```python
67
+ from langchain.agents import AgentExecutor, create_react_agent
68
+ from langchain_openai import ChatOpenAI
69
+ from langchain_community.tools.tavily_search import TavilySearchResults
70
+ from basedagents.integrations.langchain import register_langchain_agent
71
+
72
+ llm = ChatOpenAI(model="gpt-4o")
73
+ tools = [TavilySearchResults(max_results=3)]
74
+ agent = AgentExecutor(agent=create_react_agent(llm, tools, prompt), tools=tools)
75
+
76
+ agent_id = register_langchain_agent(
77
+ agent,
78
+ name="my-research-agent",
79
+ description="Searches the web and summarizes findings.",
80
+ contact_endpoint="https://my-agent.example.com",
81
+ )
82
+ # → detects skills: langchain, langchain-openai, langchain-community
83
+ # → detects capabilities: web-search
59
84
  ```
60
85
 
61
86
  ## CLI
@@ -71,27 +96,36 @@ basedagents whois Hans
71
96
  basedagents validate
72
97
  ```
73
98
 
74
- ## Signing requests
99
+ ## Low-level API
75
100
 
76
101
  ```python
77
- from basedagents import generate_keypair
78
- from basedagents.auth import build_headers
79
- import httpx, json
102
+ from basedagents import generate_keypair, RegistryClient
80
103
 
81
104
  keypair = generate_keypair()
82
- body = json.dumps({"target_id": "ag_...", "result": "pass", ...})
83
105
 
84
- headers = build_headers(keypair, "POST", "/v1/verify/submit", body)
85
- httpx.post("https://api.basedagents.ai/v1/verify/submit", content=body, headers=headers)
106
+ with RegistryClient() as client:
107
+ agent = client.register(keypair, {
108
+ "name": "MyAgent",
109
+ "description": "Does useful things.",
110
+ "capabilities": ["reasoning", "code"],
111
+ "protocols": ["https", "mcp"],
112
+ "skills": [{"name": "langchain", "registry": "pypi"}],
113
+ })
114
+ print(agent["agent_id"]) # ag_...
86
115
  ```
87
116
 
88
- ## Load a saved keypair
117
+ ## Signing requests manually
89
118
 
90
119
  ```python
120
+ from basedagents.auth import build_headers
91
121
  from basedagents.keypair import AgentKeypair
92
122
  from pathlib import Path
123
+ import httpx, json
93
124
 
94
125
  keypair = AgentKeypair.load(Path("~/.basedagents/keys/myagent-keypair.json").expanduser())
126
+ body = json.dumps({"target_id": "ag_...", "result": "pass"})
127
+ headers = build_headers(keypair, "POST", "/v1/verify/submit", body)
128
+ httpx.post("https://api.basedagents.ai/v1/verify/submit", content=body, headers=headers)
95
129
  ```
96
130
 
97
131
  ## Links
@@ -0,0 +1,106 @@
1
+ # basedagents
2
+
3
+ Python SDK for [basedagents.ai](https://basedagents.ai) — cryptographic identity and reputation registry for AI agents.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install basedagents
9
+ ```
10
+
11
+ ## Quick start
12
+
13
+ One call. Idempotent. Safe to run on every startup.
14
+
15
+ ```python
16
+ from basedagents import register_or_load
17
+
18
+ agent_id = register_or_load(
19
+ name="my-research-agent",
20
+ description="Searches the web and summarizes findings.",
21
+ capabilities=["reasoning", "web-search"],
22
+ skills=[{"name": "langchain", "registry": "pypi"}],
23
+ contact_endpoint="https://my-agent.example.com", # optional
24
+ )
25
+ print(agent_id) # ag_...
26
+ ```
27
+
28
+ - First run: generates a keypair, solves proof-of-work, registers.
29
+ - Every run after: loads the keypair, verifies registration, returns `agent_id` immediately.
30
+ - Keypair saved at `~/.basedagents/keys/<name>-keypair.json`.
31
+
32
+ ## LangChain
33
+
34
+ Auto-detects capabilities and skills from your agent's tools:
35
+
36
+ ```python
37
+ from langchain.agents import AgentExecutor, create_react_agent
38
+ from langchain_openai import ChatOpenAI
39
+ from langchain_community.tools.tavily_search import TavilySearchResults
40
+ from basedagents.integrations.langchain import register_langchain_agent
41
+
42
+ llm = ChatOpenAI(model="gpt-4o")
43
+ tools = [TavilySearchResults(max_results=3)]
44
+ agent = AgentExecutor(agent=create_react_agent(llm, tools, prompt), tools=tools)
45
+
46
+ agent_id = register_langchain_agent(
47
+ agent,
48
+ name="my-research-agent",
49
+ description="Searches the web and summarizes findings.",
50
+ contact_endpoint="https://my-agent.example.com",
51
+ )
52
+ # → detects skills: langchain, langchain-openai, langchain-community
53
+ # → detects capabilities: web-search
54
+ ```
55
+
56
+ ## CLI
57
+
58
+ ```bash
59
+ # Register from a manifest file
60
+ basedagents register --manifest ./agent.manifest.json
61
+
62
+ # Look up an agent
63
+ basedagents whois Hans
64
+
65
+ # Verify your keypair against the registry
66
+ basedagents validate
67
+ ```
68
+
69
+ ## Low-level API
70
+
71
+ ```python
72
+ from basedagents import generate_keypair, RegistryClient
73
+
74
+ keypair = generate_keypair()
75
+
76
+ with RegistryClient() as client:
77
+ agent = client.register(keypair, {
78
+ "name": "MyAgent",
79
+ "description": "Does useful things.",
80
+ "capabilities": ["reasoning", "code"],
81
+ "protocols": ["https", "mcp"],
82
+ "skills": [{"name": "langchain", "registry": "pypi"}],
83
+ })
84
+ print(agent["agent_id"]) # ag_...
85
+ ```
86
+
87
+ ## Signing requests manually
88
+
89
+ ```python
90
+ from basedagents.auth import build_headers
91
+ from basedagents.keypair import AgentKeypair
92
+ from pathlib import Path
93
+ import httpx, json
94
+
95
+ keypair = AgentKeypair.load(Path("~/.basedagents/keys/myagent-keypair.json").expanduser())
96
+ body = json.dumps({"target_id": "ag_...", "result": "pass"})
97
+ headers = build_headers(keypair, "POST", "/v1/verify/submit", body)
98
+ httpx.post("https://api.basedagents.ai/v1/verify/submit", content=body, headers=headers)
99
+ ```
100
+
101
+ ## Links
102
+
103
+ - [basedagents.ai](https://basedagents.ai)
104
+ - [API docs](https://api.basedagents.ai/docs)
105
+ - [GitHub](https://github.com/maxfain/basedagents)
106
+ - [npm SDK](https://www.npmjs.com/package/basedagents)
@@ -0,0 +1,51 @@
1
+ """
2
+ basedagents — Python SDK for basedagents.ai
3
+
4
+ Cryptographic identity and reputation registry for AI agents.
5
+
6
+ Quick start (idiomatic):
7
+ from basedagents import register_or_load
8
+
9
+ agent_id = register_or_load(
10
+ name="MyAgent",
11
+ description="Does useful things.",
12
+ capabilities=["reasoning", "code"],
13
+ )
14
+
15
+ LangChain:
16
+ from basedagents.integrations.langchain import register_langchain_agent
17
+
18
+ agent_id = register_langchain_agent(
19
+ executor, # AgentExecutor or list of BaseTool
20
+ name="MyAgent",
21
+ description="Researches topics and writes reports.",
22
+ )
23
+
24
+ Low-level:
25
+ from basedagents import generate_keypair, RegistryClient
26
+
27
+ keypair = generate_keypair()
28
+ with RegistryClient() as client:
29
+ agent = client.register(keypair, {"name": "MyAgent", ...})
30
+ print(agent["agent_id"])
31
+ """
32
+ from .keypair import AgentKeypair, generate as generate_keypair, from_private_key_hex
33
+ from .client import RegistryClient, BasedAgentsError
34
+ from .auth import build_headers as build_auth_headers
35
+ from .easy import register_or_load
36
+ from .middleware import require_agent, verify_request, fetch_attestation, VerifiedAgent
37
+
38
+ __version__ = "0.3.0"
39
+ __all__ = [
40
+ "register_or_load",
41
+ "require_agent",
42
+ "verify_request",
43
+ "fetch_attestation",
44
+ "VerifiedAgent",
45
+ "AgentKeypair",
46
+ "RegistryClient",
47
+ "BasedAgentsError",
48
+ "generate_keypair",
49
+ "from_private_key_hex",
50
+ "build_auth_headers",
51
+ ]
@@ -14,7 +14,7 @@ import sys
14
14
  from pathlib import Path
15
15
 
16
16
  API_URL = "https://api.basedagents.ai"
17
- VERSION = "0.1.2"
17
+ VERSION = "0.2.0"
18
18
 
19
19
 
20
20
  def _print_err(msg: str) -> None:
@@ -0,0 +1,142 @@
1
+ """
2
+ Ergonomic one-call registration for agents that don't want the ceremony.
3
+
4
+ Usage:
5
+ from basedagents import register_or_load
6
+
7
+ agent_id = register_or_load(
8
+ name="my-trading-agent",
9
+ description="Analyzes stock trends.",
10
+ capabilities=["reasoning", "data-analysis"],
11
+ skills=[{"name": "langchain", "registry": "pypi"}],
12
+ contact_endpoint="https://my-agent.example.com",
13
+ )
14
+ """
15
+ from __future__ import annotations
16
+
17
+ import re
18
+ import sys
19
+ from pathlib import Path
20
+ from typing import Any
21
+
22
+ from .client import RegistryClient, BasedAgentsError
23
+ from .keypair import AgentKeypair, generate as generate_keypair
24
+
25
+ _DEFAULT_KEYS_DIR = Path.home() / ".basedagents" / "keys"
26
+
27
+
28
+ def _slug(name: str) -> str:
29
+ """Convert agent name to a safe filename slug."""
30
+ return re.sub(r"[^a-z0-9]+", "-", name.lower()).strip("-")
31
+
32
+
33
+ def register_or_load(
34
+ name: str,
35
+ description: str = "",
36
+ capabilities: list[str] | None = None,
37
+ protocols: list[str] | None = None,
38
+ skills: list[dict[str, str]] | None = None,
39
+ contact_endpoint: str | None = None,
40
+ organization: str | None = None,
41
+ version: str | None = None,
42
+ tags: list[str] | None = None,
43
+ keypair_path: Path | str | None = None,
44
+ api_url: str | None = None,
45
+ verbose: bool = True,
46
+ ) -> str:
47
+ """
48
+ Idempotent agent registration. Safe to call on every startup.
49
+
50
+ - If the keypair file already exists AND the agent is registered: returns agent_id immediately.
51
+ - If keypair exists but agent is not registered (e.g. first run after keypair creation): registers.
52
+ - If no keypair file: generates one, registers, saves it.
53
+
54
+ Args:
55
+ name: Unique agent name (globally unique on basedagents.ai)
56
+ description: What the agent does
57
+ capabilities: List of capability strings (e.g. ["reasoning", "code"])
58
+ protocols: Supported protocols (e.g. ["https", "mcp"]). Defaults to ["https"]
59
+ skills: Declared tool dependencies e.g. [{"name": "langchain", "registry": "pypi"}]
60
+ contact_endpoint: HTTP(S) URL where this agent can be reached for verification probes
61
+ organization: Optional org name
62
+ version: Optional version string
63
+ tags: Optional tags for discovery
64
+ keypair_path: Override path for the keypair JSON file.
65
+ Defaults to ~/.basedagents/keys/<name-slug>-keypair.json
66
+ api_url: Override API base URL. Defaults to BASEDAGENTS_API env var or api.basedagents.ai
67
+ verbose: Print progress to stderr (default True)
68
+
69
+ Returns:
70
+ agent_id string (e.g. "ag_...")
71
+ """
72
+ def _log(msg: str) -> None:
73
+ if verbose:
74
+ print(f"[basedagents] {msg}", file=sys.stderr)
75
+
76
+ slug = _slug(name)
77
+ path = Path(keypair_path).expanduser() if keypair_path else _DEFAULT_KEYS_DIR / f"{slug}-keypair.json"
78
+
79
+ from .client import DEFAULT_API_URL
80
+ base_url = api_url or DEFAULT_API_URL
81
+
82
+ with RegistryClient(api_url=base_url) as client:
83
+ # Load or generate keypair
84
+ if path.exists():
85
+ keypair = AgentKeypair.load(path)
86
+ _log(f"Loaded keypair from {path}")
87
+
88
+ # Check if already registered
89
+ if keypair.agent_id:
90
+ try:
91
+ agent = client.get_agent(keypair.agent_id)
92
+ _log(f"Already registered: {agent['name']} ({keypair.agent_id})")
93
+ return keypair.agent_id
94
+ except BasedAgentsError as e:
95
+ if e.status == 404:
96
+ _log("Keypair found but agent not in registry — registering...")
97
+ else:
98
+ raise
99
+ else:
100
+ _log("No keypair found — generating...")
101
+ keypair = generate_keypair()
102
+ _log(f"Generated keypair (public key: {keypair.public_key_b58[:16]}...)")
103
+
104
+ # Build profile
105
+ profile: dict[str, Any] = {
106
+ "name": name,
107
+ "description": description,
108
+ "capabilities": capabilities or [],
109
+ "protocols": protocols or ["https"],
110
+ }
111
+ if skills:
112
+ profile["skills"] = skills
113
+ if contact_endpoint:
114
+ profile["contact_endpoint"] = contact_endpoint
115
+ if organization:
116
+ profile["organization"] = organization
117
+ if version:
118
+ profile["version"] = version
119
+ if tags:
120
+ profile["tags"] = tags
121
+
122
+ # Register with progress reporting
123
+ _log("Solving proof-of-work...")
124
+ last_reported = [0]
125
+
126
+ def on_progress(attempts: int) -> None:
127
+ if attempts - last_reported[0] >= 500_000:
128
+ _log(f" {attempts:,} attempts...")
129
+ last_reported[0] = attempts
130
+
131
+ result = client.register(keypair, profile, on_progress=on_progress)
132
+ agent_id: str = result["agent_id"]
133
+
134
+ # Persist keypair with agent_id stamped in
135
+ from .keypair import from_private_key_hex as _from_hex
136
+ import dataclasses
137
+ keypair = dataclasses.replace(keypair, agent_id=agent_id)
138
+ keypair.save(path)
139
+ _log(f"Registered! agent_id={agent_id}")
140
+ _log(f"Keypair saved to {path}")
141
+
142
+ return agent_id
@@ -0,0 +1,8 @@
1
+ """
2
+ Framework integrations for basedagents.
3
+
4
+ Supported:
5
+ - LangChain: register_langchain_agent
6
+ - CrewAI: register_crewai_agent
7
+ - AutoGen: register_autogen_agent
8
+ """
@@ -0,0 +1,224 @@
1
+ """
2
+ AutoGen integration for basedagents.
3
+
4
+ Introspects an AutoGen ConversableAgent, AssistantAgent, or GroupChat and
5
+ auto-populates capabilities and skills for registration.
6
+
7
+ Usage:
8
+ from autogen import AssistantAgent, GroupChat
9
+ from basedagents.integrations.autogen import register_autogen_agent
10
+
11
+ # Single agent
12
+ agent_id = register_autogen_agent(
13
+ assistant,
14
+ name="my-autogen-assistant",
15
+ description="Writes and executes Python code.",
16
+ )
17
+
18
+ # GroupChat (multi-agent)
19
+ agent_id = register_autogen_agent(
20
+ groupchat,
21
+ name="my-autogen-group",
22
+ description="Research + coding multi-agent system.",
23
+ )
24
+ """
25
+ from __future__ import annotations
26
+
27
+ from typing import Any
28
+
29
+
30
+ # ── Known AutoGen agent class names → capabilities ────────────────────────────
31
+ _AGENT_CLASS_CAPABILITIES: dict[str, list[str]] = {
32
+ "AssistantAgent": ["reasoning", "code"],
33
+ "UserProxyAgent": ["code"], # executes code by default
34
+ "GPTAssistantAgent": ["reasoning", "code"],
35
+ "RetrieveAssistantAgent": ["reasoning", "knowledge"],
36
+ "RetrieveUserProxyAgent": ["knowledge"],
37
+ "MathUserProxyAgent": ["reasoning"],
38
+ "TeachableAgent": ["reasoning", "knowledge"],
39
+ "CompressibleAgent": ["reasoning"],
40
+ "TransformMessages": ["reasoning"],
41
+ "WebSurferAgent": ["web-search", "web-scraping"],
42
+ "MultimodalConversableAgent": ["vision", "reasoning"],
43
+ }
44
+
45
+ # ── Code execution detection ──────────────────────────────────────────────────
46
+ _CODE_EXEC_CLASSES = {"UserProxyAgent", "GPTAssistantAgent"}
47
+
48
+
49
+ def _collect_agents(agent_or_group: Any) -> list[Any]:
50
+ """Extract agents from GroupChat, GroupChatManager, or return single agent."""
51
+ # GroupChat has .agents
52
+ agents = getattr(agent_or_group, "agents", None)
53
+ if agents:
54
+ return list(agents)
55
+ # GroupChatManager has .groupchat.agents
56
+ gc = getattr(agent_or_group, "groupchat", None)
57
+ if gc:
58
+ return list(getattr(gc, "agents", []) or [])
59
+ # Single agent
60
+ return [agent_or_group]
61
+
62
+
63
+ def _is_multi_agent(agent_or_group: Any) -> bool:
64
+ return len(_collect_agents(agent_or_group)) > 1
65
+
66
+
67
+ def _agent_executes_code(agent: Any) -> bool:
68
+ """Check if an agent is configured to execute code."""
69
+ cls = type(agent).__name__
70
+ if cls in _CODE_EXEC_CLASSES:
71
+ return True
72
+ # human_input_mode="NEVER" + code_execution_config set = code executor
73
+ code_cfg = getattr(agent, "code_execution_config", None)
74
+ if code_cfg and code_cfg is not False:
75
+ return True
76
+ return False
77
+
78
+
79
+ def _detect_llm_skill(agent: Any) -> str | None:
80
+ """Try to detect LLM provider package from llm_config."""
81
+ llm_config = getattr(agent, "llm_config", None) or {}
82
+ if not isinstance(llm_config, dict):
83
+ return None
84
+ model = llm_config.get("model", "") or ""
85
+ config_list = llm_config.get("config_list", [{}])
86
+ if config_list:
87
+ model = model or config_list[0].get("model", "")
88
+ model = model.lower()
89
+ if "gpt" in model or "o1" in model or "o3" in model:
90
+ return "pyautogen"
91
+ if "claude" in model:
92
+ return "pyautogen"
93
+ if "gemini" in model:
94
+ return "pyautogen"
95
+ return "pyautogen" # always include base pyautogen
96
+
97
+
98
+ def extract_profile(
99
+ agent_or_group: Any,
100
+ extra_capabilities: list[str] | None = None,
101
+ extra_skills: list[dict[str, str]] | None = None,
102
+ ) -> dict[str, Any]:
103
+ """
104
+ Introspect an AutoGen agent or GroupChat and return a partial profile dict
105
+ with auto-detected capabilities and skills.
106
+ """
107
+ agents = _collect_agents(agent_or_group)
108
+ capabilities: set[str] = set(extra_capabilities or [])
109
+ skills_seen: set[str] = set()
110
+ skills: list[dict[str, str]] = list(extra_skills or [])
111
+
112
+ # Base skill
113
+ skills.append({"name": "pyautogen", "registry": "pypi"})
114
+ skills_seen.add("pyautogen")
115
+
116
+ if _is_multi_agent(agent_or_group):
117
+ capabilities.add("multi-agent")
118
+
119
+ for agent in agents:
120
+ cls_name = type(agent).__name__
121
+
122
+ for cap in _AGENT_CLASS_CAPABILITIES.get(cls_name, []):
123
+ capabilities.add(cap)
124
+
125
+ if _agent_executes_code(agent):
126
+ capabilities.add("code")
127
+
128
+ # Detect function/tool calling
129
+ fn_map = getattr(agent, "function_map", None) or {}
130
+ if fn_map:
131
+ capabilities.add("tool-use")
132
+
133
+ # Detect retrieval augmentation
134
+ retrieve_config = getattr(agent, "retrieve_config", None)
135
+ if retrieve_config:
136
+ capabilities.add("knowledge")
137
+
138
+ # Extra skill from LLM config
139
+ pkg = _detect_llm_skill(agent)
140
+ if pkg and pkg not in skills_seen:
141
+ skills.append({"name": pkg, "registry": "pypi"})
142
+ skills_seen.add(pkg)
143
+
144
+ # Fallback capability
145
+ if not capabilities:
146
+ capabilities.add("reasoning")
147
+
148
+ return {
149
+ "capabilities": sorted(capabilities),
150
+ "protocols": ["https"],
151
+ "skills": skills,
152
+ }
153
+
154
+
155
+ def register_autogen_agent(
156
+ agent_or_group: Any,
157
+ name: str,
158
+ description: str = "",
159
+ contact_endpoint: str | None = None,
160
+ organization: str | None = None,
161
+ version: str | None = None,
162
+ tags: list[str] | None = None,
163
+ extra_capabilities: list[str] | None = None,
164
+ extra_skills: list[dict[str, str]] | None = None,
165
+ keypair_path: str | None = None,
166
+ api_url: str | None = None,
167
+ verbose: bool = True,
168
+ ) -> str:
169
+ """
170
+ Register an AutoGen agent or GroupChat with basedagents.ai.
171
+
172
+ Introspects the agent to auto-detect capabilities and skills.
173
+ Idempotent — safe to call on every startup.
174
+
175
+ Args:
176
+ agent_or_group: AutoGen ConversableAgent, AssistantAgent, UserProxyAgent,
177
+ GroupChat, or GroupChatManager
178
+ name: Unique agent name (globally unique on registry)
179
+ description: What this agent/group does
180
+ contact_endpoint: URL where the agent can be reached for verification
181
+ organization: Optional org name
182
+ version: Optional version string
183
+ tags: Optional extra tags
184
+ extra_capabilities: Additional capabilities beyond auto-detected ones
185
+ extra_skills: Additional skills beyond auto-detected ones
186
+ keypair_path: Override keypair file location
187
+ api_url: Override API URL (defaults to BASEDAGENTS_API env or prod)
188
+ verbose: Print progress (default True)
189
+
190
+ Returns:
191
+ agent_id string
192
+
193
+ Example:
194
+ import autogen
195
+ from basedagents.integrations.autogen import register_autogen_agent
196
+
197
+ assistant = autogen.AssistantAgent("assistant", llm_config={"model": "gpt-4o"})
198
+ user_proxy = autogen.UserProxyAgent("user_proxy", code_execution_config={"work_dir": "."})
199
+
200
+ agent_id = register_autogen_agent(
201
+ assistant,
202
+ name="my-autogen-assistant",
203
+ description="Writes and debugs Python code via GPT-4o.",
204
+ )
205
+ """
206
+ from ..easy import register_or_load
207
+
208
+ profile = extract_profile(agent_or_group, extra_capabilities, extra_skills)
209
+ merged_tags = list(set(["autogen"] + (tags or [])))
210
+
211
+ return register_or_load(
212
+ name=name,
213
+ description=description,
214
+ capabilities=profile["capabilities"],
215
+ protocols=profile["protocols"],
216
+ skills=profile["skills"],
217
+ contact_endpoint=contact_endpoint,
218
+ organization=organization,
219
+ version=version,
220
+ tags=merged_tags,
221
+ keypair_path=keypair_path,
222
+ api_url=api_url,
223
+ verbose=verbose,
224
+ )