Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions src/agentex/lib/core/tracing/code_revision.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
"""Opt-in stamping of the agent's source commit onto its spans.
"""Stamping of the agent's source commit onto its spans.

Nothing is stamped until the agent calls :func:`enable`, mirroring the
``lineage`` registry next door: a process-wide switch the agent sets once at
import, rather than automatic behaviour every agent inherits. When enabled the
resolved commit lands in span data under ``__commit_sha__`` and is searchable in
the SGP Traces UI as ``__commit_sha__:<sha>``.
Stamping turns on when the process starts with ``AGENT_COMMIT_SHA`` set, which
the SGP cloud deploy does from the build record's attested commit, or when the
agent calls :func:`enable` itself. Nothing is stamped otherwise: upgrading the
SDK alone never starts emitting the field. When on, the resolved commit lands in
span data under ``__commit_sha__`` and is searchable in the SGP Traces UI as
``__commit_sha__:<sha>``.

This is deliberately separate from ``__agent_version__``, which is automatic and
carries the deployed image tag verbatim ("image tag or git sha"). That tag is a
Expand Down Expand Up @@ -42,13 +43,16 @@


def enable(commit_sha: str | None = None) -> None:
"""Opt this process in to stamping ``__commit_sha__`` onto every span.
"""Turn on stamping ``__commit_sha__`` onto every span from this process.

Value precedence: the explicit ``commit_sha`` argument, else
``AGENT_COMMIT_SHA``, else ``AGENT_VERSION`` when the deployment happened to
set it to a bare commit SHA. A value that is not a git object name is
refused with a warning and leaves stamping off -- better an absent field
than one named for a commit that holds an image tag.

Called once at import when ``AGENT_COMMIT_SHA`` is set, so a deployment that
supplies the commit needs no code change in the agent.
"""
global _commit_sha

Expand Down Expand Up @@ -103,3 +107,12 @@ def is_enabled() -> bool:
def commit_sha() -> str | None:
"""The resolved commit SHA, or ``None`` when stamping is not enabled."""
return _commit_sha


def _enable_from_environment() -> None:
"""Auto-enable on ``AGENT_COMMIT_SHA`` only; ``AGENT_VERSION`` stays an explicit fallback."""
if os.environ.get(_COMMIT_SHA_ENV, "").strip():
enable()


_enable_from_environment()
7 changes: 2 additions & 5 deletions src/agentex/lib/environment_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,8 @@ class EnvironmentVariables(BaseModel):
AGENT_ID: str | None = None
# Build/version discriminator (image tag or git sha), set by the deployment
AGENT_VERSION: str | None = None
# The agent's source commit, baked into the image or set by the deployment.
# Unlike AGENT_VERSION this is expected to be a git SHA and nothing else, and
# it is OPT-IN: nothing is stamped unless the agent calls
# `adk.code_revision.enable()`, which also refuses a value that is not a git
# object name. See agentex.lib.core.tracing.code_revision.
# The agent's source commit, set by the deployment or baked into the image; a git
# SHA and nothing else. Stamped as __commit_sha__ when set (see tracing.code_revision).
AGENT_COMMIT_SHA: str | None = None
AGENT_API_KEY: str | None = None
ACP_TYPE: str | None = "async"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ def test_agent_identity_and_version_stamped_into_span_data(self):

SHA = "b362b171a9c4e1f09d8e7a6b5c4d3e2f1a0b9c8d"

def test_commit_sha_is_not_stamped_without_opt_in(self, monkeypatch):
"""Upgrading the SDK must not start emitting __commit_sha__ on its own,
even when the environment carries a perfectly good SHA."""
def test_commit_sha_is_not_stamped_when_env_absent(self, monkeypatch):
"""Upgrading the SDK must not start emitting __commit_sha__ on its own;
only AGENT_COMMIT_SHA or an enable() call turns it on."""
from agentex.lib.core.tracing import code_revision
from agentex.lib.core.tracing.processors.sgp_tracing_processor import _sgp_metadata

monkeypatch.setenv("AGENT_COMMIT_SHA", self.SHA)
monkeypatch.delenv("AGENT_COMMIT_SHA", raising=False)
code_revision.disable()

span = _make_span(); span.data = {}
Expand Down
34 changes: 27 additions & 7 deletions tests/lib/core/tracing/test_code_revision.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Opt-in commit-SHA stamping.
"""Commit-SHA stamping.

The contract that matters: an agent that does not call ``enable()`` gets nothing,
so upgrading the SDK never starts emitting this field on its own.
The contract that matters: with ``AGENT_COMMIT_SHA`` absent and no ``enable()``
call, nothing is stamped, so upgrading the SDK never starts emitting this field
on its own. A deployment that sets the env var turns it on without agent code.
"""

from __future__ import annotations
Expand All @@ -21,14 +22,33 @@ def _reset():
code_revision.disable()


class TestOptIn:
def test_disabled_by_default(self, monkeypatch):
"""Even with the env fully populated, nothing resolves until enable()."""
monkeypatch.setenv("AGENT_COMMIT_SHA", SHA)
class TestEnablement:
def test_off_when_env_absent(self, monkeypatch):
"""The import-time hook ignores AGENT_VERSION; that fallback needs enable()."""
monkeypatch.delenv("AGENT_COMMIT_SHA", raising=False)
monkeypatch.setenv("AGENT_VERSION", SHA)
code_revision._enable_from_environment()
assert code_revision.commit_sha() is None
assert code_revision.is_enabled() is False

def test_env_set_at_startup_enables_without_a_call(self, monkeypatch):
"""The cloud deploy sets AGENT_COMMIT_SHA from the build record; the agent
should not need to know."""
monkeypatch.setenv("AGENT_COMMIT_SHA", SHA)
code_revision._enable_from_environment()
assert code_revision.commit_sha() == SHA

def test_env_set_after_import_needs_enable(self, monkeypatch):
monkeypatch.setenv("AGENT_COMMIT_SHA", SHA)
assert code_revision.commit_sha() is None
code_revision.enable()
assert code_revision.commit_sha() == SHA

def test_bad_env_at_startup_leaves_it_off(self, monkeypatch):
monkeypatch.setenv("AGENT_COMMIT_SHA", "latest")
code_revision._enable_from_environment()
assert code_revision.commit_sha() is None

def test_enable_reads_agent_commit_sha(self, monkeypatch):
monkeypatch.setenv("AGENT_COMMIT_SHA", SHA)
code_revision.enable()
Expand Down
Loading