simile 0.5.3__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.
Potentially problematic release.
This version of simile might be problematic. Click here for more details.
- simile/__init__.py +61 -0
- simile/auth_client.py +270 -0
- simile/client.py +885 -0
- simile/exceptions.py +47 -0
- simile/models.py +435 -0
- simile/resources.py +328 -0
- simile-0.5.3.dist-info/METADATA +63 -0
- simile-0.5.3.dist-info/RECORD +11 -0
- simile-0.5.3.dist-info/WHEEL +5 -0
- simile-0.5.3.dist-info/licenses/LICENSE +21 -0
- simile-0.5.3.dist-info/top_level.txt +1 -0
simile/resources.py
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
from typing import TYPE_CHECKING, List, Optional, Dict
|
|
3
|
+
|
|
4
|
+
from .models import (
|
|
5
|
+
OpenGenerationRequest,
|
|
6
|
+
OpenGenerationResponse,
|
|
7
|
+
ClosedGenerationRequest,
|
|
8
|
+
ClosedGenerationResponse,
|
|
9
|
+
SurveySessionCloseResponse,
|
|
10
|
+
AddContextRequest,
|
|
11
|
+
AddContextResponse,
|
|
12
|
+
SurveySessionDetailResponse,
|
|
13
|
+
SurveySessionCreateResponse,
|
|
14
|
+
MemoryStream,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from .client import Simile
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Agent:
|
|
22
|
+
"""Represents an agent and provides methods for interacting with it directly."""
|
|
23
|
+
|
|
24
|
+
def __init__(self, agent_id: uuid.UUID, client: "Simile"):
|
|
25
|
+
self._agent_id = agent_id
|
|
26
|
+
self._client = client
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def id(self) -> uuid.UUID:
|
|
30
|
+
return self._agent_id
|
|
31
|
+
|
|
32
|
+
async def generate_open_response(
|
|
33
|
+
self,
|
|
34
|
+
question: str,
|
|
35
|
+
data_types: Optional[List[str]] = None,
|
|
36
|
+
exclude_data_types: Optional[List[str]] = None,
|
|
37
|
+
images: Optional[Dict[str, str]] = None,
|
|
38
|
+
memory_stream: Optional[MemoryStream] = None,
|
|
39
|
+
) -> OpenGenerationResponse:
|
|
40
|
+
"""Generates an open response from this agent based on a question."""
|
|
41
|
+
return await self._client.generate_open_response(
|
|
42
|
+
agent_id=self._agent_id,
|
|
43
|
+
question=question,
|
|
44
|
+
data_types=data_types,
|
|
45
|
+
exclude_data_types=exclude_data_types,
|
|
46
|
+
images=images,
|
|
47
|
+
memory_stream=memory_stream,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
async def generate_closed_response(
|
|
51
|
+
self,
|
|
52
|
+
question: str,
|
|
53
|
+
options: List[str],
|
|
54
|
+
data_types: Optional[List[str]] = None,
|
|
55
|
+
exclude_data_types: Optional[List[str]] = None,
|
|
56
|
+
images: Optional[Dict[str, str]] = None,
|
|
57
|
+
memory_stream: Optional[MemoryStream] = None,
|
|
58
|
+
) -> ClosedGenerationResponse:
|
|
59
|
+
"""Generates a closed response from this agent."""
|
|
60
|
+
return await self._client.generate_closed_response(
|
|
61
|
+
agent_id=self._agent_id,
|
|
62
|
+
question=question,
|
|
63
|
+
options=options,
|
|
64
|
+
data_types=data_types,
|
|
65
|
+
exclude_data_types=exclude_data_types,
|
|
66
|
+
images=images,
|
|
67
|
+
memory_stream=memory_stream,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class SurveySession:
|
|
72
|
+
"""Represents an active survey session with an agent, allowing for contextual multi-turn generation."""
|
|
73
|
+
|
|
74
|
+
def __init__(
|
|
75
|
+
self, id: uuid.UUID, agent_id: uuid.UUID, status: str, client: "Simile"
|
|
76
|
+
):
|
|
77
|
+
self._id = id
|
|
78
|
+
self._agent_id = agent_id
|
|
79
|
+
self._status = status
|
|
80
|
+
self._client = client
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def id(self) -> uuid.UUID:
|
|
84
|
+
return self._id
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def agent_id(self) -> uuid.UUID:
|
|
88
|
+
return self._agent_id
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def status(self) -> str:
|
|
92
|
+
return self._status
|
|
93
|
+
|
|
94
|
+
async def get_details(self) -> SurveySessionDetailResponse:
|
|
95
|
+
"""Retrieves detailed information about this survey session including typed conversation history."""
|
|
96
|
+
return await self._client.get_survey_session_details(self._id)
|
|
97
|
+
|
|
98
|
+
async def view(self) -> SurveySessionDetailResponse:
|
|
99
|
+
"""Alias for get_details() - retrieves all turns in this session."""
|
|
100
|
+
return await self.get_details()
|
|
101
|
+
|
|
102
|
+
async def generate_open_response(
|
|
103
|
+
self,
|
|
104
|
+
question: str,
|
|
105
|
+
data_types: Optional[List[str]] = None,
|
|
106
|
+
exclude_data_types: Optional[List[str]] = None,
|
|
107
|
+
images: Optional[Dict[str, str]] = None,
|
|
108
|
+
reasoning: bool = False,
|
|
109
|
+
) -> OpenGenerationResponse:
|
|
110
|
+
"""Generates an open response within this survey session."""
|
|
111
|
+
endpoint = f"sessions/{str(self._id)}/open"
|
|
112
|
+
payload = OpenGenerationRequest(
|
|
113
|
+
question=question,
|
|
114
|
+
data_types=data_types,
|
|
115
|
+
exclude_data_types=exclude_data_types,
|
|
116
|
+
images=images,
|
|
117
|
+
reasoning=reasoning,
|
|
118
|
+
)
|
|
119
|
+
return await self._client._request(
|
|
120
|
+
"POST",
|
|
121
|
+
endpoint,
|
|
122
|
+
json=payload.model_dump(),
|
|
123
|
+
response_model=OpenGenerationResponse,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
async def generate_closed_response(
|
|
127
|
+
self,
|
|
128
|
+
question: str,
|
|
129
|
+
options: List[str],
|
|
130
|
+
data_types: Optional[List[str]] = None,
|
|
131
|
+
exclude_data_types: Optional[List[str]] = None,
|
|
132
|
+
images: Optional[Dict[str, str]] = None,
|
|
133
|
+
reasoning: bool = False,
|
|
134
|
+
) -> ClosedGenerationResponse:
|
|
135
|
+
"""Generates a closed response within this survey session."""
|
|
136
|
+
endpoint = f"sessions/{str(self._id)}/closed"
|
|
137
|
+
payload = ClosedGenerationRequest(
|
|
138
|
+
question=question,
|
|
139
|
+
options=options,
|
|
140
|
+
data_types=data_types,
|
|
141
|
+
exclude_data_types=exclude_data_types,
|
|
142
|
+
images=images,
|
|
143
|
+
reasoning=reasoning,
|
|
144
|
+
)
|
|
145
|
+
return await self._client._request(
|
|
146
|
+
"POST",
|
|
147
|
+
endpoint,
|
|
148
|
+
json=payload.model_dump(),
|
|
149
|
+
response_model=ClosedGenerationResponse,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
async def add_context(self, ctx: str) -> AddContextResponse:
|
|
153
|
+
"""Adds text to the SurveySession without requesting a response."""
|
|
154
|
+
endpoint = f"sessions/{str(self._id)}/context"
|
|
155
|
+
payload = AddContextRequest(context=ctx)
|
|
156
|
+
return await self._client._request(
|
|
157
|
+
"POST",
|
|
158
|
+
endpoint,
|
|
159
|
+
json=payload.model_dump(),
|
|
160
|
+
response_model=AddContextResponse,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
async def add_context_with_timestamp(
|
|
164
|
+
self,
|
|
165
|
+
context_text: str,
|
|
166
|
+
timestamp: str,
|
|
167
|
+
) -> Dict:
|
|
168
|
+
"""Adds context to this session with a specific timestamp.
|
|
169
|
+
|
|
170
|
+
This is a lower-level method that allows specifying when the context was added.
|
|
171
|
+
For normal use, prefer the add_context() method.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
context_text: The context text to add
|
|
175
|
+
timestamp: ISO timestamp of when this interaction occurred
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
Dictionary with success status and the added turn details
|
|
179
|
+
"""
|
|
180
|
+
endpoint = f"sessions/{str(self._id)}/add-turn"
|
|
181
|
+
payload = {
|
|
182
|
+
"turn_type": "context",
|
|
183
|
+
"context_text": context_text,
|
|
184
|
+
"timestamp": timestamp,
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return await self._client._request(
|
|
188
|
+
"POST",
|
|
189
|
+
endpoint,
|
|
190
|
+
json=payload,
|
|
191
|
+
response_model=None, # Return raw dict since we don't have a specific model
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
async def add_images(
|
|
195
|
+
self,
|
|
196
|
+
images: Dict[str, str],
|
|
197
|
+
timestamp: Optional[str] = None,
|
|
198
|
+
) -> Dict:
|
|
199
|
+
"""Adds images to the session's conversation history.
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
images: Dictionary mapping image descriptions to URLs
|
|
203
|
+
timestamp: Optional ISO timestamp of when this interaction occurred
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
Dictionary with success status and the added turn details
|
|
207
|
+
"""
|
|
208
|
+
endpoint = f"sessions/{str(self._id)}/add-turn"
|
|
209
|
+
payload = {
|
|
210
|
+
"turn_type": "image",
|
|
211
|
+
"images": images,
|
|
212
|
+
}
|
|
213
|
+
if timestamp:
|
|
214
|
+
payload["timestamp"] = timestamp
|
|
215
|
+
|
|
216
|
+
return await self._client._request(
|
|
217
|
+
"POST",
|
|
218
|
+
endpoint,
|
|
219
|
+
json=payload,
|
|
220
|
+
response_model=None, # Return raw dict since we don't have a specific model
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
async def add_open_response(
|
|
224
|
+
self,
|
|
225
|
+
question: str,
|
|
226
|
+
response: str,
|
|
227
|
+
timestamp: Optional[str] = None,
|
|
228
|
+
) -> Dict:
|
|
229
|
+
"""Adds an open question-answer pair to the session's history.
|
|
230
|
+
|
|
231
|
+
Args:
|
|
232
|
+
question: The open question text
|
|
233
|
+
response: The response that was given
|
|
234
|
+
timestamp: Optional ISO timestamp of when this interaction occurred
|
|
235
|
+
|
|
236
|
+
Returns:
|
|
237
|
+
Dictionary with success status and the added turn details
|
|
238
|
+
"""
|
|
239
|
+
endpoint = f"sessions/{str(self._id)}/add-turn"
|
|
240
|
+
payload = {
|
|
241
|
+
"turn_type": "open",
|
|
242
|
+
"question": question,
|
|
243
|
+
"response": response,
|
|
244
|
+
}
|
|
245
|
+
if timestamp:
|
|
246
|
+
payload["timestamp"] = timestamp
|
|
247
|
+
|
|
248
|
+
return await self._client._request(
|
|
249
|
+
"POST",
|
|
250
|
+
endpoint,
|
|
251
|
+
json=payload,
|
|
252
|
+
response_model=None, # Return raw dict since we don't have a specific model
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
async def close(self) -> SurveySessionCloseResponse:
|
|
256
|
+
"""Closes this survey session on the server."""
|
|
257
|
+
endpoint = f"sessions/{str(self._id)}/close"
|
|
258
|
+
return await self._client._request(
|
|
259
|
+
"POST", endpoint, response_model=SurveySessionCloseResponse
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
async def add_closed_response(
|
|
263
|
+
self,
|
|
264
|
+
question: str,
|
|
265
|
+
options: List[str],
|
|
266
|
+
response: str,
|
|
267
|
+
timestamp: Optional[str] = None,
|
|
268
|
+
) -> Dict:
|
|
269
|
+
"""Adds a closed question-answer pair to the session's history.
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
question: The closed question text
|
|
273
|
+
options: List of answer options
|
|
274
|
+
response: The option that was selected
|
|
275
|
+
timestamp: Optional ISO timestamp of when this interaction occurred
|
|
276
|
+
|
|
277
|
+
Returns:
|
|
278
|
+
Dictionary with success status and the added turn details
|
|
279
|
+
"""
|
|
280
|
+
endpoint = f"sessions/{str(self._id)}/add-turn"
|
|
281
|
+
payload = {
|
|
282
|
+
"turn_type": "closed",
|
|
283
|
+
"question": question,
|
|
284
|
+
"options": options,
|
|
285
|
+
"response": response,
|
|
286
|
+
}
|
|
287
|
+
if timestamp:
|
|
288
|
+
payload["timestamp"] = timestamp
|
|
289
|
+
|
|
290
|
+
return await self._client._request(
|
|
291
|
+
"POST",
|
|
292
|
+
endpoint,
|
|
293
|
+
json=payload,
|
|
294
|
+
response_model=None, # Return raw dict since we don't have a specific model
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
async def fork(self, turn_index: int) -> "SurveySession":
|
|
298
|
+
"""Fork this session at a specific turn.
|
|
299
|
+
|
|
300
|
+
Creates a new session with the same agent and copies turns from this session
|
|
301
|
+
up to and including the specified turn index.
|
|
302
|
+
|
|
303
|
+
Args:
|
|
304
|
+
turn_index: The 0-based index of the last turn to include in the fork
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
A new SurveySession object representing the forked session
|
|
308
|
+
|
|
309
|
+
Raises:
|
|
310
|
+
Simile.APIError: If the API request fails
|
|
311
|
+
"""
|
|
312
|
+
endpoint = f"sessions/{str(self._id)}/fork"
|
|
313
|
+
params = {"turn_index": turn_index}
|
|
314
|
+
|
|
315
|
+
response = await self._client._request(
|
|
316
|
+
"POST",
|
|
317
|
+
endpoint,
|
|
318
|
+
params=params,
|
|
319
|
+
response_model=SurveySessionCreateResponse,
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
# Create a new SurveySession instance from the response
|
|
323
|
+
return SurveySession(
|
|
324
|
+
id=response.id,
|
|
325
|
+
agent_id=response.agent_id,
|
|
326
|
+
status=response.status,
|
|
327
|
+
client=self._client,
|
|
328
|
+
)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: simile
|
|
3
|
+
Version: 0.5.3
|
|
4
|
+
Summary: Package for interfacing with Simile AI agents for simulation
|
|
5
|
+
Author-email: Simile AI <cqz@simile.ai>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/simile-team/simile-sdk
|
|
8
|
+
Keywords: api,sdk,simile,ai-agent,simulation
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Python: >=3.8
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: httpx>=0.20.0
|
|
23
|
+
Requires-Dist: pydantic>=2.0.0
|
|
24
|
+
Requires-Dist: genagent>=0.2.3
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# Simile API Python Client
|
|
28
|
+
|
|
29
|
+
A Python client for interacting with the Simile API server.
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install simile
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Dependencies
|
|
38
|
+
|
|
39
|
+
- `httpx>=0.20.0`
|
|
40
|
+
- `pydantic>=2.0.0`
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from simile import Simile
|
|
46
|
+
|
|
47
|
+
client = Simile(api_key="your_api_key")
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Publishing
|
|
51
|
+
|
|
52
|
+
First, bump the version in `pyproject.toml`. Then, create the distribution files:
|
|
53
|
+
```bash
|
|
54
|
+
python3 -m build
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Afterwards, use [Twine](https://pypi.org/project/twine/) to upload the package:
|
|
58
|
+
```bash
|
|
59
|
+
pip install twine
|
|
60
|
+
twine upload dist/*
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If you need the PyPI credentials, please ask Carolyn or Chris.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
simile/__init__.py,sha256=gKK94dfA8plQFIny2fY3uL07HiK1SBdB7J4en8ud1_o,1359
|
|
2
|
+
simile/auth_client.py,sha256=ICImmaA5fZX9ADbIPIUh4RED3hBZvLf3XSiaqELDAME,7923
|
|
3
|
+
simile/client.py,sha256=tnVsgs84J2igc88ZTFC2Ltfj0_tcQP0ugQRHAWEoPaA,32321
|
|
4
|
+
simile/exceptions.py,sha256=Q1lbfwR7mEn_LYmwjAnsMc8BW79JNPvmCmVoPibYisU,1502
|
|
5
|
+
simile/models.py,sha256=x3mLaQ-PsLiRZx1lfNctt_brCLCX1sZl71jQzOZ5XH8,13026
|
|
6
|
+
simile/resources.py,sha256=LSYZSzx1YO69xvShGxxLFVPjQHw1WukHXhdYc1EyuOs,10555
|
|
7
|
+
simile-0.5.3.dist-info/licenses/LICENSE,sha256=tpxX3bpODfyOQVyEM6kCMvPHFCpkjFDj0AICRqKqOFA,1066
|
|
8
|
+
simile-0.5.3.dist-info/METADATA,sha256=snAeKerBAKe3_kZIhA8wH55m3pegS1ZpvtD22MBsOJk,1598
|
|
9
|
+
simile-0.5.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
10
|
+
simile-0.5.3.dist-info/top_level.txt,sha256=41lJneubAG4-ZOAs5qn7iDtDb-MDxa6DdvgBKwNX84M,7
|
|
11
|
+
simile-0.5.3.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Simile AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
simile
|