Add square text-to-image rendering with a spend gate
Hall of Helix needs a credential-safe render that returns a provenance receipt and refuses a batch before the quote exceeds its cap. OpenRouter is the only client; the model and the live budget stay with the founder. Assistant: grok Assistant-Session: 01a11ab6-1534-7d63-8606-662b92a80ed6
This commit is contained in:
parent
9dc6b39766
commit
e3ab268d6e
11 changed files with 1335 additions and 3 deletions
|
|
@ -2,6 +2,7 @@
|
|||
Tests for LLMServer HTTP serve mode (FR-1).
|
||||
"""
|
||||
|
||||
import base64
|
||||
import json
|
||||
import threading
|
||||
import time
|
||||
|
|
@ -18,6 +19,7 @@ from llm_connect._diagnostics import (
|
|||
)
|
||||
from llm_connect.adapter import ErrorLLMAdapter, MockLLMAdapter
|
||||
from llm_connect.exceptions import LLMAPIError, LLMConfigurationError, LLMTimeoutError
|
||||
from llm_connect.images import ImageSpendGate, ImageSpendPolicy
|
||||
from llm_connect.models import LLMResponse, RunConfig
|
||||
from llm_connect.profiles import CUSTODIAN_TRIAGE_BALANCED, ProfiledLLMAdapter, RuntimeProfile
|
||||
from llm_connect.server import LLMServer
|
||||
|
|
@ -138,6 +140,14 @@ class TestExecute:
|
|||
assert status == 400
|
||||
assert body == {"error": "invalid JSON body"}
|
||||
|
||||
def test_images_route_is_absent_until_configured(self, server):
|
||||
status, body = _post(
|
||||
f"http://127.0.0.1:{server.port}/images",
|
||||
{"prompt": "a gear"},
|
||||
)
|
||||
assert status == 404
|
||||
assert body == {"error": "not found"}
|
||||
|
||||
def test_unknown_post_path_returns_404(self, server):
|
||||
status, body = _post(
|
||||
f"http://127.0.0.1:{server.port}/wrong",
|
||||
|
|
@ -411,3 +421,43 @@ class TestExecute:
|
|||
|
||||
assert [status for status, _body in results] == [200, 200]
|
||||
assert elapsed < 1.5
|
||||
|
||||
|
||||
class _ServerImageClient:
|
||||
provider = "openrouter"
|
||||
model = "test/image"
|
||||
|
||||
def generate(self, request):
|
||||
return b"\x89PNG\r\n\x1a\nserver", 0.02
|
||||
|
||||
|
||||
def test_images_endpoint_returns_receipt_and_png_bytes():
|
||||
gate = ImageSpendGate(ImageSpendPolicy(max_cost_usd=0.10, quote_usd=0.05))
|
||||
server = LLMServer(
|
||||
adapter=MockLLMAdapter(mock_response="unused"),
|
||||
port=0,
|
||||
image_client=_ServerImageClient(),
|
||||
image_gate=gate,
|
||||
)
|
||||
server.start()
|
||||
try:
|
||||
status, body = _post(
|
||||
f"http://127.0.0.1:{server.port}/images",
|
||||
{"prompt": "a gear", "size": "1024x1024", "output_format": "png"},
|
||||
)
|
||||
execute_status, execute_body = _post(
|
||||
f"http://127.0.0.1:{server.port}/execute",
|
||||
{"prompt": "still here"},
|
||||
)
|
||||
finally:
|
||||
server.stop()
|
||||
|
||||
assert status == 200
|
||||
assert body["receipt"]["provider"] == "openrouter"
|
||||
assert body["receipt"]["model"] == "test/image"
|
||||
assert body["receipt"]["width"] == 1024
|
||||
assert body["receipt"]["within_cap"] is True
|
||||
assert "prompt" not in body["receipt"]
|
||||
assert base64.b64decode(body["image_base64"]).startswith(b"\x89PNG\r\n\x1a\n")
|
||||
assert execute_status == 200
|
||||
assert execute_body["content"] == "unused"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue