seekrai 0.5.14__tar.gz → 0.5.16__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 (75) hide show
  1. {seekrai-0.5.14 → seekrai-0.5.16}/PKG-INFO +1 -1
  2. {seekrai-0.5.14 → seekrai-0.5.16}/pyproject.toml +1 -1
  3. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/client.py +4 -0
  4. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/__init__.py +9 -1
  5. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/agents/__init__.py +6 -0
  6. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/agents/agent_inference.py +12 -0
  7. seekrai-0.5.16/src/seekrai/resources/agents/agent_observability.py +135 -0
  8. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/agents/python_functions.py +21 -56
  9. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/models.py +0 -1
  10. seekrai-0.5.16/src/seekrai/types/agents/observability.py +34 -0
  11. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/agents/runs.py +3 -0
  12. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/finetune.py +2 -0
  13. {seekrai-0.5.14 → seekrai-0.5.16}/LICENSE +0 -0
  14. {seekrai-0.5.14 → seekrai-0.5.16}/README.md +0 -0
  15. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/__init__.py +0 -0
  16. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/abstract/__init__.py +0 -0
  17. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/abstract/api_requestor.py +0 -0
  18. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/abstract/response_parsing.py +0 -0
  19. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/constants.py +0 -0
  20. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/error.py +0 -0
  21. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/filemanager.py +0 -0
  22. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/agents/agents.py +0 -0
  23. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/agents/threads.py +0 -0
  24. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/alignment.py +0 -0
  25. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/chat/__init__.py +0 -0
  26. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/chat/completions.py +0 -0
  27. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/completions.py +0 -0
  28. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/deployments.py +0 -0
  29. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/embeddings.py +0 -0
  30. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/explainability.py +0 -0
  31. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/files.py +0 -0
  32. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/finetune.py +0 -0
  33. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/images.py +0 -0
  34. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/ingestion.py +0 -0
  35. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/projects.py +0 -0
  36. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/resource_base.py +0 -0
  37. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/resources/vectordb.py +0 -0
  38. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/seekrflow_response.py +0 -0
  39. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/__init__.py +0 -0
  40. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/abstract.py +0 -0
  41. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/agents/__init__.py +0 -0
  42. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/agents/agent.py +0 -0
  43. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/agents/python_functions.py +0 -0
  44. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/agents/threads.py +0 -0
  45. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/agents/tools/__init__.py +0 -0
  46. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/agents/tools/env_model_config.py +0 -0
  47. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/agents/tools/schemas/__init__.py +0 -0
  48. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/agents/tools/schemas/file_search.py +0 -0
  49. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/agents/tools/schemas/file_search_env.py +0 -0
  50. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/agents/tools/schemas/run_python.py +0 -0
  51. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/agents/tools/schemas/run_python_env.py +0 -0
  52. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/agents/tools/schemas/web_search.py +0 -0
  53. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/agents/tools/schemas/web_search_env.py +0 -0
  54. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/agents/tools/tool.py +0 -0
  55. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/agents/tools/tool_types.py +0 -0
  56. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/alignment.py +0 -0
  57. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/chat_completions.py +0 -0
  58. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/common.py +0 -0
  59. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/completions.py +0 -0
  60. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/deployments.py +0 -0
  61. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/embeddings.py +0 -0
  62. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/error.py +0 -0
  63. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/explainability.py +0 -0
  64. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/files.py +0 -0
  65. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/images.py +0 -0
  66. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/ingestion.py +0 -0
  67. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/models.py +0 -0
  68. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/projects.py +0 -0
  69. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/types/vectordb.py +0 -0
  70. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/utils/__init__.py +0 -0
  71. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/utils/_log.py +0 -0
  72. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/utils/api_helpers.py +0 -0
  73. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/utils/files.py +0 -0
  74. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/utils/tools.py +0 -0
  75. {seekrai-0.5.14 → seekrai-0.5.16}/src/seekrai/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: seekrai
3
- Version: 0.5.14
3
+ Version: 0.5.16
4
4
  Summary: Python client for SeekrAI
5
5
  License: Apache-2.0
6
6
  Author: SeekrFlow
@@ -14,7 +14,7 @@ build-backend = "poetry.core.masonry.api"
14
14
 
15
15
  [tool.poetry]
16
16
  name = "seekrai"
17
- version = "0.5.14"
17
+ version = "0.5.16"
18
18
  authors = [
19
19
  "SeekrFlow <support@seekr.com>"
20
20
  ]
@@ -24,6 +24,7 @@ class SeekrFlow:
24
24
  deployments: resources.Deployments
25
25
  vector_database: resources.VectorDatabase
26
26
  agents: resources.Agents
27
+ observability: resources.AgentObservability
27
28
 
28
29
  # client options
29
30
  client: SeekrFlowClient
@@ -89,6 +90,7 @@ class SeekrFlow:
89
90
  self.deployments = resources.Deployments(self.client)
90
91
  self.vector_database = resources.VectorDatabase(self.client)
91
92
  self.agents = resources.Agents(self.client)
93
+ self.observability = resources.AgentObservability(self.client)
92
94
 
93
95
 
94
96
  class AsyncSeekrFlow:
@@ -105,6 +107,7 @@ class AsyncSeekrFlow:
105
107
  deployments: resources.AsyncDeployments
106
108
  vector_database: resources.AsyncVectorDatabase
107
109
  agents: resources.AsyncAgents
110
+ observability: resources.AsyncAgentObservability
108
111
 
109
112
  # client options
110
113
  client: SeekrFlowClient
@@ -170,6 +173,7 @@ class AsyncSeekrFlow:
170
173
  self.deployments = resources.AsyncDeployments(self.client)
171
174
  self.vector_database = resources.AsyncVectorDatabase(self.client)
172
175
  self.agents = resources.AsyncAgents(self.client)
176
+ self.observability = resources.AsyncAgentObservability(self.client)
173
177
 
174
178
 
175
179
  Client = SeekrFlow
@@ -1,4 +1,10 @@
1
- from seekrai.resources.agents import AgentInference, Agents, AsyncAgents
1
+ from seekrai.resources.agents import (
2
+ AgentInference,
3
+ AgentObservability,
4
+ Agents,
5
+ AsyncAgentObservability,
6
+ AsyncAgents,
7
+ )
2
8
  from seekrai.resources.alignment import Alignment, AsyncAlignment
3
9
  from seekrai.resources.chat import AsyncChat, Chat
4
10
  from seekrai.resources.completions import AsyncCompletions, Completions
