Skip to content

Commit a6a0479

Browse files
feat(galileo-a2a): rebrand to SPLUNK_AO_* env vars and SplunkAOSpanProcessor (HYBIM-716)
Core package: - Rename GALILEO_OBSERVE_KEY -> SPLUNK_AO_OBSERVE_KEY in _constants.py - Rename GALILEO_* context vars to SPLUNK_AO_* in _context.py and _client_patches.py - Update pyproject.toml: galileo dependency -> splunk-ao, update classifiers Examples: - examples/.env.example: replace SPLUNK_AO_CONSOLE_URL with SPLUNK_AO_API_URL (direct API host is required for self-hosted deployments) Documentation (README.md): - Replace GalileoSpanProcessor -> SplunkAOSpanProcessor in all code examples - Replace GALILEO_* env vars -> SPLUNK_AO_* in configuration table - Add SPLUNK_AO_API_URL row (required for self-hosted) - Update all Galileo brand mentions to Splunk AO Tests: - Update all GALILEO_* env var references to SPLUNK_AO_* in conftest.py and test_context.py Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent cb85925 commit a6a0479

8 files changed

Lines changed: 45 additions & 44 deletions

File tree

galileo-a2a/README.md

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[![Python versions](https://img.shields.io/pypi/pyversions/galileo-a2a.svg)](https://pypi.org/project/galileo-a2a/)
55
[![License](https://img.shields.io/pypi/l/galileo-a2a.svg)](https://github.com/rungalileo/galileo-python/blob/main/LICENSE)
66

7-
Galileo observability for [A2A (Agent-to-Agent)](https://github.com/google/A2A) protocol interactions. Automatic tracing of agent-to-agent calls, task lifecycle, and cross-agent distributed trace correlation.
7+
Splunk AO observability for [A2A (Agent-to-Agent)](https://github.com/google/A2A) protocol interactions. Automatic tracing of agent-to-agent calls, task lifecycle, and cross-agent distributed trace correlation.
88

99
## How It Works
1010

@@ -25,31 +25,31 @@ Galileo observability for [A2A (Agent-to-Agent)](https://github.com/google/A2A)
2525
│ └─────────────────┬────────────────────────┘ │
2626
│ │ │
2727
│ ┌──────────▼──────────┐ │
28-
│ │ Galileo │ │
28+
│ │ Splunk AO │ │
2929
│ │ (Trace Explorer) │ │
3030
│ └─────────────────────┘ │
3131
└──────────────────────────────────────────────────────────────────────┘
3232
```
3333

34-
`galileo-a2a` instruments both the **client** (outbound calls) and **server** (inbound requests) sides of the A2A protocol. Trace context is propagated through A2A message metadata so all agents appear in a single distributed trace in Galileo.
34+
`galileo-a2a` instruments both the **client** (outbound calls) and **server** (inbound requests) sides of the A2A protocol. Trace context is propagated through A2A message metadata so all agents appear in a single distributed trace in Splunk AO.
3535

3636
## Installation
3737

3838
```bash
3939
pip install galileo-a2a
4040
```
4141

42-
**Requirements:** Python 3.10+, a [Galileo API key](https://www.rungalileo.io/), and [a2a-sdk](https://pypi.org/project/a2a-sdk/) 0.3+
42+
**Requirements:** Python 3.10+, a [Splunk AO API key](https://www.splunk.com/), and [a2a-sdk](https://pypi.org/project/a2a-sdk/) 0.3+
4343

4444
## Quick Start
4545

4646
```python
47-
from splunk_ao.otel import GalileoSpanProcessor, add_galileo_span_processor
47+
from splunk_ao.otel import SplunkAOSpanProcessor, add_galileo_span_processor
4848
from galileo_a2a import A2AInstrumentor
4949
from opentelemetry.sdk.trace import TracerProvider
5050

5151
provider = TracerProvider()
52-
add_galileo_span_processor(provider, GalileoSpanProcessor())
52+
add_galileo_span_processor(provider, SplunkAOSpanProcessor())
5353
A2AInstrumentor().instrument(tracer_provider=provider, agent_name="orchestrator")
5454
```
5555

@@ -63,13 +63,14 @@ Once instrumented, all `a2a-sdk` client and server interactions produce OTel spa
6363
| `agent_name` | Name of this agent, set on spans as `gen_ai.agent.name`. |
6464
| `capture_content` | Set to `False` to disable capturing message content (e.g. for PII compliance). |
6565

66-
Environment variables for the Galileo exporter:
66+
Environment variables for the Splunk AO exporter:
6767

6868
| Environment Variable | Description |
6969
|---------------------|-------------|
70-
| `GALILEO_API_KEY` | Galileo API key (required) |
71-
| `GALILEO_PROJECT` | Project name (alternative to `GalileoSpanProcessor(project=...)`) |
72-
| `GALILEO_LOG_STREAM` | Log stream name (alternative to `GalileoSpanProcessor(logstream=...)`) |
70+
| `SPLUNK_AO_API_KEY` | Splunk AO API key (required) |
71+
| `SPLUNK_AO_API_URL` | Splunk AO API host URL (required for self-hosted deployments, e.g. `https://agent-observability-api.rc0.signalfx.com`) |
72+
| `SPLUNK_AO_PROJECT` | Project name (alternative to `SplunkAOSpanProcessor(project=...)`) |
73+
| `SPLUNK_AO_LOG_STREAM` | Log stream name (alternative to `SplunkAOSpanProcessor(logstream=...)`) |
7374

7475
## Features
7576

@@ -83,11 +84,11 @@ The instrumentor patches both sides of the A2A protocol:
8384

8485
### Cross-Agent Distributed Tracing
8586

86-
When Agent A calls Agent B, trace context is propagated through A2A message metadata. The receiving agent joins the caller's trace, so both agents appear in a single distributed trace in Galileo.
87+
When Agent A calls Agent B, trace context is propagated through A2A message metadata. The receiving agent joins the caller's trace, so both agents appear in a single distributed trace in Splunk AO.
8788

8889
### Session Tracking
8990

90-
A2A's `context_id` is mapped to `session.id`, grouping all interactions within the same conversation into a Galileo session.
91+
A2A's `context_id` is mapped to `session.id`, grouping all interactions within the same conversation into a Splunk AO session.
9192

9293
### Disabling Instrumentation
9394

@@ -119,7 +120,7 @@ from a2a.types import (
119120
AgentCapabilities, AgentCard, AgentSkill, Message, Role,
120121
TaskState, TaskStatus, TaskStatusUpdateEvent, TextPart,
121122
)
122-
from splunk_ao.otel import GalileoSpanProcessor, add_galileo_span_processor
123+
from splunk_ao.otel import SplunkAOSpanProcessor, add_galileo_span_processor
123124
from galileo_a2a import A2AInstrumentor
124125
from langchain.agents import create_agent
125126
from langchain_core.tools import tool
@@ -132,7 +133,7 @@ from typing_extensions import TypedDict
132133

133134
# ---- Only 4 lines needed for full distributed tracing ----
134135
provider = TracerProvider()
135-
add_galileo_span_processor(provider, GalileoSpanProcessor())
136+
add_galileo_span_processor(provider, SplunkAOSpanProcessor())
136137
A2AInstrumentor().instrument(tracer_provider=provider, agent_name="orchestrator")
137138
LangchainInstrumentor().instrument(tracer_provider=provider)
138139

@@ -255,13 +256,13 @@ async def main():
255256
provider.shutdown()
256257

257258
if __name__ == "__main__":
258-
# Set environment variables: GALILEO_API_KEY, OPENAI_API_KEY
259+
# Set environment variables: SPLUNK_AO_API_KEY, OPENAI_API_KEY
259260
asyncio.run(main())
260261
```
261262

262263
## Resources
263264

264-
- [Galileo Documentation](https://v2docs.galileo.ai)
265+
- [Splunk AO Documentation](https://docs.splunk.com/)
265266
- [A2A Protocol Specification](https://a2a-protocol.org)
266267
- [a2a-sdk Documentation](https://pypi.org/project/a2a-sdk)
267268

galileo-a2a/examples/.env.example

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
GALILEO_API_KEY=your-galileo-key
2-
GALILEO_CONSOLE_URL=http://localhost:8088
3-
GALILEO_PROJECT=a2a-distributed-tracing-demo
4-
GALILEO_LOG_STREAM=dev
1+
SPLUNK_AO_API_KEY=your-splunk-ao-key
2+
SPLUNK_AO_API_URL=https://<splunk-ao-api-host>
3+
SPLUNK_AO_PROJECT=a2a-distributed-tracing-demo
4+
SPLUNK_AO_LOG_STREAM=dev
55
OPENAI_API_KEY=your-openai-key

galileo-a2a/pyproject.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@ python_files = ["test_*.py"]
6969
python_classes = ["Test*"]
7070
python_functions = ["test_*"]
7171
env = [
72-
"GALILEO_CONSOLE_URL=http://fake.test:8088",
73-
"GALILEO_API_KEY=api-1234567890",
74-
"GALILEO_PROJECT=test-project",
75-
"GALILEO_LOG_STREAM=test-log-stream",
72+
"SPLUNK_AO_CONSOLE_URL=http://fake.test:8088",
73+
"SPLUNK_AO_API_KEY=api-1234567890",
74+
"SPLUNK_AO_PROJECT=test-project",
75+
"SPLUNK_AO_LOG_STREAM=test-log-stream",
7676
]
7777
addopts = [
7878
"-v",

galileo-a2a/src/galileo_a2a/_client_patches.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from opentelemetry import trace
1212
from opentelemetry.trace import StatusCode, Tracer
1313

14-
from galileo_a2a._constants import GALILEO_OBSERVE_KEY
14+
from galileo_a2a._constants import SPLUNK_AO_OBSERVE_KEY
1515
from galileo_a2a._context import inject_trace_context, iter_with_context
1616
from galileo_a2a._spans import (
1717
set_client_attributes,
@@ -107,7 +107,7 @@ async def wrapper(
107107
otel_context.detach(token)
108108

109109
request_metadata = dict(request_metadata) if request_metadata else {}
110-
request_metadata[GALILEO_OBSERVE_KEY] = observe_ctx
110+
request_metadata[SPLUNK_AO_OBSERVE_KEY] = observe_ctx
111111

112112
result = original(
113113
self,

galileo-a2a/src/galileo_a2a/_constants.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
# Instrumentor identity
44
from galileo_a2a._version import __version__
55

6-
INSTRUMENTOR_NAME = "galileo-a2a"
6+
INSTRUMENTOR_NAME = "splunk-ao-a2a"
77
INSTRUMENTOR_VERSION = __version__
88

99
# Metadata keys for in-band trace context propagation
10-
GALILEO_OBSERVE_KEY = "galileo_observe"
10+
SPLUNK_AO_OBSERVE_KEY = "splunk_ao_observe"
1111
AGNTCY_OBSERVE_KEY = "observe" # compatibility with AGNTCY Observe SDK
1212

1313
# A2A span attribute keys (match API-side A2A extension expectations)

galileo-a2a/src/galileo_a2a/_context.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
from galileo_a2a._constants import (
1414
AGNTCY_OBSERVE_KEY,
15-
GALILEO_OBSERVE_KEY,
15+
SPLUNK_AO_OBSERVE_KEY,
1616
LINK_FROM_AGENT,
1717
LINK_TYPE,
1818
LINK_TYPE_AGENT_HANDOFF,
@@ -46,14 +46,14 @@ def inject_trace_context(agent_name: str | None = None) -> dict[str, str]:
4646
def extract_trace_context(metadata: dict[str, Any] | None) -> dict[str, str] | None:
4747
"""Extract trace context from A2A request metadata.
4848
49-
Checks the Galileo key first, then falls back to the AGNTCY key for
49+
Checks the Splunk AO key first, then falls back to the AGNTCY key for
5050
interoperability with the AGNTCY Observe SDK. Returns ``None`` when
5151
no trace context is present.
5252
"""
5353
if not metadata or not isinstance(metadata, dict):
5454
return None
5555

56-
ctx = metadata.get(GALILEO_OBSERVE_KEY)
56+
ctx = metadata.get(SPLUNK_AO_OBSERVE_KEY)
5757
if ctx and isinstance(ctx, dict):
5858
return {str(k): str(v) for k, v in ctx.items()}
5959

galileo-a2a/tests/conftest.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
# 3. Security - prevents real API keys from leaking into test logs
1010
import os
1111

12-
os.environ["GALILEO_CONSOLE_URL"] = "http://fake.test:8088"
13-
os.environ["GALILEO_API_KEY"] = "api-1234567890"
14-
os.environ["GALILEO_PROJECT"] = "test-project"
15-
os.environ["GALILEO_LOG_STREAM"] = "test-log-stream"
12+
os.environ["SPLUNK_AO_CONSOLE_URL"] = "http://fake.test:8088"
13+
os.environ["SPLUNK_AO_API_KEY"] = "api-1234567890"
14+
os.environ["SPLUNK_AO_PROJECT"] = "test-project"
15+
os.environ["SPLUNK_AO_LOG_STREAM"] = "test-log-stream"
1616
# fmt: on

galileo-a2a/tests/test_context.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from opentelemetry.sdk.trace import TracerProvider
66
from opentelemetry.trace import Link
77

8-
from galileo_a2a._constants import AGNTCY_OBSERVE_KEY, GALILEO_OBSERVE_KEY
8+
from galileo_a2a._constants import AGNTCY_OBSERVE_KEY, SPLUNK_AO_OBSERVE_KEY
99
from galileo_a2a._context import (
1010
create_span_link_from_context,
1111
extract_trace_context,
@@ -33,10 +33,10 @@ def test_includes_agent_name(self):
3333

3434

3535
class TestExtractTraceContext:
36-
def test_extracts_from_galileo_observe_key(self):
37-
# Given: metadata with galileo_observe context
36+
def test_extracts_from_splunk_ao_observe_key(self):
37+
# Given: metadata with splunk_ao_observe context
3838
metadata = {
39-
GALILEO_OBSERVE_KEY: {
39+
SPLUNK_AO_OBSERVE_KEY: {
4040
"traceparent": "00-aabb00112233445566778899aabbccdd-1122334455667788-01",
4141
"agent_name": "planner",
4242
}
@@ -45,7 +45,7 @@ def test_extracts_from_galileo_observe_key(self):
4545
# When: extracting trace context
4646
result = extract_trace_context(metadata)
4747

48-
# Then: context extracted from galileo_observe key
48+
# Then: context extracted from splunk_ao_observe key
4949
assert result is not None
5050
assert result["traceparent"] == "00-aabb00112233445566778899aabbccdd-1122334455667788-01"
5151
assert result["agent_name"] == "planner"
@@ -66,19 +66,19 @@ def test_extracts_from_agntcy_observe_key(self):
6666
assert result is not None
6767
assert "traceparent" in result
6868

69-
def test_galileo_key_takes_precedence_over_agntcy(self):
69+
def test_splunk_ao_key_takes_precedence_over_agntcy(self):
7070
# Given: metadata with both keys
7171
metadata = {
72-
GALILEO_OBSERVE_KEY: {"traceparent": "galileo-traceparent"},
72+
SPLUNK_AO_OBSERVE_KEY: {"traceparent": "splunk-ao-traceparent"},
7373
AGNTCY_OBSERVE_KEY: {"traceparent": "agntcy-traceparent"},
7474
}
7575

7676
# When: extracting trace context
7777
result = extract_trace_context(metadata)
7878

79-
# Then: galileo key takes precedence
79+
# Then: splunk_ao key takes precedence
8080
assert result is not None
81-
assert result["traceparent"] == "galileo-traceparent"
81+
assert result["traceparent"] == "splunk-ao-traceparent"
8282

8383
def test_returns_none_when_missing(self):
8484
# Given: metadata with no observe keys

0 commit comments

Comments
 (0)