blade-agent-kit 0.4.1__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.
@@ -0,0 +1,3 @@
1
+ from blade_agent_kit.client import BladeAgentClient
2
+
3
+ __all__ = ["BladeAgentClient"]
@@ -0,0 +1,138 @@
1
+ """Minimal REST client for Blade Agent (v1: no Socket.IO)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ import httpx
8
+
9
+
10
+ class BladeAgentClient:
11
+ def __init__(
12
+ self,
13
+ base_url: str,
14
+ *,
15
+ token: str | None = None,
16
+ timeout: float = 60.0,
17
+ ) -> None:
18
+ self._base = base_url.rstrip("/")
19
+ self._token = token
20
+ self._timeout = timeout
21
+
22
+ def _headers(self) -> dict[str, str]:
23
+ h: dict[str, str] = {"Accept": "application/json"}
24
+ if self._token:
25
+ h["Authorization"] = f"Bearer {self._token}"
26
+ return h
27
+
28
+ def _client(self) -> httpx.Client:
29
+ return httpx.Client(
30
+ base_url=self._base,
31
+ timeout=self._timeout,
32
+ headers=self._headers(),
33
+ )
34
+
35
+ def health(self) -> dict[str, Any]:
36
+ with self._client() as c:
37
+ r = c.get("/api/health")
38
+ r.raise_for_status()
39
+ return r.json()
40
+
41
+ def list_sessions(
42
+ self,
43
+ *,
44
+ limit: int = 100,
45
+ offset: int = 0,
46
+ template_id_prefix: str | None = None,
47
+ q: str | None = None,
48
+ ) -> list[dict[str, Any]]:
49
+ """Return session items from paginated GET /api/sessions."""
50
+ params: dict[str, Any] = {"limit": limit, "offset": offset}
51
+ if template_id_prefix:
52
+ params["template_id_prefix"] = template_id_prefix
53
+ if q:
54
+ params["q"] = q.strip()
55
+ with self._client() as c:
56
+ r = c.get("/api/sessions", params=params)
57
+ r.raise_for_status()
58
+ payload = r.json()
59
+ if isinstance(payload, list):
60
+ return payload
61
+ if isinstance(payload, dict):
62
+ items = payload.get("items")
63
+ if isinstance(items, list):
64
+ return items
65
+ raise TypeError(f"unexpected /api/sessions response: {type(payload).__name__}")
66
+
67
+ def list_sessions_page(
68
+ self,
69
+ *,
70
+ limit: int = 20,
71
+ offset: int = 0,
72
+ template_id_prefix: str | None = None,
73
+ q: str | None = None,
74
+ ) -> dict[str, Any]:
75
+ """Return full paginated payload: items, total, limit, offset."""
76
+ params: dict[str, Any] = {"limit": limit, "offset": offset}
77
+ if template_id_prefix:
78
+ params["template_id_prefix"] = template_id_prefix
79
+ if q:
80
+ params["q"] = q.strip()
81
+ with self._client() as c:
82
+ r = c.get("/api/sessions", params=params)
83
+ r.raise_for_status()
84
+ payload = r.json()
85
+ if not isinstance(payload, dict):
86
+ raise TypeError(f"unexpected /api/sessions response: {type(payload).__name__}")
87
+ return payload
88
+
89
+ def get_session(self, session_id: str) -> dict[str, Any]:
90
+ with self._client() as c:
91
+ r = c.get(f"/api/sessions/{session_id}")
92
+ r.raise_for_status()
93
+ return r.json()
94
+
95
+ def get_history(self, session_id: str) -> dict[str, Any]:
96
+ with self._client() as c:
97
+ r = c.get(f"/api/sessions/{session_id}/history")
98
+ r.raise_for_status()
99
+ return r.json()
100
+
101
+ def create_session(self, intent: str = "") -> dict[str, Any]:
102
+ with self._client() as c:
103
+ r = c.post("/api/sessions", json={"intent": intent})
104
+ r.raise_for_status()
105
+ return r.json()
106
+
107
+ def delete_session(self, session_id: str) -> dict[str, Any]:
108
+ with self._client() as c:
109
+ r = c.delete(f"/api/sessions/{session_id}")
110
+ r.raise_for_status()
111
+ return r.json()
112
+
113
+ def list_dir(self, session_id: str, dir_path: str = ".") -> list[dict[str, Any]]:
114
+ with self._client() as c:
115
+ r = c.get(f"/api/sessions/{session_id}/ls/{_encode_ls_path(dir_path)}")
116
+ r.raise_for_status()
117
+ return r.json()
118
+
119
+ def get_checkpoints(self, session_id: str) -> dict[str, Any]:
120
+ with self._client() as c:
121
+ r = c.get(f"/api/sessions/{session_id}/checkpoints")
122
+ r.raise_for_status()
123
+ return r.json()
124
+
125
+
126
+ def _encode_ls_path(dir_path: str) -> str:
127
+ """Encode path for GET /api/sessions/{id}/ls/{dir_path}.
128
+
129
+ Root ``.`` must be sent as ``%2E``: ``/ls/.`` is normalized to ``/ls`` by HTTP
130
+ clients and does not match the server route (404). Aligns with browser
131
+ ``encodeURIComponent`` for nested paths (``/`` → ``%2F``).
132
+ """
133
+ from urllib.parse import quote
134
+
135
+ normalized = (dir_path or ".").strip()
136
+ if normalized == ".":
137
+ return "%2E"
138
+ return quote(normalized, safe="")
@@ -0,0 +1,6 @@
1
+ Metadata-Version: 2.4
2
+ Name: blade-agent-kit
3
+ Version: 0.4.1
4
+ Summary: REST client for Blade Agent (AgentKit Python, v1 without Socket.IO)
5
+ Requires-Python: <3.13,>=3.12
6
+ Requires-Dist: httpx>=0.28.1
@@ -0,0 +1,5 @@
1
+ blade_agent_kit/__init__.py,sha256=IdRFOMy_fUi_ZMRe3vZo5YVUgJVTG0bUG3_Ev5HnrkY,84
2
+ blade_agent_kit/client.py,sha256=NeY6l8-qIWTYRjNZH8Q8l42T-DFCAC5-diPIhXCOnnM,4577
3
+ blade_agent_kit-0.4.1.dist-info/METADATA,sha256=PtFlmaFud_iFcZxTOBVOx4vVlCC418diPqQozI6MqnI,195
4
+ blade_agent_kit-0.4.1.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
5
+ blade_agent_kit-0.4.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any