agents24 0.1.0__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.
- agents24/__init__.py +10 -0
- agents24/artifacts.py +60 -0
- agents24/builders.py +130 -0
- agents24/client.py +52 -0
- agents24/errors.py +19 -0
- agents24/generated/__init__.py +3 -0
- agents24/generated/agents.py +67 -0
- agents24/generated/embed.py +63 -0
- agents24/generated/manifest.py +28 -0
- agents24/generated/runs.py +28 -0
- agents24/http.py +178 -0
- agents24/sse.py +57 -0
- agents24/types.py +56 -0
- agents24-0.1.0.dist-info/METADATA +72 -0
- agents24-0.1.0.dist-info/RECORD +17 -0
- agents24-0.1.0.dist-info/WHEEL +5 -0
- agents24-0.1.0.dist-info/top_level.txt +1 -0
agents24/__init__.py
ADDED
agents24/artifacts.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
_EXPORTS = []
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def _json_schema(value):
|
|
5
|
+
if value is None:
|
|
6
|
+
return {}
|
|
7
|
+
if isinstance(value, dict):
|
|
8
|
+
return value
|
|
9
|
+
if hasattr(value, "model_json_schema"):
|
|
10
|
+
return value.model_json_schema()
|
|
11
|
+
if hasattr(value, "schema"):
|
|
12
|
+
return value.schema()
|
|
13
|
+
raise TypeError("schema must be a JSON Schema dict or a Pydantic model")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _register(kind, fn=None, **options):
|
|
17
|
+
def decorate(handler):
|
|
18
|
+
name = str(options.get("name") or handler.__name__).strip()
|
|
19
|
+
_EXPORTS.append(
|
|
20
|
+
{
|
|
21
|
+
"name": name,
|
|
22
|
+
"kind": kind,
|
|
23
|
+
"description": options.get("description") or getattr(handler, "__doc__", None),
|
|
24
|
+
"input_schema": _json_schema(options.get("input_schema") or options.get("input")),
|
|
25
|
+
"output_schema": _json_schema(options.get("output_schema") or options.get("output")),
|
|
26
|
+
"config_schema": _json_schema(options.get("config_schema") or options.get("config")),
|
|
27
|
+
"ui_schema": dict(options.get("ui_schema") or options.get("ui") or {}),
|
|
28
|
+
"side_effects": list(options.get("side_effects") or []),
|
|
29
|
+
"execution_mode": options.get("execution_mode") or "interactive",
|
|
30
|
+
"handler_ref": options.get("handler_ref") or handler.__name__,
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
return handler
|
|
34
|
+
|
|
35
|
+
if callable(fn):
|
|
36
|
+
return decorate(fn)
|
|
37
|
+
return decorate
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def tool(fn=None, **options):
|
|
41
|
+
return _register("tool", fn, **options)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def agent_node(fn=None, **options):
|
|
45
|
+
return _register("agent_node", fn, **options)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def rag_operator(fn=None, **options):
|
|
49
|
+
return _register("rag_operator", fn, **options)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def artifact(*, exports=None):
|
|
53
|
+
for item in exports or []:
|
|
54
|
+
if isinstance(item, dict):
|
|
55
|
+
_EXPORTS.append(item)
|
|
56
|
+
return {"exports": _EXPORTS}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def describe_exports():
|
|
60
|
+
return list(_EXPORTS)
|
agents24/builders.py
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Mapping
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def _ref_id(ref: str | Mapping[str, Any]) -> str:
|
|
7
|
+
return ref if isinstance(ref, str) else str(ref["id"])
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _normalize_refs(refs: list[str | Mapping[str, Any]] | None) -> list[str]:
|
|
11
|
+
seen: list[str] = []
|
|
12
|
+
for ref in refs or []:
|
|
13
|
+
value = _ref_id(ref)
|
|
14
|
+
if value and value not in seen:
|
|
15
|
+
seen.append(value)
|
|
16
|
+
return seen
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class AgentDefinitionBuilder:
|
|
20
|
+
def __init__(self, agents: Any, options: Mapping[str, Any]) -> None:
|
|
21
|
+
self._agents = agents
|
|
22
|
+
self._options = dict(options)
|
|
23
|
+
|
|
24
|
+
def to_graph(self) -> dict[str, Any]:
|
|
25
|
+
model = self._options.get("model")
|
|
26
|
+
config: dict[str, Any] = {
|
|
27
|
+
"instructions": self._options.get("instructions") or "",
|
|
28
|
+
"tools": _normalize_refs(self._options.get("tools")),
|
|
29
|
+
"toolsets": _normalize_refs(self._options.get("toolsets")),
|
|
30
|
+
}
|
|
31
|
+
if model:
|
|
32
|
+
config["model_id"] = _ref_id(model)
|
|
33
|
+
return {
|
|
34
|
+
"spec_version": "4.0",
|
|
35
|
+
"workflow_contract": {"inputs": []},
|
|
36
|
+
"state_contract": {"variables": []},
|
|
37
|
+
"nodes": [
|
|
38
|
+
{"id": "start", "type": "start", "position": {"x": 0, "y": 0}, "config": {}},
|
|
39
|
+
{"id": "agent", "type": "agent", "position": {"x": 260, "y": 0}, "config": config},
|
|
40
|
+
{"id": "end", "type": "end", "position": {"x": 520, "y": 0}, "config": {}},
|
|
41
|
+
],
|
|
42
|
+
"edges": [
|
|
43
|
+
{"id": "start-agent", "source": "start", "target": "agent", "type": "control"},
|
|
44
|
+
{"id": "agent-end", "source": "agent", "target": "end", "type": "control"},
|
|
45
|
+
],
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
def to_create_request(self) -> dict[str, Any]:
|
|
49
|
+
knowledge_refs = _normalize_refs(self._options.get("knowledge"))
|
|
50
|
+
memory = dict(self._options.get("memory") or {})
|
|
51
|
+
if knowledge_refs:
|
|
52
|
+
memory.update(
|
|
53
|
+
{
|
|
54
|
+
"long_term_enabled": True,
|
|
55
|
+
"long_term_index_id": knowledge_refs[0],
|
|
56
|
+
"knowledge_refs": knowledge_refs,
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
return {
|
|
60
|
+
"name": self._options["name"],
|
|
61
|
+
"description": self._options.get("description"),
|
|
62
|
+
"graph_definition": self.to_graph(),
|
|
63
|
+
"memory_config": memory,
|
|
64
|
+
"execution_constraints": dict(self._options.get("execution") or {}),
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
def create(self, options: dict[str, Any] | None = None) -> dict[str, Any]:
|
|
68
|
+
return self._agents.create(self.to_create_request(), options=options)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class GraphBuilder:
|
|
72
|
+
def __init__(self) -> None:
|
|
73
|
+
self._nodes: dict[str, dict[str, Any]] = {}
|
|
74
|
+
self._edges: list[dict[str, Any]] = []
|
|
75
|
+
|
|
76
|
+
def node(
|
|
77
|
+
self,
|
|
78
|
+
type_: str,
|
|
79
|
+
config: Mapping[str, Any] | None = None,
|
|
80
|
+
*,
|
|
81
|
+
id: str | None = None,
|
|
82
|
+
x: int | float | None = None,
|
|
83
|
+
y: int | float | None = None,
|
|
84
|
+
label: str | None = None,
|
|
85
|
+
) -> dict[str, Any]:
|
|
86
|
+
node_id = id or f"{type_}_{len(self._nodes) + 1}"
|
|
87
|
+
if node_id in self._nodes:
|
|
88
|
+
raise ValueError(f"Duplicate graph node id: {node_id}")
|
|
89
|
+
node = {
|
|
90
|
+
"id": node_id,
|
|
91
|
+
"type": type_,
|
|
92
|
+
"position": {"x": x if x is not None else len(self._nodes) * 260, "y": y if y is not None else 0},
|
|
93
|
+
"config": dict(config or {}),
|
|
94
|
+
}
|
|
95
|
+
if label:
|
|
96
|
+
node["label"] = label
|
|
97
|
+
self._nodes[node_id] = node
|
|
98
|
+
return node
|
|
99
|
+
|
|
100
|
+
def connect(
|
|
101
|
+
self,
|
|
102
|
+
source: str | Mapping[str, Any],
|
|
103
|
+
target: str | Mapping[str, Any],
|
|
104
|
+
*,
|
|
105
|
+
id: str | None = None,
|
|
106
|
+
source_handle: str | None = None,
|
|
107
|
+
target_handle: str | None = None,
|
|
108
|
+
) -> "GraphBuilder":
|
|
109
|
+
source_id = source if isinstance(source, str) else str(source["id"])
|
|
110
|
+
target_id = target if isinstance(target, str) else str(target["id"])
|
|
111
|
+
if source_id not in self._nodes:
|
|
112
|
+
raise ValueError(f"Unknown source node id: {source_id}")
|
|
113
|
+
if target_id not in self._nodes:
|
|
114
|
+
raise ValueError(f"Unknown target node id: {target_id}")
|
|
115
|
+
edge = {"id": id or f"{source_id}-{target_id}", "source": source_id, "target": target_id, "type": "control"}
|
|
116
|
+
if source_handle:
|
|
117
|
+
edge["source_handle"] = source_handle
|
|
118
|
+
if target_handle:
|
|
119
|
+
edge["target_handle"] = target_handle
|
|
120
|
+
self._edges.append(edge)
|
|
121
|
+
return self
|
|
122
|
+
|
|
123
|
+
def to_graph(self) -> dict[str, Any]:
|
|
124
|
+
return {
|
|
125
|
+
"spec_version": "4.0",
|
|
126
|
+
"workflow_contract": {"inputs": []},
|
|
127
|
+
"state_contract": {"variables": []},
|
|
128
|
+
"nodes": list(self._nodes.values()),
|
|
129
|
+
"edges": list(self._edges),
|
|
130
|
+
}
|
agents24/client.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Mapping
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
import requests
|
|
7
|
+
|
|
8
|
+
from .builders import AgentDefinitionBuilder, GraphBuilder
|
|
9
|
+
from .generated.agents import AgentsNamespace
|
|
10
|
+
from .generated.embed import EmbedNamespace
|
|
11
|
+
from .generated.runs import GeneratedRunsNamespace
|
|
12
|
+
from .http import Agents24HttpClient
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class RunsNamespace(GeneratedRunsNamespace):
|
|
16
|
+
def get_trace(self, run_id: str) -> dict[str, Any]:
|
|
17
|
+
return {
|
|
18
|
+
"run": self.get(run_id),
|
|
19
|
+
"tree": self.get_tree(run_id),
|
|
20
|
+
"events": self.get_events(run_id),
|
|
21
|
+
"context": self.get_context(run_id),
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class Agents24:
|
|
26
|
+
def __init__(
|
|
27
|
+
self,
|
|
28
|
+
*,
|
|
29
|
+
base_url: str,
|
|
30
|
+
api_key: str,
|
|
31
|
+
organization_id: str | None = None,
|
|
32
|
+
project_id: str | None = None,
|
|
33
|
+
timeout: float = 30.0,
|
|
34
|
+
session: requests.Session | None = None,
|
|
35
|
+
) -> None:
|
|
36
|
+
self._http = Agents24HttpClient(
|
|
37
|
+
base_url=base_url,
|
|
38
|
+
api_key=api_key,
|
|
39
|
+
organization_id=organization_id,
|
|
40
|
+
project_id=project_id,
|
|
41
|
+
timeout=timeout,
|
|
42
|
+
session=session,
|
|
43
|
+
)
|
|
44
|
+
self.agents = AgentsNamespace(self._http)
|
|
45
|
+
self.embed = EmbedNamespace(self._http)
|
|
46
|
+
self.runs = RunsNamespace(self._http)
|
|
47
|
+
|
|
48
|
+
def agent(self, options: Mapping[str, Any]) -> AgentDefinitionBuilder:
|
|
49
|
+
return AgentDefinitionBuilder(self.agents, options)
|
|
50
|
+
|
|
51
|
+
def graph(self) -> GraphBuilder:
|
|
52
|
+
return GraphBuilder()
|
agents24/errors.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Agents24SDKError(Exception):
|
|
7
|
+
def __init__(
|
|
8
|
+
self,
|
|
9
|
+
message: str,
|
|
10
|
+
*,
|
|
11
|
+
kind: str,
|
|
12
|
+
status: int | None = None,
|
|
13
|
+
details: Any = None,
|
|
14
|
+
) -> None:
|
|
15
|
+
super().__init__(message)
|
|
16
|
+
self.message = message
|
|
17
|
+
self.kind = kind
|
|
18
|
+
self.status = status
|
|
19
|
+
self.details = details
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Callable, Mapping, Sequence
|
|
4
|
+
|
|
5
|
+
from ..errors import Agents24SDKError
|
|
6
|
+
from ..http import Agents24HttpClient
|
|
7
|
+
from ..types import AgentListResponse, AgentResponse, AttachmentUploadResult, RequestOptions, RunCancelResult, RuntimeEvent, StartRunResult, StreamResult
|
|
8
|
+
|
|
9
|
+
class AgentsNamespace:
|
|
10
|
+
def __init__(self, http: Agents24HttpClient) -> None:
|
|
11
|
+
self._http = http
|
|
12
|
+
|
|
13
|
+
def list(self, status: str | None = None, skip: int = 0, limit: int = 20, view: str = "summary") -> AgentListResponse:
|
|
14
|
+
return self._http.request_json("GET", "/agents", params={
|
|
15
|
+
"status": status,
|
|
16
|
+
"skip": skip if skip is not None else 0,
|
|
17
|
+
"limit": limit if limit is not None else 20,
|
|
18
|
+
"view": view if view is not None else "summary",
|
|
19
|
+
}, json_body=None, options=None, mutation=False)
|
|
20
|
+
|
|
21
|
+
def get(self, agent_id: str) -> AgentResponse:
|
|
22
|
+
return self._http.request_json("GET", f"/agents/{agent_id}", params=None, json_body=None, options=None, mutation=False)
|
|
23
|
+
|
|
24
|
+
def create(self, request: Mapping[str, Any], options: RequestOptions | None = None) -> AgentResponse:
|
|
25
|
+
return self._http.request_json("POST", "/agents", params=None, json_body=request, options=options, mutation=True)
|
|
26
|
+
|
|
27
|
+
def update(self, agent_id: str, request: Mapping[str, Any], options: RequestOptions | None = None) -> AgentResponse:
|
|
28
|
+
return self._http.request_json("PATCH", f"/agents/{agent_id}", params=None, json_body=request, options=options, mutation=True)
|
|
29
|
+
|
|
30
|
+
def update_graph(self, agent_id: str, graph: Mapping[str, Any], options: RequestOptions | None = None) -> AgentResponse:
|
|
31
|
+
return self._http.request_json("PUT", f"/agents/{agent_id}/graph", params=None, json_body=graph, options=options, mutation=True)
|
|
32
|
+
|
|
33
|
+
def delete(self, agent_id: str, options: RequestOptions | None = None) -> Any:
|
|
34
|
+
return self._http.request_json("DELETE", f"/agents/{agent_id}", params=None, json_body=None, options=options, mutation=True)
|
|
35
|
+
|
|
36
|
+
def catalog(self) -> Any:
|
|
37
|
+
return self._http.request_json("GET", "/agents/nodes/catalog", params=None, json_body=None, options=None, mutation=False)
|
|
38
|
+
|
|
39
|
+
def schema(self, node_types: Any) -> Any:
|
|
40
|
+
return self._http.request_json("POST", "/agents/nodes/schema", params=None, json_body={
|
|
41
|
+
"node_types": node_types,
|
|
42
|
+
}, options=None, mutation=False)
|
|
43
|
+
|
|
44
|
+
def validate(self, agent_id: str) -> Any:
|
|
45
|
+
return self._http.request_json("POST", f"/agents/{agent_id}/validate", params=None, json_body={}, options=None, mutation=False)
|
|
46
|
+
|
|
47
|
+
def publish(self, agent_id: str, options: RequestOptions | None = None) -> AgentResponse:
|
|
48
|
+
return self._http.request_json("POST", f"/agents/{agent_id}/publish", params=None, json_body={}, options=options, mutation=True)
|
|
49
|
+
|
|
50
|
+
def start_run(self, agent_id: str, payload: Mapping[str, Any], options: RequestOptions | None = None) -> StartRunResult:
|
|
51
|
+
return self._http.request_json("POST", f"/agents/{agent_id}/run", params=None, json_body=payload, options=options, mutation=True)
|
|
52
|
+
|
|
53
|
+
def stream(self, agent_id: str, payload: Mapping[str, Any], on_event: Callable[[RuntimeEvent], None] | None = None, mode: str | None = None) -> StreamResult:
|
|
54
|
+
return self._http.request_stream("POST", f"/agents/{agent_id}/stream", json_body=dict(payload), params={"mode": mode}, on_event=on_event)
|
|
55
|
+
|
|
56
|
+
def resume_run(self, run_id: str, payload: Mapping[str, Any], options: RequestOptions | None = None) -> Any:
|
|
57
|
+
return self._http.request_json("POST", f"/agents/runs/{run_id}/resume", params=None, json_body=payload, options=options, mutation=True)
|
|
58
|
+
|
|
59
|
+
def cancel_run(self, run_id: str, assistant_output_text: str | None = None) -> RunCancelResult:
|
|
60
|
+
return self._http.request_json("POST", f"/agents/runs/{run_id}/cancel", params=None, json_body={
|
|
61
|
+
"assistant_output_text": assistant_output_text,
|
|
62
|
+
}, options=None, mutation=True)
|
|
63
|
+
|
|
64
|
+
def upload_attachments(self, agent_id: str, files: Sequence[Any], thread_id: str | None = None) -> AttachmentUploadResult:
|
|
65
|
+
return self._http.request_multipart("POST", f"/agents/{agent_id}/attachments/upload", data={
|
|
66
|
+
"thread_id": thread_id,
|
|
67
|
+
}, files=files)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Callable, Mapping, Sequence
|
|
4
|
+
|
|
5
|
+
from ..errors import Agents24SDKError
|
|
6
|
+
from ..http import Agents24HttpClient
|
|
7
|
+
from ..types import AttachmentUploadResult, RequestOptions, RunCancelResult, RunContext, RuntimeEvent, StreamResult, ThreadDeleteResult, ThreadDetail, ThreadsResponse
|
|
8
|
+
|
|
9
|
+
class EmbedNamespace:
|
|
10
|
+
def __init__(self, http: Agents24HttpClient) -> None:
|
|
11
|
+
self._http = http
|
|
12
|
+
|
|
13
|
+
def stream_agent(self, agent_id: str, payload: Mapping[str, Any], on_event: Callable[[RuntimeEvent], None] | None = None) -> StreamResult:
|
|
14
|
+
return self._http.request_stream("POST", f"/public/embed/agents/{agent_id}/chat/stream", json_body=dict(payload), params=None, on_event=on_event)
|
|
15
|
+
|
|
16
|
+
def list_agent_threads(self, agent_id: str, external_user_id: Any = None, external_session_id: Any = None, skip: Any = 0, limit: Any = 20) -> ThreadsResponse:
|
|
17
|
+
return self._http.request_json("GET", f"/public/embed/agents/{agent_id}/threads", params={
|
|
18
|
+
"external_user_id": external_user_id,
|
|
19
|
+
"external_session_id": external_session_id,
|
|
20
|
+
"skip": skip if skip is not None else 0,
|
|
21
|
+
"limit": limit if limit is not None else 20,
|
|
22
|
+
}, json_body=None, options=None, mutation=False)
|
|
23
|
+
|
|
24
|
+
def get_agent_thread(self, agent_id: str, thread_id: str, external_user_id: Any = None, external_session_id: Any = None, before_turn_index: Any = None, limit: Any = None, include_subthreads: Any = None, subthread_depth: Any = None, subthread_turn_limit: Any = None, subthread_child_limit: Any = None) -> ThreadDetail:
|
|
25
|
+
return self._http.request_json("GET", f"/public/embed/agents/{agent_id}/threads/{thread_id}", params={
|
|
26
|
+
"external_user_id": external_user_id,
|
|
27
|
+
"external_session_id": external_session_id,
|
|
28
|
+
"before_turn_index": before_turn_index,
|
|
29
|
+
"limit": limit,
|
|
30
|
+
"include_subthreads": include_subthreads,
|
|
31
|
+
"subthread_depth": subthread_depth,
|
|
32
|
+
"subthread_turn_limit": subthread_turn_limit,
|
|
33
|
+
"subthread_child_limit": subthread_child_limit,
|
|
34
|
+
}, json_body=None, options=None, mutation=False)
|
|
35
|
+
|
|
36
|
+
def delete_agent_thread(self, agent_id: str, thread_id: str, external_user_id: Any = None, external_session_id: Any = None, options: RequestOptions | None = None) -> ThreadDeleteResult:
|
|
37
|
+
return self._http.request_json("DELETE", f"/public/embed/agents/{agent_id}/threads/{thread_id}", params={
|
|
38
|
+
"external_user_id": external_user_id,
|
|
39
|
+
"external_session_id": external_session_id,
|
|
40
|
+
}, json_body=None, options=options, mutation=True)
|
|
41
|
+
|
|
42
|
+
def get_agent_run_context(self, agent_id: str, run_id: str, external_user_id: Any = None, external_session_id: Any = None) -> RunContext:
|
|
43
|
+
return self._http.request_json("GET", f"/public/embed/agents/{agent_id}/runs/{run_id}/context", params={
|
|
44
|
+
"external_user_id": external_user_id,
|
|
45
|
+
"external_session_id": external_session_id,
|
|
46
|
+
}, json_body=None, options=None, mutation=False)
|
|
47
|
+
|
|
48
|
+
def cancel_agent_run(self, agent_id: str, run_id: str, external_user_id: Any = None, external_session_id: Any = None, assistant_output_text: str | None = None) -> RunCancelResult:
|
|
49
|
+
return self._http.request_json("POST", f"/public/embed/agents/{agent_id}/runs/{run_id}/cancel", params={
|
|
50
|
+
"external_user_id": external_user_id,
|
|
51
|
+
"external_session_id": external_session_id,
|
|
52
|
+
}, json_body={
|
|
53
|
+
"assistant_output_text": assistant_output_text,
|
|
54
|
+
}, options=None, mutation=True)
|
|
55
|
+
|
|
56
|
+
def upload_agent_attachments(self, agent_id: str, files: Sequence[Any], external_user_id: str | None = None, external_session_id: str | None = None, thread_id: str | None = None) -> AttachmentUploadResult:
|
|
57
|
+
if not external_user_id:
|
|
58
|
+
raise Agents24SDKError("upload_agent_attachments requires external_user_id.", kind="protocol")
|
|
59
|
+
return self._http.request_multipart("POST", f"/public/embed/agents/{agent_id}/attachments/upload", data={
|
|
60
|
+
"external_user_id": external_user_id,
|
|
61
|
+
"external_session_id": external_session_id,
|
|
62
|
+
"thread_id": thread_id,
|
|
63
|
+
}, files=files)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
SDK_OPERATION_IDS = [
|
|
2
|
+
"agents.cancel_run",
|
|
3
|
+
"agents.catalog",
|
|
4
|
+
"agents.create",
|
|
5
|
+
"agents.delete",
|
|
6
|
+
"agents.get",
|
|
7
|
+
"agents.list",
|
|
8
|
+
"agents.publish",
|
|
9
|
+
"agents.resume_run",
|
|
10
|
+
"agents.schema",
|
|
11
|
+
"agents.start_run",
|
|
12
|
+
"agents.stream",
|
|
13
|
+
"agents.update",
|
|
14
|
+
"agents.update_graph",
|
|
15
|
+
"agents.upload_attachments",
|
|
16
|
+
"agents.validate",
|
|
17
|
+
"embed.cancel_agent_run",
|
|
18
|
+
"embed.delete_agent_thread",
|
|
19
|
+
"embed.get_agent_run_context",
|
|
20
|
+
"embed.get_agent_thread",
|
|
21
|
+
"embed.list_agent_threads",
|
|
22
|
+
"embed.stream_agent",
|
|
23
|
+
"embed.upload_agent_attachments",
|
|
24
|
+
"runs.get",
|
|
25
|
+
"runs.get_context",
|
|
26
|
+
"runs.get_events",
|
|
27
|
+
"runs.get_tree"
|
|
28
|
+
]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Callable, Mapping, Sequence
|
|
4
|
+
|
|
5
|
+
from ..errors import Agents24SDKError
|
|
6
|
+
from ..http import Agents24HttpClient
|
|
7
|
+
from ..types import RequestOptions, RunContext, RunEventsResponse, RunStatus
|
|
8
|
+
|
|
9
|
+
class GeneratedRunsNamespace:
|
|
10
|
+
def __init__(self, http: Agents24HttpClient) -> None:
|
|
11
|
+
self._http = http
|
|
12
|
+
|
|
13
|
+
def get(self, run_id: str, include_tree: bool | None = None) -> RunStatus:
|
|
14
|
+
return self._http.request_json("GET", f"/agents/runs/{run_id}", params={
|
|
15
|
+
"include_tree": include_tree,
|
|
16
|
+
}, json_body=None, options=None, mutation=False)
|
|
17
|
+
|
|
18
|
+
def get_tree(self, run_id: str) -> Any:
|
|
19
|
+
return self._http.request_json("GET", f"/agents/runs/{run_id}/tree", params=None, json_body=None, options=None, mutation=False)
|
|
20
|
+
|
|
21
|
+
def get_events(self, run_id: str, after_sequence: int | None = None, limit: int | None = None) -> RunEventsResponse:
|
|
22
|
+
return self._http.request_json("GET", f"/agents/runs/{run_id}/events", params={
|
|
23
|
+
"after_sequence": after_sequence,
|
|
24
|
+
"limit": limit,
|
|
25
|
+
}, json_body=None, options=None, mutation=False)
|
|
26
|
+
|
|
27
|
+
def get_context(self, run_id: str) -> RunContext:
|
|
28
|
+
return self._http.request_json("GET", f"/agents/runs/{run_id}/context", params=None, json_body=None, options=None, mutation=False)
|
agents24/http.py
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import uuid
|
|
5
|
+
from collections.abc import Mapping, Sequence
|
|
6
|
+
from typing import Any, Callable
|
|
7
|
+
|
|
8
|
+
import requests
|
|
9
|
+
|
|
10
|
+
from .errors import Agents24SDKError
|
|
11
|
+
from .sse import consume_event_stream
|
|
12
|
+
from .types import RequestOptions, RuntimeEvent, StreamResult
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Agents24HttpClient:
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
*,
|
|
19
|
+
base_url: str,
|
|
20
|
+
api_key: str,
|
|
21
|
+
organization_id: str | None = None,
|
|
22
|
+
project_id: str | None = None,
|
|
23
|
+
timeout: float = 30.0,
|
|
24
|
+
session: requests.Session | None = None,
|
|
25
|
+
) -> None:
|
|
26
|
+
self.base_url = self._normalize_base_url(base_url)
|
|
27
|
+
self.api_key = str(api_key or "").strip()
|
|
28
|
+
if not self.api_key:
|
|
29
|
+
raise Agents24SDKError("Agents24 requires a non-empty api_key.", kind="protocol")
|
|
30
|
+
self.organization_id = str(organization_id) if organization_id else None
|
|
31
|
+
self.project_id = str(project_id) if project_id else None
|
|
32
|
+
self.timeout = timeout
|
|
33
|
+
self.session = session or requests.Session()
|
|
34
|
+
|
|
35
|
+
@staticmethod
|
|
36
|
+
def _normalize_base_url(base_url: str) -> str:
|
|
37
|
+
normalized = str(base_url or "").strip().rstrip("/")
|
|
38
|
+
if not normalized or "://" not in normalized:
|
|
39
|
+
raise Agents24SDKError("Agents24 requires a valid base_url.", kind="protocol")
|
|
40
|
+
return normalized
|
|
41
|
+
|
|
42
|
+
def _headers(
|
|
43
|
+
self,
|
|
44
|
+
*,
|
|
45
|
+
accept: str = "application/json",
|
|
46
|
+
content_type: str | None = "application/json",
|
|
47
|
+
mutation: bool = False,
|
|
48
|
+
options: RequestOptions | None = None,
|
|
49
|
+
) -> dict[str, str]:
|
|
50
|
+
headers = {
|
|
51
|
+
"Authorization": f"Bearer {self.api_key}",
|
|
52
|
+
"Accept": accept,
|
|
53
|
+
"X-SDK-Contract": "1",
|
|
54
|
+
}
|
|
55
|
+
if content_type:
|
|
56
|
+
headers["Content-Type"] = content_type
|
|
57
|
+
if self.organization_id:
|
|
58
|
+
headers["X-Organization-ID"] = self.organization_id
|
|
59
|
+
if self.project_id:
|
|
60
|
+
headers["X-Project-ID"] = self.project_id
|
|
61
|
+
if mutation:
|
|
62
|
+
headers["X-Idempotency-Key"] = (options or {}).get("idempotency_key") or str(uuid.uuid4())
|
|
63
|
+
metadata = (options or {}).get("request_metadata")
|
|
64
|
+
if metadata:
|
|
65
|
+
headers["X-Request-Metadata"] = json.dumps(metadata, separators=(",", ":"))
|
|
66
|
+
return headers
|
|
67
|
+
|
|
68
|
+
@staticmethod
|
|
69
|
+
def _params(params: Mapping[str, Any] | None, options: RequestOptions | None = None) -> dict[str, Any]:
|
|
70
|
+
merged = {k: v for k, v in dict(params or {}).items() if v not in (None, "")}
|
|
71
|
+
if options and "dry_run" in options:
|
|
72
|
+
merged["dry_run"] = bool(options["dry_run"])
|
|
73
|
+
if options and "validate_only" in options:
|
|
74
|
+
merged["validate_only"] = bool(options["validate_only"])
|
|
75
|
+
return merged
|
|
76
|
+
|
|
77
|
+
def request_json(
|
|
78
|
+
self,
|
|
79
|
+
method: str,
|
|
80
|
+
path: str,
|
|
81
|
+
*,
|
|
82
|
+
params: Mapping[str, Any] | None = None,
|
|
83
|
+
json_body: Any = None,
|
|
84
|
+
options: RequestOptions | None = None,
|
|
85
|
+
mutation: bool = False,
|
|
86
|
+
) -> Any:
|
|
87
|
+
try:
|
|
88
|
+
response = self.session.request(
|
|
89
|
+
method=method,
|
|
90
|
+
url=f"{self.base_url}{path}",
|
|
91
|
+
params=self._params(params, options),
|
|
92
|
+
json=json_body,
|
|
93
|
+
headers=self._headers(mutation=mutation, options=options),
|
|
94
|
+
timeout=self.timeout,
|
|
95
|
+
)
|
|
96
|
+
except requests.RequestException as exc:
|
|
97
|
+
raise Agents24SDKError("Failed to connect to the Agents24 API.", kind="network") from exc
|
|
98
|
+
self._raise_for_status(response)
|
|
99
|
+
if response.text:
|
|
100
|
+
return response.json()
|
|
101
|
+
return None
|
|
102
|
+
|
|
103
|
+
def request_multipart(
|
|
104
|
+
self,
|
|
105
|
+
method: str,
|
|
106
|
+
path: str,
|
|
107
|
+
*,
|
|
108
|
+
data: Mapping[str, Any],
|
|
109
|
+
files: Sequence[Any],
|
|
110
|
+
) -> Any:
|
|
111
|
+
form_data = {k: v for k, v in dict(data or {}).items() if v not in (None, "")}
|
|
112
|
+
try:
|
|
113
|
+
response = self.session.request(
|
|
114
|
+
method=method,
|
|
115
|
+
url=f"{self.base_url}{path}",
|
|
116
|
+
data=form_data,
|
|
117
|
+
files={"files": files} if files and not isinstance(files[0], tuple) else list(files),
|
|
118
|
+
headers=self._headers(content_type=None),
|
|
119
|
+
timeout=self.timeout,
|
|
120
|
+
)
|
|
121
|
+
except requests.RequestException as exc:
|
|
122
|
+
raise Agents24SDKError("Failed to connect to the Agents24 attachment endpoint.", kind="network") from exc
|
|
123
|
+
self._raise_for_status(response)
|
|
124
|
+
return response.json()
|
|
125
|
+
|
|
126
|
+
def request_stream(
|
|
127
|
+
self,
|
|
128
|
+
method: str,
|
|
129
|
+
path: str,
|
|
130
|
+
*,
|
|
131
|
+
json_body: Mapping[str, Any],
|
|
132
|
+
params: Mapping[str, Any] | None,
|
|
133
|
+
on_event: Callable[[RuntimeEvent], None] | None,
|
|
134
|
+
) -> StreamResult:
|
|
135
|
+
try:
|
|
136
|
+
response = self.session.request(
|
|
137
|
+
method=method,
|
|
138
|
+
url=f"{self.base_url}{path}",
|
|
139
|
+
params=self._params(params),
|
|
140
|
+
json=dict(json_body),
|
|
141
|
+
headers=self._headers(accept="text/event-stream"),
|
|
142
|
+
timeout=self.timeout,
|
|
143
|
+
stream=True,
|
|
144
|
+
)
|
|
145
|
+
except requests.RequestException as exc:
|
|
146
|
+
raise Agents24SDKError("Failed to connect to the Agents24 stream endpoint.", kind="network") from exc
|
|
147
|
+
self._raise_for_status(response)
|
|
148
|
+
observed_run_id = response.headers.get("X-Run-ID")
|
|
149
|
+
for event in consume_event_stream(response.iter_lines(decode_unicode=True)):
|
|
150
|
+
observed_run_id = observed_run_id or event["run_id"]
|
|
151
|
+
if on_event:
|
|
152
|
+
on_event(event)
|
|
153
|
+
return {
|
|
154
|
+
"thread_id": response.headers.get("X-Thread-ID"),
|
|
155
|
+
"run_id": observed_run_id,
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
@staticmethod
|
|
159
|
+
def _raise_for_status(response: requests.Response) -> None:
|
|
160
|
+
if response.status_code < 400:
|
|
161
|
+
return
|
|
162
|
+
details: Any
|
|
163
|
+
try:
|
|
164
|
+
details = response.json()
|
|
165
|
+
except Exception:
|
|
166
|
+
details = response.text
|
|
167
|
+
message = response.reason or "Request failed"
|
|
168
|
+
if isinstance(details, dict):
|
|
169
|
+
detail = details.get("detail")
|
|
170
|
+
if isinstance(detail, str):
|
|
171
|
+
message = detail
|
|
172
|
+
elif isinstance(detail, dict) and isinstance(detail.get("message"), str):
|
|
173
|
+
message = detail["message"]
|
|
174
|
+
elif isinstance(details.get("message"), str):
|
|
175
|
+
message = details["message"]
|
|
176
|
+
elif isinstance(details, str) and details:
|
|
177
|
+
message = details
|
|
178
|
+
raise Agents24SDKError(message, kind="http", status=response.status_code, details=details)
|
agents24/sse.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from collections.abc import Iterable
|
|
5
|
+
|
|
6
|
+
from .errors import Agents24SDKError
|
|
7
|
+
from .types import RuntimeEvent
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _parse_sse_block(block: str) -> str | None:
|
|
11
|
+
data_lines: list[str] = []
|
|
12
|
+
for raw_line in block.split("\n"):
|
|
13
|
+
line = raw_line.rstrip("\r")
|
|
14
|
+
if not line or line.startswith(":"):
|
|
15
|
+
continue
|
|
16
|
+
field, _, value = line.partition(":")
|
|
17
|
+
if value.startswith(" "):
|
|
18
|
+
value = value[1:]
|
|
19
|
+
if field == "data":
|
|
20
|
+
data_lines.append(value)
|
|
21
|
+
return "\n".join(data_lines) if data_lines else None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def parse_runtime_event(raw_payload: str) -> RuntimeEvent:
|
|
25
|
+
try:
|
|
26
|
+
parsed = json.loads(raw_payload)
|
|
27
|
+
except Exception as exc:
|
|
28
|
+
raise Agents24SDKError("Malformed SSE event: invalid JSON payload.", kind="protocol", details=raw_payload) from exc
|
|
29
|
+
if not isinstance(parsed, dict) or parsed.get("version") != "run-stream.v2":
|
|
30
|
+
raise Agents24SDKError("SSE protocol mismatch: expected run-stream.v2 event envelopes.", kind="protocol", details=parsed)
|
|
31
|
+
for field in ("seq", "ts", "event", "run_id", "stage"):
|
|
32
|
+
if field not in parsed:
|
|
33
|
+
raise Agents24SDKError("Malformed SSE event: missing required envelope fields.", kind="protocol", details=parsed)
|
|
34
|
+
payload = parsed.get("payload") or {}
|
|
35
|
+
diagnostics = parsed.get("diagnostics") or []
|
|
36
|
+
if not isinstance(payload, dict) or not isinstance(diagnostics, list):
|
|
37
|
+
raise Agents24SDKError("Malformed SSE event payload.", kind="protocol", details=parsed)
|
|
38
|
+
parsed["payload"] = payload
|
|
39
|
+
parsed["diagnostics"] = diagnostics
|
|
40
|
+
return parsed # type: ignore[return-value]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def consume_event_stream(lines: Iterable[str | bytes]) -> Iterable[RuntimeEvent]:
|
|
44
|
+
buffer: list[str] = []
|
|
45
|
+
for item in lines:
|
|
46
|
+
line = item.decode("utf-8") if isinstance(item, bytes) else str(item)
|
|
47
|
+
if line == "":
|
|
48
|
+
payload = _parse_sse_block("\n".join(buffer))
|
|
49
|
+
buffer = []
|
|
50
|
+
if payload:
|
|
51
|
+
yield parse_runtime_event(payload)
|
|
52
|
+
else:
|
|
53
|
+
buffer.append(line)
|
|
54
|
+
if buffer:
|
|
55
|
+
payload = _parse_sse_block("\n".join(buffer))
|
|
56
|
+
if payload:
|
|
57
|
+
yield parse_runtime_event(payload)
|
agents24/types.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, NotRequired, TypeAlias, TypedDict
|
|
4
|
+
|
|
5
|
+
JSONDict: TypeAlias = dict[str, Any]
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class RequestOptions(TypedDict, total=False):
|
|
9
|
+
idempotency_key: str
|
|
10
|
+
dry_run: bool
|
|
11
|
+
validate_only: bool
|
|
12
|
+
request_metadata: dict[str, Any]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class RuntimeEvent(TypedDict):
|
|
16
|
+
version: str
|
|
17
|
+
seq: int | float
|
|
18
|
+
ts: str
|
|
19
|
+
event: str
|
|
20
|
+
run_id: str
|
|
21
|
+
stage: str
|
|
22
|
+
payload: dict[str, Any]
|
|
23
|
+
diagnostics: list[dict[str, Any]]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class StreamResult(TypedDict):
|
|
27
|
+
thread_id: str | None
|
|
28
|
+
run_id: str | None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class AttachmentUploadResult(TypedDict):
|
|
32
|
+
items: list[dict[str, Any]]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class AgentCreateRequest(TypedDict):
|
|
36
|
+
name: str
|
|
37
|
+
graph_definition: dict[str, Any]
|
|
38
|
+
description: NotRequired[str | None]
|
|
39
|
+
memory_config: NotRequired[dict[str, Any]]
|
|
40
|
+
execution_constraints: NotRequired[dict[str, Any]]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
AgentUpdateRequest: TypeAlias = dict[str, Any]
|
|
44
|
+
AgentResponse: TypeAlias = dict[str, Any]
|
|
45
|
+
AgentListResponse: TypeAlias = dict[str, Any]
|
|
46
|
+
AgentStreamRequest: TypeAlias = dict[str, Any]
|
|
47
|
+
EmbedStreamRequest: TypeAlias = dict[str, Any]
|
|
48
|
+
StartRunResult: TypeAlias = dict[str, Any]
|
|
49
|
+
RunCancelResult: TypeAlias = dict[str, Any]
|
|
50
|
+
RunContext: TypeAlias = dict[str, Any]
|
|
51
|
+
RunEventsResponse: TypeAlias = dict[str, Any]
|
|
52
|
+
RunStatus: TypeAlias = dict[str, Any]
|
|
53
|
+
RunTrace: TypeAlias = dict[str, Any]
|
|
54
|
+
ThreadDeleteResult: TypeAlias = dict[str, Any]
|
|
55
|
+
ThreadDetail: TypeAlias = dict[str, Any]
|
|
56
|
+
ThreadsResponse: TypeAlias = dict[str, Any]
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agents24
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Unified Python SDK for Agents24 agent runtime and control APIs.
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: requests>=2.31.0
|
|
9
|
+
|
|
10
|
+
# agents24
|
|
11
|
+
|
|
12
|
+
Last Updated: 2026-05-25
|
|
13
|
+
|
|
14
|
+
Unified Python SDK for Agents24.
|
|
15
|
+
|
|
16
|
+
Endpoint methods are generated from `packages/agents24-sdk-contract/agents24.sdk.json`.
|
|
17
|
+
Do not edit files under `agents24/generated/` directly. For SDK maintenance, see `docs/references/agents24_sdk_development_guide.md`.
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from agents24 import Agents24
|
|
21
|
+
|
|
22
|
+
client = Agents24(
|
|
23
|
+
base_url="http://localhost:8000",
|
|
24
|
+
api_key="tpk_...",
|
|
25
|
+
organization_id="org-id",
|
|
26
|
+
project_id="project-id",
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
agent = client.agent({
|
|
30
|
+
"name": "Support Agent",
|
|
31
|
+
"instructions": "Answer briefly.",
|
|
32
|
+
}).create()
|
|
33
|
+
|
|
34
|
+
client.agents.publish(agent["id"])
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Artifact Authoring
|
|
38
|
+
|
|
39
|
+
Artifact code imports lightweight helpers from `agents24.artifacts`:
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from agents24.artifacts import tool
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@tool(
|
|
46
|
+
name="echo",
|
|
47
|
+
input_schema={
|
|
48
|
+
"type": "object",
|
|
49
|
+
"properties": {"text": {"type": "string"}},
|
|
50
|
+
"required": ["text"],
|
|
51
|
+
},
|
|
52
|
+
output_schema={
|
|
53
|
+
"type": "object",
|
|
54
|
+
"properties": {"text": {"type": "string"}},
|
|
55
|
+
"required": ["text"],
|
|
56
|
+
},
|
|
57
|
+
)
|
|
58
|
+
async def echo(input, config, context):
|
|
59
|
+
return {"text": input["text"]}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The `agents24.artifacts` module is transport-free and safe for artifact runtime code.
|
|
63
|
+
|
|
64
|
+
## Development
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pnpm run generate:sdk
|
|
68
|
+
pnpm run check:sdk-contract
|
|
69
|
+
pnpm run test:agents24-python
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Generated endpoint methods must stay in parity with the TypeScript `@agents24/sdk` package.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
agents24/__init__.py,sha256=VQohNGpp9E2BzwKSx4iS1TvRHwKFeI6LH2OKgvR6oag,230
|
|
2
|
+
agents24/artifacts.py,sha256=kRz-1QnLeTK6CjFuGrI27mDpMv9JT4KDNInCvRszhIc,1908
|
|
3
|
+
agents24/builders.py,sha256=3Wl1V0jg72OAWhRTIge5TCIlyK5cOj2nKT-5bwfC2Ro,4802
|
|
4
|
+
agents24/client.py,sha256=5vq4yHmddXhfZoqdNFA8ywXq_G5mfkI8k-Ssmi5i3xw,1537
|
|
5
|
+
agents24/errors.py,sha256=ZRjdq0_-NMeqJBzVkMgD1ARCAmxV4xifnhFcr5tOK30,409
|
|
6
|
+
agents24/http.py,sha256=xi_uvR5GCzEdxkGFJQ-wLkWyFQIrexcwcIEzsLEt7rU,6642
|
|
7
|
+
agents24/sse.py,sha256=Omx-aeBgwapiPtyM9FV4hMY5Eg2p0x0pe4EehUHz69U,2260
|
|
8
|
+
agents24/types.py,sha256=5hGgIYPLEMbFzybSiB8ThXPJIkZTehSusy2t7R7hR4k,1479
|
|
9
|
+
agents24/generated/__init__.py,sha256=J35rhjvtYFSMtERrp9OTveWpIBEBGJByBgZ7POBg21I,73
|
|
10
|
+
agents24/generated/agents.py,sha256=rup_FcbVmKWFRMRVbMmod-e2Mw9wmCIFlRLt9jTyxoQ,4245
|
|
11
|
+
agents24/generated/embed.py,sha256=ndWnw-CbL6GFTM0j0kbreug2FDy_7vWOKE9pqiM7a_4,4217
|
|
12
|
+
agents24/generated/manifest.py,sha256=BE4EiUMeylto6wBICXgAs2-kF2Pe2dNETp9SbqY6Kfc,622
|
|
13
|
+
agents24/generated/runs.py,sha256=ponpY4VEl50-aBeByYVUCk-qiVVlS8PWGP40skfrcQI,1333
|
|
14
|
+
agents24-0.1.0.dist-info/METADATA,sha256=k4fSmod7QPCLzYVwb3vSm1na6zyzSPGntbDUEhw9F70,1661
|
|
15
|
+
agents24-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
16
|
+
agents24-0.1.0.dist-info/top_level.txt,sha256=CVcfR_w_8svOxK5tZP1uayAtxTPL2RaVYpqoPXP4KuY,9
|
|
17
|
+
agents24-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
agents24
|