@@ -39,6 +45,8 @@ __all__ = [
39
45
  "Deployments",
40
46
  "AsyncAgents",
41
47
  "Agents",
48
+ "AgentObservability",
49
+ "AsyncAgentObservability",
42
50
  "VectorDatabase",
43
51
  "AsyncVectorDatabase",
44
52
  "AgentInference",
@@ -1,4 +1,8 @@
1
1
  from seekrai.resources.agents.agent_inference import AgentInference, AsyncAgentInference
2
+ from seekrai.resources.agents.agent_observability import (
3
+ AgentObservability,
4
+ AsyncAgentObservability,
5
+ )
2
6
  from seekrai.resources.agents.agents import Agents, AsyncAgents
3
7
  from seekrai.resources.agents.python_functions import (
4
8
  AsyncCustomFunctions,
@@ -16,4 +20,6 @@ __all__ = [
16
20
  "AsyncAgentThreads",
17
21
  "CustomFunctions",
18
22
  "AsyncCustomFunctions",
23
+ "AgentObservability",
24
+ "AsyncAgentObservability",
19
25
  ]
@@ -19,6 +19,8 @@ class AgentInference:
19
19
  stream: bool = False,
20
20
  model_settings: ModelSettings = ModelSettings(),
21
21
  response_format: Optional[Any] = None,
22
+ group: Optional[str] = "default_group",
23
+ metadata: Optional[dict[str, str]] = None,
22
24
  ) -> Union[RunResponse, Iterator[Any]]:
23
25
  """
24
26
  Run an inference call on a deployed agent.
@@ -29,6 +31,8 @@ class AgentInference:
29
31
  stream (bool, optional): Whether to stream the response. Defaults to False.
30
32
  model_settings (optional): Additional parameters (such as temperature, max_tokens, etc).
31
33
  response_format: Optional structured output specification. If provided, the LLM will be constrained to return JSON matching this schema.
34
+ group (str, optional): Label used to associate a group of runs. Defaults to 'default_group'.
35
+ metadata (dict[str, str], optional): Additional metadata used to label runs. Defaults to None.
32
36
 
33
37
  Returns:
34
38
  A dictionary with the response (if non-streaming) or an iterator over response chunks.
@@ -39,6 +43,8 @@ class AgentInference:
39
43
  response_format=ResponseFormat.from_value(response_format)
40
44
  if response_format
41
45
  else None,
46
+ group=group,
47
+ metadata=metadata,
42
48
  ).model_dump()
43
49
  endpoint = f"threads/{thread_id}/runs"
44
50
  if stream:
@@ -156,6 +162,8 @@ class AsyncAgentInference:
156
162
  stream: bool = False,
157
163
  model_settings: ModelSettings = ModelSettings(),
158
164
  response_format: Optional[Any] = None,
165
+ group: Optional[str] = "default_group",
166
+ metadata: Optional[dict[str, str]] = None,
159
167
  ) -> Union[RunResponse, AsyncGenerator[Any, None]]:
160
168
  """
161
169
  Run an inference call on a deployed agent.
@@ -166,6 +174,8 @@ class AsyncAgentInference:
166
174
  stream (bool, optional): Whether to stream the response. Defaults to False.
167
175
  model_settings (optional): Additional parameters (such as temperature, max_tokens, etc).
168
176
  response_format: Optional structured output specification. If provided, the LLM will be constrained to return JSON matching this schema.
177
+ group (str, optional): Label used to associate a group of runs. Defaults to 'default_group'.
178
+ metadata (dict[str, str], optional): Additional metadata used to label runs. Defaults to None.
169
179
 
170
180
  Returns:
171
181
  A dictionary with the response (if non-streaming) or an iterator over response chunks.
@@ -176,6 +186,8 @@ class AsyncAgentInference:
176
186
  response_format=ResponseFormat.from_value(response_format)
177
187
  if response_format
178
188
  else None,
189
+ group=group,
190
+ metadata=metadata,
179
191
  ).model_dump()
180
192
  endpoint = f"threads/{thread_id}/runs"
181
193
  if stream:
