Files
wehub-resource-sync 85742ab165
CPU Test / Lint - next (push) Waiting to run
Dashboard / Chromatic (push) Waiting to run
CPU Test / Lint - fast (push) Waiting to run
CPU Test / Build documentation (push) Waiting to run
CPU Test / Test (Store, legacy, Python 3.10) (push) Waiting to run
CPU Test / Test (Utilities, legacy, Python 3.10) (push) Waiting to run
CPU Test / Test (Weave, legacy, Python 3.10) (push) Waiting to run
CPU Test / Test (AgentOps, stable, Python 3.11) (push) Waiting to run
CPU Test / Test (LLM proxy, stable, Python 3.11) (push) Waiting to run
CPU Test / Test (Others, stable, Python 3.11) (push) Waiting to run
CPU Test / Test (Store, stable, Python 3.11) (push) Waiting to run
CPU Test / Test (Utilities, stable, Python 3.11) (push) Waiting to run
CPU Test / Test (Weave, stable, Python 3.11) (push) Waiting to run
CPU Test / Test (AgentOps, stable, Python 3.12) (push) Waiting to run
CPU Test / Test (LLM proxy, stable, Python 3.12) (push) Waiting to run
CPU Test / Test (Others, stable, Python 3.12) (push) Waiting to run
CPU Test / Test (Store, stable, Python 3.12) (push) Waiting to run
CPU Test / Test (Utilities, stable, Python 3.12) (push) Waiting to run
CPU Test / Test (Weave, stable, Python 3.12) (push) Waiting to run
CPU Test / Test (AgentOps, latest, Python 3.13) (push) Waiting to run
CPU Test / Test (LLM proxy, latest, Python 3.13) (push) Waiting to run
CPU Test / Test (Others, latest, Python 3.13) (push) Waiting to run
CPU Test / Test (Store, latest, Python 3.13) (push) Waiting to run
CPU Test / Lint - slow (push) Waiting to run
CPU Test / Lint - JavaScript (push) Waiting to run
CPU Test / Test (AgentOps, legacy, Python 3.10) (push) Waiting to run
CPU Test / Test (LLM proxy, legacy, Python 3.10) (push) Waiting to run
CPU Test / Test (Others, legacy, Python 3.10) (push) Waiting to run
CPU Test / Test (Utilities, latest, Python 3.13) (push) Waiting to run
CPU Test / Test (Weave, latest, Python 3.13) (push) Waiting to run
CPU Test / Test (JavaScript) (push) Waiting to run
Deploy Documentation / deploy (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:44:17 +08:00

116 lines
3.6 KiB
Python

# Copyright (c) Microsoft. All rights reserved.
from __future__ import annotations
from typing import Any, cast
from unittest.mock import MagicMock
import pytest
from agentlightning.algorithm.base import Algorithm
from agentlightning.algorithm.utils import with_llm_proxy, with_store
from agentlightning.llm_proxy import LLMProxy
from agentlightning.store.base import LightningStore
class _BaseAlgorithm(Algorithm):
def run(self, *args: Any, **kwargs: Any) -> None:
"""Satisfy the abstract interface without invoking training logic."""
return None
class _StubLLMProxy:
"""Test double that tracks lifecycle calls."""
def __init__(self) -> None:
self.start_calls = 0
self.stop_calls = 0
self.running = False
def is_running(self) -> bool:
return self.running
async def start(self) -> None:
self.start_calls += 1
self.running = True
async def stop(self) -> None:
self.stop_calls += 1
self.running = False
@pytest.mark.asyncio
async def test_with_store_injects_store_argument():
class StoreAlgorithm(_BaseAlgorithm):
@with_store
async def record_store(self, store: LightningStore, payload: str) -> None:
self.seen_store = store # type: ignore[attr-defined]
self.seen_payload = payload # type: ignore[attr-defined]
algorithm = StoreAlgorithm()
fake_store = MagicMock(spec=LightningStore)
algorithm.set_store(fake_store)
await algorithm.record_store("batch-1")
assert algorithm.seen_store is fake_store # type: ignore[attr-defined]
assert algorithm.seen_payload == "batch-1" # type: ignore[attr-defined]
@pytest.mark.asyncio
async def test_with_llm_proxy_allows_optional_injection():
class OptionalProxyAlgorithm(_BaseAlgorithm):
@with_llm_proxy()
async def record_proxy(self, llm_proxy: LLMProxy | None, marker: str) -> None:
self.seen_proxy = llm_proxy # type: ignore[attr-defined]
self.marker = marker # type: ignore[attr-defined]
algorithm = OptionalProxyAlgorithm()
algorithm.set_llm_proxy(None)
await algorithm.record_proxy("optional")
assert algorithm.seen_proxy is None # type: ignore[attr-defined]
assert algorithm.marker == "optional" # type: ignore[attr-defined]
@pytest.mark.asyncio
async def test_with_llm_proxy_required_raises_when_missing():
class RequiredProxyAlgorithm(_BaseAlgorithm):
@with_llm_proxy(required=True)
async def record_proxy(self, llm_proxy: LLMProxy) -> None:
self.seen_proxy = llm_proxy # type: ignore[attr-defined]
algorithm = RequiredProxyAlgorithm()
algorithm.set_llm_proxy(None)
with pytest.raises(ValueError):
await algorithm.record_proxy()
@pytest.mark.asyncio
async def test_with_llm_proxy_auto_start_and_stop():
class AutoProxyAlgorithm(_BaseAlgorithm):
@with_llm_proxy()
async def use_proxy(self, llm_proxy: LLMProxy | None) -> None:
if llm_proxy is None:
raise AssertionError("LLM proxy should be injected")
self.seen_proxy = llm_proxy # type: ignore[attr-defined]
algorithm = AutoProxyAlgorithm()
proxy = _StubLLMProxy()
algorithm.set_llm_proxy(cast(LLMProxy, proxy))
await algorithm.use_proxy()
assert algorithm.seen_proxy is proxy # type: ignore[attr-defined]
assert proxy.start_calls == 1
assert proxy.stop_calls == 1
# When already running, no extra start/stop should be requested.
proxy.running = True
await algorithm.use_proxy()
assert proxy.start_calls == 1
assert proxy.stop_calls == 1