diff --git a/.release-please-manifest.json b/.release-please-manifest.json index d426d689..ce266685 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.2.0-alpha.43" + ".": "0.2.0-alpha.44" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index a6ef4d09..1b791912 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## 0.2.0-alpha.44 (2025-02-26) + +Full Changelog: [v0.2.0-alpha.43...v0.2.0-alpha.44](https://github.com/openlayer-ai/openlayer-python/compare/v0.2.0-alpha.43...v0.2.0-alpha.44) + +### Features + +* feat(tracing): completes OPEN-6538 Surface root step metadata at the request level ([1bcedcf](https://github.com/openlayer-ai/openlayer-python/commit/1bcedcf57d509064f89e2a5fae3fb39f22da5920)) + ## 0.2.0-alpha.43 (2025-02-24) Full Changelog: [v0.2.0-alpha.42...v0.2.0-alpha.43](https://github.com/openlayer-ai/openlayer-python/compare/v0.2.0-alpha.42...v0.2.0-alpha.43) diff --git a/pyproject.toml b/pyproject.toml index cb19b4dd..d4becc59 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openlayer" -version = "0.2.0-alpha.43" +version = "0.2.0-alpha.44" description = "The official Python library for the openlayer API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/openlayer/_version.py b/src/openlayer/_version.py index 628b0bc9..e2408930 100644 --- a/src/openlayer/_version.py +++ b/src/openlayer/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "openlayer" -__version__ = "0.2.0-alpha.43" # x-release-please-version +__version__ = "0.2.0-alpha.44" # x-release-please-version diff --git a/src/openlayer/lib/tracing/tracer.py b/src/openlayer/lib/tracing/tracer.py index b9ecc886..4057ad0d 100644 --- a/src/openlayer/lib/tracing/tracer.py +++ b/src/openlayer/lib/tracing/tracer.py @@ -131,7 +131,12 @@ def add_chat_completion_step_to_trace(**kwargs) -> None: # ----------------------------- Tracing decorator ---------------------------- # -def trace(*step_args, inference_pipeline_id: Optional[str] = None, context_kwarg: Optional[str] = None, **step_kwargs): +def trace( + *step_args, + inference_pipeline_id: Optional[str] = None, + context_kwarg: Optional[str] = None, + **step_kwargs, +): """Decorator to trace a function. Examples @@ -175,7 +180,9 @@ def decorator(func): def wrapper(*func_args, **func_kwargs): if step_kwargs.get("name") is None: step_kwargs["name"] = func.__name__ - with create_step(*step_args, inference_pipeline_id=inference_pipeline_id, **step_kwargs) as step: + with create_step( + *step_args, inference_pipeline_id=inference_pipeline_id, **step_kwargs + ) as step: output = exception = None try: output = func(*func_args, **func_kwargs) @@ -196,7 +203,10 @@ def wrapper(*func_args, **func_kwargs): if context_kwarg in inputs: log_context(inputs.get(context_kwarg)) else: - logger.warning("Context kwarg `%s` not found in inputs of the current function.", context_kwarg) + logger.warning( + "Context kwarg `%s` not found in inputs of the current function.", + context_kwarg, + ) step.log( inputs=inputs, @@ -215,7 +225,10 @@ def wrapper(*func_args, **func_kwargs): def trace_async( - *step_args, inference_pipeline_id: Optional[str] = None, context_kwarg: Optional[str] = None, **step_kwargs + *step_args, + inference_pipeline_id: Optional[str] = None, + context_kwarg: Optional[str] = None, + **step_kwargs, ): """Decorator to trace a function. @@ -260,7 +273,9 @@ def decorator(func): async def wrapper(*func_args, **func_kwargs): if step_kwargs.get("name") is None: step_kwargs["name"] = func.__name__ - with create_step(*step_args, inference_pipeline_id=inference_pipeline_id, **step_kwargs) as step: + with create_step( + *step_args, inference_pipeline_id=inference_pipeline_id, **step_kwargs + ) as step: output = exception = None try: output = await func(*func_args, **func_kwargs) @@ -281,7 +296,10 @@ async def wrapper(*func_args, **func_kwargs): if context_kwarg in inputs: log_context(inputs.get(context_kwarg)) else: - logger.warning("Context kwarg `%s` not found in inputs of the current function.", context_kwarg) + logger.warning( + "Context kwarg `%s` not found in inputs of the current function.", + context_kwarg, + ) step.log( inputs=inputs, @@ -299,7 +317,9 @@ async def wrapper(*func_args, **func_kwargs): return decorator -async def _invoke_with_context(coroutine: Awaitable[Any]) -> Tuple[contextvars.Context, Any]: +async def _invoke_with_context( + coroutine: Awaitable[Any], +) -> Tuple[contextvars.Context, Any]: """Runs a coroutine and preserves the context variables set within it.""" result = await coroutine context = contextvars.copy_context() @@ -356,6 +376,7 @@ def post_process_trace( "cost": processed_steps[0].get("cost", 0), "tokens": processed_steps[0].get("tokens", 0), "steps": processed_steps, + **root_step.metadata, } if input_variables: trace_data.update(input_variables)