dimo-python-sdk 1.6.0__tar.gz → 1.7.2__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.
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/PKG-INFO +25 -3
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/README.md +23 -1
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/api/__init__.py +2 -0
- dimo_python_sdk-1.7.2/dimo/api/conversations.py +343 -0
- dimo_python_sdk-1.7.2/dimo/api/fetch.py +123 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/dimo.py +4 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/environments.py +4 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo_python_sdk.egg-info/PKG-INFO +25 -3
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo_python_sdk.egg-info/SOURCES.txt +3 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/pyproject.toml +2 -1
- dimo_python_sdk-1.7.2/tests/test_conversations.py +693 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/LICENSE +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/__init__.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/api/attestation.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/api/auth.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/api/device_definitions.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/api/token_exchange.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/api/trips.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/api/valuations.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/api/vehicle_triggers.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/constants.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/errors.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/eth_signer.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/graphql/__init__.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/graphql/identity.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/graphql/telemetry.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/permission_decoder.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo/request.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo_python_sdk.egg-info/dependency_links.txt +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo_python_sdk.egg-info/requires.txt +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/dimo_python_sdk.egg-info/top_level.txt +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/setup.cfg +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/tests/test_dimo.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/tests/test_errors.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/tests/test_permission_decoder.py +0 -0
- {dimo_python_sdk-1.6.0 → dimo_python_sdk-1.7.2}/tests/test_request.py +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dimo-python-sdk
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.7.2
|
|
4
4
|
Summary: DIMO SDK in Python
|
|
5
|
-
Author-email: Barrett Kowalsky <barrettkowalsky@gmail.com>
|
|
5
|
+
Author-email: Barrett Kowalsky <barrettkowalsky@gmail.com>, James Li <james.li.upenn@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/DIMO-Network/dimo-python-sdk
|
|
7
7
|
Project-URL: Issues, https://github.com/DIMO-Network/dimo-python-sdk/issues
|
|
8
8
|
Keywords: dimo,sdk,python,depin,web3
|
|
@@ -28,7 +28,29 @@ pip install dimo-python-sdk
|
|
|
28
28
|
|
|
29
29
|
## Unit Testing
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
The SDK includes comprehensive unit tests to ensure reliability and correctness. To run the tests:
|
|
32
|
+
|
|
33
|
+
1. **Install dependencies:**
|
|
34
|
+
```bash
|
|
35
|
+
pip install -r requirements.txt
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
2. **Run all tests:**
|
|
39
|
+
```bash
|
|
40
|
+
pytest
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
3. **Run tests with verbose output:**
|
|
44
|
+
```bash
|
|
45
|
+
pytest -v
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
4. **Run specific test files:**
|
|
49
|
+
```bash
|
|
50
|
+
pytest tests/test_conversations.py -v
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The test suite uses `pytest` and includes tests for all major SDK functionality including authentication, API endpoints, GraphQL queries, and error handling
|
|
32
54
|
|
|
33
55
|
## API Documentation
|
|
34
56
|
|
|
@@ -10,7 +10,29 @@ pip install dimo-python-sdk
|
|
|
10
10
|
|
|
11
11
|
## Unit Testing
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
The SDK includes comprehensive unit tests to ensure reliability and correctness. To run the tests:
|
|
14
|
+
|
|
15
|
+
1. **Install dependencies:**
|
|
16
|
+
```bash
|
|
17
|
+
pip install -r requirements.txt
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
2. **Run all tests:**
|
|
21
|
+
```bash
|
|
22
|
+
pytest
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
3. **Run tests with verbose output:**
|
|
26
|
+
```bash
|
|
27
|
+
pytest -v
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
4. **Run specific test files:**
|
|
31
|
+
```bash
|
|
32
|
+
pytest tests/test_conversations.py -v
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The test suite uses `pytest` and includes tests for all major SDK functionality including authentication, API endpoints, GraphQL queries, and error handling
|
|
14
36
|
|
|
15
37
|
## API Documentation
|
|
16
38
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from .auth import Auth
|
|
2
2
|
from .attestation import Attestation
|
|
3
3
|
from .device_definitions import DeviceDefinitions
|
|
4
|
+
from .fetch import Fetch
|
|
4
5
|
from .token_exchange import TokenExchange
|
|
5
6
|
from .trips import Trips
|
|
6
7
|
from .valuations import Valuations
|
|
@@ -9,6 +10,7 @@ __all__ = [
|
|
|
9
10
|
"Auth",
|
|
10
11
|
"Attestation",
|
|
11
12
|
"DeviceDefinitions",
|
|
13
|
+
"Fetch",
|
|
12
14
|
"TokenExchange",
|
|
13
15
|
"Trips",
|
|
14
16
|
"Valuations",
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
from dimo.errors import check_type, check_optional_type, HTTPError
|
|
2
|
+
from typing import Dict, List, Optional, Any, Generator
|
|
3
|
+
from requests import Session, RequestException
|
|
4
|
+
import json
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Conversations:
|
|
8
|
+
"""
|
|
9
|
+
Client for the DIMO Conversations API.
|
|
10
|
+
|
|
11
|
+
This API enables developers to create conversational AI agents that can query
|
|
12
|
+
vehicle data, telemetry data, and perform web searches on behalf of users.
|
|
13
|
+
|
|
14
|
+
Key Features:
|
|
15
|
+
- Create AI agents with access to specific vehicles
|
|
16
|
+
- Query vehicle identity (make, model, owner) via GraphQL
|
|
17
|
+
- Query real-time telemetry (speed, fuel, location) via GraphQL
|
|
18
|
+
- Perform location-based web searches
|
|
19
|
+
- Stream responses in real-time using Server-Sent Events (SSE)
|
|
20
|
+
- Multi-agent delegation architecture with specialized subagents
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, request_method, get_auth_headers, get_full_path, session: Session):
|
|
24
|
+
self._request = request_method
|
|
25
|
+
self._get_auth_headers = get_auth_headers
|
|
26
|
+
self._get_full_path = get_full_path
|
|
27
|
+
self._session = session
|
|
28
|
+
|
|
29
|
+
def health_check(self) -> Dict:
|
|
30
|
+
"""
|
|
31
|
+
Check the service status and configuration.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
dict: Service health information including status, version, proxy, and default_model
|
|
35
|
+
|
|
36
|
+
Example:
|
|
37
|
+
>>> dimo = DIMO("Production")
|
|
38
|
+
>>> health = dimo.conversations.health_check()
|
|
39
|
+
>>> print(health['status'])
|
|
40
|
+
"""
|
|
41
|
+
response = self._request("GET", "Conversations", "/")
|
|
42
|
+
return response
|
|
43
|
+
|
|
44
|
+
def create_agent(
|
|
45
|
+
self,
|
|
46
|
+
developer_jwt: str,
|
|
47
|
+
api_key: str,
|
|
48
|
+
user_wallet: str,
|
|
49
|
+
agent_type: str,
|
|
50
|
+
vehicle_ids: Optional[str] = None,
|
|
51
|
+
personality: str = "uncle_mechanic",
|
|
52
|
+
) -> Dict:
|
|
53
|
+
"""
|
|
54
|
+
Create a new conversational agent with the specified configuration.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
developer_jwt (str): Developer JWT token for authentication
|
|
58
|
+
api_key (str): DIMO API key for the agent to access vehicle data
|
|
59
|
+
user_wallet (str): User's wallet address (e.g., "0x2345...")
|
|
60
|
+
agent_type (str): The type of agent to create (e.g., "driver_agent_v1")
|
|
61
|
+
vehicle_ids (str, optional): JSON array string of vehicle token IDs (e.g., "[1, 2, 3]").
|
|
62
|
+
If not provided, agent will have access to all vehicles owned by the user.
|
|
63
|
+
personality (str, optional): Personality preset for the agent. Defaults to "uncle_mechanic"
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
dict: Agent information including agentId and configuration details
|
|
67
|
+
|
|
68
|
+
Behavior:
|
|
69
|
+
- Creates a new agent with the specified type and configuration
|
|
70
|
+
- Validates configuration and mode detection
|
|
71
|
+
- Creates/reuses shared identity subagent
|
|
72
|
+
- Creates per-vehicle telemetry subagents with token exchange
|
|
73
|
+
- Creates shared websearch subagent if enabled
|
|
74
|
+
|
|
75
|
+
Example:
|
|
76
|
+
>>> dimo = DIMO("Production")
|
|
77
|
+
>>> dev_jwt = "your_developer_jwt"
|
|
78
|
+
>>> agent = dimo.conversations.create_agent(
|
|
79
|
+
... developer_jwt=dev_jwt,
|
|
80
|
+
... api_key="0x1234567890abcdef...",
|
|
81
|
+
... user_wallet="0x86b04f6d1D9E79aD7eB31cDEAF37442B00d64605",
|
|
82
|
+
... agent_type="driver_agent_v1",
|
|
83
|
+
... vehicle_ids="[1, 2, 3]",
|
|
84
|
+
... )
|
|
85
|
+
>>> print(agent['agentId'])
|
|
86
|
+
"""
|
|
87
|
+
check_type("developer_jwt", developer_jwt, str)
|
|
88
|
+
check_type("api_key", api_key, str)
|
|
89
|
+
check_type("user_wallet", user_wallet, str)
|
|
90
|
+
check_optional_type("vehicle_ids", vehicle_ids, str)
|
|
91
|
+
check_type("agent_type", agent_type, str)
|
|
92
|
+
check_type("personality", personality, str)
|
|
93
|
+
|
|
94
|
+
# Build variables dict
|
|
95
|
+
variables = {"USER_WALLET": user_wallet}
|
|
96
|
+
if vehicle_ids is not None:
|
|
97
|
+
variables["VEHICLE_IDS"] = vehicle_ids
|
|
98
|
+
|
|
99
|
+
# Build request body
|
|
100
|
+
body = {
|
|
101
|
+
"personality": personality,
|
|
102
|
+
"secrets": {"DIMO_API_KEY": api_key},
|
|
103
|
+
"type": agent_type,
|
|
104
|
+
"variables": variables,
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
response = self._request(
|
|
108
|
+
"POST",
|
|
109
|
+
"Conversations",
|
|
110
|
+
"/agents",
|
|
111
|
+
headers=self._get_auth_headers(developer_jwt),
|
|
112
|
+
data=body,
|
|
113
|
+
)
|
|
114
|
+
return response
|
|
115
|
+
|
|
116
|
+
def delete_agent(self, developer_jwt: str, agent_id: str) -> Dict:
|
|
117
|
+
"""
|
|
118
|
+
Delete an agent and all associated resources.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
developer_jwt (str): Developer JWT token for authentication
|
|
122
|
+
agent_id (str): The agent ID to delete
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
dict: Confirmation message
|
|
126
|
+
|
|
127
|
+
Behavior:
|
|
128
|
+
- Deletes Letta agent from server
|
|
129
|
+
- Removes metadata from AgentManager
|
|
130
|
+
- Cleanup errors are logged but don't fail the request
|
|
131
|
+
|
|
132
|
+
Example:
|
|
133
|
+
>>> dimo = DIMO("Production")
|
|
134
|
+
>>> dev_jwt = "your_developer_jwt"
|
|
135
|
+
>>> result = dimo.conversations.delete_agent(
|
|
136
|
+
... developer_jwt=dev_jwt,
|
|
137
|
+
... agent_id="agent-abc123"
|
|
138
|
+
... )
|
|
139
|
+
>>> print(result['message'])
|
|
140
|
+
"""
|
|
141
|
+
check_type("developer_jwt", developer_jwt, str)
|
|
142
|
+
check_type("agent_id", agent_id, str)
|
|
143
|
+
|
|
144
|
+
response = self._request(
|
|
145
|
+
"DELETE",
|
|
146
|
+
"Conversations",
|
|
147
|
+
f"/agents/{agent_id}",
|
|
148
|
+
headers=self._get_auth_headers(developer_jwt),
|
|
149
|
+
)
|
|
150
|
+
return response
|
|
151
|
+
|
|
152
|
+
def send_message(
|
|
153
|
+
self,
|
|
154
|
+
developer_jwt: str,
|
|
155
|
+
agent_id: str,
|
|
156
|
+
message: str,
|
|
157
|
+
vehicle_ids: Optional[List[int]] = None,
|
|
158
|
+
user: Optional[str] = None,
|
|
159
|
+
) -> Dict:
|
|
160
|
+
"""
|
|
161
|
+
Send a message to an agent and receive the complete response (synchronous).
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
developer_jwt (str): Developer JWT token for authentication
|
|
165
|
+
agent_id (str): The agent ID to send the message to
|
|
166
|
+
message (str): The message to send to the agent
|
|
167
|
+
vehicle_ids (list[int], optional): Optional vehicle IDs override
|
|
168
|
+
user (str, optional): Optional user override
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
dict: Response including agentId, message, response, vehiclesQueried, and timestamp
|
|
172
|
+
|
|
173
|
+
Behavior:
|
|
174
|
+
- Synchronous request/response
|
|
175
|
+
- Agent delegates to subagents as needed
|
|
176
|
+
- Returns full response after agent completes reasoning
|
|
177
|
+
- Timeout: 120 seconds for complex queries
|
|
178
|
+
|
|
179
|
+
Example:
|
|
180
|
+
>>> dimo = DIMO("Production")
|
|
181
|
+
>>> dev_jwt = "your_developer_jwt"
|
|
182
|
+
>>> response = dimo.conversations.send_message(
|
|
183
|
+
... developer_jwt=dev_jwt,
|
|
184
|
+
... agent_id="agent-abc123",
|
|
185
|
+
... message="What's the make and model of my vehicle?"
|
|
186
|
+
... )
|
|
187
|
+
>>> print(response['response'])
|
|
188
|
+
"""
|
|
189
|
+
check_type("developer_jwt", developer_jwt, str)
|
|
190
|
+
check_type("agent_id", agent_id, str)
|
|
191
|
+
check_type("message", message, str)
|
|
192
|
+
check_optional_type("vehicle_ids", vehicle_ids, list)
|
|
193
|
+
check_optional_type("user", user, str)
|
|
194
|
+
|
|
195
|
+
body = {"message": message}
|
|
196
|
+
if vehicle_ids is not None:
|
|
197
|
+
body["vehicleIds"] = vehicle_ids
|
|
198
|
+
if user is not None:
|
|
199
|
+
body["user"] = user
|
|
200
|
+
|
|
201
|
+
response = self._request(
|
|
202
|
+
"POST",
|
|
203
|
+
"Conversations",
|
|
204
|
+
f"/agents/{agent_id}/message",
|
|
205
|
+
headers=self._get_auth_headers(developer_jwt),
|
|
206
|
+
data=body,
|
|
207
|
+
)
|
|
208
|
+
return response
|
|
209
|
+
|
|
210
|
+
def stream_message(
|
|
211
|
+
self,
|
|
212
|
+
developer_jwt: str,
|
|
213
|
+
agent_id: str,
|
|
214
|
+
message: str,
|
|
215
|
+
vehicle_ids: Optional[List[int]] = None,
|
|
216
|
+
user: Optional[str] = None,
|
|
217
|
+
) -> Generator[Dict[str, Any], None, None]:
|
|
218
|
+
"""
|
|
219
|
+
Send a message and receive real-time token-by-token streaming response via SSE.
|
|
220
|
+
|
|
221
|
+
Args:
|
|
222
|
+
developer_jwt (str): Developer JWT token for authentication
|
|
223
|
+
agent_id (str): The agent ID to send the message to
|
|
224
|
+
message (str): The message to send to the agent
|
|
225
|
+
vehicle_ids (list[int], optional): Optional vehicle IDs override
|
|
226
|
+
user (str, optional): Optional user override
|
|
227
|
+
|
|
228
|
+
Yields:
|
|
229
|
+
dict: SSE events with either {"content": "token"} or {"done": true, ...metadata}
|
|
230
|
+
|
|
231
|
+
Behavior:
|
|
232
|
+
- Real-time streaming for better UX
|
|
233
|
+
- Token-by-token generation from LLM
|
|
234
|
+
- Final message includes metadata (agentId, vehiclesQueried)
|
|
235
|
+
|
|
236
|
+
Example:
|
|
237
|
+
>>> dimo = DIMO("Production")
|
|
238
|
+
>>> dev_jwt = "your_developer_jwt"
|
|
239
|
+
>>> for chunk in dimo.conversations.stream_message(
|
|
240
|
+
... developer_jwt=dev_jwt,
|
|
241
|
+
... agent_id="agent-abc123",
|
|
242
|
+
... message="What's my current speed?"
|
|
243
|
+
... ):
|
|
244
|
+
... if "content" in chunk:
|
|
245
|
+
... print(chunk["content"], end="", flush=True)
|
|
246
|
+
... elif "done" in chunk:
|
|
247
|
+
... print(f"\\nVehicles queried: {chunk['vehiclesQueried']}")
|
|
248
|
+
"""
|
|
249
|
+
check_type("developer_jwt", developer_jwt, str)
|
|
250
|
+
check_type("agent_id", agent_id, str)
|
|
251
|
+
check_type("message", message, str)
|
|
252
|
+
check_optional_type("vehicle_ids", vehicle_ids, list)
|
|
253
|
+
check_optional_type("user", user, str)
|
|
254
|
+
|
|
255
|
+
body = {"message": message}
|
|
256
|
+
if vehicle_ids is not None:
|
|
257
|
+
body["vehicleIds"] = vehicle_ids
|
|
258
|
+
if user is not None:
|
|
259
|
+
body["user"] = user
|
|
260
|
+
|
|
261
|
+
headers = self._get_auth_headers(developer_jwt)
|
|
262
|
+
headers["Accept"] = "text/event-stream"
|
|
263
|
+
headers["Content-Type"] = "application/json"
|
|
264
|
+
|
|
265
|
+
# Build full URL
|
|
266
|
+
url = self._get_full_path("Conversations", f"/agents/{agent_id}/stream")
|
|
267
|
+
|
|
268
|
+
# Make streaming request directly with session
|
|
269
|
+
try:
|
|
270
|
+
response = self._session.request(
|
|
271
|
+
method="POST",
|
|
272
|
+
url=url,
|
|
273
|
+
headers=headers,
|
|
274
|
+
data=json.dumps(body),
|
|
275
|
+
stream=True,
|
|
276
|
+
)
|
|
277
|
+
response.raise_for_status()
|
|
278
|
+
except RequestException as exc:
|
|
279
|
+
status = getattr(exc.response, "status_code", None)
|
|
280
|
+
body_error = None
|
|
281
|
+
try:
|
|
282
|
+
body_error = exc.response.json()
|
|
283
|
+
except Exception:
|
|
284
|
+
body_error = exc.response.text if exc.response else None
|
|
285
|
+
raise HTTPError(status=status or -1, message=str(exc), body=body_error)
|
|
286
|
+
|
|
287
|
+
# Parse SSE stream
|
|
288
|
+
for line in response.iter_lines():
|
|
289
|
+
if line:
|
|
290
|
+
line = line.decode("utf-8")
|
|
291
|
+
if line.startswith("data: "):
|
|
292
|
+
data = line[6:] # Remove "data: " prefix
|
|
293
|
+
try:
|
|
294
|
+
yield json.loads(data)
|
|
295
|
+
except json.JSONDecodeError:
|
|
296
|
+
# Skip malformed JSON
|
|
297
|
+
continue
|
|
298
|
+
|
|
299
|
+
def get_history(
|
|
300
|
+
self,
|
|
301
|
+
developer_jwt: str,
|
|
302
|
+
agent_id: str,
|
|
303
|
+
limit: int = 100,
|
|
304
|
+
) -> Dict:
|
|
305
|
+
"""
|
|
306
|
+
Retrieve all messages in a conversation.
|
|
307
|
+
|
|
308
|
+
Args:
|
|
309
|
+
developer_jwt (str): Developer JWT token for authentication
|
|
310
|
+
agent_id (str): The agent ID to get history for
|
|
311
|
+
limit (int): Maximum number of messages to return (default: 100)
|
|
312
|
+
|
|
313
|
+
Returns:
|
|
314
|
+
dict: Conversation history including agentId, messages array, and total count
|
|
315
|
+
|
|
316
|
+
Behavior:
|
|
317
|
+
- Retrieves from Letta server
|
|
318
|
+
- Includes all message roles (user, agent, system)
|
|
319
|
+
- Reverse chronological order (newest first)
|
|
320
|
+
|
|
321
|
+
Example:
|
|
322
|
+
>>> dimo = DIMO("Production")
|
|
323
|
+
>>> dev_jwt = "your_developer_jwt"
|
|
324
|
+
>>> history = dimo.conversations.get_history(
|
|
325
|
+
... developer_jwt=dev_jwt,
|
|
326
|
+
... agent_id="agent-abc123",
|
|
327
|
+
... limit=50
|
|
328
|
+
... )
|
|
329
|
+
>>> for msg in history['messages']:
|
|
330
|
+
... print(f"{msg['role']}: {msg['content']}")
|
|
331
|
+
"""
|
|
332
|
+
check_type("developer_jwt", developer_jwt, str)
|
|
333
|
+
check_type("agent_id", agent_id, str)
|
|
334
|
+
check_type("limit", limit, int)
|
|
335
|
+
|
|
336
|
+
response = self._request(
|
|
337
|
+
"GET",
|
|
338
|
+
"Conversations",
|
|
339
|
+
f"/agents/{agent_id}/history",
|
|
340
|
+
headers=self._get_auth_headers(developer_jwt),
|
|
341
|
+
params={"limit": limit},
|
|
342
|
+
)
|
|
343
|
+
return response
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
from dimo.errors import check_type, check_optional_type
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Fetch:
|
|
5
|
+
|
|
6
|
+
def __init__(self, request_method, get_auth_headers):
|
|
7
|
+
self._request = request_method
|
|
8
|
+
self._get_auth_headers = get_auth_headers
|
|
9
|
+
|
|
10
|
+
def _build_params(self, **kwargs):
|
|
11
|
+
params = {}
|
|
12
|
+
for key, value in kwargs.items():
|
|
13
|
+
if value is not None:
|
|
14
|
+
params[key] = value
|
|
15
|
+
return params
|
|
16
|
+
|
|
17
|
+
def get_index_keys(
|
|
18
|
+
self,
|
|
19
|
+
vehicle_jwt: str,
|
|
20
|
+
token_id: int,
|
|
21
|
+
after=None,
|
|
22
|
+
before=None,
|
|
23
|
+
id=None,
|
|
24
|
+
limit=None,
|
|
25
|
+
producer=None,
|
|
26
|
+
source=None,
|
|
27
|
+
type=None,
|
|
28
|
+
) -> dict:
|
|
29
|
+
check_type("vehicle_jwt", vehicle_jwt, str)
|
|
30
|
+
check_type("token_id", token_id, int)
|
|
31
|
+
params = self._build_params(
|
|
32
|
+
after=after, before=before, id=id, limit=limit,
|
|
33
|
+
producer=producer, source=source, type=type,
|
|
34
|
+
)
|
|
35
|
+
url = f"/v1/vehicle/index-keys/{token_id}"
|
|
36
|
+
return self._request(
|
|
37
|
+
"GET",
|
|
38
|
+
"Fetch",
|
|
39
|
+
url,
|
|
40
|
+
params=params,
|
|
41
|
+
headers=self._get_auth_headers(vehicle_jwt),
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
def get_latest_index_key(
|
|
45
|
+
self,
|
|
46
|
+
vehicle_jwt: str,
|
|
47
|
+
token_id: int,
|
|
48
|
+
after=None,
|
|
49
|
+
before=None,
|
|
50
|
+
id=None,
|
|
51
|
+
limit=None,
|
|
52
|
+
producer=None,
|
|
53
|
+
source=None,
|
|
54
|
+
type=None,
|
|
55
|
+
) -> dict:
|
|
56
|
+
check_type("vehicle_jwt", vehicle_jwt, str)
|
|
57
|
+
check_type("token_id", token_id, int)
|
|
58
|
+
params = self._build_params(
|
|
59
|
+
after=after, before=before, id=id, limit=limit,
|
|
60
|
+
producer=producer, source=source, type=type,
|
|
61
|
+
)
|
|
62
|
+
url = f"/v1/vehicle/latest-index-key/{token_id}"
|
|
63
|
+
return self._request(
|
|
64
|
+
"GET",
|
|
65
|
+
"Fetch",
|
|
66
|
+
url,
|
|
67
|
+
params=params,
|
|
68
|
+
headers=self._get_auth_headers(vehicle_jwt),
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
def get_latest_object(
|
|
72
|
+
self,
|
|
73
|
+
vehicle_jwt: str,
|
|
74
|
+
token_id: int,
|
|
75
|
+
after=None,
|
|
76
|
+
before=None,
|
|
77
|
+
id=None,
|
|
78
|
+
limit=None,
|
|
79
|
+
producer=None,
|
|
80
|
+
source=None,
|
|
81
|
+
type=None,
|
|
82
|
+
) -> dict:
|
|
83
|
+
check_type("vehicle_jwt", vehicle_jwt, str)
|
|
84
|
+
check_type("token_id", token_id, int)
|
|
85
|
+
params = self._build_params(
|
|
86
|
+
after=after, before=before, id=id, limit=limit,
|
|
87
|
+
producer=producer, source=source, type=type,
|
|
88
|
+
)
|
|
89
|
+
url = f"/v1/vehicle/latest-object/{token_id}"
|
|
90
|
+
return self._request(
|
|
91
|
+
"GET",
|
|
92
|
+
"Fetch",
|
|
93
|
+
url,
|
|
94
|
+
params=params,
|
|
95
|
+
headers=self._get_auth_headers(vehicle_jwt),
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
def get_objects(
|
|
99
|
+
self,
|
|
100
|
+
vehicle_jwt: str,
|
|
101
|
+
token_id: int,
|
|
102
|
+
after=None,
|
|
103
|
+
before=None,
|
|
104
|
+
id=None,
|
|
105
|
+
limit=None,
|
|
106
|
+
producer=None,
|
|
107
|
+
source=None,
|
|
108
|
+
type=None,
|
|
109
|
+
) -> dict:
|
|
110
|
+
check_type("vehicle_jwt", vehicle_jwt, str)
|
|
111
|
+
check_type("token_id", token_id, int)
|
|
112
|
+
params = self._build_params(
|
|
113
|
+
after=after, before=before, id=id, limit=limit,
|
|
114
|
+
producer=producer, source=source, type=type,
|
|
115
|
+
)
|
|
116
|
+
url = f"/v1/vehicle/objects/{token_id}"
|
|
117
|
+
return self._request(
|
|
118
|
+
"GET",
|
|
119
|
+
"Fetch",
|
|
120
|
+
url,
|
|
121
|
+
params=params,
|
|
122
|
+
headers=self._get_auth_headers(vehicle_jwt),
|
|
123
|
+
)
|
|
@@ -2,8 +2,10 @@ from requests import Session
|
|
|
2
2
|
|
|
3
3
|
from .api.attestation import Attestation
|
|
4
4
|
from .api.auth import Auth
|
|
5
|
+
from .api.conversations import Conversations
|
|
5
6
|
from .api.device_definitions import DeviceDefinitions
|
|
6
7
|
from .api.token_exchange import TokenExchange
|
|
8
|
+
from .api.fetch import Fetch
|
|
7
9
|
from .api.trips import Trips
|
|
8
10
|
from .api.valuations import Valuations
|
|
9
11
|
from .api.vehicle_triggers import VehicleTriggers
|
|
@@ -75,7 +77,9 @@ class DIMO:
|
|
|
75
77
|
mapping = {
|
|
76
78
|
"attestation": (Attestation, ("request", "_get_auth_headers")),
|
|
77
79
|
"auth": (Auth, ("request", "_get_auth_headers", "env", "self")),
|
|
80
|
+
"conversations": (Conversations, ("request", "_get_auth_headers", "_get_full_path", "session")),
|
|
78
81
|
"device_definitions": (DeviceDefinitions, ("request", "_get_auth_headers")),
|
|
82
|
+
"fetch": (Fetch, ("request", "_get_auth_headers")),
|
|
79
83
|
"token_exchange": (
|
|
80
84
|
TokenExchange,
|
|
81
85
|
("request", "_get_auth_headers", "identity", "self"),
|
|
@@ -2,8 +2,10 @@ dimo_environment = {
|
|
|
2
2
|
"Production": {
|
|
3
3
|
"Attestation": "https://attestation-api.dimo.zone",
|
|
4
4
|
"Auth": "https://auth.dimo.zone",
|
|
5
|
+
"Conversations": "https://conversations-api.dimo.zone",
|
|
5
6
|
"Identity": "https://identity-api.dimo.zone/query",
|
|
6
7
|
"DeviceDefinitions": "https://device-definitions-api.dimo.zone",
|
|
8
|
+
"Fetch": "https://fetch-api.dimo.zone",
|
|
7
9
|
"Telemetry": "https://telemetry-api.dimo.zone/query",
|
|
8
10
|
"TokenExchange": "https://token-exchange-api.dimo.zone",
|
|
9
11
|
"Trips": "https://trips-api.dimo.zone",
|
|
@@ -14,8 +16,10 @@ dimo_environment = {
|
|
|
14
16
|
"Dev": {
|
|
15
17
|
"Attestation": "https://attestation-api.dev.dimo.zone",
|
|
16
18
|
"Auth": "https://auth.dev.dimo.zone",
|
|
19
|
+
"Conversations": "https://conversations-api.dev.dimo.zone",
|
|
17
20
|
"Identity": "https://identity-api.dev.dimo.zone/query",
|
|
18
21
|
"DeviceDefinitions": "https://device-definitions-api.dev.dimo.zone",
|
|
22
|
+
"Fetch": "https://fetch-api.dev.dimo.zone",
|
|
19
23
|
"Telemetry": "https://telemetry-api.dev.dimo.zone/query",
|
|
20
24
|
"TokenExchange": "https://token-exchange-api.dev.dimo.zone",
|
|
21
25
|
"Trips": "https://trips-api.dev.dimo.zone",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dimo-python-sdk
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.7.2
|
|
4
4
|
Summary: DIMO SDK in Python
|
|
5
|
-
Author-email: Barrett Kowalsky <barrettkowalsky@gmail.com>
|
|
5
|
+
Author-email: Barrett Kowalsky <barrettkowalsky@gmail.com>, James Li <james.li.upenn@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/DIMO-Network/dimo-python-sdk
|
|
7
7
|
Project-URL: Issues, https://github.com/DIMO-Network/dimo-python-sdk/issues
|
|
8
8
|
Keywords: dimo,sdk,python,depin,web3
|
|
@@ -28,7 +28,29 @@ pip install dimo-python-sdk
|
|
|
28
28
|
|
|
29
29
|
## Unit Testing
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
The SDK includes comprehensive unit tests to ensure reliability and correctness. To run the tests:
|
|
32
|
+
|
|
33
|
+
1. **Install dependencies:**
|
|
34
|
+
```bash
|
|
35
|
+
pip install -r requirements.txt
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
2. **Run all tests:**
|
|
39
|
+
```bash
|
|
40
|
+
pytest
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
3. **Run tests with verbose output:**
|
|
44
|
+
```bash
|
|
45
|
+
pytest -v
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
4. **Run specific test files:**
|
|
49
|
+
```bash
|
|
50
|
+
pytest tests/test_conversations.py -v
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The test suite uses `pytest` and includes tests for all major SDK functionality including authentication, API endpoints, GraphQL queries, and error handling
|
|
32
54
|
|
|
33
55
|
## API Documentation
|
|
34
56
|
|
|
@@ -12,7 +12,9 @@ dimo/request.py
|
|
|
12
12
|
dimo/api/__init__.py
|
|
13
13
|
dimo/api/attestation.py
|
|
14
14
|
dimo/api/auth.py
|
|
15
|
+
dimo/api/conversations.py
|
|
15
16
|
dimo/api/device_definitions.py
|
|
17
|
+
dimo/api/fetch.py
|
|
16
18
|
dimo/api/token_exchange.py
|
|
17
19
|
dimo/api/trips.py
|
|
18
20
|
dimo/api/valuations.py
|
|
@@ -25,6 +27,7 @@ dimo_python_sdk.egg-info/SOURCES.txt
|
|
|
25
27
|
dimo_python_sdk.egg-info/dependency_links.txt
|
|
26
28
|
dimo_python_sdk.egg-info/requires.txt
|
|
27
29
|
dimo_python_sdk.egg-info/top_level.txt
|
|
30
|
+
tests/test_conversations.py
|
|
28
31
|
tests/test_dimo.py
|
|
29
32
|
tests/test_errors.py
|
|
30
33
|
tests/test_permission_decoder.py
|
|
@@ -4,9 +4,10 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dimo-python-sdk"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.7.2"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Barrett Kowalsky", email="barrettkowalsky@gmail.com" },
|
|
10
|
+
{ name="James Li", email="james.li.upenn@gmail.com" },
|
|
10
11
|
]
|
|
11
12
|
description = "DIMO SDK in Python"
|
|
12
13
|
readme = "README.md"
|