@@ -0,0 +1,135 @@
1
+ from datetime import datetime
2
+ from typing import Any, Optional
3
+
4
+ from seekrai.abstract import api_requestor
5
+ from seekrai.seekrflow_response import SeekrFlowResponse
6
+ from seekrai.types import SeekrFlowRequest
7
+ from seekrai.types.agents.observability import (
8
+ ObservabilitySpansRequest,
9
+ ObservabilitySpansResponse,
10
+ )
11
+
12
+
13
+ BASE_OBSERVABILITY_ENDPOINT = "observability/spans"
14
+
15
+
16
+ class AgentObservability:
17
+ def __init__(self, client: Any):
18
+ self._client = client
19
+ self._requestor = api_requestor.APIRequestor(client=self._client)
20
+
21
+ def query_spans(
22
+ self,
23
+ min_start_time: Optional[datetime] = None,
24
+ max_start_time: Optional[datetime] = None,
25
+ agent_id: Optional[str] = None,
26
+ run_id: Optional[str] = None,
27
+ trace_id: Optional[str] = None,
28
+ thread_id: Optional[str] = None,
29
+ group: Optional[str] = None,
30
+ metadata: Optional[dict[str, str]] = None,
31
+ limit: int = 100,
32
+ order: str = "desc",
33
+ offset: int = 0,
34
+ ) -> ObservabilitySpansResponse:
35
+ """
36
+ Retrieve spans for a given run or group of runs given a set of facets.
37
+ """
38
+ payload = ObservabilitySpansRequest(
39
+ min_start_datetime=min_start_time,
40
+ max_start_datetime=max_start_time,
41
+ agent_id=agent_id,
42
+ run_id=run_id,
43
+ trace_id=trace_id,
44
+ thread_id=thread_id,
45
+ group=group,
46
+ metadata=metadata,
47
+ limit=limit,
48
+ order=order,
49
+ offset=offset,
50
+ ).model_dump()
51
+
52
+ response, _, _ = self._requestor.request(
53
+ options=SeekrFlowRequest(
54
+ method="POST", url=BASE_OBSERVABILITY_ENDPOINT, params=payload
55
+ )
56
+ )
57
+
58
+ assert isinstance(response, SeekrFlowResponse)
59
+
60
+ return ObservabilitySpansResponse(spans=response.data)
61
+
62
+ def retrieve_span(self, span_id: str) -> Optional[dict[str, Any]]:
63
+ """
64
+ Retrieve a specific span given a span_id.
65
+ """
66
+ endpoint = f"{BASE_OBSERVABILITY_ENDPOINT}/{span_id}"
67
+
68
+ response, _, _ = self._requestor.request(
69
+ options=SeekrFlowRequest(method="GET", url=endpoint)
70
+ )
71
+
72
+ assert isinstance(response, SeekrFlowResponse)
73
+
74
+ return response.data
75
+
76
+
77
+ class AsyncAgentObservability:
78
+ def __init__(self, client: Any) -> None:
79
+ self._client = client
80
+ self._requestor = api_requestor.APIRequestor(client=self._client)
81
+
82
+ async def query_spans(
83
+ self,
84
+ min_start_time: Optional[datetime] = None,
85
+ max_start_time: Optional[datetime] = None,
86
+ agent_id: Optional[str] = None,
87
+ run_id: Optional[str] = None,
88
+ trace_id: Optional[str] = None,
89
+ thread_id: Optional[str] = None,
90
+ group: Optional[str] = None,
91
+ metadata: Optional[dict[str, str]] = None,
92
+ limit: int = 100,
93
+ order: str = "desc",
94
+ offset: int = 0,
95
+ ) -> ObservabilitySpansResponse:
96
+ """
97
+ Retrieve spans for a given run or group of runs given a set of facets.
98
+ """
99
+ payload = ObservabilitySpansRequest(
100
+ min_start_datetime=min_start_time,
101
+ max_start_datetime=max_start_time,
102
+ agent_id=agent_id,
103
+ run_id=run_id,
104
+ trace_id=trace_id,
105
+ thread_id=thread_id,
106
+ group=group,
107
+ metadata=metadata,
108
+ limit=limit,
109
+ order=order,
110
+ offset=offset,
111
+ ).model_dump()
112
+
113
+ response, _, _ = await self._requestor.arequest(
114
+ options=SeekrFlowRequest(
115
+ method="POST", url=BASE_OBSERVABILITY_ENDPOINT, params=payload
116
+ )
117
+ )
118
+
119
+ assert isinstance(response, SeekrFlowResponse)
120
+
121
+ return ObservabilitySpansResponse(spans=response.data)
122
+
123
+ async def retrieve_span(self, span_id: str) -> Optional[dict[str, Any]]:
124
+ """
125
+ Retrieve a specific span given a span_id.
126
+ """
127
+ endpoint = f"{BASE_OBSERVABILITY_ENDPOINT}/{span_id}"
128
+
129
+ response, _, _ = self._requestor.request(
130
+ options=SeekrFlowRequest(method="GET", url=endpoint)
131
+ )
132
+
133
+ assert isinstance(response, SeekrFlowResponse)
134
+
135
+ return response.data
@@ -17,15 +17,12 @@ class CustomFunctions:
17
17
  client=self._client,
18
18
  )
19
19
 
20
- def create(
21
- self, file_path: Union[str, Path], description: Union[str, None] = None
22
- ) -> PythonFunctionResponse:
20
+ def create(self, file_path: Union[str, Path]) -> PythonFunctionResponse:
23
21
  """
24
22
  Upload a new Python function for the user.
25
23
 
26
24
  Args:
27
25
  file_path: Path to the Python function file to upload (can be relative or absolute).
28
- description: Optional description for the function.
29
26
 
30
27
  Returns:
31
28
  The newly created Python function.
@@ -40,16 +37,12 @@ class CustomFunctions:
40
37
 
41
38
  # Prepare multipart form data
42
39
  files = {"file": (file_path.name, file_content, "text/plain")}
43
- params = {}
44
- if description:
45
- params["description"] = description
46
40
 
47
41
  response, _, _ = self._requestor.request(
48
42
  options=SeekrFlowRequest(
49
43
  method="POST",
50
44
  url="functions/",
51
45
  files=files,
52
- params=params,
53
46
  ),
54
47
  )
55
48
 
@@ -103,10 +96,7 @@ class CustomFunctions:
103
96
  return functions
104
97
 
105
98
  def update(
106
- self,
107
- function_id: str,
108
- file_path: Union[str, Path, None] = None,
109
- description: Union[str, None] = None,
99
+ self, function_id: str, file_path: Union[str, Path]
110
100
  ) -> PythonFunctionResponse:
111
101
  """
