Skip to content
Merged
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
6 changes: 6 additions & 0 deletions .github/workflows/ci-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ jobs:
python-version: ${{ matrix.python-version }}
cache-dependency-path: "poetry.lock"

- name: Select matrix Python for Poetry
run: |
poetry env remove --all
poetry env use python
poetry run python -c "import sys; expected=tuple(map(int, '${{ matrix.python-version }}'.split('.'))); actual=sys.version_info[:2]; print('Poetry Python:', sys.version); raise SystemExit(0 if actual == expected else 'Expected Python %s, got %s' % (expected, actual))"

@fercor-cisco fercor-cisco Jun 15, 2026

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.

Feel free to merge as is. I'll create a separate Jira ticket to discuss these findings:

  1. Cache invalidation (significant)

poetry env remove --all destroys the virtualenv that actions/setup-python's cache: "poetry" just restored. The sequence is:

  1. setup-python restores cached Poetry env
  2. poetry env remove --all deletes it
  3. poetry env use python creates a new empty env
  4. invoke install reinstalls everything from scratch

The cache is restored but immediately discarded every run. This effectively disables the Poetry cache and will slow down all CI jobs noticeably. A less destructive alternative would be
poetry env use python${{ matrix.python-version }} (or the full path), which would steer Poetry to the right interpreter without blowing away the cached env.

  1. Redundant version check

The inline version check at the end of the new step (line 54) duplicates the existing "Verify Poetry Python version" step at lines 62–70. The existing step also uses
sys.version_info[:len(expected)] which is slightly more flexible. The new inline check isn't wrong, just redundant — and the early-fail intent (catching the problem before invoke
install runs) would be achieved by poetry env use itself failing if the Python isn't found.

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.

- name: Install invoke
run: pipx install invoke

Expand Down
58 changes: 29 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Set the following environment variables:
- `GALILEO_API_KEY`: Your Galileo API key
- `GALILEO_PROJECT`: (Optional) Project name
- `GALILEO_LOG_STREAM`: (Optional) Log stream name
- `GALILEO_LOGGING_DISABLED`: (Optional) Disable collecting and sending logs to galileo.
- `GALILEO_LOGGING_DISABLED`: (Optional) Disable collecting and sending logs to Galileo.

Note: if you would like to point to an environment other than `app.galileo.ai`, you'll need to set the `GALILEO_CONSOLE_URL` environment variable.

Expand All @@ -40,8 +40,8 @@ Note: if you would like to point to an environment other than `app.galileo.ai`,
```python
import os

from galileo import galileo_context
from galileo.openai import openai
from splunk_ao import galileo_context
from splunk_ao.openai import openai

# If you've set your GALILEO_PROJECT and GALILEO_LOG_STREAM env vars, you can skip this step
galileo_context.init(project="your-project-name", log_stream="your-log-stream-name")
Expand All @@ -67,7 +67,7 @@ galileo_context.flush()
You can also use the `@log` decorator to log spans. Here's how to create a workflow span with two nested LLM spans:

```python
from galileo import log
from splunk_ao import log

@log
def make_nested_call():
Expand All @@ -84,7 +84,7 @@ make_nested_call()
Here's how to create a retriever span using the decorator:

```python
from galileo import log
from splunk_ao import log

@log(span_type="retriever")
def retrieve_documents(query: str):
Expand All @@ -97,7 +97,7 @@ retrieve_documents(query="history")
Here's how to create a tool span using the decorator:

```python
from galileo import log
from splunk_ao import log

@log(span_type="tool")
def tool_call(input: str = "tool call input"):
Expand All @@ -113,7 +113,7 @@ galileo_context.flush()
In some cases, you may want to wrap a block of code to start and flush a trace automatically. You can do this using the `galileo_context` context manager:

```python
from galileo import galileo_context
from splunk_ao import galileo_context

# This will log a block of code to the project and log stream specified in the context manager
with galileo_context():
Expand All @@ -124,7 +124,7 @@ with galileo_context():
`galileo_context` also allows you specify a separate project and log stream for the trace:

```python
from galileo import galileo_context
from splunk_ao import galileo_context

# This will log to the project and log stream specified in the context manager
with galileo_context(project="gen-ai-project", log_stream="test2"):
Expand All @@ -135,7 +135,7 @@ with galileo_context(project="gen-ai-project", log_stream="test2"):
You can also use the `GalileoLogger` for manual logging scenarios:

```python
from galileo.logger import GalileoLogger
from splunk_ao.logger import GalileoLogger

# This will log to the project and log stream specified in the logger constructor
logger = GalileoLogger(project="gen-ai-project", log_stream="test3")
Expand All @@ -162,7 +162,7 @@ current Galileo log stream as the runtime target:

```python
import agent_control
from galileo import galileo_context, get_agent_control_target
from splunk_ao import galileo_context, get_agent_control_target

galileo_context.init(project="my-project", log_stream="prod")

Expand All @@ -183,16 +183,16 @@ Control SDK or resolve log stream names over the network. If you use a direct
Agent Control client instead of `agent_control.init(...)`, pass
`target.target_type` and `target.target_id` on each evaluation call.

