ó
    À‘´jD  ã                  óŠ  • S r SSKJr  SSKJr  SSKJr  SSKJrJ	r	J
r
Jr  SSKJrJrJr  SSKJrJr  \" SS	S
S9r1 SkrS$S jr\\\" \5      4   rSr " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r  " S S \5      r!\S%S! j5       r"/ S"Qr#g#)&u  Centralized configuration: one Pydantic ``Settings`` tree.

A single ``BaseSettings`` object composed of nested domain groups owns every
config value. Modules read config via ``get_settings()`` (a cached singleton)
instead of touching the environment directly. The one exception is the
provider key-presence probes in ``quber.agents.factory``, which read
``os.getenv`` by design.

Design notes:

- Each group is a ``BaseSettings`` subclass (not a plain ``BaseModel``) so it
  loads the *flat* legacy env names â€” ``ANTHROPIC_API_KEY``, ``POSTGRES_*``,
  etc. â€” natively via per-field ``validation_alias``. A plain nested
  ``BaseModel`` would only populate through an ``env_nested_delimiter`` prefix
  (``LLM__ANTHROPIC_API_KEY``), which would break every existing ``.env``.
- Renamed vars keep their old name as an ``AliasChoices`` fallback so a
  transition window exists (e.g. ``LOGFIRE_TOKEN`` -> ``PYDANTIC_LOGFIRE_TOKEN``).
- ``Settings()`` construction performs no network or credential calls, so it is
  safe to call at package import (``files.cache.init_s3_cache`` does, via
  ``quber/__init__.py``).
- AWS credentials are intentionally absent: they stay on the boto3 default
  credential chain (env / ``~/.aws`` / IAM role). Only non-secret AWS knobs
  (S3 cache dir, TTL, region) live here.
