SPB Git

spb/ai-atlas

Public

Lint fixes

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Simon-Pierre Boucher committed (Sep 11, 2026) parent 9f1db17 Browse files

20 changed files +113 −52

modified src/aiatlas/db/__init__.py +1 −1
@@ -72,4 +72,4 @@ async def execute_many(conn: AsyncConnection, sql: str, rows: Sequence[Mapping[s
72 await conn.execute(text(sql), list(rows)) 72 await conn.execute(text(sql), list(rows))
73 73
74 74
75−__all__ = ["engine", "dispose", "connection", "transaction", "execute", "fetch_all", "fetch_one", "fetch_val", "execute_many", "jsonb"] 75+__all__ = ["connection", "dispose", "engine", "execute", "execute_many", "fetch_all", "fetch_one", "fetch_val", "jsonb", "transaction"]
modified src/aiatlas/registry/__init__.py +2 −2
@@ -58,7 +58,7 @@ def org_by_github(gh_org: str) -> dict[str, Any] | None:
58 @lru_cache 58 @lru_cache
59 def org_by_domain(domain: str) -> dict[str, Any] | None: 59 def org_by_domain(domain: str) -> dict[str, Any] | None:
60 d = domain.lower() 60 d = domain.lower()
61− d = d[4:] if d.startswith("www.") else d 61+ d = d.removeprefix("www.")
62 for o in organizations().values(): 62 for o in organizations().values():
63 for od in o.get("domains", []): 63 for od in o.get("domains", []):
64 if d == od or d.endswith("." + od): 64 if d == od or d.endswith("." + od):
@@ -102,4 +102,4 @@ def provider_by_openrouter(slug: str) -> str | None:
102 return None 102 return None
103 103
104 104
105−__all__ = ["load", "organizations", "providers", "org_by_hf", "org_by_github", "org_by_domain", "org_ref", "provider_ref", "provider_by_openrouter", "REGISTRY_DIR"] 105+__all__ = ["REGISTRY_DIR", "load", "org_by_domain", "org_by_github", "org_by_hf", "org_ref", "organizations", "provider_by_openrouter", "provider_ref", "providers"]
modified src/aiatlas/sdk/__init__.py +19 −3
@@ -1,7 +1,23 @@
1 """Connector SDK — every connector shares this infrastructure: fetch transport, raw archive, extraction, facts, change detection.""" 1 """Connector SDK — every connector shares this infrastructure: fetch transport, raw archive, extraction, facts, change detection."""
2 from aiatlas.sdk.connector import BaseConnector, ConnectorError, RunContext, Target 2 from aiatlas.sdk.connector import BaseConnector, ConnectorError, RunContext, Target
3 from aiatlas.sdk.facts import Claim, EntityRef, Event, Facts, PriceObs, Relation, ResultObs 3 from aiatlas.sdk.facts import Claim, EntityRef, Event, Facts, PriceObs, Relation, ResultObs
4−from aiatlas.sdk.fetch import BlockedError, FetchError, FetchResult, Fetcher, NotModified 4+from aiatlas.sdk.fetch import BlockedError, Fetcher, FetchError, FetchResult, NotModified
5 5
6−__all__ = ["BaseConnector", "ConnectorError", "RunContext", "Target", "Claim", "EntityRef", "Event", "Facts", "PriceObs", 6+__all__ = [
7− "Relation", "ResultObs", "BlockedError", "FetchError", "FetchResult", "Fetcher", "NotModified"] 7+ "BaseConnector",
8+ "BlockedError",
9+ "Claim",
10+ "ConnectorError",
11+ "EntityRef",
12+ "Event",
13+ "Facts",
14+ "FetchError",
15+ "FetchResult",
16+ "Fetcher",
17+ "NotModified",
18+ "PriceObs",
19+ "Relation",
20+ "ResultObs",
21+ "RunContext",
22+ "Target",
23+]
modified src/aiatlas/sdk/archive.py +1 −1
@@ -71,4 +71,4 @@ def archive_size() -> dict[str, int]:
71 return out 71 return out
72 72
73 73
74−__all__ = ["store_raw", "store_text", "load_raw", "load_text", "archive_size"] 74+__all__ = ["archive_size", "load_raw", "load_text", "store_raw", "store_text"]
modified src/aiatlas/sdk/connector.py +4 −5
@@ -16,7 +16,6 @@ from dataclasses import dataclass, field
16 from datetime import UTC, datetime, timedelta 16 from datetime import UTC, datetime, timedelta
17 from typing import Any 17 from typing import Any
18 18
19−from aiatlas.config import settings
20 from aiatlas.db import execute, fetch_one, jsonb, transaction 19 from aiatlas.db import execute, fetch_one, jsonb, transaction
21 from aiatlas.ids import new_id 20 from aiatlas.ids import new_id
22 from aiatlas.sdk import archive 21 from aiatlas.sdk import archive
@@ -24,7 +23,7 @@ from aiatlas.sdk.extract.feeds import FeedItem, parse_feed
24 from aiatlas.sdk.extract.html import HtmlDoc, parse_html 23 from aiatlas.sdk.extract.html import HtmlDoc, parse_html
25 from aiatlas.sdk.extract.markdown import MarkdownDoc, parse_markdown 24 from aiatlas.sdk.extract.markdown import MarkdownDoc, parse_markdown
26 from aiatlas.sdk.facts import Facts, Target 25 from aiatlas.sdk.facts import Facts, Target
27−from aiatlas.sdk.fetch import BlockedError, FetchError, Fetcher, FetchResult, NotModified, canonicalize_url, file_result 26+from aiatlas.sdk.fetch import BlockedError, Fetcher, FetchError, FetchResult, NotModified, canonicalize_url, file_result
28 from aiatlas.sdk.writer import FactWriter 27 from aiatlas.sdk.writer import FactWriter
29 28
30 log = logging.getLogger(__name__) 29 log = logging.getLogger(__name__)
@@ -208,7 +207,7 @@ class BaseConnector:
208 d=f"parser_breakage:{self.name}:{started.date()}") 207 d=f"parser_breakage:{self.name}:{started.date()}")
209 ctx.log.info("run finished", extra={"status": status, **{k: v for k, v in ctx.stats.__dict__.items() if k != "meta"}, 208 ctx.log.info("run finished", extra={"status": status, **{k: v for k, v in ctx.stats.__dict__.items() if k != "meta"},
210 "ms": int((time.perf_counter() - t0) * 1000)}) 209 "ms": int((time.perf_counter() - t0) * 1000)})
211− except Exception as exc: # noqa: BLE001 210+ except Exception as exc:
212 ctx.log.exception("run failed", extra={"error": str(exc)}) 211 ctx.log.exception("run failed", extra={"error": str(exc)})
213 async with transaction() as conn: 212 async with transaction() as conn:
214 await self._record(conn, ctx, "failed", error=f"{exc.__class__.__name__}: {exc}"[:2000]) 213 await self._record(conn, ctx, "failed", error=f"{exc.__class__.__name__}: {exc}"[:2000])
@@ -385,7 +384,7 @@ class BaseConnector:
385 parsed = parsed or self.parse(target, res) 384 parsed = parsed or self.parse(target, res)
386 try: 385 try:
387 facts = await self.extract(ctx, target, res, parsed) 386 facts = await self.extract(ctx, target, res, parsed)
388− except Exception as exc: # noqa: BLE001 387+ except Exception as exc:
389 ctx.log.exception("extract failed", extra={"url": res.url}) 388 ctx.log.exception("extract failed", extra={"url": res.url})
390 async with transaction() as conn: 389 async with transaction() as conn:
391 await execute(conn, "insert into connector_errors (connector_name, run_id, url, error_type, message) values (:n, :r, :u, :t, :m)", 390 await execute(conn, "insert into connector_errors (connector_name, run_id, url, error_type, message) values (:n, :r, :u, :t, :m)",
@@ -480,4 +479,4 @@ def _jsonable(obj: Any) -> Any:
480 return json.loads(json.dumps(obj, default=str)) 479 return json.loads(json.dumps(obj, default=str))
481 480
482 481
483−__all__ = ["BaseConnector", "ConnectorError", "RunContext", "RunStats", "Parsed", "Target"] 482+__all__ = ["BaseConnector", "ConnectorError", "Parsed", "RunContext", "RunStats", "Target"]
modified src/aiatlas/sdk/extract/__init__.py +24 −4
@@ -4,9 +4,29 @@ from aiatlas.sdk.extract.dates import parse_date, parse_datetime
4 from aiatlas.sdk.extract.feeds import FeedItem, parse_feed 4 from aiatlas.sdk.extract.feeds import FeedItem, parse_feed
5 from aiatlas.sdk.extract.html import HtmlDoc, parse_html 5 from aiatlas.sdk.extract.html import HtmlDoc, parse_html
6 from aiatlas.sdk.extract.markdown import MarkdownDoc, parse_front_matter, parse_markdown 6 from aiatlas.sdk.extract.markdown import MarkdownDoc, parse_front_matter, parse_markdown
7−from aiatlas.sdk.extract.numbers import parse_context_length, parse_money_per_mtok, parse_param_count, parse_percent, parse_tokens 7+from aiatlas.sdk.extract.numbers import (
8+ parse_context_length,
9+ parse_money_per_mtok,
10+ parse_param_count,
11+ parse_percent,
12+ parse_tokens,
13+)
8 from aiatlas.sdk.extract.sitemap import parse_sitemap 14 from aiatlas.sdk.extract.sitemap import parse_sitemap
9 15
10−__all__ = ["parse_date", "parse_datetime", "FeedItem", "parse_feed", "HtmlDoc", "parse_html", "MarkdownDoc", "parse_front_matter", 16+__all__ = [
11− "parse_markdown", "parse_context_length", "parse_money_per_mtok", "parse_param_count", "parse_percent", "parse_tokens", 17+ "FeedItem",
12− "parse_sitemap"] 18+ "HtmlDoc",
19+ "MarkdownDoc",
20+ "parse_context_length",
21+ "parse_date",
22+ "parse_datetime",
23+ "parse_feed",
24+ "parse_front_matter",
25+ "parse_html",
26+ "parse_markdown",
27+ "parse_money_per_mtok",
28+ "parse_param_count",
29+ "parse_percent",
30+ "parse_sitemap",
31+ "parse_tokens",
32+]
modified src/aiatlas/sdk/extract/dates.py +2 −2
@@ -7,7 +7,7 @@ from datetime import UTC, date, datetime
7 from dateutil import parser as duparser 7 from dateutil import parser as duparser
8 8
9 _MONTHS = "january|february|march|april|may|june|july|august|september|october|november|december|jan|feb|mar|apr|jun|jul|aug|sep|sept|oct|nov|dec" 9 _MONTHS = "january|february|march|april|may|june|july|august|september|october|november|december|jan|feb|mar|apr|jun|jul|aug|sep|sept|oct|nov|dec"
10−_MONTH_YEAR = re.compile(rf"\b({_MONTHS})\.?\s+(\d{{4}})\b", re.I) 10+_MONTH_YEAR = re.compile(rf"\b({_MONTHS})\.?\s+(\d{{4}})\b", re.IGNORECASE)
11 _YEAR = re.compile(r"\b(19[89]\d|20[0-4]\d)\b") 11 _YEAR = re.compile(r"\b(19[89]\d|20[0-4]\d)\b")
12 12
13 13
@@ -68,4 +68,4 @@ def iso(dt: datetime | date | None) -> str | None:
68 return dt.isoformat() 68 return dt.isoformat()
69 69
70 70
71−__all__ = ["parse_datetime", "parse_date", "iso"] 71+__all__ = ["iso", "parse_date", "parse_datetime"]
modified src/aiatlas/sdk/extract/html.py +1 −1
@@ -233,4 +233,4 @@ def find_in_json(obj: Any, key: str, *, max_hits: int = 50) -> list[Any]:
233 return hits 233 return hits
234 234
235 235
236−__all__ = ["HtmlDoc", "parse_html", "clean_text", "node_text", "extract_text", "find_in_json"] 236+__all__ = ["HtmlDoc", "clean_text", "extract_text", "find_in_json", "node_text", "parse_html"]
modified src/aiatlas/sdk/extract/markdown.py +7 −9
@@ -7,8 +7,8 @@ from typing import Any
7 7
8 import yaml 8 import yaml
9 9
10−_FM = re.compile(r"\A---[ \t]*\r?\n(.*?)\r?\n---[ \t]*\r?\n", re.S) 10+_FM = re.compile(r"\A---[ \t]*\r?\n(.*?)\r?\n---[ \t]*\r?\n", re.DOTALL)
11−_HEADING = re.compile(r"^(#{1,6})\s+(.*?)\s*#*\s*$", re.M) 11+_HEADING = re.compile(r"^(#{1,6})\s+(.*?)\s*#*\s*$", re.MULTILINE)
12 _LINK = re.compile(r"\[([^\]]*)\]\((https?://[^)\s]+)\)") 12 _LINK = re.compile(r"\[([^\]]*)\]\((https?://[^)\s]+)\)")
13 _TABLE_ROW = re.compile(r"^\s*\|(.+)\|\s*$") 13 _TABLE_ROW = re.compile(r"^\s*\|(.+)\|\s*$")
14 _SEP_ROW = re.compile(r"^\s*\|?\s*:?-{2,}:?\s*(\|\s*:?-{2,}:?\s*)*\|?\s*$") 14 _SEP_ROW = re.compile(r"^\s*\|?\s*:?-{2,}:?\s*(\|\s*:?-{2,}:?\s*)*\|?\s*$")
@@ -25,7 +25,7 @@ class MarkdownDoc:
25 25
26 def section(self, title_pattern: str) -> str: 26 def section(self, title_pattern: str) -> str:
27 """Body text of the first heading matching `title_pattern` (case-insensitive) up to the next heading of same/higher level.""" 27 """Body text of the first heading matching `title_pattern` (case-insensitive) up to the next heading of same/higher level."""
28− rx = re.compile(title_pattern, re.I) 28+ rx = re.compile(title_pattern, re.IGNORECASE)
29 lines = self.body.split("\n") 29 lines = self.body.split("\n")
30 start = None 30 start = None
31 level = 0 31 level = 0
@@ -83,19 +83,17 @@ def _tables(body: str) -> list[dict[str, Any]]:
83 83
84 def _cells(line: str) -> list[str]: 84 def _cells(line: str) -> list[str]:
85 inner = line.strip() 85 inner = line.strip()
86− if inner.startswith("|"): 86+ inner = inner.removeprefix("|")
87− inner = inner[1:] 87+ inner = inner.removesuffix("|")
88− if inner.endswith("|"):
89− inner = inner[:-1]
90 return [re.sub(r"\*\*|`", "", c).strip() for c in inner.split("|")] 88 return [re.sub(r"\*\*|`", "", c).strip() for c in inner.split("|")]
91 89
92 90
93 def _to_text(body: str) -> str: 91 def _to_text(body: str) -> str:
94− s = re.sub(r"```.*?```", " ", body, flags=re.S) 92+ s = re.sub(r"```.*?```", " ", body, flags=re.DOTALL)
95 s = re.sub(r"!\[[^\]]*\]\([^)]*\)", " ", s) 93 s = re.sub(r"!\[[^\]]*\]\([^)]*\)", " ", s)
96 s = re.sub(r"\[([^\]]*)\]\([^)]*\)", r"\1", s) 94 s = re.sub(r"\[([^\]]*)\]\([^)]*\)", r"\1", s)
97 s = re.sub(r"<[^>]+>", " ", s) 95 s = re.sub(r"<[^>]+>", " ", s)
98− s = re.sub(r"^[#>*\-|\s]+", "", s, flags=re.M) 96+ s = re.sub(r"^[#>*\-|\s]+", "", s, flags=re.MULTILINE)
99 s = re.sub(r"[ \t]+", " ", s) 97 s = re.sub(r"[ \t]+", " ", s)
100 return re.sub(r"\n{3,}", "\n\n", s).strip() 98 return re.sub(r"\n{3,}", "\n\n", s).strip()
101 99
modified src/aiatlas/sdk/extract/numbers.py +15 −7
@@ -5,10 +5,10 @@ import re
5 5
6 _MULT = {"k": 1e3, "m": 1e6, "b": 1e9, "t": 1e12, "g": 1e9} 6 _MULT = {"k": 1e3, "m": 1e6, "b": 1e9, "t": 1e12, "g": 1e9}
7 7
8−_PARAMS = re.compile(r"(?<![\w.])(\d+(?:[.,]\d+)?)\s*([kKmMbBtT])\b(?:\s*(?:params?|parameters?))?", re.I) 8+_PARAMS = re.compile(r"(?<![\w.])(\d+(?:[.,]\d+)?)\s*([kKmMbBtT])\b(?:\s*(?:params?|parameters?))?", re.IGNORECASE)
9−_PARAMS_WORD = re.compile(r"(\d+(?:[.,]\d+)?)\s*(billion|million|trillion)\s*(?:params?|parameters?)", re.I) 9+_PARAMS_WORD = re.compile(r"(\d+(?:[.,]\d+)?)\s*(billion|million|trillion)\s*(?:params?|parameters?)", re.IGNORECASE)
10−_CONTEXT = re.compile(r"(\d+(?:[.,]\d+)?)\s*([kKmM])?\s*(?:tokens?|token|ctx|context)?", re.I) 10+_CONTEXT = re.compile(r"(\d+(?:[.,]\d+)?)\s*([kKmM])?\s*(?:tokens?|token|ctx|context)?", re.IGNORECASE)
11−_MONEY = re.compile(r"(?:US)?\$\s*(\d+(?:[.,]\d+)?)\s*(?:/|per)\s*(?:1\s*)?([mMkK])\s*(?:tok(?:ens?)?)?", re.I) 11+_MONEY = re.compile(r"(?:US)?\$\s*(\d+(?:[.,]\d+)?)\s*(?:/|per)\s*(?:1\s*)?([mMkK])\s*(?:tok(?:ens?)?)?", re.IGNORECASE)
12 _MONEY_SIMPLE = re.compile(r"(?:US)?\$\s*(\d+(?:\.\d+)?)") 12 _MONEY_SIMPLE = re.compile(r"(?:US)?\$\s*(\d+(?:\.\d+)?)")
13 _PCT = re.compile(r"(-?\d+(?:\.\d+)?)\s*%") 13 _PCT = re.compile(r"(-?\d+(?:\.\d+)?)\s*%")
14 14
@@ -34,7 +34,7 @@ def parse_active_params(text: str) -> int | None:
34 """'235B-A22B' / '30B-A3B' → active parameters of an MoE model.""" 34 """'235B-A22B' / '30B-A3B' → active parameters of an MoE model."""
35 m = re.search(r"-A(\d+(?:\.\d+)?)([bBmM])\b", text) 35 m = re.search(r"-A(\d+(?:\.\d+)?)([bBmM])\b", text)
36 if not m: 36 if not m:
37− m = re.search(r"(\d+(?:\.\d+)?)\s*([bB])\s*active", text, re.I) 37+ m = re.search(r"(\d+(?:\.\d+)?)\s*([bB])\s*active", text, re.IGNORECASE)
38 if not m: 38 if not m:
39 return None 39 return None
40 return int(_num(m.group(1)) * _MULT[m.group(2).lower()]) 40 return int(_num(m.group(1)) * _MULT[m.group(2).lower()])
@@ -102,5 +102,13 @@ def parse_int(text: str) -> int | None:
102 return None 102 return None
103 103
104 104
105−__all__ = ["parse_param_count", "parse_active_params", "parse_context_length", "parse_tokens", "parse_money_per_mtok", "parse_money", 105+__all__ = [
106− "parse_percent", "parse_int"] 106+ "parse_active_params",
107+ "parse_context_length",
108+ "parse_int",
109+ "parse_money",
110+ "parse_money_per_mtok",
111+ "parse_param_count",
112+ "parse_percent",
113+ "parse_tokens",
114+]
modified src/aiatlas/sdk/facts.py +14 −2
@@ -218,5 +218,17 @@ EVENT_CATEGORY_BY_TYPE: dict[str, str] = {
218 "mcp_server": "tool", "researcher": "company", "license": "model", "product": "tool", "robot": "hardware", 218 "mcp_server": "tool", "researcher": "company", "license": "model", "product": "tool", "robot": "hardware",
219 } 219 }
220 220
221−__all__ = ["EntityRef", "Claim", "Relation", "Event", "PriceObs", "ResultObs", "Target", "Facts", "MATERIAL_PROPERTIES", 221+__all__ = [
222− "NOISY_PREFIXES", "EVENT_CATEGORY_BY_TYPE", "CONFIDENCE"] 222+ "CONFIDENCE",
223+ "EVENT_CATEGORY_BY_TYPE",
224+ "MATERIAL_PROPERTIES",
225+ "NOISY_PREFIXES",
226+ "Claim",
227+ "EntityRef",
228+ "Event",
229+ "Facts",
230+ "PriceObs",
231+ "Relation",
232+ "ResultObs",
233+ "Target",
234+]
modified src/aiatlas/sdk/fetch.py +2 −2
@@ -102,7 +102,7 @@ def canonicalize_url(url: str) -> str:
102 102
103 def domain_of(url: str) -> str: 103 def domain_of(url: str) -> str:
104 host = urlparse(url).netloc.lower() 104 host = urlparse(url).netloc.lower()
105− return host[4:] if host.startswith("www.") else host 105+ return host.removeprefix("www.")
106 106
107 107
108 class _RateLimiter: 108 class _RateLimiter:
@@ -326,4 +326,4 @@ def file_result(path: str, *, url: str, content_type: str = "application/octet-s
326 _limiter = _RateLimiter() 326 _limiter = _RateLimiter()
327 _robots = _Robots() 327 _robots = _Robots()
328 328
329−__all__ = ["Fetcher", "FetchResult", "FetchError", "BlockedError", "NotModified", "canonicalize_url", "domain_of", "file_result"] 329+__all__ = ["BlockedError", "FetchError", "FetchResult", "Fetcher", "NotModified", "canonicalize_url", "domain_of", "file_result"]
modified src/aiatlas/sdk/writer.py +9 −1
@@ -19,7 +19,15 @@ from sqlalchemy.ext.asyncio import AsyncConnection
19 19
20 from aiatlas.db import execute, fetch_one, jsonb 20 from aiatlas.db import execute, fetch_one, jsonb
21 from aiatlas.ids import new_id, normalize_alias 21 from aiatlas.ids import new_id, normalize_alias
22−from aiatlas.sdk.facts import EVENT_CATEGORY_BY_TYPE, MATERIAL_PROPERTIES, NOISY_PREFIXES, EntityRef, Facts, PriceObs, ResultObs 22+from aiatlas.sdk.facts import (
23+ EVENT_CATEGORY_BY_TYPE,
24+ MATERIAL_PROPERTIES,
25+ NOISY_PREFIXES,
26+ EntityRef,
27+ Facts,
28+ PriceObs,
29+ ResultObs,
30+)
23 from aiatlas.sdk.resolution import Resolver 31 from aiatlas.sdk.resolution import Resolver
24 32
25 log = logging.getLogger(__name__) 33 log = logging.getLogger(__name__)
modified src/aiatlas/services/cache.py +1 −1
@@ -96,4 +96,4 @@ async def close() -> None:
96 await asyncio.sleep(0) 96 await asyncio.sleep(0)
97 97
98 98
99−__all__ = ["redis", "cache_get", "cache_set", "cache_invalidate", "lock", "heartbeat", "heartbeats", "close"] 99+__all__ = ["cache_get", "cache_invalidate", "cache_set", "close", "heartbeat", "heartbeats", "lock", "redis"]
modified src/aiatlas/services/handlers.py +2 −2
@@ -6,10 +6,10 @@ from datetime import UTC
6 from typing import Any 6 from typing import Any
7 7
8 from aiatlas.db import execute, fetch_one, transaction 8 from aiatlas.db import execute, fetch_one, transaction
9+from aiatlas.schemas import schema_for
9 from aiatlas.sdk import archive 10 from aiatlas.sdk import archive
10 from aiatlas.sdk.facts import EntityRef, Facts 11 from aiatlas.sdk.facts import EntityRef, Facts
11 from aiatlas.sdk.writer import FactWriter 12 from aiatlas.sdk.writer import FactWriter
12−from aiatlas.schemas import schema_for
13 from aiatlas.services.jobs import handler 13 from aiatlas.services.jobs import handler
14 from aiatlas.services.llm import LLMUnavailable, gateway 14 from aiatlas.services.llm import LLMUnavailable, gateway
15 15
@@ -253,4 +253,4 @@ async def recompute_quality(payload: dict[str, Any], job: dict[str, Any]) -> dic
253 return await recompute(entity_ids=payload.get("entity_ids")) 253 return await recompute(entity_ids=payload.get("entity_ids"))
254 254
255 255
256−__all__ = ["llm_extract", "facts_from_llm", "embed_entity", "reprocess_snapshot", "recompute_quality"] 256+__all__ = ["embed_entity", "facts_from_llm", "llm_extract", "recompute_quality", "reprocess_snapshot"]
modified src/aiatlas/services/jobs.py +1 −1
@@ -125,4 +125,4 @@ async def requeue_stale(conn: AsyncConnection, *, older_than_minutes: int = 120)
125 return int(row["n"]) if row else 0 125 return int(row["n"]) if row else 0
126 126
127 127
128−__all__ = ["enqueue", "claim_next", "complete", "fail", "queue_depth", "run_worker", "handler", "requeue_stale"] 128+__all__ = ["claim_next", "complete", "enqueue", "fail", "handler", "queue_depth", "requeue_stale", "run_worker"]
modified src/aiatlas/services/llm/gateway.py +3 −3
@@ -207,7 +207,7 @@ class LLMGateway:
207 207
208 def _parse_json(raw: str) -> dict[str, Any] | None: 208 def _parse_json(raw: str) -> dict[str, Any] | None:
209 s = raw.strip() 209 s = raw.strip()
210− s = re.sub(r"<think>.*?</think>", "", s, flags=re.S).strip() 210+ s = re.sub(r"<think>.*?</think>", "", s, flags=re.DOTALL).strip()
211 if s.startswith("```"): 211 if s.startswith("```"):
212 s = re.sub(r"^```(?:json)?\s*", "", s) 212 s = re.sub(r"^```(?:json)?\s*", "", s)
213 s = re.sub(r"\s*```$", "", s) 213 s = re.sub(r"\s*```$", "", s)
@@ -216,7 +216,7 @@ def _parse_json(raw: str) -> dict[str, Any] | None:
216 return v if isinstance(v, dict) else None 216 return v if isinstance(v, dict) else None
217 except json.JSONDecodeError: 217 except json.JSONDecodeError:
218 pass 218 pass
219− m = re.search(r"\{.*\}", s, flags=re.S) 219+ m = re.search(r"\{.*\}", s, flags=re.DOTALL)
220 if m: 220 if m:
221 try: 221 try:
222 v = json.loads(m.group(0)) 222 v = json.loads(m.group(0))
@@ -228,4 +228,4 @@ def _parse_json(raw: str) -> dict[str, Any] | None:
228 228
229 gateway = LLMGateway() 229 gateway = LLMGateway()
230 230
231−__all__ = ["LLMGateway", "LLMResult", "LLMUnavailable", "Engine", "OpenAICompatEngine", "gateway"] 231+__all__ = ["Engine", "LLMGateway", "LLMResult", "LLMUnavailable", "OpenAICompatEngine", "gateway"]
modified src/aiatlas/services/quality.py +1 −1
@@ -69,4 +69,4 @@ async def recompute(*, entity_ids: list[str] | None = None, limit: int = 20000)
69 return {"updated": updated} 69 return {"updated": updated}
70 70
71 71
72−__all__ = ["recompute", "QUALITY_VERSION", "EXPECTED_FIELDS"] 72+__all__ = ["EXPECTED_FIELDS", "QUALITY_VERSION", "recompute"]
modified src/aiatlas/services/search.py +3 −3
@@ -80,12 +80,12 @@ def compile_query(q: str) -> Query:
80 if m: 80 if m:
81 out.organization = m.group(1) 81 out.organization = m.group(1)
82 # residual free-text (remove the structured bits) 82 # residual free-text (remove the structured bits)
83− residual = re.sub(r"\b(more than|over|above|less than|under|below|at least|at most|released|launched|published|since|after|before|until|with|and|in|from|by|the|a|an|context|window|params?|parameters)\b", " ", s, flags=re.I) 83+ residual = re.sub(r"\b(more than|over|above|less than|under|below|at least|at most|released|launched|published|since|after|before|until|with|and|in|from|by|the|a|an|context|window|params?|parameters)\b", " ", s, flags=re.IGNORECASE)
84 residual = re.sub(r"\d+(?:\.\d+)?\s*[bBmMkKtT]\b|\b20\d\d\b|[<>≤≥]", " ", residual) 84 residual = re.sub(r"\d+(?:\.\d+)?\s*[bBmMkKtT]\b|\b20\d\d\b|[<>≤≥]", " ", residual)
85 for words in TYPE_WORDS.values(): 85 for words in TYPE_WORDS.values():
86 for w in words: 86 for w in words:
87− residual = re.sub(rf"\b{re.escape(w)}\b", " ", residual, flags=re.I) 87+ residual = re.sub(rf"\b{re.escape(w)}\b", " ", residual, flags=re.IGNORECASE)
88− residual = re.sub(r"\b(open[- ]?(weight|weights|source)|proprietary|closed)\b", " ", residual, flags=re.I) 88+ residual = re.sub(r"\b(open[- ]?(weight|weights|source)|proprietary|closed)\b", " ", residual, flags=re.IGNORECASE)
89 out.filters["residual"] = " ".join(residual.split()) 89 out.filters["residual"] = " ".join(residual.split())
90 return out 90 return out
91 91
modified src/aiatlas/services/stats.py +1 −1
@@ -50,4 +50,4 @@ async def history(conn: AsyncConnection, days: int = 90) -> list[dict[str, Any]]
50 from stats_snapshots where computed_at > now() - make_interval(days => :d) order by 1 desc, computed_at desc""", d=days) 50 from stats_snapshots where computed_at > now() - make_interval(days => :d) order by 1 desc, computed_at desc""", d=days)
51 51
52 52
53−__all__ = ["live_counts", "compute_stats", "history"] 53+__all__ = ["compute_stats", "history", "live_counts"]
54 54
Menu

Theme