simile 0.2.5__tar.gz → 0.2.7__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.

Potentially problematic release.


This version of simile might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simile
3
- Version: 0.2.5
3
+ Version: 0.2.7
4
4
  Summary: Package for interfacing with Simile AI agents for simulation
5
5
  Author-email: Simile AI <cqz@simile.ai>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "simile"
7
- version = "0.2.5"
7
+ version = "0.2.7"
8
8
  authors = [
9
9
  { name="Simile AI", email="cqz@simile.ai" },
10
10
  ]
@@ -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)
@@ -0,0 +1,198 @@
1
+ from typing import List, Dict, Any, Optional, Union, Literal
2
+ from pydantic import BaseModel, Field, validator
3
+ from datetime import datetime
4
+ from enum import Enum
5
+ import uuid
6
+
7
+
8
+ class Population(BaseModel):
9
+ population_id: uuid.UUID
10
+ name: str
11
+ description: Optional[str] = None
12
+ created_at: datetime
13
+ updated_at: datetime
14
+
15
+
16
+ class DataItem(BaseModel):
17
+ id: uuid.UUID
18
+ agent_id: uuid.UUID
19
+ data_type: str
20
+ content: Any
21
+ created_at: datetime
22
+ updated_at: datetime
23
+
24
+
25
+ class Agent(BaseModel):
26
+ agent_id: uuid.UUID
27
+ name: str
28
+ population_id: Optional[uuid.UUID] = None
29
+ created_at: datetime
30
+ updated_at: datetime
31
+ data_items: List[DataItem] = Field(default_factory=list)
32
+
33
+ class CreatePopulationPayload(BaseModel):
34
+ name: str
35
+ description: Optional[str] = None
36
+
37
+
38
+ class InitialDataItemPayload(BaseModel):
39
+ data_type: str
40
+ content: Any
41
+
42
+
43
+ class CreateAgentPayload(BaseModel):
44
+ name: str
45
+ population_id: Optional[uuid.UUID] = None
46
+ agent_data: Optional[List[InitialDataItemPayload]] = None
47
+
48
+
49
+ class CreateDataItemPayload(BaseModel):
50
+ data_type: str
51
+ content: Any
52
+
53
+
54
+ class UpdateDataItemPayload(BaseModel):
55
+ content: Any
56
+
57
+
58
+ class DeletionResponse(BaseModel):
59
+ message: str
60
+
61
+
62
+ # --- Generation Operation Models ---
63
+ class QualGenerationRequest(BaseModel):
64
+ question: str
65
+ image_url: Optional[str] = None # For backward compatibility
66
+ images: Optional[Dict[str, str]] = None # Dict of {description: url} for multiple images
67
+
68
+ class QualGenerationResponse(BaseModel):
69
+ question: str
70
+ answer: str
71
+
72
+ class MCGenerationRequest(BaseModel):
73
+ question: str
74
+ options: List[str]
75
+ image_url: Optional[str] = None
76
+
77
+ class MCGenerationResponse(BaseModel):
78
+ question: str
79
+ options: List[str]
80
+ chosen_option: str
81
+
82
+ class AddContextRequest(BaseModel):
83
+ context: str
84
+
85
+ class AddContextResponse(BaseModel):
86
+ message: str
87
+ session_id: uuid.UUID
88
+
89
+
90
+ # --- Survey Session Models ---
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
+
156
+
157
+ class SurveySessionCreateResponse(BaseModel):
158
+ id: uuid.UUID # Session ID
159
+ agent_id: uuid.UUID
160
+ created_at: datetime
161
+ status: str
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
+
194
+ class SurveySessionCloseResponse(BaseModel):
195
+ id: uuid.UUID # Session ID
196
+ status: str
197
+ updated_at: datetime
198
+ message: Optional[str] = None
@@ -0,0 +1,126 @@
1
+ import uuid
2
+ from typing import TYPE_CHECKING, List, Optional, Dict
3
+
4
+ from .models import (
5
+ QualGenerationRequest,
6
+ QualGenerationResponse,
7
+ MCGenerationRequest,
8
+ MCGenerationResponse,
9
+ SurveySessionCloseResponse,
10
+ AddContextRequest,
11
+ AddContextResponse,
12
+ SurveySessionDetailResponse,
13
+ )
14
+
15
+ if TYPE_CHECKING:
16
+ from .client import Simile
17
+
18
+
19
+ class Agent:
20
+ """Represents an agent and provides methods for interacting with it directly."""
21
+
22
+ def __init__(self, agent_id: uuid.UUID, client: "Simile"):
23
+ self._agent_id = agent_id
24
+ self._client = client
25
+
26
+ @property
27
+ def id(self) -> uuid.UUID:
28
+ return self._agent_id
29
+
30
+ async def generate_qual_response(
31
+ self, question: str, image_url: Optional[str] = None
32
+ ) -> QualGenerationResponse:
33
+ """Generates a qualitative response from this agent based on a question."""
34
+ return await self._client.generate_qual_response(
35
+ agent_id=self._agent_id, question=question, image_url=image_url
36
+ )
37
+
38
+ async def generate_mc_response(
39
+ self, question: str, options: List[str], image_url: Optional[str] = None
40
+ ) -> MCGenerationResponse:
41
+ """Generates a multiple-choice response from this agent."""
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
+ )
48
+
49
+
50
+ class SurveySession:
51
+ """Represents an active survey session with an agent, allowing for contextual multi-turn generation."""
52
+
53
+ def __init__(
54
+ self, id: uuid.UUID, agent_id: uuid.UUID, status: str, client: "Simile"
55
+ ):
56
+ self._id = id
57
+ self._agent_id = agent_id
58
+ self._status = status
59
+ self._client = client
60
+
61
+ @property
62
+ def id(self) -> uuid.UUID:
63
+ return self._id
64
+
65
+ @property
66
+ def agent_id(self) -> uuid.UUID:
67
+ return self._agent_id
68
+
69
+ @property
70
+ def status(self) -> str:
71
+ return self._status
72
+
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:
83
+ """Generates a qualitative response within this survey session."""
84
+ endpoint = f"sessions/{str(self._id)}/qual"
85
+ payload = QualGenerationRequest(
86
+ question=question, image_url=image_url, images=images
87
+ )
88
+ return await self._client._request(
89
+ "POST",
90
+ endpoint,
91
+ json=payload.model_dump(),
92
+ response_model=QualGenerationResponse,
93
+ )
94
+
95
+ async def generate_mc_response(
96
+ self, question: str, options: List[str], image_url: Optional[str] = None
97
+ ) -> MCGenerationResponse:
98
+ """Generates a multiple-choice response within this survey session."""
99
+ endpoint = f"sessions/{str(self._id)}/mc"
100
+ payload = MCGenerationRequest(
101
+ question=question, options=options, image_url=image_url
102
+ )
103
+ return await self._client._request(
104
+ "POST",
105
+ endpoint,
106
+ json=payload.model_dump(),
107
+ response_model=MCGenerationResponse,
108
+ )
109
+
110
+ async def add_context(self, ctx: str) -> AddContextResponse:
111
+ """Adds text to the SurveySession without requesting a response."""
112
+ endpoint = f"sessions/{str(self._id)}/context"
113
+ payload = AddContextRequest(context=ctx)
114
+ return await self._client._request(
115
+ "POST",
116
+ endpoint,
117
+ json=payload.model_dump(),
118
+ response_model=AddContextResponse,
119
+ )
120
+
121
+ async def close(self) -> SurveySessionCloseResponse:
122
+ """Closes this survey session on the server."""
123
+ endpoint = f"sessions/{str(self._id)}/close"
124
+ return await self._client._request(
125
+ "POST", endpoint, response_model=SurveySessionCloseResponse
126
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simile
3
- Version: 0.2.5
3
+ Version: 0.2.7
4
4
  Summary: Package for interfacing with Simile AI agents for simulation
5
5
  Author-email: Simile AI <cqz@simile.ai>
6
6
  License: MIT
@@ -1,100 +0,0 @@
1
- from typing import List, Dict, Any, Optional
2
- from pydantic import BaseModel, Field
3
- from datetime import datetime
4
- import uuid
5
-
6
-
7
- class Population(BaseModel):
8
- population_id: uuid.UUID
9
- name: str
10
- description: Optional[str] = None
11
- created_at: datetime
12
- updated_at: datetime
13
-
14
-
15
- class DataItem(BaseModel):
16
- id: uuid.UUID
17
- agent_id: uuid.UUID
18
- data_type: str
19
- content: Any
20
- created_at: datetime
21
- updated_at: datetime
22
-
23
-
24
- class Agent(BaseModel):
25
- agent_id: uuid.UUID
26
- name: str
27
- population_id: Optional[uuid.UUID] = None
28
- created_at: datetime
29
- updated_at: datetime
30
- data_items: List[DataItem] = Field(default_factory=list)
31
-
32
- class CreatePopulationPayload(BaseModel):
33
- name: str
34
- description: Optional[str] = None
35
-
36
-
37
- class InitialDataItemPayload(BaseModel):
38
- data_type: str
39
- content: Any
40
-
41
-
42
- class CreateAgentPayload(BaseModel):
43
- name: str
44
- population_id: Optional[uuid.UUID] = None
45
- agent_data: Optional[List[InitialDataItemPayload]] = None
46
-
47
-
48
- class CreateDataItemPayload(BaseModel):
49
- data_type: str
50
- content: Any
51
-
52
-
53
- class UpdateDataItemPayload(BaseModel):
54
- content: Any
55
-
56
-
57
- class DeletionResponse(BaseModel):
58
- message: str
59
-
60
-
61
- # --- Generation Operation Models ---
62
- class QualGenerationRequest(BaseModel):
63
- question: str
64
- image_url: Optional[str] = None
65
-
66
- class QualGenerationResponse(BaseModel):
67
- question: str
68
- answer: str
69
-
70
- class MCGenerationRequest(BaseModel):
71
- question: str
72
- options: List[str]
73
- image_url: Optional[str] = None
74
-
75
- class MCGenerationResponse(BaseModel):
76
- question: str
77
- options: List[str]
78
- chosen_option: str
79
-
80
-
81
- # --- Survey Session Models ---
82
- class ConversationTurn(BaseModel):
83
- type: str # "qual" or "mc"
84
- question: str
85
- options: Optional[List[str]] = None
86
- answer: Optional[str] = None
87
- chosen_option: Optional[str] = None
88
- timestamp: datetime
89
-
90
- class SurveySessionCreateResponse(BaseModel):
91
- id: uuid.UUID # Session ID
92
- agent_id: uuid.UUID
93
- created_at: datetime
94
- status: str
95
-
96
- class SurveySessionCloseResponse(BaseModel):
97
- id: uuid.UUID # Session ID
98
- status: str
99
- updated_at: datetime
100
- message: Optional[str] = None
@@ -1,83 +0,0 @@
1
- import uuid
2
- from typing import TYPE_CHECKING, List, Optional
3
-
4
- from .models import (
5
- QualGenerationRequest,
6
- QualGenerationResponse,
7
- MCGenerationRequest,
8
- MCGenerationResponse,
9
- SurveySessionCloseResponse
10
- )
11
-
12
- if TYPE_CHECKING:
13
- from .client import Simile
14
-
15
- class Agent:
16
- """Represents an agent and provides methods for interacting with it directly."""
17
- def __init__(self, agent_id: uuid.UUID, client: 'Simile'):
18
- self._agent_id = agent_id
19
- self._client = client
20
-
21
- @property
22
- def id(self) -> uuid.UUID:
23
- return self._agent_id
24
-
25
- async def generate_qual_response(self, question: str, image_url: Optional[str] = None) -> QualGenerationResponse:
26
- """Generates a qualitative response from this agent based on a question."""
27
- return await self._client.generate_qual_response(agent_id=self._agent_id, question=question, image_url=image_url)
28
-
29
- async def generate_mc_response(self, question: str, options: List[str], image_url: Optional[str] = None) -> MCGenerationResponse:
30
- """Generates a multiple-choice response from this agent."""
31
- return await self._client.generate_mc_response(agent_id=self._agent_id, question=question, options=options, image_url=image_url)
32
-
33
-
34
- class SurveySession:
35
- """Represents an active survey session with an agent, allowing for contextual multi-turn generation."""
36
- def __init__(self, id: uuid.UUID, agent_id: uuid.UUID, status: str, client: 'Simile'):
37
- self._id = id
38
- self._agent_id = agent_id
39
- self._status = status
40
- self._client = client
41
-
42
- @property
43
- def id(self) -> uuid.UUID:
44
- return self._id
45
-
46
- @property
47
- def agent_id(self) -> uuid.UUID:
48
- return self._agent_id
49
-
50
- @property
51
- def status(self) -> str:
52
- return self._status
53
-
54
- async def generate_qual_response(self, question: str, image_url: Optional[str] = None) -> QualGenerationResponse:
55
- """Generates a qualitative response within this survey session."""
56
- endpoint = f"sessions/{str(self._id)}/qual"
57
- payload = QualGenerationRequest(question=question, image_url=image_url)
58
- return await self._client._request(
59
- "POST",
60
- endpoint,
61
- json=payload.model_dump(),
62
- response_model=QualGenerationResponse
63
- )
64
-
65
- async def generate_mc_response(self, question: str, options: List[str], image_url: Optional[str] = None) -> MCGenerationResponse:
66
- """Generates a multiple-choice response within this survey session."""
67
- endpoint = f"sessions/{str(self._id)}/mc"
68
- payload = MCGenerationRequest(question=question, options=options, image_url=image_url)
69
- return await self._client._request(
70
- "POST",
71
- endpoint,
72
- json=payload.model_dump(),
73
- response_model=MCGenerationResponse
74
- )
75
-
76
- async def close(self) -> SurveySessionCloseResponse:
77
- """Closes this survey session on the server."""
78
- endpoint = f"sessions/{str(self._id)}/close"
79
- return await self._client._request(
80
- "POST",
81
- endpoint,
82
- response_model=SurveySessionCloseResponse
83
- )
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes