mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-11 03:38:38 +00:00
* feat(harness): add litellm/__init__.py * feat(harness): add litellm/constants.py * feat(harness): add litellm/harness/__init__.py * feat(harness): add litellm/harness/adapters/__init__.py * feat(harness): add litellm/harness/adapters/base.py * feat(harness): add litellm/harness/adapters/claude_code.py * feat(harness): add litellm/harness/adapters/codex.py * feat(harness): add litellm/harness/adapters/opencode.py * feat(harness): add litellm/harness/endpoint.py * feat(harness): add litellm/harness/errors.py * feat(harness): add litellm/harness/options.py * feat(harness): add litellm/harness/runtime.py * feat(harness): add litellm/harness/sandbox/__init__.py * feat(harness): add litellm/harness/sandbox/base.py * feat(harness): add litellm/harness/sandbox/docker.py * feat(harness): add litellm/harness/sandbox/local.py * feat(harness): add litellm/harness/sandbox/snapshot.py * feat(harness): add litellm/harness/sync.py * feat(harness): add litellm/harness/types.py * feat(harness): add litellm/sandbox/__init__.py * feat(harness): add README.md * feat(harness): add tests/harness_e2e/__init__.py * feat(harness): add tests/harness_e2e/conftest.py * feat(harness): add tests/harness_e2e/test_harness_e2e.py * feat(harness): add tests/test_litellm/harness/__init__.py * feat(harness): add tests/test_litellm/harness/adapters/__init__.py * feat(harness): add tests/test_litellm/harness/adapters/fixtures/claude_code/api_error.jsonl * feat(harness): add tests/test_litellm/harness/adapters/fixtures/claude_code/max_turns.jsonl * feat(harness): add tests/test_litellm/harness/adapters/fixtures/claude_code/resume_turn.jsonl * feat(harness): add tests/test_litellm/harness/adapters/fixtures/claude_code/structured_output.jsonl * feat(harness): add tests/test_litellm/harness/adapters/fixtures/claude_code/success_tools.jsonl * feat(harness): add tests/test_litellm/harness/adapters/fixtures/codex/reasoning.jsonl * feat(harness): add tests/test_litellm/harness/adapters/fixtures/codex/structured_output.jsonl * feat(harness): add tests/test_litellm/harness/adapters/fixtures/codex/turn_failed.jsonl * feat(harness): add tests/test_litellm/harness/adapters/fixtures/codex/turn1_bash.jsonl * feat(harness): add tests/test_litellm/harness/adapters/fixtures/codex/turn2_resume_apply_patch.jsonl * feat(harness): add tests/test_litellm/harness/adapters/fixtures/opencode/api_error.jsonl * feat(harness): add tests/test_litellm/harness/adapters/fixtures/opencode/endpoint_requests.jsonl * feat(harness): add tests/test_litellm/harness/adapters/fixtures/opencode/readonly_denied_bash.jsonl * feat(harness): add tests/test_litellm/harness/adapters/fixtures/opencode/turn1_write_read.jsonl * feat(harness): add tests/test_litellm/harness/adapters/fixtures/opencode/turn2_session_skill.jsonl * feat(harness): add tests/test_litellm/harness/adapters/test_claude_code.py * feat(harness): add tests/test_litellm/harness/adapters/test_codex.py * feat(harness): add tests/test_litellm/harness/adapters/test_opencode.py * feat(harness): add tests/test_litellm/harness/core_fakes.py * feat(harness): add tests/test_litellm/harness/sandbox/__init__.py * feat(harness): add tests/test_litellm/harness/sandbox/test_docker.py * feat(harness): add tests/test_litellm/harness/sandbox/test_local.py * feat(harness): add tests/test_litellm/harness/sandbox/test_snapshot.py * feat(harness): add tests/test_litellm/harness/test_endpoint.py * feat(harness): add tests/test_litellm/harness/test_init.py * feat(harness): add tests/test_litellm/harness/test_runtime.py * feat(harness): add tests/test_litellm/harness/test_sync.py * feat(harness): add tests/test_litellm/harness/test_types.py * test(harness): use word recall in stream e2e test * refactor(harness): update litellm/__init__.py * refactor(harness): update litellm/constants.py * refactor(harness): update litellm/harness/__init__.py * refactor(harness): remove litellm/harness/adapters/__init__.py * refactor(harness): update litellm/harness/context.py * refactor(harness): update litellm/harness/endpoint.py * refactor(harness): update litellm/harness/handlers/__init__.py * refactor(harness): update litellm/harness/handlers/base.py * refactor(harness): update litellm/harness/handlers/cli_handler.py * refactor(harness): update litellm/harness/handlers/deepagents_handler.py * refactor(harness): update litellm/harness/runtime.py * refactor(harness): update litellm/harness/sandbox/docker.py * refactor(harness): update litellm/harness/sandbox/local.py * refactor(harness): update litellm/harness/sync.py * refactor(harness): update litellm/harness/types.py * refactor(harness): update litellm/llms/base_llm/harness/__init__.py * refactor(harness): update litellm/llms/base_llm/harness/transformation.py * refactor(harness): update litellm/llms/base_llm/harness/utils.py * refactor(harness): update litellm/llms/claude_code/__init__.py * refactor(harness): update litellm/llms/claude_code/harness/__init__.py * refactor(harness): update litellm/llms/claude_code/harness/transformation.py * refactor(harness): update litellm/llms/codex/__init__.py * refactor(harness): update litellm/llms/codex/harness/__init__.py * refactor(harness): update litellm/llms/codex/harness/transformation.py * refactor(harness): update litellm/llms/deepagents/__init__.py * refactor(harness): update litellm/llms/deepagents/harness/__init__.py * refactor(harness): update litellm/llms/deepagents/harness/sandbox_backend.py * refactor(harness): update litellm/llms/deepagents/harness/transformation.py * refactor(harness): update litellm/llms/opencode/__init__.py * refactor(harness): update litellm/llms/opencode/harness/__init__.py * refactor(harness): update litellm/llms/opencode/harness/transformation.py * refactor(harness): update litellm/utils.py * refactor(harness): update README.md * refactor(harness): update tests/harness_e2e/conftest.py * refactor(harness): update tests/harness_e2e/test_harness_e2e.py * refactor(harness): remove tests/test_litellm/harness/__init__.py * refactor(harness): remove tests/test_litellm/harness/adapters/__init__.py * refactor(harness): remove tests/test_litellm/harness/adapters/fixtures/claude_code/api_error.jsonl * refactor(harness): remove tests/test_litellm/harness/adapters/fixtures/claude_code/max_turns.jsonl * refactor(harness): remove tests/test_litellm/harness/adapters/fixtures/claude_code/resume_turn.jsonl * refactor(harness): remove tests/test_litellm/harness/adapters/fixtures/claude_code/structured_output.jsonl * refactor(harness): remove tests/test_litellm/harness/adapters/fixtures/claude_code/success_tools.jsonl * refactor(harness): remove tests/test_litellm/harness/adapters/fixtures/codex/reasoning.jsonl * refactor(harness): remove tests/test_litellm/harness/adapters/fixtures/codex/structured_output.jsonl * refactor(harness): remove tests/test_litellm/harness/adapters/fixtures/codex/turn_failed.jsonl * refactor(harness): remove tests/test_litellm/harness/adapters/fixtures/codex/turn1_bash.jsonl * refactor(harness): remove tests/test_litellm/harness/adapters/fixtures/codex/turn2_resume_apply_patch.jsonl * refactor(harness): remove tests/test_litellm/harness/adapters/fixtures/opencode/api_error.jsonl * refactor(harness): remove tests/test_litellm/harness/adapters/fixtures/opencode/endpoint_requests.jsonl * refactor(harness): remove tests/test_litellm/harness/adapters/fixtures/opencode/readonly_denied_bash.jsonl * refactor(harness): remove tests/test_litellm/harness/adapters/fixtures/opencode/turn1_write_read.jsonl * refactor(harness): remove tests/test_litellm/harness/adapters/fixtures/opencode/turn2_session_skill.jsonl * refactor(harness): remove tests/test_litellm/harness/adapters/test_claude_code.py * refactor(harness): remove tests/test_litellm/harness/adapters/test_codex.py * refactor(harness): remove tests/test_litellm/harness/adapters/test_opencode.py * refactor(harness): remove tests/test_litellm/harness/core_fakes.py * refactor(harness): remove tests/test_litellm/harness/sandbox/__init__.py * refactor(harness): remove tests/test_litellm/harness/sandbox/test_docker.py * refactor(harness): remove tests/test_litellm/harness/sandbox/test_local.py * refactor(harness): remove tests/test_litellm/harness/sandbox/test_snapshot.py * refactor(harness): remove tests/test_litellm/harness/test_endpoint.py * refactor(harness): remove tests/test_litellm/harness/test_init.py * refactor(harness): remove tests/test_litellm/harness/test_runtime.py * refactor(harness): remove tests/test_litellm/harness/test_sync.py * refactor(harness): remove tests/test_litellm/harness/test_types.py * refactor(harness): update tests/unit/harness/__init__.py * refactor(harness): update tests/unit/harness/core_fakes.py * refactor(harness): update tests/unit/harness/handlers/__init__.py * refactor(harness): update tests/unit/harness/handlers/test_deepagents_handler.py * refactor(harness): update tests/unit/harness/sandbox/__init__.py * refactor(harness): update tests/unit/harness/sandbox/test_docker.py * refactor(harness): update tests/unit/harness/sandbox/test_local.py * refactor(harness): update tests/unit/harness/sandbox/test_snapshot.py * refactor(harness): update tests/unit/harness/test_endpoint.py * refactor(harness): update tests/unit/harness/test_init.py * refactor(harness): update tests/unit/harness/test_runtime.py * refactor(harness): update tests/unit/harness/test_sync.py * refactor(harness): update tests/unit/harness/test_types.py * refactor(harness): update tests/unit/llms/claude_code/__init__.py * refactor(harness): update tests/unit/llms/claude_code/harness/__init__.py * refactor(harness): update tests/unit/llms/claude_code/harness/fixtures/api_error.jsonl * refactor(harness): update tests/unit/llms/claude_code/harness/fixtures/max_turns.jsonl * refactor(harness): update tests/unit/llms/claude_code/harness/fixtures/resume_turn.jsonl * refactor(harness): update tests/unit/llms/claude_code/harness/fixtures/structured_output.jsonl * refactor(harness): update tests/unit/llms/claude_code/harness/fixtures/success_tools.jsonl * refactor(harness): update tests/unit/llms/claude_code/harness/test_transformation.py * refactor(harness): update tests/unit/llms/codex/__init__.py * refactor(harness): update tests/unit/llms/codex/harness/__init__.py * refactor(harness): update tests/unit/llms/codex/harness/fixtures/reasoning.jsonl * refactor(harness): update tests/unit/llms/codex/harness/fixtures/structured_output.jsonl * refactor(harness): update tests/unit/llms/codex/harness/fixtures/turn1_bash.jsonl * refactor(harness): update tests/unit/llms/codex/harness/fixtures/turn2_resume_apply_patch.jsonl * refactor(harness): update tests/unit/llms/codex/harness/fixtures/turn_failed.jsonl * refactor(harness): update tests/unit/llms/codex/harness/test_transformation.py * refactor(harness): update tests/unit/llms/deepagents/__init__.py * refactor(harness): update tests/unit/llms/deepagents/harness/__init__.py * refactor(harness): update tests/unit/llms/deepagents/harness/test_transformation.py * refactor(harness): update tests/unit/llms/opencode/__init__.py * refactor(harness): update tests/unit/llms/opencode/harness/__init__.py * refactor(harness): update tests/unit/llms/opencode/harness/fixtures/api_error.jsonl * refactor(harness): update tests/unit/llms/opencode/harness/fixtures/endpoint_requests.jsonl * refactor(harness): update tests/unit/llms/opencode/harness/fixtures/readonly_denied_bash.jsonl * refactor(harness): update tests/unit/llms/opencode/harness/fixtures/turn1_write_read.jsonl * refactor(harness): update tests/unit/llms/opencode/harness/fixtures/turn2_session_skill.jsonl * refactor(harness): update tests/unit/llms/opencode/harness/test_transformation.py * ci: allowlist tests/harness_e2e, which needs live runtimes and a gateway * fix(harness): bound the turn event queue * fix(harness): bound the turn event queue with backpressure * style: sort imports in utils * ci: exclude agent-harness config folders from provider docs check * refactor(harness): update tests/harness_e2e/conftest.py * refactor(harness): update tests/harness_e2e/test_harness_e2e.py * refactor(harness): update tests/unit/harness/core_fakes.py * refactor(harness): update tests/unit/harness/handlers/test_deepagents_handler.py * refactor(harness): update tests/unit/harness/test_runtime.py * refactor(harness): update tests/unit/harness/test_sync.py * refactor(harness): update tests/unit/llms/deepagents/harness/test_transformation.py * refactor(harness): update tests/unit/llms/opencode/harness/test_transformation.py * refactor(harness): update litellm/harness/endpoint.py * refactor(harness): update litellm/harness/handlers/deepagents_handler.py * refactor(harness): update litellm/harness/options.py * refactor(harness): update litellm/harness/runtime.py * refactor(harness): update litellm/harness/sandbox/snapshot.py * refactor(harness): update litellm/llms/base_llm/harness/transformation.py * refactor(harness): update litellm/llms/base_llm/harness/utils.py * refactor(harness): update litellm/llms/claude_code/harness/transformation.py * refactor(harness): update litellm/llms/codex/harness/transformation.py * refactor(harness): update litellm/llms/deepagents/harness/sandbox_backend.py * refactor(harness): update litellm/llms/deepagents/harness/transformation.py * refactor(harness): update litellm/llms/opencode/harness/transformation.py * refactor(harness): update litellm/sandbox/__init__.py * refactor(harness): update tests/unit/llms/claude_code/harness/test_transformation.py * refactor(harness): update tests/unit/llms/deepagents/harness/test_sandbox_backend_symlinks.py * refactor(harness): update tests/unit/llms/opencode/harness/test_transformation.py * refactor(harness): update litellm/llms/base_llm/harness/utils.py * refactor(harness): update litellm/llms/codex/harness/transformation.py * refactor(harness): update tests/code_coverage_tests/recursive_detector.py * refactor(harness): update tests/unit/llms/base_llm/harness/__init__.py * refactor(harness): update tests/unit/llms/claude_code/harness/fixtures/__init__.py * refactor(harness): update tests/unit/llms/codex/harness/fixtures/__init__.py * refactor(harness): update tests/unit/llms/opencode/harness/fixtures/__init__.py * refactor(harness): update litellm/harness/__init__.py * refactor(harness): update litellm/harness/context.py * refactor(harness): update litellm/harness/endpoint.py * refactor(harness): update litellm/harness/handlers/__init__.py * refactor(harness): update litellm/harness/handlers/base.py * refactor(harness): update litellm/harness/handlers/cli_handler.py * refactor(harness): update litellm/harness/handlers/deepagents_handler.py * refactor(harness): update litellm/harness/runtime.py * refactor(harness): update litellm/harness/sandbox/__init__.py * refactor(harness): update litellm/harness/sandbox/base.py * refactor(harness): update litellm/harness/sandbox/docker.py * refactor(harness): update litellm/harness/sandbox/local.py * refactor(harness): update litellm/harness/sandbox/snapshot.py * refactor(harness): update litellm/harness/sync.py * refactor(harness): update litellm/harness/types.py * refactor(harness): update litellm/llms/base_llm/harness/transformation.py * refactor(harness): update litellm/llms/base_llm/harness/utils.py * refactor(harness): update litellm/llms/claude_code/harness/transformation.py * refactor(harness): update litellm/llms/codex/harness/transformation.py * refactor(harness): update litellm/llms/deepagents/harness/sandbox_backend.py * refactor(harness): update litellm/llms/deepagents/harness/transformation.py * refactor(harness): update litellm/llms/opencode/harness/transformation.py * refactor(harness): update litellm/types/llms/custom_http.py * refactor(harness): update tests/unit/harness/test_endpoint.py * refactor(harness): update litellm/harness/runtime.py * refactor(harness): update litellm/llms/deepagents/harness/sandbox_backend.py * refactor(harness): update tests/unit/harness/test_init.py * refactor(harness): update tests/unit/harness/test_runtime.py * refactor(harness): update tests/unit/llms/deepagents/harness/test_sandbox_backend_symlinks.py
246 lines
7.5 KiB
Python
246 lines
7.5 KiB
Python
"""Fake handler/config, sandbox and endpoint shared by the core runtime tests."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import os
|
|
from collections.abc import AsyncIterator, Callable
|
|
from dataclasses import dataclass
|
|
from typing import Any, ClassVar
|
|
|
|
import pytest
|
|
|
|
from litellm.harness import runtime
|
|
from litellm.harness.context import SessionContext
|
|
from litellm.harness.handlers.base import BaseHarnessHandler
|
|
from litellm.llms.base_llm.harness.transformation import BaseHarnessConfig
|
|
from litellm.harness.options import ClaudeCodeOptions
|
|
from litellm.harness.sandbox.base import CompletedRun
|
|
from litellm.harness.sandbox.snapshot import snapshot_local
|
|
from litellm.harness.types import (
|
|
Approval,
|
|
Capabilities,
|
|
Event,
|
|
Harness,
|
|
Text,
|
|
ToolCall,
|
|
ToolResult,
|
|
)
|
|
|
|
ALL_MODES = frozenset({"read-only", "ask", "edit", "full"})
|
|
FULL_CAPS = Capabilities(
|
|
structured_output=True,
|
|
tool_approval=True,
|
|
tool_filtering=True,
|
|
history=True,
|
|
custom_tools=True,
|
|
skills=True,
|
|
resume=True,
|
|
permission_modes=ALL_MODES,
|
|
)
|
|
NARROW_CAPS = Capabilities(
|
|
structured_output=False,
|
|
tool_approval=False,
|
|
tool_filtering=False,
|
|
history=False,
|
|
custom_tools=False,
|
|
skills=False,
|
|
resume=False,
|
|
permission_modes=frozenset({"read-only", "full"}),
|
|
)
|
|
|
|
|
|
class FakeConfig(BaseHarnessConfig):
|
|
"""Declares the fake harness; per-test subclasses override capabilities."""
|
|
|
|
harness: ClassVar[Harness] = Harness.CLAUDE_CODE
|
|
options_type: ClassVar[type] = ClaudeCodeOptions
|
|
capabilities: ClassVar[Capabilities] = FULL_CAPS
|
|
uses_model_endpoint: ClassVar[bool] = True
|
|
|
|
|
|
Script = Callable[["FakeAdapter", SessionContext, str], AsyncIterator[Event]]
|
|
|
|
|
|
class FakeSandbox:
|
|
"""A LocalSandbox-like object over a temp dir; no subprocesses."""
|
|
|
|
def __init__(self, workdir: str) -> None:
|
|
self.workdir = workdir
|
|
self.closed = False
|
|
|
|
def _path(self, path: str) -> str:
|
|
return path if os.path.isabs(path) else os.path.join(self.workdir, path)
|
|
|
|
async def exec(self, cmd: list[str], *, env: Any = None, cwd: Any = None) -> Any:
|
|
raise NotImplementedError
|
|
|
|
async def run(
|
|
self, cmd: list[str], *, env: Any = None, cwd: Any = None, timeout: Any = None
|
|
) -> CompletedRun:
|
|
return CompletedRun(stdout="", stderr="", exit_code=0)
|
|
|
|
async def read(self, path: str) -> bytes:
|
|
with open(self._path(path), "rb") as fh:
|
|
return fh.read()
|
|
|
|
async def write(self, path: str, data: bytes) -> None:
|
|
full = self._path(path)
|
|
os.makedirs(os.path.dirname(full), exist_ok=True)
|
|
with open(full, "wb") as fh:
|
|
fh.write(data)
|
|
|
|
def host_url(self, port: int) -> str:
|
|
return f"http://127.0.0.1:{port}"
|
|
|
|
async def which(self, binary: str) -> str | None:
|
|
return None
|
|
|
|
async def snapshot(self) -> dict[str, str]:
|
|
return await snapshot_local(self.workdir)
|
|
|
|
async def close(self) -> None:
|
|
self.closed = True
|
|
|
|
|
|
@dataclass
|
|
class FakeUsage:
|
|
input_tokens: int = 0
|
|
output_tokens: int = 0
|
|
cost: float = 0.0
|
|
calls: int = 0
|
|
|
|
def add(self, input_tokens: int, output_tokens: int, cost: float) -> None:
|
|
self.input_tokens += input_tokens
|
|
self.output_tokens += output_tokens
|
|
self.cost += cost
|
|
self.calls += 1
|
|
|
|
|
|
class FakeEndpoint:
|
|
"""Stands in for ModelEndpoint; records every instance."""
|
|
|
|
instances: ClassVar[list[FakeEndpoint]] = []
|
|
|
|
def __init__(self, harness: Harness, model: Any, gateway: Any, **kwargs: Any):
|
|
self.harness = harness
|
|
self.model = model
|
|
self.gateway = gateway
|
|
self.kwargs = kwargs
|
|
self.usage = FakeUsage()
|
|
self.url = "http://127.0.0.1:1"
|
|
self.token = "tok"
|
|
self.entered = False
|
|
self.exited = False
|
|
FakeEndpoint.instances.append(self)
|
|
|
|
async def __aenter__(self) -> FakeEndpoint:
|
|
self.entered = True
|
|
return self
|
|
|
|
async def __aexit__(self, *exc_info: object) -> None:
|
|
self.exited = True
|
|
|
|
|
|
async def script_hello(
|
|
adapter: FakeAdapter, ctx: SessionContext, prompt: str
|
|
) -> AsyncIterator[Event]:
|
|
yield Text("hello ")
|
|
yield ToolCall(id="t1", name="bash", native_name="Bash", input={"cmd": "ls"})
|
|
yield ToolResult(id="t1", output="a.txt")
|
|
yield Text("world")
|
|
if ctx.endpoint is not None:
|
|
ctx.endpoint.usage.add(10, 5, 0.25)
|
|
else:
|
|
ctx.input_tokens += 10
|
|
ctx.output_tokens += 5
|
|
ctx.cost += 0.25
|
|
ctx.calls += 1
|
|
|
|
|
|
class FakeAdapter(BaseHarnessHandler):
|
|
"""Configurable adapter; subclass per test and set `script` / `caps`."""
|
|
|
|
harness: ClassVar[Harness] = Harness.CLAUDE_CODE
|
|
options_type: ClassVar[type] = ClaudeCodeOptions
|
|
capabilities: ClassVar[Capabilities] = FULL_CAPS
|
|
uses_endpoint: ClassVar[bool] = True
|
|
script: ClassVar[Script] = script_hello
|
|
instances: ClassVar[list[FakeAdapter]] = []
|
|
|
|
def __init__(self, config: BaseHarnessConfig | None = None) -> None:
|
|
self.config = config if config is not None else FakeConfig()
|
|
self.calls: list[str] = []
|
|
self.prompts: list[str] = []
|
|
self.resumed_with: str | None = None
|
|
self.approvals: list[tuple[bool, str]] = []
|
|
type(self).instances.append(self)
|
|
|
|
async def start(self, ctx: SessionContext) -> None:
|
|
self.calls.append("start")
|
|
|
|
async def turn(self, ctx: SessionContext, prompt: str) -> AsyncIterator[Event]:
|
|
self.calls.append("turn")
|
|
self.prompts.append(prompt)
|
|
async for event in type(self).script(self, ctx, prompt):
|
|
yield event
|
|
|
|
async def stop(self, ctx: SessionContext) -> None:
|
|
self.calls.append("stop")
|
|
|
|
def native_session_id(self) -> str | None:
|
|
return "native-123"
|
|
|
|
async def resume(self, ctx: SessionContext, native_session_id: str) -> None:
|
|
self.calls.append("resume")
|
|
self.resumed_with = native_session_id
|
|
|
|
async def history(self, ctx: SessionContext) -> list[dict[str, Any]]:
|
|
return [{"role": "user", "content": p} for p in self.prompts]
|
|
|
|
|
|
async def script_approval(
|
|
adapter: FakeAdapter, ctx: SessionContext, prompt: str
|
|
) -> AsyncIterator[Event]:
|
|
approval = Approval(tool="bash", input={"cmd": "rm"})
|
|
yield approval
|
|
decision = await approval.wait()
|
|
adapter.approvals.append(decision)
|
|
yield Text("allowed" if decision[0] else "denied")
|
|
|
|
|
|
def install_adapter(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
script: Script = script_hello,
|
|
caps: Capabilities = FULL_CAPS,
|
|
uses_endpoint: bool = True,
|
|
) -> type[FakeAdapter]:
|
|
"""Register a FakeAdapter subclass for every harness and fake the endpoint."""
|
|
adapter_cls = type(
|
|
"TestAdapter",
|
|
(FakeAdapter,),
|
|
{
|
|
"script": staticmethod(script),
|
|
"capabilities": caps,
|
|
"uses_endpoint": uses_endpoint,
|
|
"instances": [],
|
|
},
|
|
)
|
|
config_cls = type(
|
|
"TestConfig",
|
|
(FakeConfig,),
|
|
{"capabilities": caps, "uses_model_endpoint": uses_endpoint},
|
|
)
|
|
monkeypatch.setattr(runtime, "get_harness_config", lambda harness: config_cls())
|
|
monkeypatch.setattr(
|
|
runtime, "get_harness_handler", lambda config: adapter_cls(config)
|
|
)
|
|
monkeypatch.setattr(runtime, "ModelEndpoint", FakeEndpoint)
|
|
monkeypatch.delenv("LITELLM_PROXY_API_BASE", raising=False)
|
|
monkeypatch.delenv("LITELLM_PROXY_API_KEY", raising=False)
|
|
FakeEndpoint.instances = []
|
|
return adapter_cls
|
|
|
|
|
|
async def wait_forever() -> None:
|
|
await asyncio.Event().wait()
|