knowledge2 0.4.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.
Files changed (139) hide show
  1. knowledge2-0.4.0.dist-info/METADATA +556 -0
  2. knowledge2-0.4.0.dist-info/RECORD +139 -0
  3. knowledge2-0.4.0.dist-info/WHEEL +5 -0
  4. knowledge2-0.4.0.dist-info/top_level.txt +1 -0
  5. sdk/__init__.py +70 -0
  6. sdk/_async_base.py +525 -0
  7. sdk/_async_paging.py +57 -0
  8. sdk/_base.py +541 -0
  9. sdk/_logging.py +41 -0
  10. sdk/_paging.py +73 -0
  11. sdk/_preview.py +70 -0
  12. sdk/_raw_response.py +25 -0
  13. sdk/_request_options.py +51 -0
  14. sdk/_transport.py +144 -0
  15. sdk/_validation.py +25 -0
  16. sdk/_validation_response.py +36 -0
  17. sdk/_version.py +3 -0
  18. sdk/async_client.py +320 -0
  19. sdk/async_resources/__init__.py +45 -0
  20. sdk/async_resources/_mixin_base.py +42 -0
  21. sdk/async_resources/a2a.py +230 -0
  22. sdk/async_resources/agents.py +489 -0
  23. sdk/async_resources/audit.py +145 -0
  24. sdk/async_resources/auth.py +133 -0
  25. sdk/async_resources/console.py +409 -0
  26. sdk/async_resources/corpora.py +276 -0
  27. sdk/async_resources/deployments.py +106 -0
  28. sdk/async_resources/documents.py +592 -0
  29. sdk/async_resources/feeds.py +248 -0
  30. sdk/async_resources/indexes.py +208 -0
  31. sdk/async_resources/jobs.py +165 -0
  32. sdk/async_resources/metadata.py +48 -0
  33. sdk/async_resources/models.py +102 -0
  34. sdk/async_resources/onboarding.py +538 -0
  35. sdk/async_resources/orgs.py +37 -0
  36. sdk/async_resources/pipelines.py +523 -0
  37. sdk/async_resources/projects.py +90 -0
  38. sdk/async_resources/search.py +262 -0
  39. sdk/async_resources/training.py +357 -0
  40. sdk/async_resources/usage.py +91 -0
  41. sdk/client.py +417 -0
  42. sdk/config.py +182 -0
  43. sdk/errors.py +178 -0
  44. sdk/examples/auth_factory.py +34 -0
  45. sdk/examples/batch_operations.py +57 -0
  46. sdk/examples/document_upload.py +56 -0
  47. sdk/examples/e2e_lifecycle.py +213 -0
  48. sdk/examples/error_handling.py +61 -0
  49. sdk/examples/pagination.py +64 -0
  50. sdk/examples/quickstart.py +36 -0
  51. sdk/examples/request_options.py +44 -0
  52. sdk/examples/search.py +64 -0
  53. sdk/integrations/__init__.py +57 -0
  54. sdk/integrations/_client.py +101 -0
  55. sdk/integrations/langchain/__init__.py +6 -0
  56. sdk/integrations/langchain/retriever.py +166 -0
  57. sdk/integrations/langchain/tools.py +108 -0
  58. sdk/integrations/llamaindex/__init__.py +11 -0
  59. sdk/integrations/llamaindex/filters.py +78 -0
  60. sdk/integrations/llamaindex/retriever.py +162 -0
  61. sdk/integrations/llamaindex/tools.py +109 -0
  62. sdk/integrations/llamaindex/vector_store.py +320 -0
  63. sdk/models/__init__.py +18 -0
  64. sdk/models/_base.py +24 -0
  65. sdk/models/_registry.py +457 -0
  66. sdk/models/a2a.py +92 -0
  67. sdk/models/agents.py +109 -0
  68. sdk/models/audit.py +28 -0
  69. sdk/models/auth.py +49 -0
  70. sdk/models/chunks.py +20 -0
  71. sdk/models/common.py +14 -0
  72. sdk/models/console.py +103 -0
  73. sdk/models/corpora.py +48 -0
  74. sdk/models/deployments.py +13 -0
  75. sdk/models/documents.py +126 -0
  76. sdk/models/embeddings.py +24 -0
  77. sdk/models/evaluation.py +17 -0
  78. sdk/models/feedback.py +9 -0
  79. sdk/models/feeds.py +57 -0
  80. sdk/models/indexes.py +36 -0
  81. sdk/models/jobs.py +52 -0
  82. sdk/models/models.py +26 -0
  83. sdk/models/onboarding.py +323 -0
  84. sdk/models/orgs.py +11 -0
  85. sdk/models/pipelines.py +147 -0
  86. sdk/models/projects.py +19 -0
  87. sdk/models/search.py +149 -0
  88. sdk/models/training.py +57 -0
  89. sdk/models/usage.py +39 -0
  90. sdk/namespaces.py +386 -0
  91. sdk/py.typed +0 -0
  92. sdk/resources/__init__.py +45 -0
  93. sdk/resources/_mixin_base.py +40 -0
  94. sdk/resources/a2a.py +230 -0
  95. sdk/resources/agents.py +487 -0
  96. sdk/resources/audit.py +144 -0
  97. sdk/resources/auth.py +138 -0
  98. sdk/resources/console.py +411 -0
  99. sdk/resources/corpora.py +269 -0
  100. sdk/resources/deployments.py +105 -0
  101. sdk/resources/documents.py +597 -0
  102. sdk/resources/feeds.py +246 -0
  103. sdk/resources/indexes.py +210 -0
  104. sdk/resources/jobs.py +164 -0
  105. sdk/resources/metadata.py +53 -0
  106. sdk/resources/models.py +99 -0
  107. sdk/resources/onboarding.py +542 -0
  108. sdk/resources/orgs.py +35 -0
  109. sdk/resources/pipeline_builder.py +257 -0
  110. sdk/resources/pipelines.py +520 -0
  111. sdk/resources/projects.py +87 -0
  112. sdk/resources/search.py +277 -0
  113. sdk/resources/training.py +358 -0
  114. sdk/resources/usage.py +92 -0
  115. sdk/types/__init__.py +366 -0
  116. sdk/types/a2a.py +88 -0
  117. sdk/types/agents.py +133 -0
  118. sdk/types/audit.py +26 -0
  119. sdk/types/auth.py +45 -0
  120. sdk/types/chunks.py +18 -0
  121. sdk/types/common.py +10 -0
  122. sdk/types/console.py +99 -0
  123. sdk/types/corpora.py +42 -0
  124. sdk/types/deployments.py +11 -0
  125. sdk/types/documents.py +104 -0
  126. sdk/types/embeddings.py +22 -0
  127. sdk/types/evaluation.py +15 -0
  128. sdk/types/feedback.py +7 -0
  129. sdk/types/feeds.py +61 -0
  130. sdk/types/indexes.py +30 -0
  131. sdk/types/jobs.py +50 -0
  132. sdk/types/models.py +22 -0
  133. sdk/types/onboarding.py +395 -0
  134. sdk/types/orgs.py +9 -0
  135. sdk/types/pipelines.py +177 -0
  136. sdk/types/projects.py +14 -0
  137. sdk/types/search.py +116 -0
  138. sdk/types/training.py +55 -0
  139. sdk/types/usage.py +37 -0