112
102
  Update an existing Python function.
@@ -119,30 +109,22 @@ class CustomFunctions:
119
109
  Returns:
120
110
  The updated Python function.
121
111
  """
122
- files = None
123
- params = {}
124
-
125
- if file_path:
126
- # Convert string to Path if needed
127
- if isinstance(file_path, str):
128
- file_path = Path(file_path)
129
-
130
- # Read the file contents
131
- with file_path.open("rb") as f:
132
- file_content = f.read()
112
+ # Convert string to Path if needed
113
+ if isinstance(file_path, str):
114
+ file_path = Path(file_path)
133
115
 
134
- # Prepare multipart form data
135
- files = {"file": (file_path.name, file_content, "text/plain")}
116
+ # Read the file contents
117
+ with file_path.open("rb") as f:
118
+ file_content = f.read()
136
119
 
137
- if description:
138
- params["description"] = description
120
+ # Prepare multipart form data
121
+ files = {"file": (file_path.name, file_content, "text/plain")}
139
122
 
140
123
  response, _, _ = self._requestor.request(
141
124
  options=SeekrFlowRequest(
142
125
  method="PATCH",
143
126
  url=f"functions/{function_id}",
144
127
  files=files,
145
- params=params,
146
128
  ),
147
129
  )
148
130
 
@@ -177,15 +159,12 @@ class AsyncCustomFunctions:
177
159
  client=self._client,
178
160
  )
179
161
 
180
- async def create(
181
- self, file_path: Union[str, Path], description: Union[str, None] = None
182
- ) -> PythonFunctionResponse:
162
+ async def create(self, file_path: Union[str, Path]) -> PythonFunctionResponse:
183
163
  """
184
164
  Upload a new Python function for the user.
185
165
 
186
166
  Args:
187
167
  file_path: Path to the Python function file to upload (can be relative or absolute).
188
- description: Optional description for the function.
189
168
 
190
169
  Returns:
191
170
  The newly created Python function.
@@ -200,16 +179,12 @@ class AsyncCustomFunctions:
200
179
 
201
180
  # Prepare multipart form data
202
181
  files = {"file": (file_path.name, file_content, "text/plain")}
203
- params = {}
204
- if description:
205
- params["description"] = description
206
182
 
207
183
  response, _, _ = await self._requestor.arequest(
208
184
  options=SeekrFlowRequest(
209
185
  method="POST",
210
186
  url="functions/",
211
187
  files=files,
212
- params=params,
213
188
  ),
214
189
  )
215
190
 
@@ -265,44 +240,34 @@ class AsyncCustomFunctions:
265
240
  async def update(
266
241
  self,
267
242
  function_id: str,
268
- file_path: Union[str, Path, None] = None,
269
- description: Union[str, None] = None,
243
+ file_path: Union[str, Path],
270
244
  ) -> PythonFunctionResponse:
271
245
  """
272
246
  Update an existing Python function.
273
247
 
274
248
  Args:
275
249
  function_id: The ID of the Python function to update.
276
- file_path: Optional path to a new Python function file (can be relative or absolute).
277
- description: Optional new description for the function.
250
+ file_path: Path to a new Python function file (can be relative or absolute).
278
251
 
279
252
  Returns:
280
253
  The updated Python function.
281
254
  """
282
- files = None
283
- params = {}
284
-
285
- if file_path:
286
- # Convert string to Path if needed
287
- if isinstance(file_path, str):
288
- file_path = Path(file_path)
289
-
290
- # Read the file contents
291
- with file_path.open("rb") as f:
292
- file_content = f.read()
255
+ # Convert string to Path if needed
256
+ if isinstance(file_path, str):
257
+ file_path = Path(file_path)
293
258
 
294
- # Prepare multipart form data
295
- files = {"file": (file_path.name, file_content, "text/plain")}
259
+ # Read the file contents
260
+ with file_path.open("rb") as f:
261
+ file_content = f.read()
296
262
 
297
- if description:
298
- params["description"] = description
263
+ # Prepare multipart form data
264
+ files = {"file": (file_path.name, file_content, "text/plain")}
299
265
 
300
266
  response, _, _ = await self._requestor.arequest(
301
267
  options=SeekrFlowRequest(
302
268
  method="PATCH",
303
269
  url=f"functions/{function_id}",
304
270
  files=files,
305
- params=params,
306
271
  ),
307
272
  )
308
273
 
@@ -5,7 +5,6 @@ from seekrai.resources.resource_base import ResourceBase
5
5
  from seekrai.seekrflow_response import SeekrFlowResponse
6
6
  from seekrai.types import ModelList, ModelResponse, SeekrFlowRequest
7
7
  from seekrai.types.common import ObjectType
8
- from seekrai.utils import parse_timestamp
9
8
 
10
9
 
11
10
  class Models(ResourceBase):
@@ -0,0 +1,34 @@
1
+ from datetime import datetime
2
+ from typing import Any, Dict, List, Optional
3
+
4
+ from pydantic import field_serializer
5
+
6
+ from seekrai.types.abstract import BaseModel
7
+
8
+
9
+ class ObservabilitySpansRequest(BaseModel):
10
+ """Request model for requesting observability spans."""
11
+
12
+ min_start_datetime: Optional[datetime]
13
+ max_start_datetime: Optional[datetime]
14
+ agent_id: Optional[str]
15
+ run_id: Optional[str]
16
+ trace_id: Optional[str]
17
+ thread_id: Optional[str]
18
+ group: Optional[str]
19
+ metadata: Optional[dict[str, str]]
20
+ limit: int = 100
21
+ order: str = "desc"
22
+ offset: int = 0
23
+
24
+ @field_serializer("min_start_datetime", "max_start_datetime")
25
+ def serialize_dt(self, dt: Optional[datetime], _info: Any) -> Optional[str]:
26
+ if dt is not None:
27
+ return dt.isoformat()
28
+ return None
29
+
30
+
31
+ class ObservabilitySpansResponse(BaseModel):
32
+ """Response model for requesting observability spans."""
33
+
34
+ spans: List[Dict[str, Any]]
@@ -58,6 +58,8 @@ class RunRequest(BaseModel):
58
58
  agent_id: str = Field(default="default_agent")
59
59
  model_settings: ModelSettings = ModelSettings()
60
60
  response_format: Optional[Union[ResponseFormat, Dict[str, Any], type]] = None
61
+ group: Optional[str] = None
62
+ metadata: Optional[Dict[str, str]] = None
61
63
 
62
64
 
63
65
  class RunResponse(BaseModel):
@@ -66,6 +68,7 @@ class RunResponse(BaseModel):
66
68
  run_id: str
67
69
  thread_id: str
68
70
  status: str
71
+ group: Optional[str] = None
69
72
 
70
73
 
71
74
  class RunStatus(str, Enum):
@@ -26,6 +26,7 @@ class FinetuneJobStatus(str, Enum):
26
26
  STATUS_CANCELLED = "cancelled"
27
27
  STATUS_FAILED = "failed"
28
28
  STATUS_COMPLETED = "completed"
29
+ STATUS_DELETED = "deleted"
29
30
 
30
31
 
31
32
  class FinetuneEventLevels(str, Enum):
@@ -182,6 +183,7 @@ class FinetuneResponse(BaseModel):
182
183
  experiment_name: str | None = None
183
184
  # job status
184
185
  status: FinetuneJobStatus | None = None
186
+ deleted_at: datetime | None = None
185
187
 
186
188
  # list of fine-tune events
187
189
  events: List[FinetuneEvent] | None = None
File without changes
File without changes
File without changes