""" Tests for external_offering — the orchestrated outbound consultation flow. Architecture §4 Step 22. These tests use a mock model caller so no real API requests are made. A separate live integration test (skipped by default) can run against Anthropic's API when ANTHROPIC_API_KEY is set and the SHORASHIM_LIVE_API env var is true. """ import os import pytest from korban_processor.external_offering import ( ExternalConsultation, consult_external_model, ) from korban_processor.korban import OfferingType, Provenance from korban_processor.model_interface import ModelRequest, ModelResponse def _fake_caller(response_text: str): """Build a mock caller that returns a fixed response.""" def caller(request: ModelRequest) -> ModelResponse: return ModelResponse( content=response_text, model="mock-claude", stop_reason="end_turn", input_tokens=10, output_tokens=20, ) return caller # ============================================================ # Basic flow # ============================================================ def test_consult_external_model_returns_full_consultation(): """A consultation captures request, raw response, processed korban, and routing — the full chain is auditable.""" fake_response = ( "Bereishit 1:1 begins with the root bara. The shoresh ב-ר-א means " "to create from nothing. This is foundational." ) result = consult_external_model( query="Explain bereishit 1:1", source_query="user_courtyard_request_42", caller=_fake_caller(fake_response), ) assert isinstance(result, ExternalConsultation) assert result.request.query == "Explain bereishit 1:1" assert result.raw_response.content == fake_response assert result.raw_response.model == "mock-claude" assert result.processed.provenance is Provenance.CLAUDE assert result.routing.destination == "talmudic_engine" # default OLAH def test_raw_korban_is_preserved_on_processed_output(): """Eish zarah Form 3 (gilui arayot — severed coupling): the raw korban must be preserved on the processed output. The floor between input and output is never severed.""" result = consult_external_model( query="any", source_query="trigger_query", caller=_fake_caller( "The root k-d-sh appears in Vayikra. Holiness is separation." ), ) raw = result.processed.raw_korban assert raw is not None, ( "raw_korban must be preserved on ProcessedKorban — " "severing input from output is gilui arayot" ) assert raw.source_query == "trigger_query" assert raw.provenance is Provenance.CLAUDE def test_provenance_is_recorded_on_korban(): """Eish zarah Form 1 (avodah zarah — external as Torah): provenance is never concealed. Every external response is tagged with its source.""" result = consult_external_model( query="any", source_query="any", provenance=Provenance.CLAUDE, caller=_fake_caller("test response with bereishit reference"), ) assert result.processed.provenance is Provenance.CLAUDE assert result.processed.raw_korban.provenance is Provenance.CLAUDE # ============================================================ # Offering type → routing destination # ============================================================ @pytest.mark.parametrize("offering_type,destination", [ (OfferingType.OLAH, "talmudic_engine"), (OfferingType.SHELAMIM, "talmudic_engine"), (OfferingType.MINCHAH, "talmudic_engine"), (OfferingType.CHATAT, "error_correction"), ]) def test_offering_type_drives_routing(offering_type, destination): """Each offering type routes to its specified destination.""" result = consult_external_model( query="any", source_query="any", offering_type=offering_type, caller=_fake_caller( "The shoresh r-tz-h means will. Vayikra 1:3 uses lirtzono — " "for his acceptance." ), ) assert result.routing.destination == destination # ============================================================ # Refusal to silently proxy unknown providers # ============================================================ def test_unknown_provenance_without_caller_raises(): """We don't silently route MISTRAL/GPT/etc through Claude. A caller must be supplied explicitly. This prevents accidental misrouting and keeps provenance honest.""" with pytest.raises(NotImplementedError) as excinfo: consult_external_model( query="any", source_query="any", provenance=Provenance.GPT, ) assert "GPT" in str(excinfo.value).upper() or "gpt" in str(excinfo.value) def test_explicit_caller_overrides_provider_check(): """If the caller supplies a callable for a non-Claude provider, the flow proceeds — they took responsibility for the wiring.""" result = consult_external_model( query="any", source_query="any", provenance=Provenance.GPT, caller=_fake_caller("test response with shoresh sh-l-m"), ) assert result.processed.provenance is Provenance.GPT # ============================================================ # System prompt is forwarded # ============================================================ def test_system_prompt_is_forwarded(): """A system prompt sent in becomes part of the request record.""" result = consult_external_model( query="any", source_query="any", system_prompt="You are a Torah scholar. Cite verse references.", caller=_fake_caller("Bereishit 1:1 is the opening verse."), ) assert result.request.system_prompt == "You are a Torah scholar. Cite verse references." # ============================================================ # Live API integration test — opt-in only # ============================================================ @pytest.mark.skipif( not os.environ.get("SHORASHIM_LIVE_API"), reason="Set SHORASHIM_LIVE_API=1 to run a real API call against Anthropic", ) def test_live_anthropic_call(): """Real API call. Costs money. Run only when explicitly enabled.""" if not os.environ.get("ANTHROPIC_API_KEY"): pytest.skip("ANTHROPIC_API_KEY not set") result = consult_external_model( query="What is the shoresh of bereishit?", source_query="live_integration_test", offering_type=OfferingType.OLAH, ) assert result.raw_response.content assert result.processed.raw_korban is not None assert result.processed.provenance is Provenance.CLAUDE assert result.raw_response.model.startswith("claude")