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
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: "v0.9.7"
rev: "v0.15.22"
hooks:
- id: ruff
args: [--fix]
Expand Down
95 changes: 53 additions & 42 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ mypy = "^1.16.0"
invoke = "^2.2.0"
openai = ">=2.8.0,<3.0.0"
fastapi = "^0.115.0"
ruff = "^0.12.3"
openapi-python-client = "^0.26.1"
ruff = "^0.15.22"
openapi-python-client = "^0.29.0"
yq = "^3.4.3"
pyyaml = "^6.0.2"
pytest-timeout = "^2.4.0"
Expand Down Expand Up @@ -280,6 +280,8 @@ ignore = [
"src/splunk_ao/project.py" = ["PLC0415"] # Bottom-of-file circular import avoidance
"src/splunk_ao/logger/logger.py" = ["PLC0415"] # Local imports to avoid circular dependencies
"src/splunk_ao/logger/__init__.py" = ["PLC0415"] # Lazy import for GalileoLogger
"src/splunk_ao/experiment.py" = ["PLC0415"] # Local imports to avoid circular dependencies
"src/splunk_ao/metric.py" = ["PLC0415"] # Local imports to avoid circular dependencies

[tool.ruff.lint.isort]
known-first-party = ["galileo_core"]
Expand Down
28 changes: 16 additions & 12 deletions scripts/patch_http_validation_error.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,29 @@
# Patterns to find in the auto-generated file
# ---------------------------------------------------------------------------

# Inside from_dict — bare initialisation + for-loop produced by the generator:
# Inside from_dict — pattern produced by the generator (openapi-python-client 0.29+):
#
# detail = []
# _detail = d.pop("detail", UNSET)
# for detail_item_data in _detail or []:
# detail_item = ValidationError.from_dict(detail_item_data)
# detail: list[ValidationError] | Unset = UNSET
# if _detail is not UNSET:
# detail = []
# for detail_item_data in _detail:
# detail_item = ValidationError.from_dict(detail_item_data)
# <- blank line
# detail.append(detail_item)
# detail.append(detail_item)
#
# The class-level field annotation already comes out as
# `Union[Unset, list["ValidationError"]] = UNSET` from the generator, so it
# `list[ValidationError] | Unset = UNSET` from the generator, so it
# does NOT need to be patched — only the from_dict body is rewritten here.
_LOOP_RE = re.compile(
r"(?P<indent>[ \t]+)detail = \[\]\n"
r"(?P=indent)_detail = d\.pop\(\"detail\", UNSET\)\n"
r"(?P=indent)for detail_item_data in _detail or \[\]:\n"
r"(?P=indent) detail_item = ValidationError\.from_dict\(detail_item_data\)\n"
r"(?P<indent>[ \t]+)_detail = d\.pop\(\"detail\", UNSET\)\n"
r"(?P=indent)detail: list\[ValidationError\] \| Unset = UNSET\n"
r"(?P=indent)if _detail is not UNSET:\n"
r"(?P=indent) detail = \[\]\n"
r"(?P=indent) for detail_item_data in _detail:\n"
r"(?P=indent) detail_item = ValidationError\.from_dict\(detail_item_data\)\n"
r"[ \t]*\n"
r"(?P=indent) detail\.append\(detail_item\)",
r"(?P=indent) detail\.append\(detail_item\)",
re.MULTILINE,
)

Expand All @@ -65,8 +69,8 @@ def _loop_replacement(indent: str) -> str:
i4 = indent + " "
return "\n".join(
[
f"{i}detail: Union[Unset, list[ValidationError]] = UNSET",
f'{i}_detail = d.pop("detail", UNSET)',
f"{i}detail: list[ValidationError] | Unset = UNSET",
f"{i}if isinstance(_detail, list):",
f"{i4}detail = [ValidationError.from_dict(item) for item in _detail]",
f"{i}elif isinstance(_detail, str) and _detail:",
Expand Down
4 changes: 2 additions & 2 deletions src/splunk_ao/constants/routes.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from enum import Enum
from enum import StrEnum


class Routes(str, Enum):
class Routes(StrEnum):
healthcheck = "healthcheck"
login = "login"
api_key_login = "login/api_key"
Expand Down
2 changes: 1 addition & 1 deletion src/splunk_ao/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ def create(self) -> Experiment:

if existing_experiment:
_logger.warning(f"Experiment {existing_experiment.name} already exists, adding a timestamp")
now = datetime.datetime.now(datetime.timezone.utc)
now = datetime.datetime.now(datetime.UTC)
self.name = f"{existing_experiment.name} {now:%Y-%m-%d} at {now:%H:%M:%S}.{now.microsecond // 1000:03d}"

# Resolve prompt template before create (needed for trigger=True)
Expand Down
4 changes: 2 additions & 2 deletions src/splunk_ao/experiments.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from galileo_core.constants.request_method import RequestMethod
from splunk_ao.config import SplunkAOConfig
from splunk_ao.datasets import Dataset, convert_dataset_row_to_record
from splunk_ao.decorator import splunk_ao_context, splunk_ao_dataset_context, log
from splunk_ao.decorator import log, splunk_ao_context, splunk_ao_dataset_context
from splunk_ao.experiment_tags import upsert_experiment_tag
from splunk_ao.projects import Project, Projects
from splunk_ao.prompts import PromptTemplate
Expand Down Expand Up @@ -424,7 +424,7 @@ def run_experiment(

if existing_experiment:
logging.warning(f"Experiment {existing_experiment.name} already exists, adding a timestamp")
now = datetime.datetime.now(datetime.timezone.utc)
now = datetime.datetime.now(datetime.UTC)
experiment_name = f"{existing_experiment.name} {now:%Y-%m-%d} at {now:%H:%M:%S}.{now.microsecond // 1000:03d}"

# Execute a runner function experiment (custom function flow — uses logstream pipeline)
Expand Down
6 changes: 3 additions & 3 deletions src/splunk_ao/handlers/agent_control/bridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import threading
import uuid
from dataclasses import dataclass
from datetime import datetime, timezone
from datetime import UTC, datetime
from types import ModuleType
from typing import Any

Expand Down Expand Up @@ -53,9 +53,9 @@ def _load_agent_control_modules() -> _AgentControlModules:
def _normalize_datetime(value: Any) -> datetime:
if isinstance(value, datetime):
if value.tzinfo is None:
return value.replace(tzinfo=timezone.utc)
return value.replace(tzinfo=UTC)
return value
return datetime.now(tz=timezone.utc)
return datetime.now(tz=UTC)


def _duration_ms_to_ns(value: Any) -> int | None:
Expand Down
4 changes: 2 additions & 2 deletions src/splunk_ao/handlers/base_handler.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
import time
from collections.abc import Callable
from datetime import datetime, timezone
from datetime import UTC, datetime
from typing import Any
from uuid import UUID

Expand Down Expand Up @@ -257,7 +257,7 @@ def start_node(self, node_type: NODE_TYPE, parent_run_id: UUID | None, run_id: U
node.span_params["start_time"] = time.perf_counter_ns()

if "created_at" not in node.span_params:
node.span_params["created_at"] = datetime.now(tz=timezone.utc)
node.span_params["created_at"] = datetime.now(tz=UTC)

found_node = self._nodes.get(node_id)
if found_node:
Expand Down
8 changes: 4 additions & 4 deletions src/splunk_ao/handlers/openai_agents/handler.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import uuid
from datetime import datetime, timezone
from datetime import UTC, datetime
from typing import Any, cast

from agents import Span, Trace, TracingProcessor
Expand Down Expand Up @@ -66,7 +66,7 @@ def on_trace_start(self, trace: Trace) -> None:
run_id=trace.trace_id,
span_params={
"start_time": _get_timestamp(),
"start_time_iso": datetime.now(timezone.utc).isoformat(),
"start_time_iso": datetime.now(UTC).isoformat(),
"name": trace.name,
"metadata": convert_to_string_dict(trace.metadata),
},
Expand Down Expand Up @@ -242,7 +242,7 @@ def on_span_start(self, span: Span[Any]) -> None:
# Extract initial data based on type
initial_params: dict[str, Any] = {
"name": span_name,
"start_time_iso": span.started_at or datetime.now(timezone.utc).isoformat(),
"start_time_iso": span.started_at or datetime.now(UTC).isoformat(),
}
if splunk_ao_type in ["llm", "chat"]:
llm_data = _extract_llm_data(span.span_data)
Expand Down Expand Up @@ -316,7 +316,7 @@ def on_span_end(self, span: Span[Any]) -> None:

# Update node with final data
splunk_ao_type = node.node_type
end_params: dict[str, Any] = {"end_time_iso": span.ended_at or datetime.now(timezone.utc).isoformat()}
end_params: dict[str, Any] = {"end_time_iso": span.ended_at or datetime.now(UTC).isoformat()}
end_params["duration_ns"] = convert_time_delta_to_ns(
datetime.fromisoformat(span.ended_at) - datetime.fromisoformat(node.span_params["start_time_iso"])
)
Expand Down
Loading
Loading