Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
58eb627
Add provider agnostic traceing
namrataghadi-galileo Mar 23, 2026
3d39706
fix linting
namrataghadi-galileo Mar 23, 2026
c3241c1
add test
namrataghadi-galileo Mar 23, 2026
fc27836
Merge branch 'feature/59789-add-provider-agnostic-tracing' into featu…
namrataghadi-galileo Mar 26, 2026
55e57b5
draft
namrataghadi-galileo Mar 26, 2026
61cd788
address comments
namrataghadi-galileo Mar 26, 2026
f0391db
separate evaluation and emission
namrataghadi-galileo Mar 27, 2026
d532300
resolve conflicst
namrataghadi-galileo Mar 31, 2026
ff1e344
update docstring
namrataghadi-galileo Mar 31, 2026
a8c40c5
TS sdk fix
namrataghadi-galileo Mar 31, 2026
f58778e
address comments
namrataghadi-galileo Apr 1, 2026
c0d9a57
ensure control sink exists for merged mode
namrataghadi-galileo Apr 1, 2026
33fcc18
refactor this PR to only have merge mode
namrataghadi-galileo Apr 1, 2026
efd0271
Merge branch 'feature/59787-merge-events' into feature/59790-configur…
namrataghadi-galileo Apr 1, 2026
6496502
Add configurable event sinks
namrataghadi-galileo Apr 1, 2026
b785836
Merge branch 'main' into feature/59787-merge-events
namrataghadi-galileo Apr 1, 2026
e70832a
mergeing from main
namrataghadi-galileo Apr 2, 2026
ca5bf6f
address comments
namrataghadi-galileo Apr 2, 2026
001228a
fix typescript
namrataghadi-galileo Apr 2, 2026
f24e07e
fix TS
namrataghadi-galileo Apr 2, 2026
a714e27
fix ts
namrataghadi-galileo Apr 2, 2026
9baf9d1
add more TS fix
namrataghadi-galileo Apr 2, 2026
8731f7e
code coverage
namrataghadi-galileo Apr 2, 2026
9af1755
add more tests for code cov
namrataghadi-galileo Apr 2, 2026
9b0ae70
address comments
namrataghadi-galileo Apr 2, 2026
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: 0 additions & 2 deletions models/src/agent_control_models/evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,6 @@ class EvaluationResponse(BaseModel):
default=None,
description="List of controls that were evaluated but did not match (if any)",
)


class EvaluationResult(EvaluationResponse):
"""
Client-side result model for evaluation analysis.
Expand Down
19 changes: 19 additions & 0 deletions sdks/python/src/agent_control/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,13 @@ async def handle_input(user_message: str) -> str:
sync_shutdown_observability,
)
from .telemetry import (
ControlEventSink,
clear_control_event_sink,
clear_trace_context_provider,
emit_control_events,
get_trace_context_from_provider,
has_control_event_sink,
set_control_event_sink,
set_trace_context_provider,
)
from .tracing import (
Expand Down Expand Up @@ -396,6 +401,7 @@ def init(
observability_enabled: bool | None = None,
log_config: dict[str, Any] | None = None,
policy_refresh_interval_seconds: int = 60,
merge_events: bool = False,
**kwargs: object
) -> Agent:
"""
Expand Down Expand Up @@ -426,6 +432,9 @@ def init(
{"enabled": True, "span_start": True, "span_end": True, "control_eval": True}
policy_refresh_interval_seconds: Interval for background policy refresh loop.
Defaults to 60 seconds. Set to 0 to disable background refresh.
merge_events: Whether to merge local and server event creation in the
SDK before enqueueing through the built-in observability path.
Defaults to False.
**kwargs: Additional metadata to store with the agent

Returns:
Expand Down Expand Up @@ -496,6 +505,7 @@ async def handle(message: str):
state.current_agent = next_agent
state.server_url = server_url or os.getenv('AGENT_CONTROL_URL') or 'http://localhost:8000'
state.api_key = api_key
state.merge_events = merge_events

# Merge auto-discovered steps from @control() decorators with explicit steps.
# Explicit steps take precedence when (type, name) collides.
Expand Down Expand Up @@ -547,6 +557,7 @@ async def register() -> list[dict[str, Any]] | None:
state.current_agent,
steps=registration_steps,
conflict_mode=conflict_mode,
merge_events=merge_events,
)
created = response.get('created', False)
controls: list[dict[str, Any]] = response.get('controls', [])
Expand Down Expand Up @@ -636,13 +647,16 @@ def _reset_state() -> None:
"""Clear all global SDK state."""
global _session_generation

clear_control_event_sink()

with _session_lock:
_session_generation += 1
state.current_agent = None
state.control_engine = None
state.server_controls = None
state.server_url = None
state.api_key = None
state.merge_events = False


async def ashutdown() -> None:
Expand Down Expand Up @@ -1307,6 +1321,11 @@ async def main():
"set_trace_context_provider",
"get_trace_context_from_provider",
"clear_trace_context_provider",
"ControlEventSink",
"set_control_event_sink",
"has_control_event_sink",
"emit_control_events",
"clear_control_event_sink",
# Observability
"init_observability",
"add_event",
Expand Down
1 change: 1 addition & 0 deletions sdks/python/src/agent_control/_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def __init__(self) -> None:
self.server_controls: list[dict[str, Any]] | None = None
self.server_url: str | None = None
self.api_key: str | None = None
self.merge_events: bool = False


# Singleton state instance
Expand Down
8 changes: 7 additions & 1 deletion sdks/python/src/agent_control/agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ async def register_agent(
agent: Agent,
steps: list[dict[str, Any]] | None = None,
conflict_mode: Literal["strict", "overwrite"] = "overwrite",
merge_events: bool = False,
) -> dict[str, Any]:
"""Register an agent with the server via /initAgent endpoint."""
ensure_evaluators_discovered()
Expand All @@ -27,7 +28,12 @@ async def register_agent(
"conflict_mode": conflict_mode,
}

response = await client.http_client.post("/api/v1/agents/initAgent", json=payload)
headers = {"X-Agent-Control-Merge-Session": "true"} if merge_events else None
response = await client.http_client.post(
"/api/v1/agents/initAgent",
json=payload,
headers=headers,
)
response.raise_for_status()
return cast(dict[str, Any], response.json())

Expand Down
Loading
Loading