hammad-python 0.0.23__py3-none-any.whl → 0.0.25__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.
- hammad/__init__.py +62 -14
- hammad/_main.py +226 -0
- hammad/cli/__init__.py +0 -2
- hammad/cli/plugins.py +3 -1
- hammad/data/__init__.py +4 -5
- hammad/data/types/__init__.py +37 -1
- hammad/data/types/file.py +74 -1
- hammad/data/types/multimodal/__init__.py +14 -2
- hammad/data/types/multimodal/audio.py +106 -2
- hammad/data/types/multimodal/image.py +104 -2
- hammad/data/types/text.py +242 -0
- hammad/genai/__init__.py +73 -0
- hammad/genai/a2a/__init__.py +32 -0
- hammad/genai/a2a/workers.py +552 -0
- hammad/genai/agents/__init__.py +8 -0
- hammad/genai/agents/agent.py +747 -214
- hammad/genai/agents/run.py +421 -12
- hammad/genai/agents/types/agent_response.py +2 -1
- hammad/genai/graphs/__init__.py +125 -0
- hammad/genai/graphs/base.py +1786 -0
- hammad/genai/graphs/plugins.py +316 -0
- hammad/genai/graphs/types.py +638 -0
- hammad/genai/models/language/__init__.py +6 -1
- hammad/genai/models/language/model.py +46 -0
- hammad/genai/models/language/run.py +330 -4
- hammad/genai/models/language/types/language_model_response.py +1 -1
- hammad/genai/types/tools.py +1 -1
- hammad/logging/logger.py +60 -5
- hammad/mcp/__init__.py +3 -0
- hammad/types.py +288 -0
- {hammad_python-0.0.23.dist-info → hammad_python-0.0.25.dist-info}/METADATA +6 -1
- {hammad_python-0.0.23.dist-info → hammad_python-0.0.25.dist-info}/RECORD +34 -32
- hammad/_main/__init__.py +0 -4
- hammad/_main/_fn.py +0 -20
- hammad/_main/_new.py +0 -52
- hammad/_main/_run.py +0 -50
- hammad/_main/_to.py +0 -19
- hammad/cli/_runner.py +0 -265
- {hammad_python-0.0.23.dist-info → hammad_python-0.0.25.dist-info}/WHEEL +0 -0
- {hammad_python-0.0.23.dist-info → hammad_python-0.0.25.dist-info}/licenses/LICENSE +0 -0
@@ -1,12 +1,19 @@
|
|
1
1
|
"""hammad.data.types.multimodal.image"""
|
2
2
|
|
3
3
|
import httpx
|
4
|
+
import mimetypes
|
5
|
+
from pathlib import Path
|
4
6
|
from typing import Self
|
5
7
|
|
6
|
-
from ...types.file import File, FileSource
|
8
|
+
from ...types.file import File, FileSource, _FILE_SIGNATURES
|
7
9
|
from ...models.fields import field
|
8
10
|
|
9
|
-
|
11
|
+
|
12
|
+
__all__ = (
|
13
|
+
"Image",
|
14
|
+
"read_image_from_path",
|
15
|
+
"read_image_from_url",
|
16
|
+
)
|
10
17
|
|
11
18
|
|
12
19
|
class Image(File):
|
@@ -78,3 +85,98 @@ class Image(File):
|
|
78
85
|
size=size,
|
79
86
|
),
|
80
87
|
)
|
88
|
+
|
89
|
+
@classmethod
|
90
|
+
def from_path(
|
91
|
+
cls,
|
92
|
+
path: str | Path,
|
93
|
+
) -> Self:
|
94
|
+
"""Create an image from a file path.
|
95
|
+
|
96
|
+
Args:
|
97
|
+
path: The path to the image file.
|
98
|
+
|
99
|
+
Returns:
|
100
|
+
A new Image instance.
|
101
|
+
|
102
|
+
Raises:
|
103
|
+
FileNotFoundError: If the file does not exist.
|
104
|
+
ValueError: If the file is not a valid image.
|
105
|
+
"""
|
106
|
+
path_obj = Path(path)
|
107
|
+
|
108
|
+
if not path_obj.exists():
|
109
|
+
raise FileNotFoundError(f"Image file not found: {path}")
|
110
|
+
|
111
|
+
if not path_obj.is_file():
|
112
|
+
raise ValueError(f"Path is not a file: {path}")
|
113
|
+
|
114
|
+
# Read the file data
|
115
|
+
data = path_obj.read_bytes()
|
116
|
+
|
117
|
+
# Detect MIME type
|
118
|
+
type = None
|
119
|
+
for sig, mime in _FILE_SIGNATURES.items():
|
120
|
+
if data.startswith(sig):
|
121
|
+
type = mime
|
122
|
+
break
|
123
|
+
|
124
|
+
# Fallback to mimetypes module
|
125
|
+
if not type:
|
126
|
+
type, _ = mimetypes.guess_type(str(path))
|
127
|
+
|
128
|
+
# Validate it's an image
|
129
|
+
if type and not type.startswith("image/"):
|
130
|
+
raise ValueError(f"File is not an image: {type}")
|
131
|
+
|
132
|
+
return cls(
|
133
|
+
data=data,
|
134
|
+
type=type,
|
135
|
+
source=FileSource(
|
136
|
+
is_file=True,
|
137
|
+
path=path_obj,
|
138
|
+
size=len(data),
|
139
|
+
),
|
140
|
+
)
|
141
|
+
|
142
|
+
|
143
|
+
def read_image_from_url(
|
144
|
+
url: str,
|
145
|
+
*,
|
146
|
+
lazy: bool = True,
|
147
|
+
timeout: float = 30.0,
|
148
|
+
) -> Image:
|
149
|
+
"""Download and create an image from a URL.
|
150
|
+
|
151
|
+
Args:
|
152
|
+
url: The URL to download from.
|
153
|
+
lazy: If True, defer loading content until needed.
|
154
|
+
timeout: Request timeout in seconds.
|
155
|
+
|
156
|
+
Returns:
|
157
|
+
A new Image instance.
|
158
|
+
|
159
|
+
Raises:
|
160
|
+
httpx.RequestError: If the request fails.
|
161
|
+
httpx.HTTPStatusError: If the response has an error status code.
|
162
|
+
ValueError: If the URL does not point to an image.
|
163
|
+
"""
|
164
|
+
return Image.from_url(url, lazy=lazy, timeout=timeout)
|
165
|
+
|
166
|
+
|
167
|
+
def read_image_from_path(
|
168
|
+
path: str | Path,
|
169
|
+
) -> Image:
|
170
|
+
"""Create an image from a file path.
|
171
|
+
|
172
|
+
Args:
|
173
|
+
path: The path to the image file.
|
174
|
+
|
175
|
+
Returns:
|
176
|
+
A new Image instance.
|
177
|
+
|
178
|
+
Raises:
|
179
|
+
FileNotFoundError: If the file does not exist.
|
180
|
+
ValueError: If the file is not a valid image.
|
181
|
+
"""
|
182
|
+
return Image.from_path(path)
|
hammad/data/types/text.py
CHANGED
@@ -1054,6 +1054,242 @@ class Text(BaseText, Generic[T]):
|
|
1054
1054
|
return self.render(OutputFormat.ANY)
|
1055
1055
|
|
1056
1056
|
|
1057
|
+
def convert_to_simple_text(
|
1058
|
+
obj: Any,
|
1059
|
+
*,
|
1060
|
+
title: Optional[str] = None,
|
1061
|
+
description: Optional[str] = None,
|
1062
|
+
type: str = "simple",
|
1063
|
+
heading_level: int = 2,
|
1064
|
+
show_in_toc: bool = True,
|
1065
|
+
collapsible: bool = False,
|
1066
|
+
metadata: Optional[Dict[str, Any]] = None,
|
1067
|
+
sections: Optional[List["BaseText"]] = None,
|
1068
|
+
format_config: Optional[Dict["OutputFormat", Dict[str, Any]]] = None,
|
1069
|
+
**kwargs,
|
1070
|
+
) -> "SimpleText":
|
1071
|
+
"""Convert any object to a SimpleText instance (fully parameterized)."""
|
1072
|
+
content = convert_to_text(obj)
|
1073
|
+
return SimpleText(
|
1074
|
+
content=content,
|
1075
|
+
title=title,
|
1076
|
+
description=description,
|
1077
|
+
type=type,
|
1078
|
+
heading_level=heading_level,
|
1079
|
+
show_in_toc=show_in_toc,
|
1080
|
+
collapsible=collapsible,
|
1081
|
+
metadata=metadata or {},
|
1082
|
+
sections=sections or [],
|
1083
|
+
format_config=format_config or {},
|
1084
|
+
**kwargs,
|
1085
|
+
)
|
1086
|
+
|
1087
|
+
|
1088
|
+
def convert_to_output_text(
|
1089
|
+
obj: Any,
|
1090
|
+
*,
|
1091
|
+
title: Optional[str] = None,
|
1092
|
+
description: Optional[str] = None,
|
1093
|
+
type: str = "output",
|
1094
|
+
heading_level: int = 2,
|
1095
|
+
show_in_toc: bool = True,
|
1096
|
+
collapsible: bool = False,
|
1097
|
+
metadata: Optional[Dict[str, Any]] = None,
|
1098
|
+
sections: Optional[List["BaseText"]] = None,
|
1099
|
+
format_config: Optional[Dict["OutputFormat", Dict[str, Any]]] = None,
|
1100
|
+
output_schema: Optional[Any] = None,
|
1101
|
+
examples: Optional[List[Any]] = None,
|
1102
|
+
validation_rules: Optional[List[str]] = None,
|
1103
|
+
error_cases: Optional[List[Dict[str, Any]]] = None,
|
1104
|
+
**kwargs,
|
1105
|
+
) -> "OutputText":
|
1106
|
+
"""Convert any object to an OutputText instance (fully parameterized)."""
|
1107
|
+
content = convert_to_text(obj)
|
1108
|
+
return OutputText(
|
1109
|
+
content=content,
|
1110
|
+
title=title,
|
1111
|
+
description=description,
|
1112
|
+
type=type,
|
1113
|
+
heading_level=heading_level,
|
1114
|
+
show_in_toc=show_in_toc,
|
1115
|
+
collapsible=collapsible,
|
1116
|
+
metadata=metadata or {},
|
1117
|
+
sections=sections or [],
|
1118
|
+
format_config=format_config or {},
|
1119
|
+
output_schema=output_schema,
|
1120
|
+
examples=examples or [],
|
1121
|
+
validation_rules=validation_rules or [],
|
1122
|
+
error_cases=error_cases or [],
|
1123
|
+
**kwargs,
|
1124
|
+
)
|
1125
|
+
|
1126
|
+
|
1127
|
+
def convert_to_output_instructions(
|
1128
|
+
obj: Any,
|
1129
|
+
*,
|
1130
|
+
title: Optional[str] = None,
|
1131
|
+
description: Optional[str] = None,
|
1132
|
+
type: str = "output",
|
1133
|
+
heading_level: int = 2,
|
1134
|
+
show_in_toc: bool = True,
|
1135
|
+
collapsible: bool = False,
|
1136
|
+
metadata: Optional[Dict[str, Any]] = None,
|
1137
|
+
sections: Optional[List["BaseText"]] = None,
|
1138
|
+
format_config: Optional[Dict["OutputFormat", Dict[str, Any]]] = None,
|
1139
|
+
output_schema: Optional[Any] = None,
|
1140
|
+
examples: Optional[List[Any]] = None,
|
1141
|
+
validation_rules: Optional[List[str]] = None,
|
1142
|
+
error_cases: Optional[List[Dict[str, Any]]] = None,
|
1143
|
+
as_message: bool = False,
|
1144
|
+
role: str = "user",
|
1145
|
+
as_message_content: bool = False,
|
1146
|
+
**kwargs,
|
1147
|
+
) -> Union[str, Dict[str, Any]]:
|
1148
|
+
"""
|
1149
|
+
Convert any object to output instructions, returning either:
|
1150
|
+
- a string (default)
|
1151
|
+
- a chat message dict (if as_message=True)
|
1152
|
+
- a chat message content param dict (if as_message_content=True)
|
1153
|
+
|
1154
|
+
Only one of as_message or as_message_content can be True.
|
1155
|
+
"""
|
1156
|
+
if as_message and as_message_content:
|
1157
|
+
raise ValueError("Only one of as_message or as_message_content can be True.")
|
1158
|
+
|
1159
|
+
content = convert_to_text(obj)
|
1160
|
+
output_text = OutputText(
|
1161
|
+
content=content,
|
1162
|
+
title=title,
|
1163
|
+
description=description,
|
1164
|
+
type=type,
|
1165
|
+
heading_level=heading_level,
|
1166
|
+
show_in_toc=show_in_toc,
|
1167
|
+
collapsible=collapsible,
|
1168
|
+
metadata=metadata or {},
|
1169
|
+
sections=sections or [],
|
1170
|
+
format_config=format_config or {},
|
1171
|
+
output_schema=output_schema,
|
1172
|
+
examples=examples or [],
|
1173
|
+
validation_rules=validation_rules or [],
|
1174
|
+
error_cases=error_cases or [],
|
1175
|
+
**kwargs,
|
1176
|
+
)
|
1177
|
+
text_str = str(output_text)
|
1178
|
+
|
1179
|
+
if as_message:
|
1180
|
+
# Return a chat message dict
|
1181
|
+
return {"role": role, "content": text_str}
|
1182
|
+
elif as_message_content:
|
1183
|
+
# Return a chat message content param dict
|
1184
|
+
return {"type": "text", "text": text_str}
|
1185
|
+
else:
|
1186
|
+
# Return as plain string
|
1187
|
+
return text_str
|
1188
|
+
|
1189
|
+
|
1190
|
+
def convert_to_code_section(
|
1191
|
+
obj: Any,
|
1192
|
+
*,
|
1193
|
+
language: str = "python",
|
1194
|
+
title: Optional[str] = None,
|
1195
|
+
description: Optional[str] = None,
|
1196
|
+
type: str = "code",
|
1197
|
+
heading_level: int = 2,
|
1198
|
+
show_in_toc: bool = True,
|
1199
|
+
collapsible: bool = False,
|
1200
|
+
metadata: Optional[Dict[str, Any]] = None,
|
1201
|
+
sections: Optional[List["BaseText"]] = None,
|
1202
|
+
format_config: Optional[Dict["OutputFormat", Dict[str, Any]]] = None,
|
1203
|
+
line_numbers: bool = False,
|
1204
|
+
**kwargs,
|
1205
|
+
) -> "CodeSection":
|
1206
|
+
"""Convert any object to a CodeSection instance (fully parameterized)."""
|
1207
|
+
content = convert_to_text(obj)
|
1208
|
+
return CodeSection(
|
1209
|
+
content=content,
|
1210
|
+
language=language,
|
1211
|
+
title=title,
|
1212
|
+
description=description,
|
1213
|
+
type=type,
|
1214
|
+
heading_level=heading_level,
|
1215
|
+
show_in_toc=show_in_toc,
|
1216
|
+
collapsible=collapsible,
|
1217
|
+
metadata=metadata or {},
|
1218
|
+
sections=sections or [],
|
1219
|
+
format_config=format_config or {},
|
1220
|
+
line_numbers=line_numbers,
|
1221
|
+
**kwargs,
|
1222
|
+
)
|
1223
|
+
|
1224
|
+
|
1225
|
+
def convert_to_schema_section(
|
1226
|
+
obj: Any,
|
1227
|
+
*,
|
1228
|
+
title: Optional[str] = None,
|
1229
|
+
description: Optional[str] = None,
|
1230
|
+
type: str = "schema",
|
1231
|
+
heading_level: int = 2,
|
1232
|
+
show_in_toc: bool = True,
|
1233
|
+
collapsible: bool = False,
|
1234
|
+
metadata: Optional[Dict[str, Any]] = None,
|
1235
|
+
sections: Optional[List["BaseText"]] = None,
|
1236
|
+
format_config: Optional[Dict["OutputFormat", Dict[str, Any]]] = None,
|
1237
|
+
schema_object: Optional[Any] = None,
|
1238
|
+
show_examples: bool = True,
|
1239
|
+
table_format: bool = True,
|
1240
|
+
**kwargs,
|
1241
|
+
) -> "SchemaSection":
|
1242
|
+
"""Convert any object to a SchemaSection instance (fully parameterized)."""
|
1243
|
+
content = convert_to_text(obj)
|
1244
|
+
return SchemaSection(
|
1245
|
+
content=content,
|
1246
|
+
title=title,
|
1247
|
+
description=description,
|
1248
|
+
type=type,
|
1249
|
+
heading_level=heading_level,
|
1250
|
+
show_in_toc=show_in_toc,
|
1251
|
+
collapsible=collapsible,
|
1252
|
+
metadata=metadata or {},
|
1253
|
+
sections=sections or [],
|
1254
|
+
format_config=format_config or {},
|
1255
|
+
schema_object=schema_object or obj,
|
1256
|
+
show_examples=show_examples,
|
1257
|
+
table_format=table_format,
|
1258
|
+
**kwargs,
|
1259
|
+
)
|
1260
|
+
|
1261
|
+
|
1262
|
+
def convert_to_base_text(
|
1263
|
+
obj: Any,
|
1264
|
+
*,
|
1265
|
+
title: Optional[str] = None,
|
1266
|
+
description: Optional[str] = None,
|
1267
|
+
type: str = "base",
|
1268
|
+
heading_level: int = 2,
|
1269
|
+
show_in_toc: bool = True,
|
1270
|
+
collapsible: bool = False,
|
1271
|
+
metadata: Optional[Dict[str, Any]] = None,
|
1272
|
+
sections: Optional[List["BaseText"]] = None,
|
1273
|
+
format_config: Optional[Dict["OutputFormat", Dict[str, Any]]] = None,
|
1274
|
+
**kwargs,
|
1275
|
+
) -> "BaseText":
|
1276
|
+
"""Convert any object to a BaseText instance (fully parameterized)."""
|
1277
|
+
content = convert_to_text(obj)
|
1278
|
+
return BaseText(
|
1279
|
+
content=content,
|
1280
|
+
title=title,
|
1281
|
+
description=description,
|
1282
|
+
type=type,
|
1283
|
+
heading_level=heading_level,
|
1284
|
+
show_in_toc=show_in_toc,
|
1285
|
+
collapsible=collapsible,
|
1286
|
+
metadata=metadata or {},
|
1287
|
+
sections=sections or [],
|
1288
|
+
format_config=format_config or {},
|
1289
|
+
**kwargs,
|
1290
|
+
)
|
1291
|
+
|
1292
|
+
|
1057
1293
|
__all__ = (
|
1058
1294
|
"OutputFormat",
|
1059
1295
|
"HeadingStyle",
|
@@ -1063,4 +1299,10 @@ __all__ = (
|
|
1063
1299
|
"SimpleText",
|
1064
1300
|
"OutputText",
|
1065
1301
|
"Text",
|
1302
|
+
"convert_to_simple_text",
|
1303
|
+
"convert_to_output_text",
|
1304
|
+
"convert_to_output_instructions",
|
1305
|
+
"convert_to_code_section",
|
1306
|
+
"convert_to_schema_section",
|
1307
|
+
"convert_to_base_text",
|
1066
1308
|
)
|
hammad/genai/__init__.py
CHANGED
@@ -4,10 +4,17 @@ from typing import TYPE_CHECKING
|
|
4
4
|
from .._internal import create_getattr_importer
|
5
5
|
|
6
6
|
|
7
|
+
if TYPE_CHECKING:
|
8
|
+
from .a2a import (
|
9
|
+
as_a2a_app,
|
10
|
+
GraphWorker,
|
11
|
+
AgentWorker,
|
12
|
+
)
|
7
13
|
if TYPE_CHECKING:
|
8
14
|
from .agents import (
|
9
15
|
Agent,
|
10
16
|
AgentEvent,
|
17
|
+
AgentSettings,
|
11
18
|
AgentResponse,
|
12
19
|
AgentStream,
|
13
20
|
AgentContext,
|
@@ -20,6 +27,36 @@ if TYPE_CHECKING:
|
|
20
27
|
run_agent_iter,
|
21
28
|
async_run_agent,
|
22
29
|
async_run_agent_iter,
|
30
|
+
agent_decorator,
|
31
|
+
)
|
32
|
+
from .graphs import (
|
33
|
+
GraphBuilder,
|
34
|
+
GraphContext,
|
35
|
+
GraphEnd,
|
36
|
+
GraphEvent,
|
37
|
+
GraphHistoryEntry,
|
38
|
+
GraphNode,
|
39
|
+
GraphState,
|
40
|
+
GraphResponse,
|
41
|
+
GraphStream,
|
42
|
+
GraphResponseChunk,
|
43
|
+
BaseGraph,
|
44
|
+
BasePlugin,
|
45
|
+
PluginDecorator,
|
46
|
+
PydanticGraphContext,
|
47
|
+
AudioPlugin,
|
48
|
+
ServePlugin,
|
49
|
+
MemoryPlugin,
|
50
|
+
HistoryPlugin,
|
51
|
+
SettingsPlugin,
|
52
|
+
ActionNode,
|
53
|
+
ActionInfo,
|
54
|
+
ActionSettings,
|
55
|
+
action,
|
56
|
+
plugin,
|
57
|
+
select,
|
58
|
+
SelectionStrategy,
|
59
|
+
ActionDecorator,
|
23
60
|
)
|
24
61
|
from .models.embeddings import (
|
25
62
|
Embedding,
|
@@ -42,6 +79,7 @@ if TYPE_CHECKING:
|
|
42
79
|
LanguageModelStream,
|
43
80
|
run_language_model,
|
44
81
|
async_run_language_model,
|
82
|
+
language_model_decorator,
|
45
83
|
create_language_model,
|
46
84
|
)
|
47
85
|
from .models.reranking import run_reranking_model, async_run_reranking_model
|
@@ -73,9 +111,14 @@ if TYPE_CHECKING:
|
|
73
111
|
|
74
112
|
|
75
113
|
__all__ = [
|
114
|
+
# hammad.genai.a2a
|
115
|
+
"as_a2a_app",
|
116
|
+
"GraphWorker",
|
117
|
+
"AgentWorker",
|
76
118
|
# hammad.genai.agents.agent
|
77
119
|
"Agent",
|
78
120
|
"AgentEvent",
|
121
|
+
"AgentSettings",
|
79
122
|
"AgentResponse",
|
80
123
|
"AgentStream",
|
81
124
|
"AgentContext",
|
@@ -87,6 +130,35 @@ __all__ = [
|
|
87
130
|
"run_agent_iter",
|
88
131
|
"async_run_agent",
|
89
132
|
"async_run_agent_iter",
|
133
|
+
"agent_decorator",
|
134
|
+
# hammad.genai.graphs
|
135
|
+
"GraphBuilder",
|
136
|
+
"GraphContext",
|
137
|
+
"GraphEnd",
|
138
|
+
"GraphEvent",
|
139
|
+
"GraphHistoryEntry",
|
140
|
+
"GraphNode",
|
141
|
+
"GraphState",
|
142
|
+
"GraphResponse",
|
143
|
+
"GraphStream",
|
144
|
+
"GraphResponseChunk",
|
145
|
+
"BaseGraph",
|
146
|
+
"BasePlugin",
|
147
|
+
"PluginDecorator",
|
148
|
+
"PydanticGraphContext",
|
149
|
+
"AudioPlugin",
|
150
|
+
"ServePlugin",
|
151
|
+
"MemoryPlugin",
|
152
|
+
"HistoryPlugin",
|
153
|
+
"SettingsPlugin",
|
154
|
+
"ActionNode",
|
155
|
+
"ActionInfo",
|
156
|
+
"ActionSettings",
|
157
|
+
"action",
|
158
|
+
"plugin",
|
159
|
+
"select",
|
160
|
+
"SelectionStrategy",
|
161
|
+
"ActionDecorator",
|
90
162
|
# hammad.genai.models.embeddings
|
91
163
|
"Embedding",
|
92
164
|
"EmbeddingModel",
|
@@ -108,6 +180,7 @@ __all__ = [
|
|
108
180
|
"run_language_model",
|
109
181
|
"async_run_language_model",
|
110
182
|
"create_language_model",
|
183
|
+
"language_model_decorator",
|
111
184
|
# hammad.genai.models.reranking
|
112
185
|
"run_reranking_model",
|
113
186
|
"async_run_reranking_model",
|
@@ -0,0 +1,32 @@
|
|
1
|
+
"""hammad.genai.a2a"""
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING
|
4
|
+
from ..._internal import create_getattr_importer
|
5
|
+
|
6
|
+
|
7
|
+
if TYPE_CHECKING:
|
8
|
+
from fasta2a import (
|
9
|
+
FastA2A
|
10
|
+
)
|
11
|
+
from .workers import (
|
12
|
+
as_a2a_app,
|
13
|
+
GraphWorker,
|
14
|
+
AgentWorker,
|
15
|
+
)
|
16
|
+
|
17
|
+
|
18
|
+
__all__ = (
|
19
|
+
# fasta2a
|
20
|
+
"FastA2A",
|
21
|
+
# hammad.genai.a2a.workers
|
22
|
+
"as_a2a_app",
|
23
|
+
"GraphWorker",
|
24
|
+
"AgentWorker",
|
25
|
+
)
|
26
|
+
|
27
|
+
|
28
|
+
__getattr__ = create_getattr_importer(__all__)
|
29
|
+
|
30
|
+
|
31
|
+
def __dir__() -> list[str]:
|
32
|
+
return list(__all__)
|