latitude-sdk 0.1.0b9__py3-none-any.whl → 1.0.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.
- latitude_sdk/client/payloads.py +3 -1
- latitude_sdk/sdk/evaluations.py +3 -6
- latitude_sdk/sdk/latitude.py +7 -3
- latitude_sdk/sdk/logs.py +7 -9
- latitude_sdk/sdk/prompts.py +140 -29
- latitude_sdk/sdk/types.py +14 -84
- latitude_sdk/util/utils.py +8 -6
- {latitude_sdk-0.1.0b9.dist-info → latitude_sdk-1.0.1.dist-info}/METADATA +3 -2
- {latitude_sdk-0.1.0b9.dist-info → latitude_sdk-1.0.1.dist-info}/RECORD +10 -10
- {latitude_sdk-0.1.0b9.dist-info → latitude_sdk-1.0.1.dist-info}/WHEEL +0 -0
latitude_sdk/client/payloads.py
CHANGED
latitude_sdk/sdk/evaluations.py
CHANGED
@@ -8,10 +8,7 @@ from latitude_sdk.client import (
|
|
8
8
|
TriggerEvaluationRequestBody,
|
9
9
|
TriggerEvaluationRequestParams,
|
10
10
|
)
|
11
|
-
from latitude_sdk.sdk.types import
|
12
|
-
EvaluationResult,
|
13
|
-
SdkOptions,
|
14
|
-
)
|
11
|
+
from latitude_sdk.sdk.types import EvaluationResult, SdkOptions
|
15
12
|
from latitude_sdk.util import Model
|
16
13
|
|
17
14
|
|
@@ -40,8 +37,8 @@ class Evaluations:
|
|
40
37
|
self._options = options
|
41
38
|
self._client = client
|
42
39
|
|
43
|
-
async def trigger(self, uuid: str, options: TriggerEvaluationOptions) -> TriggerEvaluationResult:
|
44
|
-
options = TriggerEvaluationOptions(**{**dict(self._options), **dict(options)})
|
40
|
+
async def trigger(self, uuid: str, options: Optional[TriggerEvaluationOptions] = None) -> TriggerEvaluationResult:
|
41
|
+
options = TriggerEvaluationOptions(**{**dict(self._options), **dict(options or {})})
|
45
42
|
|
46
43
|
async with self._client.request(
|
47
44
|
handler=RequestHandler.TriggerEvaluation,
|
latitude_sdk/sdk/latitude.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Optional
|
2
2
|
|
3
3
|
from latitude_telemetry import Telemetry, TelemetryOptions
|
4
|
+
from promptl_ai import Promptl, PromptlOptions
|
4
5
|
|
5
6
|
from latitude_sdk.client import Client, ClientOptions, RouterOptions
|
6
7
|
from latitude_sdk.env import env
|
@@ -20,6 +21,7 @@ class InternalOptions(Model):
|
|
20
21
|
|
21
22
|
|
22
23
|
class LatitudeOptions(SdkOptions, Model):
|
24
|
+
promptl: Optional[PromptlOptions] = None
|
23
25
|
telemetry: Optional[TelemetryOptions] = None
|
24
26
|
internal: Optional[InternalOptions] = None
|
25
27
|
|
@@ -48,15 +50,16 @@ class Latitude:
|
|
48
50
|
_options: LatitudeOptions
|
49
51
|
_client: Client
|
50
52
|
|
53
|
+
promptl: Promptl
|
51
54
|
telemetry: Optional[Telemetry]
|
52
55
|
|
53
56
|
prompts: Prompts
|
54
57
|
logs: Logs
|
55
58
|
evaluations: Evaluations
|
56
59
|
|
57
|
-
def __init__(self, api_key: str, options: LatitudeOptions):
|
60
|
+
def __init__(self, api_key: str, options: Optional[LatitudeOptions] = None):
|
61
|
+
options = LatitudeOptions(**{**dict(DEFAULT_LATITUDE_OPTIONS), **dict(options or {})})
|
58
62
|
options.internal = InternalOptions(**{**dict(DEFAULT_INTERNAL_OPTIONS), **dict(options.internal or {})})
|
59
|
-
options = LatitudeOptions(**{**dict(DEFAULT_LATITUDE_OPTIONS), **dict(options)})
|
60
63
|
self._options = options
|
61
64
|
|
62
65
|
assert self._options.internal is not None
|
@@ -77,9 +80,10 @@ class Latitude:
|
|
77
80
|
)
|
78
81
|
)
|
79
82
|
|
83
|
+
self.promptl = Promptl(self._options.promptl)
|
80
84
|
if self._options.telemetry:
|
81
85
|
self.telemetry = Telemetry(api_key, self._options.telemetry)
|
82
86
|
|
83
|
-
self.prompts = Prompts(self._client, self._options)
|
87
|
+
self.prompts = Prompts(self._client, self.promptl, self._options)
|
84
88
|
self.logs = Logs(self._client, self._options)
|
85
89
|
self.evaluations = Evaluations(self._client, self._options)
|
latitude_sdk/sdk/logs.py
CHANGED
@@ -1,13 +1,11 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import Optional, Sequence
|
2
|
+
|
3
|
+
from promptl_ai import MessageLike
|
4
|
+
from promptl_ai.bindings.types import _Message
|
2
5
|
|
3
6
|
from latitude_sdk.client import Client, CreateLogRequestBody, CreateLogRequestParams, RequestHandler
|
4
7
|
from latitude_sdk.sdk.errors import ApiError, ApiErrorCodes
|
5
|
-
from latitude_sdk.sdk.types import
|
6
|
-
Log,
|
7
|
-
Message,
|
8
|
-
SdkOptions,
|
9
|
-
_Message,
|
10
|
-
)
|
8
|
+
from latitude_sdk.sdk.types import Log, SdkOptions
|
11
9
|
from latitude_sdk.util import Model
|
12
10
|
|
13
11
|
|
@@ -42,9 +40,9 @@ class Logs:
|
|
42
40
|
)
|
43
41
|
|
44
42
|
async def create(
|
45
|
-
self, path: str, messages: Sequence[
|
43
|
+
self, path: str, messages: Sequence[MessageLike], options: Optional[CreateLogOptions] = None
|
46
44
|
) -> CreateLogResult:
|
47
|
-
options = CreateLogOptions(**{**dict(self._options), **dict(options)})
|
45
|
+
options = CreateLogOptions(**{**dict(self._options), **dict(options or {})})
|
48
46
|
self._ensure_log_options(options)
|
49
47
|
assert options.project_id is not None
|
50
48
|
|
latitude_sdk/sdk/prompts.py
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
import asyncio
|
2
2
|
from typing import Any, AsyncGenerator, Dict, List, Optional, Sequence, Union
|
3
3
|
|
4
|
+
from promptl_ai import Adapter, Message, MessageLike, Promptl, ToolMessage, ToolResultContent
|
5
|
+
from promptl_ai.bindings.types import _Message
|
6
|
+
|
4
7
|
from latitude_sdk.client import (
|
5
8
|
ChatPromptRequestBody,
|
6
9
|
ChatPromptRequestParams,
|
@@ -21,21 +24,33 @@ from latitude_sdk.sdk.types import (
|
|
21
24
|
ChainEventStep,
|
22
25
|
ChainEventStepCompleted,
|
23
26
|
FinishedEvent,
|
24
|
-
|
27
|
+
OnStep,
|
25
28
|
OnToolCall,
|
26
29
|
OnToolCallDetails,
|
27
30
|
Prompt,
|
31
|
+
Providers,
|
28
32
|
SdkOptions,
|
29
33
|
StreamCallbacks,
|
30
34
|
StreamEvents,
|
31
35
|
StreamTypes,
|
32
|
-
ToolMessage,
|
33
36
|
ToolResult,
|
34
|
-
ToolResultContent,
|
35
|
-
_Message,
|
36
37
|
)
|
37
38
|
from latitude_sdk.util import Model
|
38
39
|
|
40
|
+
_PROVIDER_TO_ADAPTER = {
|
41
|
+
Providers.OpenAI: Adapter.OpenAI,
|
42
|
+
Providers.Anthropic: Adapter.Anthropic,
|
43
|
+
}
|
44
|
+
|
45
|
+
_PROMPT_ATTR_TO_ADAPTER_ATTR = {
|
46
|
+
"maxTokens": ("max_tokens", [Adapter.OpenAI, Adapter.Anthropic]),
|
47
|
+
"topP": ("top_p", [Adapter.OpenAI, Adapter.Anthropic]),
|
48
|
+
"topK": ("top_k", [Adapter.OpenAI, Adapter.Anthropic]),
|
49
|
+
"presencePenalty": ("presence_penalty", [Adapter.OpenAI, Adapter.Anthropic]),
|
50
|
+
"stopSequences": ("stop_sequences", [Adapter.OpenAI, Adapter.Anthropic]),
|
51
|
+
"toolChoice": ("tool_choice", [Adapter.OpenAI, Adapter.Anthropic]),
|
52
|
+
}
|
53
|
+
|
39
54
|
|
40
55
|
class OnToolCallPaused(Exception):
|
41
56
|
pass
|
@@ -82,13 +97,34 @@ class ChatPromptResult(FinishedEvent, Model):
|
|
82
97
|
pass
|
83
98
|
|
84
99
|
|
100
|
+
class RenderPromptOptions(Model):
|
101
|
+
parameters: Optional[Dict[str, Any]] = None
|
102
|
+
adapter: Optional[Adapter] = None
|
103
|
+
|
104
|
+
|
105
|
+
class RenderPromptResult(Model):
|
106
|
+
messages: List[MessageLike]
|
107
|
+
config: Dict[str, Any]
|
108
|
+
|
109
|
+
|
110
|
+
class RenderChainOptions(Model):
|
111
|
+
parameters: Optional[Dict[str, Any]] = None
|
112
|
+
adapter: Optional[Adapter] = None
|
113
|
+
|
114
|
+
|
115
|
+
class RenderChainResult(RenderPromptResult, Model):
|
116
|
+
pass
|
117
|
+
|
118
|
+
|
85
119
|
class Prompts:
|
86
120
|
_options: SdkOptions
|
87
121
|
_client: Client
|
122
|
+
_promptl: Promptl
|
88
123
|
|
89
|
-
def __init__(self, client: Client, options: SdkOptions):
|
124
|
+
def __init__(self, client: Client, promptl: Promptl, options: SdkOptions):
|
90
125
|
self._options = options
|
91
126
|
self._client = client
|
127
|
+
self._promptl = promptl
|
92
128
|
|
93
129
|
def _ensure_prompt_options(self, options: PromptOptions):
|
94
130
|
if not options.project_id:
|
@@ -168,9 +204,26 @@ class Prompts:
|
|
168
204
|
# NOTE: FinishedEvent not in on_event
|
169
205
|
return FinishedEvent(uuid=uuid, conversation=conversation, response=response)
|
170
206
|
|
171
|
-
|
207
|
+
@staticmethod
|
208
|
+
def _pause_tool_execution() -> Any:
|
172
209
|
raise OnToolCallPaused()
|
173
210
|
|
211
|
+
@staticmethod
|
212
|
+
async def _wrap_tool_handler(
|
213
|
+
handler: OnToolCall, arguments: Dict[str, Any], details: OnToolCallDetails
|
214
|
+
) -> ToolResult:
|
215
|
+
tool_result: Dict[str, Any] = {"id": details.id, "name": details.name}
|
216
|
+
|
217
|
+
try:
|
218
|
+
result = await handler(arguments, details)
|
219
|
+
|
220
|
+
return ToolResult(**tool_result, result=result)
|
221
|
+
except Exception as exception:
|
222
|
+
if isinstance(exception, OnToolCallPaused):
|
223
|
+
raise exception
|
224
|
+
|
225
|
+
return ToolResult(**tool_result, result=str(exception), is_error=True)
|
226
|
+
|
174
227
|
async def _handle_tool_calls(
|
175
228
|
self, result: FinishedEvent, options: Union[RunPromptOptions, ChatPromptOptions]
|
176
229
|
) -> Optional[FinishedEvent]:
|
@@ -194,15 +247,22 @@ class Prompts:
|
|
194
247
|
response=f"Tool {tool_call.name} not supplied",
|
195
248
|
)
|
196
249
|
|
197
|
-
details = OnToolCallDetails(
|
198
|
-
conversation_uuid=result.uuid,
|
199
|
-
messages=result.conversation,
|
200
|
-
pause_execution=self._pause_tool_execution,
|
201
|
-
requested_tool_calls=result.response.tool_calls,
|
202
|
-
)
|
203
|
-
|
204
250
|
tool_results = await asyncio.gather(
|
205
|
-
*[
|
251
|
+
*[
|
252
|
+
self._wrap_tool_handler(
|
253
|
+
options.tools[tool_call.name],
|
254
|
+
tool_call.arguments,
|
255
|
+
OnToolCallDetails(
|
256
|
+
id=tool_call.id,
|
257
|
+
name=tool_call.name,
|
258
|
+
conversation_uuid=result.uuid,
|
259
|
+
messages=result.conversation,
|
260
|
+
pause_execution=self._pause_tool_execution,
|
261
|
+
requested_tool_calls=result.response.tool_calls,
|
262
|
+
),
|
263
|
+
)
|
264
|
+
for tool_call in result.response.tool_calls
|
265
|
+
],
|
206
266
|
return_exceptions=False,
|
207
267
|
)
|
208
268
|
|
@@ -224,8 +284,8 @@ class Prompts:
|
|
224
284
|
|
225
285
|
return FinishedEvent(**dict(next_result)) if next_result else None
|
226
286
|
|
227
|
-
async def get(self, path: str, options: GetPromptOptions) -> GetPromptResult:
|
228
|
-
options = GetPromptOptions(**{**dict(self._options), **dict(options)})
|
287
|
+
async def get(self, path: str, options: Optional[GetPromptOptions] = None) -> GetPromptResult:
|
288
|
+
options = GetPromptOptions(**{**dict(self._options), **dict(options or {})})
|
229
289
|
self._ensure_prompt_options(options)
|
230
290
|
assert options.project_id is not None
|
231
291
|
|
@@ -239,8 +299,10 @@ class Prompts:
|
|
239
299
|
) as response:
|
240
300
|
return GetPromptResult.model_validate_json(response.content)
|
241
301
|
|
242
|
-
async def get_or_create(
|
243
|
-
|
302
|
+
async def get_or_create(
|
303
|
+
self, path: str, options: Optional[GetOrCreatePromptOptions] = None
|
304
|
+
) -> GetOrCreatePromptResult:
|
305
|
+
options = GetOrCreatePromptOptions(**{**dict(self._options), **dict(options or {})})
|
244
306
|
self._ensure_prompt_options(options)
|
245
307
|
assert options.project_id is not None
|
246
308
|
|
@@ -257,12 +319,12 @@ class Prompts:
|
|
257
319
|
) as response:
|
258
320
|
return GetOrCreatePromptResult.model_validate_json(response.content)
|
259
321
|
|
260
|
-
async def run(self, path: str, options: RunPromptOptions) -> Optional[RunPromptResult]:
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
assert options.project_id is not None
|
322
|
+
async def run(self, path: str, options: Optional[RunPromptOptions] = None) -> Optional[RunPromptResult]:
|
323
|
+
options = RunPromptOptions(**{**dict(self._options), **dict(options or {})})
|
324
|
+
self._ensure_prompt_options(options)
|
325
|
+
assert options.project_id is not None
|
265
326
|
|
327
|
+
try:
|
266
328
|
async with self._client.request(
|
267
329
|
handler=RequestHandler.RunPrompt,
|
268
330
|
params=RunPromptRequestParams(
|
@@ -311,13 +373,13 @@ class Prompts:
|
|
311
373
|
return None
|
312
374
|
|
313
375
|
async def chat(
|
314
|
-
self, uuid: str, messages: Sequence[
|
376
|
+
self, uuid: str, messages: Sequence[MessageLike], options: Optional[ChatPromptOptions] = None
|
315
377
|
) -> Optional[ChatPromptResult]:
|
316
|
-
|
317
|
-
options = ChatPromptOptions(**{**dict(self._options), **dict(options)})
|
378
|
+
options = ChatPromptOptions(**{**dict(self._options), **dict(options or {})})
|
318
379
|
|
319
|
-
|
380
|
+
messages = [_Message.validate_python(message) for message in messages]
|
320
381
|
|
382
|
+
try:
|
321
383
|
async with self._client.request(
|
322
384
|
handler=RequestHandler.ChatPrompt,
|
323
385
|
params=ChatPromptRequestParams(
|
@@ -362,6 +424,55 @@ class Prompts:
|
|
362
424
|
|
363
425
|
return None
|
364
426
|
|
365
|
-
|
427
|
+
def _adapt_prompt_config(self, config: Dict[str, Any], adapter: Adapter) -> Dict[str, Any]:
|
428
|
+
adapted_config: Dict[str, Any] = {}
|
429
|
+
|
430
|
+
# NOTE: Should we delete attributes not supported by the provider?
|
431
|
+
for attr, value in config.items():
|
432
|
+
if attr in _PROMPT_ATTR_TO_ADAPTER_ATTR and adapter in _PROMPT_ATTR_TO_ADAPTER_ATTR[attr][1]:
|
433
|
+
adapted_config[_PROMPT_ATTR_TO_ADAPTER_ATTR[attr][0]] = value
|
434
|
+
else:
|
435
|
+
adapted_config[attr] = value
|
436
|
+
|
437
|
+
return adapted_config
|
438
|
+
|
439
|
+
async def render(self, prompt: str, options: Optional[RenderPromptOptions] = None) -> RenderPromptResult:
|
440
|
+
options = RenderPromptOptions(**{**dict(self._options), **dict(options or {})})
|
441
|
+
adapter = options.adapter or Adapter.OpenAI
|
366
442
|
|
367
|
-
|
443
|
+
result = self._promptl.prompts.render(
|
444
|
+
prompt=prompt,
|
445
|
+
parameters=options.parameters,
|
446
|
+
adapter=adapter,
|
447
|
+
)
|
448
|
+
|
449
|
+
return RenderPromptResult(
|
450
|
+
messages=result.messages,
|
451
|
+
config=self._adapt_prompt_config(result.config, adapter),
|
452
|
+
)
|
453
|
+
|
454
|
+
async def render_chain(
|
455
|
+
self, prompt: Prompt, on_step: OnStep, options: Optional[RenderChainOptions] = None
|
456
|
+
) -> RenderChainResult:
|
457
|
+
options = RenderChainOptions(**{**dict(self._options), **dict(options or {})})
|
458
|
+
adapter = options.adapter or _PROVIDER_TO_ADAPTER.get(prompt.provider or Providers.OpenAI, Adapter.OpenAI)
|
459
|
+
|
460
|
+
chain = self._promptl.chains.create(
|
461
|
+
prompt=prompt.content,
|
462
|
+
parameters=options.parameters,
|
463
|
+
adapter=adapter,
|
464
|
+
)
|
465
|
+
|
466
|
+
step = None
|
467
|
+
response = None
|
468
|
+
while not chain.completed:
|
469
|
+
step = chain.step(response)
|
470
|
+
if not step.completed:
|
471
|
+
response = await on_step(step.messages, self._adapt_prompt_config(step.config, adapter))
|
472
|
+
|
473
|
+
assert step is not None
|
474
|
+
|
475
|
+
return RenderChainResult(
|
476
|
+
messages=step.messages,
|
477
|
+
config=self._adapt_prompt_config(step.config, adapter),
|
478
|
+
)
|
latitude_sdk/sdk/types.py
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
from datetime import datetime
|
2
|
-
from typing import Any, Callable, Dict, List, Literal, Optional, Protocol, Union, runtime_checkable
|
2
|
+
from typing import Any, Callable, Dict, List, Literal, Optional, Protocol, Sequence, Union, runtime_checkable
|
3
|
+
|
4
|
+
from promptl_ai import Message, MessageLike
|
3
5
|
|
4
6
|
from latitude_sdk.sdk.errors import ApiError
|
5
|
-
from latitude_sdk.util import
|
7
|
+
from latitude_sdk.util import Field, Model, StrEnum
|
6
8
|
|
7
9
|
|
8
10
|
class DbErrorRef(Model):
|
@@ -28,87 +30,6 @@ class Prompt(Model):
|
|
28
30
|
provider: Optional[Providers] = None
|
29
31
|
|
30
32
|
|
31
|
-
class ContentType(StrEnum):
|
32
|
-
Text = "text"
|
33
|
-
Image = "image"
|
34
|
-
File = "file"
|
35
|
-
ToolCall = "tool-call"
|
36
|
-
ToolResult = "tool-result"
|
37
|
-
|
38
|
-
|
39
|
-
class TextContent(Model):
|
40
|
-
type: Literal[ContentType.Text] = ContentType.Text
|
41
|
-
text: str
|
42
|
-
|
43
|
-
|
44
|
-
class ImageContent(Model):
|
45
|
-
type: Literal[ContentType.Image] = ContentType.Image
|
46
|
-
image: str
|
47
|
-
|
48
|
-
|
49
|
-
class FileContent(Model):
|
50
|
-
type: Literal[ContentType.File] = ContentType.File
|
51
|
-
file: str
|
52
|
-
mime_type: str = Field(alias=str("mimeType"))
|
53
|
-
|
54
|
-
|
55
|
-
class ToolCallContent(Model):
|
56
|
-
type: Literal[ContentType.ToolCall] = ContentType.ToolCall
|
57
|
-
id: str = Field(alias=str("toolCallId"))
|
58
|
-
name: str = Field(alias=str("toolName"))
|
59
|
-
arguments: Dict[str, Any] = Field(alias=str("args"))
|
60
|
-
|
61
|
-
|
62
|
-
class ToolResultContent(Model):
|
63
|
-
type: Literal[ContentType.ToolResult] = ContentType.ToolResult
|
64
|
-
id: str = Field(alias=str("toolCallId"))
|
65
|
-
name: str = Field(alias=str("toolName"))
|
66
|
-
result: Any
|
67
|
-
is_error: Optional[bool] = Field(default=None, alias=str("isError"))
|
68
|
-
|
69
|
-
|
70
|
-
MessageContent = Union[
|
71
|
-
str,
|
72
|
-
List[TextContent],
|
73
|
-
List[ImageContent],
|
74
|
-
List[FileContent],
|
75
|
-
List[ToolCallContent],
|
76
|
-
List[ToolResultContent],
|
77
|
-
]
|
78
|
-
|
79
|
-
|
80
|
-
class MessageRole(StrEnum):
|
81
|
-
System = "system"
|
82
|
-
User = "user"
|
83
|
-
Assistant = "assistant"
|
84
|
-
Tool = "tool"
|
85
|
-
|
86
|
-
|
87
|
-
class SystemMessage(Model):
|
88
|
-
role: Literal[MessageRole.System] = MessageRole.System
|
89
|
-
content: Union[str, List[TextContent]]
|
90
|
-
|
91
|
-
|
92
|
-
class UserMessage(Model):
|
93
|
-
role: Literal[MessageRole.User] = MessageRole.User
|
94
|
-
content: Union[str, List[Union[TextContent, ImageContent, FileContent]]]
|
95
|
-
name: Optional[str] = None
|
96
|
-
|
97
|
-
|
98
|
-
class AssistantMessage(Model):
|
99
|
-
role: Literal[MessageRole.Assistant] = MessageRole.Assistant
|
100
|
-
content: Union[str, List[Union[TextContent, ToolCallContent]]]
|
101
|
-
|
102
|
-
|
103
|
-
class ToolMessage(Model):
|
104
|
-
role: Literal[MessageRole.Tool] = MessageRole.Tool
|
105
|
-
content: List[ToolResultContent]
|
106
|
-
|
107
|
-
|
108
|
-
Message = Union[SystemMessage, UserMessage, AssistantMessage, ToolMessage]
|
109
|
-
_Message = Adapter(Message)
|
110
|
-
|
111
|
-
|
112
33
|
class ModelUsage(Model):
|
113
34
|
prompt_tokens: int = Field(alias=str("promptTokens"))
|
114
35
|
completion_tokens: int = Field(alias=str("completionTokens"))
|
@@ -295,6 +216,8 @@ class StreamCallbacks(Model):
|
|
295
216
|
|
296
217
|
|
297
218
|
class OnToolCallDetails(Model):
|
219
|
+
id: str
|
220
|
+
name: str
|
298
221
|
conversation_uuid: str
|
299
222
|
messages: List[Message]
|
300
223
|
pause_execution: Callable[[], ToolResult]
|
@@ -303,7 +226,14 @@ class OnToolCallDetails(Model):
|
|
303
226
|
|
304
227
|
@runtime_checkable
|
305
228
|
class OnToolCall(Protocol):
|
306
|
-
async def __call__(self,
|
229
|
+
async def __call__(self, arguments: Dict[str, Any], details: OnToolCallDetails) -> Any: ...
|
230
|
+
|
231
|
+
|
232
|
+
@runtime_checkable
|
233
|
+
class OnStep(Protocol):
|
234
|
+
async def __call__(
|
235
|
+
self, messages: List[MessageLike], config: Dict[str, Any]
|
236
|
+
) -> Union[str, MessageLike, Sequence[MessageLike]]: ...
|
307
237
|
|
308
238
|
|
309
239
|
class SdkOptions(Model):
|
latitude_sdk/util/utils.py
CHANGED
@@ -64,6 +64,10 @@ class StrEnum(str, Enum):
|
|
64
64
|
Field = pydantic.Field
|
65
65
|
Config = pydantic.ConfigDict
|
66
66
|
Adapter = pydantic.TypeAdapter
|
67
|
+
Aliases = pydantic.AliasChoices
|
68
|
+
Validator = pydantic.WrapValidator
|
69
|
+
ValidatorInfo = pydantic.ValidationInfo
|
70
|
+
ValidatorHandler = pydantic.ValidatorFunctionWrapHandler
|
67
71
|
|
68
72
|
|
69
73
|
class Model(pydantic.BaseModel):
|
@@ -76,12 +80,12 @@ class Model(pydantic.BaseModel):
|
|
76
80
|
@is_like(pydantic.BaseModel.model_dump)
|
77
81
|
def model_dump(self, *args: Any, **kwargs: Any) -> Any:
|
78
82
|
exclude_none = kwargs.pop("exclude_none", True)
|
79
|
-
|
83
|
+
by_alias = kwargs.pop("by_alias", True)
|
84
|
+
return super().model_dump(*args, exclude_none=exclude_none, by_alias=by_alias, **kwargs)
|
80
85
|
|
81
86
|
@is_like(pydantic.BaseModel.dict) # pyright: ignore [reportDeprecated]
|
82
87
|
def dict(self, *args: Any, **kwargs: Any) -> Any:
|
83
|
-
|
84
|
-
return super().dict(*args, exclude_none=exclude_none, **kwargs) # pyright: ignore [reportDeprecated]
|
88
|
+
raise NotImplementedError("deprecated")
|
85
89
|
|
86
90
|
@is_like(pydantic.BaseModel.model_dump_json)
|
87
91
|
def model_dump_json(self, *args: Any, **kwargs: Any) -> Any:
|
@@ -91,6 +95,4 @@ class Model(pydantic.BaseModel):
|
|
91
95
|
|
92
96
|
@is_like(pydantic.BaseModel.json) # pyright: ignore [reportDeprecated]
|
93
97
|
def json(self, *args: Any, **kwargs: Any) -> Any:
|
94
|
-
|
95
|
-
by_alias = kwargs.pop("by_alias", True)
|
96
|
-
return super().json(*args, exclude_none=exclude_none, by_alias=by_alias, **kwargs) # pyright: ignore [reportDeprecated]
|
98
|
+
raise NotImplementedError("deprecated")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: latitude-sdk
|
3
|
-
Version: 0.1
|
3
|
+
Version: 1.0.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,8 @@ 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: latitude-telemetry>=0.
|
14
|
+
Requires-Dist: latitude-telemetry>=1.0.0
|
15
|
+
Requires-Dist: promptl-ai>=1.0.1
|
15
16
|
Requires-Dist: pydantic>=2.10.3
|
16
17
|
Requires-Dist: typing-extensions>=4.12.2
|
17
18
|
Description-Content-Type: text/markdown
|
@@ -2,19 +2,19 @@ latitude_sdk/__init__.py,sha256=-AbNXLmzDZeGbRdDIOpNjdCbacOvLBflSJwQtLlZfgk,19
|
|
2
2
|
latitude_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
3
|
latitude_sdk/client/__init__.py,sha256=d8CnNB8UoGwcftiIeeC0twdg01qNvfpj-v7O40I7IiE,68
|
4
4
|
latitude_sdk/client/client.py,sha256=Oc4COkVFR1vFewVKZzUIvztJi_yTxeSMoyeML-ivVsY,4389
|
5
|
-
latitude_sdk/client/payloads.py,sha256=
|
5
|
+
latitude_sdk/client/payloads.py,sha256=odYmsrK5F_Ym9wTCbwuBuiBRBKiScdSnnRn40ywGR3E,2719
|
6
6
|
latitude_sdk/client/router.py,sha256=XYi24oUKL1wHDLvydpwLWCjy9tDGSVPN-zhetuvaj8I,4038
|
7
7
|
latitude_sdk/env/__init__.py,sha256=66of5veJ-u1aNI025L65Rrj321AjrYevMqomTMYIrPQ,19
|
8
8
|
latitude_sdk/env/env.py,sha256=MnXexPOHE6aXcAszrDCbW7hzACUv4YtU1bfxpYwvHNw,455
|
9
9
|
latitude_sdk/sdk/__init__.py,sha256=C9LlIjfnrS7KOK3-ruXKmbT77nSQMm23nZ6-t8sO8ME,137
|
10
10
|
latitude_sdk/sdk/errors.py,sha256=9GlGdDE8LGy3dE2Ry_BipBg-tDbQx7LWXJfSnTJSSBE,1747
|
11
|
-
latitude_sdk/sdk/evaluations.py,sha256=
|
12
|
-
latitude_sdk/sdk/latitude.py,sha256=
|
13
|
-
latitude_sdk/sdk/logs.py,sha256=
|
14
|
-
latitude_sdk/sdk/prompts.py,sha256=
|
15
|
-
latitude_sdk/sdk/types.py,sha256=
|
11
|
+
latitude_sdk/sdk/evaluations.py,sha256=fDGtAWjdPG9OuKLit6u-jufVleC1EnshRplK6RN8iyg,2277
|
12
|
+
latitude_sdk/sdk/latitude.py,sha256=fdOWrAs0k3puLIhyU_zwvLsMyV_f1RxDWpV65_Euenc,2928
|
13
|
+
latitude_sdk/sdk/logs.py,sha256=CyHkRJvPl_p7wTSvR9bgxEI5akS0Tjc9FeQRb2C2vMg,1997
|
14
|
+
latitude_sdk/sdk/prompts.py,sha256=HXvJVqcn446VI2nlIT2lCuOrNypNqE0x1Sy0l77MDFM,16756
|
15
|
+
latitude_sdk/sdk/types.py,sha256=v8K1zzJqPexos08U4cnsHJ3LrkVRlbgMNvwtKuXoxuQ,6922
|
16
16
|
latitude_sdk/util/__init__.py,sha256=alIDGBnxWH4JvP-UW-7N99seBBi0r1GV1h8f1ERFBec,21
|
17
|
-
latitude_sdk/util/utils.py,sha256=
|
18
|
-
latitude_sdk-0.1.
|
19
|
-
latitude_sdk-0.1.
|
20
|
-
latitude_sdk-0.1.
|
17
|
+
latitude_sdk/util/utils.py,sha256=hMOmF-u1QaDgOwXN6ME6n4TaQ70yZKLvijDUqNCMwXI,2844
|
18
|
+
latitude_sdk-1.0.1.dist-info/METADATA,sha256=6eLckfer4mDy1JY6ZzWNJcdh0zk_RmLJ7H2aFEoQfCg,2060
|
19
|
+
latitude_sdk-1.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
20
|
+
latitude_sdk-1.0.1.dist-info/RECORD,,
|
File without changes
|