latitude-sdk 2.0.2__py3-none-any.whl → 2.1.1__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.
@@ -1,5 +1,5 @@
1
1
  import asyncio
2
- from typing import Any, AsyncGenerator, List, Optional, Sequence, Union
2
+ from typing import Any, AsyncGenerator, List, Optional, Sequence, Tuple, Union
3
3
 
4
4
  from promptl_ai import Adapter, Message, MessageLike, Promptl, ToolMessage, ToolResultContent
5
5
  from promptl_ai.bindings.types import _Message
@@ -19,6 +19,7 @@ from latitude_sdk.client import (
19
19
  )
20
20
  from latitude_sdk.sdk.errors import ApiError, ApiErrorCodes
21
21
  from latitude_sdk.sdk.types import (
22
+ AGENT_END_TOOL_NAME,
22
23
  ChainEvents,
23
24
  FinishedResult,
24
25
  OnStep,
@@ -29,7 +30,6 @@ from latitude_sdk.sdk.types import (
29
30
  SdkOptions,
30
31
  StreamCallbacks,
31
32
  StreamEvents,
32
- StreamTypes,
33
33
  ToolCall,
34
34
  ToolResult,
35
35
  _LatitudeEvent,
@@ -110,7 +110,7 @@ class RenderPromptOptions(Model):
110
110
 
111
111
 
112
112
  class RenderPromptResult(Model):
113
- messages: list[MessageLike]
113
+ messages: List[MessageLike]
114
114
  config: dict[str, Any]
115
115
 
116
116
 
@@ -142,13 +142,28 @@ class Prompts:
142
142
  response="Project ID is required",
143
143
  )
144
144
 
145
+ async def _extract_agent_tool_requests(
146
+ self, tool_requests: List[ToolCall]
147
+ ) -> Tuple[List[ToolCall], List[ToolCall]]:
148
+ agent: List[ToolCall] = []
149
+ other: List[ToolCall] = []
150
+
151
+ for tool in tool_requests:
152
+ if tool.name == AGENT_END_TOOL_NAME:
153
+ agent.append(tool)
154
+ else:
155
+ other.append(tool)
156
+
157
+ return agent, other
158
+
145
159
  async def _handle_stream(
146
160
  self, stream: AsyncGenerator[ClientEvent, Any], on_event: Optional[StreamCallbacks.OnEvent]
147
161
  ) -> FinishedResult:
148
162
  uuid = None
149
- conversation: list[Message] = []
163
+ conversation: List[Message] = []
150
164
  response = None
151
- tool_requests: list[ToolCall] = []
165
+ agent_response = None
166
+ tool_requests: List[ToolCall] = []
152
167
 
153
168
  async for stream_event in stream:
154
169
  event = None
@@ -195,7 +210,17 @@ class Prompts:
195
210
  response="Stream ended without a chain-complete event. Missing uuid or response.",
196
211
  )
197
212
 
198
- return FinishedResult(uuid=uuid, conversation=conversation, response=response, tool_requests=tool_requests)
213
+ agent_requests, tool_requests = await self._extract_agent_tool_requests(tool_requests)
214
+ if len(agent_requests) > 0:
215
+ agent_response = agent_requests[0].arguments
216
+
217
+ return FinishedResult(
218
+ uuid=uuid,
219
+ conversation=conversation,
220
+ response=response,
221
+ agent_response=agent_response,
222
+ tool_requests=tool_requests,
223
+ )
199
224
 
200
225
  @staticmethod
201
226
  def _pause_tool_execution() -> Any:
@@ -220,9 +245,6 @@ class Prompts:
220
245
  async def _handle_tool_calls(
221
246
  self, result: FinishedResult, options: Union[RunPromptOptions, ChatPromptOptions]
222
247
  ) -> Optional[FinishedResult]:
223
- # Seems Python cannot infer the type
224
- assert result.response.type == StreamTypes.Text and result.tool_requests is not None
225
-
226
248
  if not options.tools:
