simile 0.2.6__py3-none-any.whl → 0.2.7__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/client.py +15 -3
- simile/models.py +101 -10
- simile/resources.py +50 -20
- {simile-0.2.6.dist-info → simile-0.2.7.dist-info}/METADATA +1 -1
- simile-0.2.7.dist-info/RECORD +10 -0
- simile-0.2.6.dist-info/RECORD +0 -10
- {simile-0.2.6.dist-info → simile-0.2.7.dist-info}/WHEEL +0 -0
- {simile-0.2.6.dist-info → simile-0.2.7.dist-info}/licenses/LICENSE +0 -0
- {simile-0.2.6.dist-info → simile-0.2.7.dist-info}/top_level.txt +0 -0
simile/client.py
CHANGED
|
@@ -10,7 +10,7 @@ from .models import (
|
|
|
10
10
|
MCGenerationRequest, MCGenerationResponse,
|
|
11
11
|
CreatePopulationPayload, CreateAgentPayload, CreateDataItemPayload, UpdateDataItemPayload,
|
|
12
12
|
InitialDataItemPayload,
|
|
13
|
-
SurveySessionCreateResponse
|
|
13
|
+
SurveySessionCreateResponse, SurveySessionDetailResponse
|
|
14
14
|
)
|
|
15
15
|
from .resources import Agent, SurveySession
|
|
16
16
|
from .exceptions import (
|
|
@@ -94,13 +94,25 @@ class Simile:
|
|
|
94
94
|
json={"agent_id": str(agent_id)},
|
|
95
95
|
response_model=SurveySessionCreateResponse
|
|
96
96
|
)
|
|
97
|
+
|
|
98
|
+
# Create and return a SurveySession object
|
|
97
99
|
return SurveySession(
|
|
98
|
-
id=response_data.id,
|
|
99
|
-
agent_id=response_data.agent_id,
|
|
100
|
+
id=response_data.id,
|
|
101
|
+
agent_id=response_data.agent_id,
|
|
100
102
|
status=response_data.status,
|
|
101
103
|
client=self
|
|
102
104
|
)
|
|
103
105
|
|
|
106
|
+
async def get_survey_session(self, session_id: Union[str, uuid.UUID]) -> SurveySessionDetailResponse:
|
|
107
|
+
"""Retrieves detailed information about a survey session including typed conversation history."""
|
|
108
|
+
endpoint = f"sessions/{str(session_id)}"
|
|
109
|
+
response_data = await self._request(
|
|
110
|
+
"GET",
|
|
111
|
+
endpoint,
|
|
112
|
+
response_model=SurveySessionDetailResponse
|
|
113
|
+
)
|
|
114
|
+
return response_data
|
|
115
|
+
|
|
104
116
|
async def create_population(self, name: str, description: Optional[str] = None) -> Population:
|
|
105
117
|
"""Creates a new population."""
|
|
106
118
|
payload = CreatePopulationPayload(name=name, description=description)
|
simile/models.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
from typing import List, Dict, Any, Optional
|
|
2
|
-
from pydantic import BaseModel, Field
|
|
1
|
+
from typing import List, Dict, Any, Optional, Union, Literal
|
|
2
|
+
from pydantic import BaseModel, Field, validator
|
|
3
3
|
from datetime import datetime
|
|
4
|
+
from enum import Enum
|
|
4
5
|
import uuid
|
|
5
6
|
|
|
6
7
|
|
|
@@ -61,7 +62,8 @@ class DeletionResponse(BaseModel):
|
|
|
61
62
|
# --- Generation Operation Models ---
|
|
62
63
|
class QualGenerationRequest(BaseModel):
|
|
63
64
|
question: str
|
|
64
|
-
image_url: Optional[str] = None
|
|
65
|
+
image_url: Optional[str] = None # For backward compatibility
|
|
66
|
+
images: Optional[Dict[str, str]] = None # Dict of {description: url} for multiple images
|
|
65
67
|
|
|
66
68
|
class QualGenerationResponse(BaseModel):
|
|
67
69
|
question: str
|
|
@@ -86,13 +88,71 @@ class AddContextResponse(BaseModel):
|
|
|
86
88
|
|
|
87
89
|
|
|
88
90
|
# --- Survey Session Models ---
|
|
89
|
-
class
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
class TurnType(str, Enum):
|
|
92
|
+
"""Enum for different types of conversation turns."""
|
|
93
|
+
CONTEXT = "context"
|
|
94
|
+
IMAGE = "image"
|
|
95
|
+
QUALITATIVE_QUESTION = "qualitative_question"
|
|
96
|
+
MULTIPLE_CHOICE_QUESTION = "multiple_choice_question"
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class BaseTurn(BaseModel):
|
|
100
|
+
"""Base model for all conversation turns."""
|
|
101
|
+
timestamp: datetime = Field(default_factory=lambda: datetime.now())
|
|
102
|
+
type: TurnType
|
|
103
|
+
|
|
104
|
+
class Config:
|
|
105
|
+
use_enum_values = True
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class ContextTurn(BaseTurn):
|
|
109
|
+
"""A context turn that provides background information."""
|
|
110
|
+
type: Literal[TurnType.CONTEXT] = TurnType.CONTEXT
|
|
111
|
+
user_context: str
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class ImageTurn(BaseTurn):
|
|
115
|
+
"""A standalone image turn (e.g., for context or reference)."""
|
|
116
|
+
type: Literal[TurnType.IMAGE] = TurnType.IMAGE
|
|
117
|
+
image_url: str
|
|
118
|
+
caption: Optional[str] = None
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class QualitativeQuestionTurn(BaseTurn):
|
|
122
|
+
"""A qualitative question-answer turn."""
|
|
123
|
+
type: Literal[TurnType.QUALITATIVE_QUESTION] = TurnType.QUALITATIVE_QUESTION
|
|
124
|
+
user_question: str
|
|
125
|
+
user_image_url: Optional[str] = None # For backward compatibility
|
|
126
|
+
user_images: Optional[Dict[str, str]] = None # Dict of {description: url} for multiple images
|
|
127
|
+
llm_response: Optional[str] = None
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class MultipleChoiceQuestionTurn(BaseTurn):
|
|
131
|
+
"""A multiple choice question-answer turn."""
|
|
132
|
+
type: Literal[TurnType.MULTIPLE_CHOICE_QUESTION] = TurnType.MULTIPLE_CHOICE_QUESTION
|
|
133
|
+
user_question: str
|
|
134
|
+
user_options: List[str]
|
|
135
|
+
user_image_url: Optional[str] = None
|
|
136
|
+
llm_chosen_option: Optional[str] = None
|
|
137
|
+
|
|
138
|
+
@validator('user_options')
|
|
139
|
+
def validate_options(cls, v):
|
|
140
|
+
if not v:
|
|
141
|
+
raise ValueError("Multiple choice questions must have at least one option")
|
|
142
|
+
if len(v) < 2:
|
|
143
|
+
raise ValueError("Multiple choice questions should have at least two options")
|
|
144
|
+
return v
|
|
145
|
+
|
|
146
|
+
@validator('llm_chosen_option')
|
|
147
|
+
def validate_chosen_option(cls, v, values):
|
|
148
|
+
if v is not None and 'user_options' in values and v not in values['user_options']:
|
|
149
|
+
raise ValueError(f"Chosen option '{v}' must be one of the provided options")
|
|
150
|
+
return v
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
# Union type for all possible turn types
|
|
154
|
+
SurveySessionTurn = Union[ContextTurn, ImageTurn, QualitativeQuestionTurn, MultipleChoiceQuestionTurn]
|
|
155
|
+
|
|
96
156
|
|
|
97
157
|
class SurveySessionCreateResponse(BaseModel):
|
|
98
158
|
id: uuid.UUID # Session ID
|
|
@@ -100,6 +160,37 @@ class SurveySessionCreateResponse(BaseModel):
|
|
|
100
160
|
created_at: datetime
|
|
101
161
|
status: str
|
|
102
162
|
|
|
163
|
+
|
|
164
|
+
class SurveySessionDetailResponse(BaseModel):
|
|
165
|
+
"""Detailed survey session response with typed conversation turns."""
|
|
166
|
+
id: uuid.UUID
|
|
167
|
+
agent_id: uuid.UUID
|
|
168
|
+
created_at: datetime
|
|
169
|
+
updated_at: datetime
|
|
170
|
+
status: str
|
|
171
|
+
conversation_history: List[SurveySessionTurn] = Field(default_factory=list)
|
|
172
|
+
|
|
173
|
+
class Config:
|
|
174
|
+
json_encoders = {
|
|
175
|
+
datetime: lambda v: v.isoformat()
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class SurveySessionListItemResponse(BaseModel):
|
|
180
|
+
"""Summary response for listing survey sessions."""
|
|
181
|
+
id: uuid.UUID
|
|
182
|
+
agent_id: uuid.UUID
|
|
183
|
+
created_at: datetime
|
|
184
|
+
updated_at: datetime
|
|
185
|
+
status: str
|
|
186
|
+
turn_count: int = Field(description="Number of turns in conversation history")
|
|
187
|
+
|
|
188
|
+
class Config:
|
|
189
|
+
json_encoders = {
|
|
190
|
+
datetime: lambda v: v.isoformat()
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
|
|
103
194
|
class SurveySessionCloseResponse(BaseModel):
|
|
104
195
|
id: uuid.UUID # Session ID
|
|
105
196
|
status: str
|
simile/resources.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import uuid
|
|
2
|
-
from typing import TYPE_CHECKING, List, Optional
|
|
2
|
+
from typing import TYPE_CHECKING, List, Optional, Dict
|
|
3
3
|
|
|
4
4
|
from .models import (
|
|
5
5
|
QualGenerationRequest,
|
|
@@ -8,15 +8,18 @@ from .models import (
|
|
|
8
8
|
MCGenerationResponse,
|
|
9
9
|
SurveySessionCloseResponse,
|
|
10
10
|
AddContextRequest,
|
|
11
|
-
AddContextResponse
|
|
11
|
+
AddContextResponse,
|
|
12
|
+
SurveySessionDetailResponse,
|
|
12
13
|
)
|
|
13
14
|
|
|
14
15
|
if TYPE_CHECKING:
|
|
15
16
|
from .client import Simile
|
|
16
17
|
|
|
18
|
+
|
|
17
19
|
class Agent:
|
|
18
20
|
"""Represents an agent and provides methods for interacting with it directly."""
|
|
19
|
-
|
|
21
|
+
|
|
22
|
+
def __init__(self, agent_id: uuid.UUID, client: "Simile"):
|
|
20
23
|
self._agent_id = agent_id
|
|
21
24
|
self._client = client
|
|
22
25
|
|
|
@@ -24,18 +27,32 @@ class Agent:
|
|
|
24
27
|
def id(self) -> uuid.UUID:
|
|
25
28
|
return self._agent_id
|
|
26
29
|
|
|
27
|
-
async def generate_qual_response(
|
|
30
|
+
async def generate_qual_response(
|
|
31
|
+
self, question: str, image_url: Optional[str] = None
|
|
32
|
+
) -> QualGenerationResponse:
|
|
28
33
|
"""Generates a qualitative response from this agent based on a question."""
|
|
29
|
-
return await self._client.generate_qual_response(
|
|
34
|
+
return await self._client.generate_qual_response(
|
|
35
|
+
agent_id=self._agent_id, question=question, image_url=image_url
|
|
36
|
+
)
|
|
30
37
|
|
|
31
|
-
async def generate_mc_response(
|
|
38
|
+
async def generate_mc_response(
|
|
39
|
+
self, question: str, options: List[str], image_url: Optional[str] = None
|
|
40
|
+
) -> MCGenerationResponse:
|
|
32
41
|
"""Generates a multiple-choice response from this agent."""
|
|
33
|
-
return await self._client.generate_mc_response(
|
|
42
|
+
return await self._client.generate_mc_response(
|
|
43
|
+
agent_id=self._agent_id,
|
|
44
|
+
question=question,
|
|
45
|
+
options=options,
|
|
46
|
+
image_url=image_url,
|
|
47
|
+
)
|
|
34
48
|
|
|
35
49
|
|
|
36
50
|
class SurveySession:
|
|
37
51
|
"""Represents an active survey session with an agent, allowing for contextual multi-turn generation."""
|
|
38
|
-
|
|
52
|
+
|
|
53
|
+
def __init__(
|
|
54
|
+
self, id: uuid.UUID, agent_id: uuid.UUID, status: str, client: "Simile"
|
|
55
|
+
):
|
|
39
56
|
self._id = id
|
|
40
57
|
self._agent_id = agent_id
|
|
41
58
|
self._status = status
|
|
@@ -53,26 +70,41 @@ class SurveySession:
|
|
|
53
70
|
def status(self) -> str:
|
|
54
71
|
return self._status
|
|
55
72
|
|
|
56
|
-
async def
|
|
73
|
+
async def get_details(self) -> SurveySessionDetailResponse:
|
|
74
|
+
"""Retrieves detailed information about this survey session including typed conversation history."""
|
|
75
|
+
return await self._client.get_survey_session(self._id)
|
|
76
|
+
|
|
77
|
+
async def generate_qual_response(
|
|
78
|
+
self,
|
|
79
|
+
question: str,
|
|
80
|
+
image_url: Optional[str] = None,
|
|
81
|
+
images: Optional[Dict[str, str]] = None,
|
|
82
|
+
) -> QualGenerationResponse:
|
|
57
83
|
"""Generates a qualitative response within this survey session."""
|
|
58
84
|
endpoint = f"sessions/{str(self._id)}/qual"
|
|
59
|
-
payload = QualGenerationRequest(
|
|
85
|
+
payload = QualGenerationRequest(
|
|
86
|
+
question=question, image_url=image_url, images=images
|
|
87
|
+
)
|
|
60
88
|
return await self._client._request(
|
|
61
89
|
"POST",
|
|
62
90
|
endpoint,
|
|
63
|
-
json=payload.model_dump(),
|
|
64
|
-
response_model=QualGenerationResponse
|
|
91
|
+
json=payload.model_dump(),
|
|
92
|
+
response_model=QualGenerationResponse,
|
|
65
93
|
)
|
|
66
94
|
|
|
67
|
-
async def generate_mc_response(
|
|
95
|
+
async def generate_mc_response(
|
|
96
|
+
self, question: str, options: List[str], image_url: Optional[str] = None
|
|
97
|
+
) -> MCGenerationResponse:
|
|
68
98
|
"""Generates a multiple-choice response within this survey session."""
|
|
69
99
|
endpoint = f"sessions/{str(self._id)}/mc"
|
|
70
|
-
payload = MCGenerationRequest(
|
|
100
|
+
payload = MCGenerationRequest(
|
|
101
|
+
question=question, options=options, image_url=image_url
|
|
102
|
+
)
|
|
71
103
|
return await self._client._request(
|
|
72
104
|
"POST",
|
|
73
105
|
endpoint,
|
|
74
|
-
json=payload.model_dump(),
|
|
75
|
-
response_model=MCGenerationResponse
|
|
106
|
+
json=payload.model_dump(),
|
|
107
|
+
response_model=MCGenerationResponse,
|
|
76
108
|
)
|
|
77
109
|
|
|
78
110
|
async def add_context(self, ctx: str) -> AddContextResponse:
|
|
@@ -83,14 +115,12 @@ class SurveySession:
|
|
|
83
115
|
"POST",
|
|
84
116
|
endpoint,
|
|
85
117
|
json=payload.model_dump(),
|
|
86
|
-
response_model=AddContextResponse
|
|
118
|
+
response_model=AddContextResponse,
|
|
87
119
|
)
|
|
88
120
|
|
|
89
121
|
async def close(self) -> SurveySessionCloseResponse:
|
|
90
122
|
"""Closes this survey session on the server."""
|
|
91
123
|
endpoint = f"sessions/{str(self._id)}/close"
|
|
92
124
|
return await self._client._request(
|
|
93
|
-
"POST",
|
|
94
|
-
endpoint,
|
|
95
|
-
response_model=SurveySessionCloseResponse
|
|
125
|
+
"POST", endpoint, response_model=SurveySessionCloseResponse
|
|
96
126
|
)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
simile/__init__.py,sha256=2OZ1LQIkAEtSs0EI5Fzlg7QGKduCgCe_nTh9FfIuHlQ,865
|
|
2
|
+
simile/client.py,sha256=Bw9KML7S-V8gB8-ctitDvgesAkgI5w6cqasRL8Z_070,10394
|
|
3
|
+
simile/exceptions.py,sha256=-rJ3KZcpvNRi9JXbDpxWDSL2lU1mEJX2piwYRZvhKmg,1406
|
|
4
|
+
simile/models.py,sha256=gM6QqVySJe6sG-X7deDcpQYo0JMhfxtfZtBHFP-ZqSI,5376
|
|
5
|
+
simile/resources.py,sha256=4SgiA24lYPCZi_DlJZzX-nUbE8rPMoDSPR65VT0YoW0,4181
|
|
6
|
+
simile-0.2.7.dist-info/licenses/LICENSE,sha256=tpxX3bpODfyOQVyEM6kCMvPHFCpkjFDj0AICRqKqOFA,1066
|
|
7
|
+
simile-0.2.7.dist-info/METADATA,sha256=Upzlhf06MRQThgSVZnzls4liEPX4dJrHvYILAJ-uKf0,1276
|
|
8
|
+
simile-0.2.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
9
|
+
simile-0.2.7.dist-info/top_level.txt,sha256=41lJneubAG4-ZOAs5qn7iDtDb-MDxa6DdvgBKwNX84M,7
|
|
10
|
+
simile-0.2.7.dist-info/RECORD,,
|
simile-0.2.6.dist-info/RECORD
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
simile/__init__.py,sha256=2OZ1LQIkAEtSs0EI5Fzlg7QGKduCgCe_nTh9FfIuHlQ,865
|
|
2
|
-
simile/client.py,sha256=_XsrdDHO25Fsnap6uhUlbMrKO8vMJGJaDCeym8xBs8o,9866
|
|
3
|
-
simile/exceptions.py,sha256=-rJ3KZcpvNRi9JXbDpxWDSL2lU1mEJX2piwYRZvhKmg,1406
|
|
4
|
-
simile/models.py,sha256=dBqH3mVcjvNpOTPV5CBwXjkqZrgmgvZYU1r5ZUqI878,2311
|
|
5
|
-
simile/resources.py,sha256=AeT8547YChPGGSIkhZ2bfN73BhDh1c3OEopJqGIlGE8,3650
|
|
6
|
-
simile-0.2.6.dist-info/licenses/LICENSE,sha256=tpxX3bpODfyOQVyEM6kCMvPHFCpkjFDj0AICRqKqOFA,1066
|
|
7
|
-
simile-0.2.6.dist-info/METADATA,sha256=Ny1lEKybPGZ_CC9q3ibcAfU4AtG2SKVg_jol8QDsbYE,1276
|
|
8
|
-
simile-0.2.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
9
|
-
simile-0.2.6.dist-info/top_level.txt,sha256=41lJneubAG4-ZOAs5qn7iDtDb-MDxa6DdvgBKwNX84M,7
|
|
10
|
-
simile-0.2.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|