hammad-python 0.0.30__py3-none-any.whl → 0.0.32__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.
- ham/__init__.py +200 -0
- {hammad_python-0.0.30.dist-info → hammad_python-0.0.32.dist-info}/METADATA +6 -32
- hammad_python-0.0.32.dist-info/RECORD +6 -0
- hammad/__init__.py +0 -84
- hammad/_internal.py +0 -256
- hammad/_main.py +0 -226
- hammad/cache/__init__.py +0 -40
- hammad/cache/base_cache.py +0 -181
- hammad/cache/cache.py +0 -169
- hammad/cache/decorators.py +0 -261
- hammad/cache/file_cache.py +0 -80
- hammad/cache/ttl_cache.py +0 -74
- hammad/cli/__init__.py +0 -33
- hammad/cli/animations.py +0 -573
- hammad/cli/plugins.py +0 -867
- hammad/cli/styles/__init__.py +0 -55
- hammad/cli/styles/settings.py +0 -139
- hammad/cli/styles/types.py +0 -358
- hammad/cli/styles/utils.py +0 -634
- hammad/data/__init__.py +0 -90
- hammad/data/collections/__init__.py +0 -49
- hammad/data/collections/collection.py +0 -326
- hammad/data/collections/indexes/__init__.py +0 -37
- hammad/data/collections/indexes/qdrant/__init__.py +0 -1
- hammad/data/collections/indexes/qdrant/index.py +0 -723
- hammad/data/collections/indexes/qdrant/settings.py +0 -94
- hammad/data/collections/indexes/qdrant/utils.py +0 -210
- hammad/data/collections/indexes/tantivy/__init__.py +0 -1
- hammad/data/collections/indexes/tantivy/index.py +0 -426
- hammad/data/collections/indexes/tantivy/settings.py +0 -40
- hammad/data/collections/indexes/tantivy/utils.py +0 -176
- hammad/data/configurations/__init__.py +0 -35
- hammad/data/configurations/configuration.py +0 -564
- hammad/data/models/__init__.py +0 -50
- hammad/data/models/extensions/__init__.py +0 -4
- hammad/data/models/extensions/pydantic/__init__.py +0 -42
- hammad/data/models/extensions/pydantic/converters.py +0 -759
- hammad/data/models/fields.py +0 -546
- hammad/data/models/model.py +0 -1078
- hammad/data/models/utils.py +0 -280
- hammad/data/sql/__init__.py +0 -24
- hammad/data/sql/database.py +0 -576
- hammad/data/sql/types.py +0 -127
- hammad/data/types/__init__.py +0 -75
- hammad/data/types/file.py +0 -431
- hammad/data/types/multimodal/__init__.py +0 -36
- hammad/data/types/multimodal/audio.py +0 -200
- hammad/data/types/multimodal/image.py +0 -182
- hammad/data/types/text.py +0 -1308
- hammad/formatting/__init__.py +0 -33
- hammad/formatting/json/__init__.py +0 -27
- hammad/formatting/json/converters.py +0 -158
- hammad/formatting/text/__init__.py +0 -63
- hammad/formatting/text/converters.py +0 -723
- hammad/formatting/text/markdown.py +0 -131
- hammad/formatting/yaml/__init__.py +0 -26
- hammad/formatting/yaml/converters.py +0 -5
- hammad/genai/__init__.py +0 -217
- hammad/genai/a2a/__init__.py +0 -32
- hammad/genai/a2a/workers.py +0 -552
- hammad/genai/agents/__init__.py +0 -59
- hammad/genai/agents/agent.py +0 -1973
- hammad/genai/agents/run.py +0 -1024
- hammad/genai/agents/types/__init__.py +0 -42
- hammad/genai/agents/types/agent_context.py +0 -13
- hammad/genai/agents/types/agent_event.py +0 -128
- hammad/genai/agents/types/agent_hooks.py +0 -220
- hammad/genai/agents/types/agent_messages.py +0 -31
- hammad/genai/agents/types/agent_response.py +0 -125
- hammad/genai/agents/types/agent_stream.py +0 -327
- hammad/genai/graphs/__init__.py +0 -125
- hammad/genai/graphs/_utils.py +0 -190
- hammad/genai/graphs/base.py +0 -1828
- hammad/genai/graphs/plugins.py +0 -316
- hammad/genai/graphs/types.py +0 -638
- hammad/genai/models/__init__.py +0 -1
- hammad/genai/models/embeddings/__init__.py +0 -43
- hammad/genai/models/embeddings/model.py +0 -226
- hammad/genai/models/embeddings/run.py +0 -163
- hammad/genai/models/embeddings/types/__init__.py +0 -37
- hammad/genai/models/embeddings/types/embedding_model_name.py +0 -75
- hammad/genai/models/embeddings/types/embedding_model_response.py +0 -76
- hammad/genai/models/embeddings/types/embedding_model_run_params.py +0 -66
- hammad/genai/models/embeddings/types/embedding_model_settings.py +0 -47
- hammad/genai/models/language/__init__.py +0 -57
- hammad/genai/models/language/model.py +0 -1098
- hammad/genai/models/language/run.py +0 -878
- hammad/genai/models/language/types/__init__.py +0 -40
- hammad/genai/models/language/types/language_model_instructor_mode.py +0 -47
- hammad/genai/models/language/types/language_model_messages.py +0 -28
- hammad/genai/models/language/types/language_model_name.py +0 -239
- hammad/genai/models/language/types/language_model_request.py +0 -127
- hammad/genai/models/language/types/language_model_response.py +0 -217
- hammad/genai/models/language/types/language_model_response_chunk.py +0 -56
- hammad/genai/models/language/types/language_model_settings.py +0 -89
- hammad/genai/models/language/types/language_model_stream.py +0 -600
- hammad/genai/models/language/utils/__init__.py +0 -28
- hammad/genai/models/language/utils/requests.py +0 -421
- hammad/genai/models/language/utils/structured_outputs.py +0 -135
- hammad/genai/models/model_provider.py +0 -4
- hammad/genai/models/multimodal.py +0 -47
- hammad/genai/models/reranking.py +0 -26
- hammad/genai/types/__init__.py +0 -1
- hammad/genai/types/base.py +0 -215
- hammad/genai/types/history.py +0 -290
- hammad/genai/types/tools.py +0 -507
- hammad/logging/__init__.py +0 -35
- hammad/logging/decorators.py +0 -834
- hammad/logging/logger.py +0 -1018
- hammad/mcp/__init__.py +0 -53
- hammad/mcp/client/__init__.py +0 -35
- hammad/mcp/client/client.py +0 -624
- hammad/mcp/client/client_service.py +0 -400
- hammad/mcp/client/settings.py +0 -178
- hammad/mcp/servers/__init__.py +0 -26
- hammad/mcp/servers/launcher.py +0 -1161
- hammad/runtime/__init__.py +0 -32
- hammad/runtime/decorators.py +0 -142
- hammad/runtime/run.py +0 -299
- hammad/service/__init__.py +0 -49
- hammad/service/create.py +0 -527
- hammad/service/decorators.py +0 -283
- hammad/types.py +0 -288
- hammad/typing/__init__.py +0 -435
- hammad/web/__init__.py +0 -43
- hammad/web/http/__init__.py +0 -1
- hammad/web/http/client.py +0 -944
- hammad/web/models.py +0 -275
- hammad/web/openapi/__init__.py +0 -1
- hammad/web/openapi/client.py +0 -740
- hammad/web/search/__init__.py +0 -1
- hammad/web/search/client.py +0 -1023
- hammad/web/utils.py +0 -472
- hammad_python-0.0.30.dist-info/RECORD +0 -135
- {hammad → ham}/py.typed +0 -0
- {hammad_python-0.0.30.dist-info → hammad_python-0.0.32.dist-info}/WHEEL +0 -0
- {hammad_python-0.0.30.dist-info → hammad_python-0.0.32.dist-info}/licenses/LICENSE +0 -0
@@ -1,42 +0,0 @@
|
|
1
|
-
"""hammad.genai.agents.types"""
|
2
|
-
|
3
|
-
from typing import TYPE_CHECKING
|
4
|
-
from ...._internal import create_getattr_importer
|
5
|
-
|
6
|
-
|
7
|
-
if TYPE_CHECKING:
|
8
|
-
from .agent_event import AgentEvent
|
9
|
-
from .agent_hooks import HookManager, HookDecorator
|
10
|
-
from .agent_response import (
|
11
|
-
AgentResponse,
|
12
|
-
_create_agent_response_from_language_model_response,
|
13
|
-
)
|
14
|
-
from .agent_stream import AgentStream, AgentResponseChunk
|
15
|
-
from .agent_context import AgentContext
|
16
|
-
from .agent_messages import AgentMessages
|
17
|
-
|
18
|
-
|
19
|
-
__all__ = [
|
20
|
-
# hammad.genai.agents.types.agent_event
|
21
|
-
"AgentEvent",
|
22
|
-
# hammad.genai.agents.types.agent_hooks
|
23
|
-
"HookManager",
|
24
|
-
"HookDecorator",
|
25
|
-
# hammad.genai.agents.types.agent_response
|
26
|
-
"AgentResponse",
|
27
|
-
"_create_agent_response_from_language_model_response",
|
28
|
-
# hammad.genai.agents.types.agent_stream
|
29
|
-
"AgentStream",
|
30
|
-
"AgentResponseChunk",
|
31
|
-
# hammad.genai.agents.types.agent_context
|
32
|
-
"AgentContext",
|
33
|
-
# hammad.genai.agents.types.agent_messages
|
34
|
-
"AgentMessages",
|
35
|
-
]
|
36
|
-
|
37
|
-
|
38
|
-
__getattr__ = create_getattr_importer(__all__)
|
39
|
-
|
40
|
-
|
41
|
-
def __dir__() -> list[str]:
|
42
|
-
return __all__
|
@@ -1,13 +0,0 @@
|
|
1
|
-
"""hammad.genai.agents.types.agent_context"""
|
2
|
-
|
3
|
-
from typing import Dict, Any, TypeVar
|
4
|
-
from pydantic import BaseModel
|
5
|
-
|
6
|
-
|
7
|
-
__all__ = [
|
8
|
-
"AgentContext",
|
9
|
-
]
|
10
|
-
|
11
|
-
|
12
|
-
AgentContext = TypeVar("AgentContext", bound=BaseModel | Dict[str, Any])
|
13
|
-
"""A context object that can be used to store information about the agent's state."""
|
@@ -1,128 +0,0 @@
|
|
1
|
-
"""hammad.genai.agents.types.agent_event"""
|
2
|
-
|
3
|
-
from typing import Any, Dict, Optional, Literal
|
4
|
-
from openai.types.chat import ChatCompletionMessageParam, ChatCompletionContentPartParam
|
5
|
-
|
6
|
-
from ...types.base import BaseGenAIModelEvent
|
7
|
-
|
8
|
-
|
9
|
-
__all__ = [
|
10
|
-
"AgentEvent",
|
11
|
-
]
|
12
|
-
|
13
|
-
|
14
|
-
class AgentEvent(BaseGenAIModelEvent[Any]):
|
15
|
-
"""Base class for all agent events with universal event checking.
|
16
|
-
|
17
|
-
This class extends BaseGenAIModelEvent to provide agent-specific
|
18
|
-
event handling capabilities.
|
19
|
-
"""
|
20
|
-
|
21
|
-
type: Literal["agent"] = "agent"
|
22
|
-
"""The type of the model. Always 'agent'."""
|
23
|
-
|
24
|
-
model: str = "agent"
|
25
|
-
"""The model that generated this event."""
|
26
|
-
|
27
|
-
output: Any = None
|
28
|
-
"""The event data/output."""
|
29
|
-
|
30
|
-
event_type: str
|
31
|
-
"""The specific type of event (e.g., 'context_update', 'tool_call', etc.)."""
|
32
|
-
|
33
|
-
metadata: Dict[str, Any] = {}
|
34
|
-
"""Additional metadata for the event."""
|
35
|
-
|
36
|
-
def __init__(
|
37
|
-
self,
|
38
|
-
event_type: str,
|
39
|
-
data: Any = None,
|
40
|
-
metadata: Optional[Dict[str, Any]] = None,
|
41
|
-
**kwargs: Any,
|
42
|
-
):
|
43
|
-
"""Initialize an AgentEvent.
|
44
|
-
|
45
|
-
Args:
|
46
|
-
event_type: The type of event
|
47
|
-
data: The event data
|
48
|
-
metadata: Additional metadata
|
49
|
-
**kwargs: Additional keyword arguments
|
50
|
-
"""
|
51
|
-
super().__init__(
|
52
|
-
output=data, event_type=event_type, metadata=metadata or {}, **kwargs
|
53
|
-
)
|
54
|
-
|
55
|
-
def is_event(self, event_type: str) -> bool:
|
56
|
-
"""Universal event type checker."""
|
57
|
-
return self.event_type == event_type
|
58
|
-
|
59
|
-
def is_event_category(self, category: str) -> bool:
|
60
|
-
"""Check if event belongs to a category (e.g., 'tool' matches 'tool_call', 'tool_execution')."""
|
61
|
-
return self.event_type.startswith(category)
|
62
|
-
|
63
|
-
def has_metadata(self, key: str) -> bool:
|
64
|
-
"""Check if event has specific metadata."""
|
65
|
-
return key in self.metadata
|
66
|
-
|
67
|
-
def get_metadata(self, key: str, default: Any = None) -> Any:
|
68
|
-
"""Get metadata value."""
|
69
|
-
return self.metadata.get(key, default)
|
70
|
-
|
71
|
-
# Common event type checks (for convenience)
|
72
|
-
def is_context_update(self) -> bool:
|
73
|
-
return self.is_event("context_update")
|
74
|
-
|
75
|
-
def is_tool_call(self) -> bool:
|
76
|
-
return self.is_event("tool_call")
|
77
|
-
|
78
|
-
def is_tool_execution(self) -> bool:
|
79
|
-
return self.is_event("tool_execution")
|
80
|
-
|
81
|
-
def is_tool_response(self) -> bool:
|
82
|
-
return self.is_event("tool_response")
|
83
|
-
|
84
|
-
def is_final_response(self) -> bool:
|
85
|
-
return self.is_event("final_response")
|
86
|
-
|
87
|
-
def is_step_start(self) -> bool:
|
88
|
-
return self.is_event("step_start")
|
89
|
-
|
90
|
-
def is_step_end(self) -> bool:
|
91
|
-
return self.is_event("step_end")
|
92
|
-
|
93
|
-
def is_error(self) -> bool:
|
94
|
-
return self.is_event("error")
|
95
|
-
|
96
|
-
def is_stream_chunk(self) -> bool:
|
97
|
-
return self.is_event("stream_chunk")
|
98
|
-
|
99
|
-
# Category checks
|
100
|
-
def is_tool_event(self) -> bool:
|
101
|
-
return self.is_event_category("tool")
|
102
|
-
|
103
|
-
def is_context_event(self) -> bool:
|
104
|
-
return self.is_event_category("context")
|
105
|
-
|
106
|
-
def is_stream_event(self) -> bool:
|
107
|
-
return self.is_event_category("stream")
|
108
|
-
|
109
|
-
def to_message(self) -> ChatCompletionMessageParam:
|
110
|
-
"""Convert the event to a chat completion message."""
|
111
|
-
content = f"Event: {self.event_type}"
|
112
|
-
if self.output:
|
113
|
-
content += f"\nData: {self.output}"
|
114
|
-
if self.metadata:
|
115
|
-
content += f"\nMetadata: {self.metadata}"
|
116
|
-
|
117
|
-
return {"role": "assistant", "content": content}
|
118
|
-
|
119
|
-
def to_content_part(self) -> ChatCompletionContentPartParam:
|
120
|
-
"""Convert the event to a chat completion content part."""
|
121
|
-
content = f"Event: {self.event_type}"
|
122
|
-
if self.output:
|
123
|
-
content += f" - {self.output}"
|
124
|
-
|
125
|
-
return {"type": "text", "text": content}
|
126
|
-
|
127
|
-
def __repr__(self) -> str:
|
128
|
-
return f"AgentEvent(type='{self.event_type}', data={self.output}, metadata={self.metadata})"
|
@@ -1,220 +0,0 @@
|
|
1
|
-
"""hammad.genai.agents.types.agent_hooks"""
|
2
|
-
|
3
|
-
from typing import Any, Dict, List, Callable, Optional
|
4
|
-
from .agent_event import AgentEvent
|
5
|
-
|
6
|
-
|
7
|
-
__all__ = [
|
8
|
-
"HookManager",
|
9
|
-
"HookDecorator",
|
10
|
-
]
|
11
|
-
|
12
|
-
|
13
|
-
class HookManager:
|
14
|
-
"""Manages hooks for agent events."""
|
15
|
-
|
16
|
-
def __init__(self):
|
17
|
-
self.hooks: Dict[str, List[Callable]] = {}
|
18
|
-
self.specific_hooks: Dict[str, Dict[str, List[Callable]]] = {}
|
19
|
-
|
20
|
-
def register_hook(
|
21
|
-
self, event_type: str, callback: Callable, specific_name: Optional[str] = None
|
22
|
-
):
|
23
|
-
"""Register a hook for an event type.
|
24
|
-
|
25
|
-
Args:
|
26
|
-
event_type: The type of event to hook into
|
27
|
-
callback: The callback function to execute
|
28
|
-
specific_name: Optional specific name for targeted hooks
|
29
|
-
"""
|
30
|
-
if specific_name:
|
31
|
-
if event_type not in self.specific_hooks:
|
32
|
-
self.specific_hooks[event_type] = {}
|
33
|
-
if specific_name not in self.specific_hooks[event_type]:
|
34
|
-
self.specific_hooks[event_type][specific_name] = []
|
35
|
-
self.specific_hooks[event_type][specific_name].append(callback)
|
36
|
-
else:
|
37
|
-
if event_type not in self.hooks:
|
38
|
-
self.hooks[event_type] = []
|
39
|
-
self.hooks[event_type].append(callback)
|
40
|
-
|
41
|
-
def trigger_hooks(
|
42
|
-
self, event_type: str, data: Any, specific_name: Optional[str] = None
|
43
|
-
) -> Any:
|
44
|
-
"""Trigger hooks for an event type.
|
45
|
-
|
46
|
-
Args:
|
47
|
-
event_type: The type of event
|
48
|
-
data: The event data
|
49
|
-
specific_name: Optional specific name for targeted hooks
|
50
|
-
|
51
|
-
Returns:
|
52
|
-
The potentially modified data after running through hooks
|
53
|
-
"""
|
54
|
-
result = data
|
55
|
-
|
56
|
-
# Trigger general hooks
|
57
|
-
if event_type in self.hooks:
|
58
|
-
for hook in self.hooks[event_type]:
|
59
|
-
hook_result = hook(result)
|
60
|
-
if hook_result is not None:
|
61
|
-
result = hook_result
|
62
|
-
|
63
|
-
# Trigger specific hooks
|
64
|
-
if specific_name and event_type in self.specific_hooks:
|
65
|
-
if specific_name in self.specific_hooks[event_type]:
|
66
|
-
for hook in self.specific_hooks[event_type][specific_name]:
|
67
|
-
hook_result = hook(result)
|
68
|
-
if hook_result is not None:
|
69
|
-
result = hook_result
|
70
|
-
|
71
|
-
return result
|
72
|
-
|
73
|
-
def trigger_event(
|
74
|
-
self, event: AgentEvent, specific_name: Optional[str] = None
|
75
|
-
) -> Any:
|
76
|
-
"""Trigger hooks for an AgentEvent.
|
77
|
-
|
78
|
-
Args:
|
79
|
-
event: The AgentEvent instance
|
80
|
-
specific_name: Optional specific name for targeted hooks
|
81
|
-
|
82
|
-
Returns:
|
83
|
-
The potentially modified event data after running through hooks
|
84
|
-
"""
|
85
|
-
return self.trigger_hooks(event.event_type, event.output, specific_name)
|
86
|
-
|
87
|
-
def clear_hooks(
|
88
|
-
self, event_type: Optional[str] = None, specific_name: Optional[str] = None
|
89
|
-
):
|
90
|
-
"""Clear hooks for a specific event type or all hooks.
|
91
|
-
|
92
|
-
Args:
|
93
|
-
event_type: Optional event type to clear (clears all if None)
|
94
|
-
specific_name: Optional specific name to clear
|
95
|
-
"""
|
96
|
-
if event_type is None:
|
97
|
-
self.hooks.clear()
|
98
|
-
self.specific_hooks.clear()
|
99
|
-
else:
|
100
|
-
if event_type in self.hooks:
|
101
|
-
if specific_name is None:
|
102
|
-
del self.hooks[event_type]
|
103
|
-
|
104
|
-
if event_type in self.specific_hooks:
|
105
|
-
if specific_name is None:
|
106
|
-
del self.specific_hooks[event_type]
|
107
|
-
elif specific_name in self.specific_hooks[event_type]:
|
108
|
-
del self.specific_hooks[event_type][specific_name]
|
109
|
-
|
110
|
-
def list_hooks(self) -> Dict[str, Any]:
|
111
|
-
"""List all registered hooks.
|
112
|
-
|
113
|
-
Returns:
|
114
|
-
Dictionary containing all hooks information
|
115
|
-
"""
|
116
|
-
return {
|
117
|
-
"general_hooks": {k: len(v) for k, v in self.hooks.items()},
|
118
|
-
"specific_hooks": {
|
119
|
-
k: {sk: len(sv) for sk, sv in v.items()}
|
120
|
-
for k, v in self.specific_hooks.items()
|
121
|
-
},
|
122
|
-
}
|
123
|
-
|
124
|
-
|
125
|
-
class HookDecorator:
|
126
|
-
"""Provides type-hinted hook decorators with extensible event system."""
|
127
|
-
|
128
|
-
def __init__(self, hook_manager: HookManager):
|
129
|
-
self.hook_manager = hook_manager
|
130
|
-
self._event_types = set()
|
131
|
-
|
132
|
-
def __call__(self, event_type: str, specific_name: Optional[str] = None):
|
133
|
-
"""Register a hook for any event type.
|
134
|
-
|
135
|
-
Args:
|
136
|
-
event_type: The type of event to hook into
|
137
|
-
specific_name: Optional specific name for targeted hooks
|
138
|
-
|
139
|
-
Returns:
|
140
|
-
Decorator function
|
141
|
-
"""
|
142
|
-
|
143
|
-
def decorator(func: Callable):
|
144
|
-
self.hook_manager.register_hook(event_type, func, specific_name)
|
145
|
-
self._event_types.add(event_type)
|
146
|
-
return func
|
147
|
-
|
148
|
-
return decorator
|
149
|
-
|
150
|
-
def get_registered_event_types(self) -> set:
|
151
|
-
"""Get all registered event types."""
|
152
|
-
return self._event_types.copy()
|
153
|
-
|
154
|
-
def supports_event(self, event_type: str) -> bool:
|
155
|
-
"""Check if an event type is supported."""
|
156
|
-
return event_type in self._event_types
|
157
|
-
|
158
|
-
# Convenience decorators for common events
|
159
|
-
def on_context_update(self, specific_name: Optional[str] = None):
|
160
|
-
"""Decorator for context update events."""
|
161
|
-
return self.__call__("context_update", specific_name)
|
162
|
-
|
163
|
-
def on_tool_call(self, specific_name: Optional[str] = None):
|
164
|
-
"""Decorator for tool call events."""
|
165
|
-
return self.__call__("tool_call", specific_name)
|
166
|
-
|
167
|
-
def on_tool_execution(self, specific_name: Optional[str] = None):
|
168
|
-
"""Decorator for tool execution events."""
|
169
|
-
return self.__call__("tool_execution", specific_name)
|
170
|
-
|
171
|
-
def on_tool_response(self, specific_name: Optional[str] = None):
|
172
|
-
"""Decorator for tool response events."""
|
173
|
-
return self.__call__("tool_response", specific_name)
|
174
|
-
|
175
|
-
def on_final_response(self, specific_name: Optional[str] = None):
|
176
|
-
"""Decorator for final response events."""
|
177
|
-
return self.__call__("final_response", specific_name)
|
178
|
-
|
179
|
-
def on_step_start(self, specific_name: Optional[str] = None):
|
180
|
-
"""Decorator for step start events."""
|
181
|
-
return self.__call__("step_start", specific_name)
|
182
|
-
|
183
|
-
def on_step_end(self, specific_name: Optional[str] = None):
|
184
|
-
"""Decorator for step end events."""
|
185
|
-
return self.__call__("step_end", specific_name)
|
186
|
-
|
187
|
-
def on_error(self, specific_name: Optional[str] = None):
|
188
|
-
"""Decorator for error events."""
|
189
|
-
return self.__call__("error", specific_name)
|
190
|
-
|
191
|
-
def on_stream_chunk(self, specific_name: Optional[str] = None):
|
192
|
-
"""Decorator for stream chunk events."""
|
193
|
-
return self.__call__("stream_chunk", specific_name)
|
194
|
-
|
195
|
-
# Dynamic event type classes - these are created dynamically
|
196
|
-
# based on the actual events that occur in the system
|
197
|
-
def __getattr__(self, name: str):
|
198
|
-
"""Dynamically create event type classes for better type hinting."""
|
199
|
-
if name.startswith("_"):
|
200
|
-
raise AttributeError(
|
201
|
-
f"'{self.__class__.__name__}' object has no attribute '{name}'"
|
202
|
-
)
|
203
|
-
|
204
|
-
# Create a dynamic class for this event type
|
205
|
-
class DynamicEventType:
|
206
|
-
def __init__(
|
207
|
-
self, event_data: Any = None, metadata: Optional[Dict[str, Any]] = None
|
208
|
-
):
|
209
|
-
self.event_data = event_data
|
210
|
-
self.metadata = metadata or {}
|
211
|
-
|
212
|
-
def __repr__(self):
|
213
|
-
return f"{name}(data={self.event_data}, metadata={self.metadata})"
|
214
|
-
|
215
|
-
DynamicEventType.__name__ = name
|
216
|
-
DynamicEventType.__qualname__ = f"{self.__class__.__name__}.{name}"
|
217
|
-
|
218
|
-
# Cache the class
|
219
|
-
setattr(self, name, DynamicEventType)
|
220
|
-
return DynamicEventType
|
@@ -1,31 +0,0 @@
|
|
1
|
-
"""hammad.genai.agents.types.agent_messages"""
|
2
|
-
|
3
|
-
from typing import TypeAlias, Union, List, Any, TYPE_CHECKING
|
4
|
-
|
5
|
-
from ...models.language.types import LanguageModelMessages
|
6
|
-
|
7
|
-
if TYPE_CHECKING:
|
8
|
-
from openai.types.chat import ChatCompletionMessageParam
|
9
|
-
from ...types.history import History
|
10
|
-
|
11
|
-
|
12
|
-
__all__ = [
|
13
|
-
"AgentMessages",
|
14
|
-
]
|
15
|
-
|
16
|
-
|
17
|
-
AgentMessages: TypeAlias = Union[
|
18
|
-
str,
|
19
|
-
"ChatCompletionMessageParam",
|
20
|
-
"List[ChatCompletionMessageParam]",
|
21
|
-
"History",
|
22
|
-
LanguageModelMessages,
|
23
|
-
Any,
|
24
|
-
]
|
25
|
-
"""Type alias for agent message inputs that extends LanguageModelMessages to include History objects.
|
26
|
-
|
27
|
-
This type alias allows agents to accept:
|
28
|
-
- All standard LanguageModelMessages types (str, ChatCompletionMessageParam, List[ChatCompletionMessageParam])
|
29
|
-
- History objects for conversation history management
|
30
|
-
- Any other type for flexibility
|
31
|
-
"""
|
@@ -1,125 +0,0 @@
|
|
1
|
-
"""hammad.genai.agents.types.agent_response"""
|
2
|
-
|
3
|
-
from typing import List, Any, TypeVar, Literal, Generic
|
4
|
-
from pydantic import Field
|
5
|
-
|
6
|
-
from ....cache import cached
|
7
|
-
from ....typing import get_type_description
|
8
|
-
from ...models.language.types import (
|
9
|
-
LanguageModelResponse,
|
10
|
-
)
|
11
|
-
|
12
|
-
from .agent_context import AgentContext
|
13
|
-
|
14
|
-
__all__ = [
|
15
|
-
"AgentResponse",
|
16
|
-
"_create_agent_response_from_language_model_response",
|
17
|
-
]
|
18
|
-
|
19
|
-
|
20
|
-
T = TypeVar("T")
|
21
|
-
|
22
|
-
|
23
|
-
def _create_agent_response_from_language_model_response(
|
24
|
-
response: LanguageModelResponse[T],
|
25
|
-
steps: List[LanguageModelResponse[str]] | None = None,
|
26
|
-
context: Any = None,
|
27
|
-
) -> "AgentResponse[T]":
|
28
|
-
"""Create a AgentResponse from a LanguageModelResponse."""
|
29
|
-
try:
|
30
|
-
return AgentResponse(
|
31
|
-
type="agent",
|
32
|
-
model=response.model,
|
33
|
-
output=response.output,
|
34
|
-
content=response.content,
|
35
|
-
completion=response.completion,
|
36
|
-
refusal=response.refusal,
|
37
|
-
steps=steps or [],
|
38
|
-
context=context,
|
39
|
-
)
|
40
|
-
except Exception as e:
|
41
|
-
raise ValueError(
|
42
|
-
"Failed to create AgentResponse from LanguageModelResponse."
|
43
|
-
) from e
|
44
|
-
|
45
|
-
|
46
|
-
class AgentResponse(LanguageModelResponse[T], Generic[T, AgentContext]):
|
47
|
-
"""A response generated by an agent, that includes the steps and final
|
48
|
-
output during the agent's execution."""
|
49
|
-
|
50
|
-
type: Literal["agent"] = "agent"
|
51
|
-
"""The type of the response. Always `agent`."""
|
52
|
-
|
53
|
-
steps: List[LanguageModelResponse[str]] = Field(default_factory=list)
|
54
|
-
"""
|
55
|
-
A list of steps taken by the agent **BEFORE** its final output.
|
56
|
-
|
57
|
-
NOTE: If the final output was also the first step, this will be
|
58
|
-
empty.
|
59
|
-
"""
|
60
|
-
|
61
|
-
context: AgentContext | None = None
|
62
|
-
"""
|
63
|
-
The final context object after agent execution.
|
64
|
-
|
65
|
-
This is always the final version of the context after any updates
|
66
|
-
have been applied during the agent's execution.
|
67
|
-
"""
|
68
|
-
|
69
|
-
@cached
|
70
|
-
def __str__(self) -> str:
|
71
|
-
"""Pretty prints the response object."""
|
72
|
-
output = ">>> AgentResponse:"
|
73
|
-
|
74
|
-
if self.output or self.content:
|
75
|
-
output += f"\n{self.output if self.output else self.content}"
|
76
|
-
else:
|
77
|
-
output += f"\n{self.completion}"
|
78
|
-
|
79
|
-
output += f"\n\n>>> Model: {self.model}"
|
80
|
-
# NOTE:
|
81
|
-
# added +1 to include final step in the output
|
82
|
-
output += f"\n>>> Steps: {len(self.steps) + 1}"
|
83
|
-
output += f"\n>>> Output Type: {get_type_description(type(self.output))}"
|
84
|
-
|
85
|
-
# Calculate total tool calls across all steps
|
86
|
-
total_tool_calls = 0
|
87
|
-
for step in self.steps:
|
88
|
-
if step.has_tool_calls():
|
89
|
-
total_tool_calls += len(step.tool_calls)
|
90
|
-
|
91
|
-
output += f"\n>>> Total Tool Calls: {total_tool_calls}"
|
92
|
-
|
93
|
-
# Show context if available
|
94
|
-
if self.context:
|
95
|
-
output += (
|
96
|
-
f"\n>>> Final Context: {self._format_context_display(self.context)}"
|
97
|
-
)
|
98
|
-
|
99
|
-
return output
|
100
|
-
|
101
|
-
def _format_context_display(self, context: AgentContext) -> str:
|
102
|
-
"""Format context for display in string representation."""
|
103
|
-
if context is None:
|
104
|
-
return "None"
|
105
|
-
|
106
|
-
try:
|
107
|
-
# For Pydantic models, show as dict
|
108
|
-
if hasattr(context, "model_dump"):
|
109
|
-
context_dict = context.model_dump()
|
110
|
-
elif isinstance(context, dict):
|
111
|
-
context_dict = context
|
112
|
-
else:
|
113
|
-
return str(context)
|
114
|
-
|
115
|
-
# Format as compact JSON-like string
|
116
|
-
items = []
|
117
|
-
for key, value in context_dict.items():
|
118
|
-
if isinstance(value, str):
|
119
|
-
items.append(f"{key}='{value}'")
|
120
|
-
else:
|
121
|
-
items.append(f"{key}={value}")
|
122
|
-
|
123
|
-
return "{" + ", ".join(items) + "}"
|
124
|
-
except Exception:
|
125
|
-
return str(context)
|