Skip to content

HYBIM-935: Rename log stream → agent stream (SDK-only) - #185

Merged
shuningc merged 8 commits into
mainfrom
HYBIM-935
Jul 30, 2026
Merged

HYBIM-935: Rename log stream → agent stream (SDK-only)#185
shuningc merged 8 commits into
mainfrom
HYBIM-935

Conversation

@shuningc

Copy link
Copy Markdown
Contributor

Summary

Renames log stream → agent stream across the Splunk AO Python SDK public API, internal helpers, examples, ADK, and tests — while keeping all backend wire formats unchanged until rungalileo/api adopts the new terminology.
This is a SDK-only breaking change. OTLP headers, OTLP resource attributes, REST JSON field names, and Agent Control target_type values remain aligned with the current backend.

Motivation

HYBIM-935 aligns SDK terminology with the product rename without breaking live integrations. Backend OpenAPI still uses log_stream_id; OTLP routing still expects logstream / logstreamid headers and splunk_ao.logstream.* resource attributes.

Breaking changes

Context & logger

# Before
with splunk_ao_context(project="my-project", log_stream="production"):
    ...
logger = SplunkAOLogger(project="my-project", log_stream="production")
logger.log_stream_name
logger.log_stream_id
splunk_ao_context.get_current_log_stream()
# After
with splunk_ao_context(project="my-project", agent_stream="production"):
    ...
logger = SplunkAOLogger(project="my-project", agent_stream="production")
logger.agent_stream_name
logger.agent_stream_id
splunk_ao_context.get_current_agent_stream()

Traces, export, search, evaluators, annotation queues

# Before
Traces(project_id="...", log_stream_id="...")
export_records(project_id="...", log_stream_id="...")
get_spans(project_id="...", log_stream_id="...")
get_evaluators(project_id="...", log_stream_id="...")
add_records_to_annotation_queue(..., log_stream_id="...")
# After
Traces(project_id="...", agent_stream_id="...")
export_records(project_id="...", agent_stream_id="...")
get_spans(project_id="...", agent_stream_id="...")
get_evaluators(project_id="...", agent_stream_id="...")
add_records_to_annotation_queue(..., agent_stream_id="...")

Agent Control & OTel

# Before
get_agent_control_target(log_stream_id="...")
SplunkAOSpanProcessor(logstream="production")
SplunkAOSpanProcessor(log_stream_id="...")
# After
get_agent_control_target(agent_stream_id="...")
SplunkAOSpanProcessor(agentstream="production")  # logstream= rejected
SplunkAOSpanProcessor(agent_stream_id="...")     # log_stream_id= rejected

Constants

# Before
DEFAULT_LOG_STREAM_NAME
# After
DEFAULT_AGENT_STREAM_NAME

Environment variables

# Before
SPLUNK_AO_LOG_STREAM
SPLUNK_AO_LOG_STREAM_ID
# After (preferred)
SPLUNK_AO_AGENT_STREAM
SPLUNK_AO_AGENT_STREAM_ID
# Note: old env vars still work as deprecated aliases

Intentionally unchanged (backend wire format)