227
249
  raise ApiError(
228
250
  status=400,
@@ -350,7 +372,7 @@ class Prompts:
350
372
  else:
351
373
  result = RunPromptResult.model_validate_json(response.content)
352
374
 
353
- if options.tools and result.response.type == StreamTypes.Text and result.tool_requests:
375
+ if options.tools and result.tool_requests:
354
376
  try:
355
377
  # NOTE: The last sdk.chat called will already call on_finished
356
378
  final_result = await self._handle_tool_calls(result, options)
@@ -402,7 +424,7 @@ class Prompts:
402
424
  else:
403
425
  result = ChatPromptResult.model_validate_json(response.content)
404
426
 
405
- if options.tools and result.response.type == StreamTypes.Text and result.tool_requests:
427
+ if options.tools and result.tool_requests:
406
428
  try:
407
429
  # NOTE: The last sdk.chat called will already call on_finished
408
430
  final_result = await self._handle_tool_calls(result, options)
latitude_sdk/sdk/types.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from datetime import datetime
2
- from typing import Any, Callable, Literal, Optional, Protocol, Sequence, Union, runtime_checkable
2
+ from typing import Any, Callable, List, Literal, Optional, Protocol, Sequence, Union, runtime_checkable
3
3
 
4
4
  from promptl_ai import Message, MessageLike
5
5
 
@@ -59,6 +59,10 @@ class FinishReason(StrEnum):
59
59
  Unknown = "unknown"
60
60
 
61
61
 
62
+ AGENT_START_TOOL_NAME = "start_autonomous_chain"
63
+ AGENT_END_TOOL_NAME = "end_autonomous_chain"
64
+
65
+
62
66
  class ToolCall(Model):
63
67
  id: str
64
68
  name: str
@@ -80,7 +84,7 @@ class StreamTypes(StrEnum):
80
84
  class ChainTextResponse(Model):
81
85
  type: Literal[StreamTypes.Text] = Field(default=StreamTypes.Text, alias=str("streamType"))
82
86
  text: str
83
- tool_calls: list[ToolCall] = Field(alias=str("toolCalls"))
87
+ tool_calls: List[ToolCall] = Field(alias=str("toolCalls"))
84
88
  usage: ModelUsage
85
89
 
86
90
 
@@ -122,7 +126,7 @@ class ChainEvents(StrEnum):
122
126
 
123
127
  class GenericChainEvent(Model):
124
128
  event: Literal[StreamEvents.Latitude] = StreamEvents.Latitude
125
- messages: list[Message]
129
+ messages: List[Message]
126
130
  uuid: str
127
131
 
128
132
 
@@ -149,7 +153,7 @@ class ChainEventProviderCompleted(GenericChainEvent):
149
153
 
150
154
  class ChainEventToolsStarted(GenericChainEvent):
151
155
  type: Literal[ChainEvents.ToolsStarted] = ChainEvents.ToolsStarted
152
- tools: list[ToolCall]
156
+ tools: List[ToolCall]
153
157
 
154
158
 
155
159
  class ChainEventToolCompleted(GenericChainEvent):
@@ -173,7 +177,7 @@ class ChainEventChainError(GenericChainEvent):
173
177
 
174
178
  class ChainEventToolsRequested(GenericChainEvent):
175
179
  type: Literal[ChainEvents.ToolsRequested] = ChainEvents.ToolsRequested
176
- tools: list[ToolCall]
180
+ tools: List[ToolCall]
177
181
 
178
182
 
179
183
  ChainEvent = Union[
@@ -195,9 +199,10 @@ _LatitudeEvent = Adapter[LatitudeEvent](LatitudeEvent)
195
199
 
196
200
  class FinishedResult(Model):
197
201
  uuid: str
198
- conversation: list[Message]
202
+ conversation: List[Message]
199
203
  response: ChainResponse
200
- tool_requests: list[ToolCall] = Field(alias=str("toolRequests"))
204
+ agent_response: Optional[dict[str, Any]] = Field(default=None, alias=str("agentResponse"))
205
+ tool_requests: List[ToolCall] = Field(alias=str("toolRequests"))
201
206
 
202
207
 
203
208
  StreamEvent = Union[ProviderEvent, LatitudeEvent]
@@ -271,9 +276,9 @@ class OnToolCallDetails(Model):
271
276
  id: str
272
277
  name: str
273
278
  conversation_uuid: str
274
- messages: list[Message]
279
+ messages: List[Message]
275
280
  pause_execution: Callable[[], ToolResult]
276
- requested_tool_calls: list[ToolCall]
281
+ requested_tool_calls: List[ToolCall]
277
282
 
278
283
 
279
284
  @runtime_checkable
@@ -284,7 +289,7 @@ class OnToolCall(Protocol):
284
289
  @runtime_checkable
285
290
  class OnStep(Protocol):
286
291
  async def __call__(
287
- self, messages: list[MessageLike], config: dict[str, Any]
292
+ self, messages: List[MessageLike], config: dict[str, Any]
288
293
  ) -> Union[str, MessageLike, Sequence[MessageLike]]: ...
289
294
 
290
295
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: latitude-sdk
3
- Version: 2.0.2
3
+ Version: 2.1.1
4
4
  Summary: Latitude SDK for Python
5
5
  Project-URL: repository, https://github.com/latitude-dev/latitude-llm/tree/main/packages/sdks/python
6
6
  Project-URL: homepage, https://github.com/latitude-dev/latitude-llm/tree/main/packages/sdks/python#readme
@@ -11,7 +11,7 @@ License-Expression: LGPL-3.0
11
11
  Requires-Python: <3.13,>=3.9
12
12
  Requires-Dist: httpx-sse>=0.4.0
13
13
  Requires-Dist: httpx>=0.28.1
14
- Requires-Dist: promptl-ai>=1.0.5
14
+ Requires-Dist: promptl-ai>=1.0.6
15
15
  Requires-Dist: pydantic>=2.10.3
16
16
  Requires-Dist: typing-extensions>=4.12.2
17
17
  Description-Content-Type: text/markdown
@@ -11,10 +11,10 @@ latitude_sdk/sdk/errors.py,sha256=9GlGdDE8LGy3dE2Ry_BipBg-tDbQx7LWXJfSnTJSSBE,17
11
11
  latitude_sdk/sdk/evaluations.py,sha256=fDGtAWjdPG9OuKLit6u-jufVleC1EnshRplK6RN8iyg,2277
12
12
  latitude_sdk/sdk/latitude.py,sha256=UpWHxZlaa7vYIiy35Lv12FpjeYqj5EtO8LWO_upxF9c,2626
13
13
  latitude_sdk/sdk/logs.py,sha256=CyHkRJvPl_p7wTSvR9bgxEI5akS0Tjc9FeQRb2C2vMg,1997
14
- latitude_sdk/sdk/prompts.py,sha256=VaBZr58aQtREWFlpZnKD8tWRFgGwy8Q7TP0fLUElC48,16853
15
- latitude_sdk/sdk/types.py,sha256=_VMTl2BEpdIfKLZexKGALzd6ml4ayYQf6_yly088BXo,8371
14
+ latitude_sdk/sdk/prompts.py,sha256=WztCpDSt0mxng0N2hyIrrzEw1TanqGRIl7Cpc_5ei4M,17369
15
+ latitude_sdk/sdk/types.py,sha256=wGxwFEzHWShy6a2eGUt4NwRkKP_snvSrlH0rYwNYdgY,8568
16
16
  latitude_sdk/util/__init__.py,sha256=alIDGBnxWH4JvP-UW-7N99seBBi0r1GV1h8f1ERFBec,21
17
17
  latitude_sdk/util/utils.py,sha256=hMOmF-u1QaDgOwXN6ME6n4TaQ70yZKLvijDUqNCMwXI,2844
18
- latitude_sdk-2.0.2.dist-info/METADATA,sha256=lZrHjAbB6o4BXa2g3H4whmTgahly2Fwa93kWukaQ3J0,2327
19
- latitude_sdk-2.0.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
20
- latitude_sdk-2.0.2.dist-info/RECORD,,
18
+ latitude_sdk-2.1.1.dist-info/METADATA,sha256=HhWee4Iq9Uys8Xnk2vAxaGLbTUUc5aPgdwl4DtIhIi8,2327
19
+ latitude_sdk-2.1.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
20
+ latitude_sdk-2.1.1.dist-info/RECORD,,