Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
5d8b921
add weave tracer
Nov 5, 2025
296c610
fix _convert_weave_call_to_readable_span
Nov 6, 2025
40c73a3
Merge remote-tracking branch 'upstream/main' into hao/add_weave_tracer
Nov 6, 2025
b2d2648
add otel provider
Nov 6, 2025
48aca6c
Merge remote-tracking branch 'upstream/main' into hao/add_weave_tracer
Nov 11, 2025
12d1164
fix lint
Nov 11, 2025
e4402d4
fix lint
Nov 11, 2025
f9261ba
add uv fix
Nov 11, 2025
434e13a
fix lint
Nov 11, 2025
4f2cc47
add weave into workflow
Nov 12, 2025
8085a73
fix tests.yml
Nov 19, 2025
5a5a3f5
Merge remote-tracking branch 'upstream/main' into hao/add_weave_tracer
acured Nov 19, 2025
b5ad8ea
fix uvlock
acured Nov 19, 2025
b9314b7
weave tracer inherits from OtelTracer
acured Nov 19, 2025
3d02b37
remove _weaveclient
acured Nov 19, 2025
f257624
fix lint
acured Nov 19, 2025
4f2c3fd
fix style
acured Nov 19, 2025
9d37fe9
fix lint in test
acured Nov 19, 2025
f270717
Merge remote-tracking branch 'upstream/main' into hao/add_weave_tracer
acured Nov 20, 2025
503ff4e
remove weave package from javasript test step
acured Nov 20, 2025
6bcc22c
add weave group in js test
acured Nov 20, 2025
13161e3
revert..
acured Nov 20, 2025
5850fa7
change weave to optional
acured Nov 20, 2025
bf56456
pass weave upload and hook trace on end_trace
acured Nov 21, 2025
84dc5d8
Merge remote-tracking branch 'upstream/main' into hao/add_weave_tracer
acured Nov 26, 2025
06d641f
Separate Weave from OTel
acured Nov 27, 2025
3870f38
fix lint
acured Nov 27, 2025
e126db7
fix lint
acured Nov 27, 2025
670d035
fix lint
acured Nov 27, 2025
adede8f
fix lint
acured Nov 27, 2025
4aa8280
fix lint
acured Nov 27, 2025
4fffb1e
fix lint
acured Nov 27, 2025
205a37b
fix lint
acured Nov 27, 2025
f2ada23
Merge remote-tracking branch 'upstream/main' into hao/add_weave_tracer
acured Dec 1, 2025
1e5e557
move mock to instrument and add test
acured Dec 1, 2025
36eb3b3
add copyright
acured Dec 1, 2025
5a33688
ignore pyright check on tracer/weave.py
acured Dec 1, 2025
e175594
fix lint..
acured Dec 1, 2025
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
14 changes: 14 additions & 0 deletions agentlightning/instrumentation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
AGENTOPS_LANGCHAIN_INSTALLED: bool = False
LITELLM_INSTALLED: bool = False
VLLM_INSTALLED: bool = False
WEAVE_INSTALLED: bool = False

try:
from . import agentops # type: ignore
Expand Down Expand Up @@ -69,6 +70,11 @@ def instrument_all():
else:
warnings.warn("Agentops-langchain integration is not installed. It's therefore not instrumented.")

if WEAVE_INSTALLED:
from .weave import instrument_weave

instrument_weave()


def uninstrument_all():
"""Uninstrument all the instrumentation libraries."""
Expand Down Expand Up @@ -111,3 +117,11 @@ def uninstrument_all():
warnings.warn("agentops_langchain is installed but uninstrument_agentops_langchain could not be imported.")
else:
warnings.warn("Agentops-langchain integration is not installed. It's therefore not uninstrumented.")

if WEAVE_INSTALLED:
try:
from .weave import uninstrument_weave

uninstrument_weave()
except ImportError:
warnings.warn("weave is installed but uninstrument_weave could not be imported.")
139 changes: 139 additions & 0 deletions agentlightning/instrumentation/weave.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Copyright (c) Microsoft. All rights reserved.

import logging
import os
from typing import Any, Callable

import requests

logger = logging.getLogger(__name__)

__all__ = [
"instrument_weave",
"uninstrument_weave",
]

# Module-level storage for originals
_original_default_entity_name_getter: Callable[..., Any] | None = None
_original_upsert_project_getter: Callable[..., Any] | None = None
_original_weave_get = False
_original_weave_post = False


