From 1f887bac09e9e96e94a615a6ddbbaca55dd0daf2 Mon Sep 17 00:00:00 2001 From: etserend Date: Thu, 6 Aug 2026 15:11:20 -0500 Subject: [PATCH 1/5] fix(docs): replace stale log_stream with agent_stream in docstring examples (HYBIM-941) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - agent_stream.py: all example blocks now use agent_stream.* calls - agent_streams.py: enable_evaluators example blocks updated - singleton.py: rename log_stream/log_stream_id param docs to agent_stream/agent_stream_id across get(), reset(), flush(); fix body prose "log_stream" → "agent_stream" in flush() description - decorator.py: rename log_stream/log_stream_id param docs to agent_stream/agent_stream_id in get(), flush(), and reset() methods Co-Authored-By: Claude Opus 4.7 --- src/splunk_ao/agent_stream.py | 70 ++++++++++++++++---------------- src/splunk_ao/agent_streams.py | 4 +- src/splunk_ao/decorator.py | 22 +++++----- src/splunk_ao/utils/singleton.py | 24 +++++------ 4 files changed, 60 insertions(+), 60 deletions(-) diff --git a/src/splunk_ao/agent_stream.py b/src/splunk_ao/agent_stream.py index 5ba50dfc..e9a2c4b1 100644 --- a/src/splunk_ao/agent_stream.py +++ b/src/splunk_ao/agent_stream.py @@ -79,14 +79,14 @@ class AgentStream(StateManagementMixin): # Enable metrics on the log stream from splunk_ao.schema.metrics import SplunkAOEvaluators - local_metrics = log_stream.enable_evaluators([ + local_metrics = agent_stream.enable_evaluators([ SplunkAOEvaluators.correctness, SplunkAOEvaluators.completeness, "context_relevance" ]) # Refresh log stream state from API - log_stream.refresh() + agent_stream.refresh() """ created_at: datetime | None @@ -170,7 +170,7 @@ def create(self) -> AgentStream: Examples -------- agent_stream = AgentStream(name="Production Logs", project_name="My AI Project").create() - assert log_stream.is_synced() + assert agent_stream.is_synced() """ if not self.name: raise ValueError("Log stream name is not set. Cannot create log stream without a name.") @@ -371,8 +371,8 @@ def refresh(self) -> None: Examples -------- - log_stream.refresh() - assert log_stream.is_synced() + agent_stream.refresh() + assert agent_stream.is_synced() """ if self.id is None: raise ValueError("Log stream ID is not set. Cannot refresh a local-only log stream.") @@ -421,7 +421,7 @@ def get_metrics(self) -> builtins.list[str]: Examples -------- agent_stream = AgentStream.get(name="Production Logs", project_name="My Project") - current_metrics = log_stream.get_metrics() + current_metrics = agent_stream.get_metrics() print(f"Currently enabled: {current_metrics}") """ logger.info(f"AgentStream.get_metrics: id='{self.id}' - started") @@ -472,7 +472,7 @@ def set_metrics( agent_stream = AgentStream.get(name="Production Logs", project_name="My Project") # Set evaluators (replaces existing) - log_stream.set_metrics([ + agent_stream.set_metrics([ Evaluator.metrics.correctness, Evaluator.metrics.completeness, Evaluator.get(id="evaluator-from-console-uuid"), # From console @@ -530,14 +530,14 @@ def query( agent_stream = AgentStream.get(name="Production Logs", project_name="My AI Project") # Query with column-based filters and sort - results = log_stream.query( + results = agent_stream.query( record_type=RecordType.SPAN, filters=[ - log_stream.span_columns["input"].contains("largest"), - log_stream.span_columns["metrics/completeness_gpt"].greater_than(0.8), - log_stream.span_columns["created_at"].after("2024-01-01") + agent_stream.span_columns["input"].contains("largest"), + agent_stream.span_columns["metrics/completeness_gpt"].greater_than(0.8), + agent_stream.span_columns["created_at"].after("2024-01-01") ], - sort=log_stream.span_columns["created_at"].descending(), + sort=agent_stream.span_columns["created_at"].descending(), limit=50 ) @@ -626,12 +626,12 @@ def get_spans( agent_stream = AgentStream.get(name="Production Logs", project_name="My AI Project") # Get spans with filters and sorting - spans = log_stream.get_spans( + spans = agent_stream.get_spans( filters=[ - log_stream.span_columns["input"].contains("world"), - log_stream.span_columns["metrics/num_input_tokens"].greater_than(10) + agent_stream.span_columns["input"].contains("world"), + agent_stream.span_columns["metrics/num_input_tokens"].greater_than(10) ], - sort=log_stream.span_columns["created_at"].descending(), + sort=agent_stream.span_columns["created_at"].descending(), limit=50 ) @@ -679,12 +679,12 @@ def get_traces( agent_stream = AgentStream.get(name="Production Logs", project_name="My AI Project") # Get traces with filters - traces = log_stream.get_traces( + traces = agent_stream.get_traces( filters=[ - log_stream.trace_columns["input"].contains("largest"), - log_stream.trace_columns["created_at"].after("2024-01-01") + agent_stream.trace_columns["input"].contains("largest"), + agent_stream.trace_columns["created_at"].after("2024-01-01") ], - sort=log_stream.trace_columns["created_at"].descending(), + sort=agent_stream.trace_columns["created_at"].descending(), limit=50 ) @@ -728,12 +728,12 @@ def get_sessions( agent_stream = AgentStream.get(name="Production Logs", project_name="My AI Project") # Get sessions with filters - sessions = log_stream.get_sessions( + sessions = agent_stream.get_sessions( filters=[ - log_stream.session_columns["model"].equals("gpt-4o-mini"), - log_stream.session_columns["metrics/num_traces"].greater_than(5) + agent_stream.session_columns["model"].equals("gpt-4o-mini"), + agent_stream.session_columns["metrics/num_traces"].greater_than(5) ], - sort=log_stream.session_columns["created_at"].descending(), + sort=agent_stream.session_columns["created_at"].descending(), limit=50 ) @@ -784,13 +784,13 @@ def export_records( agent_stream = AgentStream.get(name="Production Logs", project_name="My AI Project") # Export records with filters - for record in log_stream.export_records( + for record in agent_stream.export_records( record_type=RecordType.SPAN, filters=[ - log_stream.span_columns["model"].one_of(["gpt-4", "gpt-3.5-turbo", "gpt-4o-mini"]), - log_stream.span_columns["metrics/num_input_tokens"].greater_than(1) + agent_stream.span_columns["model"].one_of(["gpt-4", "gpt-3.5-turbo", "gpt-4o-mini"]), + agent_stream.span_columns["metrics/num_input_tokens"].greater_than(1) ], - sort=log_stream.span_columns["created_at"].descending() + sort=agent_stream.span_columns["created_at"].descending() ): print(record) """ @@ -836,7 +836,7 @@ def context(self) -> Any: project_name="My AI Project" ) - with log_stream.context(): + with agent_stream.context(): # Your logging code here response = openai_client.chat.completions.create(...) """ @@ -879,13 +879,13 @@ def span_columns(self) -> ColumnCollection: Examples -------- agent_stream = AgentStream.get(name="Production Logs", project_name="My AI Project") - columns = log_stream.span_columns + columns = agent_stream.span_columns # Access a specific column input_column = columns["input"] # Filter using columns - spans = log_stream.get_spans( + spans = agent_stream.get_spans( filters=[columns["input"].contains("world")], sort=columns["created_at"].descending() ) @@ -912,13 +912,13 @@ def session_columns(self) -> ColumnCollection: Examples -------- agent_stream = AgentStream.get(name="Production Logs", project_name="My AI Project") - columns = log_stream.session_columns + columns = agent_stream.session_columns # Access a specific column model_column = columns["model"] # Filter using columns - sessions = log_stream.get_sessions( + sessions = agent_stream.get_sessions( filters=[columns["model"].equals("gpt-4o-mini")], sort=columns["created_at"].descending() ) @@ -946,13 +946,13 @@ def trace_columns(self) -> ColumnCollection: Examples -------- agent_stream = AgentStream.get(name="Production Logs", project_name="My AI Project") - columns = log_stream.trace_columns + columns = agent_stream.trace_columns # Access a specific column input_column = columns["input"] # Filter using columns - traces = log_stream.get_traces( + traces = agent_stream.get_traces( filters=[columns["input"].contains("largest")], sort=columns["created_at"].descending() ) diff --git a/src/splunk_ao/agent_streams.py b/src/splunk_ao/agent_streams.py index 84ad68e6..b8c9c1c6 100644 --- a/src/splunk_ao/agent_streams.py +++ b/src/splunk_ao/agent_streams.py @@ -176,7 +176,7 @@ def enable_evaluators( agent_stream = log_streams.get(name="Production Logs", project_name="My AI Project") # Enable metrics directly - clean and intuitive! - local_metrics = log_stream.enable_evaluators([ + local_metrics = agent_stream.enable_evaluators([ SplunkAOEvaluators.correctness, SplunkAOEvaluators.completeness, "context_relevance", @@ -195,7 +195,7 @@ def enable_evaluators( def custom_scorer(trace_or_span): return 0.75 # Your scoring logic - local_metrics = log_stream.enable_evaluators([ + local_metrics = agent_stream.enable_evaluators([ SplunkAOEvaluators.correctness, "completeness", Metric(name="domain_relevance", version=3), diff --git a/src/splunk_ao/decorator.py b/src/splunk_ao/decorator.py index 99dd26ec..3fd8fd84 100644 --- a/src/splunk_ao/decorator.py +++ b/src/splunk_ao/decorator.py @@ -1209,10 +1209,10 @@ def get_logger_instance( Optional project name to use project_id Optional project ID to use - log_stream - Optional log stream name to use - log_stream_id - Optional log stream ID to use + agent_stream + Optional agent stream name to use + agent_stream_id + Optional agent stream ID to use experiment_id Optional experiment ID to use mode @@ -1309,16 +1309,16 @@ def flush( on_error: Callable[[Exception], None] | None = None, ) -> None: """ - Upload all captured traces under a project and log stream context to Splunk AO. + Upload all captured traces under a project and agent stream context to Splunk AO. - If no project or log stream is provided, then the currently initialized context is used. + If no project or agent stream is provided, then the currently initialized context is used. Parameters ---------- project The project name. Defaults to None. - log_stream - The log stream name. Defaults to None. + agent_stream + The agent stream name. Defaults to None. experiment_id The experiment ID. Defaults to None. mode @@ -1405,14 +1405,14 @@ def init( to start a trace. This method resets the existing active context with a new context with - the specified project and log stream. + the specified project and agent stream. Parameters ---------- project The project name. Defaults to None. - log_stream - The log stream name. Defaults to None. + agent_stream + The agent stream name. Defaults to None. experiment_id The experiment id. Defaults to None. local_metrics diff --git a/src/splunk_ao/utils/singleton.py b/src/splunk_ao/utils/singleton.py index 93cdccde..19407e6f 100644 --- a/src/splunk_ao/utils/singleton.py +++ b/src/splunk_ao/utils/singleton.py @@ -165,7 +165,7 @@ def get( """ Retrieve an existing SplunkAOLogger or create a new one if it does not exist. - This method first computes the key from the project and log_stream parameters, + This method first computes the key from the project and agent_stream parameters, checks if a logger exists in the cache, and if not, creates a new SplunkAOLogger. The creation and caching are done in a thread-safe manner. @@ -173,8 +173,8 @@ def get( ---------- project (Optional[str], optional) The project name. Defaults to None. - log_stream (Optional[str], optional) - The log stream name. Defaults to None. + agent_stream (Optional[str], optional) + The agent stream name. Defaults to None. experiment_id (Optional[str], optional) The experiment ID. Defaults to None. local_metrics (Optional[list[LocalScorerConfig]], optional) @@ -252,10 +252,10 @@ def reset( The project name. Defaults to None. project_id (Optional[str], optional) The project ID. Defaults to None. - log_stream (Optional[str], optional) - The log stream name. Defaults to None. - log_stream_id (Optional[str], optional) - The log stream ID. Defaults to None. + agent_stream (Optional[str], optional) + The agent stream name. Defaults to None. + agent_stream_id (Optional[str], optional) + The agent stream ID. Defaults to None. experiment_id (Optional[str], optional) The experiment ID. Defaults to None. mode (Optional[str], optional) @@ -297,7 +297,7 @@ def flush( """ Flush (upload and clear) a SplunkAOLogger instance. - If both project and log_stream are None, then all cached loggers are flushed + If both project and agent_stream are None, then all cached loggers are flushed and cleared. Otherwise, only the specific logger corresponding to the provided key (project, agent_stream) is flushed and removed. @@ -307,10 +307,10 @@ def flush( The project name. Defaults to None. project_id (Optional[str], optional) The project ID. Defaults to None. - log_stream (Optional[str], optional) - The log stream name. Defaults to None. - log_stream_id (Optional[str], optional) - The log stream ID. Defaults to None. + agent_stream (Optional[str], optional) + The agent stream name. Defaults to None. + agent_stream_id (Optional[str], optional) + The agent stream ID. Defaults to None. experiment_id (Optional[str], optional) The experiment ID. Defaults to None. mode (Optional[str], optional) From 00f4df27b06cc4b659231efb9b4d8cdb900a8bfb Mon Sep 17 00:00:00 2001 From: etserend Date: Thu, 6 Aug 2026 16:16:44 -0500 Subject: [PATCH 2/5] fix(docs): address inline review comments on stale log_stream references MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - decorator.py: fix malformed agent_stream param (inline style + duplicate description → NumPy convention) - agent_stream.py: rename log_streams variable to agent_streams in list() docstring examples; update caption prose - agent_streams.py: rename log_streams variable and "Log Stream:" log message to agent_streams / "Agent Stream:" in class docstring Co-Authored-By: Claude Opus 4.7 --- src/splunk_ao/agent_stream.py | 10 +++++----- src/splunk_ao/agent_streams.py | 8 ++++---- src/splunk_ao/decorator.py | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/splunk_ao/agent_stream.py b/src/splunk_ao/agent_stream.py index e9a2c4b1..3127278e 100644 --- a/src/splunk_ao/agent_stream.py +++ b/src/splunk_ao/agent_stream.py @@ -330,16 +330,16 @@ def list( Examples -------- # List by project name - log_streams = AgentStream.list(project_name="My AI Project") + agent_streams = AgentStream.list(project_name="My AI Project") # List by project ID - log_streams = AgentStream.list(project_id="project-123") + agent_streams = AgentStream.list(project_id="project-123") # List using SPLUNK_AO_PROJECT environment variable - log_streams = AgentStream.list() + agent_streams = AgentStream.list() - # Cap the number of returned log streams - log_streams = AgentStream.list(project_name="My AI Project", limit=3) + # Cap the number of returned agent streams + agent_streams = AgentStream.list(project_name="My AI Project", limit=3) # Fetch the next page page_2 = AgentStream.list(project_name="My AI Project", starting_token=100) diff --git a/src/splunk_ao/agent_streams.py b/src/splunk_ao/agent_streams.py index b8c9c1c6..309d0959 100644 --- a/src/splunk_ao/agent_streams.py +++ b/src/splunk_ao/agent_streams.py @@ -60,11 +60,11 @@ class AgentStream(LogStreamResponse): from splunk_ao.agent_streams import get_agent_stream agent_stream = get_agent_stream(name="Production Logs", project_name="My AI Project") - # List all log streams in a project + # List all agent streams in a project from splunk_ao.agent_streams import list_agent_streams - log_streams = list_agent_streams(project_name="My AI Project") - for stream in log_streams: - logger.info(f"Log Stream: {stream.name} (ID: {stream.id})") + agent_streams = list_agent_streams(project_name="My AI Project") + for stream in agent_streams: + logger.info(f"Agent Stream: {stream.name} (ID: {stream.id})") # Use a log stream with the context manager from splunk_ao.openai import openai diff --git a/src/splunk_ao/decorator.py b/src/splunk_ao/decorator.py index 3fd8fd84..b0fe3381 100644 --- a/src/splunk_ao/decorator.py +++ b/src/splunk_ao/decorator.py @@ -212,8 +212,8 @@ def __call__( ---------- project The project name to use for this context - agent_stream: The log stream name to use for this context - The log stream name to use for this context + agent_stream + The agent stream name to use for this context experiment_id The experiment ID to use for this context mode From 050f699396bc9ab2debd82e40249c09e4dd12fd6 Mon Sep 17 00:00:00 2001 From: Erdenesaikhan Tserendavga <105012329+etserend@users.noreply.github.com> Date: Thu, 6 Aug 2026 16:49:22 -0500 Subject: [PATCH 3/5] Update src/splunk_ao/agent_stream.py Co-authored-by: Fernando Correia --- src/splunk_ao/agent_stream.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/splunk_ao/agent_stream.py b/src/splunk_ao/agent_stream.py index 3127278e..eef5f087 100644 --- a/src/splunk_ao/agent_stream.py +++ b/src/splunk_ao/agent_stream.py @@ -79,7 +79,9 @@ class AgentStream(StateManagementMixin): # Enable metrics on the log stream from splunk_ao.schema.metrics import SplunkAOEvaluators - local_metrics = agent_stream.enable_evaluators([ + # Enable metrics on the agent stream + from splunk_ao.schema.metrics import SplunkAOEvaluators + local_metrics = agent_stream.set_metrics([ SplunkAOEvaluators.correctness, SplunkAOEvaluators.completeness, "context_relevance" From b4318ad48ec79bf9da5a1f7fe4f3b5a806445619 Mon Sep 17 00:00:00 2001 From: Erdenesaikhan Tserendavga <105012329+etserend@users.noreply.github.com> Date: Thu, 6 Aug 2026 16:49:59 -0500 Subject: [PATCH 4/5] Update src/splunk_ao/agent_streams.py Co-authored-by: Fernando Correia --- src/splunk_ao/agent_streams.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/splunk_ao/agent_streams.py b/src/splunk_ao/agent_streams.py index 309d0959..63ad15b4 100644 --- a/src/splunk_ao/agent_streams.py +++ b/src/splunk_ao/agent_streams.py @@ -173,7 +173,9 @@ def enable_evaluators( # Get a log stream first log_streams = AgentStreams() - agent_stream = log_streams.get(name="Production Logs", project_name="My AI Project") + # Get an agent stream first + agent_streams = AgentStreams() + agent_stream = agent_streams.get(name="Production Logs", project_name="My AI Project") # Enable metrics directly - clean and intuitive! local_metrics = agent_stream.enable_evaluators([ From 1c2833cecb1ce8ddf01c7bf7c44ac45bbd7c8d40 Mon Sep 17 00:00:00 2001 From: etserend Date: Thu, 6 Aug 2026 17:10:26 -0500 Subject: [PATCH 5/5] fix(docs): fix remaining stale log_stream prose in published docstrings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - singleton.py: class docstring "log_stream" parameter reference → "agent_stream" - decorator.py: Returns section "project and log stream" → "project and agent stream" - decorator.py: init_context short description "log stream" → "agent stream" Co-Authored-By: Claude Opus 4.7 --- src/splunk_ao/decorator.py | 4 ++-- src/splunk_ao/utils/singleton.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/splunk_ao/decorator.py b/src/splunk_ao/decorator.py index b0fe3381..fb02472b 100644 --- a/src/splunk_ao/decorator.py +++ b/src/splunk_ao/decorator.py @@ -1220,7 +1220,7 @@ def get_logger_instance( Returns ------- - SplunkAOLogger instance configured with the specified project and log stream + SplunkAOLogger instance configured with the specified project and agent stream """ kwargs = { "project": project if project is not None else (None if project_id is not None else _project_context.get()), @@ -1401,7 +1401,7 @@ def init( mode: str | None = None, ) -> None: """ - Initialize the context with a project and log stream. Optionally, it can also be used + Initialize the context with a project and agent stream. Optionally, it can also be used to start a trace. This method resets the existing active context with a new context with diff --git a/src/splunk_ao/utils/singleton.py b/src/splunk_ao/utils/singleton.py index 19407e6f..99c00017 100644 --- a/src/splunk_ao/utils/singleton.py +++ b/src/splunk_ao/utils/singleton.py @@ -18,7 +18,7 @@ class SplunkAOLoggerSingleton: This class ensures that only one instance exists across the application and provides a thread-safe way to retrieve or create SplunkAOLogger clients based on - the given 'project' and 'log_stream' parameters. If the parameters are not provided, + the given 'project' and 'agent_stream' parameters. If the parameters are not provided, the class attempts to read the values from the environment variables SPLUNK_AO_PROJECT and SPLUNK_AO_AGENT_STREAM. The loggers are stored in a dictionary using a tuple (project, agent_stream) as the key.