hammad-python 0.0.25__py3-none-any.whl → 0.0.27__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 +2 -0
- hammad/data/collections/collection.py +32 -3
- hammad/genai/graphs/_utils.py +190 -0
- hammad/genai/graphs/base.py +56 -14
- hammad/genai/models/language/types/language_model_response.py +2 -0
- {hammad_python-0.0.25.dist-info → hammad_python-0.0.27.dist-info}/METADATA +1 -1
- {hammad_python-0.0.25.dist-info → hammad_python-0.0.27.dist-info}/RECORD +9 -8
- {hammad_python-0.0.25.dist-info → hammad_python-0.0.27.dist-info}/WHEEL +0 -0
- {hammad_python-0.0.25.dist-info → hammad_python-0.0.27.dist-info}/licenses/LICENSE +0 -0
hammad/__init__.py
CHANGED
@@ -222,7 +222,16 @@ def create_collection(
|
|
222
222
|
distance_metric: "DistanceMetric" = "dot",
|
223
223
|
settings: Optional["QdrantCollectionIndexSettings"] = None,
|
224
224
|
query_settings: Optional["QdrantCollectionIndexQuerySettings"] = None,
|
225
|
-
|
225
|
+
embedding_model: Optional[
|
226
|
+
"EmbeddingModelName"
|
227
|
+
] = "openai/text-embedding-3-small",
|
228
|
+
embedding_dimensions: Optional[int] = None,
|
229
|
+
embedding_api_key: Optional[str] = None,
|
230
|
+
embedding_base_url: Optional[str] = None,
|
231
|
+
# Rerank-specific parameters
|
232
|
+
rerank_model: Optional[str] = None,
|
233
|
+
rerank_api_key: Optional[str] = None,
|
234
|
+
rerank_base_url: Optional[str] = None,
|
226
235
|
) -> "QdrantCollectionIndex": ...
|
227
236
|
|
228
237
|
|
@@ -247,7 +256,16 @@ def create_collection(
|
|
247
256
|
] = None,
|
248
257
|
# Vector/Qdrant-specific parameters
|
249
258
|
distance_metric: "DistanceMetric" = "dot",
|
250
|
-
|
259
|
+
embedding_model: Optional[
|
260
|
+
"EmbeddingModelName"
|
261
|
+
] = "openai/text-embedding-3-small",
|
262
|
+
embedding_dimensions: Optional[int] = None,
|
263
|
+
embedding_api_key: Optional[str] = None,
|
264
|
+
embedding_base_url: Optional[str] = None,
|
265
|
+
# Rerank-specific parameters
|
266
|
+
rerank_model: Optional[str] = None,
|
267
|
+
rerank_api_key: Optional[str] = None,
|
268
|
+
rerank_base_url: Optional[str] = None,
|
251
269
|
) -> Union["TantivyCollectionIndex", "QdrantCollectionIndex"]:
|
252
270
|
"""
|
253
271
|
Create a data collection of the specified type. Collections are a unified
|
@@ -275,6 +293,11 @@ def create_collection(
|
|
275
293
|
embedding_api_key: API key for the embedding service
|
276
294
|
embedding_base_url: Base URL for the embedding service
|
277
295
|
|
296
|
+
# Rerank parameters (for vector collections):
|
297
|
+
rerank_model: The rerank model to use (e.g., 'cohere/rerank-english-v3.0')
|
298
|
+
rerank_api_key: API key for the rerank service
|
299
|
+
rerank_base_url: Base URL for the rerank service
|
300
|
+
|
278
301
|
Returns:
|
279
302
|
A TantivyCollectionIndex or QdrantCollectionIndex instance
|
280
303
|
"""
|
@@ -289,5 +312,11 @@ def create_collection(
|
|
289
312
|
settings=settings,
|
290
313
|
query_settings=query_settings,
|
291
314
|
distance_metric=distance_metric,
|
292
|
-
|
315
|
+
embedding_model=embedding_model,
|
316
|
+
embedding_dimensions=embedding_dimensions,
|
317
|
+
embedding_api_key=embedding_api_key,
|
318
|
+
embedding_base_url=embedding_base_url,
|
319
|
+
rerank_model=rerank_model,
|
320
|
+
rerank_api_key=rerank_api_key,
|
321
|
+
rerank_base_url=rerank_base_url,
|
293
322
|
)
|
@@ -0,0 +1,190 @@
|
|
1
|
+
|
2
|
+
from typing import TYPE_CHECKING
|
3
|
+
|
4
|
+
if TYPE_CHECKING:
|
5
|
+
from .base import BaseGraph
|
6
|
+
|
7
|
+
|
8
|
+
def visualize_base_graph(graph: "BaseGraph", filename: str) -> None:
|
9
|
+
"""Generate a visualization of the graph with clean, readable flow."""
|
10
|
+
if not graph._action_nodes or not graph._start_action_name:
|
11
|
+
raise ValueError("No actions defined in graph")
|
12
|
+
|
13
|
+
# Build our own mermaid code for better control over layout
|
14
|
+
mermaid_lines = ["graph TD"] # Top-Down layout
|
15
|
+
|
16
|
+
# Track which nodes we've already added
|
17
|
+
added_nodes = set()
|
18
|
+
|
19
|
+
# Style definitions
|
20
|
+
mermaid_lines.append(" %% Styles")
|
21
|
+
mermaid_lines.append(" classDef startNode fill:#4CAF50,stroke:#333,stroke-width:2px,color:#fff")
|
22
|
+
mermaid_lines.append(" classDef endNode fill:#f44336,stroke:#333,stroke-width:2px,color:#fff")
|
23
|
+
mermaid_lines.append(" classDef defaultNode fill:#2196F3,stroke:#333,stroke-width:2px,color:#fff")
|
24
|
+
mermaid_lines.append("")
|
25
|
+
|
26
|
+
# Helper to get clean node ID
|
27
|
+
def get_node_id(action_name: str) -> str:
|
28
|
+
return action_name.replace(" ", "_").replace("-", "_")
|
29
|
+
|
30
|
+
# Helper to add a node if not already added
|
31
|
+
def add_node(action_name: str, is_start: bool = False, is_end: bool = False) -> None:
|
32
|
+
if action_name not in added_nodes:
|
33
|
+
node_id = get_node_id(action_name)
|
34
|
+
# Use the action name as the display label
|
35
|
+
display_name = action_name
|
36
|
+
|
37
|
+
if is_start:
|
38
|
+
mermaid_lines.append(f" {node_id}[{display_name}]:::startNode")
|
39
|
+
elif is_end:
|
40
|
+
mermaid_lines.append(f" {node_id}[{display_name}]:::endNode")
|
41
|
+
else:
|
42
|
+
mermaid_lines.append(f" {node_id}[{display_name}]:::defaultNode")
|
43
|
+
added_nodes.add(action_name)
|
44
|
+
|
45
|
+
# Add all nodes and connections
|
46
|
+
mermaid_lines.append(" %% Nodes and connections")
|
47
|
+
|
48
|
+
# Start with the start node
|
49
|
+
add_node(graph._start_action_name, is_start=True)
|
50
|
+
|
51
|
+
# Process all actions to find connections
|
52
|
+
for action_name in graph._action_nodes:
|
53
|
+
action_func = getattr(graph, action_name, None)
|
54
|
+
if action_func and hasattr(action_func, '_action_settings'):
|
55
|
+
settings = action_func._action_settings
|
56
|
+
|
57
|
+
# Add the node
|
58
|
+
add_node(action_name, is_end=settings.terminates)
|
59
|
+
|
60
|
+
# Add connections based on 'next' settings
|
61
|
+
if settings.next:
|
62
|
+
source_id = get_node_id(action_name)
|
63
|
+
|
64
|
+
if isinstance(settings.next, str):
|
65
|
+
# Simple string case
|
66
|
+
target_id = get_node_id(settings.next)
|
67
|
+
add_node(settings.next)
|
68
|
+
mermaid_lines.append(f" {source_id} --> {target_id}")
|
69
|
+
|
70
|
+
elif isinstance(settings.next, list):
|
71
|
+
# List case - branches to multiple nodes
|
72
|
+
for next_action in settings.next:
|
73
|
+
if isinstance(next_action, str):
|
74
|
+
target_id = get_node_id(next_action)
|
75
|
+
add_node(next_action)
|
76
|
+
mermaid_lines.append(f" {source_id} --> {target_id}")
|
77
|
+
|
78
|
+
elif hasattr(settings.next, '__class__') and settings.next.__class__.__name__ == 'SelectionStrategy':
|
79
|
+
# SelectionStrategy case
|
80
|
+
if settings.next.actions:
|
81
|
+
# Show all possible paths with a decision diamond
|
82
|
+
decision_id = f"{source_id}_decision"
|
83
|
+
mermaid_lines.append(f" {source_id} --> {decision_id}{{LLM Selection}}")
|
84
|
+
|
85
|
+
for next_action in settings.next.actions:
|
86
|
+
target_id = get_node_id(next_action)
|
87
|
+
add_node(next_action)
|
88
|
+
mermaid_lines.append(f" {decision_id} --> {target_id}")
|
89
|
+
else:
|
90
|
+
# If no specific actions, it can go to any node
|
91
|
+
# For visualization, show connections to all non-start nodes
|
92
|
+
decision_id = f"{source_id}_decision"
|
93
|
+
mermaid_lines.append(f" {source_id} --> {decision_id}{{LLM Selection}}")
|
94
|
+
|
95
|
+
for other_action in graph._action_nodes:
|
96
|
+
if other_action != action_name and other_action != graph._start_action_name:
|
97
|
+
target_id = get_node_id(other_action)
|
98
|
+
add_node(other_action)
|
99
|
+
mermaid_lines.append(f" {decision_id} -.-> {target_id}")
|
100
|
+
|
101
|
+
# If start node has no explicit next, but there are other nodes, show possible connections
|
102
|
+
start_func = getattr(graph, graph._start_action_name, None)
|
103
|
+
if start_func and hasattr(start_func, '_action_settings'):
|
104
|
+
if not start_func._action_settings.next and len(graph._action_nodes) > 1:
|
105
|
+
source_id = get_node_id(graph._start_action_name)
|
106
|
+
# Find end nodes (terminates=True) to connect to
|
107
|
+
for action_name in graph._action_nodes:
|
108
|
+
if action_name != graph._start_action_name:
|
109
|
+
action_func = getattr(graph, action_name, None)
|
110
|
+
if action_func and hasattr(action_func, '_action_settings'):
|
111
|
+
if action_func._action_settings.terminates:
|
112
|
+
target_id = get_node_id(action_name)
|
113
|
+
add_node(action_name, is_end=True)
|
114
|
+
mermaid_lines.append(f" {source_id} --> {target_id}")
|
115
|
+
|
116
|
+
# Join all lines
|
117
|
+
mermaid_code = "\n".join(mermaid_lines)
|
118
|
+
|
119
|
+
# Render the mermaid diagram and save it
|
120
|
+
try:
|
121
|
+
import subprocess
|
122
|
+
import tempfile
|
123
|
+
import os
|
124
|
+
import shutil
|
125
|
+
|
126
|
+
# Check if mmdc (mermaid CLI) is available
|
127
|
+
if shutil.which('mmdc') is None:
|
128
|
+
raise FileNotFoundError("mermaid-cli (mmdc) not found. Install with: npm install -g @mermaid-js/mermaid-cli")
|
129
|
+
|
130
|
+
# Create a temporary mermaid file
|
131
|
+
with tempfile.NamedTemporaryFile(mode='w', suffix='.mmd', delete=False) as temp_file:
|
132
|
+
temp_file.write(mermaid_code)
|
133
|
+
temp_mmd_path = temp_file.name
|
134
|
+
|
135
|
+
try:
|
136
|
+
# Determine output format from filename extension
|
137
|
+
output_format = 'png' # default
|
138
|
+
if filename.lower().endswith('.svg'):
|
139
|
+
output_format = 'svg'
|
140
|
+
elif filename.lower().endswith('.pdf'):
|
141
|
+
output_format = 'pdf'
|
142
|
+
|
143
|
+
# Use mermaid CLI to render the diagram
|
144
|
+
cmd = ['mmdc', '-i', temp_mmd_path, '-o', filename]
|
145
|
+
|
146
|
+
# Add format flag only if not PNG (PNG is default)
|
147
|
+
if output_format != 'png':
|
148
|
+
cmd.extend(['-f', output_format])
|
149
|
+
|
150
|
+
# Add theme and background color
|
151
|
+
cmd.extend(['-t', 'default', '-b', 'transparent'])
|
152
|
+
|
153
|
+
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
|
154
|
+
|
155
|
+
if result.returncode == 0:
|
156
|
+
print(f"Graph visualization saved to: {filename}")
|
157
|
+
else:
|
158
|
+
raise subprocess.CalledProcessError(result.returncode, result.args, result.stderr)
|
159
|
+
|
160
|
+
finally:
|
161
|
+
# Clean up temporary file
|
162
|
+
if os.path.exists(temp_mmd_path):
|
163
|
+
os.unlink(temp_mmd_path)
|
164
|
+
|
165
|
+
except FileNotFoundError as e:
|
166
|
+
# Provide helpful error message for missing mermaid CLI
|
167
|
+
print(f"Warning: {e}")
|
168
|
+
# Save as .mmd file instead
|
169
|
+
mmd_filename = filename.rsplit('.', 1)[0] + '.mmd'
|
170
|
+
with open(mmd_filename, "w") as f:
|
171
|
+
f.write(mermaid_code)
|
172
|
+
print(f"Mermaid code saved to: {mmd_filename}")
|
173
|
+
print("To render as PNG, install mermaid-cli: npm install -g @mermaid-js/mermaid-cli")
|
174
|
+
|
175
|
+
except subprocess.CalledProcessError as e:
|
176
|
+
# Handle mermaid CLI errors
|
177
|
+
print(f"Error rendering mermaid diagram: {e.stderr if e.stderr else str(e)}")
|
178
|
+
# Save as .mmd file as fallback
|
179
|
+
mmd_filename = filename.rsplit('.', 1)[0] + '.mmd'
|
180
|
+
with open(mmd_filename, "w") as f:
|
181
|
+
f.write(mermaid_code)
|
182
|
+
print(f"Mermaid code saved to: {mmd_filename} (rendering failed)")
|
183
|
+
|
184
|
+
except Exception as e:
|
185
|
+
# General fallback: save the mermaid code
|
186
|
+
print(f"Unexpected error: {e}")
|
187
|
+
mmd_filename = filename.rsplit('.', 1)[0] + '.mmd'
|
188
|
+
with open(mmd_filename, "w") as f:
|
189
|
+
f.write(mermaid_code)
|
190
|
+
print(f"Mermaid code saved to: {mmd_filename}")
|
hammad/genai/graphs/base.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
"""hammad.genai.graphs.base
|
1
|
+
"""hammad.genai.graphs.base"""
|
2
2
|
|
3
3
|
from typing import (
|
4
4
|
Any,
|
@@ -44,6 +44,7 @@ from .types import (
|
|
44
44
|
ActionSettings,
|
45
45
|
GraphHistoryEntry,
|
46
46
|
)
|
47
|
+
from ._utils import visualize_base_graph
|
47
48
|
|
48
49
|
if TYPE_CHECKING:
|
49
50
|
try:
|
@@ -825,6 +826,29 @@ class ActionDecorator:
|
|
825
826
|
|
826
827
|
def decorator(f: Callable) -> Callable:
|
827
828
|
action_name = name or f.__name__
|
829
|
+
|
830
|
+
# Check if action name is reserved
|
831
|
+
reserved_names = {
|
832
|
+
'run', 'async_run', 'iter', 'async_iter',
|
833
|
+
'visualize', 'builder', 'as_a2a',
|
834
|
+
'_initialize', '_collect_state_class', '_collect_actions',
|
835
|
+
'_create_pydantic_graph', '_get_start_action_signature'
|
836
|
+
}
|
837
|
+
if action_name in reserved_names:
|
838
|
+
raise ValueError(
|
839
|
+
f"Action name '{action_name}' is reserved and cannot be used. "
|
840
|
+
f"Reserved names include: {', '.join(sorted(reserved_names))}. "
|
841
|
+
"Please choose a different name for your action."
|
842
|
+
)
|
843
|
+
|
844
|
+
# Check that the action has at least one parameter besides 'self'
|
845
|
+
sig = inspect.signature(f)
|
846
|
+
params = [p for p in sig.parameters if p != 'self']
|
847
|
+
if not params:
|
848
|
+
raise ValueError(
|
849
|
+
f"Action '{action_name}' must have at least one parameter besides 'self'. "
|
850
|
+
"Actions need input parameters to process."
|
851
|
+
)
|
828
852
|
|
829
853
|
# Create a dynamic ActionNode class for this specific action with unique name
|
830
854
|
class DynamicActionNode(ActionNode[StateT]):
|
@@ -921,7 +945,7 @@ class BaseGraph(Generic[StateT, T]):
|
|
921
945
|
self,
|
922
946
|
state: Optional[StateT] = None,
|
923
947
|
*,
|
924
|
-
model: Optional[LanguageModelName | str] =
|
948
|
+
model: Optional[LanguageModelName | str] = "openai/gpt-4.1-nano",
|
925
949
|
temperature: Optional[float] = None,
|
926
950
|
max_tokens: Optional[int] = None,
|
927
951
|
tools: Optional[List[Callable]] = None,
|
@@ -1160,6 +1184,10 @@ class BaseGraph(Generic[StateT, T]):
|
|
1160
1184
|
# Merge global settings with provided kwargs
|
1161
1185
|
merged_settings = self._global_settings.copy()
|
1162
1186
|
merged_settings.update(language_model_kwargs)
|
1187
|
+
|
1188
|
+
# Include the global model if it's set and not overridden
|
1189
|
+
if self._global_model and "model" not in merged_settings:
|
1190
|
+
merged_settings["model"] = self._global_model
|
1163
1191
|
|
1164
1192
|
# Pass verbose/debug flags (prefer explicit params over global settings)
|
1165
1193
|
start_node._verbose = (
|
@@ -1329,6 +1357,10 @@ class BaseGraph(Generic[StateT, T]):
|
|
1329
1357
|
# Merge global settings with provided kwargs
|
1330
1358
|
merged_settings = self._global_settings.copy()
|
1331
1359
|
merged_settings.update(language_model_kwargs)
|
1360
|
+
|
1361
|
+
# Include the global model if it's set and not overridden
|
1362
|
+
if self._global_model and "model" not in merged_settings:
|
1363
|
+
merged_settings["model"] = self._global_model
|
1332
1364
|
|
1333
1365
|
# Pass verbose/debug flags (prefer explicit params over global settings)
|
1334
1366
|
start_node._verbose = (
|
@@ -1466,6 +1498,10 @@ class BaseGraph(Generic[StateT, T]):
|
|
1466
1498
|
# Merge global settings with provided kwargs
|
1467
1499
|
merged_settings = self._global_settings.copy()
|
1468
1500
|
merged_settings.update(language_model_kwargs)
|
1501
|
+
|
1502
|
+
# Include the global model if it's set and not overridden
|
1503
|
+
if self._global_model and "model" not in merged_settings:
|
1504
|
+
merged_settings["model"] = self._global_model
|
1469
1505
|
|
1470
1506
|
# Pass verbose/debug flags (prefer explicit params over global settings)
|
1471
1507
|
start_node._verbose = (
|
@@ -1634,6 +1670,10 @@ class BaseGraph(Generic[StateT, T]):
|
|
1634
1670
|
# Merge global settings with provided kwargs
|
1635
1671
|
merged_settings = self._global_settings.copy()
|
1636
1672
|
merged_settings.update(language_model_kwargs)
|
1673
|
+
|
1674
|
+
# Include the global model if it's set and not overridden
|
1675
|
+
if self._global_model and "model" not in merged_settings:
|
1676
|
+
merged_settings["model"] = self._global_model
|
1637
1677
|
|
1638
1678
|
# Pass verbose/debug flags (prefer explicit params over global settings)
|
1639
1679
|
start_node._verbose = (
|
@@ -1678,18 +1718,6 @@ class BaseGraph(Generic[StateT, T]):
|
|
1678
1718
|
**language_model_kwargs,
|
1679
1719
|
)
|
1680
1720
|
|
1681
|
-
def visualize(self, filename: str) -> None:
|
1682
|
-
"""Generate a visualization of the graph using pydantic-graph's mermaid support."""
|
1683
|
-
if self._pydantic_graph and self._start_action_name:
|
1684
|
-
start_node_class = self._action_nodes.get(self._start_action_name)
|
1685
|
-
if start_node_class:
|
1686
|
-
# Use pydantic-graph's built-in mermaid generation
|
1687
|
-
mermaid_code = self._pydantic_graph.mermaid_code(
|
1688
|
-
start_node=start_node_class
|
1689
|
-
)
|
1690
|
-
with open(filename, "w") as f:
|
1691
|
-
f.write(mermaid_code)
|
1692
|
-
|
1693
1721
|
@classmethod
|
1694
1722
|
def builder(cls) -> GraphBuilder[StateT, T]:
|
1695
1723
|
"""Create a builder for this graph."""
|
@@ -1784,3 +1812,17 @@ class BaseGraph(Generic[StateT, T]):
|
|
1784
1812
|
lifespan_timeout=lifespan_timeout,
|
1785
1813
|
**uvicorn_kwargs,
|
1786
1814
|
)
|
1815
|
+
|
1816
|
+
def visualize(self, filename: str) -> None:
|
1817
|
+
"""Visualize the graph as mermaid.
|
1818
|
+
|
1819
|
+
Args:
|
1820
|
+
filename: The filename to save the visualization to.
|
1821
|
+
|
1822
|
+
Ex: 'graph.png' / 'graph.mmd'
|
1823
|
+
|
1824
|
+
Returns:
|
1825
|
+
None
|
1826
|
+
|
1827
|
+
"""
|
1828
|
+
visualize_base_graph(self, filename)
|
@@ -13,6 +13,7 @@ from typing import (
|
|
13
13
|
)
|
14
14
|
|
15
15
|
from .....cache import cached
|
16
|
+
from .....typing import get_type_description
|
16
17
|
|
17
18
|
from ...model_provider import litellm
|
18
19
|
from ....types.base import BaseGenAIModelResponse
|
@@ -210,6 +211,7 @@ class LanguageModelResponse(BaseGenAIModelResponse[T]):
|
|
210
211
|
output += f"\n{self.completion}"
|
211
212
|
|
212
213
|
output += f"\n\n>>> Model: {self.model}"
|
214
|
+
output += f"\n>>> Type: {get_type_description(type(self.output))}"
|
213
215
|
output += f"\n>>> Tool Calls: {len(self.tool_calls) if self.tool_calls else 0}"
|
214
216
|
|
215
217
|
return output
|
@@ -1,4 +1,4 @@
|
|
1
|
-
hammad/__init__.py,sha256=
|
1
|
+
hammad/__init__.py,sha256=PtKUoTlLLfTA8cuhfvvaG1PCz6B4gkyl4d0OgZA0rNY,1705
|
2
2
|
hammad/_internal.py,sha256=qQGXjzQyyCxzH5kMjCHwVdAojp-2OOVAO2T2QDxOBn8,8957
|
3
3
|
hammad/_main.py,sha256=2y18WxvGqRtA0C4aaYK9-LhFXwhFvY6832kNmUyebRA,6902
|
4
4
|
hammad/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -18,7 +18,7 @@ hammad/cli/styles/types.py,sha256=vNIeQY_23m10K8qVT7Iy-PMwosGL-La-UAZKszHJjEE,79
|
|
18
18
|
hammad/cli/styles/utils.py,sha256=zzi0JdH1X7O8XWRlMVfJP2jB-OWt7zkpm_LeCHoSKVY,28287
|
19
19
|
hammad/data/__init__.py,sha256=rga828Od--N3QeGlnOSweADD1WsRLjSTqkaZVk1VhW0,2232
|
20
20
|
hammad/data/collections/__init__.py,sha256=xEORHnjoV75Fa6LFDMyFw90oDaJ0e9VmISLFV3mOsIQ,1110
|
21
|
-
hammad/data/collections/collection.py,sha256=
|
21
|
+
hammad/data/collections/collection.py,sha256=SvmZY0B5_VDMQGX72TxLs9BMeDs8kASmROQca_F3534,11989
|
22
22
|
hammad/data/collections/indexes/__init__.py,sha256=RmXKWKq2sbtA1swz5vamKKWut-eKfc-Q2tUnij-E-IU,960
|
23
23
|
hammad/data/collections/indexes/qdrant/__init__.py,sha256=KU89TIJkYmJPnVxWKHfXntkIYwhn86ejXtWG30hCyHg,49
|
24
24
|
hammad/data/collections/indexes/qdrant/index.py,sha256=UzhW64i5Yq5AXyGZjkW4dljgQxwKUbjF6vhzendbjko,25634
|
@@ -68,7 +68,8 @@ hammad/genai/agents/types/agent_messages.py,sha256=csjEq42bElaTZYZW2dE6nlFZc142-
|
|
68
68
|
hammad/genai/agents/types/agent_response.py,sha256=tQ3oNBZC_9dD7t-7tRuKA2h1a-XE5gGryVF9XcmZ5GA,3863
|
69
69
|
hammad/genai/agents/types/agent_stream.py,sha256=VIfqZp55wq6jQh_OtPzZjiL_K4cEoVCkeEZS3s_MIXI,11069
|
70
70
|
hammad/genai/graphs/__init__.py,sha256=bK59ilXuR46DgSjat7kOOr_KujIpJSfbCSgriceRhjw,3112
|
71
|
-
hammad/genai/graphs/
|
71
|
+
hammad/genai/graphs/_utils.py,sha256=kLPD9iAWhI7zRDTNLnYGRrD2f2IPre-0GYLMQcq1xzU,8854
|
72
|
+
hammad/genai/graphs/base.py,sha256=02kLcQRFJxGw-rPlfFBDWW9C9_CAlPYHdlTwu7rg7nA,69633
|
72
73
|
hammad/genai/graphs/plugins.py,sha256=AK_JSo2eLCD9cdrxZ5OxxZtLVrUDcQ8f_FWBxOQPzyw,10007
|
73
74
|
hammad/genai/graphs/types.py,sha256=kpQvWpE7cKjK9TzNFa_I-z7LfxWdlCuIA-lfRTk_nFU,20701
|
74
75
|
hammad/genai/models/__init__.py,sha256=e4TbEsiKIoXENOEsdIdQcWWt0RnFdTEqCz0nICHQHtM,26
|
@@ -91,7 +92,7 @@ hammad/genai/models/language/types/language_model_instructor_mode.py,sha256=7ywB
|
|
91
92
|
hammad/genai/models/language/types/language_model_messages.py,sha256=e-HZ_YKXq17gwmMlpOmYUYUpBFm7Mu3aRawtjSslWXs,504
|
92
93
|
hammad/genai/models/language/types/language_model_name.py,sha256=2V70cZ47L9yIcug6LCcMHcvEJaee7gRN6DUPhLUBlsE,8056
|
93
94
|
hammad/genai/models/language/types/language_model_request.py,sha256=ZtzhCx8o6zkEBS3uTFXFLf_poDD7MnIp1y7MbKckOmI,3911
|
94
|
-
hammad/genai/models/language/types/language_model_response.py,sha256=
|
95
|
+
hammad/genai/models/language/types/language_model_response.py,sha256=CE-PWxmAB9RDzHqGjEUvYaVnbDnKYz4eEMW4Fz65F4s,7640
|
95
96
|
hammad/genai/models/language/types/language_model_response_chunk.py,sha256=wIzGZw732KsI-a1-uASjATA6qvBuq-7rupWoFjsAgQo,1796
|
96
97
|
hammad/genai/models/language/types/language_model_settings.py,sha256=C0EvLXZoOLgPZ4bX7mVFs_CWP-jam27qkseJRGsBAfQ,2794
|
97
98
|
hammad/genai/models/language/types/language_model_stream.py,sha256=XgJ83JSbtTdf7jeLQMrDhMfI7zp0pRrdY7JWYbZV_h0,22043
|
@@ -128,7 +129,7 @@ hammad/web/openapi/__init__.py,sha256=JhJQ6_laBmB2djIYFc0vgGha2GsdUe4FP1LDdZCQ5J
|
|
128
129
|
hammad/web/openapi/client.py,sha256=1pXz7KAO_0pN4kQZoWKWskXDYGiJ535TsPO1GGCiC0E,26816
|
129
130
|
hammad/web/search/__init__.py,sha256=e9A6znPIiZCz-4secyHbUs0uUGf5yAqW6wGacgx961U,24
|
130
131
|
hammad/web/search/client.py,sha256=LIx2MsHhn6cRTuq5i1mWowRTdIhPobY4GQV3S3bk9lk,36694
|
131
|
-
hammad_python-0.0.
|
132
|
-
hammad_python-0.0.
|
133
|
-
hammad_python-0.0.
|
134
|
-
hammad_python-0.0.
|
132
|
+
hammad_python-0.0.27.dist-info/METADATA,sha256=WfL-hAEfVrPhAwRn3cBaEdm0EfaVIv3RYfz54OkLv08,6785
|
133
|
+
hammad_python-0.0.27.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
134
|
+
hammad_python-0.0.27.dist-info/licenses/LICENSE,sha256=h74yFUWjbBaodcWG5wNmm30npjl8obVcxD-1nQfUp2I,1069
|
135
|
+
hammad_python-0.0.27.dist-info/RECORD,,
|
File without changes
|
File without changes
|