simile 0.2.0__py3-none-any.whl → 0.2.2__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 CHANGED
@@ -5,10 +5,14 @@ import uuid
5
5
  from pydantic import BaseModel
6
6
 
7
7
  from .models import (
8
- Population, Agent, DataItem,
8
+ Population, Agent as AgentModel, DataItem, DeletionResponse,
9
+ QualGenerationRequest, QualGenerationResponse,
10
+ MCGenerationRequest, MCGenerationResponse,
9
11
  CreatePopulationPayload, CreateAgentPayload, CreateDataItemPayload, UpdateDataItemPayload,
10
- DeletionResponse, QualGenerationRequest, QualGenerationResponse, MCGenerationRequest, MCGenerationResponse
12
+ InitialDataItemPayload,
13
+ SurveySessionCreateResponse
11
14
  )
15
+ from .resources import Agent, SurveySession
12
16
  from .exceptions import (
13
17
  SimileAPIError, SimileAuthenticationError, SimileNotFoundError, SimileBadRequestError
14
18
  )
@@ -17,6 +21,11 @@ DEFAULT_BASE_URL = "https://simile-api-3a83be7adae0.herokuapp.com/api/v1"
17
21
  TIMEOUT_CONFIG = httpx.Timeout(5.0, read=30.0, write=30.0, pool=30.0)
18
22
 
19
23
  class Simile:
24
+ APIError = SimileAPIError
25
+ AuthenticationError = SimileAuthenticationError
26
+ NotFoundError = SimileNotFoundError
27
+ BadRequestError = SimileBadRequestError
28
+
20
29
  def __init__(self, api_key: str, base_url: str = DEFAULT_BASE_URL):
21
30
  if not api_key:
22
31
  raise ValueError("API key is required.")
@@ -58,8 +67,29 @@ class Simile:
58
67
  except httpx.RequestError as e:
59
68
  raise SimileAPIError(f"Request error: {e}")
60
69
 
61
- # --- Population Endpoints ---
62
- async def create_population(self, payload: CreatePopulationPayload) -> Population:
70
+ def agent(self, agent_id: uuid.UUID) -> Agent:
71
+ """Returns an Agent object to interact with a specific agent."""
72
+ return Agent(agent_id=agent_id, client=self)
73
+
74
+ async def create_survey_session(self, agent_id: uuid.UUID) -> SurveySession:
75
+ """Creates a new survey session for the given agent and returns a SurveySession object."""
76
+ endpoint = "sessions/"
77
+ response_data = await self._request(
78
+ "POST",
79
+ endpoint,
80
+ json={"agent_id": str(agent_id)},
81
+ response_model=SurveySessionCreateResponse
82
+ )
83
+ return SurveySession(
84
+ id=response_data.id,
85
+ agent_id=response_data.agent_id,
86
+ status=response_data.status,
87
+ client=self
88
+ )
89
+
90
+ async def create_population(self, name: str, description: Optional[str] = None) -> Population:
91
+ """Creates a new population."""
92
+ payload = CreatePopulationPayload(name=name, description=description)
63
93
  response_data = await self._request("POST", "populations/create", json=payload.model_dump(mode='json', exclude_none=True), response_model=Population)
64
94
  return response_data
65
95
 
@@ -71,21 +101,27 @@ class Simile:
71
101
  response_data = await self._request("DELETE", f"populations/delete/{str(population_id)}", response_model=DeletionResponse)
72
102
  return response_data
73
103
 
74
- # --- Agent Endpoints ---
75
- async def create_agent(self, payload: CreateAgentPayload) -> Agent:
76
- response_data = await self._request("POST", "agents/create", json=payload.model_dump(mode='json', exclude_none=True), response_model=Agent)
104
+ async def create_agent(self, name: str, population_id: Optional[Union[str, uuid.UUID]] = None, agent_data: Optional[List[Dict[str, Any]]] = None) -> AgentModel:
105
+ """Creates a new agent, optionally within a population and with initial data items."""
106
+ pop_id_uuid: Optional[uuid.UUID] = None
107
+ if population_id:
108
+ pop_id_uuid = uuid.UUID(str(population_id)) if not isinstance(population_id, uuid.UUID) else population_id
109
+
110
+ payload = CreateAgentPayload(name=name, population_id=pop_id_uuid, agent_data=agent_data)
111
+ response_data = await self._request("POST", "agents/create", json=payload.model_dump(mode='json', exclude_none=True), response_model=AgentModel)
77
112
  return response_data
78
113
 
79
- async def get_agent(self, agent_id: Union[str, uuid.UUID]) -> Agent:
80
- response_data = await self._request("GET", f"agents/get/{str(agent_id)}", response_model=Agent)
114
+ async def get_agent(self, agent_id: Union[str, uuid.UUID]) -> AgentModel:
115
+ response_data = await self._request("GET", f"agents/get/{str(agent_id)}", response_model=AgentModel)
81
116
  return response_data