def instrument_weave():
"""
Patch the Weave/W&B integration to bypass actual network calls for testing.

- Mocks HTTP POST/GET requests
- Patches wandb.Api methods
- Silences Weave logging
- Sets dummy WANDB_API_KEY if not provided
"""
try:
import weave
from weave.compat import wandb # type: ignore
except ImportError:
logger.warning("Weave or wandb not installed; cannot uninstrument.")
return

_weave_tracer_entity_name = "weave_tracer_entity"

def default_entity_name_getter(_self) -> str: # type: ignore
return _weave_tracer_entity_name

def upsert_project_getter(
_self, project: str, description: Optional[str] = None, entity: Optional[str] = None # type: ignore
) -> dict[str, Any]:
return {
"upsertModel": {
"model": {
"name": project,
"description": description or "",
"entity": entity or _weave_tracer_entity_name,
}
},
"project": "weave_tracer_project",
}

# Mock network requests to avoid real HTTP calls
def post(url: str, *args: Any, **kwargs: Any) -> requests.Response:
response = requests.Response()
response.status_code = 200
response._content = b'{"digest": "mocked_digest"}'
return response

def get(url: str, *args: Any, **kwargs: Any) -> requests.Response:
response = requests.Response()
response.status_code = 200
response._content = b'{"min_required_weave_python_version": "0.52.14"}'
return response

# Patch API methods and HTTP requests
global _original_default_entity_name_getter
global _original_upsert_project_getter
global _original_weave_post
global _original_weave_get
_original_default_entity_name_getter = wandb.Api.default_entity_name # type: ignore
_original_upsert_project_getter = wandb.Api.upsert_project # type: ignore
_original_weave_post = weave.utils.http_requests.session.post # type: ignore
_original_weave_get = weave.utils.http_requests.session.get # type: ignore

# Patch API methods and HTTP requests
wandb.Api.default_entity_name = default_entity_name_getter # type: ignore
wandb.Api.upsert_project = upsert_project_getter # type: ignore
weave.utils.http_requests.session.post = post # type: ignore
weave.utils.http_requests.session.get = get # type: ignore

# Silence Weave logging
for name in logging.root.manager.loggerDict:
if name.startswith("weave"):
logging.getLogger(name).disabled = True

# Set dummy API key if missing
if not os.environ.get("WANDB_API_KEY"):
os.environ["WANDB_API_KEY"] = "dumped_api_key_for_weave_tracer"

# if needed in future tests, enable this and replace WF_TRACE_SERVER_URL to local server
# full_url = f"http://127.0.0.1:{_port}"
# os.environ["WF_TRACE_SERVER_URL"] = full_url


def uninstrument_weave():
"""
Restore the original Weave/W&B integration methods and HTTP requests.
"""
try:
import weave
from weave.compat import wandb # type: ignore
except ImportError:
logger.warning("Weave or wandb not installed; cannot uninstrument.")
return

global _original_default_entity_name_getter
if _original_default_entity_name_getter is not None:
wandb.Api.default_entity_name = _original_default_entity_name_getter # type: ignore
_original_default_entity_name_getter = None
logger.info("restored wandb.Api.default_entity_name")

global _original_upsert_project_getter
if _original_upsert_project_getter is not None:
wandb.Api.upsert_project = _original_upsert_project_getter # type: ignore
_original_upsert_project_getter = None
logger.info("restored wandb.Api.upsert_project")

global _original_weave_post
if _original_weave_post is not None:
weave.utils.http_requests.session.post = _original_weave_post # type: ignore
_original_weave_post = None
logger.info("restored weave.utils.http_requests.session.post")

global _original_weave_get
if _original_weave_get is not None:
weave.utils.http_requests.session.get = _original_weave_get # type: ignore
_original_weave_get = None
logger.info("restored weave.utils.http_requests.session.get")

# Restore Weave logging
for name in logging.root.manager.loggerDict:
if name.startswith("weave"):
logging.getLogger(name).disabled = False
3 changes: 2 additions & 1 deletion agentlightning/tracer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
from .agentops import AgentOpsTracer
from .base import Tracer
from .otel import OtelTracer
from .weave import WeaveTracer

__all__ = ["AgentOpsTracer", "Tracer", "OtelTracer"]
__all__ = ["AgentOpsTracer", "Tracer", "OtelTracer", "WeaveTracer"]
Loading