papersearch 0.0.0-stage → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +208 -0
- package/LICENSE +21 -0
- package/README.md +213 -2
- package/README.zh.md +214 -0
- package/carsi/LICENSE +21 -0
- package/carsi/NOTICE +5 -0
- package/carsi/README.md +75 -0
- package/carsi/paper_search_carsi/__init__.py +6 -0
- package/carsi/paper_search_carsi/_core/__init__.py +26 -0
- package/carsi/paper_search_carsi/_core/racing.pyx +280 -0
- package/carsi/paper_search_carsi/adapters/__init__.py +26 -0
- package/carsi/paper_search_carsi/adapters/acm/__init__.py +13 -0
- package/carsi/paper_search_carsi/adapters/acs/__init__.py +47 -0
- package/carsi/paper_search_carsi/adapters/aha_journals/__init__.py +13 -0
- package/carsi/paper_search_carsi/adapters/ams/__init__.py +19 -0
- package/carsi/paper_search_carsi/adapters/annual_reviews/__init__.py +154 -0
- package/carsi/paper_search_carsi/adapters/aps/__init__.py +127 -0
- package/carsi/paper_search_carsi/adapters/asce/__init__.py +13 -0
- package/carsi/paper_search_carsi/adapters/base.py +320 -0
- package/carsi/paper_search_carsi/adapters/bmj/__init__.py +32 -0
- package/carsi/paper_search_carsi/adapters/copernicus/__init__.py +20 -0
- package/carsi/paper_search_carsi/adapters/dovepress/__init__.py +43 -0
- package/carsi/paper_search_carsi/adapters/elsevier/__init__.py +302 -0
- package/carsi/paper_search_carsi/adapters/elsevier/journal_site.py +237 -0
- package/carsi/paper_search_carsi/adapters/elsevier/sciencedirect.py +138 -0
- package/carsi/paper_search_carsi/adapters/ieee/__init__.py +184 -0
- package/carsi/paper_search_carsi/adapters/iop/__init__.py +41 -0
- package/carsi/paper_search_carsi/adapters/jama/__init__.py +54 -0
- package/carsi/paper_search_carsi/adapters/karger/__init__.py +75 -0
- package/carsi/paper_search_carsi/adapters/lww/__init__.py +103 -0
- package/carsi/paper_search_carsi/adapters/lww/journals_lww.py +36 -0
- package/carsi/paper_search_carsi/adapters/lww/ovid.py +72 -0
- package/carsi/paper_search_carsi/adapters/mdpi/__init__.py +20 -0
- package/carsi/paper_search_carsi/adapters/nejm/__init__.py +18 -0
- package/carsi/paper_search_carsi/adapters/neurology/__init__.py +13 -0
- package/carsi/paper_search_carsi/adapters/optica/__init__.py +33 -0
- package/carsi/paper_search_carsi/adapters/oup/__init__.py +366 -0
- package/carsi/paper_search_carsi/adapters/platforms/__init__.py +5 -0
- package/carsi/paper_search_carsi/adapters/platforms/atypon/__init__.py +149 -0
- package/carsi/paper_search_carsi/adapters/platforms/silverchair/__init__.py +83 -0
- package/carsi/paper_search_carsi/adapters/plos/__init__.py +20 -0
- package/carsi/paper_search_carsi/adapters/pnas/__init__.py +13 -0
- package/carsi/paper_search_carsi/adapters/rsc/__init__.py +74 -0
- package/carsi/paper_search_carsi/adapters/sage/__init__.py +154 -0
- package/carsi/paper_search_carsi/adapters/science/__init__.py +13 -0
- package/carsi/paper_search_carsi/adapters/springer/__init__.py +62 -0
- package/carsi/paper_search_carsi/adapters/taylor_francis/__init__.py +46 -0
- package/carsi/paper_search_carsi/adapters/thieme/__init__.py +164 -0
- package/carsi/paper_search_carsi/adapters/wiley/__init__.py +145 -0
- package/carsi/paper_search_carsi/adapters/world_scientific/__init__.py +27 -0
- package/carsi/paper_search_carsi/assets/icon-32.png +0 -0
- package/carsi/paper_search_carsi/assets/icon-512.png +0 -0
- package/carsi/paper_search_carsi/assets/icon-64.png +0 -0
- package/carsi/paper_search_carsi/assets/icon.svg +43 -0
- package/carsi/paper_search_carsi/blocked_journals.py +63 -0
- package/carsi/paper_search_carsi/browser/__init__.py +1 -0
- package/carsi/paper_search_carsi/browser/backend.py +823 -0
- package/carsi/paper_search_carsi/browser/cookies.py +386 -0
- package/carsi/paper_search_carsi/browser/ego_relay.py +152 -0
- package/carsi/paper_search_carsi/browser/engine.py +927 -0
- package/carsi/paper_search_carsi/browser/login.py +336 -0
- package/carsi/paper_search_carsi/browser/preview.py +379 -0
- package/carsi/paper_search_carsi/browser/watchdog.py +193 -0
- package/carsi/paper_search_carsi/cache.py +62 -0
- package/carsi/paper_search_carsi/carsi_schools.py +109 -0
- package/carsi/paper_search_carsi/cli.py +479 -0
- package/carsi/paper_search_carsi/cold_start.py +251 -0
- package/carsi/paper_search_carsi/config.py +301 -0
- package/carsi/paper_search_carsi/data/institutional_identity_policy.json +165 -0
- package/carsi/paper_search_carsi/data/publisher_access_catalog.json +969 -0
- package/carsi/paper_search_carsi/data/publisher_browser_verification_matrix.json +625 -0
- package/carsi/paper_search_carsi/download_diagnostics.py +228 -0
- package/carsi/paper_search_carsi/engine/__init__.py +1 -0
- package/carsi/paper_search_carsi/engine/access_rules.py +345 -0
- package/carsi/paper_search_carsi/engine/batch.py +702 -0
- package/carsi/paper_search_carsi/engine/batch_access.py +483 -0
- package/carsi/paper_search_carsi/engine/batch_capture.py +1531 -0
- package/carsi/paper_search_carsi/engine/batch_common.py +427 -0
- package/carsi/paper_search_carsi/engine/batch_diagnostics.py +307 -0
- package/carsi/paper_search_carsi/engine/batch_institution.py +981 -0
- package/carsi/paper_search_carsi/engine/batch_login.py +1605 -0
- package/carsi/paper_search_carsi/engine/batch_pdf_urls.py +274 -0
- package/carsi/paper_search_carsi/engine/batch_runs.py +711 -0
- package/carsi/paper_search_carsi/engine/batch_user.py +173 -0
- package/carsi/paper_search_carsi/engine/batch_waits.py +441 -0
- package/carsi/paper_search_carsi/engine/bridge.py +666 -0
- package/carsi/paper_search_carsi/engine/pdf_guard.py +310 -0
- package/carsi/paper_search_carsi/engine/router.py +514 -0
- package/carsi/paper_search_carsi/engine/supplements.py +148 -0
- package/carsi/paper_search_carsi/entitlements.py +233 -0
- package/carsi/paper_search_carsi/extractors/__init__.py +0 -0
- package/carsi/paper_search_carsi/extractors/pdf_extractor.py +149 -0
- package/carsi/paper_search_carsi/identifiers.py +121 -0
- package/carsi/paper_search_carsi/issues.py +227 -0
- package/carsi/paper_search_carsi/log.py +84 -0
- package/carsi/paper_search_carsi/mcp_progress.py +82 -0
- package/carsi/paper_search_carsi/network.py +359 -0
- package/carsi/paper_search_carsi/orchestrator.py +130 -0
- package/carsi/paper_search_carsi/pdf_utils.py +279 -0
- package/carsi/paper_search_carsi/progress_bar.py +778 -0
- package/carsi/paper_search_carsi/progress_reporter.py +530 -0
- package/carsi/paper_search_carsi/progress_status.py +212 -0
- package/carsi/paper_search_carsi/publishers/__init__.py +10 -0
- package/carsi/paper_search_carsi/publishers/builtin/acm.json +65 -0
- package/carsi/paper_search_carsi/publishers/builtin/acs.json +73 -0
- package/carsi/paper_search_carsi/publishers/builtin/aha-journals.json +47 -0
- package/carsi/paper_search_carsi/publishers/builtin/aip.json +66 -0
- package/carsi/paper_search_carsi/publishers/builtin/ams.json +66 -0
- package/carsi/paper_search_carsi/publishers/builtin/annual-reviews.json +64 -0
- package/carsi/paper_search_carsi/publishers/builtin/aps.json +70 -0
- package/carsi/paper_search_carsi/publishers/builtin/asce.json +46 -0
- package/carsi/paper_search_carsi/publishers/builtin/bmj.json +46 -0
- package/carsi/paper_search_carsi/publishers/builtin/copernicus.json +45 -0
- package/carsi/paper_search_carsi/publishers/builtin/dovepress.json +35 -0
- package/carsi/paper_search_carsi/publishers/builtin/elsevier.json +77 -0
- package/carsi/paper_search_carsi/publishers/builtin/frontiers.json +62 -0
- package/carsi/paper_search_carsi/publishers/builtin/ieee.json +68 -0
- package/carsi/paper_search_carsi/publishers/builtin/iop.json +69 -0
- package/carsi/paper_search_carsi/publishers/builtin/jama.json +48 -0
- package/carsi/paper_search_carsi/publishers/builtin/karger.json +48 -0
- package/carsi/paper_search_carsi/publishers/builtin/lww.json +57 -0
- package/carsi/paper_search_carsi/publishers/builtin/mdpi.json +46 -0
- package/carsi/paper_search_carsi/publishers/builtin/nejm.json +46 -0
- package/carsi/paper_search_carsi/publishers/builtin/neurology.json +45 -0
- package/carsi/paper_search_carsi/publishers/builtin/optica.json +77 -0
- package/carsi/paper_search_carsi/publishers/builtin/oxfordacademic.json +64 -0
- package/carsi/paper_search_carsi/publishers/builtin/plos.json +46 -0
- package/carsi/paper_search_carsi/publishers/builtin/pnas.json +67 -0
- package/carsi/paper_search_carsi/publishers/builtin/royalsocietypublishing.json +62 -0
- package/carsi/paper_search_carsi/publishers/builtin/rsc.json +71 -0
- package/carsi/paper_search_carsi/publishers/builtin/sage.json +48 -0
- package/carsi/paper_search_carsi/publishers/builtin/science.json +68 -0
- package/carsi/paper_search_carsi/publishers/builtin/springer.json +92 -0
- package/carsi/paper_search_carsi/publishers/builtin/taylor-francis.json +52 -0
- package/carsi/paper_search_carsi/publishers/builtin/thieme.json +50 -0
- package/carsi/paper_search_carsi/publishers/builtin/wiley.json +77 -0
- package/carsi/paper_search_carsi/publishers/builtin/world-scientific.json +68 -0
- package/carsi/paper_search_carsi/publishers/extensions.py +241 -0
- package/carsi/paper_search_carsi/publishers/loader.py +93 -0
- package/carsi/paper_search_carsi/publishers/model.py +90 -0
- package/carsi/paper_search_carsi/publishers/profiles.py +127 -0
- package/carsi/paper_search_carsi/publishers/schema.json +129 -0
- package/carsi/paper_search_carsi/publishers/site.py +86 -0
- package/carsi/paper_search_carsi/rate_limit.py +51 -0
- package/carsi/paper_search_carsi/server.py +197 -0
- package/carsi/paper_search_carsi/session_broker.py +163 -0
- package/carsi/paper_search_carsi/tor.py +9 -0
- package/carsi/paper_search_carsi/user_settings.py +55 -0
- package/carsi/pyproject.toml +41 -0
- package/dist/capabilities/body-snippet-search/handler.d.ts +9 -0
- package/dist/capabilities/body-snippet-search/handler.d.ts.map +1 -0
- package/dist/capabilities/body-snippet-search/handler.js +17 -0
- package/dist/capabilities/body-snippet-search/handler.js.map +1 -0
- package/dist/capabilities/body-snippet-search/index.d.ts +7 -0
- package/dist/capabilities/body-snippet-search/index.d.ts.map +1 -0
- package/dist/capabilities/body-snippet-search/index.js +6 -0
- package/dist/capabilities/body-snippet-search/index.js.map +1 -0
- package/dist/capabilities/body-snippet-search/schemas.d.ts +36 -0
- package/dist/capabilities/body-snippet-search/schemas.d.ts.map +1 -0
- package/dist/capabilities/body-snippet-search/schemas.js +16 -0
- package/dist/capabilities/body-snippet-search/schemas.js.map +1 -0
- package/dist/capabilities/body-snippet-search/service.d.ts +4 -0
- package/dist/capabilities/body-snippet-search/service.d.ts.map +1 -0
- package/dist/capabilities/body-snippet-search/service.js +4 -0
- package/dist/capabilities/body-snippet-search/service.js.map +1 -0
- package/dist/capabilities/body-snippet-search/tools.d.ts +187 -0
- package/dist/capabilities/body-snippet-search/tools.d.ts.map +1 -0
- package/dist/capabilities/body-snippet-search/tools.js +49 -0
- package/dist/capabilities/body-snippet-search/tools.js.map +1 -0
- package/dist/capabilities/body-snippet-search/types.d.ts +14 -0
- package/dist/capabilities/body-snippet-search/types.d.ts.map +1 -0
- package/dist/capabilities/body-snippet-search/types.js +2 -0
- package/dist/capabilities/body-snippet-search/types.js.map +1 -0
- package/dist/capabilities/citation-expansion/CitationService.d.ts +47 -0
- package/dist/capabilities/citation-expansion/CitationService.d.ts.map +1 -0
- package/dist/capabilities/citation-expansion/CitationService.js +243 -0
- package/dist/capabilities/citation-expansion/CitationService.js.map +1 -0
- package/dist/capabilities/citation-expansion/handler.d.ts +36 -0
- package/dist/capabilities/citation-expansion/handler.d.ts.map +1 -0
- package/dist/capabilities/citation-expansion/handler.js +44 -0
- package/dist/capabilities/citation-expansion/handler.js.map +1 -0
- package/dist/capabilities/citation-expansion/index.d.ts +6 -0
- package/dist/capabilities/citation-expansion/index.d.ts.map +1 -0
- package/dist/capabilities/citation-expansion/index.js +5 -0
- package/dist/capabilities/citation-expansion/index.js.map +1 -0
- package/dist/capabilities/citation-expansion/schemas.d.ts +28 -0
- package/dist/capabilities/citation-expansion/schemas.d.ts.map +1 -0
- package/dist/capabilities/citation-expansion/schemas.js +13 -0
- package/dist/capabilities/citation-expansion/schemas.js.map +1 -0
- package/dist/capabilities/citation-expansion/tools.d.ts +82 -0
- package/dist/capabilities/citation-expansion/tools.d.ts.map +1 -0
- package/dist/capabilities/citation-expansion/tools.js +48 -0
- package/dist/capabilities/citation-expansion/tools.js.map +1 -0
- package/dist/capabilities/citation-expansion/types.d.ts +22 -0
- package/dist/capabilities/citation-expansion/types.d.ts.map +1 -0
- package/dist/capabilities/citation-expansion/types.js +2 -0
- package/dist/capabilities/citation-expansion/types.js.map +1 -0
- package/dist/capabilities/journal-metrics/JournalMetricsService.d.ts +3 -0
- package/dist/capabilities/journal-metrics/JournalMetricsService.d.ts.map +1 -0
- package/dist/capabilities/journal-metrics/JournalMetricsService.js +142 -0
- package/dist/capabilities/journal-metrics/JournalMetricsService.js.map +1 -0
- package/dist/capabilities/journal-metrics/handler.d.ts +12 -0
- package/dist/capabilities/journal-metrics/handler.d.ts.map +1 -0
- package/dist/capabilities/journal-metrics/handler.js +38 -0
- package/dist/capabilities/journal-metrics/handler.js.map +1 -0
- package/dist/capabilities/journal-metrics/index.d.ts +6 -0
- package/dist/capabilities/journal-metrics/index.d.ts.map +1 -0
- package/dist/capabilities/journal-metrics/index.js +5 -0
- package/dist/capabilities/journal-metrics/index.js.map +1 -0
- package/dist/capabilities/journal-metrics/schemas.d.ts +28 -0
- package/dist/capabilities/journal-metrics/schemas.d.ts.map +1 -0
- package/dist/capabilities/journal-metrics/schemas.js +13 -0
- package/dist/capabilities/journal-metrics/schemas.js.map +1 -0
- package/dist/capabilities/journal-metrics/tools.d.ts +67 -0
- package/dist/capabilities/journal-metrics/tools.d.ts.map +1 -0
- package/dist/capabilities/journal-metrics/tools.js +27 -0
- package/dist/capabilities/journal-metrics/tools.js.map +1 -0
- package/dist/capabilities/journal-metrics/types.d.ts +36 -0
- package/dist/capabilities/journal-metrics/types.d.ts.map +1 -0
- package/dist/capabilities/journal-metrics/types.js +2 -0
- package/dist/capabilities/journal-metrics/types.js.map +1 -0
- package/dist/capabilities/metadata-search/MultiSourceSearchService.d.ts +9 -0
- package/dist/capabilities/metadata-search/MultiSourceSearchService.d.ts.map +1 -0
- package/dist/capabilities/metadata-search/MultiSourceSearchService.js +81 -0
- package/dist/capabilities/metadata-search/MultiSourceSearchService.js.map +1 -0
- package/dist/capabilities/metadata-search/handler.d.ts +23 -0
- package/dist/capabilities/metadata-search/handler.d.ts.map +1 -0
- package/dist/capabilities/metadata-search/handler.js +153 -0
- package/dist/capabilities/metadata-search/handler.js.map +1 -0
- package/dist/capabilities/metadata-search/index.d.ts +6 -0
- package/dist/capabilities/metadata-search/index.d.ts.map +1 -0
- package/dist/capabilities/metadata-search/index.js +5 -0
- package/dist/capabilities/metadata-search/index.js.map +1 -0
- package/dist/capabilities/metadata-search/schemas.d.ts +83 -0
- package/dist/capabilities/metadata-search/schemas.d.ts.map +1 -0
- package/dist/capabilities/metadata-search/schemas.js +80 -0
- package/dist/capabilities/metadata-search/schemas.js.map +1 -0
- package/dist/capabilities/metadata-search/tools.d.ts +178 -0
- package/dist/capabilities/metadata-search/tools.d.ts.map +1 -0
- package/dist/capabilities/metadata-search/tools.js +75 -0
- package/dist/capabilities/metadata-search/tools.js.map +1 -0
- package/dist/capabilities/metadata-search/types.d.ts +13 -0
- package/dist/capabilities/metadata-search/types.d.ts.map +1 -0
- package/dist/capabilities/metadata-search/types.js +2 -0
- package/dist/capabilities/metadata-search/types.js.map +1 -0
- package/dist/capabilities/pdf-discovery/DownloadTier.d.ts +43 -0
- package/dist/capabilities/pdf-discovery/DownloadTier.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/DownloadTier.js +2 -0
- package/dist/capabilities/pdf-discovery/DownloadTier.js.map +1 -0
- package/dist/capabilities/pdf-discovery/OpenAccessFallbackService.d.ts +16 -0
- package/dist/capabilities/pdf-discovery/OpenAccessFallbackService.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/OpenAccessFallbackService.js +202 -0
- package/dist/capabilities/pdf-discovery/OpenAccessFallbackService.js.map +1 -0
- package/dist/capabilities/pdf-discovery/batch.d.ts +74 -0
- package/dist/capabilities/pdf-discovery/batch.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/batch.js +370 -0
- package/dist/capabilities/pdf-discovery/batch.js.map +1 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiAttempt.d.ts +7 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiAttempt.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiAttempt.js +46 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiAttempt.js.map +1 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiMcpClient.d.ts +35 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiMcpClient.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiMcpClient.js +689 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiMcpClient.js.map +1 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiProgress.d.ts +23 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiProgress.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiProgress.js +30 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiProgress.js.map +1 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiReadiness.d.ts +29 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiReadiness.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiReadiness.js +176 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiReadiness.js.map +1 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiResultNormalizer.d.ts +8 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiResultNormalizer.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiResultNormalizer.js +225 -0
- package/dist/capabilities/pdf-discovery/carsi/CarsiResultNormalizer.js.map +1 -0
- package/dist/capabilities/pdf-discovery/carsi/index.d.ts +8 -0
- package/dist/capabilities/pdf-discovery/carsi/index.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/carsi/index.js +11 -0
- package/dist/capabilities/pdf-discovery/carsi/index.js.map +1 -0
- package/dist/capabilities/pdf-discovery/carsi/types.d.ts +118 -0
- package/dist/capabilities/pdf-discovery/carsi/types.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/carsi/types.js +2 -0
- package/dist/capabilities/pdf-discovery/carsi/types.js.map +1 -0
- package/dist/capabilities/pdf-discovery/handler.d.ts +28 -0
- package/dist/capabilities/pdf-discovery/handler.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/handler.js +72 -0
- package/dist/capabilities/pdf-discovery/handler.js.map +1 -0
- package/dist/capabilities/pdf-discovery/identity.d.ts +8 -0
- package/dist/capabilities/pdf-discovery/identity.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/identity.js +24 -0
- package/dist/capabilities/pdf-discovery/identity.js.map +1 -0
- package/dist/capabilities/pdf-discovery/index.d.ts +8 -0
- package/dist/capabilities/pdf-discovery/index.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/index.js +6 -0
- package/dist/capabilities/pdf-discovery/index.js.map +1 -0
- package/dist/capabilities/pdf-discovery/oaHosts.d.ts +3 -0
- package/dist/capabilities/pdf-discovery/oaHosts.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/oaHosts.js +37 -0
- package/dist/capabilities/pdf-discovery/oaHosts.js.map +1 -0
- package/dist/capabilities/pdf-discovery/pmcCloud.d.ts +6 -0
- package/dist/capabilities/pdf-discovery/pmcCloud.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/pmcCloud.js +95 -0
- package/dist/capabilities/pdf-discovery/pmcCloud.js.map +1 -0
- package/dist/capabilities/pdf-discovery/publisherApi/elsevier.d.ts +4 -0
- package/dist/capabilities/pdf-discovery/publisherApi/elsevier.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/publisherApi/elsevier.js +122 -0
- package/dist/capabilities/pdf-discovery/publisherApi/elsevier.js.map +1 -0
- package/dist/capabilities/pdf-discovery/publisherApi/index.d.ts +31 -0
- package/dist/capabilities/pdf-discovery/publisherApi/index.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/publisherApi/index.js +20 -0
- package/dist/capabilities/pdf-discovery/publisherApi/index.js.map +1 -0
- package/dist/capabilities/pdf-discovery/publisherApi/springer.d.ts +4 -0
- package/dist/capabilities/pdf-discovery/publisherApi/springer.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/publisherApi/springer.js +114 -0
- package/dist/capabilities/pdf-discovery/publisherApi/springer.js.map +1 -0
- package/dist/capabilities/pdf-discovery/schemas.d.ts +176 -0
- package/dist/capabilities/pdf-discovery/schemas.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/schemas.js +72 -0
- package/dist/capabilities/pdf-discovery/schemas.js.map +1 -0
- package/dist/capabilities/pdf-discovery/tiers/directPdfUrl.d.ts +5 -0
- package/dist/capabilities/pdf-discovery/tiers/directPdfUrl.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/tiers/directPdfUrl.js +40 -0
- package/dist/capabilities/pdf-discovery/tiers/directPdfUrl.js.map +1 -0
- package/dist/capabilities/pdf-discovery/tiers/entitledAccess.d.ts +13 -0
- package/dist/capabilities/pdf-discovery/tiers/entitledAccess.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/tiers/entitledAccess.js +123 -0
- package/dist/capabilities/pdf-discovery/tiers/entitledAccess.js.map +1 -0
- package/dist/capabilities/pdf-discovery/tiers/primary.d.ts +3 -0
- package/dist/capabilities/pdf-discovery/tiers/primary.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/tiers/primary.js +21 -0
- package/dist/capabilities/pdf-discovery/tiers/primary.js.map +1 -0
- package/dist/capabilities/pdf-discovery/tiers/publisherApi.d.ts +12 -0
- package/dist/capabilities/pdf-discovery/tiers/publisherApi.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/tiers/publisherApi.js +109 -0
- package/dist/capabilities/pdf-discovery/tiers/publisherApi.js.map +1 -0
- package/dist/capabilities/pdf-discovery/tiers/repositories.d.ts +10 -0
- package/dist/capabilities/pdf-discovery/tiers/repositories.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/tiers/repositories.js +37 -0
- package/dist/capabilities/pdf-discovery/tiers/repositories.js.map +1 -0
- package/dist/capabilities/pdf-discovery/tiers/scihub.d.ts +3 -0
- package/dist/capabilities/pdf-discovery/tiers/scihub.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/tiers/scihub.js +21 -0
- package/dist/capabilities/pdf-discovery/tiers/scihub.js.map +1 -0
- package/dist/capabilities/pdf-discovery/tiers/unpaywall.d.ts +3 -0
- package/dist/capabilities/pdf-discovery/tiers/unpaywall.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/tiers/unpaywall.js +76 -0
- package/dist/capabilities/pdf-discovery/tiers/unpaywall.js.map +1 -0
- package/dist/capabilities/pdf-discovery/tools.d.ts +337 -0
- package/dist/capabilities/pdf-discovery/tools.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/tools.js +144 -0
- package/dist/capabilities/pdf-discovery/tools.js.map +1 -0
- package/dist/capabilities/pdf-discovery/types.d.ts +86 -0
- package/dist/capabilities/pdf-discovery/types.d.ts.map +1 -0
- package/dist/capabilities/pdf-discovery/types.js +2 -0
- package/dist/capabilities/pdf-discovery/types.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1196 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/ConfigService.d.ts +28 -0
- package/dist/config/ConfigService.d.ts.map +1 -0
- package/dist/config/ConfigService.js +204 -0
- package/dist/config/ConfigService.js.map +1 -0
- package/dist/config/ResultCaps.d.ts +4 -0
- package/dist/config/ResultCaps.d.ts.map +1 -0
- package/dist/config/ResultCaps.js +10 -0
- package/dist/config/ResultCaps.js.map +1 -0
- package/dist/config/constants.d.ts +158 -0
- package/dist/config/constants.d.ts.map +1 -0
- package/dist/config/constants.js +102 -0
- package/dist/config/constants.js.map +1 -0
- package/dist/core/capabilityProfile.d.ts +2 -0
- package/dist/core/capabilityProfile.d.ts.map +1 -0
- package/dist/core/capabilityProfile.js +2 -0
- package/dist/core/capabilityProfile.js.map +1 -0
- package/dist/core/diagnostics.d.ts +2 -0
- package/dist/core/diagnostics.d.ts.map +1 -0
- package/dist/core/diagnostics.js +2 -0
- package/dist/core/diagnostics.js.map +1 -0
- package/dist/core/handleToolCall.d.ts +13 -0
- package/dist/core/handleToolCall.d.ts.map +1 -0
- package/dist/core/handleToolCall.js +304 -0
- package/dist/core/handleToolCall.js.map +1 -0
- package/dist/core/httpPolicies.d.ts +2 -0
- package/dist/core/httpPolicies.d.ts.map +1 -0
- package/dist/core/httpPolicies.js +2 -0
- package/dist/core/httpPolicies.js.map +1 -0
- package/dist/core/liveSmoke.d.ts +2 -0
- package/dist/core/liveSmoke.d.ts.map +1 -0
- package/dist/core/liveSmoke.js +2 -0
- package/dist/core/liveSmoke.js.map +1 -0
- package/dist/core/platformFactories.d.ts +2 -0
- package/dist/core/platformFactories.d.ts.map +1 -0
- package/dist/core/platformFactories.js +2 -0
- package/dist/core/platformFactories.js.map +1 -0
- package/dist/core/platformMetadata.d.ts +2 -0
- package/dist/core/platformMetadata.d.ts.map +1 -0
- package/dist/core/platformMetadata.js +2 -0
- package/dist/core/platformMetadata.js.map +1 -0
- package/dist/core/schemas.d.ts +365 -0
- package/dist/core/schemas.d.ts.map +1 -0
- package/dist/core/schemas.js +256 -0
- package/dist/core/schemas.js.map +1 -0
- package/dist/core/searchers.d.ts +41 -0
- package/dist/core/searchers.d.ts.map +1 -0
- package/dist/core/searchers.js +24 -0
- package/dist/core/searchers.js.map +1 -0
- package/dist/core/textReports.d.ts +2 -0
- package/dist/core/textReports.d.ts.map +1 -0
- package/dist/core/textReports.js +2 -0
- package/dist/core/textReports.js.map +1 -0
- package/dist/core/tools.d.ts +7 -0
- package/dist/core/tools.d.ts.map +1 -0
- package/dist/core/tools.js +489 -0
- package/dist/core/tools.js.map +1 -0
- package/dist/infrastructure/cache/RequestCache.d.ts +26 -0
- package/dist/infrastructure/cache/RequestCache.d.ts.map +1 -0
- package/dist/infrastructure/cache/RequestCache.js +66 -0
- package/dist/infrastructure/cache/RequestCache.js.map +1 -0
- package/dist/infrastructure/http/ErrorHandler.d.ts +101 -0
- package/dist/infrastructure/http/ErrorHandler.d.ts.map +1 -0
- package/dist/infrastructure/http/ErrorHandler.js +278 -0
- package/dist/infrastructure/http/ErrorHandler.js.map +1 -0
- package/dist/infrastructure/http/HttpClient.d.ts +31 -0
- package/dist/infrastructure/http/HttpClient.d.ts.map +1 -0
- package/dist/infrastructure/http/HttpClient.js +52 -0
- package/dist/infrastructure/http/HttpClient.js.map +1 -0
- package/dist/infrastructure/pdf/PDFExtractor.d.ts +34 -0
- package/dist/infrastructure/pdf/PDFExtractor.d.ts.map +1 -0
- package/dist/infrastructure/pdf/PDFExtractor.js +130 -0
- package/dist/infrastructure/pdf/PDFExtractor.js.map +1 -0
- package/dist/infrastructure/pdf/PdfDownload.d.ts +16 -0
- package/dist/infrastructure/pdf/PdfDownload.d.ts.map +1 -0
- package/dist/infrastructure/pdf/PdfDownload.js +242 -0
- package/dist/infrastructure/pdf/PdfDownload.js.map +1 -0
- package/dist/infrastructure/pdf/PdfFirstPage.cjs +70 -0
- package/dist/infrastructure/pdf/PdfFirstPage.cjs.map +1 -0
- package/dist/infrastructure/pdf/PdfFirstPage.d.cts +16 -0
- package/dist/infrastructure/pdf/PdfFirstPage.d.cts.map +1 -0
- package/dist/infrastructure/pdf/PdfIdentity.d.ts +29 -0
- package/dist/infrastructure/pdf/PdfIdentity.d.ts.map +1 -0
- package/dist/infrastructure/pdf/PdfIdentity.js +283 -0
- package/dist/infrastructure/pdf/PdfIdentity.js.map +1 -0
- package/dist/infrastructure/rate-limit/RateLimiter.d.ts +50 -0
- package/dist/infrastructure/rate-limit/RateLimiter.d.ts.map +1 -0
- package/dist/infrastructure/rate-limit/RateLimiter.js +128 -0
- package/dist/infrastructure/rate-limit/RateLimiter.js.map +1 -0
- package/dist/infrastructure/runlog/RunLedger.d.ts +61 -0
- package/dist/infrastructure/runlog/RunLedger.d.ts.map +1 -0
- package/dist/infrastructure/runlog/RunLedger.js +284 -0
- package/dist/infrastructure/runlog/RunLedger.js.map +1 -0
- package/dist/infrastructure/runlog/failureClass.d.ts +26 -0
- package/dist/infrastructure/runlog/failureClass.d.ts.map +1 -0
- package/dist/infrastructure/runlog/failureClass.js +125 -0
- package/dist/infrastructure/runlog/failureClass.js.map +1 -0
- package/dist/infrastructure/security/SecurityUtils.d.ts +80 -0
- package/dist/infrastructure/security/SecurityUtils.d.ts.map +1 -0
- package/dist/infrastructure/security/SecurityUtils.js +357 -0
- package/dist/infrastructure/security/SecurityUtils.js.map +1 -0
- package/dist/management/capability-profile/carsiReadiness.d.ts +10 -0
- package/dist/management/capability-profile/carsiReadiness.d.ts.map +1 -0
- package/dist/management/capability-profile/carsiReadiness.js +13 -0
- package/dist/management/capability-profile/carsiReadiness.js.map +1 -0
- package/dist/management/capability-profile/index.d.ts +26 -0
- package/dist/management/capability-profile/index.d.ts.map +1 -0
- package/dist/management/capability-profile/index.js +183 -0
- package/dist/management/capability-profile/index.js.map +1 -0
- package/dist/management/carsi/host.d.ts +4 -0
- package/dist/management/carsi/host.d.ts.map +1 -0
- package/dist/management/carsi/host.js +65 -0
- package/dist/management/carsi/host.js.map +1 -0
- package/dist/management/carsi/installer.d.ts +146 -0
- package/dist/management/carsi/installer.d.ts.map +1 -0
- package/dist/management/carsi/installer.js +527 -0
- package/dist/management/carsi/installer.js.map +1 -0
- package/dist/management/carsi/runtime.d.ts +31 -0
- package/dist/management/carsi/runtime.d.ts.map +1 -0
- package/dist/management/carsi/runtime.js +67 -0
- package/dist/management/carsi/runtime.js.map +1 -0
- package/dist/management/config/index.d.ts +2 -0
- package/dist/management/config/index.d.ts.map +1 -0
- package/dist/management/config/index.js +2 -0
- package/dist/management/config/index.js.map +1 -0
- package/dist/management/diagnostics/index.d.ts +43 -0
- package/dist/management/diagnostics/index.d.ts.map +1 -0
- package/dist/management/diagnostics/index.js +610 -0
- package/dist/management/diagnostics/index.js.map +1 -0
- package/dist/management/failures/index.d.ts +47 -0
- package/dist/management/failures/index.d.ts.map +1 -0
- package/dist/management/failures/index.js +134 -0
- package/dist/management/failures/index.js.map +1 -0
- package/dist/management/reports/index.d.ts +32 -0
- package/dist/management/reports/index.d.ts.map +1 -0
- package/dist/management/reports/index.js +123 -0
- package/dist/management/reports/index.js.map +1 -0
- package/dist/management/skills/autoSync.d.ts +41 -0
- package/dist/management/skills/autoSync.d.ts.map +1 -0
- package/dist/management/skills/autoSync.js +142 -0
- package/dist/management/skills/autoSync.js.map +1 -0
- package/dist/management/skills/index.d.ts +3 -0
- package/dist/management/skills/index.d.ts.map +1 -0
- package/dist/management/skills/index.js +3 -0
- package/dist/management/skills/index.js.map +1 -0
- package/dist/management/smoke/index.d.ts +44 -0
- package/dist/management/smoke/index.d.ts.map +1 -0
- package/dist/management/smoke/index.js +254 -0
- package/dist/management/smoke/index.js.map +1 -0
- package/dist/models/Paper.d.ts +64 -0
- package/dist/models/Paper.d.ts.map +1 -0
- package/dist/models/Paper.js +70 -0
- package/dist/models/Paper.js.map +1 -0
- package/dist/platforms/ACMSearcher.d.ts +16 -0
- package/dist/platforms/ACMSearcher.d.ts.map +1 -0
- package/dist/platforms/ACMSearcher.js +125 -0
- package/dist/platforms/ACMSearcher.js.map +1 -0
- package/dist/platforms/BioRxivSearcher.d.ts +47 -0
- package/dist/platforms/BioRxivSearcher.d.ts.map +1 -0
- package/dist/platforms/BioRxivSearcher.js +215 -0
- package/dist/platforms/BioRxivSearcher.js.map +1 -0
- package/dist/platforms/CORESearcher.d.ts +17 -0
- package/dist/platforms/CORESearcher.d.ts.map +1 -0
- package/dist/platforms/CORESearcher.js +185 -0
- package/dist/platforms/CORESearcher.js.map +1 -0
- package/dist/platforms/CrossrefSearcher.d.ts +34 -0
- package/dist/platforms/CrossrefSearcher.d.ts.map +1 -0
- package/dist/platforms/CrossrefSearcher.js +339 -0
- package/dist/platforms/CrossrefSearcher.js.map +1 -0
- package/dist/platforms/DBLPSearcher.d.ts +16 -0
- package/dist/platforms/DBLPSearcher.d.ts.map +1 -0
- package/dist/platforms/DBLPSearcher.js +116 -0
- package/dist/platforms/DBLPSearcher.js.map +1 -0
- package/dist/platforms/EuropePMCSearcher.d.ts +20 -0
- package/dist/platforms/EuropePMCSearcher.d.ts.map +1 -0
- package/dist/platforms/EuropePMCSearcher.js +173 -0
- package/dist/platforms/EuropePMCSearcher.js.map +1 -0
- package/dist/platforms/GoogleScholarSearcher.d.ts +142 -0
- package/dist/platforms/GoogleScholarSearcher.d.ts.map +1 -0
- package/dist/platforms/GoogleScholarSearcher.js +648 -0
- package/dist/platforms/GoogleScholarSearcher.js.map +1 -0
- package/dist/platforms/IACRSearcher.d.ts +51 -0
- package/dist/platforms/IACRSearcher.d.ts.map +1 -0
- package/dist/platforms/IACRSearcher.js +339 -0
- package/dist/platforms/IACRSearcher.js.map +1 -0
- package/dist/platforms/IEEESearcher.d.ts +15 -0
- package/dist/platforms/IEEESearcher.d.ts.map +1 -0
- package/dist/platforms/IEEESearcher.js +123 -0
- package/dist/platforms/IEEESearcher.js.map +1 -0
- package/dist/platforms/OpenAIRESearcher.d.ts +22 -0
- package/dist/platforms/OpenAIRESearcher.d.ts.map +1 -0
- package/dist/platforms/OpenAIRESearcher.js +235 -0
- package/dist/platforms/OpenAIRESearcher.js.map +1 -0
- package/dist/platforms/OpenAlexSearcher.d.ts +14 -0
- package/dist/platforms/OpenAlexSearcher.d.ts.map +1 -0
- package/dist/platforms/OpenAlexSearcher.js +114 -0
- package/dist/platforms/OpenAlexSearcher.js.map +1 -0
- package/dist/platforms/OpenReviewSearcher.d.ts +19 -0
- package/dist/platforms/OpenReviewSearcher.d.ts.map +1 -0
- package/dist/platforms/OpenReviewSearcher.js +141 -0
- package/dist/platforms/OpenReviewSearcher.js.map +1 -0
- package/dist/platforms/PMCSearcher.d.ts +20 -0
- package/dist/platforms/PMCSearcher.d.ts.map +1 -0
- package/dist/platforms/PMCSearcher.js +177 -0
- package/dist/platforms/PMCSearcher.js.map +1 -0
- package/dist/platforms/PaperSource.d.ts +149 -0
- package/dist/platforms/PaperSource.d.ts.map +1 -0
- package/dist/platforms/PaperSource.js +125 -0
- package/dist/platforms/PaperSource.js.map +1 -0
- package/dist/platforms/PubMedSearcher.d.ts +104 -0
- package/dist/platforms/PubMedSearcher.d.ts.map +1 -0
- package/dist/platforms/PubMedSearcher.js +430 -0
- package/dist/platforms/PubMedSearcher.js.map +1 -0
- package/dist/platforms/SciHubSearcher.d.ts +66 -0
- package/dist/platforms/SciHubSearcher.d.ts.map +1 -0
- package/dist/platforms/SciHubSearcher.js +398 -0
- package/dist/platforms/SciHubSearcher.js.map +1 -0
- package/dist/platforms/ScienceDirectSearcher.d.ts +42 -0
- package/dist/platforms/ScienceDirectSearcher.d.ts.map +1 -0
- package/dist/platforms/ScienceDirectSearcher.js +334 -0
- package/dist/platforms/ScienceDirectSearcher.js.map +1 -0
- package/dist/platforms/ScopusSearcher.d.ts +43 -0
- package/dist/platforms/ScopusSearcher.d.ts.map +1 -0
- package/dist/platforms/ScopusSearcher.js +377 -0
- package/dist/platforms/ScopusSearcher.js.map +1 -0
- package/dist/platforms/SemanticScholarSearcher.d.ts +96 -0
- package/dist/platforms/SemanticScholarSearcher.d.ts.map +1 -0
- package/dist/platforms/SemanticScholarSearcher.js +419 -0
- package/dist/platforms/SemanticScholarSearcher.js.map +1 -0
- package/dist/platforms/SpringerSearcher.d.ts +54 -0
- package/dist/platforms/SpringerSearcher.d.ts.map +1 -0
- package/dist/platforms/SpringerSearcher.js +387 -0
- package/dist/platforms/SpringerSearcher.js.map +1 -0
- package/dist/platforms/USENIXSearcher.d.ts +14 -0
- package/dist/platforms/USENIXSearcher.d.ts.map +1 -0
- package/dist/platforms/USENIXSearcher.js +75 -0
- package/dist/platforms/USENIXSearcher.js.map +1 -0
- package/dist/platforms/UnpaywallSearcher.d.ts +29 -0
- package/dist/platforms/UnpaywallSearcher.d.ts.map +1 -0
- package/dist/platforms/UnpaywallSearcher.js +135 -0
- package/dist/platforms/UnpaywallSearcher.js.map +1 -0
- package/dist/platforms/WebOfScienceSearcher.d.ts +111 -0
- package/dist/platforms/WebOfScienceSearcher.d.ts.map +1 -0
- package/dist/platforms/WebOfScienceSearcher.js +500 -0
- package/dist/platforms/WebOfScienceSearcher.js.map +1 -0
- package/dist/registry/aliases.d.ts +2 -0
- package/dist/registry/aliases.d.ts.map +1 -0
- package/dist/registry/aliases.js +2 -0
- package/dist/registry/aliases.js.map +1 -0
- package/dist/registry/httpPolicies.d.ts +3 -0
- package/dist/registry/httpPolicies.d.ts.map +1 -0
- package/dist/registry/httpPolicies.js +13 -0
- package/dist/registry/httpPolicies.js.map +1 -0
- package/dist/registry/platformFactories.d.ts +8 -0
- package/dist/registry/platformFactories.d.ts.map +1 -0
- package/dist/registry/platformFactories.js +51 -0
- package/dist/registry/platformFactories.js.map +1 -0
- package/dist/registry/platformMetadata.d.ts +55 -0
- package/dist/registry/platformMetadata.d.ts.map +1 -0
- package/dist/registry/platformMetadata.js +438 -0
- package/dist/registry/platformMetadata.js.map +1 -0
- package/dist/services/CitationService.d.ts +3 -0
- package/dist/services/CitationService.d.ts.map +1 -0
- package/dist/services/CitationService.js +2 -0
- package/dist/services/CitationService.js.map +1 -0
- package/dist/services/JournalMetricsService.d.ts +3 -0
- package/dist/services/JournalMetricsService.d.ts.map +1 -0
- package/dist/services/JournalMetricsService.js +2 -0
- package/dist/services/JournalMetricsService.js.map +1 -0
- package/dist/services/MultiSourceSearchService.d.ts +3 -0
- package/dist/services/MultiSourceSearchService.d.ts.map +1 -0
- package/dist/services/MultiSourceSearchService.js +2 -0
- package/dist/services/MultiSourceSearchService.js.map +1 -0
- package/dist/services/OpenAccessFallbackService.d.ts +4 -0
- package/dist/services/OpenAccessFallbackService.d.ts.map +1 -0
- package/dist/services/OpenAccessFallbackService.js +2 -0
- package/dist/services/OpenAccessFallbackService.js.map +1 -0
- package/dist/skills/SkillInstaller.d.ts +110 -0
- package/dist/skills/SkillInstaller.d.ts.map +1 -0
- package/dist/skills/SkillInstaller.js +393 -0
- package/dist/skills/SkillInstaller.js.map +1 -0
- package/dist/utils/ErrorHandler.d.ts +3 -0
- package/dist/utils/ErrorHandler.d.ts.map +1 -0
- package/dist/utils/ErrorHandler.js +3 -0
- package/dist/utils/ErrorHandler.js.map +1 -0
- package/dist/utils/HttpClient.d.ts +2 -0
- package/dist/utils/HttpClient.d.ts.map +1 -0
- package/dist/utils/HttpClient.js +2 -0
- package/dist/utils/HttpClient.js.map +1 -0
- package/dist/utils/Logger.d.ts +6 -0
- package/dist/utils/Logger.d.ts.map +1 -0
- package/dist/utils/Logger.js +26 -0
- package/dist/utils/Logger.js.map +1 -0
- package/dist/utils/PDFExtractor.d.ts +3 -0
- package/dist/utils/PDFExtractor.d.ts.map +1 -0
- package/dist/utils/PDFExtractor.js +3 -0
- package/dist/utils/PDFExtractor.js.map +1 -0
- package/dist/utils/PdfDownload.d.ts +2 -0
- package/dist/utils/PdfDownload.d.ts.map +1 -0
- package/dist/utils/PdfDownload.js +2 -0
- package/dist/utils/PdfDownload.js.map +1 -0
- package/dist/utils/QuotaManager.d.ts +32 -0
- package/dist/utils/QuotaManager.d.ts.map +1 -0
- package/dist/utils/QuotaManager.js +95 -0
- package/dist/utils/QuotaManager.js.map +1 -0
- package/dist/utils/RateLimiter.d.ts +2 -0
- package/dist/utils/RateLimiter.d.ts.map +1 -0
- package/dist/utils/RateLimiter.js +2 -0
- package/dist/utils/RateLimiter.js.map +1 -0
- package/dist/utils/RequestCache.d.ts +3 -0
- package/dist/utils/RequestCache.d.ts.map +1 -0
- package/dist/utils/RequestCache.js +3 -0
- package/dist/utils/RequestCache.js.map +1 -0
- package/dist/utils/SecurityUtils.d.ts +3 -0
- package/dist/utils/SecurityUtils.d.ts.map +1 -0
- package/dist/utils/SecurityUtils.js +3 -0
- package/dist/utils/SecurityUtils.js.map +1 -0
- package/package.json +118 -4
- package/skills/paper-search/SKILL.md +151 -0
- package/skills/paper-search/references/browser-download.md +101 -0
- package/skills/paper-search/references/capability-routing.md +174 -0
- package/skills/paper-search/references/carsi-setup.md +69 -0
- package/skills/paper-search/references/cli-contract.md +200 -0
- package/skills/paper-search/references/management-layer.md +149 -0
- package/skills/paper-search/references/publisher-support.md +72 -0
- package/skills/paper-search/references/troubleshooting.md +15 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
"""Is a captured PDF this article's main text? Evidence from its first pages.
|
|
2
|
+
|
|
3
|
+
The same rule as PaperSearch's src/infrastructure/pdf/PdfIdentity.ts, with the
|
|
4
|
+
same test cases (tests/fixtures/pdf_identity_cases.json). One rule for every
|
|
5
|
+
publisher, layout and decade (2026-11-02, measured on 5,378 PDFs of the
|
|
6
|
+
maintainer's Zotero library from 1970 to 2026, each also checked against a
|
|
7
|
+
neighbouring article and the article with the most similar title). The text of
|
|
8
|
+
the first pages is normalised so that what extraction and OCR vary (line breaks,
|
|
9
|
+
hyphenation, spaces inside a DOI, line numbers, superscripts, ligatures,
|
|
10
|
+
misread letters, reading order) does not matter, and the evidence is weighed:
|
|
11
|
+
|
|
12
|
+
- strong: the whole title, exactly (letters only, at least 50 of them),
|
|
13
|
+
standing as a title (an exact match inside a longer line counts one level lower);
|
|
14
|
+
- single: the target DOI; the title with a few misread letters; a shorter title.
|
|
15
|
+
|
|
16
|
+
Strong evidence, or two single pieces, verify the PDF; one single piece verifies
|
|
17
|
+
it while the pages print no other DOI. Other DOIs and no evidence at all:
|
|
18
|
+
another article. A title's numbers must always be exact. An attachment
|
|
19
|
+
(supplementary material, disclosure form) and a notice about the article
|
|
20
|
+
(correction, retraction, briefing, letter to the editor), each known by its own
|
|
21
|
+
heading line, are not the article, unless the notice is itself the requested
|
|
22
|
+
item: its title says so, or the pages name it (its DOI in the header, or its
|
|
23
|
+
whole title and its DOI) and print no other DOI. A scan without a text layer is
|
|
24
|
+
``"source"`` when the URL it came from names the DOI (``assess`` with ``source``;
|
|
25
|
+
the frontend passes it, the engine does not).
|
|
26
|
+
|
|
27
|
+
``classify`` gives ``"match"`` (verified), ``"other"`` (another article),
|
|
28
|
+
``"unknown"`` (no decision: no text layer, or nothing printed) or ``"invalid"``
|
|
29
|
+
(not a readable PDF). The caller accepts a match at once, never saves "other",
|
|
30
|
+
and keeps an "unknown" file as a fallback to be checked later.
|
|
31
|
+
"""
|
|
32
|
+
from __future__ import annotations
|
|
33
|
+
|
|
34
|
+
import logging
|
|
35
|
+
import re
|
|
36
|
+
import unicodedata
|
|
37
|
+
from urllib.parse import unquote
|
|
38
|
+
|
|
39
|
+
log = logging.getLogger(__name__)
|
|
40
|
+
|
|
41
|
+
PAGES = 3 # the title and DOI are on page 1, or on page 2 after a cover or an opener page
|
|
42
|
+
STRONG_TITLE = 50 # letters a title needs to be strong evidence alone
|
|
43
|
+
SHORT_TITLE = 15 # letters a title needs to be evidence at all ("Editorial" is not)
|
|
44
|
+
CLOSE_TITLE = 25 # letters a title needs before misread letters are allowed in it
|
|
45
|
+
LETTERS_PER_ERROR = 12 # one misread letter allowed per this many letters
|
|
46
|
+
HEAD_CHARS = 400 # where an attachment or a notice announces itself
|
|
47
|
+
SHARED_SUFFIX = 10 # a suffix this long names one article under whichever prefix
|
|
48
|
+
SCAN_MAX_LETTERS = 300 # fewer letters on the pages read: a scan without a text layer
|
|
49
|
+
|
|
50
|
+
# A reference list cites other articles: its DOIs and titles are not evidence.
|
|
51
|
+
_REFERENCES_HEADING = re.compile(r"^\s*(?:references?|literature cited)\s*$", re.I | re.M)
|
|
52
|
+
# An attachment's own heading line, not a sentence that starts with the same words.
|
|
53
|
+
_ATTACHMENT_HEADING = re.compile(
|
|
54
|
+
r"^\s*(?:electronic\s+)?(?:supplement(?:ary|al)?|supporting|online(?:\s+only)?)\s+(?:online\s+)?"
|
|
55
|
+
r"(?:information|materials?|data|content|appendix|methods|figures?|figure legends|tables?|text|files?)"
|
|
56
|
+
r"\s*(?:for\b.*|:.*)?$|^\s*appendix(?:\s+[a-z0-9])?\s*:?\s*$|^\s*plain language summary\b|^\s*(?:icmje\s+)?disclosure\s+form"
|
|
57
|
+
r"|^\s*conflicts?\s+of\s+interest\s+(?:form|disclosure)", re.I | re.M)
|
|
58
|
+
# A notice's own heading line: the word opens the line, alone or followed by ":" or
|
|
59
|
+
# "to" ("CORRECTION", "Correction to: …", "Retraction Note", "RETRACTED ARTICLE: …",
|
|
60
|
+
# "Notice of Retraction"), or closes it after a colon ("<title>: Erratum"); not a
|
|
61
|
+
# sentence that uses it ("Upper eyelid retraction…", "Correction of hallux valgus…").
|
|
62
|
+
_NOTICE = re.compile(
|
|
63
|
+
r"^\s*(?:(?:author|publisher|editorial|notice\s+of|statement\s+of)\s+)?"
|
|
64
|
+
r"(?:correction|erratum|corrigendum|retraction|retracted|expression of concern|research briefing|letter to the editor)"
|
|
65
|
+
r"(?:\s+(?:note|notice|article))?\s*(?::|\bto\b|$)|^\s*withdrawn\s*:"
|
|
66
|
+
r"|:[ \t]*(?:correction|erratum|corrigendum|retraction|expression of concern)[ \t]*$", re.I | re.M)
|
|
67
|
+
# A requested item whose title says it is a notice ("…: Erratum", "Reply to …").
|
|
68
|
+
_NOTICE_TITLE = re.compile(r"\b(?:erratum|corrigendum|correction|retraction|retracted|withdrawn|expression of concern|reply to|letter)\b", re.I)
|
|
69
|
+
# A DOI may break right after its prefix ("https://doi.org/10.1016/" then "S0140-…", The Lancet).
|
|
70
|
+
_DOI_IN_TEXT = re.compile(r"10\.\d{4,9}/(?:[ \t]*\n[ \t]*)?[^\s\"<>]+")
|
|
71
|
+
_LETTER = re.compile(r"[a-zЀ-ӿ一-鿿]")
|
|
72
|
+
_ENTITIES = {"amp": "&", "lt": "<", "gt": ">", "quot": '"', "apos": "'"}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def normalize_doi_text(value: str) -> str:
|
|
76
|
+
"""Case, invisible characters, typographic dashes and control characters do not matter."""
|
|
77
|
+
text = unicodedata.normalize("NFKC", value or "")
|
|
78
|
+
text = re.sub("[-]", "", text)
|
|
79
|
+
text = re.sub("[‐-―−﹘﹣-]", "-", text)
|
|
80
|
+
return re.sub("[\x00-\x08\x0e-\x1f\x7f]", " ", text).lower()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _plain_title(title: str) -> str:
|
|
84
|
+
"""A Crossref title without its markup ("<i>", "&")."""
|
|
85
|
+
def entity(match: re.Match[str]) -> str:
|
|
86
|
+
name = match.group(1)
|
|
87
|
+
if not name.startswith("#"):
|
|
88
|
+
return _ENTITIES.get(name.lower(), match.group(0))
|
|
89
|
+
return chr(int(name[2:], 16) if name[1:2].lower() == "x" else int(name[1:]))
|
|
90
|
+
return re.sub(r"&(#x[0-9a-f]+|#\d+|[a-z]+);", entity, re.sub(r"<[^>]+>", " ", title or ""), flags=re.I)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _letters(text: str) -> tuple[str, list[int]]:
|
|
94
|
+
"""Letters of a normalised text (accents dropped; digits, Greek, punctuation left out) and their positions."""
|
|
95
|
+
chars: list[str] = []
|
|
96
|
+
at: list[int] = []
|
|
97
|
+
for i, char in enumerate(text):
|
|
98
|
+
base = unicodedata.normalize("NFD", char)[0]
|
|
99
|
+
if _LETTER.match(base):
|
|
100
|
+
chars.append(base)
|
|
101
|
+
at.append(i)
|
|
102
|
+
return "".join(chars), at
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _weight(key: str) -> int:
|
|
106
|
+
"""A CJK character carries about as much as a short word."""
|
|
107
|
+
return len(key) + 2 * len(re.findall("[一-鿿]", key))
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _close_match_end(text: str, key: str, errors: int) -> int:
|
|
111
|
+
"""End of the best match of ``key`` in ``text`` with at most ``errors`` edits, or -1."""
|
|
112
|
+
m = len(key)
|
|
113
|
+
previous = list(range(m + 1))
|
|
114
|
+
best, end = errors + 1, -1
|
|
115
|
+
for j, char in enumerate(text):
|
|
116
|
+
current = [0] * (m + 1)
|
|
117
|
+
for i in range(1, m + 1):
|
|
118
|
+
current[i] = min(previous[i - 1] + (key[i - 1] != char), previous[i] + 1, current[i - 1] + 1)
|
|
119
|
+
if current[m] < best:
|
|
120
|
+
best, end = current[m], j + 1
|
|
121
|
+
previous = current
|
|
122
|
+
return end
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _stands_alone(text: str, start: int, stop: int) -> bool:
|
|
126
|
+
"""No words before the matched title on its first line, nor after it on its last."""
|
|
127
|
+
before = text[max(0, start - 80):start]
|
|
128
|
+
after = text[stop:stop + 80]
|
|
129
|
+
line_after = after.split("\n", 1)[0]
|
|
130
|
+
return not re.search(r"[a-z]{2,}", before[before.rfind("\n") + 1:]) and not re.search(r"[a-z]{3,}", line_after)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def _numbers_match(window: str, title: str) -> bool:
|
|
134
|
+
found = set(re.findall(r"[0-9]+", window))
|
|
135
|
+
return all(number in found for number in re.findall(r"[0-9]+", title))
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _title_evidence(text: str, chars: str, at: list[int], title: str) -> str | None:
|
|
139
|
+
plain = normalize_doi_text(_plain_title(title))
|
|
140
|
+
key = _letters(plain)[0]
|
|
141
|
+
if _weight(key) < SHORT_TITLE:
|
|
142
|
+
return None
|
|
143
|
+
|
|
144
|
+
def window(end: int, length: int) -> str:
|
|
145
|
+
# The matched stretch, a little wider: a title may start or end with numbers.
|
|
146
|
+
return text[max(0, at[max(0, end - length)] - 25):at[end - 1] + 26]
|
|
147
|
+
|
|
148
|
+
inside = False
|
|
149
|
+
exact = chars.find(key)
|
|
150
|
+
while exact >= 0:
|
|
151
|
+
if _numbers_match(window(exact + len(key), len(key)), plain):
|
|
152
|
+
if _stands_alone(text, at[exact], at[exact + len(key) - 1] + 1):
|
|
153
|
+
return "strong" if _weight(key) >= STRONG_TITLE else "single"
|
|
154
|
+
inside = True
|
|
155
|
+
exact = chars.find(key, exact + 1)
|
|
156
|
+
if inside: # only inside longer lines: part of another title or of a sentence
|
|
157
|
+
return "single" if _weight(key) >= STRONG_TITLE else None
|
|
158
|
+
if _weight(key) < CLOSE_TITLE:
|
|
159
|
+
return None
|
|
160
|
+
errors = len(key) // LETTERS_PER_ERROR
|
|
161
|
+
end = _close_match_end(chars, key, errors)
|
|
162
|
+
return "single" if end > 0 and _numbers_match(window(end, len(key) + errors), plain) else None
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def _target_doi(identifier: str) -> str:
|
|
166
|
+
return re.sub(r"^(?:https?://(?:dx\.)?doi\.org/|doi:\s*)", "", (identifier or "").strip().lower())
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def _bare(doi: str) -> str:
|
|
170
|
+
return re.sub(r"[^0-9a-z]", "", doi)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def _suffix(doi: str) -> str:
|
|
174
|
+
return doi[doi.find("/") + 1:]
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _doi_named(pages: str, target: str) -> bool:
|
|
178
|
+
"""The DOI anywhere, spaces inside it ignored, not part of a longer DOI; a long suffix under another prefix too."""
|
|
179
|
+
if not re.match(r"10\.\d{4,9}/\S", target):
|
|
180
|
+
return False
|
|
181
|
+
pattern = lambda value: r"\s*".join(re.escape(char) for char in value) # noqa: E731
|
|
182
|
+
suffix = _suffix(target)
|
|
183
|
+
head = r"10\.\d{4,9}/\s*" if len(_bare(suffix)) >= SHARED_SUFFIX else pattern(target[:-len(suffix)]) + r"\s*"
|
|
184
|
+
return re.search(rf"(?<![0-9.]){head}{pattern(suffix)}(?![0-9a-z_/-]|\.[0-9a-z])", pages) is not None
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def _other_dois(pages: str, target: str) -> list[str]:
|
|
188
|
+
"""DOIs printed that are not the target, nor a piece, an extension, a misprint or an older prefix of it."""
|
|
189
|
+
own, own_suffix = _bare(target), _bare(_suffix(target))
|
|
190
|
+
found = [re.sub(r"[.,;:)\]]+$", "", re.sub(r"\s+", "", m.group(0))) for m in _DOI_IN_TEXT.finditer(pages)]
|
|
191
|
+
return [doi for doi in found if not own.startswith(_bare(doi)) and not _bare(doi).startswith(own)
|
|
192
|
+
and not (len(own_suffix) >= SHARED_SUFFIX and _bare(_suffix(doi)) == own_suffix)]
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def _title_before(text: str, title: str) -> bool:
|
|
196
|
+
"""The requested title (its first letters) is printed in ``text``."""
|
|
197
|
+
key = _letters(normalize_doi_text(_plain_title(title)))[0]
|
|
198
|
+
return _weight(key) >= SHORT_TITLE and key[:30] in _letters(text)[0]
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def title_printed(text: str, title: str) -> bool:
|
|
202
|
+
"""The title (its first letters) is printed in ``text``, as on the article's own page."""
|
|
203
|
+
return bool((title or "").strip()) and _title_before(normalize_doi_text(text or ""), title)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def _not_the_article(head: str, title: str, named: bool) -> bool:
|
|
207
|
+
"""An attachment, or a notice about an article (not the requested notice itself).
|
|
208
|
+
``named``: the pages name the requested item and no other article (``evidence``)."""
|
|
209
|
+
# A supplementary file opens with its heading and names the article after it;
|
|
210
|
+
# an article whose toolbar lists "Supporting Information" below its own title
|
|
211
|
+
# is the article (ACS, 2026-11-02).
|
|
212
|
+
attachment = _ATTACHMENT_HEADING.search(head)
|
|
213
|
+
if attachment and not _title_before(head[:attachment.start()], title):
|
|
214
|
+
return True
|
|
215
|
+
return bool(_NOTICE.search(head)) and not named and not _NOTICE_TITLE.search(_plain_title(title))
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def evidence(first_pages: str, identifier: str, title: str = "") -> dict | None:
|
|
219
|
+
"""What the first pages show; None without any text."""
|
|
220
|
+
if not (first_pages or "").strip():
|
|
221
|
+
return None
|
|
222
|
+
text = normalize_doi_text(first_pages)
|
|
223
|
+
front = _REFERENCES_HEADING.split(text, maxsplit=1)[0]
|
|
224
|
+
target = _target_doi(identifier)
|
|
225
|
+
chars, at = _letters(front)
|
|
226
|
+
doi = _doi_named(front, target)
|
|
227
|
+
found = _title_evidence(front, chars, at, title) if (title or "").strip() else None
|
|
228
|
+
others = _other_dois(front, target)
|
|
229
|
+
# A notice is itself the requested item when the pages name it (its DOI in the
|
|
230
|
+
# header, Neurology; its whole title and its DOI, a letter under a "Letter to the
|
|
231
|
+
# editor" heading) and print no other DOI. A notice about an article prints its
|
|
232
|
+
# own DOI as well ("Author Correction" then "Correction to: Nature
|
|
233
|
+
# https://doi.org/<the article>"; a Frontiers corrigendum, 2026-11-02).
|
|
234
|
+
named = (_doi_named(front[:HEAD_CHARS], target) or (doi and found == "strong")) and not others
|
|
235
|
+
return {
|
|
236
|
+
"not_article": _not_the_article(text[:HEAD_CHARS], title or "", named),
|
|
237
|
+
"doi": doi,
|
|
238
|
+
"title": found,
|
|
239
|
+
"other_dois": others,
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def _decoded(url: str) -> str:
|
|
244
|
+
"""The URL percent-decoded; as given when it does not decode (as decodeURIComponent)."""
|
|
245
|
+
if re.search(r"%(?![0-9a-f]{2})", url, re.I):
|
|
246
|
+
return url
|
|
247
|
+
try:
|
|
248
|
+
return unquote(url, errors="strict")
|
|
249
|
+
except UnicodeDecodeError:
|
|
250
|
+
return url
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def _source_names_doi(source: str, target: str) -> bool:
|
|
254
|
+
"""The URL a PDF came from names the DOI, not as part of a longer DOI (a ".pdf" may follow)."""
|
|
255
|
+
if not re.match(r"10\.\d{4,9}/\S", target):
|
|
256
|
+
return False
|
|
257
|
+
return re.search(rf"(?<![0-9.]){re.escape(target)}(?![0-9a-z_/-]|\.(?!pdf(?![0-9a-z]))[0-9a-z])",
|
|
258
|
+
_decoded(source).lower()) is not None
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def assess(first_pages: str, identifier: str, title: str = "", source: str = "") -> str:
|
|
262
|
+
"""``"verified"``, ``"mismatch"``, ``"source"`` or ``"unverified"`` for the text of the first
|
|
263
|
+
pages. ``source``: the URL the PDF came from, the only evidence for a scan without a text
|
|
264
|
+
layer (``"source"``) when nothing printed points elsewhere."""
|
|
265
|
+
found = evidence(first_pages, identifier, title)
|
|
266
|
+
if found and not found["not_article"]:
|
|
267
|
+
single = int(found["doi"]) + int(found["title"] == "single")
|
|
268
|
+
if found["title"] == "strong" or single == 2 or (single == 1 and not found["other_dois"]):
|
|
269
|
+
return "verified"
|
|
270
|
+
if single == 0 and found["other_dois"]:
|
|
271
|
+
return "mismatch"
|
|
272
|
+
scan = (sum(char.isalpha() for char in first_pages or "") < SCAN_MAX_LETTERS
|
|
273
|
+
and not (found and (found["not_article"] or found["other_dois"])))
|
|
274
|
+
return "source" if source and scan and _source_names_doi(source, _target_doi(identifier)) else "unverified"
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def first_pages_text(body: bytes) -> str | None:
|
|
278
|
+
"""Text of the first pages; None for an unreadable PDF."""
|
|
279
|
+
import pymupdf
|
|
280
|
+
|
|
281
|
+
try:
|
|
282
|
+
with pymupdf.open(stream=body, filetype="pdf") as document:
|
|
283
|
+
if not document.page_count:
|
|
284
|
+
return None
|
|
285
|
+
return "\n".join(document[i].get_text() for i in range(min(PAGES, document.page_count)))
|
|
286
|
+
except (pymupdf.FileDataError, RuntimeError, ValueError) as exc:
|
|
287
|
+
log.info("pdf_guard: unreadable PDF (%s)", type(exc).__name__)
|
|
288
|
+
return None
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def classify(body: bytes, doi: str, title: str = "") -> str:
|
|
292
|
+
return classify_with_evidence(body, doi, title)[0]
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def classify_with_evidence(body: bytes, doi: str, title: str = "") -> tuple[str, dict | None]:
|
|
296
|
+
"""``classify``'s verdict and the evidence behind it (``evidence``: doi,
|
|
297
|
+
title, other_dois, not_article; None for an unreadable PDF or no text)."""
|
|
298
|
+
text = first_pages_text(body)
|
|
299
|
+
if text is None:
|
|
300
|
+
return "invalid", None
|
|
301
|
+
verdict = {"verified": "match", "mismatch": "other"}.get(assess(text, doi, title), "unknown")
|
|
302
|
+
return verdict, evidence(text, doi, title)
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
def names_other_article(body: bytes, doi: str, title: str = "") -> list[str]:
|
|
306
|
+
"""Other articles' DOIs when the PDF names only them (else an empty list); an unreadable PDF passes."""
|
|
307
|
+
text = first_pages_text(body)
|
|
308
|
+
if not text or assess(text, doi, title) != "mismatch":
|
|
309
|
+
return []
|
|
310
|
+
return sorted(set((evidence(text, doi, title) or {}).get("other_dois", [])))
|