82
117
 
83
118
  async def delete_agent(self, agent_id: Union[str, uuid.UUID]) -> DeletionResponse:
84
119
  response_data = await self._request("DELETE", f"agents/delete/{str(agent_id)}", response_model=DeletionResponse)
85
120
  return response_data
86
121
 
87
- # --- Data Item Endpoints ---
88
- async def create_data_item(self, agent_id: Union[str, uuid.UUID], payload: CreateDataItemPayload) -> DataItem:
122
+ async def create_data_item(self, agent_id: Union[str, uuid.UUID], data_type: str, content: Any) -> DataItem:
123
+ """Creates a new data item for a specific agent."""
124
+ payload = CreateDataItemPayload(data_type=data_type, content=content)
89
125
  response_data = await self._request("POST", f"data_item/create/{str(agent_id)}", json=payload.model_dump(mode='json'), response_model=DataItem)
90
126
  return response_data
91
127
 
@@ -97,20 +133,24 @@ class Simile:
97
133
  params = {}
98
134
  if data_type:
99
135
  params["data_type"] = data_type
100
- raw_response = await self._request("GET", f"data_item/list/{str(agent_id)}", params=params)
136
+ agent_id_str = str(agent_id)
137
+ raw_response = await self._request("GET", f"data_item/list/{agent_id_str}", params=params)
101
138
  return [DataItem(**item) for item in raw_response.json()]
102
139
 
103
- async def update_data_item(self, data_item_id: Union[str, uuid.UUID], payload: UpdateDataItemPayload) -> DataItem:
104
- response_data = await self._request("POST", f"data_item/update/{data_item_id}", json=payload.model_dump(), response_model=DataItem)
140
+ async def update_data_item(self, data_item_id: Union[str, uuid.UUID], content: Any) -> DataItem:
141
+ """Updates an existing data item."""
142
+ payload = UpdateDataItemPayload(content=content)
143
+ response_data = await self._request("POST", f"data_item/update/{str(data_item_id)}", json=payload.model_dump(), response_model=DataItem)
105
144
  return response_data
106
145
 
107
146
  async def delete_data_item(self, data_item_id: Union[str, uuid.UUID]) -> DeletionResponse:
108
147
  response_data = await self._request("DELETE", f"data_item/delete/{str(data_item_id)}", response_model=DeletionResponse)
109
148
  return response_data
110
149
 
111
- # --- LLM Generation Methods ---
112
- async def generate_qual_response(self, agent_id: uuid.UUID, request_payload: QualGenerationRequest) -> QualGenerationResponse:
150
+ async def generate_qual_response(self, agent_id: uuid.UUID, question: str) -> QualGenerationResponse:
151
+ """Generates a qualitative response from an agent based on a question."""
113
152
  endpoint = f"/generation/qual/{str(agent_id)}"
153
+ request_payload = QualGenerationRequest(question=question)
114
154
  response_data = await self._request(
115
155
  "POST",
116
156
  endpoint,
@@ -119,9 +159,16 @@ class Simile:
119
159
  )
120
160
  return response_data
121
161
 
122
- async def generate_mc_response(self, agent_id: uuid.UUID, request_payload: MCGenerationRequest) -> MCGenerationResponse:
123
- endpoint = f"generation/mc/{agent_id}"
124
- response_data = await self._request("POST", endpoint, json=request_payload.model_dump(), response_model=MCGenerationResponse)
162
+ async def generate_mc_response(self, agent_id: uuid.UUID, question: str, options: List[str]) -> MCGenerationResponse:
163
+ """Generates a multiple-choice response from an agent."""
164
+ endpoint = f"generation/mc/{str(agent_id)}"
165
+ request_payload = MCGenerationRequest(question=question, options=options)
166
+ response_data = await self._request(
167
+ "POST",
168
+ endpoint,
169
+ json=request_payload.model_dump(),
170
+ response_model=MCGenerationResponse
171
+ )
125
172
  return response_data
126
173
 
127
174
  async def aclose(self):
simile/models.py CHANGED
@@ -34,10 +34,15 @@ class CreatePopulationPayload(BaseModel):
34
34
  description: Optional[str] = None
35
35
 
36
36
 
37
+ class InitialDataItemPayload(BaseModel):
38
+ data_type: str
39
+ content: Any
40
+
41
+
37
42
  class CreateAgentPayload(BaseModel):
38
43
  name: str
39
44
  population_id: Optional[uuid.UUID] = None
40
- agent_data: Optional[List[Dict[str, Any]]] = None # For initial data items
45
+ agent_data: Optional[List[InitialDataItemPayload]] = None
41
46
 
42
47
 
43
48
  class CreateDataItemPayload(BaseModel):
@@ -53,13 +58,11 @@ class DeletionResponse(BaseModel):
53
58
  message: str
54
59
 
55
60
 
56
- # --- LLM Generation Models ---
57
-
61
+ # --- Generation Operation Models ---
58
62
  class QualGenerationRequest(BaseModel):