é    )Úannotations)Ú	lru_cache)ÚPath)Ú	AnnotatedÚAnyÚLiteralÚOptional)ÚAliasChoicesÚBeforeValidatorÚField)ÚBaseSettingsÚSettingsConfigDictz.envÚignoreF)Úenv_fileÚextraÚcase_sensitive>   Ú1ÚonÚyesÚtruec                ó‚   • [        U [        5      (       a%  U R                  5       R                  5       [        ;   $ U c  gU $ )NF)Ú
isinstanceÚstrÚstripÚlowerÚTRUTHY_TOKENS)Úvalues    Ú5/home/mande/repo/quber/src/quber/settings/__init__.pyÚcoerce_legacy_boolr   /   s6   € Ü�%œ×ÑØ�{‰{‹}×"Ñ"Ó$¬Ñ5Ð5Ø�}ØØ€Ló    zclaude-haiku-4-5-20251001c                  óô  • \ rS rSr% Sr\r\" S\" SS5      S9r	S\
S'   \" SS	S9rS\
S
'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SS S9rS\
S!'   \" SS"S9rS\
S#'   \" SS$S9rS\
S%'   \" SS&S9rS\
S''   \" S(S)S9rS\
S*'   \" S(S+S9rS\
S,'   \" S(S-S9rS\
S.'   \" S(S/S9rS\
S0'   S1rg)2ÚLLMSettingséA   zFLLM model selection, Anthropic/OpenAI credentials, per-agent backends.NÚQUBER_LLM_MODELÚANTHROPIC_MODEL©ÚdefaultÚvalidation_aliasúOptional[str]ÚmodelÚANTHROPIC_API_KEYÚanthropic_api_keyÚANTHROPIC_AUTH_TOKENÚanthropic_auth_tokenÚOPENAI_API_KEYÚopenai_api_keyÚapiÚQUBER_LLM_BACKENDr   Úllm_backendÚQUBER_UNIFIER_BACKENDÚunifier_backendÚQUBER_CLASSIFIER_BACKENDÚclassifier_backendÚQUBER_DETECTOR_BACKENDÚdetector_backendÚQUBER_GRID_LOCATOR_BACKENDÚgrid_locator_backendÚQUBER_CELL_READER_BACKENDÚcell_reader_backendÚtextÚQUBER_COMPLETENESS_BACKENDÚcompleteness_backendÚQUBER_CAPTURE_ADVISOR_BACKENDÚcapture_advisor_backendÚQUBER_STATUS_INSPECTOR_BACKENDÚstatus_inspector_backendÚQUBER_FIGURE_CORRECTION_BACKENDÚfigure_correction_backendÚQUBER_FIGURE_VALUES_BACKENDÚfigure_values_backendzclaude-sonnet-5ÚQUBER_GRID_LOCATOR_MODELÚgrid_locator_modelÚQUBER_VET_MODELÚ	vet_modelÚQUBER_FIGURE_CORRECTION_MODELÚfigure_correction_modelÚQUBER_FIGURE_VALUES_MODELÚfigure_values_model© )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__ÚBASE_CONFIGÚmodel_configr   r
   r*   Ú__annotations__r,   r.   r0   r3   r5   r7   r9   r;   r=   r@   rB   rD   rF   rH   rJ   rL   rN   rP   Ú__static_attributes__rQ   r    r   r"   r"   A   s   ‡ ÙPà€Lá ØÙ%Ð&7Ð9JÓKñ€Eˆ=ó ñ (-°TÐL_Ñ'`Ð�}Ó`Ù*/¸ÐOeÑ*fÐ˜-Ófá$)°$ÐIYÑ$Z€N�MÓZñ  UÐ=PÑQ€K�ÓQÙ ¨ÐAXÑY€O�SÓYÙ#¨EÐD^Ñ_Ð˜Ó_Ù!¨%ÐBZÑ[Ð�cÓ[Ù %¨eÐFbÑ cÐ˜#ÓcÙ$¨UÐE`ÑaÐ˜ÓaÙ %¨fÐGcÑ dÐ˜#Ódñ $)°ÐIhÑ#iÐ˜SÓiñ
 %*°%ÐJjÑ$kÐ˜cÓkñ
 &+°5ÐKlÑ%mÐ˜sÓmñ
 "'¨uÐGdÑ!eÐ˜3Óeñ ).Ø!Ð4Nñ)Ð˜ó ñ  %Ð->ÐQbÑc€Iˆ}Ócñ .3Ø!Ð4Sñ.Ð˜]ó ñ */Ø!Ð4Oñ*Ð˜ö r    r"   c                  ó–   • \ rS rSr% Sr\r\" SSS9rS\	S'   \" SS	S9r
S\	S
'   \" SSS9rS\	S'   \" SSS9rS\	S'   \" SSS9rS\	S'   Srg)Ú
DBSettingsé’   z1Postgres connection parameters for the RAG store.ÚquberÚPOSTGRES_USERr&   r   ÚuserÚ	quber_devÚPOSTGRES_PASSWORDÚpasswordÚ	localhostÚPOSTGRES_HOSTÚhosti8  ÚPOSTGRES_PORTÚintÚportÚ	quber_ragÚPOSTGRES_DBÚdbrQ   N)rR   rS   rT   rU   rV   rW   rX   r   r`   rY   rc   rf   ri   rl   rZ   rQ   r    r   r\   r\   ’   s`   ‡ Ù;à€Lá˜g¸ÑH€Dˆ#ÓHÙ +Ð@SÑT€HˆcÓTÙ˜k¸OÑL€Dˆ#ÓLÙ˜d°_ÑE€Dˆ#ÓEÙ˜K¸-ÑH€BˆÖHr    r\   c                  ó€   • \ rS rSr% Sr\r\" \" S5      SS9r	S\
S'   \" SS	S9rS
\
S'   \" S\" SS5      S9rS\
S'   Srg)ÚS3CacheSettingséž   zINon-secret S3 ingestion-cache knobs. Credentials stay on the boto3 chain.z	.cache/s3ÚQUBER_S3_CACHE_DIRr&   r   Ú	cache_diri€— ÚQUBER_S3_CACHE_TTLÚfloatÚttl_secondsNÚQUBER_S3_REGIONÚ
AWS_REGIONr)   ÚregionrQ   )rR   rS   rT   rU   rV   rW   rX   r   r   rq   rY   rt   r
   rw   rZ   rQ   r    r   rn   rn   ž   sR   ‡ ÙSà€Lá¡D¨Ó$5ÐH\Ñ]€IˆtÓ]Ù yÐCWÑX€K�ÓXÙ!ØÙ%Ð&7¸ÓFñ€FˆMö r    rn   c                  óN   • \ rS rSr% Sr\r\" SSS9rS\	S'   \" SS	S9r
