forked from themanojdesai/python-a2a
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdecorators.py
More file actions
106 lines (84 loc) · 3.62 KB
/
Copy pathdecorators.py
File metadata and controls
106 lines (84 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
"""
Decorators for creating A2A agents and skills.
"""
def skill(name, description=None, tags=None, examples=None):
"""Decorator to register a method as an A2A skill"""
def decorator(func):
# Extract info from function
func_name = func.__name__
func_doc = func.__doc__ or ""
# Parse examples from docstring if not provided
parsed_examples = []
if examples is None and "Examples:" in func_doc:
example_section = func_doc.split("Examples:", 1)[1]
parsed_examples = [
line.strip().strip('"`\'')
for line in example_section.split("\n")
if line.strip()
]
# Construct skill info
skill_info = {
"id": func_name,
"name": name or func_name.replace("_", " ").title(),
"description": description or func_doc.split("\n\n")[0].strip(),
"tags": tags or [],
"examples": examples or parsed_examples
}
# Attach skill info to the function
func._skill_info = skill_info
return func
return decorator
def agent(name, description=None, version=None, **kwargs):
"""Decorator to create an A2A agent class"""
def decorator(cls):
# Store original __init__ method
original_init = cls.__init__
# Define a new __init__ that will collect skills and set up the agent card
def new_init(self, *args, **kwargs):
# Call original __init__ first
original_init(self, *args, **kwargs)
# Import here to avoid circular imports
from ..models.agent import AgentSkill, AgentCard
# Collect skills from decorated methods
skills = []
for attr_name in dir(self):
if attr_name.startswith('__'):
continue
attr = getattr(self, attr_name)
if callable(attr) and hasattr(attr, '_skill_info'):
skill_info = attr._skill_info
skills.append(AgentSkill(
id=skill_info["id"],
name=skill_info["name"],
description=skill_info["description"],
tags=skill_info["tags"],
examples=skill_info["examples"]
))
# Create agent card with collected skills
self.agent_card = AgentCard(
name=name or cls.__name__,
description=description or cls.__doc__ or "",
url=kwargs.get("url", getattr(self, "url", None)),
version=version or "1.0.0",
skills=skills
)
# Replace __init__ with our new version
cls.__init__ = new_init
# Set class attributes
cls.name = name or cls.__name__
cls.description = description or cls.__doc__ or ""
cls.version = version or "1.0.0"
# Add additional agent card attributes
for key, value in kwargs.items():
setattr(cls, key, value)
# Add helper method to run the agent
def run(self, host="0.0.0.0", port=None):
from ..server import run_server
# Use the provided port or let run_server use its default
if port is not None:
run_server(self, host=host, port=port)
else:
run_server(self, host=host)
cls.run = run
return cls
return decorator