statebase 0.1.0__tar.gz
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.
- statebase-0.1.0/PKG-INFO +128 -0
- statebase-0.1.0/README.md +93 -0
- statebase-0.1.0/setup.cfg +4 -0
- statebase-0.1.0/setup.py +39 -0
- statebase-0.1.0/statebase/__init__.py +4 -0
- statebase-0.1.0/statebase/async_client.py +187 -0
- statebase-0.1.0/statebase/client.py +191 -0
- statebase-0.1.0/statebase/models.py +86 -0
- statebase-0.1.0/statebase.egg-info/PKG-INFO +128 -0
- statebase-0.1.0/statebase.egg-info/SOURCES.txt +11 -0
- statebase-0.1.0/statebase.egg-info/dependency_links.txt +1 -0
- statebase-0.1.0/statebase.egg-info/requires.txt +3 -0
- statebase-0.1.0/statebase.egg-info/top_level.txt +1 -0
statebase-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: statebase
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: The Reliability Layer for Production AI Agents
|
|
5
|
+
Home-page: https://github.com/StateBase/statebase-python
|
|
6
|
+
Author: StateBase Team
|
|
7
|
+
Author-email: hello@statebase.org
|
|
8
|
+
Project-URL: Bug Reports, https://github.com/StateBase/statebase-python/issues
|
|
9
|
+
Project-URL: Source, https://github.com/StateBase/statebase-python
|
|
10
|
+
Keywords: ai,agents,memory,state,llm
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
Requires-Dist: httpx>=0.24.0
|
|
22
|
+
Requires-Dist: pydantic>=2.0.0
|
|
23
|
+
Requires-Dist: typing-extensions>=4.0.0
|
|
24
|
+
Dynamic: author
|
|
25
|
+
Dynamic: author-email
|
|
26
|
+
Dynamic: classifier
|
|
27
|
+
Dynamic: description
|
|
28
|
+
Dynamic: description-content-type
|
|
29
|
+
Dynamic: home-page
|
|
30
|
+
Dynamic: keywords
|
|
31
|
+
Dynamic: project-url
|
|
32
|
+
Dynamic: requires-dist
|
|
33
|
+
Dynamic: requires-python
|
|
34
|
+
Dynamic: summary
|
|
35
|
+
|
|
36
|
+
# StateBase SDKs
|
|
37
|
+
|
|
38
|
+
This repository contains the official SDKs for StateBase API.
|
|
39
|
+
|
|
40
|
+
## 📦 Python SDK
|
|
41
|
+
|
|
42
|
+
### Installation
|
|
43
|
+
```bash
|
|
44
|
+
cd state-base-api-client
|
|
45
|
+
pip install -e .
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Usage
|
|
49
|
+
```python
|
|
50
|
+
from state_base_api_client import Client
|
|
51
|
+
from state_base_api_client.api.sessions import create_session_v1_sessions_post
|
|
52
|
+
from state_base_api_client.models import SessionCreateRequest
|
|
53
|
+
|
|
54
|
+
# Initialize client
|
|
55
|
+
client = Client(base_url="https://api.statebase.org")
|
|
56
|
+
client = client.with_headers({"X-API-Key": "your-api-key"})
|
|
57
|
+
|
|
58
|
+
# Create a session
|
|
59
|
+
request = SessionCreateRequest(
|
|
60
|
+
agent_id="my-agent",
|
|
61
|
+
initial_state={"user_name": "Alice"}
|
|
62
|
+
)
|
|
63
|
+
session = create_session_v1_sessions_post.sync(client=client, body=request)
|
|
64
|
+
|
|
65
|
+
print(f"Created session: {session.id}")
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Features:**
|
|
69
|
+
- ✅ Auto-generated from OpenAPI spec (always in sync)
|
|
70
|
+
- ✅ Full type hints with Pydantic
|
|
71
|
+
- ✅ Sync and async support
|
|
72
|
+
- ✅ Complete API coverage
|
|
73
|
+
|
|
74
|
+
## 📦 TypeScript SDK
|
|
75
|
+
|
|
76
|
+
### Installation
|
|
77
|
+
```bash
|
|
78
|
+
cd ../statebase-ts-sdk
|
|
79
|
+
npm install
|
|
80
|
+
npm run build
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Usage
|
|
84
|
+
```typescript
|
|
85
|
+
import StateBase from './src/index';
|
|
86
|
+
|
|
87
|
+
// Initialize client
|
|
88
|
+
const client = new StateBase('your-api-key', 'http://api.statebase.org');
|
|
89
|
+
|
|
90
|
+
// Create a session
|
|
91
|
+
const session = await client.createSession({
|
|
92
|
+
agent_id: 'my-agent',
|
|
93
|
+
initial_state: { user_name: 'Alice' }
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
console.log(`Created session: ${session.id}`);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Features:**
|
|
100
|
+
- ✅ Auto-generated TypeScript types from OpenAPI
|
|
101
|
+
- ✅ Clean, intuitive API
|
|
102
|
+
- ✅ Full type safety
|
|
103
|
+
- ✅ Promise-based async
|
|
104
|
+
|
|
105
|
+
## 🔄 Regenerating SDKs
|
|
106
|
+
|
|
107
|
+
When the API changes, regenerate the SDKs:
|
|
108
|
+
|
|
109
|
+
### TypeScript Types
|
|
110
|
+
```bash
|
|
111
|
+
cd statebase-ts-sdk
|
|
112
|
+
npx openapi-typescript ../statebase/openapi.json -o src/schema.ts
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Python Client
|
|
116
|
+
```bash
|
|
117
|
+
cd statebase-py-sdk
|
|
118
|
+
python -m openapi_python_client generate --path ../statebase/openapi.json
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## 📚 Documentation
|
|
122
|
+
|
|
123
|
+
- API Docs: http://api.statebase.org/docs
|
|
124
|
+
- Full Documentation: https://docs.statebase.org
|
|
125
|
+
|
|
126
|
+
## License
|
|
127
|
+
|
|
128
|
+
MIT
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# StateBase SDKs
|
|
2
|
+
|
|
3
|
+
This repository contains the official SDKs for StateBase API.
|
|
4
|
+
|
|
5
|
+
## 📦 Python SDK
|
|
6
|
+
|
|
7
|
+
### Installation
|
|
8
|
+
```bash
|
|
9
|
+
cd state-base-api-client
|
|
10
|
+
pip install -e .
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Usage
|
|
14
|
+
```python
|
|
15
|
+
from state_base_api_client import Client
|
|
16
|
+
from state_base_api_client.api.sessions import create_session_v1_sessions_post
|
|
17
|
+
from state_base_api_client.models import SessionCreateRequest
|
|
18
|
+
|
|
19
|
+
# Initialize client
|
|
20
|
+
client = Client(base_url="https://api.statebase.org")
|
|
21
|
+
client = client.with_headers({"X-API-Key": "your-api-key"})
|
|
22
|
+
|
|
23
|
+
# Create a session
|
|
24
|
+
request = SessionCreateRequest(
|
|
25
|
+
agent_id="my-agent",
|
|
26
|
+
initial_state={"user_name": "Alice"}
|
|
27
|
+
)
|
|
28
|
+
session = create_session_v1_sessions_post.sync(client=client, body=request)
|
|
29
|
+
|
|
30
|
+
print(f"Created session: {session.id}")
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Features:**
|
|
34
|
+
- ✅ Auto-generated from OpenAPI spec (always in sync)
|
|
35
|
+
- ✅ Full type hints with Pydantic
|
|
36
|
+
- ✅ Sync and async support
|
|
37
|
+
- ✅ Complete API coverage
|
|
38
|
+
|
|
39
|
+
## 📦 TypeScript SDK
|
|
40
|
+
|
|
41
|
+
### Installation
|
|
42
|
+
```bash
|
|
43
|
+
cd ../statebase-ts-sdk
|
|
44
|
+
npm install
|
|
45
|
+
npm run build
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Usage
|
|
49
|
+
```typescript
|
|
50
|
+
import StateBase from './src/index';
|
|
51
|
+
|
|
52
|
+
// Initialize client
|
|
53
|
+
const client = new StateBase('your-api-key', 'http://api.statebase.org');
|
|
54
|
+
|
|
55
|
+
// Create a session
|
|
56
|
+
const session = await client.createSession({
|
|
57
|
+
agent_id: 'my-agent',
|
|
58
|
+
initial_state: { user_name: 'Alice' }
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
console.log(`Created session: ${session.id}`);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Features:**
|
|
65
|
+
- ✅ Auto-generated TypeScript types from OpenAPI
|
|
66
|
+
- ✅ Clean, intuitive API
|
|
67
|
+
- ✅ Full type safety
|
|
68
|
+
- ✅ Promise-based async
|
|
69
|
+
|
|
70
|
+
## 🔄 Regenerating SDKs
|
|
71
|
+
|
|
72
|
+
When the API changes, regenerate the SDKs:
|
|
73
|
+
|
|
74
|
+
### TypeScript Types
|
|
75
|
+
```bash
|
|
76
|
+
cd statebase-ts-sdk
|
|
77
|
+
npx openapi-typescript ../statebase/openapi.json -o src/schema.ts
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Python Client
|
|
81
|
+
```bash
|
|
82
|
+
cd statebase-py-sdk
|
|
83
|
+
python -m openapi_python_client generate --path ../statebase/openapi.json
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 📚 Documentation
|
|
87
|
+
|
|
88
|
+
- API Docs: http://api.statebase.org/docs
|
|
89
|
+
- Full Documentation: https://docs.statebase.org
|
|
90
|
+
|
|
91
|
+
## License
|
|
92
|
+
|
|
93
|
+
MIT
|
statebase-0.1.0/setup.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
import pathlib
|
|
3
|
+
|
|
4
|
+
# Read the README
|
|
5
|
+
here = pathlib.Path(__file__).parent.resolve()
|
|
6
|
+
long_description = (here / "README.md").read_text(encoding="utf-8")
|
|
7
|
+
|
|
8
|
+
setup(
|
|
9
|
+
name="statebase",
|
|
10
|
+
version="0.1.0",
|
|
11
|
+
description="The Reliability Layer for Production AI Agents",
|
|
12
|
+
long_description=long_description,
|
|
13
|
+
long_description_content_type="text/markdown",
|
|
14
|
+
url="https://github.com/StateBase/statebase-python",
|
|
15
|
+
author="StateBase Team",
|
|
16
|
+
author_email="hello@statebase.org",
|
|
17
|
+
classifiers=[
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
21
|
+
"License :: OSI Approved :: MIT License",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.9",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
],
|
|
27
|
+
keywords="ai, agents, memory, state, llm",
|
|
28
|
+
packages=find_packages(exclude=["tests"]),
|
|
29
|
+
python_requires=">=3.9",
|
|
30
|
+
install_requires=[
|
|
31
|
+
"httpx>=0.24.0",
|
|
32
|
+
"pydantic>=2.0.0",
|
|
33
|
+
"typing-extensions>=4.0.0"
|
|
34
|
+
],
|
|
35
|
+
project_urls={
|
|
36
|
+
"Bug Reports": "https://github.com/StateBase/statebase-python/issues",
|
|
37
|
+
"Source": "https://github.com/StateBase/statebase-python",
|
|
38
|
+
},
|
|
39
|
+
)
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"""
|
|
2
|
+
StateBase Python SDK - Async Client
|
|
3
|
+
"""
|
|
4
|
+
import httpx
|
|
5
|
+
from typing import Optional, Dict, Any, List
|
|
6
|
+
from .models import (
|
|
7
|
+
SessionResponse,
|
|
8
|
+
TurnResponse,
|
|
9
|
+
MemoryResponse,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AsyncStateBase:
|
|
14
|
+
"""Asynchronous client for StateBase API"""
|
|
15
|
+
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
api_key: str,
|
|
19
|
+
base_url: str = "https://api.statebase.org",
|
|
20
|
+
timeout: float = 30.0
|
|
21
|
+
):
|
|
22
|
+
"""
|
|
23
|
+
Initialize async StateBase client.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
api_key: Your StateBase API key
|
|
27
|
+
base_url: Base URL for the API
|
|
28
|
+
timeout: Request timeout in seconds
|
|
29
|
+
"""
|
|
30
|
+
self.base_url = base_url.rstrip('/')
|
|
31
|
+
self.timeout = timeout
|
|
32
|
+
self.client = httpx.AsyncClient(
|
|
33
|
+
headers={
|
|
34
|
+
"X-API-Key": api_key,
|
|
35
|
+
"Content-Type": "application/json"
|
|
36
|
+
},
|
|
37
|
+
timeout=timeout
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
async def __aenter__(self):
|
|
41
|
+
return self
|
|
42
|
+
|
|
43
|
+
async def __aexit__(self, *args):
|
|
44
|
+
await self.close()
|
|
45
|
+
|
|
46
|
+
async def close(self):
|
|
47
|
+
"""Close the HTTP client"""
|
|
48
|
+
await self.client.aclose()
|
|
49
|
+
|
|
50
|
+
# Sessions
|
|
51
|
+
async def create_session(
|
|
52
|
+
self,
|
|
53
|
+
agent_id: str,
|
|
54
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
55
|
+
initial_state: Optional[Dict[str, Any]] = None,
|
|
56
|
+
ttl_seconds: Optional[int] = None
|
|
57
|
+
) -> SessionResponse:
|
|
58
|
+
"""Create a new session"""
|
|
59
|
+
response = await self.client.post(
|
|
60
|
+
f"{self.base_url}/v1/sessions",
|
|
61
|
+
json={
|
|
62
|
+
"agent_id": agent_id,
|
|
63
|
+
"metadata": metadata,
|
|
64
|
+
"initial_state": initial_state,
|
|
65
|
+
"ttl_seconds": ttl_seconds
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
response.raise_for_status()
|
|
69
|
+
return SessionResponse(**response.json())
|
|
70
|
+
|
|
71
|
+
async def get_session(self, session_id: str) -> SessionResponse:
|
|
72
|
+
"""Get session by ID"""
|
|
73
|
+
response = await self.client.get(f"{self.base_url}/v1/sessions/{session_id}")
|
|
74
|
+
response.raise_for_status()
|
|
75
|
+
return SessionResponse(**response.json())
|
|
76
|
+
|
|
77
|
+
async def delete_session(self, session_id: str) -> None:
|
|
78
|
+
"""Delete a session"""
|
|
79
|
+
response = await self.client.delete(f"{self.base_url}/v1/sessions/{session_id}")
|
|
80
|
+
response.raise_for_status()
|
|
81
|
+
|
|
82
|
+
# Turns
|
|
83
|
+
async def create_turn(
|
|
84
|
+
self,
|
|
85
|
+
session_id: str,
|
|
86
|
+
input_content: str,
|
|
87
|
+
output_content: str,
|
|
88
|
+
input_type: str = "text",
|
|
89
|
+
output_type: str = "text",
|
|
90
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
91
|
+
reasoning: Optional[str] = None
|
|
92
|
+
) -> TurnResponse:
|
|
93
|
+
"""Create a new turn in a session"""
|
|
94
|
+
response = await self.client.post(
|
|
95
|
+
f"{self.base_url}/v1/sessions/{session_id}/turns",
|
|
96
|
+
json={
|
|
97
|
+
"input": {"type": input_type, "content": input_content},
|
|
98
|
+
"output": {"type": output_type, "content": output_content},
|
|
99
|
+
"metadata": metadata,
|
|
100
|
+
"reasoning": reasoning
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
response.raise_for_status()
|
|
104
|
+
return TurnResponse(**response.json())
|
|
105
|
+
|
|
106
|
+
# State
|
|
107
|
+
async def get_state(self, session_id: str) -> Dict[str, Any]:
|
|
108
|
+
"""Get current state of a session"""
|
|
109
|
+
response = await self.client.get(f"{self.base_url}/v1/sessions/{session_id}/state")
|
|
110
|
+
response.raise_for_status()
|
|
111
|
+
return response.json()
|
|
112
|
+
|
|
113
|
+
async def update_state(
|
|
114
|
+
self,
|
|
115
|
+
session_id: str,
|
|
116
|
+
updates: Dict[str, Any],
|
|
117
|
+
reasoning: Optional[str] = None
|
|
118
|
+
) -> Dict[str, Any]:
|
|
119
|
+
"""Partially update session state"""
|
|
120
|
+
response = await self.client.patch(
|
|
121
|
+
f"{self.base_url}/v1/sessions/{session_id}/state",
|
|
122
|
+
json={"updates": updates, "reasoning": reasoning}
|
|
123
|
+
)
|
|
124
|
+
response.raise_for_status()
|
|
125
|
+
return response.json()
|
|
126
|
+
|
|
127
|
+
async def replace_state(
|
|
128
|
+
self,
|
|
129
|
+
session_id: str,
|
|
130
|
+
state: Dict[str, Any],
|
|
131
|
+
reasoning: Optional[str] = None
|
|
132
|
+
) -> Dict[str, Any]:
|
|
133
|
+
"""Replace entire session state"""
|
|
134
|
+
response = await self.client.put(
|
|
135
|
+
f"{self.base_url}/v1/sessions/{session_id}/state",
|
|
136
|
+
json={"state": state, "reasoning": reasoning}
|
|
137
|
+
)
|
|
138
|
+
response.raise_for_status()
|
|
139
|
+
return response.json()
|
|
140
|
+
|
|
141
|
+
# Memories
|
|
142
|
+
async def create_memory(
|
|
143
|
+
self,
|
|
144
|
+
content: str,
|
|
145
|
+
memory_type: str = "fact",
|
|
146
|
+
session_id: Optional[str] = None,
|
|
147
|
+
tags: Optional[List[str]] = None,
|
|
148
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
149
|
+
) -> MemoryResponse:
|
|
150
|
+
"""Create a new memory"""
|
|
151
|
+
response = await self.client.post(
|
|
152
|
+
f"{self.base_url}/v1/memories",
|
|
153
|
+
json={
|
|
154
|
+
"content": content,
|
|
155
|
+
"memory_type": memory_type,
|
|
156
|
+
"session_id": session_id,
|
|
157
|
+
"tags": tags,
|
|
158
|
+
"metadata": metadata
|
|
159
|
+
}
|
|
160
|
+
)
|
|
161
|
+
response.raise_for_status()
|
|
162
|
+
return MemoryResponse(**response.json())
|
|
163
|
+
|
|
164
|
+
async def search_memories(
|
|
165
|
+
self,
|
|
166
|
+
query: str,
|
|
167
|
+
session_id: Optional[str] = None,
|
|
168
|
+
memory_type: Optional[str] = None,
|
|
169
|
+
limit: int = 10
|
|
170
|
+
) -> List[MemoryResponse]:
|
|
171
|
+
"""Search memories by semantic similarity"""
|
|
172
|
+
params = {"query": query, "limit": limit}
|
|
173
|
+
if session_id:
|
|
174
|
+
params["session_id"] = session_id
|
|
175
|
+
if memory_type:
|
|
176
|
+
params["type"] = memory_type
|
|
177
|
+
|
|
178
|
+
response = await self.client.get(f"{self.base_url}/v1/memories/search", params=params)
|
|
179
|
+
response.raise_for_status()
|
|
180
|
+
return [MemoryResponse(**m) for m in response.json().get("data", [])]
|
|
181
|
+
|
|
182
|
+
# Health
|
|
183
|
+
async def health(self) -> Dict[str, Any]:
|
|
184
|
+
"""Check API health"""
|
|
185
|
+
response = await self.client.get(f"{self.base_url}/health")
|
|
186
|
+
response.raise_for_status()
|
|
187
|
+
return response.json()
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"""
|
|
2
|
+
StateBase Python SDK - Synchronous Client
|
|
3
|
+
"""
|
|
4
|
+
import httpx
|
|
5
|
+
from typing import Optional, Dict, Any, List
|
|
6
|
+
from .models import (
|
|
7
|
+
SessionCreateRequest,
|
|
8
|
+
SessionResponse,
|
|
9
|
+
TurnCreateRequest,
|
|
10
|
+
TurnResponse,
|
|
11
|
+
MemoryCreateRequest,
|
|
12
|
+
MemoryResponse,
|
|
13
|
+
StateUpdateRequest,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class StateBase:
|
|
18
|
+
"""Synchronous client for StateBase API"""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
api_key: str,
|
|
23
|
+
base_url: str = "https://api.statebase.org",
|
|
24
|
+
timeout: float = 30.0
|
|
25
|
+
):
|
|
26
|
+
"""
|
|
27
|
+
Initialize StateBase client.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
api_key: Your StateBase API key
|
|
31
|
+
base_url: Base URL for the API (default: production)
|
|
32
|
+
timeout: Request timeout in seconds
|
|
33
|
+
"""
|
|
34
|
+
self.base_url = base_url.rstrip('/')
|
|
35
|
+
self.timeout = timeout
|
|
36
|
+
self.client = httpx.Client(
|
|
37
|
+
headers={
|
|
38
|
+
"X-API-Key": api_key,
|
|
39
|
+
"Content-Type": "application/json"
|
|
40
|
+
},
|
|
41
|
+
timeout=timeout
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
def __enter__(self):
|
|
45
|
+
return self
|
|
46
|
+
|
|
47
|
+
def __exit__(self, *args):
|
|
48
|
+
self.close()
|
|
49
|
+
|
|
50
|
+
def close(self):
|
|
51
|
+
"""Close the HTTP client"""
|
|
52
|
+
self.client.close()
|
|
53
|
+
|
|
54
|
+
# Sessions
|
|
55
|
+
def create_session(
|
|
56
|
+
self,
|
|
57
|
+
agent_id: str,
|
|
58
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
59
|
+
initial_state: Optional[Dict[str, Any]] = None,
|
|
60
|
+
ttl_seconds: Optional[int] = None
|
|
61
|
+
) -> SessionResponse:
|
|
62
|
+
"""Create a new session"""
|
|
63
|
+
response = self.client.post(
|
|
64
|
+
f"{self.base_url}/v1/sessions",
|
|
65
|
+
json={
|
|
66
|
+
"agent_id": agent_id,
|
|
67
|
+
"metadata": metadata,
|
|
68
|
+
"initial_state": initial_state,
|
|
69
|
+
"ttl_seconds": ttl_seconds
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
response.raise_for_status()
|
|
73
|
+
return SessionResponse(**response.json())
|
|
74
|
+
|
|
75
|
+
def get_session(self, session_id: str) -> SessionResponse:
|
|
76
|
+
"""Get session by ID"""
|
|
77
|
+
response = self.client.get(f"{self.base_url}/v1/sessions/{session_id}")
|
|
78
|
+
response.raise_for_status()
|
|
79
|
+
return SessionResponse(**response.json())
|
|
80
|
+
|
|
81
|
+
def delete_session(self, session_id: str) -> None:
|
|
82
|
+
"""Delete a session"""
|
|
83
|
+
response = self.client.delete(f"{self.base_url}/v1/sessions/{session_id}")
|
|
84
|
+
response.raise_for_status()
|
|
85
|
+
|
|
86
|
+
# Turns
|
|
87
|
+
def create_turn(
|
|
88
|
+
self,
|
|
89
|
+
session_id: str,
|
|
90
|
+
input_content: str,
|
|
91
|
+
output_content: str,
|
|
92
|
+
input_type: str = "text",
|
|
93
|
+
output_type: str = "text",
|
|
94
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
95
|
+
reasoning: Optional[str] = None
|
|
96
|
+
) -> TurnResponse:
|
|
97
|
+
"""Create a new turn in a session"""
|
|
98
|
+
response = self.client.post(
|
|
99
|
+
f"{self.base_url}/v1/sessions/{session_id}/turns",
|
|
100
|
+
json={
|
|
101
|
+
"input": {"type": input_type, "content": input_content},
|
|
102
|
+
"output": {"type": output_type, "content": output_content},
|
|
103
|
+
"metadata": metadata,
|
|
104
|
+
"reasoning": reasoning
|
|
105
|
+
}
|
|
106
|
+
)
|
|
107
|
+
response.raise_for_status()
|
|
108
|
+
return TurnResponse(**response.json())
|
|
109
|
+
|
|
110
|
+
# State
|
|
111
|
+
def get_state(self, session_id: str) -> Dict[str, Any]:
|
|
112
|
+
"""Get current state of a session"""
|
|
113
|
+
response = self.client.get(f"{self.base_url}/v1/sessions/{session_id}/state")
|
|
114
|
+
response.raise_for_status()
|
|
115
|
+
return response.json()
|
|
116
|
+
|
|
117
|
+
def update_state(
|
|
118
|
+
self,
|
|
119
|
+
session_id: str,
|
|
120
|
+
updates: Dict[str, Any],
|
|
121
|
+
reasoning: Optional[str] = None
|
|
122
|
+
) -> Dict[str, Any]:
|
|
123
|
+
"""Partially update session state"""
|
|
124
|
+
response = self.client.patch(
|
|
125
|
+
f"{self.base_url}/v1/sessions/{session_id}/state",
|
|
126
|
+
json={"state": updates, "reasoning": reasoning}
|
|
127
|
+
)
|
|
128
|
+
response.raise_for_status()
|
|
129
|
+
return response.json()
|
|
130
|
+
|
|
131
|
+
def replace_state(
|
|
132
|
+
self,
|
|
133
|
+
session_id: str,
|
|
134
|
+
state: Dict[str, Any],
|
|
135
|
+
reasoning: Optional[str] = None
|
|
136
|
+
) -> Dict[str, Any]:
|
|
137
|
+
"""Replace entire session state"""
|
|
138
|
+
response = self.client.put(
|
|
139
|
+
f"{self.base_url}/v1/sessions/{session_id}/state",
|
|
140
|
+
json={"state": state, "reasoning": reasoning}
|
|
141
|
+
)
|
|
142
|
+
response.raise_for_status()
|
|
143
|
+
return response.json()
|
|
144
|
+
|
|
145
|
+
# Memories
|
|
146
|
+
def create_memory(
|
|
147
|
+
self,
|
|
148
|
+
content: str,
|
|
149
|
+
memory_type: str = "fact",
|
|
150
|
+
session_id: Optional[str] = None,
|
|
151
|
+
tags: Optional[List[str]] = None,
|
|
152
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
153
|
+
) -> MemoryResponse:
|
|
154
|
+
"""Create a new memory"""
|
|
155
|
+
response = self.client.post(
|
|
156
|
+
f"{self.base_url}/v1/memories",
|
|
157
|
+
json={
|
|
158
|
+
"content": content,
|
|
159
|
+
"type": memory_type,
|
|
160
|
+
"session_id": session_id,
|
|
161
|
+
"tags": tags,
|
|
162
|
+
"metadata": metadata
|
|
163
|
+
}
|
|
164
|
+
)
|
|
165
|
+
response.raise_for_status()
|
|
166
|
+
return MemoryResponse(**response.json())
|
|
167
|
+
|
|
168
|
+
def search_memories(
|
|
169
|
+
self,
|
|
170
|
+
query: str,
|
|
171
|
+
session_id: Optional[str] = None,
|
|
172
|
+
memory_type: Optional[str] = None,
|
|
173
|
+
limit: int = 10
|
|
174
|
+
) -> List[MemoryResponse]:
|
|
175
|
+
"""Search memories by semantic similarity"""
|
|
176
|
+
params = {"query": query, "limit": limit}
|
|
177
|
+
if session_id:
|
|
178
|
+
params["session_id"] = session_id
|
|
179
|
+
if memory_type:
|
|
180
|
+
params["types"] = memory_type
|
|
181
|
+
|
|
182
|
+
response = self.client.get(f"{self.base_url}/v1/memories/search", params=params)
|
|
183
|
+
response.raise_for_status()
|
|
184
|
+
return [MemoryResponse(**m) for m in response.json().get("data", [])]
|
|
185
|
+
|
|
186
|
+
# Health
|
|
187
|
+
def health(self) -> Dict[str, Any]:
|
|
188
|
+
"""Check API health"""
|
|
189
|
+
response = self.client.get(f"{self.base_url}/health")
|
|
190
|
+
response.raise_for_status()
|
|
191
|
+
return response.json()
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"""
|
|
2
|
+
StateBase SDK Models
|
|
3
|
+
"""
|
|
4
|
+
from typing import Optional, Dict, Any, List
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SessionCreateRequest(BaseModel):
|
|
9
|
+
agent_id: str
|
|
10
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
11
|
+
initial_state: Optional[Dict[str, Any]] = None
|
|
12
|
+
ttl_seconds: Optional[int] = None
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SessionResponse(BaseModel):
|
|
16
|
+
object: str = "session"
|
|
17
|
+
id: str
|
|
18
|
+
agent_id: str
|
|
19
|
+
created_at: str
|
|
20
|
+
updated_at: str
|
|
21
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
22
|
+
state: Dict[str, Any]
|
|
23
|
+
memory_count: int
|
|
24
|
+
turn_count: int
|
|
25
|
+
ttl_expires_at: Optional[str] = None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class TurnInput(BaseModel):
|
|
29
|
+
type: str
|
|
30
|
+
content: str
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class TurnOutput(BaseModel):
|
|
34
|
+
type: str
|
|
35
|
+
content: str
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class TurnCreateRequest(BaseModel):
|
|
39
|
+
input: TurnInput
|
|
40
|
+
output: TurnOutput
|
|
41
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
42
|
+
reasoning: Optional[str] = None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class TurnResponse(BaseModel):
|
|
46
|
+
object: str = "turn"
|
|
47
|
+
id: str
|
|
48
|
+
session_id: str
|
|
49
|
+
turn_number: int
|
|
50
|
+
input: TurnInput
|
|
51
|
+
output: TurnOutput
|
|
52
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
53
|
+
reasoning: Optional[str] = None
|
|
54
|
+
state_before: Dict[str, Any]
|
|
55
|
+
state_after: Dict[str, Any]
|
|
56
|
+
created_at: str
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class MemoryCreateRequest(BaseModel):
|
|
60
|
+
content: str
|
|
61
|
+
memory_type: str = "fact"
|
|
62
|
+
session_id: Optional[str] = None
|
|
63
|
+
tags: Optional[List[str]] = None
|
|
64
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class MemoryResponse(BaseModel):
|
|
68
|
+
object: str = "memory"
|
|
69
|
+
id: str
|
|
70
|
+
content: str
|
|
71
|
+
memory_type: str
|
|
72
|
+
session_id: Optional[str] = None
|
|
73
|
+
tags: List[str] = []
|
|
74
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
75
|
+
created_at: str
|
|
76
|
+
updated_at: str
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class StateUpdateRequest(BaseModel):
|
|
80
|
+
updates: Dict[str, Any]
|
|
81
|
+
reasoning: Optional[str] = None
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class StateReplaceRequest(BaseModel):
|
|
85
|
+
state: Dict[str, Any]
|
|
86
|
+
reasoning: Optional[str] = None
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: statebase
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: The Reliability Layer for Production AI Agents
|
|
5
|
+
Home-page: https://github.com/StateBase/statebase-python
|
|
6
|
+
Author: StateBase Team
|
|
7
|
+
Author-email: hello@statebase.org
|
|
8
|
+
Project-URL: Bug Reports, https://github.com/StateBase/statebase-python/issues
|
|
9
|
+
Project-URL: Source, https://github.com/StateBase/statebase-python
|
|
10
|
+
Keywords: ai,agents,memory,state,llm
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
Requires-Dist: httpx>=0.24.0
|
|
22
|
+
Requires-Dist: pydantic>=2.0.0
|
|
23
|
+
Requires-Dist: typing-extensions>=4.0.0
|
|
24
|
+
Dynamic: author
|
|
25
|
+
Dynamic: author-email
|
|
26
|
+
Dynamic: classifier
|
|
27
|
+
Dynamic: description
|
|
28
|
+
Dynamic: description-content-type
|
|
29
|
+
Dynamic: home-page
|
|
30
|
+
Dynamic: keywords
|
|
31
|
+
Dynamic: project-url
|
|
32
|
+
Dynamic: requires-dist
|
|
33
|
+
Dynamic: requires-python
|
|
34
|
+
Dynamic: summary
|
|
35
|
+
|
|
36
|
+
# StateBase SDKs
|
|
37
|
+
|
|
38
|
+
This repository contains the official SDKs for StateBase API.
|
|
39
|
+
|
|
40
|
+
## 📦 Python SDK
|
|
41
|
+
|
|
42
|
+
### Installation
|
|
43
|
+
```bash
|
|
44
|
+
cd state-base-api-client
|
|
45
|
+
pip install -e .
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Usage
|
|
49
|
+
```python
|
|
50
|
+
from state_base_api_client import Client
|
|
51
|
+
from state_base_api_client.api.sessions import create_session_v1_sessions_post
|
|
52
|
+
from state_base_api_client.models import SessionCreateRequest
|
|
53
|
+
|
|
54
|
+
# Initialize client
|
|
55
|
+
client = Client(base_url="https://api.statebase.org")
|
|
56
|
+
client = client.with_headers({"X-API-Key": "your-api-key"})
|
|
57
|
+
|
|
58
|
+
# Create a session
|
|
59
|
+
request = SessionCreateRequest(
|
|
60
|
+
agent_id="my-agent",
|
|
61
|
+
initial_state={"user_name": "Alice"}
|
|
62
|
+
)
|
|
63
|
+
session = create_session_v1_sessions_post.sync(client=client, body=request)
|
|
64
|
+
|
|
65
|
+
print(f"Created session: {session.id}")
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Features:**
|
|
69
|
+
- ✅ Auto-generated from OpenAPI spec (always in sync)
|
|
70
|
+
- ✅ Full type hints with Pydantic
|
|
71
|
+
- ✅ Sync and async support
|
|
72
|
+
- ✅ Complete API coverage
|
|
73
|
+
|
|
74
|
+
## 📦 TypeScript SDK
|
|
75
|
+
|
|
76
|
+
### Installation
|
|
77
|
+
```bash
|
|
78
|
+
cd ../statebase-ts-sdk
|
|
79
|
+
npm install
|
|
80
|
+
npm run build
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Usage
|
|
84
|
+
```typescript
|
|
85
|
+
import StateBase from './src/index';
|
|
86
|
+
|
|
87
|
+
// Initialize client
|
|
88
|
+
const client = new StateBase('your-api-key', 'http://api.statebase.org');
|
|
89
|
+
|
|
90
|
+
// Create a session
|
|
91
|
+
const session = await client.createSession({
|
|
92
|
+
agent_id: 'my-agent',
|
|
93
|
+
initial_state: { user_name: 'Alice' }
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
console.log(`Created session: ${session.id}`);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Features:**
|
|
100
|
+
- ✅ Auto-generated TypeScript types from OpenAPI
|
|
101
|
+
- ✅ Clean, intuitive API
|
|
102
|
+
- ✅ Full type safety
|
|
103
|
+
- ✅ Promise-based async
|
|
104
|
+
|
|
105
|
+
## 🔄 Regenerating SDKs
|
|
106
|
+
|
|
107
|
+
When the API changes, regenerate the SDKs:
|
|
108
|
+
|
|
109
|
+
### TypeScript Types
|
|
110
|
+
```bash
|
|
111
|
+
cd statebase-ts-sdk
|
|
112
|
+
npx openapi-typescript ../statebase/openapi.json -o src/schema.ts
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Python Client
|
|
116
|
+
```bash
|
|
117
|
+
cd statebase-py-sdk
|
|
118
|
+
python -m openapi_python_client generate --path ../statebase/openapi.json
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## 📚 Documentation
|
|
122
|
+
|
|
123
|
+
- API Docs: http://api.statebase.org/docs
|
|
124
|
+
- Full Documentation: https://docs.statebase.org
|
|
125
|
+
|
|
126
|
+
## License
|
|
127
|
+
|
|
128
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
setup.py
|
|
3
|
+
statebase/__init__.py
|
|
4
|
+
statebase/async_client.py
|
|
5
|
+
statebase/client.py
|
|
6
|
+
statebase/models.py
|
|
7
|
+
statebase.egg-info/PKG-INFO
|
|
8
|
+
statebase.egg-info/SOURCES.txt
|
|
9
|
+
statebase.egg-info/dependency_links.txt
|
|
10
|
+
statebase.egg-info/requires.txt
|
|
11
|
+
statebase.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
statebase
|