tracia 0.1.1__tar.gz → 0.2.0__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.
- {tracia-0.1.1 → tracia-0.2.0}/PKG-INFO +1 -1
- {tracia-0.1.1 → tracia-0.2.0}/pyproject.toml +1 -1
- {tracia-0.1.1 → tracia-0.2.0}/tracia/__init__.py +3 -0
- {tracia-0.1.1 → tracia-0.2.0}/tracia/_client.py +24 -1
- {tracia-0.1.1 → tracia-0.2.0}/tracia/_constants.py +1 -1
- {tracia-0.1.1 → tracia-0.2.0}/tracia/_llm.py +56 -0
- {tracia-0.1.1 → tracia-0.2.0}/tracia/_types.py +21 -0
- {tracia-0.1.1 → tracia-0.2.0}/.claude/settings.local.json +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/.gitignore +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/CLAUDE.md +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/LICENSE +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/README.md +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/tests/__init__.py +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/tests/test_client.py +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/tests/test_errors.py +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/tests/test_llm.py +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/tests/test_types.py +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/tests/test_utils.py +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/tracia/_errors.py +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/tracia/_http.py +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/tracia/_session.py +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/tracia/_streaming.py +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/tracia/_utils.py +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/tracia/py.typed +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/tracia/resources/__init__.py +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/tracia/resources/prompts.py +0 -0
- {tracia-0.1.1 → tracia-0.2.0}/tracia/resources/spans.py +0 -0
|
@@ -66,6 +66,7 @@ from ._types import (
|
|
|
66
66
|
PromptListItem,
|
|
67
67
|
PromptMessage,
|
|
68
68
|
PromptVersion,
|
|
69
|
+
ResponseFormatJsonSchema,
|
|
69
70
|
ResponsesEvent,
|
|
70
71
|
ResponsesFunctionCall,
|
|
71
72
|
ResponsesFunctionCallOutput,
|
|
@@ -121,6 +122,8 @@ __all__ = [
|
|
|
121
122
|
"JsonSchemaProperty",
|
|
122
123
|
"ToolCall",
|
|
123
124
|
"ToolChoice",
|
|
125
|
+
# Types - Response Format
|
|
126
|
+
"ResponseFormatJsonSchema",
|
|
124
127
|
# Types - Run Local
|
|
125
128
|
"RunLocalInput",
|
|
126
129
|
"RunLocalResult",
|
|
@@ -20,13 +20,14 @@ from ._constants import (
|
|
|
20
20
|
)
|
|
21
21
|
from ._errors import TraciaError, TraciaErrorCode, sanitize_error_message
|
|
22
22
|
from ._http import AsyncHttpClient, HttpClient
|
|
23
|
-
from ._llm import LLMClient, build_assistant_message, resolve_provider
|
|
23
|
+
from ._llm import LLMClient, build_assistant_message, convert_response_format, resolve_provider
|
|
24
24
|
from ._session import TraciaSession
|
|
25
25
|
from ._streaming import AsyncLocalStream, LocalStream
|
|
26
26
|
from ._types import (
|
|
27
27
|
CreateSpanPayload,
|
|
28
28
|
LocalPromptMessage,
|
|
29
29
|
LLMProvider,
|
|
30
|
+
ResponseFormat,
|
|
30
31
|
RunLocalResult,
|
|
31
32
|
StreamResult,
|
|
32
33
|
TokenUsage,
|
|
@@ -263,6 +264,7 @@ class Tracia:
|
|
|
263
264
|
span_id: str | None = None,
|
|
264
265
|
tools: list[ToolDefinition] | None = None,
|
|
265
266
|
tool_choice: ToolChoice | None = None,
|
|
267
|
+
response_format: ResponseFormat | None = None,
|
|
266
268
|
trace_id: str | None = None,
|
|
267
269
|
parent_span_id: str | None = None,
|
|
268
270
|
) -> RunLocalResult: ...
|
|
@@ -289,6 +291,7 @@ class Tracia:
|
|
|
289
291
|
span_id: str | None = None,
|
|
290
292
|
tools: list[ToolDefinition] | None = None,
|
|
291
293
|
tool_choice: ToolChoice | None = None,
|
|
294
|
+
response_format: ResponseFormat | None = None,
|
|
292
295
|
trace_id: str | None = None,
|
|
293
296
|
parent_span_id: str | None = None,
|
|
294
297
|
) -> LocalStream: ...
|
|
@@ -314,6 +317,7 @@ class Tracia:
|
|
|
314
317
|
span_id: str | None = None,
|
|
315
318
|
tools: list[ToolDefinition] | None = None,
|
|
316
319
|
tool_choice: ToolChoice | None = None,
|
|
320
|
+
response_format: ResponseFormat | None = None,
|
|
317
321
|
trace_id: str | None = None,
|
|
318
322
|
parent_span_id: str | None = None,
|
|
319
323
|
) -> RunLocalResult | LocalStream:
|
|
@@ -361,6 +365,8 @@ class Tracia:
|
|
|
361
365
|
# Calculate timeout
|
|
362
366
|
timeout_seconds = (timeout_ms or DEFAULT_TIMEOUT_MS) / 1000.0
|
|
363
367
|
|
|
368
|
+
litellm_response_format = convert_response_format(response_format)
|
|
369
|
+
|
|
364
370
|
if stream:
|
|
365
371
|
return self._run_local_streaming(
|
|
366
372
|
messages=prompt_messages,
|
|
@@ -382,6 +388,7 @@ class Tracia:
|
|
|
382
388
|
tools=tools,
|
|
383
389
|
tool_choice=tool_choice,
|
|
384
390
|
variables=variables,
|
|
391
|
+
response_format=litellm_response_format,
|
|
385
392
|
)
|
|
386
393
|
else:
|
|
387
394
|
return self._run_local_non_streaming(
|
|
@@ -404,6 +411,7 @@ class Tracia:
|
|
|
404
411
|
tools=tools,
|
|
405
412
|
tool_choice=tool_choice,
|
|
406
413
|
variables=variables,
|
|
414
|
+
response_format=litellm_response_format,
|
|
407
415
|
)
|
|
408
416
|
|
|
409
417
|
def _run_local_non_streaming(
|
|
@@ -428,6 +436,7 @@ class Tracia:
|
|
|
428
436
|
tools: list[ToolDefinition] | None,
|
|
429
437
|
tool_choice: ToolChoice | None,
|
|
430
438
|
variables: dict[str, str] | None,
|
|
439
|
+
response_format: dict[str, Any] | None = None,
|
|
431
440
|
) -> RunLocalResult:
|
|
432
441
|
"""Run local prompt without streaming."""
|
|
433
442
|
start_time = time.time()
|
|
@@ -451,6 +460,7 @@ class Tracia:
|
|
|
451
460
|
tool_choice=tool_choice,
|
|
452
461
|
api_key=provider_api_key,
|
|
453
462
|
timeout=timeout,
|
|
463
|
+
response_format=response_format,
|
|
454
464
|
)
|
|
455
465
|
|
|
456
466
|
result_text = completion.text
|
|
@@ -537,6 +547,7 @@ class Tracia:
|
|
|
537
547
|
tools: list[ToolDefinition] | None,
|
|
538
548
|
tool_choice: ToolChoice | None,
|
|
539
549
|
variables: dict[str, str] | None,
|
|
550
|
+
response_format: dict[str, Any] | None = None,
|
|
540
551
|
) -> LocalStream:
|
|
541
552
|
"""Run local prompt with streaming."""
|
|
542
553
|
start_time = time.time()
|
|
@@ -555,6 +566,7 @@ class Tracia:
|
|
|
555
566
|
tool_choice=tool_choice,
|
|
556
567
|
api_key=provider_api_key,
|
|
557
568
|
timeout=timeout,
|
|
569
|
+
response_format=response_format,
|
|
558
570
|
)
|
|
559
571
|
|
|
560
572
|
def wrapped_chunks():
|
|
@@ -660,6 +672,7 @@ class Tracia:
|
|
|
660
672
|
span_id: str | None = None,
|
|
661
673
|
tools: list[ToolDefinition] | None = None,
|
|
662
674
|
tool_choice: ToolChoice | None = None,
|
|
675
|
+
response_format: ResponseFormat | None = None,
|
|
663
676
|
trace_id: str | None = None,
|
|
664
677
|
parent_span_id: str | None = None,
|
|
665
678
|
) -> RunLocalResult: ...
|
|
@@ -686,6 +699,7 @@ class Tracia:
|
|
|
686
699
|
span_id: str | None = None,
|
|
687
700
|
tools: list[ToolDefinition] | None = None,
|
|
688
701
|
tool_choice: ToolChoice | None = None,
|
|
702
|
+
response_format: ResponseFormat | None = None,
|
|
689
703
|
trace_id: str | None = None,
|
|
690
704
|
parent_span_id: str | None = None,
|
|
691
705
|
) -> AsyncLocalStream: ...
|
|
@@ -711,6 +725,7 @@ class Tracia:
|
|
|
711
725
|
span_id: str | None = None,
|
|
712
726
|
tools: list[ToolDefinition] | None = None,
|
|
713
727
|
tool_choice: ToolChoice | None = None,
|
|
728
|
+
response_format: ResponseFormat | None = None,
|
|
714
729
|
trace_id: str | None = None,
|
|
715
730
|
parent_span_id: str | None = None,
|
|
716
731
|
) -> RunLocalResult | AsyncLocalStream:
|
|
@@ -732,6 +747,8 @@ class Tracia:
|
|
|
732
747
|
# Calculate timeout
|
|
733
748
|
timeout_seconds = (timeout_ms or DEFAULT_TIMEOUT_MS) / 1000.0
|
|
734
749
|
|
|
750
|
+
litellm_response_format = convert_response_format(response_format)
|
|
751
|
+
|
|
735
752
|
if stream:
|
|
736
753
|
return await self._arun_local_streaming(
|
|
737
754
|
messages=prompt_messages,
|
|
@@ -753,6 +770,7 @@ class Tracia:
|
|
|
753
770
|
tools=tools,
|
|
754
771
|
tool_choice=tool_choice,
|
|
755
772
|
variables=variables,
|
|
773
|
+
response_format=litellm_response_format,
|
|
756
774
|
)
|
|
757
775
|
else:
|
|
758
776
|
return await self._arun_local_non_streaming(
|
|
@@ -775,6 +793,7 @@ class Tracia:
|
|
|
775
793
|
tools=tools,
|
|
776
794
|
tool_choice=tool_choice,
|
|
777
795
|
variables=variables,
|
|
796
|
+
response_format=litellm_response_format,
|
|
778
797
|
)
|
|
779
798
|
|
|
780
799
|
async def _arun_local_non_streaming(
|
|
@@ -799,6 +818,7 @@ class Tracia:
|
|
|
799
818
|
tools: list[ToolDefinition] | None,
|
|
800
819
|
tool_choice: ToolChoice | None,
|
|
801
820
|
variables: dict[str, str] | None,
|
|
821
|
+
response_format: dict[str, Any] | None = None,
|
|
802
822
|
) -> RunLocalResult:
|
|
803
823
|
"""Run local prompt without streaming (async)."""
|
|
804
824
|
start_time = time.time()
|
|
@@ -823,6 +843,7 @@ class Tracia:
|
|
|
823
843
|
tool_choice=tool_choice,
|
|
824
844
|
api_key=provider_api_key,
|
|
825
845
|
timeout=timeout,
|
|
846
|
+
response_format=response_format,
|
|
826
847
|
)
|
|
827
848
|
|
|
828
849
|
result_text = completion.text
|
|
@@ -909,6 +930,7 @@ class Tracia:
|
|
|
909
930
|
tools: list[ToolDefinition] | None,
|
|
910
931
|
tool_choice: ToolChoice | None,
|
|
911
932
|
variables: dict[str, str] | None,
|
|
933
|
+
response_format: dict[str, Any] | None = None,
|
|
912
934
|
) -> AsyncLocalStream:
|
|
913
935
|
"""Run local prompt with streaming (async)."""
|
|
914
936
|
start_time = time.time()
|
|
@@ -928,6 +950,7 @@ class Tracia:
|
|
|
928
950
|
tool_choice=tool_choice,
|
|
929
951
|
api_key=provider_api_key,
|
|
930
952
|
timeout=timeout,
|
|
953
|
+
response_format=response_format,
|
|
931
954
|
)
|
|
932
955
|
|
|
933
956
|
async def wrapped_chunks():
|
|
@@ -14,6 +14,7 @@ from ._types import (
|
|
|
14
14
|
FinishReason,
|
|
15
15
|
LLMProvider,
|
|
16
16
|
LocalPromptMessage,
|
|
17
|
+
ResponseFormatJsonSchema,
|
|
17
18
|
TextPart,
|
|
18
19
|
ToolCall,
|
|
19
20
|
ToolCallPart,
|
|
@@ -284,6 +285,49 @@ def convert_tool_choice(tool_choice: ToolChoice | None) -> str | dict[str, Any]
|
|
|
284
285
|
return None
|
|
285
286
|
|
|
286
287
|
|
|
288
|
+
def convert_response_format(
|
|
289
|
+
response_format: dict[str, Any] | ResponseFormatJsonSchema | None,
|
|
290
|
+
) -> dict[str, Any] | None:
|
|
291
|
+
"""Convert a Tracia response format to LiteLLM format.
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
response_format: The Tracia response format.
|
|
295
|
+
|
|
296
|
+
Returns:
|
|
297
|
+
Response format in LiteLLM/OpenAI format, or None.
|
|
298
|
+
"""
|
|
299
|
+
if response_format is None:
|
|
300
|
+
return None
|
|
301
|
+
|
|
302
|
+
if isinstance(response_format, ResponseFormatJsonSchema):
|
|
303
|
+
schema = response_format.schema_
|
|
304
|
+
name = response_format.name or "response"
|
|
305
|
+
json_schema: dict[str, Any] = {"name": name, "schema": schema}
|
|
306
|
+
if response_format.description is not None:
|
|
307
|
+
json_schema["description"] = response_format.description
|
|
308
|
+
return {"type": "json_schema", "json_schema": json_schema}
|
|
309
|
+
|
|
310
|
+
# Plain dict — check for our simplified format
|
|
311
|
+
if isinstance(response_format, dict):
|
|
312
|
+
fmt_type = response_format.get("type")
|
|
313
|
+
schema = response_format.get("schema")
|
|
314
|
+
|
|
315
|
+
if fmt_type == "json" and schema is not None:
|
|
316
|
+
name = response_format.get("name", "response")
|
|
317
|
+
json_schema: dict[str, Any] = {"name": name, "schema": schema}
|
|
318
|
+
description = response_format.get("description")
|
|
319
|
+
if description is not None:
|
|
320
|
+
json_schema["description"] = description
|
|
321
|
+
return {"type": "json_schema", "json_schema": json_schema}
|
|
322
|
+
|
|
323
|
+
if fmt_type == "json":
|
|
324
|
+
return {"type": "json_object"}
|
|
325
|
+
|
|
326
|
+
return response_format
|
|
327
|
+
|
|
328
|
+
return None
|
|
329
|
+
|
|
330
|
+
|
|
287
331
|
def parse_finish_reason(reason: str | None) -> FinishReason:
|
|
288
332
|
"""Parse the finish reason from LiteLLM response.
|
|
289
333
|
|
|
@@ -357,6 +401,7 @@ class LLMClient:
|
|
|
357
401
|
tool_choice: ToolChoice | None = None,
|
|
358
402
|
api_key: str | None = None,
|
|
359
403
|
timeout: float | None = None,
|
|
404
|
+
response_format: dict[str, Any] | None = None,
|
|
360
405
|
) -> CompletionResult:
|
|
361
406
|
"""Make a synchronous completion request.
|
|
362
407
|
|
|
@@ -415,6 +460,8 @@ class LLMClient:
|
|
|
415
460
|
request_kwargs["tool_choice"] = litellm_tool_choice
|
|
416
461
|
if timeout is not None:
|
|
417
462
|
request_kwargs["timeout"] = timeout
|
|
463
|
+
if response_format is not None:
|
|
464
|
+
request_kwargs["response_format"] = response_format
|
|
418
465
|
|
|
419
466
|
try:
|
|
420
467
|
response = litellm.completion(**request_kwargs)
|
|
@@ -456,6 +503,7 @@ class LLMClient:
|
|
|
456
503
|
tool_choice: ToolChoice | None = None,
|
|
457
504
|
api_key: str | None = None,
|
|
458
505
|
timeout: float | None = None,
|
|
506
|
+
response_format: dict[str, Any] | None = None,
|
|
459
507
|
) -> CompletionResult:
|
|
460
508
|
"""Make an asynchronous completion request.
|
|
461
509
|
|
|
@@ -514,6 +562,8 @@ class LLMClient:
|
|
|
514
562
|
request_kwargs["tool_choice"] = litellm_tool_choice
|
|
515
563
|
if timeout is not None:
|
|
516
564
|
request_kwargs["timeout"] = timeout
|
|
565
|
+
if response_format is not None:
|
|
566
|
+
request_kwargs["response_format"] = response_format
|
|
517
567
|
|
|
518
568
|
try:
|
|
519
569
|
response = await litellm.acompletion(**request_kwargs)
|
|
@@ -555,6 +605,7 @@ class LLMClient:
|
|
|
555
605
|
tool_choice: ToolChoice | None = None,
|
|
556
606
|
api_key: str | None = None,
|
|
557
607
|
timeout: float | None = None,
|
|
608
|
+
response_format: dict[str, Any] | None = None,
|
|
558
609
|
) -> tuple[Iterator[str], list[CompletionResult], LLMProvider]:
|
|
559
610
|
"""Make a streaming completion request.
|
|
560
611
|
|
|
@@ -614,6 +665,8 @@ class LLMClient:
|
|
|
614
665
|
request_kwargs["tool_choice"] = litellm_tool_choice
|
|
615
666
|
if timeout is not None:
|
|
616
667
|
request_kwargs["timeout"] = timeout
|
|
668
|
+
if response_format is not None:
|
|
669
|
+
request_kwargs["response_format"] = response_format
|
|
617
670
|
|
|
618
671
|
result_holder: list[CompletionResult] = []
|
|
619
672
|
|
|
@@ -717,6 +770,7 @@ class LLMClient:
|
|
|
717
770
|
tool_choice: ToolChoice | None = None,
|
|
718
771
|
api_key: str | None = None,
|
|
719
772
|
timeout: float | None = None,
|
|
773
|
+
response_format: dict[str, Any] | None = None,
|
|
720
774
|
) -> tuple[AsyncIterator[str], list[CompletionResult], LLMProvider]:
|
|
721
775
|
"""Make an async streaming completion request.
|
|
722
776
|
|
|
@@ -776,6 +830,8 @@ class LLMClient:
|
|
|
776
830
|
request_kwargs["tool_choice"] = litellm_tool_choice
|
|
777
831
|
if timeout is not None:
|
|
778
832
|
request_kwargs["timeout"] = timeout
|
|
833
|
+
if response_format is not None:
|
|
834
|
+
request_kwargs["response_format"] = response_format
|
|
779
835
|
|
|
780
836
|
result_holder: list[CompletionResult] = []
|
|
781
837
|
|
|
@@ -90,6 +90,26 @@ class ToolCall(BaseModel):
|
|
|
90
90
|
ToolChoice = Union[Literal["auto", "none", "required"], dict[str, str]]
|
|
91
91
|
|
|
92
92
|
|
|
93
|
+
# Response Format
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class ResponseFormatJsonSchema(BaseModel):
|
|
97
|
+
"""JSON schema response format for structured outputs."""
|
|
98
|
+
|
|
99
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
100
|
+
|
|
101
|
+
type: Literal["json"] = "json"
|
|
102
|
+
schema_: dict[str, Any] = Field(alias="schema")
|
|
103
|
+
name: str | None = None
|
|
104
|
+
description: str | None = None
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
ResponseFormat = Union[
|
|
108
|
+
dict[str, Any],
|
|
109
|
+
ResponseFormatJsonSchema,
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
|
|
93
113
|
# Messages
|
|
94
114
|
|
|
95
115
|
|
|
@@ -134,6 +154,7 @@ class RunLocalInput(BaseModel):
|
|
|
134
154
|
span_id: str | None = Field(default=None, alias="spanId")
|
|
135
155
|
tools: list[ToolDefinition] | None = None
|
|
136
156
|
tool_choice: ToolChoice | None = Field(default=None, alias="toolChoice")
|
|
157
|
+
response_format: ResponseFormat | None = Field(default=None, alias="responseFormat")
|
|
137
158
|
trace_id: str | None = Field(default=None, alias="traceId")
|
|
138
159
|
parent_span_id: str | None = Field(default=None, alias="parentSpanId")
|
|
139
160
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|