persona-sdk-python 0.2.16__tar.gz → 0.2.18__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.
Files changed (41) hide show
  1. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/PKG-INFO +39 -24
  2. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/README.md +38 -23
  3. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/persona_sdk/__init__.py +47 -3
  4. persona_sdk_python-0.2.18/persona_sdk/_serde.py +20 -0
  5. persona_sdk_python-0.2.18/persona_sdk/api/agents.py +70 -0
  6. persona_sdk_python-0.2.18/persona_sdk/api/credentials.py +40 -0
  7. persona_sdk_python-0.2.18/persona_sdk/api/features.py +64 -0
  8. persona_sdk_python-0.2.18/persona_sdk/api/knowledge_bases.py +81 -0
  9. persona_sdk_python-0.2.18/persona_sdk/api/known_models.py +49 -0
  10. persona_sdk_python-0.2.18/persona_sdk/api/missions.py +74 -0
  11. persona_sdk_python-0.2.18/persona_sdk/api/projects.py +76 -0
  12. persona_sdk_python-0.2.18/persona_sdk/api/service_prices.py +47 -0
  13. persona_sdk_python-0.2.18/persona_sdk/api/sessions.py +89 -0
  14. persona_sdk_python-0.2.18/persona_sdk/api/triggers.py +61 -0
  15. persona_sdk_python-0.2.18/persona_sdk/api/workflows.py +72 -0
  16. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/persona_sdk/client.py +15 -7
  17. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/persona_sdk/runners/agent_runner.py +4 -3
  18. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/persona_sdk/runners/resource_retriever.py +4 -4
  19. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/persona_sdk/runners/tool_invoker.py +6 -6
  20. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/pyproject.toml +1 -1
  21. persona_sdk_python-0.2.16/persona_sdk/api/agents.py +0 -39
  22. persona_sdk_python-0.2.16/persona_sdk/api/credentials.py +0 -21
  23. persona_sdk_python-0.2.16/persona_sdk/api/features.py +0 -30
  24. persona_sdk_python-0.2.16/persona_sdk/api/knowledge_bases.py +0 -34
  25. persona_sdk_python-0.2.16/persona_sdk/api/known_models.py +0 -24
  26. persona_sdk_python-0.2.16/persona_sdk/api/missions.py +0 -41
  27. persona_sdk_python-0.2.16/persona_sdk/api/projects.py +0 -51
  28. persona_sdk_python-0.2.16/persona_sdk/api/service_prices.py +0 -24
  29. persona_sdk_python-0.2.16/persona_sdk/api/sessions.py +0 -45
  30. persona_sdk_python-0.2.16/persona_sdk/api/triggers.py +0 -34
  31. persona_sdk_python-0.2.16/persona_sdk/api/workflows.py +0 -34
  32. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/.gitignore +0 -0
  33. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/DEPLOY.md +0 -0
  34. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/bitbucket-pipelines.yml +0 -0
  35. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/persona_sdk/api/__init__.py +0 -0
  36. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/persona_sdk/auth/__init__.py +0 -0
  37. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/persona_sdk/auth/api_key_auth.py +0 -0
  38. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/persona_sdk/auth/base.py +0 -0
  39. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/persona_sdk/auth/bearer_token_auth.py +0 -0
  40. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/persona_sdk/runners/__init__.py +0 -0
  41. {persona_sdk_python-0.2.16 → persona_sdk_python-0.2.18}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: persona-sdk-python
3
- Version: 0.2.16
3
+ Version: 0.2.18
4
4
  Summary: Async Python SDK for the Persona AI platform
5
5
  Project-URL: Homepage, https://persona.applica.guru
6
6
  Project-URL: Repository, https://bitbucket.org/applicaguru/persona-sdk-python
@@ -53,9 +53,10 @@ async def main():
53
53
  auth="prs_your_project_api_key",
54
54
  )
55
55
 
56
- # List agents in your project
57
- agents = await sdk.agents.list()
58
- print(agents)
56
+ # List agents in your project -> Paginated[AgentConfiguration]
57
+ page = await sdk.agents.list()
58
+ for agent in page.items:
59
+ print(agent.id, agent.name, agent.model.model_name)
59
60
 
60
61
  await sdk.close()
61
62
 
@@ -150,22 +151,37 @@ finally:
150
151
 
