deploypod 0.1.0__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.
@@ -0,0 +1,64 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ import httpx
6
+
7
+ from deploypod._http import message_result, raise_for_status
8
+ from deploypod.types import LLMModelResponse, LLMProviderResponse, MessageResult
9
+
10
+
11
+ class ProvidersResource:
12
+ def __init__(self, http: httpx.Client):
13
+ self._http = http
14
+
15
+ def create(self, *, provider_type: str, **kwargs: Any) -> LLMProviderResponse:
16
+ payload = {"provider_type": provider_type, **kwargs}
17
+ resp = self._http.post("/llm-providers/", json=payload)
18
+ raise_for_status(resp)
19
+ return LLMProviderResponse(**resp.json())
20
+
21
+ def list(self) -> list[LLMProviderResponse]:
22
+ resp = self._http.get("/llm-providers/")
23
+ raise_for_status(resp)
24
+ return [LLMProviderResponse(**p) for p in resp.json()]
25
+
26
+ def get(self, provider_id: int) -> LLMProviderResponse:
27
+ resp = self._http.get(f"/llm-providers/{provider_id}")
28
+ raise_for_status(resp)
29
+ return LLMProviderResponse(**resp.json())
30
+
31
+ def get_default(self) -> LLMProviderResponse:
32
+ resp = self._http.get("/llm-providers/default")
33
+ raise_for_status(resp)
34
+ return LLMProviderResponse(**resp.json())
35
+
36
+ def update(self, provider_id: int, **kwargs: Any) -> LLMProviderResponse:
37
+ resp = self._http.put(f"/llm-providers/{provider_id}", json=kwargs)
38
+ raise_for_status(resp)
39
+ return LLMProviderResponse(**resp.json())
40
+
41
+ def delete(self, provider_id: int) -> MessageResult:
42
+ resp = self._http.delete(f"/llm-providers/{provider_id}")
43
+ raise_for_status(resp)
44
+ return message_result(resp)
45
+
46
+ def test(self, provider_id: int) -> dict:
47
+ resp = self._http.post(f"/llm-providers/{provider_id}/test")
48
+ raise_for_status(resp)
49
+ return resp.json()
50
+
51
+ def list_models(self, provider_id: int) -> list[dict]:
52
+ resp = self._http.get(f"/llm-providers/{provider_id}/models")
53
+ raise_for_status(resp)
54
+ return resp.json()
55
+
56
+ def set_default(self, provider_id: int) -> dict:
57
+ resp = self._http.post(f"/llm-providers/{provider_id}/set-default")
58
+ raise_for_status(resp)
59
+ return resp.json()
60
+
61
+ def discover_vllm(self) -> dict:
62
+ resp = self._http.post("/llm-providers/discover-vllm")
63
+ raise_for_status(resp)
64
+ return resp.json()
@@ -0,0 +1,75 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Dict, List
4
+
5
+ import httpx
6
+
7
+ from deploypod._http import message_result, raise_for_status
8
+ from deploypod.types import MessageResult, SkillResponse
9
+
10
+
11
+ class SkillsResource:
12
+ def __init__(self, http: httpx.Client):
13
+ self._http = http
14
+
15
+ def create(
16
+ self,
17
+ *,
18
+ name: str,
19
+ slug: str,
20
+ description: str | None = None,
21
+ invocation_mode: str = "always_on",
22
+ prompt_instructions: str | None = None,
23
+ examples: list[dict[str, Any]] | None = None,
24
+ allowed_tools: list[str] | None = None,
25
+ additional_tools: list[dict[str, Any]] | None = None,
26
+ ) -> SkillResponse:
27
+ payload: dict[str, Any] = {"name": name, "slug": slug, "invocation_mode": invocation_mode}
28
+ if description is not None:
29
+ payload["description"] = description
30
+ if prompt_instructions is not None:
31
+ payload["prompt_instructions"] = prompt_instructions
32
+ if examples is not None:
33
+ payload["examples"] = examples
34
+ if allowed_tools is not None:
35
+ payload["allowed_tools"] = allowed_tools
36
+ if additional_tools is not None:
37
+ payload["additional_tools"] = additional_tools
38
+ resp = self._http.post("/skills/", json=payload)
39
+ raise_for_status(resp)
40
+ return SkillResponse(**resp.json())
41
+
42
+ def list(self) -> list[SkillResponse]:
43
+ resp = self._http.get("/skills/")
44
+ raise_for_status(resp)
45
+ return [SkillResponse(**s) for s in resp.json()]
46
+
47
+ def get(self, skill_id: int) -> SkillResponse:
48
+ resp = self._http.get(f"/skills/{skill_id}")
49
+ raise_for_status(resp)
50
+ return SkillResponse(**resp.json())
51
+
52
+ def update(self, skill_id: int, **kwargs: Any) -> SkillResponse:
53
+ resp = self._http.put(f"/skills/{skill_id}", json=kwargs)
54
+ raise_for_status(resp)
55
+ return SkillResponse(**resp.json())
56
+
57
+ def delete(self, skill_id: int) -> MessageResult:
58
+ resp = self._http.delete(f"/skills/{skill_id}")
59
+ raise_for_status(resp)
60
+ return message_result(resp)
61
+
62
+ def assign_to_agent(self, skill_id: int, agent_id: int) -> MessageResult:
63
+ resp = self._http.post(f"/skills/{skill_id}/agents/{agent_id}")
64
+ raise_for_status(resp)
65
+ return message_result(resp)
66
+
67
+ def remove_from_agent(self, skill_id: int, agent_id: int) -> MessageResult:
68
+ resp = self._http.delete(f"/skills/{skill_id}/agents/{agent_id}")
69
+ raise_for_status(resp)
70
+ return message_result(resp)
71
+
72
+ def list_for_agent(self, agent_id: int) -> list[SkillResponse]:
73
+ resp = self._http.get(f"/skills/agents/{agent_id}/skills/")
74
+ raise_for_status(resp)
75
+ return [SkillResponse(**s) for s in resp.json()]
@@ -0,0 +1,56 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ import httpx
6
+
7
+ from deploypod._http import message_result, raise_for_status
8
+ from deploypod.types import MessageResult, UserResponse
9
+
10
+
11
+ class UsersResource:
12
+ def __init__(self, http: httpx.Client):
13
+ self._http = http
14
+
15
+ def create(
16
+ self,
17
+ *,
18
+ email: str,
19
+ roles: list[str] | None = None,
20
+ username: str | None = None,
21
+ deployed_agent_slug: str | None = None,
22
+ send_password_email: bool = False,
23
+ app_url: str | None = None,
24
+ ) -> UserResponse:
25
+ payload: dict[str, Any] = {"email": email, "send_password_email": send_password_email}
26
+ if roles is not None:
27
+ payload["roles"] = roles
28
+ if username is not None:
29
+ payload["username"] = username
30
+ if deployed_agent_slug is not None:
31
+ payload["deployed_agent_slug"] = deployed_agent_slug
32
+ if app_url is not None:
33
+ payload["app_url"] = app_url
34
+ resp = self._http.post("/user/create-user", json=payload)
35
+ raise_for_status(resp)
36
+ return UserResponse(**resp.json())
37
+
38
+ def list(self) -> list[UserResponse]:
39
+ resp = self._http.get("/user/list")
40
+ raise_for_status(resp)
41
+ return [UserResponse(**u) for u in resp.json()]
42
+
43
+ def update_roles(self, user_id: str, roles: list[str]) -> dict:
44
+ resp = self._http.put(f"/user/{user_id}/roles", json={"roles": roles})
45
+ raise_for_status(resp)
46
+ return resp.json()
47
+
48
+ def delete(self, user_id: str) -> MessageResult:
49
+ resp = self._http.delete(f"/user/{user_id}")
50
+ raise_for_status(resp)
51
+ return message_result(resp)
52
+
53
+ def my_groups(self) -> list[dict]:
54
+ resp = self._http.get("/user/me/groups")
55
+ raise_for_status(resp)
56
+ return resp.json()
deploypod/types.py ADDED
@@ -0,0 +1,390 @@
1
+ """Response models mirroring the Deploypod API."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from datetime import datetime
6
+ from typing import Any, Dict, List, Optional, Union
7
+ from uuid import UUID
8
+
9
+ from pydantic import BaseModel, field_validator
10
+
11
+
12
+ # ── Agents ───────────────────────────────────────────────────────────
13
+
14
+ class WelcomeMessageResponse(BaseModel):
15
+ id: UUID
16
+ name: str
17
+ message: str
18
+ is_template: bool
19
+ template_variables: Optional[List[str]] = None
20
+ created_at: datetime
21
+ updated_at: datetime
22
+
23
+
24
+ class WalkthroughQuestionResponse(BaseModel):
25
+ id: UUID
26
+ question_text: str
27
+ description: Optional[str] = None
28
+ display_order: Optional[int] = None
29
+ category: Optional[str] = None
30
+ is_active: Optional[bool] = None
31
+ created_at: Optional[datetime] = None
32
+ updated_at: Optional[datetime] = None
33
+
34
+
35
+ class AgentResponse(BaseModel):
36
+ id: int
37
+ uuid: UUID
38
+ org_id: int
39
+ name: str
40
+ group_id: Optional[int] = None
41
+ group_name: Optional[str] = None
42
+ knowledge_base_ids: List[int] = []
43
+ writable_kb_ids: Optional[List[int]] = None
44
+ llm_provider_id: Optional[int] = None
45
+ llm_model: Optional[str] = None
46
+ system_prompt_extension: Optional[str] = None
47
+ # JSON-Schema object the final answer is forced into (emit_result).
48
+ output_schema: Optional[dict[str, Any]] = None
49
+ autonomy_mode: str = "interactive"
50
+ can_use_web_search: bool = False
51
+ # Every web query the agent sends waits for a person's approval.
52
+ web_confirmation_required: bool = False
53
+ table_manager_enabled: bool = False
54
+ tts_provider: Optional[str] = None
55
+ tts_model: Optional[str] = None
56
+ tts_voice: Optional[str] = None
57
+ voice_id: Optional[str] = None
58
+ speech_speed: Optional[float] = 1.0
59
+ config: Optional[Dict[str, Any]] = None
60
+ third_party_auth_enabled: bool = False
61
+ welcome_messages: Optional[List[str]] = None
62
+ welcome_message_relationships: Optional[List[WelcomeMessageResponse]] = None
63
+ walkthrough_question_relationships: Optional[List[WalkthroughQuestionResponse]] = None
64
+ subagent_relationships: Optional[List[Dict[str, Any]]] = None
65
+ user_permission_level: Optional[str] = None
66
+ created_at: datetime
67
+ updated_at: datetime
68
+
69
+
70
+ class ThirdPartyAuthResponse(BaseModel):
71
+ shared_secret_key: str
72
+ message: str
73
+
74
+
75
+ class DeploymentResponse(BaseModel):
76
+ slug: Optional[str] = None
77
+ deployed: bool = False
78
+ message: Optional[str] = None
79
+
80
+
81
+ # ── Knowledge Bases ──────────────────────────────────────────────────
82
+
83
+ class KnowledgeBaseResponse(BaseModel):
84
+ id: int
85
+ org_id: int
86
+ name: str
87
+ description: Optional[str] = None
88
+ created_at: datetime
89
+ group_id: Optional[int] = None
90
+ group_name: Optional[str] = None
91
+ has_navigation: Optional[bool] = None
92
+ navigation_status: Optional[str] = None
93
+ user_permission_level: Optional[str] = None
94
+
95
+
96
+ class KBConstraintsResponse(BaseModel):
97
+ max_navigation_sources: int
98
+ max_navigation_kbs_per_agent: int
99
+
100
+
101
+ # ── Knowledge Sources ────────────────────────────────────────────────
102
+
103
+ class KnowledgeSourceResponse(BaseModel):
104
+ id: int
105
+ name: str
106
+ source_identifier: str
107
+ status: str
108
+ purpose: str
109
+ source_type: str
110
+ created_at: datetime
111
+ last_processed_at: Optional[datetime] = None
112
+ error_message: Optional[str] = None
113
+ options: Optional[Dict[str, Any]] = None
114
+
115
+
116
+ # ── Skills ───────────────────────────────────────────────────────────
117
+
118
+ class SkillResponse(BaseModel):
119
+ id: int
120
+ uuid: str
121
+ organization_id: int
122
+ name: str
123
+ slug: str
124
+ description: Optional[str] = None
125
+ invocation_mode: str
126
+ prompt_instructions: Optional[str] = None
127
+ examples: Optional[Any] = None
128
+ allowed_tools: Optional[List[str]] = None
129
+ additional_tools: Optional[List[Dict[str, Any]]] = None
130
+ is_active: bool
131
+ created_by: Optional[str] = None
132
+ created_at: Optional[datetime] = None
133
+ updated_at: Optional[datetime] = None
134
+
135
+
136
+ # ── Custom Tools ─────────────────────────────────────────────────────
137
+
138
+ class CustomToolResponse(BaseModel):
139
+ id: int
140
+ org_id: int
141
+ name: str
142
+ description: Optional[str] = None
143
+ tool_type: str
144
+ method: Optional[str] = None
145
+ url: Optional[str] = None
146
+ parameters: Optional[Union[List[Dict[str, Any]], Dict[str, Any]]] = None
147
+ headers: Optional[Union[List[Dict[str, Any]], Dict[str, Any]]] = None
148
+ body_template: Optional[Dict[str, Any]] = None
149
+ response_mapping: Optional[Dict[str, Any]] = None
150
+ group_id: Optional[int] = None
151
+ created_at: Optional[datetime] = None
152
+ updated_at: Optional[datetime] = None
153
+
154
+
155
+ class ToolExecutionResponse(BaseModel):
156
+ id: int
157
+ tool_id: int
158
+ status: str
159
+ response_data: Optional[Dict[str, Any]] = None
160
+ error_message: Optional[str] = None
161
+ execution_time_ms: Optional[float] = None
162
+ created_at: Optional[datetime] = None
163
+
164
+
165
+ # ── MCP Servers ──────────────────────────────────────────────────────
166
+
167
+ class MCPToolResponse(BaseModel):
168
+ id: int
169
+ mcp_server_id: Optional[int] = None
170
+ tool_name: Optional[str] = None
171
+ name: Optional[str] = None
172
+ description: Optional[str] = None
173
+ input_schema: Optional[Dict[str, Any]] = None
174
+ parameters_schema: Optional[Dict[str, Any]] = None
175
+ is_enabled: bool = True
176
+ created_at: Optional[datetime] = None
177
+
178
+
179
+ class MCPServerResponse(BaseModel):
180
+ id: int
181
+ org_id: Optional[int] = None
182
+ name: str
183
+ description: Optional[str] = None
184
+ endpoint_url: Optional[str] = None
185
+ server_type: Optional[str] = None
186
+ is_active: bool = True
187
+ health_status: Optional[str] = None
188
+ last_heartbeat: Optional[datetime] = None
189
+ group_id: Optional[int] = None
190
+ timeout_seconds: Optional[int] = None
191
+ retry_attempts: Optional[int] = None
192
+ tools: Optional[List[MCPToolResponse]] = None
193
+ created_at: Optional[datetime] = None
194
+ updated_at: Optional[datetime] = None
195
+
196
+
197
+ # ── LLM Providers ───────────────────────────────────────────────────
198
+
199
+ class LLMProviderResponse(BaseModel):
200
+ id: int
201
+ org_id: int
202
+ provider_type: str
203
+ name: Optional[str] = None
204
+ api_base: Optional[str] = None
205
+ is_default: bool = False
206
+ created_at: Optional[datetime] = None
207
+ updated_at: Optional[datetime] = None
208
+
209
+
210
+ class LLMModelResponse(BaseModel):
211
+ id: str
212
+ name: Optional[str] = None
213
+
214
+
215
+ # ── Database Connections ─────────────────────────────────────────────
216
+
217
+ class ConnectionResponse(BaseModel):
218
+ id: int
219
+ org_id: int
220
+ name: str
221
+ db_type: str
222
+ host: Optional[str] = None
223
+ port: Optional[int] = None
224
+ database: Optional[str] = None
225
+ status: Optional[str] = None
226
+ created_at: Optional[datetime] = None
227
+ updated_at: Optional[datetime] = None
228
+
229
+
230
+ class TableResponse(BaseModel):
231
+ id: int
232
+ connection_id: int
233
+ name: str
234
+ schema_info: Optional[Dict[str, Any]] = None
235
+ row_count: Optional[int] = None
236
+
237
+
238
+ # ── Conversations ────────────────────────────────────────────────────
239
+
240
+ class ConversationResponse(BaseModel):
241
+ id: UUID
242
+ user_id: Optional[str] = None
243
+ session_id: Optional[str] = None
244
+ org_id: int
245
+ agent_id: int
246
+ title: Optional[str] = None
247
+ created_at: datetime
248
+ message_count: int
249
+ agent_name: Optional[str] = None
250
+ username: Optional[str] = None
251
+ session_status: Optional[str] = None
252
+ session_display_status: Optional[str] = None
253
+ last_activity_at: Optional[datetime] = None
254
+ session_expires_at: Optional[datetime] = None
255
+
256
+
257
+ class MessageResponse(BaseModel):
258
+ id: int
259
+ conversation_id: UUID
260
+ sender: str
261
+ content: str
262
+ timestamp: datetime
263
+ response_metadata: Optional[Dict] = None
264
+ iterations: Optional[List[Dict]] = None
265
+
266
+
267
+ class ConversationDetailResponse(BaseModel):
268
+ conversation: ConversationResponse
269
+ messages: List[MessageResponse]
270
+
271
+
272
+ # ── Users ────────────────────────────────────────────────────────────
273
+
274
+ class UserGroupMembershipInfo(BaseModel):
275
+ group_id: int
276
+ group_name: str
277
+ permission_level: str
278
+
279
+
280
+ class UserResponse(BaseModel):
281
+ id: str
282
+ username: str
283
+ email: str
284
+ org_id: int
285
+ roles: Optional[List[str]] = None
286
+ created_at: Optional[datetime] = None
287
+ group_memberships: Optional[List[UserGroupMembershipInfo]] = None
288
+ # Only on create-user: whether the login email went out, and the
289
+ # temporary password, returned this once.
290
+ email_sent: Optional[bool] = None
291
+ email_error: Optional[str] = None
292
+ temp_password: Optional[str] = None
293
+
294
+
295
+ # ── Groups ───────────────────────────────────────────────────────────
296
+
297
+ class GroupResponse(BaseModel):
298
+ id: int
299
+ uuid: Optional[UUID] = None
300
+ org_id: int
301
+ name: str
302
+ created_at: Optional[datetime] = None
303
+ updated_at: Optional[datetime] = None
304
+ member_count: Optional[int] = None
305
+
306
+
307
+ class GroupMemberResponse(BaseModel):
308
+ user_id: str
309
+ username: Optional[str] = None
310
+ email: Optional[str] = None
311
+ permission_level: str
312
+
313
+
314
+ # ── Organization ─────────────────────────────────────────────────────
315
+
316
+ class LicenseInfoResponse(BaseModel):
317
+ tier: str
318
+ status: str
319
+ limits: Dict[str, Any]
320
+ current_usage: Dict[str, Any]
321
+ expires_at: Optional[str] = None
322
+ features: Dict[str, Any]
323
+
324
+
325
+ # ── Async Tasks ──────────────────────────────────────────────────────
326
+
327
+ class AsyncTaskResponse(BaseModel):
328
+ id: int
329
+ agent_id: int
330
+ name: str
331
+ prompt: str
332
+ schedule_cron: str
333
+ timeout_seconds: Optional[int] = None
334
+ enabled: bool = True
335
+ next_run_at: Optional[datetime] = None
336
+ created_at: Optional[datetime] = None
337
+ updated_at: Optional[datetime] = None
338
+
339
+
340
+ class AsyncRunResponse(BaseModel):
341
+ id: int
342
+ task_id: int
343
+ status: str
344
+ result_data: Optional[Dict[str, Any]] = None
345
+ result_summary: Optional[str] = None
346
+ error_message: Optional[str] = None
347
+ execution_time_ms: Optional[float] = None
348
+ started_at: Optional[datetime] = None
349
+ completed_at: Optional[datetime] = None
350
+
351
+ @field_validator("result_data", mode="before")
352
+ @classmethod
353
+ def _parse_result_data(cls, v: Any) -> Any:
354
+ if isinstance(v, str):
355
+ import json
356
+ return json.loads(v)
357
+ return v
358
+
359
+
360
+ # ── Jobs ─────────────────────────────────────────────────────────────
361
+
362
+ class JobResponse(BaseModel):
363
+ id: int
364
+ status: str
365
+ job_type: Optional[str] = None
366
+ progress: Optional[float] = None
367
+ error_message: Optional[str] = None
368
+ created_at: Optional[datetime] = None
369
+ updated_at: Optional[datetime] = None
370
+
371
+
372
+ # ── Pruning ──────────────────────────────────────────────────────────
373
+
374
+ class TestPruningResponse(BaseModel):
375
+ total_tables: int
376
+ total_tools: int
377
+ selected_tables: list[str]
378
+ selected_tools: list[str]
379
+ duration_ms: int
380
+ source_pruning_active: bool
381
+ tool_pruning_active: bool
382
+ source_threshold: int
383
+ tool_threshold: int
384
+
385
+
386
+ # ── Generic ──────────────────────────────────────────────────────────
387
+
388
+ class MessageResult(BaseModel):
389
+ """Generic {message: ...} response from delete/assign endpoints."""
390
+ message: str
@@ -0,0 +1,104 @@
1
+ Metadata-Version: 2.4
2
+ Name: deploypod
3
+ Version: 0.1.0
4
+ Summary: Python client for the Deploypod API: run AI agents, manage their tools and knowledge bases.
5
+ Author: Deploypod
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://deploypod.ai
8
+ Project-URL: Documentation, https://docs.deploypod.ai/en/gelistirici/sdk-ve-widget/
9
+ Keywords: deploypod,ai,agents,llm,sdk
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Typing :: Typed
16
+ Requires-Python: >=3.9
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: httpx>=0.25.0
20
+ Requires-Dist: pydantic>=2.0
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest>=7.0; extra == "dev"
23
+ Requires-Dist: pytest-httpx>=0.30.0; extra == "dev"
24
+ Dynamic: license-file
25
+
26
+ # Deploypod Python SDK
27
+
28
+ The Python client for the [Deploypod](https://deploypod.ai) API. Run your AI
29
+ agents from code, and manage their instructions, tools and knowledge bases.
30
+
31
+ ```bash
32
+ pip install deploypod
33
+ ```
34
+
35
+ Python 3.9 or newer.
36
+
37
+ ## Sign in
38
+
39
+ Ask your Deploypod administrator for an application (`app_id`, `app_secret`)
40
+ and your organization's number. The client gets the access token itself and
41
+ renews it before it expires.
42
+
43
+ ```python
44
+ from deploypod import DeploypodClient
45
+
46
+ client = DeploypodClient(
47
+ org_id="42",
48
+ app_id="YOUR_APP_ID",
49
+ app_secret="YOUR_APP_SECRET",
50
+ )
51
+ ```
52
+
53
+ Keep `app_secret` out of your code: read it from the environment.
54
+
55
+ ```bash
56
+ export DEPLOYPOD_ORG_ID=42
57
+ export DEPLOYPOD_APP_ID=...
58
+ export DEPLOYPOD_APP_SECRET=...
59
+ ```
60
+
61
+ ```python
62
+ from deploypod import get_client_from_env
63
+
64
+ client = get_client_from_env()
65
+ ```
66
+
67
+ Already have an access token? Pass `token="..."` instead of the app
68
+ credentials. For an on-premises installation, pass
69
+ `base_url="https://your-host/api"`.
70
+
71
+ ## Run an agent
72
+
73
+ ```python
74
+ for agent in client.agents.list():
75
+ print(agent.uuid, agent.name)
76
+
77
+ result = client.agents.run(
78
+ "AGENT_UUID",
79
+ "How many days of annual leave do I have?",
80
+ run_exploration=True,
81
+ timeout=300,
82
+ )
83
+ print(result["result_summary"])
84
+ ```
85
+
86
+ `run` waits for the answer. Other request fields go in as keyword arguments,
87
+ for example `output_schema={...}` to get the answer as JSON in
88
+ `result["final_emit"]`. Requests through `deploypod.ai` are cut after 100
89
+ seconds; for longer work (web research, presentations) use the WebSocket API.
90
+
91
+ ## Errors
92
+
93
+ Every error is a `deploypod.DeploypodError` with `status_code` and `detail`.
94
+ Subclasses: `AuthenticationError` (401/403), `NotFoundError`,
95
+ `ValidationError`, `ConflictError`, `LicenseError`, `ServerError`.
96
+
97
+ ## Documentation
98
+
99
+ Full guides, the REST and WebSocket APIs, and the chat widget:
100
+ <https://docs.deploypod.ai/en/>
101
+
102
+ ## License
103
+
104
+ MIT