Add tenant-safe value, telemetry, connector, commercial, and production-readiness foundations.
80 lines
2.2 KiB
Python
80 lines
2.2 KiB
Python
from __future__ import annotations
|
|
|
|
from app.services.runtime_chat import RuntimeChatOperationContext, RuntimeChatService
|
|
from app.services.runtime_chat_attempts import RuntimeChatAttemptPermit
|
|
|
|
|
|
class RecordingAttemptObserver:
|
|
def __init__(self, timeline: list[str] | None = None) -> None:
|
|
self.permits = []
|
|
self.completed = []
|
|
self.failures = []
|
|
self.timeline = timeline
|
|
|
|
def on_permit(self, event):
|
|
self.permits.append(event)
|
|
if self.timeline is not None:
|
|
self.timeline.append(f"permit:{event.identity.attempt}")
|
|
return None
|
|
|
|
def on_completed(self, event) -> None:
|
|
self.completed.append(event)
|
|
if self.timeline is not None:
|
|
self.timeline.append(
|
|
f"completed:{event.identity.attempt}:{event.outcome}"
|
|
)
|
|
|
|
def on_observer_failure(self, failure) -> None:
|
|
self.failures.append(failure)
|
|
|
|
|
|
class FailingCompletionObserver(RecordingAttemptObserver):
|
|
def on_completed(self, event) -> None:
|
|
super().on_completed(event)
|
|
raise RuntimeError("completion observer unavailable")
|
|
|
|
|
|
class FailingPermitObserver(RecordingAttemptObserver):
|
|
def on_permit(self, event):
|
|
super().on_permit(event)
|
|
raise RuntimeError("permit observer unavailable")
|
|
|
|
|
|
class DenyingAttemptObserver(RecordingAttemptObserver):
|
|
def on_permit(self, event):
|
|
super().on_permit(event)
|
|
return RuntimeChatAttemptPermit(
|
|
allowed=False,
|
|
reason="tenant quota exhausted",
|
|
)
|
|
|
|
|
|
def build_operation_context() -> RuntimeChatOperationContext:
|
|
return RuntimeChatOperationContext(
|
|
tenant_id="tenant-runtime-chat",
|
|
operation_id="operation-runtime-chat-001",
|
|
run_id="run-runtime-chat-001",
|
|
invocation_seq=7,
|
|
attempt_scope="unit-test-completion",
|
|
)
|
|
|
|
|
|
def patch_single_slot(
|
|
monkeypatch,
|
|
service: RuntimeChatService,
|
|
*,
|
|
provider: str,
|
|
model: str,
|
|
) -> None:
|
|
monkeypatch.setattr(
|
|
service,
|
|
"_load_chat_slot",
|
|
lambda slot: {
|
|
"slot": slot,
|
|
"provider": provider,
|
|
"endpoint": "https://example.com/v1",
|
|
"model": model,
|
|
"apiKey": "secret",
|
|
},
|
|
)
|