S\	S
'   Srg)ÚEmbeddingSettingsé«   zIEmbedding provider/device selection. OpenAI key lives in ``LLMSettings``.ÚlocalÚEMBEDDING_PROVIDERr&   r   ÚproviderÚcudaÚEMBEDDING_DEVICEÚdevicerQ   N)rR   rS   rT   rU   rV   rW   rX   r   r}   rY   r€   rZ   rQ   r    r   ry   ry   «   s.   ‡ ÙSà€Lá 'Ð<PÑQ€HˆcÓQÙ Ð9KÑL€FˆCÖLr    ry   c                  óD   • \ rS rSr% Sr\r\" S\" SS5      S9r	S\
S'   S	rg)
ÚLandingSettingsé´   zDLanding.AI ADE parse credentials for the standalone extraction path.NÚADE_API_KEYÚVISION_AGENT_API_KEYr&   r)   Úapi_keyrQ   )rR   rS   rT   rU   rV   rW   rX   r   r
   r†   rY   rZ   rQ   r    r   r‚   r‚   ´   s+   ‡ ÙNà€Lñ
 #ØÙ% mÐ5KÓLñ€Gˆ]ö r    r‚   c                  ó®   • \ rS rSr% Sr\r\" SSS9rS\	S'   \" SS	S9r
S
\	S'   \" SSS9rS\	S'   \" SSS9rS\	S'   \" SSS9rS\	S'   \" SSS9rS\	S'   Srg)ÚTypeSafeSettingséÂ   ztTypeSafe scoring API: credential, pinned model, the chunk grade cut, and
how hard the playground's ranker drives it.NÚTYPESAFE_API_KEYr&   r)   r†   z
jev-1.13.0ÚQUBER_TYPESAFE_MODELr   r*   gffffffö?ÚQUBER_TYPESAFE_GRADE_CUTrs   Ú	grade_cuté    ÚQUBER_TYPESAFE_CONCURRENCYrh   Úconcurrencyé   ÚQUBER_TYPESAFE_MAX_RETRIESÚmax_retriesg      N@ÚQUBER_TYPESAFE_TIMEOUT_SECONDSÚtimeout_secondsrQ   )rR   rS   rT   rU   rV   rW   rX   r   r†   rY   r*   r�   r�   r“   r•   rZ   rQ   r    r   rˆ   rˆ   Â   s‚   ‡ ñ3ð €Lñ #¨4ÐBTÑU€Gˆ]ÓUÙ˜|Ð>TÑU€Eˆ3ÓUñ
  SÐ;UÑV€IˆuÓVñ  RÐ:VÑW€K�ÓWñ  QÐ9UÑV€K�ÓVÙ"¨4ÐBbÑc€O�UÖcr    rˆ   c                  óJ  • \ rS rSr% Sr\r\" \" S5      SS9r	S\
S'   \" SS	S9rS
\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SSS9rS \
S!'   \" S"S#S9rS
\
S$'   S%rg)&ÚPlaygroundSettingséÜ   z€The answering playground: where its local corpus lives, how many
ingests may run at once, and which step ranks retrieved chunks.zdata/playgroundÚQUBER_PLAYGROUND_DATA_DIRr&   r   Údata_dirr‘   Ú#QUBER_PLAYGROUND_UPLOAD_CONCURRENCYrh   Úupload_concurrencyNÚQUBER_PLAYGROUND_ARTIFACTS_URIr)   Úartifacts_uriÚRUNPOD_ENDPOINT_IDÚrunpod_endpoint_idÚRUNPOD_API_KEYÚrunpod_api_keyÚ#QUBER_PLAYGROUND_ACTIVITY_NAMESPACEÚactivity_namespaceÚWORKOS_API_KEYÚworkos_api_keyÚWORKOS_CLIENT_IDÚworkos_client_idÚWORKOS_ORGANIZATION_IDÚworkos_organization_idÚPLAYGROUND_SESSION_SECRETÚsession_secretÚhaikuÚQUBER_PLAYGROUND_RANKERzLiteral['haiku', 'jev']Úrankeré   Ú%QUBER_PLAYGROUND_QUESTION_CONCURRENCYÚquestion_concurrencyrQ   )rR   rS   rT   rU   rV   rW   rX   r   r   rš   rY   rœ   rž   r    r¢   r¤   r¦   r¨   rª   r¬   r¯   r²   rZ   rQ   r    r   r—   r—   Ü   s	  ‡ ñGð €Lñ ¡4Ð(9Ó#:ÐMhÑi€HˆdÓiñ $¨AÐ@eÑfÐ˜Ófñ $)°ÐHhÑ#i€M�=Óiñ
 ).°dÐMaÑ(bÐ˜ÓbÙ$)°$ÐIYÑ$Z€N�MÓZñ
 ).ØÐ'Lñ)Ð˜ó ñ %*°$ÐIYÑ$Z€N�MÓZÙ&+°DÐK]Ñ&^Ð�mÓ^Ù,1¸$ÐQiÑ,jÐ˜MÓjÙ$)°$ÐIdÑ$e€N�MÓeñ
 ',°GÐNgÑ&h€FÐ#Óhñ !&¨aÐBiÑ jÐ˜#Öjr    r—   c                  ó¼   • \ rS rSr% Sr\r\" S\" SS5      S9r	S\
S'   \" S	S
S9rS\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   \" SSS9rS\
S'   Srg)ÚObservabilitySettingsi  z*Logfire + LangSmith tracing configuration.NÚPYDANTIC_LOGFIRE_TOKENÚLOGFIRE_TOKENr&   r)   Úlogfire_tokenTÚQUBER_ENABLE_LOGFIREÚ
LegacyBoolÚenable_logfireFÚTRACE_TO_LANGSMITHÚtrace_to_langsmithÚCC_LANGSMITH_API_KEYÚlangsmith_api_keyr'   ÚCC_LANGSMITH_PROJECTr   Úlangsmith_projectÚCC_LANGSMITH_DEBUGÚlangsmith_debugrQ   )rR   rS   rT   rU   rV   rW   rX   r   r
   r·   rY   rº   r¼   r¾   rÀ   rÂ   rZ   rQ   r    r   r´   r´     sˆ   ‡ Ù4à€Lá#(ØÙ%Ð&>ÀÓPñ$€M�=ó ñ "'¨tÐF\Ñ!]€N�JÓ]Ù%*°5ÐK_Ñ%`Ð˜