151
152
  ## CRUD example
152
153
 
154
+ Every API method is typed via the pydantic models re-exported from
155
+ `persona-models` (e.g. `AgentConfiguration`, `Project`, `Mission`, ...). Write
156
+ methods accept either a model instance or a plain dict; read methods always
157
+ return the parsed model (or `Paginated[...]` for list endpoints).
158
+
153
159
  ```python
154
- # Create an agent
155
- agent = await sdk.agents.create({
156
- "name": "my-agent",
157
- "model": {"modelName": "gpt-4o"},
158
- })
160
+ from persona_sdk import AgentConfiguration, ModelConfiguration
161
+
162
+ # Create an agent from a typed model
163
+ agent = await sdk.agents.create(
164
+ AgentConfiguration(
165
+ name="my-agent",
166
+ model=ModelConfiguration(model_name="gpt-4o"),
167
+ )
168
+ )
159
169
 
160
- # Read
161
- fetched = await sdk.agents.get(agent["id"])
170
+ # Read -> AgentConfiguration
171
+ fetched = await sdk.agents.get(agent.id)
162
172
 
163
- # Update
164
- fetched["name"] = "renamed-agent"
165
- await sdk.agents.update(agent["id"], fetched)
173
+ # Update (mutate the model and send it back)
174
+ fetched.name = "renamed-agent"
175
+ await sdk.agents.update(agent.id, fetched)
166
176
 
167
177
  # Delete
168
- await sdk.agents.delete(agent["id"])
178
+ await sdk.agents.delete(agent.id)
179
+ ```
180
+
181
+ A plain dict is still accepted for backwards compatibility:
182
+
183
+ ```python
184
+ agent = await sdk.agents.create({"name": "my-agent", "model": {"modelName": "gpt-4o"}})
169
185
  ```
170
186
 
171
187
  ## AI System Instructions Generation
@@ -184,22 +200,21 @@ instructions = await sdk.agents.generate_system_instructions(
184
200
  session_id="my-session-id",
185
201
  )
186
202
 
187
- # Get the project's architect agent configuration
203
+ # Get the project's architect agent configuration -> AgentConfiguration
188
204
  architect = await sdk.agents.get_architect()
189
205
  ```
190
206
 
191
207
  ## Pagination
192
208
 
193
- List endpoints accept `keyword`, `page`, and `size`:
209
+ List endpoints return a `Paginated[<Model>]` with typed `.items`, `.total`,
210
+ `.page` and `.size`:
194
211
 
195
212
  ```python
196
- result = await sdk.agents.list(keyword="bot", page=1, size=20)
197
- # {
198
- # "items": [...],
199
- # "total": 42,
200
- # "page": 1,
201
- # "size": 20
202
- # }
213
+ page = await sdk.agents.list(keyword="bot", page=1, size=20)
214
+ # page.items -> list[AgentConfiguration]
215
+ # page.total -> 42
216
+ # page.page -> 1
217
+ # page.size -> 20
203
218
  ```
204
219
 
205
220
  ## Workflows
@@ -29,9 +29,10 @@ async def main():
29
29
  auth="prs_your_project_api_key",
30
30
  )
31
31
 
32
- # List agents in your project
33
- agents = await sdk.agents.list()
34
- print(agents)
32
+ # List agents in your project -> Paginated[AgentConfiguration]
33
+ page = await sdk.agents.list()
34
+ for agent in page.items:
35
+ print(agent.id, agent.name, agent.model.model_name)
35
36
 
36
37
  await sdk.close()
37
38
 
@@ -126,22 +127,37 @@ finally:
126
127
 
127
128
  ## CRUD example
128
129
 
130
+ Every API method is typed via the pydantic models re-exported from
131
+ `persona-models` (e.g. `AgentConfiguration`, `Project`, `Mission`, ...). Write
132
+ methods accept either a model instance or a plain dict; read methods always
133
+ return the parsed model (or `Paginated[...]` for list endpoints).
134
+
129
135
  ```python
130
- # Create an agent
131
- agent = await sdk.agents.create({
132
- "name": "my-agent",
133
- "model": {"modelName": "gpt-4o"},
134
- })
136
+ from persona_sdk import AgentConfiguration, ModelConfiguration
137
+
138
+ # Create an agent from a typed model
139
+ agent = await sdk.agents.create(
140
+ AgentConfiguration(
141
+ name="my-agent",
142
+ model=ModelConfiguration(model_name="gpt-4o"),
143
+ )
144
+ )
135
145
 
136
- # Read
137
- fetched = await sdk.agents.get(agent["id"])
146
+ # Read -> AgentConfiguration
147
+ fetched = await sdk.agents.get(agent.id)
138
148
 
139
- # Update
140
- fetched["name"] = "renamed-agent"
141
- await sdk.agents.update(agent["id"], fetched)
149
+ # Update (mutate the model and send it back)
150
+ fetched.name = "renamed-agent"
151
+ await sdk.agents.update(agent.id, fetched)
142
152
 
143
153
  # Delete
144
- await sdk.agents.delete(agent["id"])
154
+ await sdk.agents.delete(agent.id)
155
+ ```
156
+
157
+ A plain dict is still accepted for backwards compatibility:
158
+
159
+ ```python
160
+ agent = await sdk.agents.create({"name": "my-agent", "model": {"modelName": "gpt-4o"}})
145
161
  ```
146
162
 
147
163
  ## AI System Instructions Generation
@@ -160,22 +176,21 @@ instructions = await sdk.agents.generate_system_instructions(
160
176
  session_id="my-session-id",
161
177
  )
162
178
 
163
- # Get the project's architect agent configuration
179
+ # Get the project's architect agent configuration -> AgentConfiguration
164
180
  architect = await sdk.agents.get_architect()
165
181
  ```
166
182
 
167
183
  ## Pagination
168
184
 
169
- List endpoints accept `keyword`, `page`, and `size`:
185
+ List endpoints return a `Paginated[<Model>]` with typed `.items`, `.total`,
186
+ `.page` and `.size`:
170
187
 
171
188
  ```python
172
- result = await sdk.agents.list(keyword="bot", page=1, size=20)
173
- # {
174
- # "items": [...],
175
- # "total": 42,
176
- # "page": 1,
177
- # "size": 20
178
- # }
189
+ page = await sdk.agents.list(keyword="bot", page=1, size=20)
190
+ # page.items -> list[AgentConfiguration]
191
+ # page.total -> 42
192
+ # page.page -> 1
193
+ # page.size -> 20
179
194
  ```
180
195
 
181
196
  ## Workflows
@@ -18,6 +18,27 @@ from persona_sdk.auth import (
18
18
  )
19
19
  from persona_sdk.client import PersonaClient
20
20
 
21
+ # Re-export the pydantic models returned/accepted by the typed API so users can
22
+ # build requests and inspect responses without depending on ``persona-models``
23
+ # directly. These are intentionally the same objects used internally.
24
+ from persona_models.common import Paginated
25
+ from persona_models.agents import AgentConfiguration, ModelConfiguration
26
+ from persona_models.credentials import AuthorizeRequest, Credentials
27
+ from persona_models.features import FeatureTemplate
28
+ from persona_models.knowledge_bases import (
29
+ KnowledgeBase,
30
+ KnowledgeBaseDocument,
31
+ SearchChunksRequest,
32
+ )
33
+ from persona_models.known_models import KnownModel
34
+ from persona_models.mcp import GenerationRequest
35
+ from persona_models.missions import CreateMissionRequest, Mission
36
+ from persona_models.projects import Project
37
+ from persona_models.service_prices import ServicePrice, UsageCost
38
+ from persona_models.sessions import GenerationResponse, Message, Session
39
+ from persona_models.triggers import Trigger, TriggerExecutionResult
40
+ from persona_models.workflows import Workflow
41
+
21
42
  __all__ = [
22
43
  "PersonaSdk",
23
44
  "PersonaClient",
@@ -35,6 +56,29 @@ __all__ = [
35
56
  "SessionsApi",
36
57
  "TriggersApi",
37
58
  "WorkflowsApi",
59
+ # Domain models (re-exported from persona-models)
60
+ "Paginated",
61
+ "AgentConfiguration",
62
+ "ModelConfiguration",
63
+ "AuthorizeRequest",
64
+ "Credentials",
65
+ "FeatureTemplate",
66
+ "KnowledgeBase",
67
+ "KnowledgeBaseDocument",
68
+ "SearchChunksRequest",
69
+ "KnownModel",
70
+ "GenerationRequest",
71
+ "GenerationResponse",
72
+ "CreateMissionRequest",
73
+ "Mission",
74
+ "Project",
75
+ "ServicePrice",
76
+ "UsageCost",
77
+ "Message",
78
+ "Session",
79
+ "Trigger",
80
+ "TriggerExecutionResult",
81
+ "Workflow",
38
82
  ]
39
83
 
40
84
 
@@ -71,9 +115,9 @@ class PersonaSdk:
71
115
  self,
72
116
  base_url: str,
73
117
  auth: Union[str, AuthenticationProvider, None] = None,
74
- proxy: str = None,
75
- workflows_url: str = None,
76
- api_key: str = None,
118
+ proxy: str | None = None,
119
+ workflows_url: str | None = None,
120
+ api_key: str | None = None,
77
121
  ):
