Files
Stirling-PDF/engine/tests/test_stirling_contracts.py
James BruntonandGitHub d52c7ced7c Improvements to Stirling Engine to prepare for SaaS release (#6603)
# Description of Changes
- Use pool for postgres connections
- Add ability to require user ID to be set on API calls to the engine
- Add process-wide concurrency cap on AI access (in addition to existing
user caps)
- Allow number of workers (threads) to be specified for stirling engine
- Update env var names to reflect that the DB is not just for RAG
2026-06-11 16:31:35 +01:00

112 lines
3.4 KiB
Python

from stirling.config import AppSettings
from stirling.contracts import (
AgentExecutionRequest,
AgentSpec,
AgentSpecStep,
AiFile,
EditPlanResponse,
ExecutionContext,
ExtractedFileText,
ExtractedTextArtifact,
OrchestratorRequest,
PdfQuestionAnswerResponse,
PdfTextSelection,
ToolOperationStep,
)
from stirling.models import FileId
from stirling.models.tool_models import Angle, RotatePdfParams, ToolEndpoint
def test_orchestrator_request_accepts_user_message() -> None:
request = OrchestratorRequest(
user_message="Rotate the PDF",
files=[AiFile(id=FileId("test-id"), name="test.pdf")],
artifacts=[
ExtractedTextArtifact(
files=[
ExtractedFileText(
file_name="test.pdf",
pages=[PdfTextSelection(page_number=1, text="Hello")],
)
]
)
],
)
assert request.user_message == "Rotate the PDF"
assert len(request.artifacts) == 1
def test_agent_execution_request_uses_typed_agent_spec() -> None:
steps: list[AgentSpecStep] = [
ToolOperationStep(
tool=ToolEndpoint.ROTATE_PDF,
parameters=RotatePdfParams(angle=Angle(90)),
)
]
request = AgentExecutionRequest(
agent_spec=AgentSpec(
name="Invoice cleanup",
description="Normalise inbound invoices",
objective="Prepare uploads for accounting review",
steps=steps,
),
current_step_index=0,
execution_context=ExecutionContext(input_files=["invoice.pdf"]),
)
assert request.agent_spec.steps[0].kind == "tool"
def test_edit_plan_response_has_typed_steps() -> None:
steps = [ToolOperationStep(tool=ToolEndpoint.ROTATE_PDF, parameters=RotatePdfParams(angle=Angle(90)))]
response = EditPlanResponse(
summary="Rotate the input PDF by 90 degrees.",
steps=steps,
)
assert response.steps[0].tool == ToolEndpoint.ROTATE_PDF
def test_pdf_question_answer_defaults_evidence_list() -> None:
response = PdfQuestionAnswerResponse(answer="The invoice total is 120.00")
assert response.evidence == []
def test_app_settings_accepts_model_configuration() -> None:
from pathlib import Path
from stirling.config import DocumentsBackend
settings = AppSettings(
smart_model_name="claude-sonnet-4-5-20250929",
fast_model_name="claude-haiku-4-5-20251001",
smart_model_max_tokens=8192,
fast_model_max_tokens=2048,
model_max_concurrency=32,
documents_backend=DocumentsBackend.SQLITE,
rag_embedding_model="voyageai:voyage-4",
documents_sqlite_path=Path(":memory:"),
documents_pgvector_dsn="",
documents_pgvector_pool_min_size=1,
documents_pgvector_pool_max_size=10,
rag_chunk_size=512,
rag_chunk_overlap=64,
rag_default_top_k=5,
rag_max_searches=5,
chunked_reasoner_chars_per_slice=16_000,
chunked_reasoner_concurrency=10,
chunked_reasoner_worker_timeout_seconds=60.0,
chunked_reasoner_notes_char_budget=250_000,
max_pages=200,
max_characters=200_000,
require_user_id=False,
posthog_enabled=False,
posthog_api_key="",
posthog_host="https://eu.i.posthog.com",
)
assert settings.smart_model_name
assert settings.fast_model_max_tokens == 2048