`galileo.agent_control` resolves targets for Agent Control calls.
`galileo.handlers.agent_control` bridges Agent Control telemetry into Galileo
`splunk_ao.agent_control` resolves targets for Agent Control calls.
`splunk_ao.handlers.agent_control` bridges Agent Control telemetry into Galileo
logging.

OpenAI streaming example:

```python
import os

from galileo.openai import openai
from splunk_ao.openai import openai

client = openai.OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))

Expand All @@ -210,8 +210,8 @@ In some cases (like long-running processes), it may be necessary to explicitly f
```python
import os

from galileo import galileo_context
from galileo.openai import openai
from splunk_ao import galileo_context
from splunk_ao.openai import openai

galileo_context.init(project="your-project-name", log_stream="your-log-stream-name")

Expand All @@ -236,7 +236,7 @@ galileo_context.flush()
Using the Langchain callback handler:

```python
from galileo.handlers.langchain import GalileoCallback
from splunk_ao.handlers.langchain import GalileoCallback
from langchain.schema import HumanMessage
from langchain_openai import ChatOpenAI

Expand All @@ -259,7 +259,7 @@ print(response.content)
Create a dataset:

```python
from galileo.datasets import create_dataset
from splunk_ao.datasets import create_dataset

create_dataset(
name="names",
Expand All @@ -273,15 +273,15 @@ create_dataset(
Get a dataset:

```python
from galileo.datasets import get_dataset
from splunk_ao.datasets import get_dataset

dataset = get_dataset(name="names")
```

List all datasets:

```python
from galileo.datasets import list_datasets
from splunk_ao.datasets import list_datasets

datasets = list_datasets()
```
Expand All @@ -292,7 +292,7 @@ datasets = list_datasets()
>
> Example:
> ```python
> from galileo.schema.datasets import DatasetRecord
> from splunk_ao.schema.datasets import DatasetRecord
>
> record = DatasetRecord(
> input="What is 2+2?",
Expand All @@ -305,7 +305,7 @@ datasets = list_datasets()
>
> Example:
> ```python
> from galileo.schema.datasets import DatasetRecord
> from splunk_ao.schema.datasets import DatasetRecord
>
> # Using 'output' (backward compatible)
> record1 = DatasetRecord(input="What is 2+2?", output="4")
Expand All @@ -322,10 +322,10 @@ datasets = list_datasets()
Run an experiment with a prompt template:

```python
from galileo import Message, MessageRole
from galileo.datasets import get_dataset
from galileo.experiments import run_experiment
from galileo.prompts import create_prompt_template
from splunk_ao import Message, MessageRole
from splunk_ao.datasets import get_dataset
from splunk_ao.experiments import run_experiment
from splunk_ao.prompts import create_prompt_template

prompt = create_prompt_template(
name="my-prompt",
Expand All @@ -349,7 +349,7 @@ Run an experiment with a runner function with local dataset:

```python
import openai
from galileo.experiments import run_experiment
from splunk_ao.experiments import run_experiment


dataset = [
Expand Down Expand Up @@ -379,7 +379,7 @@ run_experiment(
Sessions allow you to group related traces together. By default, a session is created for each trace and a session name is auto-generated. If you would like to override this, you can explicitly start a session:

```python
from galileo import GalileoLogger
from splunk_ao import GalileoLogger

logger = GalileoLogger(project="gen-ai-project", log_stream="my-log-stream")
session_id =logger.start_session(name="my-session-name")
Expand All @@ -393,7 +393,7 @@ logger.flush()
You can continue a previous session by using the same session ID that was previously generated:

```python
from galileo import GalileoLogger
from splunk_ao import GalileoLogger

logger = GalileoLogger(project="gen-ai-project", log_stream="my-log-stream")
logger.set_session(session_id="123e4567-e89b-12d3-a456-426614174000")
Expand All @@ -407,7 +407,7 @@ logger.flush()
All of this can also be done using the `galileo_context` context manager:

```python
from galileo import galileo_context
from splunk_ao import galileo_context

session_id = galileo_context.start_session(name="my-session-name")

Expand Down
4 changes: 2 additions & 2 deletions examples/langgraph/basic_langgraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from langgraph.graph.message import add_messages
from typing_extensions import TypedDict

from galileo.handlers.langchain import GalileoCallback
from splunk_ao.handlers.langchain import SplunkAOCallback


class State(TypedDict):
Expand Down Expand Up @@ -45,4 +45,4 @@ def node2(state: State) -> dict:
graph = graph_builder.compile()

graph.get_graph().print_ascii()
graph.invoke({"messages": [{"role": "user", "content": "hi!"}]}, config={"callbacks": [GalileoCallback()]})
graph.invoke({"messages": [{"role": "user", "content": "hi!"}]}, config={"callbacks": [SplunkAOCallback()]})
4 changes: 2 additions & 2 deletions examples/langgraph/with_openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from langgraph.graph.message import add_messages
from typing_extensions import TypedDict

from galileo.handlers.langchain import GalileoCallback
from splunk_ao.handlers.langchain import SplunkAOCallback


class State(TypedDict):
Expand All @@ -42,4 +42,4 @@ def chatbot(state: State) -> dict:

graph.get_graph().print_ascii()

graph.invoke({"messages": [{"role": "user", "content": "hi!"}]}, {"callbacks": [GalileoCallback()]})
graph.invoke({"messages": [{"role": "user", "content": "hi!"}]}, {"callbacks": [SplunkAOCallback()]})
4 changes: 2 additions & 2 deletions examples/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
# dependencies = ["galileo"]
# ///

from galileo import Message, MessageRole
from galileo.prompts import create_prompt, get_prompt, get_prompts
from splunk_ao import Message, MessageRole
from splunk_ao.prompts import create_prompt, get_prompt, get_prompts

# Create a global template
prompt_template = create_prompt(
Expand Down
4 changes: 2 additions & 2 deletions galileo-a2a/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pip install galileo-a2a
## Quick Start

```python
from galileo.otel import GalileoSpanProcessor, add_galileo_span_processor
from splunk_ao.otel import GalileoSpanProcessor, add_galileo_span_processor
from galileo_a2a import A2AInstrumentor
from opentelemetry.sdk.trace import TracerProvider

Expand Down Expand Up @@ -119,7 +119,7 @@ from a2a.types import (
AgentCapabilities, AgentCard, AgentSkill, Message, Role,
TaskState, TaskStatus, TaskStatusUpdateEvent, TextPart,
)
from galileo.otel import GalileoSpanProcessor, add_galileo_span_processor
from splunk_ao.otel import GalileoSpanProcessor, add_galileo_span_processor
from galileo_a2a import A2AInstrumentor
from langchain.agents import create_agent
from langchain_core.tools import tool
Expand Down
4 changes: 2 additions & 2 deletions galileo-a2a/examples/two_agent_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@
from langgraph.graph import END, START, StateGraph
from opentelemetry.instrumentation.langchain import LangchainInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from splunk_ao.otel import SplunkAOSpanProcessor, add_galileo_span_processor
from starlette.applications import Starlette
from typing_extensions import TypedDict

from galileo.otel import GalileoSpanProcessor, add_galileo_span_processor
from galileo_a2a import A2AInstrumentor

load_dotenv(Path(__file__).parent / ".env")
Expand All @@ -61,7 +61,7 @@
# ---------------------------------------------------------------------------

provider = TracerProvider()
add_galileo_span_processor(provider, GalileoSpanProcessor())
add_galileo_span_processor(provider, SplunkAOSpanProcessor())
A2AInstrumentor().instrument(tracer_provider=provider, agent_name="orchestrator")
LangchainInstrumentor().instrument(tracer_provider=provider)

Expand Down
4 changes: 2 additions & 2 deletions galileo-a2a/src/galileo_a2a/instrumentor.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ class A2AInstrumentor(BaseInstrumentor): # type: ignore[misc]
Example::

from opentelemetry.sdk.trace import TracerProvider
from galileo.otel import GalileoSpanProcessor, add_galileo_span_processor
from splunk_ao.otel import SplunkAOSpanProcessor, add_galileo_span_processor
from galileo_a2a import A2AInstrumentor

provider = TracerProvider()
add_galileo_span_processor(provider, GalileoSpanProcessor())
add_galileo_span_processor(provider, SplunkAOSpanProcessor())
A2AInstrumentor().instrument(tracer_provider=provider, agent_name="my-agent")

# To disable message content capture (e.g. for PII compliance):
Expand Down
4 changes: 2 additions & 2 deletions galileo-adk/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This package is part of the [galileo-python](https://github.com/rungalileo/galil

```
galileo-python/
├── src/galileo/ ← Main Galileo SDK
├── src/splunk_ao/ ← Main Galileo SDK
└── galileo-adk/
├── src/galileo_adk/
├── tests/
Expand Down Expand Up @@ -112,7 +112,7 @@ cd galileo-adk
uv sync --dev
```

This installs `galileo` in **editable mode** from `../src/galileo/`. Changes to either package are immediately available without reinstalling.
This installs `galileo` in **editable mode** from `../src/splunk_ao/`. Changes to either package are immediately available without reinstalling.

### Running Tests

Expand Down
2 changes: 1 addition & 1 deletion galileo-adk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ Intercept traces for custom processing before forwarding to Galileo:
```python
import asyncio
import os
from galileo import GalileoLogger
from splunk_ao import GalileoLogger
from galileo_adk import GalileoADKPlugin
from google.adk.runners import Runner
from google.adk.agents import LlmAgent
Expand Down
3 changes: 2 additions & 1 deletion galileo-adk/src/galileo_adk/callback.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
from collections.abc import Callable
from typing import Any

from galileo.schema.trace import TracesIngestRequest
from splunk_ao.schema.trace import TracesIngestRequest

from galileo_adk.observer import (
GalileoObserver,
get_agent_name_from_tool_context,
Expand Down
Loading
Loading