From bacfb3d7396d0c4ef23503692f7e9144654b79e5 Mon Sep 17 00:00:00 2001 From: Andrii Soldatenko Date: Wed, 4 Jun 2025 21:23:18 +0200 Subject: [PATCH 1/6] feat: add add_agent_span method to GalileoLogger --- pyproject.toml | 4 ++-- src/galileo/logger.py | 41 +++++++++++++++++++++++++++++++++++++++++ tests/test_logger.py | 32 +++++++++++++++++++++++++++++++- 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 3583b7a8..f57ed017 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ langchain-core = { version = "^0.3.61", optional = true } openai = { version = "<1.84.0", optional = true } openai-agents = { version = "<0.0.13", optional = true } -galileo-core = "~=3.38.0" +galileo-core = { git = "https://github.com/rungalileo/galileo-core.git", branch = "add-agent-span-type" } [tool.poetry.group.test.dependencies] pytest = "^8.3.5" @@ -28,7 +28,7 @@ pytest-xdist = "^3.3.1" pytest-socket = "^0.7" pytest-asyncio = "^0.26.0" requests-mock = "^1.11.0" -galileo-core = { extras = ["testing"], version = "~=3.38.0" } +galileo-core = { extras = ["testing"], git = "https://github.com/rungalileo/galileo-core.git", branch = "add-agent-span-type" } pytest-env = "^1.1.5" langchain-core = "^0.3.61" pytest-sugar = "^1.0.0" diff --git a/src/galileo/logger.py b/src/galileo/logger.py index d4df5545..14f6e59e 100644 --- a/src/galileo/logger.py +++ b/src/galileo/logger.py @@ -19,7 +19,9 @@ from galileo.utils.metrics import populate_local_metrics from galileo.utils.nop_logger import nop_async, nop_sync from galileo.utils.serialization import serialize_to_str +from galileo_core.schemas.logging.agent import AgentType from galileo_core.schemas.logging.span import ( + AgentSpan, LlmSpan, LlmSpanAllowedInputType, LlmSpanAllowedOutputType, @@ -519,6 +521,45 @@ def add_workflow_span( tags=tags, ) + @nop_sync + def add_agent_span( + self, + input: str, + output: Optional[str] = None, + name: Optional[str] = None, + duration_ns: Optional[int] = None, + created_at: Optional[datetime] = None, + metadata: Optional[dict[str, str]] = None, + tags: Optional[list[str]] = None, + agent_type: Optional[AgentType] = None, + ) -> AgentSpan: + """ + TODO: need description + + Args: + input: str: Input to the node. + output: Optional[str]: Output of the node. This can also be set on conclude(). + name: Optional[str]: Name of the span. + duration_ns: Optional[int]: duration_ns of the node in nanoseconds. + created_at: Optional[datetime]: Timestamp of the span's creation. + metadata: Optional[Dict[str, str]]: Metadata associated with this span. + agent_type: + + Returns: + ------- + AgentSpan: The created span. + """ + return super().add_agent_span( + input=input, + output=output, + name=name, + duration_ns=duration_ns, + created_at=created_at, + user_metadata=metadata, + tags=tags, + agent_type=agent_type, + ) + @nop_sync def conclude( self, diff --git a/tests/test_logger.py b/tests/test_logger.py index d8918559..b8821492 100644 --- a/tests/test_logger.py +++ b/tests/test_logger.py @@ -10,7 +10,8 @@ from galileo.logger import GalileoLogger from galileo.schema.metrics import LocalMetricConfig from galileo.schema.trace import TracesIngestRequest -from galileo_core.schemas.logging.span import LlmSpan, RetrieverSpan, Span, ToolSpan, WorkflowSpan +from galileo_core.schemas.logging.agent import AgentType +from galileo_core.schemas.logging.span import AgentSpan, LlmSpan, RetrieverSpan, Span, ToolSpan, WorkflowSpan from galileo_core.schemas.logging.step import Metrics from galileo_core.schemas.logging.trace import Trace from galileo_core.schemas.shared.document import Document @@ -203,6 +204,35 @@ def test_nested_span_trace_to_galileo( assert logger._parent_stack == deque() +@patch("galileo.logger.LogStreams") +@patch("galileo.logger.Projects") +@patch("galileo.logger.GalileoCoreApiClient") +def test_add_agent_span(mock_core_api_client: Mock, mock_projects_client: Mock, mock_logstreams_client: Mock) -> None: + mock_core_api_instance = setup_mock_core_api_client(mock_core_api_client) + setup_mock_projects_client(mock_projects_client) + setup_mock_logstreams_client(mock_logstreams_client) + + created_at = datetime.datetime.now() + metadata = {"key": "value"} + logger = GalileoLogger(project="my_project", log_stream="my_log_stream") + trace = logger.start_trace( + input="input", name="test-trace", duration_ns=1_000_000, created_at=created_at, metadata=metadata + ) + + logger.add_agent_span(input="prompt", name="test-agent-span", created_at=created_at, metadata=metadata) + + logger.conclude(output="response", duration_ns=1_000_000, status_code=200) + logger.flush() + + payload = mock_core_api_instance.ingest_traces_sync.call_args[0][0] + expected_payload = TracesIngestRequest(log_stream_id=None, experiment_id=None, traces=[trace]) + assert payload == expected_payload + assert isinstance(payload.traces[0].spans[0], AgentSpan) + assert payload.traces[0].spans[0].agent_type == AgentType.default + assert logger.traces == list() + assert logger._parent_stack == deque() + + @patch("galileo.logger.LogStreams") @patch("galileo.logger.Projects") @patch("galileo.logger.GalileoCoreApiClient") From 35b5dde1a59312f22f398188577073672d556b2a Mon Sep 17 00:00:00 2001 From: Andrii Soldatenko Date: Thu, 5 Jun 2025 20:05:53 +0200 Subject: [PATCH 2/6] switch to release version of core --- pyproject.toml | 5 +++-- tasks.py | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f57ed017..ff44aed1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ langchain-core = { version = "^0.3.61", optional = true } openai = { version = "<1.84.0", optional = true } openai-agents = { version = "<0.0.13", optional = true } -galileo-core = { git = "https://github.com/rungalileo/galileo-core.git", branch = "add-agent-span-type" } +galileo-core = "^3.40.0" [tool.poetry.group.test.dependencies] pytest = "^8.3.5" @@ -28,7 +28,8 @@ pytest-xdist = "^3.3.1" pytest-socket = "^0.7" pytest-asyncio = "^0.26.0" requests-mock = "^1.11.0" -galileo-core = { extras = ["testing"], git = "https://github.com/rungalileo/galileo-core.git", branch = "add-agent-span-type" } +galileo-core = { extras = ["testing"], version = "^3.40.0" } + pytest-env = "^1.1.5" langchain-core = "^0.3.61" pytest-sugar = "^1.0.0" diff --git a/tasks.py b/tasks.py index c598b10a..bd9cfff9 100644 --- a/tasks.py +++ b/tasks.py @@ -49,3 +49,16 @@ def type_check(ctx: Context) -> None: @task def docs_build(ctx: Context) -> None: ctx.run("poetry run mkdocs build --verbose", **COMMON_PARAMS) + + +@task +def poetry_lock(ctx: Context) -> None: + """ + Update poetry.lock file. + + Parameters + ---------- + ctx : Context + Invoke context. + """ + ctx.run("poetry lock", **COMMON_PARAMS) From 1554ad863b6d6c5a14ef45464060e682bfda5db3 Mon Sep 17 00:00:00 2001 From: Andrii Soldatenko Date: Thu, 5 Jun 2025 20:07:44 +0200 Subject: [PATCH 3/6] remove TODO --- poetry.lock | 11 ++++------- src/galileo/logger.py | 7 ++++--- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/poetry.lock b/poetry.lock index 7667aa2e..ab2705b8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -716,14 +716,14 @@ typing = ["typing-extensions (>=4.12.2) ; python_version < \"3.11\""] [[package]] name = "galileo-core" -version = "3.38.0" +version = "3.40.0" description = "Shared schemas and configuration for Galileo's Python packages." optional = false python-versions = ">=3.8.1" groups = ["main", "test"] files = [ - {file = "galileo_core-3.38.0-py3-none-any.whl", hash = "sha256:6e5235ce898dd7d2cf0f6050d2a6a82b8255a469247739eaf3e6bf091e94d6cd"}, - {file = "galileo_core-3.38.0.tar.gz", hash = "sha256:a991d4c7452d08e376bce451704d78b2e81dbf7eb21a8019530796bf1841e2f3"}, + {file = "galileo_core-3.40.0-py3-none-any.whl", hash = "sha256:51bf98eec856215b17c7b82c4e9a9e77797f05c1d5429cb8294ca30deffebc0a"}, + {file = "galileo_core-3.40.0.tar.gz", hash = "sha256:e130e4fe6223fe87a9eae1410dcfa9ecd8cd0559c4c3666094a76d08ffa16c70"}, ] [package.dependencies] @@ -1511,11 +1511,8 @@ files = [ {file = "lxml-5.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7ce1a171ec325192c6a636b64c94418e71a1964f56d002cc28122fceff0b6121"}, {file = "lxml-5.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:795f61bcaf8770e1b37eec24edf9771b307df3af74d1d6f27d812e15a9ff3872"}, {file = "lxml-5.4.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29f451a4b614a7b5b6c2e043d7b64a15bd8304d7e767055e8ab68387a8cacf4e"}, - {file = "lxml-5.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:891f7f991a68d20c75cb13c5c9142b2a3f9eb161f1f12a9489c82172d1f133c0"}, {file = "lxml-5.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4aa412a82e460571fad592d0f93ce9935a20090029ba08eca05c614f99b0cc92"}, - {file = "lxml-5.4.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:ac7ba71f9561cd7d7b55e1ea5511543c0282e2b6450f122672a2694621d63b7e"}, {file = "lxml-5.4.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:c5d32f5284012deaccd37da1e2cd42f081feaa76981f0eaa474351b68df813c5"}, - {file = "lxml-5.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:ce31158630a6ac85bddd6b830cffd46085ff90498b397bd0a259f59d27a12188"}, {file = "lxml-5.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:31e63621e073e04697c1b2d23fcb89991790eef370ec37ce4d5d469f40924ed6"}, {file = "lxml-5.4.0-cp37-cp37m-win32.whl", hash = "sha256:be2ba4c3c5b7900246a8f866580700ef0d538f2ca32535e991027bdaba944063"}, {file = "lxml-5.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:09846782b1ef650b321484ad429217f5154da4d6e786636c38e434fa32e94e49"}, @@ -4212,4 +4209,4 @@ openai = ["openai", "openai-agents", "packaging"] [metadata] lock-version = "2.1" python-versions = "^3.9,<3.14" -content-hash = "6704034d2dbd3673c490319425b62f09dc67db814f2d32f17e12b4e197c2bc30" +content-hash = "9b3e973dfca45fdc1ab4605ead7b5a778bbcec5bd669f155c9faba5a8d9671c2" diff --git a/src/galileo/logger.py b/src/galileo/logger.py index 14f6e59e..c50d7fae 100644 --- a/src/galileo/logger.py +++ b/src/galileo/logger.py @@ -534,16 +534,17 @@ def add_agent_span( agent_type: Optional[AgentType] = None, ) -> AgentSpan: """ - TODO: need description + Add an agent type span to the current parent. - Args: + Parameters: + ---------- input: str: Input to the node. output: Optional[str]: Output of the node. This can also be set on conclude(). name: Optional[str]: Name of the span. duration_ns: Optional[int]: duration_ns of the node in nanoseconds. created_at: Optional[datetime]: Timestamp of the span's creation. metadata: Optional[Dict[str, str]]: Metadata associated with this span. - agent_type: + agent_type: Optional[AgentType]: Agent type of the span. Returns: ------- From befaffbfe5e3857b719c7d3dfae0113faa661697 Mon Sep 17 00:00:00 2001 From: Andrii Soldatenko Date: Fri, 6 Jun 2025 16:17:23 +0200 Subject: [PATCH 4/6] empty commit From 3ed4c0ec32dbdb1f077472b46ce0ecae475e86ab Mon Sep 17 00:00:00 2001 From: Andrii Soldatenko Date: Fri, 6 Jun 2025 16:32:55 +0200 Subject: [PATCH 5/6] update --- poetry.lock | 2 +- pyproject.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index ab2705b8..bacb616b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4209,4 +4209,4 @@ openai = ["openai", "openai-agents", "packaging"] [metadata] lock-version = "2.1" python-versions = "^3.9,<3.14" -content-hash = "9b3e973dfca45fdc1ab4605ead7b5a778bbcec5bd669f155c9faba5a8d9671c2" +content-hash = "475a54f768854f6c52c25b8553ccab8db6e9e7e4616e642742a205a9d397bfdb" diff --git a/pyproject.toml b/pyproject.toml index ff44aed1..2e2e55e9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ langchain-core = { version = "^0.3.61", optional = true } openai = { version = "<1.84.0", optional = true } openai-agents = { version = "<0.0.13", optional = true } -galileo-core = "^3.40.0" +galileo-core = "~=3.40.0" [tool.poetry.group.test.dependencies] pytest = "^8.3.5" @@ -28,7 +28,7 @@ pytest-xdist = "^3.3.1" pytest-socket = "^0.7" pytest-asyncio = "^0.26.0" requests-mock = "^1.11.0" -galileo-core = { extras = ["testing"], version = "^3.40.0" } +galileo-core = { extras = ["testing"], version = "~=3.40.0" } pytest-env = "^1.1.5" langchain-core = "^0.3.61" From 57efa1970fb76bb842ce4698845601620d229fa6 Mon Sep 17 00:00:00 2001 From: Andrii Soldatenko Date: Fri, 6 Jun 2025 19:22:04 +0200 Subject: [PATCH 6/6] fixup --- poetry.lock | 3 +++ 1 file changed, 3 insertions(+) diff --git a/poetry.lock b/poetry.lock index bacb616b..a33fddc4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1511,8 +1511,11 @@ files = [ {file = "lxml-5.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7ce1a171ec325192c6a636b64c94418e71a1964f56d002cc28122fceff0b6121"}, {file = "lxml-5.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:795f61bcaf8770e1b37eec24edf9771b307df3af74d1d6f27d812e15a9ff3872"}, {file = "lxml-5.4.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29f451a4b614a7b5b6c2e043d7b64a15bd8304d7e767055e8ab68387a8cacf4e"}, + {file = "lxml-5.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:891f7f991a68d20c75cb13c5c9142b2a3f9eb161f1f12a9489c82172d1f133c0"}, {file = "lxml-5.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4aa412a82e460571fad592d0f93ce9935a20090029ba08eca05c614f99b0cc92"}, + {file = "lxml-5.4.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:ac7ba71f9561cd7d7b55e1ea5511543c0282e2b6450f122672a2694621d63b7e"}, {file = "lxml-5.4.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:c5d32f5284012deaccd37da1e2cd42f081feaa76981f0eaa474351b68df813c5"}, + {file = "lxml-5.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:ce31158630a6ac85bddd6b830cffd46085ff90498b397bd0a259f59d27a12188"}, {file = "lxml-5.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:31e63621e073e04697c1b2d23fcb89991790eef370ec37ce4d5d469f40924ed6"}, {file = "lxml-5.4.0-cp37-cp37m-win32.whl", hash = "sha256:be2ba4c3c5b7900246a8f866580700ef0d538f2ca32535e991027bdaba944063"}, {file = "lxml-5.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:09846782b1ef650b321484ad429217f5154da4d6e786636c38e434fa32e94e49"},