Spaces:
Sleeping
Sleeping
File size: 5,141 Bytes
b92b744 53c0860 b92b744 befe23e b92b744 0cb871f befe23e 0cb871f 285b041 0cb871f 285b041 b92b744 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | from pathlib import Path
from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(
env_file=Path(__file__).resolve().parents[1] / ".env", extra="ignore"
)
elastic_url: str = "http://localhost:9200"
elastic_api_key: str = ""
elastic_index: str = "studies"
elastic_local: bool = False
openai_api_key: str = ""
openalex_snapshot_manifest: str = (
"https://openalex.s3.amazonaws.com/data/parquet/works/manifest.json"
)
hf_token: str = ""
embedding_model: str = "sentence-transformers/all-MiniLM-L6-v2"
embedding_dimensions: int = 384
embedding_device: str = "cpu"
embeddings_enabled: bool = True
reference_min_similarity: float = Field(default=0.55, ge=0, le=1)
classifier_model_path: str = ""
small_model: str = "gpt-4.1-mini"
narration_model: str = "gpt-4.1"
extraction_limit: int = Field(default=100, ge=0, le=200)
llm_concurrency: int = Field(default=5, ge=1, le=20)
# USD per million tokens: configurable assumptions, never claimed as a bill.
small_input_price: float = 0.4
small_cached_price: float = 0.1
small_output_price: float = 1.6
narration_input_price: float = 2.0
narration_cached_price: float = 0.5
narration_output_price: float = 8.0
ttc_api_key: str = ""
ttc_model: str = "bear-2"
compression_enabled: bool = False
compression_validated: bool = False
ttc_input_price: float = 0.0
request_timeout: float = 45.0
extraction_cache_version: str = "v4-result-direction"
# Query-time full text from Europe PMC for papers with a PMCID; abstract otherwise.
fulltext_enabled: bool = True
europepmc_url: str = "https://www.ebi.ac.uk/europepmc/webservices/rest"
fulltext_timeout: float = 20.0
fulltext_max_lines: int = Field(default=160, ge=20, le=600)
# Gap map: the studies nearest the question, fetched by kNN and clustered per
# question. A few hundred nodes is what a reader can take in and what a force
# layout can settle in a second; the full-index scan below only runs when
# there is no question to center on.
gapmap_neighborhood: int = Field(default=800, ge=50, le=5000)
# Whole-index build (no question): every embedded study, scanned in pages.
# The region count is a resolution, and what counts as an empty band depends on
# it: measured on 6000 documents of the live index, 24 regions leave the corpus
# continuous (no band under the occupancy threshold) while 80 keep a median of
# 64 primary attempts per region and still expose bands.
gapmap_regions: int = Field(default=80, ge=2, le=200)
gapmap_seed: int = 0
# A cap on how much of the embedded corpus one build reads; 0 is no cap, and
# the coverage line and the warning always report what was actually read.
# Measured on the live index (2,078,515 embedded studies, 384 dimensions):
# the scan runs at ~11k documents/s and the vectors weigh ~3.0 GiB, so an
# uncapped build is ~3 minutes and needs a host with several GB to spare.
gapmap_scan_limit: int = Field(default=0, ge=0)
# Page size and concurrent point-in-time slices for that scan. Sixteen slices
# measured ~11k docs/s against ~3.2k for a single unsliced walk.
gapmap_batch: int = Field(default=2000, ge=100, le=10000)
gapmap_slices: int = Field(default=16, ge=1, le=64)
# How many of the clustered studies the canvas draws. Every study shapes the
# regions; a browser cannot paint two million marks, so the drawn subset is
# thinned by a hash of the document id.
gapmap_points: int = Field(default=6000, ge=100, le=50000)
# Edges the canvas draws between drawn studies: each study joins its most
# similar few, and only when the cosine reaches the floor. The cap is what
# keeps a dense literature from becoming one hub; the floor is what leaves an
# isolated paper isolated instead of tethered to its nearest stranger.
gapmap_edge_neighbors: int = Field(default=3, ge=1, le=12)
gapmap_edge_floor: float = Field(default=0.8, ge=-1.0, le=1.0)
# Rows the 2-D projection is fitted on. The basis is a drawing choice, and a
# full-corpus SVD would stall the build for minutes to move points by pixels.
# Nothing can be drawn before it exists, so it is fitted on the first pages
# rather than after a long silent read.
gapmap_projection_sample: int = Field(default=1000, ge=1000, le=500000)
# Bound on the full-corpus k-means. Measured at 200k documents and 80
# regions: 10 iterations ~3.2 s, 40 ~7.7 s; the assignment usually settles
# first and the loop stops when it does.
gapmap_iterations: int = Field(default=25, ge=1, le=200)
# Minimum seconds between two streamed frames while the corpus is scanning.
gapmap_tick_seconds: float = Field(default=0.15, ge=0.0, le=10.0)
max_concurrent_searches: int = 4
frontend_dist: str = str(Path(__file__).resolve().parents[2] / "dist")
cors_origins: list[str] = ["http://localhost:5173"]
settings = Settings()
|