78
122
  # Backwards compatibility: keep the legacy `api_key` keyword
79
123
  if auth is None:
@@ -0,0 +1,20 @@
1
+ """Internal (de)serialization helpers shared by the typed API classes."""
2
+ from __future__ import annotations
3
+
4
+ from typing import Any
5
+
6
+ from pydantic import BaseModel
7
+
8
+
9
+ def dump_payload(model: BaseModel | dict[str, Any] | None) -> dict[str, Any] | None:
10
+ """Serialize a write payload for an HTTP request.
11
+
12
+ Accepts either a pydantic model instance (serialized to a camelCase dict,
13
+ dropping unset/``None`` fields so server-side defaults are preserved) or a
14
+ plain dict which is returned as-is. ``None`` passes through unchanged.
15
+ """
16
+ if model is None:
17
+ return None
18
+ if isinstance(model, BaseModel):
19
+ return model.model_dump(by_alias=True, exclude_none=True)
20
+ return dict(model)
@@ -0,0 +1,70 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from persona_models.agents import AgentConfiguration
6
+ from persona_models.common import Paginated
7
+
8
+ from persona_sdk._serde import dump_payload
9
+ from persona_sdk.client import PersonaClient
10
+
11
+
12
+ class AgentsApi:
13
+ def __init__(self, client: PersonaClient):
14
+ self._client = client
15
+
16
+ async def list(
17
+ self,
18
+ keyword: str | None = None,
19
+ page: int = 1,
20
+ size: int = 20,
21
+ ) -> Paginated[AgentConfiguration]:
22
+ """List agents in the authenticated project."""
23
+ params: dict[str, Any] = {"page": page, "size": size}
24
+ if keyword:
25
+ params["keyword"] = keyword
26
+ data = await self._client.get("/agents", params=params)
27
+ return Paginated[AgentConfiguration].model_validate(data)
28
+
29
+ async def get(self, agent_id: str) -> AgentConfiguration:
30
+ return AgentConfiguration.model_validate(
31
+ await self._client.get(f"/agents/{agent_id}")
32
+ )
33
+
34
+ async def create(
35
+ self, agent: AgentConfiguration | dict[str, Any]
36
+ ) -> AgentConfiguration:
37
+ data = await self._client.post("/agents", json=dump_payload(agent))
38
+ return AgentConfiguration.model_validate(data)
39
+
40
+ async def update(
41
+ self,
42
+ agent_id: str,
43
+ agent: AgentConfiguration | dict[str, Any],
44
+ ) -> AgentConfiguration:
45
+ data = await self._client.put(f"/agents/{agent_id}", json=dump_payload(agent))
46
+ return AgentConfiguration.model_validate(data)
47
+
48
+ async def delete(self, agent_id: str) -> AgentConfiguration:
49
+ data = await self._client.delete(f"/agents/{agent_id}")
50
+ return AgentConfiguration.model_validate(data)
51
+
52
+ async def get_voices(self, synthesizer_type: str) -> dict[str, Any]:
53
+ """List available voices for a TTS synthesizer type."""
54
+ return await self._client.get(f"/values/synthesizers/{synthesizer_type}/voices")
55
+
56
+ async def generate_system_instructions(
57
+ self, prompt: str, session_id: str | None = None
58
+ ) -> str:
59
+ """Generate system instructions using the project's AI architect agent."""
60
+ body: dict[str, Any] = {"prompt": prompt}
61
+ if session_id:
62
+ body["sessionId"] = session_id
63
+ result = await self._client.post("/agents/system-instructions", json=body)
64
+ return result.get("instructions", "") if isinstance(result, dict) else ""
65
+
66
+ async def get_architect(self) -> AgentConfiguration:
67
+ """Get or create the project's architect agent configuration."""
68
+ return AgentConfiguration.model_validate(
69
+ await self._client.get("/agents/architect")
70
+ )
@@ -0,0 +1,40 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from persona_models.credentials import AuthorizeRequest, Credentials
6
+
7
+ from persona_sdk._serde import dump_payload
8
+ from persona_sdk.client import PersonaClient
9
+
10
+
11
+ class CredentialsApi:
12
+ def __init__(self, client: PersonaClient):
13
+ self._client = client
14
+
15
+ async def list(self) -> list[Credentials]:
16
+ data = await self._client.get("/credentials")
17
+ return [Credentials.model_validate(item) for item in (data or [])]
18
+
19
+ async def list_by_provider(self, provider: str) -> list[Credentials]:
20
+ data = await self._client.get(f"/credentials/{provider}")
21
+ return [Credentials.model_validate(item) for item in (data or [])]
22
+
23
+ async def get(self, credentials_id: str) -> Credentials:
24
+ data = await self._client.get(f"/credentials/all/{credentials_id}")
25
+ return Credentials.model_validate(data)
26
+
27
+ async def authorize(
28
+ self, provider: str, request: AuthorizeRequest | dict[str, Any]
29
+ ) -> dict[str, Any]:
30
+ """Authorize credentials for a provider.
31
+
32
+ Returns the server's ``AuthorizeResponse`` (``credentials``, ``state``,
33
+ ``redirect_url``) as a plain dict.
34
+ """
35
+ return await self._client.post(
36
+ f"/credentials/{provider}/authorize", json=dump_payload(request)
37
+ )
38
+
39
+ async def delete(self, credentials_id: str) -> dict[str, Any]:
40
+ return await self._client.delete(f"/credentials/all/{credentials_id}")
@@ -0,0 +1,64 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from persona_models.common import Paginated
6
+ from persona_models.features import FeatureTemplate, McpServerConfiguration
7
+
8
+ from persona_sdk._serde import dump_payload
9
+ from persona_sdk.client import PersonaClient
10
+
11
+
12
+ class FeaturesApi:
13
+ def __init__(self, client: PersonaClient):
14
+ self._client = client
15
+
16
+ async def list(
17
+ self, keyword: str | None = None, page: int = 1, size: int = 20
18
+ ) -> Paginated[FeatureTemplate]:
19
+ params: dict[str, Any] = {"page": page, "size": size}
20
+ if keyword:
21
+ params["keyword"] = keyword
22
+ data = await self._client.get("/features/templates", params=params)
23
+ return Paginated[FeatureTemplate].model_validate(data)
24
+
25
+ async def get(self, template_id: str) -> FeatureTemplate:
26
+ data = await self._client.get(f"/features/templates/{template_id}")
27
+ return FeatureTemplate.model_validate(data)
28
+
29
+ async def create(
30
+ self, feature_template: FeatureTemplate | dict[str, Any]
31
+ ) -> FeatureTemplate:
32
+ data = await self._client.post(
33
+ "/features/templates", json=dump_payload(feature_template)
34
+ )
35
+ return FeatureTemplate.model_validate(data)
36
+
37
+ async def update(
38
+ self, template_id: str, feature_template: FeatureTemplate | dict[str, Any]
39
+ ) -> FeatureTemplate:
40
+ data = await self._client.put(
41
+ f"/features/templates/{template_id}", json=dump_payload(feature_template)
42
+ )
43
+ return FeatureTemplate.model_validate(data)
44
+
45
+ async def delete(self, template_id: str) -> FeatureTemplate:
46
+ data = await self._client.delete(f"/features/templates/{template_id}")
47
+ return FeatureTemplate.model_validate(data)
48
+
49
+ async def get_mcp_tools(
50
+ self,
51
+ mcp_config: McpServerConfiguration | dict[str, Any],
52
+ credentials_id: str | None = None,
53
+ ) -> dict[str, Any]:
54
+ """List the tools exposed by an MCP server.
55
+
56
+ Returns the server's ``McpToolsResponse`` (``tools`` and optional
57
+ ``error``) as a plain dict.
58
+ """
59
+ params = {"credentialsId": credentials_id} if credentials_id else None
60
+ return await self._client.post(
61
+ "/features/templates/mcp/available-tools",
62
+ json=dump_payload(mcp_config),
63
+ params=params,
64
+ )
@@ -0,0 +1,81 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from persona_models.common import Paginated
6
+ from persona_models.knowledge_bases import (
7
+ KnowledgeBase,
8
+ KnowledgeBaseDocument,
9
+ SearchChunksRequest,
10
+ )
11
+
12
+ from persona_sdk._serde import dump_payload
13
+ from persona_sdk.client import PersonaClient
14
+
15
+
16
+ class KnowledgeBasesApi:
17
+ def __init__(self, client: PersonaClient):
18
+ self._client = client
19
+
20
+ async def list(
21
+ self, keyword: str | None = None, page: int = 1, size: int = 20
22
+ ) -> Paginated[KnowledgeBase]:
23
+ params: dict[str, Any] = {"page": page, "size": size}
24
+ if keyword:
25
+ params["keyword"] = keyword
26
+ data = await self._client.get("/knowledges", params=params)
27
+ return Paginated[KnowledgeBase].model_validate(data)
28
+
29
+ async def get(self, knowledge_base_id: str) -> KnowledgeBase:
30
+ data = await self._client.get(f"/knowledges/{knowledge_base_id}")
31
+ return KnowledgeBase.model_validate(data)
32
+
33
+ async def create(
34
+ self, knowledge_base: KnowledgeBase | dict[str, Any]
35
+ ) -> KnowledgeBase:
36
+ data = await self._client.post("/knowledges", json=dump_payload(knowledge_base))
37
+ return KnowledgeBase.model_validate(data)
38
+
39
+ async def update(
40
+ self, knowledge_base_id: str, knowledge_base: KnowledgeBase | dict[str, Any]
41
+ ) -> KnowledgeBase:
42
+ data = await self._client.put(
43
+ f"/knowledges/{knowledge_base_id}", json=dump_payload(knowledge_base)
44
+ )
45
+ return KnowledgeBase.model_validate(data)
46
+
47
+ async def delete(self, knowledge_base_id: str) -> KnowledgeBase:
48
+ data = await self._client.delete(f"/knowledges/{knowledge_base_id}")
49
+ return KnowledgeBase.model_validate(data)
50
+
51
+ async def list_documents(
52
+ self, knowledge_base_id: str, page: int = 1, size: int = 20
53
+ ) -> Paginated[KnowledgeBaseDocument]:
54
+ params: dict[str, Any] = {"page": page, "size": size}
55
+ data = await self._client.get(
56
+ f"/knowledges/{knowledge_base_id}/documents", params=params
57
+ )
58
+ return Paginated[KnowledgeBaseDocument].model_validate(data)
59
+
60
+ async def delete_document(
61
+ self, knowledge_base_id: str, document_id: str
62
+ ) -> KnowledgeBaseDocument:
63
+ data = await self._client.delete(
64
+ f"/knowledges/{knowledge_base_id}/documents/{document_id}"
65
+ )
66
+ return KnowledgeBaseDocument.model_validate(data)
67
+
68
+ async def search_chunks(
69
+ self,
70
+ knowledge_base_id: str,
71
+ request: SearchChunksRequest | dict[str, Any],
72
+ ) -> list[dict[str, Any]]:
73
+ """Search a knowledge base for matching chunks.
74
+
75
+ Each chunk has the server-side ``ChunkResult`` shape
76
+ (``id``, ``text``, ``score``, ``metadata``, ``documentId``).
77
+ """
78
+ data = await self._client.post(
79
+ f"/knowledges/{knowledge_base_id}/search", json=dump_payload(request)
80
+ )
81
+ return list(data or [])
@@ -0,0 +1,49 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from persona_models.common import Paginated
6
+ from persona_models.known_models import KnownModel
7
+
8
+ from persona_sdk._serde import dump_payload
9
+ from persona_sdk.client import PersonaClient
10
+
11
+
12
+ class KnownModelsApi:
13
+ def __init__(self, client: PersonaClient):
14
+ self._client = client
15
+
16
+ async def list(
17
+ self, keyword: str | None = None, page: int = 1, size: int = 100
18
+ ) -> Paginated[KnownModel]:
19
+ params: dict[str, Any] = {"page": page, "size": size}
20
+ if keyword:
21
+ params["keyword"] = keyword
22
+ data = await self._client.get("/known-models", params=params)
23
+ return Paginated[KnownModel].model_validate(data)
24
+
25
+ async def get(self, known_model_id: str) -> KnownModel:
26
+ data = await self._client.get(f"/known-models/{known_model_id}")
27
+ return KnownModel.model_validate(data)
28
+
29
+ async def create(
30
+ self, known_model: KnownModel | dict[str, Any]
31
+ ) -> KnownModel:
32
+ data = await self._client.post(
33
+ "/known-models", json=dump_payload(known_model)
34
+ )
35
+ return KnownModel.model_validate(data)
36
+
37
+ async def update(
38
+ self,
39
+ known_model_id: str,
40
+ known_model: KnownModel | dict[str, Any],
41
+ ) -> KnownModel:
42
+ data = await self._client.put(
43
+ f"/known-models/{known_model_id}", json=dump_payload(known_model)
44
+ )
45
+ return KnownModel.model_validate(data)
46
+
47
+ async def delete(self, known_model_id: str) -> KnownModel:
48
+ data = await self._client.delete(f"/known-models/{known_model_id}")
49
+ return KnownModel.model_validate(data)
@@ -0,0 +1,74 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from persona_models.common import Paginated
6
+ from persona_models.missions import CreateMissionRequest, Mission
7
+
8
+ from persona_sdk._serde import dump_payload
9
+ from persona_sdk.client import PersonaClient
10
+
11
+
12
+ class MissionsApi:
13
+ def __init__(self, client: PersonaClient):
14
+ self._client = client
15
+
16
+ async def list(
17
+ self,
18
+ keyword: str | None = None,
19
+ status: str | None = None,
20
+ page: int = 1,
21
+ size: int = 20,
22
+ ) -> Paginated[Mission]:
23
+ params: dict[str, Any] = {"page": page, "size": size}
24
+ if keyword:
25
+ params["keyword"] = keyword
26
+ if status:
27
+ params["status"] = status
28
+ data = await self._client.get("/missions", params=params)
29
+ return Paginated[Mission].model_validate(data)
30
+
31
+ async def get(self, mission_id: str) -> Mission:
32
+ return Mission.model_validate(await self._client.get(f"/missions/{mission_id}"))
33
+
34
+ async def create(
35
+ self, mission: CreateMissionRequest | Mission | dict[str, Any]
36
+ ) -> Mission:
37
+ data = await self._client.post("/missions", json=dump_payload(mission))
38
+ return Mission.model_validate(data)
39
+
40
+ async def update(
41
+ self, mission_id: str, mission: Mission | dict[str, Any]
42
+ ) -> Mission:
43
+ data = await self._client.put(
44
+ f"/missions/{mission_id}", json=dump_payload(mission)
45
+ )
46
+ return Mission.model_validate(data)
47
+
48
+ async def delete(self, mission_id: str) -> Mission:
49
+ data = await self._client.delete(f"/missions/{mission_id}")
50
+ return Mission.model_validate(data)
51
+
52
+ async def generate(self, mission_id: str) -> Mission:
53
+ data = await self._client.post(f"/missions/{mission_id}/generate")
54
+ return Mission.model_validate(data)
55
+
56
+ async def execute(self, mission_id: str) -> Mission:
57
+ data = await self._client.post(f"/missions/{mission_id}/execute")
58
+ return Mission.model_validate(data)
59
+
60
+ async def continue_mission(self, mission_id: str) -> Mission:
61
+ data = await self._client.post(f"/missions/{mission_id}/continue")
62
+ return Mission.model_validate(data)
63
+
64
+ async def stop(self, mission_id: str) -> Mission:
65
+ data = await self._client.post(f"/missions/{mission_id}/stop")
66
+ return Mission.model_validate(data)
67
+
68
+ async def send_instructions(
69
+ self, mission_id: str, instructions: dict[str, Any]
70
+ ) -> Mission:
71
+ data = await self._client.post(
72
+ f"/missions/{mission_id}/instructions", json=instructions
73
+ )
74
+ return Mission.model_validate(data)