Ó`Ù',°TÐLbÑ'cÐ�}ÓcÙ"¨9ÐG]Ñ^Ð�sÓ^Ù"'°ÐH\Ñ"]€O�ZÖ]r    r´   c                  óþ   • \ rS rSr% Sr\r\" SSS9rS\	S'   \" SS	S9r
S
\	S'   \" \S9rS\	S'   \" \S9rS\	S'   \" \S9rS\	S'   \" \S9rS\	S'   \" \S9rS\	S'   \" \S9rS\	S'   \" \S9rS\	S'   \" \S9rS\	S'   Srg)ÚSettingsi$  z6Root settings object. Access via :func:`get_settings`.ÚINFOÚQUBER_LOG_LEVELr&   r   Ú	log_levelr°   ÚQUBER_MAX_CONCURRENT_TABLESrh   Úmax_concurrent_tables)Údefault_factoryr"   Úllmr\   rl   rn   Ús3_cachery   Ú
embeddingsr‚   Úlandingrˆ   Útypesafer—   Ú
playgroundr´   ÚobsrQ   N)rR   rS   rT   rU   rV   rW   rX   r   rÇ   rY   rÉ   r"   rË   r\   rl   rn   rÌ   ry   rÍ   r‚   rÎ   rˆ   rÏ   r—   rÐ   r´   rÑ   rZ   rQ   r    r   rÄ   rÄ   $  s¯   ‡ Ù@à€Lá 6Ð<MÑN€IˆsÓNÙ!&¨qÐC`Ñ!aÐ˜3Óaá¨[Ñ9€CˆÓ9Ù¨:Ñ6€Bˆ
Ó6Ù %°oÑ F€HˆoÓFÙ$)Ð:KÑ$L€JÐ!ÓLÙ$°_ÑE€Gˆ_ÓEÙ!&Ð7GÑ!H€HÐÓHÙ%*Ð;MÑ%N€JÐ"ÓNÙ!&Ð7LÑ!M€CÐ	ÖMr    rÄ   c                 ó   • [        5       $ )uÆ   Return the process-wide cached :class:`Settings` singleton.

Construction reads ``.env`` and the environment only â€” no network or
credential resolution â€” so this is safe to call at import time.
)rÄ   rQ   r    r   Úget_settingsrÓ   6  s   € ô ‹:Ðr    )ÚDEFAULT_LLM_MODELr\   ry   r"   r‚   r´   r—   rn   rÄ   rˆ   rÓ   N)r   r   Úreturnr   )rÕ   rÄ   )$rV   Ú
__future__r   Ú	functoolsr   Úpathlibr   Útypingr   r   r   r	   Úpydanticr
   r   r   Úpydantic_settingsr   r   rW   r   r   Úboolr¹   rÔ   r"   r\   rn   ry   r‚   rˆ   r—   r´   rÄ   rÓ   Ú__all__rQ   r    r   Ú<module>rÞ      s÷   ðñõ2 #å Ý ß 4Ó 4ç 9Ñ 9ß >ñ
 !¨&¸ÐQVÑW€ò +€ôð �t™_Ð-?Ó@Ð@ÑA€
ð 0Ð ôN�,ô Nôb	I�ô 	Iô
�lô 
ôM˜ô Mô�lô ôd�|ô dô45k˜ô 5kôp^˜Lô ^ô Nˆ|ô Nð$ óó ðò�r    