@@ -0,0 +1,489 @@
1
+ """Async agent resource mixin for the Knowledge2 SDK."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Literal
6
+
7
+ from sdk._paging import Page
8
+ from sdk._preview import preview_resource
9
+ from sdk._request_options import RequestOptions
10
+ from sdk._validation import require_str
11
+ from sdk.async_resources._mixin_base import AsyncRequesterMixin
12
+
13
+
14
+ @preview_resource
15
+ class AsyncAgentsMixin(AsyncRequesterMixin):
16
+ async def create_agent(
17
+ self,
18
+ *,
19
+ name: str,
20
+ corpus_id: str,
21
+ description: str | None = None,
22
+ system_prompt: str | None = None,
23
+ model: str | None = None,
24
+ project_id: str | None = None,
25
+ task_type: str | None = None,
26
+ instructions: str | None = None,
27
+ source_agents: list[dict[str, Any]] | None = None,
28
+ tool_config: dict[str, Any] | None = None,
29
+ request_options: RequestOptions | None = None,
30
+ ) -> dict[str, Any]:
31
+ """Create a new knowledge agent.
32
+
33
+ Args:
34
+ name: Human-readable name for the agent.
35
+ corpus_id: ID of the corpus the agent queries against.
36
+ description: Optional description of the agent's purpose.
37
+ system_prompt: Optional custom system prompt for the agent.
38
+ model: Optional model identifier (defaults to server-side default).
39
+ project_id: Optional project that will own the agent.
40
+ task_type: Optional task type for the agent (e.g. "summarize", "extract").
41
+ instructions: Optional natural-language instructions for the agent.
42
+ source_agents: Optional list of source agent references, each with
43
+ ``agent_id`` and ``mode`` keys.
44
+ tool_config: Optional tool configuration dictionary for the agent.
45
+
46
+ Returns:
47
+ The newly created agent record.
48
+
49
+ Raises:
50
+ Knowledge2Error: If the API request fails.
51
+ """
52
+ corpus_id = require_str(corpus_id, "corpus_id")
53
+ payload: dict[str, Any] = {"name": name, "corpus_id": corpus_id}
54
+ if description is not None:
55
+ payload["description"] = description
56
+ if system_prompt is not None:
57
+ payload["system_prompt"] = system_prompt
58
+ if model is not None:
59
+ payload["model"] = model
60
+ if project_id is not None:
61
+ payload["project_id"] = project_id
62
+ if task_type is not None:
63
+ payload["task_type"] = task_type
64
+ if instructions is not None:
65
+ payload["instructions"] = instructions
66
+ if source_agents is not None:
67
+ payload["source_agents"] = source_agents
68
+ if tool_config is not None:
69
+ payload["tool_config"] = tool_config
70
+ data = await self._request(
71
+ "POST", "/v1/agents", json=payload, request_options=request_options
72
+ )
73
+ return self._maybe_validate(data, "AgentResponse")
74
+
75
+ async def get_agent(
76
+ self,
77
+ agent_id: str,
78
+ request_options: RequestOptions | None = None,
79
+ ) -> dict[str, Any]:
80
+ """Retrieve a single agent by ID.
81
+
82
+ Args:
83
+ agent_id: Unique identifier of the agent.
84
+
85
+ Returns:
86
+ The agent record.
87
+
88
+ Raises:
89
+ NotFoundError: If the agent does not exist.
90
+ Knowledge2Error: If the API request fails.
91
+ """
92
+ agent_id = require_str(agent_id, "agent_id")
93
+ data = await self._request("GET", f"/v1/agents/{agent_id}", request_options=request_options)
94
+ return self._maybe_validate(data, "AgentResponse")
95
+
96
+ async def list_agents(
97
+ self,
98
+ *,
99
+ project_id: str | None = None,
100
+ limit: int = 20,
101
+ offset: int = 0,
102
+ request_options: RequestOptions | None = None,
103
+ ) -> Page[dict[str, Any]]:
104
+ """List agents accessible to the current credentials.
105
+
106
+ Args:
107
+ project_id: Optional project ID to filter agents by.
108
+ limit: Maximum number of agents to return per page.
109
+ offset: Number of agents to skip for pagination.
110
+
111
+ Returns:
112
+ A Page containing agent records with pagination metadata.
113
+
114
+ Raises:
115
+ Knowledge2Error: If the API request fails.
116
+ """
117
+ params: dict[str, Any] = {}
118
+ if project_id is not None:
119
+ params["project_id"] = project_id
120
+ return await self._list_page(
121
+ "GET",
122
+ "/v1/agents",
123
+ items_key="agents",
124
+ params=params or None,
125
+ limit=limit,
126
+ offset=offset,
127
+ )
128
+
129
+ async def update_agent(
130
+ self,
131
+ agent_id: str,
132
+ *,
133
+ name: str | None = None,
134
+ description: str | None = None,
135
+ corpus_id: str | None = None,
136
+ system_prompt: str | None = None,
137
+ model: str | None = None,
138
+ task_type: str | None = None,
139
+ instructions: str | None = None,
140
+ source_agents: list[dict[str, Any]] | None = None,
141
+ tool_config: dict[str, Any] | None = None,
142
+ request_options: RequestOptions | None = None,
143
+ ) -> dict[str, Any]:
144
+ """Update agent settings.
145
+
146
+ Args:
147
+ agent_id: ID of the agent to update.
148
+ name: New name for the agent.
149
+ description: New description for the agent.
150
+ corpus_id: New corpus ID for the agent.
151
+ system_prompt: New system prompt for the agent.
152
+ model: New model identifier for the agent.
153
+ task_type: New task type for the agent.
154
+ instructions: New natural-language instructions for the agent.
155
+ source_agents: New list of source agent references, each with
156
+ ``agent_id`` and ``mode`` keys.
157
+ tool_config: New tool configuration dictionary for the agent.
158
+
159
+ Returns:
160
+ Updated agent record.
161
+
162
+ Raises:
163
+ NotFoundError: If the agent does not exist.
164
+ Knowledge2Error: If the API request fails.
165
+ """
166
+ agent_id = require_str(agent_id, "agent_id")
167
+ payload: dict[str, Any] = {}
168
+ if name is not None:
169
+ payload["name"] = name
170
+ if description is not None:
171
+ payload["description"] = description
172
+ if corpus_id is not None:
173
+ payload["corpus_id"] = corpus_id
174
+ if system_prompt is not None:
175
+ payload["system_prompt"] = system_prompt
176
+ if model is not None:
177
+ payload["model"] = model
178
+ if task_type is not None:
179
+ payload["task_type"] = task_type
180
+ if instructions is not None:
181
+ payload["instructions"] = instructions
182
+ if source_agents is not None:
183
+ payload["source_agents"] = source_agents
184
+ if tool_config is not None:
185
+ payload["tool_config"] = tool_config
186
+ data = await self._request(
187
+ "PATCH", f"/v1/agents/{agent_id}", json=payload, request_options=request_options
188
+ )
189
+ return self._maybe_validate(data, "AgentResponse")
190
+
191
+ async def delete_agent(
192
+ self,
193
+ agent_id: str,
194
+ request_options: RequestOptions | None = None,
195
+ ) -> None:
196
+ """Delete an agent.
197
+
198
+ The agent must be in ``draft`` or ``archived`` status; deleting
199
+ an ``active`` agent will return a 409 Conflict error.
200
+
201
+ Args:
202
+ agent_id: Unique identifier of the agent to delete.
203
+
204
+ Returns:
205
+ None (the API returns 204 No Content on success).
206
+
207
+ Raises:
208
+ NotFoundError: If the agent does not exist.
209
+ ConflictError: If the agent is currently active.
210
+ Knowledge2Error: If the API request fails.
211
+ """
212
+ agent_id = require_str(agent_id, "agent_id")
213
+ await self._request("DELETE", f"/v1/agents/{agent_id}", request_options=request_options)
214
+
215
+ async def activate_agent(
216
+ self,
217
+ agent_id: str,
218
+ request_options: RequestOptions | None = None,
219
+ ) -> dict[str, Any]:
220
+ """Activate a draft or archived agent.
221
+
222
+ Validates that the agent's corpus is ready and model is valid
223
+ before transitioning the agent to ``active`` status.
224
+
225
+ Args:
226
+ agent_id: Unique identifier of the agent to activate.
227
+
228
+ Returns:
229
+ The updated agent record with ``active`` status.
230
+
231
+ Raises:
232
+ NotFoundError: If the agent does not exist.
233
+ ConflictError: If the agent is already active.
234
+ Knowledge2Error: If the API request fails.
235
+ """
236
+ agent_id = require_str(agent_id, "agent_id")
237
+ data = await self._request(
238
+ "POST", f"/v1/agents/{agent_id}/activate", request_options=request_options
239
+ )
240
+ return self._maybe_validate(data, "AgentResponse")
241
+
242
+ async def archive_agent(
243
+ self,
244
+ agent_id: str,
245
+ request_options: RequestOptions | None = None,
246
+ ) -> dict[str, Any]:
247
+ """Archive an active agent.
248
+
249
+ Transitions the agent from ``active`` to ``archived`` status.
250
+
251
+ Args:
252
+ agent_id: Unique identifier of the agent to archive.
253
+
254
+ Returns:
255
+ The updated agent record with ``archived`` status.
256
+
257
+ Raises:
258
+ NotFoundError: If the agent does not exist.
259
+ ConflictError: If the agent is not currently active.
260
+ Knowledge2Error: If the API request fails.
261
+ """
262
+ agent_id = require_str(agent_id, "agent_id")
263
+ data = await self._request(
264
+ "POST", f"/v1/agents/{agent_id}/archive", request_options=request_options
265
+ )
266
+ return self._maybe_validate(data, "AgentResponse")
267
+
268
+ async def chat_with_agent(
269
+ self,
270
+ agent_id: str,
271
+ *,
272
+ query: str,
273
+ top_k: int = 5,
274
+ filters: dict[str, Any] | None = None,
275
+ request_options: RequestOptions | None = None,
276
+ ) -> dict[str, Any]:
277
+ """Send a chat query to an active agent.
278
+
279
+ The agent retrieves relevant context from its corpus and generates
280
+ a grounded answer using its configured model and system prompt.
281
+
282
+ Args:
283
+ agent_id: Unique identifier of the agent to chat with.
284
+ query: The user's question or prompt.
285
+ top_k: Number of top search results to use as context.
286
+ filters: Optional metadata filters to narrow the search scope.
287
+
288
+ Returns:
289
+ A chat response containing the generated answer and sources.
290
+
291
+ Raises:
292
+ NotFoundError: If the agent does not exist.
293
+ ConflictError: If the agent is not active.
294
+ Knowledge2Error: If the API request fails.
295
+ """
296
+ agent_id = require_str(agent_id, "agent_id")
297
+ payload: dict[str, Any] = {"query": query, "top_k": top_k}
298
+ if filters is not None:
299
+ payload["filters"] = filters
300
+ data = await self._request(
301
+ "POST",
302
+ f"/v1/agents/{agent_id}/chat",
303
+ json=payload,
304
+ request_options=request_options,
305
+ )
306
+ return self._maybe_validate(data, "AgentChatResponse")
307
+
308
+ async def list_agent_models(
309
+ self,
310
+ request_options: RequestOptions | None = None,
311
+ ) -> dict[str, Any]:
312
+ """List available models for knowledge agents.
313
+
314
+ Returns:
315
+ A dict containing the list of supported model identifiers.
316
+
317
+ Raises:
318
+ Knowledge2Error: If the API request fails.
319
+ """
320
+ data = await self._request("GET", "/v1/agents/models", request_options=request_options)
321
+ return self._maybe_validate(data, "AgentModelsResponse")
322
+
323
+ async def run_agent(
324
+ self,
325
+ agent_id: str,
326
+ *,
327
+ input_chunks: list[dict[str, Any]],
328
+ top_k: int = 5,
329
+ request_options: RequestOptions | None = None,
330
+ ) -> dict[str, Any]:
331
+ """Run an agent on a set of input chunks.
332
+
333
+ The endpoint returns HTTP 202 and the task is queued as a background
334
+ job. Poll ``list_agent_runs()`` or the Jobs API to check for
335
+ completion.
336
+
337
+ Args:
338
+ agent_id: Unique identifier of the agent to run.
339
+ input_chunks: List of input chunk dicts, each containing a ``text``
340
+ key and an optional ``metadata`` key.
341
+ top_k: Number of top search results to use as context.
342
+
343
+ Returns:
344
+ A dict containing ``job_id`` and ``status`` for the queued run.
345
+
346
+ Raises:
347
+ NotFoundError: If the agent does not exist.
348
+ Knowledge2Error: If the API request fails.
349
+ """
350
+ agent_id = require_str(agent_id, "agent_id")
351
+ payload: dict[str, Any] = {"input_chunks": input_chunks, "top_k": top_k}
352
+ data = await self._request(
353
+ "POST",
354
+ f"/v1/agents/{agent_id}/run",
355
+ json=payload,
356
+ request_options=request_options,
357
+ )
358
+ return self._maybe_validate(data, "AgentRunResponse")
359
+
360
+ async def list_agent_runs(
361
+ self,
362
+ agent_id: str,
363
+ *,
364
+ limit: int = 100,
365
+ offset: int = 0,
366
+ request_options: RequestOptions | None = None,
367
+ ) -> Page[dict[str, Any]]:
368
+ """List runs for a given agent.
369
+
370
+ Args:
371
+ agent_id: Unique identifier of the agent.
372
+ limit: Maximum number of runs to return per page.
373
+ offset: Number of runs to skip for pagination.
374
+
375
+ Returns:
376
+ A Page containing agent run records with pagination metadata.
377
+
378
+ Raises:
379
+ NotFoundError: If the agent does not exist.
380
+ Knowledge2Error: If the API request fails.
381
+ """
382
+ agent_id = require_str(agent_id, "agent_id")
383
+ return await self._list_page(
384
+ "GET",
385
+ f"/v1/agents/{agent_id}/runs",
386
+ items_key="runs",
387
+ limit=limit,
388
+ offset=offset,
389
+ )
390
+
391
+ async def list_task_types(
392
+ self,
393
+ request_options: RequestOptions | None = None,
394
+ ) -> dict[str, Any]:
395
+ """List available task types for knowledge agents.
396
+
397
+ Returns:
398
+ A dict containing the list of supported task type identifiers.
399
+
400
+ Raises:
401
+ Knowledge2Error: If the API request fails.
402
+ """
403
+ data = await self._request("GET", "/v1/agents/task-types", request_options=request_options)
404
+ return self._maybe_validate(data, "AgentTaskTypesResponse")
405
+
406
+ async def create_subscription(
407
+ self,
408
+ agent_id: str,
409
+ *,
410
+ feed_id: str,
411
+ role: Literal["input", "output"],
412
+ request_options: RequestOptions | None = None,
413
+ ) -> dict[str, Any]:
414
+ """Create a feed subscription for an agent.
415
+
416
+ Args:
417
+ agent_id: Unique identifier of the agent.
418
+ feed_id: Unique identifier of the feed to subscribe to.
419
+ role: Subscription role, either ``"input"`` or ``"output"``.
420
+
421
+ Returns:
422
+ The newly created subscription record.
423
+
424
+ Raises:
425
+ NotFoundError: If the agent or feed does not exist.
426
+ Knowledge2Error: If the API request fails.
427
+ """
428
+ agent_id = require_str(agent_id, "agent_id")
429
+ feed_id = require_str(feed_id, "feed_id")
430
+ payload: dict[str, Any] = {"feed_id": feed_id, "role": role}
431
+ data = await self._request(
432
+ "POST",
433
+ f"/v1/agents/{agent_id}/subscriptions",
434
+ json=payload,
435
+ request_options=request_options,
436
+ )
437
+ return self._maybe_validate(data, "SubscriptionResponse")
438
+
439
+ async def list_subscriptions(
440
+ self,
441
+ agent_id: str,
442
+ request_options: RequestOptions | None = None,
443
+ ) -> dict[str, Any]:
444
+ """List all feed subscriptions for an agent.
445
+
446
+ Args:
447
+ agent_id: Unique identifier of the agent.
448
+
449
+ Returns:
450
+ A dict containing the list of subscription records.
451
+
452
+ Raises:
453
+ NotFoundError: If the agent does not exist.
454
+ Knowledge2Error: If the API request fails.
455
+ """
456
+ agent_id = require_str(agent_id, "agent_id")
457
+ data = await self._request(
458
+ "GET",
459
+ f"/v1/agents/{agent_id}/subscriptions",
460
+ request_options=request_options,
461
+ )
462
+ return self._maybe_validate(data, "SubscriptionListResponse")
463
+
464
+ async def delete_subscription(
465
+ self,
466
+ agent_id: str,
467
+ subscription_id: str,
468
+ request_options: RequestOptions | None = None,
469
+ ) -> None:
470
+ """Delete a feed subscription from an agent.
471
+
472
+ Args:
473
+ agent_id: Unique identifier of the agent.
474
+ subscription_id: Unique identifier of the subscription to delete.
475
+
476
+ Returns:
477
+ None (the API returns 204 No Content on success).
478
+
479
+ Raises:
480
+ NotFoundError: If the agent or subscription does not exist.
481
+ Knowledge2Error: If the API request fails.
482
+ """
483
+ agent_id = require_str(agent_id, "agent_id")
484
+ subscription_id = require_str(subscription_id, "subscription_id")
485
+ await self._request(
486
+ "DELETE",
487
+ f"/v1/agents/{agent_id}/subscriptions/{subscription_id}",
488
+ request_options=request_options,
489
+ )
@@ -0,0 +1,145 @@
1
+ """Async audit-log resource mixin for the Knowledge2 SDK."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from sdk._async_paging import AsyncPager
8
+ from sdk._paging import Page
9
+ from sdk._request_options import RequestOptions
10
+ from sdk.async_resources._mixin_base import AsyncRequesterMixin
11
+ from sdk.types import AuditLogActionsResponse
12
+
13
+
14
+ class AsyncAuditMixin(AsyncRequesterMixin):
15
+ async def list_audit_logs(
16
+ self,
17
+ *,
18
+ corpus_id: str | None = None,
19
+ project_id: str | None = None,
20
+ action: str | None = None,
21
+ entity_type: str | None = None,
22
+ since: str | None = None,
23
+ until: str | None = None,
24
+ user_id: str | None = None,
25
+ limit: int = 100,
26
+ offset: int = 0,
27
+ request_options: RequestOptions | None = None,
28
+ ) -> Page[dict[str, Any]]:
29
+ """List audit log entries with optional filters.
30
+
31
+ Args:
32
+ corpus_id: Filter logs to a specific corpus.
33
+ project_id: Filter logs to a specific project.
34
+ action: Filter logs by action type.
35
+ entity_type: Filter logs by entity type.
36
+ since: Filter logs created on or after this ISO 8601 timestamp.
37
+ until: Filter logs created before this ISO 8601 timestamp.
38
+ user_id: Filter logs by the acting user.
39
+ limit: Maximum number of entries to return per page.
40
+ offset: Number of entries to skip for pagination.
41
+
42
+ Returns:
43
+ A Page containing audit log entries with pagination metadata.
44
+
45
+ Raises:
46
+ Knowledge2Error: If the API request fails.
47
+ """
48
+ params: dict[str, Any] = {}
49
+ if corpus_id:
50
+ params["corpus_id"] = corpus_id
51
+ if project_id:
52
+ params["project_id"] = project_id
53
+ if action:
54
+ params["action"] = action
55
+ if entity_type:
56
+ params["entity_type"] = entity_type
57
+ if since:
58
+ params["since"] = since
59
+ if until:
60
+ params["until"] = until
61
+ if user_id:
62
+ params["user_id"] = user_id
63
+ return await self._list_page(
64
+ "GET",
65
+ "/v1/audit-logs",
66
+ items_key="logs",
67
+ params=params or None,
68
+ limit=limit,
69
+ offset=offset,
70
+ )
71
+
72
+ def iter_audit_logs(
73
+ self,
74
+ *,
75
+ corpus_id: str | None = None,
76
+ project_id: str | None = None,
77
+ action: str | None = None,
78
+ entity_type: str | None = None,
79
+ since: str | None = None,
80
+ until: str | None = None,
81
+ user_id: str | None = None,
82
+ limit: int = 100,
83
+ request_options: RequestOptions | None = None,
84
+ ) -> AsyncPager[dict[str, Any]]:
85
+ """Iterate over audit logs, automatically paginating.
86
+
87
+ Args:
88
+ corpus_id: Filter logs to a specific corpus.
89
+ project_id: Filter logs to a specific project.
90
+ action: Filter logs by action type.
91
+ entity_type: Filter logs by entity type.
92
+ since: Filter logs created on or after this ISO 8601 timestamp.
93
+ until: Filter logs created before this ISO 8601 timestamp.
94
+ user_id: Filter logs by the acting user.
95
+ limit: Page size used for each underlying API request.
96
+
97
+ Yields:
98
+ Individual audit log entry dicts.
99
+
100
+ Raises:
101
+ Knowledge2Error: If any underlying API request fails.
102
+ """
103
+ params: dict[str, Any] = {}
104
+ if corpus_id:
105
+ params["corpus_id"] = corpus_id
106
+ if project_id:
107
+ params["project_id"] = project_id
108
+ if action:
109
+ params["action"] = action
110
+ if entity_type:
111
+ params["entity_type"] = entity_type
112
+ if since:
113
+ params["since"] = since
114
+ if until:
115
+ params["until"] = until
116
+ if user_id:
117
+ params["user_id"] = user_id
118
+ return self._paginate(
119
+ "GET", "/v1/audit-logs", items_key="logs", params=params or None, limit=limit
120
+ )
121
+
122
+ async def list_audit_actions(
123
+ self,
124
+ *,
125
+ user_id: str | None = None,
126
+ request_options: RequestOptions | None = None,
127
+ ) -> AuditLogActionsResponse:
128
+ """List distinct audit action types that have occurred in the organization.
129
+
130
+ Args:
131
+ user_id: Filter actions to those performed by a specific user.
132
+
133
+ Returns:
134
+ An object containing the list of distinct action type strings.
135
+
136
+ Raises:
137
+ Knowledge2Error: If the API request fails.
138
+ """
139
+ params: dict[str, Any] = {}
140
+ if user_id:
141
+ params["user_id"] = user_id
142
+ data = await self._request(
143
+ "GET", "/v1/audit-logs/actions", params=params or None, request_options=request_options
144
+ )
145
+ return self._maybe_validate(data, "AuditLogActionsResponse")