59
63
  question: str
60
64
 
61
65
  class QualGenerationResponse(BaseModel):
62
- agent_id: uuid.UUID
63
66
  question: str
64
67
  answer: str
65
68
 
@@ -68,7 +71,28 @@ class MCGenerationRequest(BaseModel):
68
71
  options: List[str]
69
72
 
70
73
  class MCGenerationResponse(BaseModel):
71
- agent_id: uuid.UUID
72
74
  question: str
73
75
  options: List[str]
74
76
  chosen_option: str
77
+
78
+
79
+ # --- Survey Session Models ---
80
+ class ConversationTurn(BaseModel):
81
+ type: str # "qual" or "mc"
82
+ question: str
83
+ options: Optional[List[str]] = None
84
+ answer: Optional[str] = None
85
+ chosen_option: Optional[str] = None
86
+ timestamp: datetime
87
+
88
+ class SurveySessionCreateResponse(BaseModel):
89
+ id: uuid.UUID # Session ID
90
+ agent_id: uuid.UUID
91
+ created_at: datetime
92
+ status: str
93
+
94
+ class SurveySessionCloseResponse(BaseModel):
95
+ id: uuid.UUID # Session ID
96
+ status: str
97
+ updated_at: datetime
98
+ message: Optional[str] = None
simile/resources.py ADDED
@@ -0,0 +1,83 @@
1
+ import uuid
2
+ from typing import TYPE_CHECKING, List
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) -> 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)
28
+
29
+ async def generate_mc_response(self, question: str, options: List[str]) -> 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)
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) -> QualGenerationResponse:
55
+ """Generates a qualitative response within this survey session."""
56
+ endpoint = f"sessions/{str(self._id)}/qual"
57
+ payload = QualGenerationRequest(question=question)
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]) -> 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)
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
+ )
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simile
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Package for interfacing with Simile AI agents for simulation
5
5
  Author-email: Simile AI <cqz@simile.ai>
6
- License: MIT
6
+ License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/simile-team/simile-sdk
8
8
  Keywords: api,sdk,simile,ai-agent,simulation
9
9
  Classifier: Development Status :: 3 - Alpha
@@ -0,0 +1,10 @@
1
+ simile/__init__.py,sha256=2OZ1LQIkAEtSs0EI5Fzlg7QGKduCgCe_nTh9FfIuHlQ,865
2
+ simile/client.py,sha256=rBXGfuD1kMlzHCXaqaPNzuzoqqDe5tTWH28Szg6DMCI,8534
3
+ simile/exceptions.py,sha256=-rJ3KZcpvNRi9JXbDpxWDSL2lU1mEJX2piwYRZvhKmg,1406
4
+ simile/models.py,sha256=bdvKNT10VlZHC51S5U1vpm2i-HV-2hVVeQZFOB-5jmQ,2104
5
+ simile/resources.py,sha256=n6TSuqEplO0Gyim-pqhrrxg8yPqsHWcFflOcZpd-uVo,2950
6
+ simile-0.2.2.dist-info/licenses/LICENSE,sha256=tpxX3bpODfyOQVyEM6kCMvPHFCpkjFDj0AICRqKqOFA,1066
7
+ simile-0.2.2.dist-info/METADATA,sha256=MCSE0Rjd8xR-WdsU3Igz0YLY6Bvh7NM64mC6T9753AA,1256
8
+ simile-0.2.2.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
9
+ simile-0.2.2.dist-info/top_level.txt,sha256=41lJneubAG4-ZOAs5qn7iDtDb-MDxa6DdvgBKwNX84M,7
10
+ simile-0.2.2.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- simile/__init__.py,sha256=2OZ1LQIkAEtSs0EI5Fzlg7QGKduCgCe_nTh9FfIuHlQ,865
2
- simile/client.py,sha256=8FMhdyi35CQPJFh7pMLf6c9pczN7IlcCvnBh8kocOiI,6377
3
- simile/exceptions.py,sha256=-rJ3KZcpvNRi9JXbDpxWDSL2lU1mEJX2piwYRZvhKmg,1406
4
- simile/models.py,sha256=3T1UYCPp3KWMBD-u7lZEMahm4fS4ltm9h0oPUWs_oyI,1530
5
- simile-0.2.0.dist-info/licenses/LICENSE,sha256=tpxX3bpODfyOQVyEM6kCMvPHFCpkjFDj0AICRqKqOFA,1066
6
- simile-0.2.0.dist-info/METADATA,sha256=CTeN0Kl12ehJhMPbvra6o7ruVuojOyfpPB7uvUHuHjw,1245
7
- simile-0.2.0.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
8
- simile-0.2.0.dist-info/top_level.txt,sha256=41lJneubAG4-ZOAs5qn7iDtDb-MDxa6DdvgBKwNX84M,7
9
- simile-0.2.0.dist-info/RECORD,,
File without changes