Layer Value sent to backend
OTLP HTTP headers logstream, logstreamid
OTLP resource attributes splunk_ao.logstream.name, splunk_ao.logstream.id
REST JSON body fields log_stream_id
Agent Control target_type "log_stream"
OpenAPI-generated client src/splunk_ao/resources/** untouched
REST URL paths /log_streams/... unchanged

Scope

85 files changed (+805 / −804)

  • Core SDK: logger, decorator, singleton, traces, export, search, evaluators, annotation_queues, agent_control, otel, exporter
  • Examples, README, migration-tool samples
  • splunk-ao-adk plugin/callback/observer
  • Full test suite updates

Commits

  1. ea9e180 — Initial SDK API rename
  2. e2b36b7 — Review fixes (missed test params, README/examples)
  3. 8cea2ee — Extend rename outside resources/; preserve backend wire format

shuningc and others added 4 commits July 29, 2026 11:11
Complete the mechanical terminology rename for SplunkAOLogger params, Agent Control targets, OTLP routing headers, and resource attributes.

Co-authored-by: Cursor <cursoragent@cursor.com>
Fix missed SplunkAOLogger call sites, TracesIngestRequest assertions, user-facing terminology, legacy routing attr stripping, and README/examples.

Co-authored-by: Cursor <cursoragent@cursor.com>
…format

Expand agent stream terminology across SDK, examples, and tests outside resources/, but keep OTLP headers, resource attributes, and Agent Control target_type aligned with the current backend API.

Co-authored-by: Cursor <cursoragent@cursor.com>
Keep agent_stream SDK rename while adopting main's Splunk AO branding.
Fix splunk-ao-logger redaction example and exporter config test after merge.

Co-authored-by: Cursor <cursoragent@cursor.com>
@shuningc
shuningc marked this pull request as ready for review July 29, 2026 23:48

@fercor-cisco fercor-cisco left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 This review was generated by the Astra agent (claude-opus-4-8). It may contain mistakes.

Verdict: request_changes — Rename leaked into a generated-client call, passing a nonexistent kwarg that will crash AgentStream.refresh()/get(id=...) at runtime.

Follow-ups

Suggested follow-up work that could be tracked as Shortcut stories:

  • src/splunk_ao/agent_streams.py:409-415: Add a unit test that exercises AgentStreams.get(id=...) by patching the generated get_log_stream_projects_project_id_log_streams_log_stream_id_get.sync function (rather than mocking the whole AgentStreams class). The current refresh() tests mock AgentStreams entirely, so no test ever calls the real generated client — which is exactly why this TypeError shipped undetected.

Comment thread src/splunk_ao/agent_streams.py Outdated
if id:
log_stream_response = get_log_stream_projects_project_id_log_streams_log_stream_id_get.sync(
project_id=project_id, log_stream_id=id, client=self.config.api_client
project_id=project_id, agent_stream_id=id, client=self.config.api_client

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 critical (bug): The rename leaked into the OpenAPI-generated client call — which the PR description explicitly states must stay untouched. The generated function signature is sync(project_id: str, log_stream_id: str, *, client) (see src/splunk_ao/resources/api/log_stream/get_log_stream_projects_project_id_log_streams_log_stream_id_get.py). It has no agent_stream_id parameter and no **kwargs, so this call raises TypeError: sync() got an unexpected keyword argument 'agent_stream_id' (and a missing-required-argument error for log_stream_id).

This breaks every AgentStreams.get(id=...) lookup at runtime — most notably AgentStream.refresh() (agent_stream.py:386). The existing refresh tests don't catch it because they mock AgentStreams wholesale, so this call path is never exercised. Revert the keyword to log_stream_id=id (only the local variable id was renamed elsewhere; the generated parameter name was not).

Suggested change
project_id=project_id, agent_stream_id=id, client=self.config.api_client
log_stream_response = get_log_stream_projects_project_id_log_streams_log_stream_id_get.sync(
project_id=project_id, log_stream_id=id, client=self.config.api_client
)

🤖 Generated by the Astra agent

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverting this 07a2b39

shuningc and others added 3 commits July 29, 2026 17:52
The OpenAPI client expects log_stream_id, not agent_stream_id; passing the
renamed kwarg broke AgentStreams.get(id=...) and AgentStream.refresh().
Add a regression test that exercises the generated sync call directly.

Co-authored-by: Cursor <cursoragent@cursor.com>
The OpenAPI client expects log_stream_id, not agent_stream_id; the renamed
kwarg broke AgentStreams.get(id=...) and AgentStream.refresh().

Co-authored-by: Cursor <cursoragent@cursor.com>

@fercor-cisco fercor-cisco left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 This review was generated by the Astra agent (claude-opus-4-8). It may contain mistakes.

Verdict: approve — Rename is thorough, internally consistent, and preserves backend wire format; the one critical bug was already reverted. Remaining issues are example/doc-level only.

Follow-ups

Suggested follow-up work that could be tracked as Shortcut stories:

  • src/splunk_ao/agent_streams.py:409-415: The existing refresh/get(id=...) tests mock AgentStreams wholesale, so the generated-client call path (get_log_stream_projects_project_id_log_streams_log_stream_id_get.sync) is never exercised — which is why the earlier keyword regression slipped through. Consider adding a test that mocks the generated sync function directly and asserts it is called with log_stream_id=, to guard the SDK↔generated-client boundary against future renames.

Comment on lines +15 to +20
with galileo_context(project="my-project", agent_stream="production"):
result = call_llm("Hello")

# Direct logger approach
# project/log_stream are constructor args, not start_session args
logger = GalileoLogger(project="my-project", log_stream="production")
logger = GalileoLogger(project="my-project", agent_stream="production")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 minor (bug): This is the "before" example demonstrating the real Galileo SDK (from galileo import GalileoLogger, galileo_context). Galileo's API uses the log_stream= keyword — it has no agent_stream= parameter. The rename over-reached into this file, so both galileo_context(..., agent_stream="production") and GalileoLogger(project=..., agent_stream="production") would raise TypeError: unexpected keyword argument 'agent_stream' if a user ran them. The pre-migration snippet should keep Galileo's real terminology. (The same over-reach appears in the migration-tool README's "before Galileo" code block.)

Suggested change
with galileo_context(project="my-project", agent_stream="production"):
result = call_llm("Hello")
# Direct logger approach
# project/log_stream are constructor args, not start_session args
logger = GalileoLogger(project="my-project", log_stream="production")
logger = GalileoLogger(project="my-project", agent_stream="production")
with galileo_context(project="my-project", log_stream="production"):
result = call_llm("Hello")
# Direct logger approach
# project/log_stream are constructor args, not start_session args
logger = GalileoLogger(project="my-project", log_stream="production")

🤖 Generated by the Astra agent

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted

Comment thread README.md

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

README.md:82-82 (line not in diff)

🟡 minor (documentation): This PR makes SPLUNK_AO_AGENT_STREAM the preferred env var and demotes SPLUNK_AO_LOG_STREAM to a deprecated alias, but the primary setup instructions here (and the accompanying comments on lines 103/134) still point new users at the deprecated name. Recommend updating the shell example and comments to SPLUNK_AO_AGENT_STREAM so docs steer users to the non-deprecated variable. The same applies to splunk-ao-migration-tool/examples/after_splunk_ao.py, which sets os.environ["SPLUNK_AO_LOG_STREAM"].

Suggested change
export SPLUNK_AO_AGENT_STREAM="your-agent-stream-name"

🤖 Generated by the Astra agent

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

…REAM

Restore log_stream= in before-Galileo examples (real Galileo API) and
document SPLUNK_AO_AGENT_STREAM as the preferred env var, with
SPLUNK_AO_LOG_STREAM noted as a deprecated alias.

Co-authored-by: Cursor <cursoragent@cursor.com>

@fercor-cisco fercor-cisco left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 This review was generated by the Astra agent (claude-opus-4-8). It may contain mistakes.

Verdict: approve — Mechanical rename is consistent and correct; backend wire formats preserved as intended; the one critical bug was already fixed. Only stale-docstring nits remain.

General Comments

  • 🟡 minor (documentation): Several docstrings still document parameters by their old names (log_stream, log_stream_id) even though the actual keyword parameters were renamed to agent_stream / agent_stream_id. Examples: src/splunk_ao/utils/singleton.py reset() (lines ~255-258) and flush() (lines ~310-313) Parameters sections; src/splunk_ao/utils/singleton.py _get_key docstring ("The log stream name"/"The log stream ID"); src/splunk_ao/decorator.py get_logger_instance/flush/init docstrings referencing log_stream. Since HYBIM-935's acceptance criteria is that no log_stream spelling remains in SDK source (outside the intentional wire-format exceptions), these stale docstrings that name non-existent parameters should be updated to avoid confusing users. Non-blocking.

Follow-ups

Suggested follow-up work that could be tracked as Jira tickets:

  • tests/test_config.py:40-43: Consider adding an explicit test that when both SPLUNK_AO_AGENT_STREAM and the deprecated SPLUNK_AO_LOG_STREAM are set, the non-deprecated var wins (both in the env-var bridge and in _get_agent_stream_from_env/_get_agent_stream_or_default). The precedence relies on _BRIDGE ordering and getenv(new) or getenv(old) fallback logic that is newly introduced by this PR but not directly asserted.

@shuningc
shuningc merged commit 23a02dd into main Jul 30, 2026
17 checks passed
@shuningc
shuningc deleted the HYBIM-935 branch July 30, 2026 18:15
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 30, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants